Strona 1 z 1

Atmega8 i czujniki DS18B20. Problem z powielaniem wartości.

: czwartek 16 sty 2014, 21:36
autor: zgf1
Witam. Kolejny raz proszę Was o pomoc. Mam w sumie już pracujący układ. Przeznaczony jest on do sterowania pomp w kolektorze słonecznym, z racji tego dobrze byłoby aby układ sygnalizował gdy któryś czujnik zostanie odłączony bądź nastąpi jego awaria.

Obecnie wszystko działa, ale jeśli do układu podepnę tylko jeden czujnik to temperatura jest powielana, w miejscu w którym powinna być temperatura czujnika 2 wyświetlana jest temperatura czujnika 1, w miejscu w którym powinna być wyświetlana temperatura czuknika 3 jest wyświetlana temperatura czujnika 1 itd.
Oczywiście jeśli do układu podpięte są wszystkie 4 czujniki wszystko pracuje poprawnie.

Mam prośbę do doświadczonych użytkowników o pomoc w modyfikacji kodu programu....

Całość wygląda tak:
$regfile = "m8def.DAT"
$crystal = 8000000
Config Lcdpin = Pin , Db4 = Portd.3 , Db5 = Portd.2 , Db6 = Portd.1 , Db7 = Portd.0 , E = Portd.4 , Rs = Portb.6
Config Lcd = 16 * 2

Config Pinc.0 = Input
Config Pinc.1 = Input
Config Pinc.2 = Input
Config Pinc.3 = Output
Config Pinc.4 = Output
Config Pinc.5 = Output
Config 1wire = Portb.1

Portc.0 = 1
Portc.1 = 1
Portc.2 = 1
Portc.3 = 1
Portc.4 = 1
Portc.5 = 1

S1 Alias Pinc.0
S2 Alias Pinc.1
S3 Alias Pinc.2


Dim I1 As Integer , Ss As String * 6
Dim I2 As Integer
Dim I3 As Integer
Dim I4 As Integer
Dim Dsid1(8) As Byte
Dim Dsid2(8) As Byte
Dim Dsid3(8) As Byte
Dim Dsid4(8) As Byte
Dim B As Byte
Dim W As Byte
Dim Alarm As Integer
Dim Alarm1 As Integer
Dim Alarm2 As Integer
Dim Rlarm As Integer
Dim Rlarm1 As Integer
Dim Rlarm2 As Integer
Dim Xa As Eram Integer At &H01
Dim Xa1 As Integer
Dim Ra As Eram Integer At &H03
Dim Ra1 As Integer

If Xa = -1 Then
Xa = 0
End If
If Ra = -1 Then
Ra = 0
End If

Alarm = Xa
Rlarm = Ra
Alarm1 = Alarm / 10
Rlarm1 = Rlarm / 10

Deflcdchar 0 , 8 , 20 , 11 , 4 , 4 , 4 , 3 , 32
Deflcdchar 1 , 32 , 4 , 4 , 4 , 4 , 4 , 4 , 32
Deflcdchar 2 , 32 , 10 , 10 , 10 , 10 , 10 , 10 , 32
Deflcdchar 3 , 32 , 21 , 21 , 21 , 21 , 21 , 21 , 32
Deflcdchar 4 , 32 , 21 , 21 , 21 , 21 , 18 , 18 , 32
Deflcdchar 5 , 31 , 27 , 27 , 27 , 27 , 27 , 27 , 31



Cursor Off
Cls
Locate 1 , 1
Lcd "Obieg 1: " ; Alarm1 ; Chr(0) ;
Locate 2 , 1
Lcd "Obieg 2: " ; Rlarm1 ; Chr(0) ;
Wait 4
Cls
W = 1wirecount()
Lcd "Czujniki: "
Waitms 2000
Lcd W
Wait 4
Cls
Dsid1(1) = 1wsearchfirst()
Dsid2(1) = 1wsearchnext()
Dsid3(1) = 1wsearchnext()
Dsid4(1) = 1wsearchnext()

Waitms 500

If Dsid1(8) = Crc8(dsid1(1) , 7) Then
Locate 1 , 1
Cls
Lcd "T1 id:"
Wait 1
Locate 2 , 1
For B = 1 To 8
Lcd Hex(dsid1(b))
Next
End If
Wait 2

If Dsid2(8) = Crc8(dsid2(1) , 7) Then
Locate 2 , 1
Cls
Lcd "T2 id:"
Wait 1
Locate 2 , 1
For B = 1 To 8
Lcd Hex(dsid2(b))
Next
End If
Wait 2

If Dsid3(8) = Crc8(dsid3(1) , 7) Then
Locate 1 , 1
Cls
Lcd "T3 id:"
Wait 1
Locate 2 , 1
For B = 1 To 8
Lcd Hex(dsid3(b))
Next
End If
Wait 2

If Dsid4(8) = Crc8(dsid4(1) , 7) Then
Locate 1 , 1
Cls
Lcd "T4 id:"
Wait 1
Locate 2 , 1
For B = 1 To 8
Lcd Hex(dsid4(b))
Next
End If
Wait 2
Cls



Pomiar:
Do
1wreset
1wwrite &H55
1wverify Dsid1(1)
1wwrite &HBE
I1 = 1wread(2)
'---------------------------------
1wreset
1wwrite &H55
1wverify Dsid2(1)
1wwrite &HBE
I2 = 1wread(2)
'---------------------------------
1wreset
1wwrite &H55
1wverify Dsid3(1)
1wwrite &HBE
I3 = 1wread(2)
'---------------------------------
1wreset
1wwrite &H55
1wverify Dsid4(1)
1wwrite &HBE
I4 = 1wread(2)
'--------konwersja temp dla wszystkich dsow
1wreset
1wwrite &HCC
1wwrite &H44
Wait 1


I1 = I1 * 10
I1 = I1 / 16
If I1 > 0 Then
Ss = Str(i1)
Ss = Format(ss , " 0.0")
Locate 1 , 1
Lcd Chr(1) ; Ss ; Chr(0) ;
Else
Ss = Str(i1)
Ss = Format(ss , " 0.0")
Locate 1 , 1
Lcd Chr(1) ; Ss ; Chr(0) ;
End If

I2 = I2 * 10
I2 = I2 / 16
If I2 > 0 Then
Ss = Str(i2)
Ss = Format(ss , " 0.0")
Locate 1 , 10
Lcd Chr(2) ; Ss ; Chr(0) ;
Else
Ss = Str(i2)
Ss = Format(ss , " 0.0")
Locate 1 , 10
Lcd Chr(2) ; Ss ; Chr(0) ;
End If

I3 = I3 * 10
I3 = I3 / 16
If I3 > 0 Then
Ss = Str(i3)
Ss = Format(ss , " 0.0")
Locate 2 , 1
Lcd Chr(3) ; Ss ; Chr(0) ;
Else
Ss = Str(i3)
Ss = Format(ss , " 0.0")
Locate 2 , 1
Lcd Chr(3) ; Ss ; Chr(0) ;
End If

I4 = I4 * 10
I4 = I4 / 16
If I4 > 0 Then
Ss = Str(i4)
Ss = Format(ss , " 0.0")
Locate 2 , 10
Lcd Chr(4) ; Ss ; Chr(0) ;
Else
Ss = Str(i4)
Ss = Format(ss , " 0.0")
Locate 2 , 10
Lcd Chr(4) ; Ss ; Chr(0) ;

End If


Alarm2 = I2 - I1
Rlarm2 = I4 - I3


If Alarm2 > Alarm Then
Reset Portc.4
End If
If Alarm2 < Alarm Then
Set Portc.4
End If

If Rlarm2 > Rlarm Then
Reset Portc.3
End If
If Rlarm2 < Rlarm Then
Set Portc.3
End If


If S1 = 0 Then
Waitms 100
Cls
Lcd " ..USTAWIENIA.. "
Wait 1
Goto Ustawienia
End If



Toggle Portc.5
Goto Pomiar




Ustawienia:
Cls
Waitms 25
Cls
If S3 = 0 Then
Alarm = Alarm + 10
Waitms 20
End If
If S2 = 0 Then
Alarm = Alarm - 10
Waitms 20
End If
Alarm1 = Alarm
Alarm1 = Alarm1 / 10
Locate 1 , 1
Lcd "Obieg 1: " ; Alarm1 ; Chr(0)
Locate 2 , 1
Lcd "[ " ; Alarm ; " ]"
Waitms 300
If S1 = 0 Then
Waitms 300
Cls
Locate 1 , 1
Lcd "Zapisano: " ; Alarm1 ; Chr(0)
Locate 2 , 1
Lcd Alarm
If Xa <> Alarm Then
Xa = Alarm
End If
Waitms 3000
Cls
Goto Ustawienia2
End If
Goto Ustawienia



Ustawienia2:
Cls
Waitms 25
Cls
If S3 = 0 Then
Rlarm = Rlarm + 10
Waitms 20
End If
If S2 = 0 Then
Rlarm = Rlarm - 10
Waitms 20
End If
Rlarm1 = Rlarm
Rlarm1 = Rlarm1 / 10
Locate 1 , 1
Lcd "Obieg 2: " ; Rlarm1 ; Chr(0)
Locate 2 , 1
Lcd "[ " ; Rlarm ; " ]"
Waitms 300
If S1 = 0 Then
Waitms 300
Cls
Locate 1 , 1
Lcd "Zapisano: " ; Rlarm1 ; Chr(0)
Locate 2 , 1
Lcd Rlarm
If Ra <> Rlarm Then
Ra = Rlarm
End If
Waitms 3000
Cls
Locate 1 , 1
Lcd "Obieg 1 : " ; Alarm1 ; Chr(0) ; "
Locate 2 , 1
Lcd "Obieg 2 : " ; Rlarm1 ; Chr(0) ;
Waitms 5000
Cls
Goto Pomiar
End If
Goto Ustawienia2





Loop
End

: piątek 17 sty 2014, 06:19
autor: Pyra
Witam
Spróbuj sobie wydrukować na wyświetlaczu adresy i porównaj.

Pozdrawiam

: piątek 17 sty 2014, 08:06
autor: pier
Program powinien wyglądać trochę inaczej.
Nie napisze Ci gotowca ale zobacz tutaj , ja wzorowałem się na tym i mam na jednej linii 4 czujniki i żadnych problemów.

Musisz zrobić procedurę rejestracji adresów czujników i zapisać je do pamięci eprom.

: piątek 17 sty 2014, 17:25
autor: zgf1
Adresy czujników wyświetlają się podczas startu, znam je. Problem z przyporządkowaniem miejsca.


Chyba za wysokie progi dla mnie, próbuję wyciąć część programu z linka tylko do odczytu DS i wyświetlania wartości na LCD, ale za cholerę nie umiem sobie z tym poradzić :(

: piątek 17 sty 2014, 17:33
autor: pier
Sama procedura odczytu niewiele Ci da bo nie masz zapisanych adresów w epromie.
Podejdź do tego programu z linku ze spokojem i krok po kroku przeanalizuj.
Ja też się za głowę złapałem jak go pierwszy raz zobaczyłem ale teraz mam już gotowe działające urządzenie z czterema czujnikami na jednej linii.

Analizuj i pytaj. Postaram się pomóc.

: piątek 17 sty 2014, 17:36
autor: Pyra
Witam
Powinieneś ograniczyć ilość czujników do tej wskazanej przez 1wirecount().
Z dynamicznym przypisywaniem czujników jest jeden problem, czujniki są przydzielane kolejno i np usunięcie jednego powoduje, że reszta się przesuwa i zawsze masz od 1. Jest z tym związane pewne niebezpieczeństwo, w razie awarii któregoś czujnika, inny wskakuje w jego miejsce i masz kaszanę... Najlepiej je odczytywać pojedynczo i wpisywać do eepromu.
Kilka lat temu walczyłem z taki przypadkiem, ale już nie pamiętam jak to dokładnie było...

Pozdrawiam

: sobota 18 sty 2014, 16:52
autor: zgf1
No właśnie nie jestem, aż tak zaawansowany aby to ogarnąć, próbowałem z tamtego programu wyciąć tylko odczyt czujników, pomiar, wyświetlanie temperatur, ale na chwilę obecną mnie to przerasta. Przeszukałem też cały prawie internet, ale gotowców brak.

Pomyślałem więc jak obejść problem w inny sposób, użyłem pętli, zwiększanie wartości przy każdym pomiarze o 1, gdy wartość pętli osiągnie pewną liczbę używam Watchdog i restartuje układ. Przy wykrywaniu czujników jeśli wykrywa ich mniej niż 4 układ sygnalizuje to(jest informacja na wyświetlaczu o awarii, pompy włączają się na 30s, wyłączają na 30s i znów włączają...).


Chyba nic więcej nie jestem w stanie zrobić, przynajmniej na tym poziomie zaawansowania....



EDIT:
Wprowadziłem przed wykrywaniem czujników etykietę, co kilka minut program odsyła do niej i jeśli wykrywa mniej niż 4 czujniki włącza się tryb awaryjny. Chyba to najlepsze z rozwiązań?