Pomiar temperatury przez ds18b20 i przerwanie w Bascom

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
zbynio-87
-
Posty: 3
Rejestracja: 24 lip 2010, 23:01
Lokalizacja: Kaczyce

Pomiar temperatury przez ds18b20 i przerwanie w Bascom

Post autor: zbynio-87 » 24 lip 2010, 23:04

Witam serdecznie.
Szukałem już chyba wszędzie, próbowałem kilkunastu innych programów i problem ciągle zostaje nie rozwiązany.
Otóż piszę program do sterownika pieca. Posiada on 3 czujniki DS18B20, 3 przekaźniki i 1 triak do sterowania pompki kolektorów. Wszystko działa bez zarzutu. Problem pojawia się dopiero po włączeniu przerwania od INT0 (regulacja fazowa pompki). Co jakiś czas wynik pomiaru z obojętnie, którego czujnika wyświetlany jest w postaci 0.0 st.C. Jest to problematyczne, gdyż np. pompka załączy się i wyłączy, podobnie jest z klapką, elektrozaworem lub pompką o obwodzie grzewczym pieca.
Dotychczas próbowałem wyłączać przerwania na czas pomiaru, czy ustalać dodatkowe czasy, wgrywałem inne programy, ale wynik końcowy był ciągle taki sam, tzn: 0.0 st.C co jakiś czas.
Gdy projekt będzie skończony to chętnie podzielę się wszystkim z szanownymi forumowiczami.

Poniżej kod programu (fragmenty) na ATmega 16, 8MHz:

Kod: Zaznacz cały

$regfile = "m16def.DAT"
$crystal = 8000000

Dim Tp As Integer , Ss1 As String * 6
Dim Tb As Integer , Ss2 As String * 6
Dim Tk As Integer , Ss3 As String * 6

Dim Dsid1(8) As Byte
Dim Dsid2(8) As Byte
Dim Dsid3(8) As Byte

Dim B As Byte 'deklaracja zmiennej do odczytu kodów ID
Dim W As Byte

'*************************konfiguracja przerwania INT0**************************
Config Int0 = Falling ' INT0 wyzwalane zboczem opadającym
On Int0 Zero_cross 'skocz do Zero_cross - przejście przez zero

'*************************konfiguracja TIMER1***********************************
Config Timer1 = Timer , Prescale = 64 'Timer1 jako licznik, dzielnik = 64(przepełnienie co 4us)
On Timer1 Tim1_isr 'skocz do Tim_isr - załaczenie triaków

'*************************odblokowanie systemu przerwań*************************
Enable Int0 'odblokowanie przerwania
Enable Interrupts 'odblokowanie globalnego systemu przerwań

'**************************zmienne w programie*********************************
Dim Moc As Byte ' zmienna przechowująca poziom
Dim K As Word
Moc = 0

'program główny

do

1wreset
1wwrite &H55
1wverify Dsid1(1) 'wysyłamy adres pierwszego czujnika
If Err <> 1 Then
1wwrite &HBE
Tp = 1wread(2)

Tp = Tp * 10
Tp = Tp / 16
Ss1 = Str(tp)
Ss1 = Format(ss1 , " 0.0")
Locate 1 , 1 'Pozycja wyświetlania nazwy i temperatury (1.1 -> 1 linia 1 kolumna, 2.10 -> 2 linia 10 kolumna itd)
Lcd "Piec: " ; Ss1 ; Chr(0) ; Chr(1)
Else
Locate 1 , 1
Lcd "ERROR Piec "
End If

'---------------------------------

1wreset
1wwrite &H55
1wverify Dsid2(1) 'wysylam adres drugiego czujnika
If Err <> 1 Then
1wwrite &HBE
Tb = 1wread(2)

Tb = Tb * 10
Tb = Tb / 16
Ss2 = Str(tb)
Ss2 = Format(ss2 , " 0.0")
Locate 2 , 1
Lcd "Bojler: " ; Ss2 ; Chr(0) ; Chr(1)
Else
Locate 2 , 1
Lcd "ERROR Bojler "
End If


'---------------------------------


1wreset
1wwrite &H55
1wverify Dsid3(1) 'wysylam adres trzeciego czujnika
If Err <> 1 Then
1wwrite &HBE
Tk = 1wread(2)

Tk = Tk * 10
Tk = Tk / 16
Ss3 = Str(tk)
Ss3 = Format(ss3 , " 0.0")
Locate 3 , 1
Lcd "Kolektor:" ; Ss3 ; Chr(0) ; Chr(1)
Else
Locate 3 , 1
Lcd "ERROR Kolektor "
End If

'--------konwersja temp dla wszystkich dsow

1wreset
1wwrite &HCC
1wwrite &H44
Wait 3

Tna = E_tna
Tn = Tna / 10
Locate 4 , 1
Lcd "Nastawa: " ; Tn ; ".0" ; Chr(0) ; Chr(1)

loop

Tim1_isr:

Set K_pompa 'załącz triak2
Disable Timer1 'wyłącz Timer1
Return 'powrót

'*****************podprogram odmierzajacy czas od przerwania********************
Zero_cross:

Reset K_pompa ' wył. Triaka w ZERO sieci 230V
K = Lookup(moc , Obroty) ' pobranie z tablicy wartości Timera1
Load Timer1 , K ' załadowanie pobranej wartości do Timera1
Enable Timer1 ' załączenie Timera1 - odliczanie czasu
Return 'powrót


Obroty: 'podprogram prędkości
Data 0% ,
Data 915% , 760% , 625% , 490% , 335% , 100% 
Bardzo proszę o jakieś praktyczne rozwiązania lub przykłady.
Pozdrawiam

keruseykaryu

Post autor: keruseykaryu » 25 lip 2010, 7:58

Jak DS zwraca temperaturę zero, to rozjeżdżają się czasy w transmisji 1wire. Z sieci masz co 10ms przerwania, i to w tych odcinkach musisz się mieścić z całą transmisją 1wire. Trzeba to jakoś zsynchronizować, aby wymiana danych z 1wire odbywała się po wykonaniu przerwania z INT0.

Awatar użytkownika
Pikczu
Użytkownik
Posty: 754
Rejestracja: 18 lip 2005, 18:33
Lokalizacja: Dublin
Kontakt:

Post autor: Pikczu » 25 lip 2010, 9:58

Witam zobacz na mój kod w tym temacje:
https://forum.elportal.pl/viewtopic.php?t=9910
Może coś będziesz w stanie wyciąc i użyć u siebie.

zbynio-87
-
Posty: 3
Rejestracja: 24 lip 2010, 23:01
Lokalizacja: Kaczyce

Post autor: zbynio-87 » 25 lip 2010, 9:59

...czyli, po wywołaniu przerwania ustawić flagę, a w programie głównym gdy flaga będzie przypuśćmy = 1 (funkcja while - wend) to wykona się podprogram odczytu z DS-ów.
Coś takiego?

Kod: Zaznacz cały

While flaga = 1 
   1wreset
   1wwrite &H55
   1wverify Dsid1(1)           
   1wwrite &HBE
   Tp = 1wread(2)
   reset flaga
wend
A w przypadku gdy jest więcej czujników, np. trzy?
Proszę o jakieś przykłady

Awatar użytkownika
Pikczu
Użytkownik
Posty: 754
Rejestracja: 18 lip 2005, 18:33
Lokalizacja: Dublin
Kontakt:

Post autor: Pikczu » 25 lip 2010, 10:20

Ja osobiscie bym to przerobił a raczej bardzej rozbudował
Popatrz na to jak masz zamiar zarejstrować czujniki ?
Nie widzę nigdzie czegoś takiego u ciebie w programie.
Druga sprawa może być taka sytuacja że po zaniku zasilania i restarcje program przypisze sam czujniki w innej kolejności, musi być to na sztywno ustawione.

Kolejne zagadnienie to konwersia temperatury trwa 750ms więć nie ma po co odczytywać częściej.
U Ciebie jest pętla do loop i to się kręci w kółko bardzo szybko (nie wiem ile musiał bym sprawdzić)

Przeklej z mojego kodu całą rejestarcję czujnkiów w tedy w pamięci eeprom będizesz miał na stałe zapisane czujnki i będziesz wiedział który jest który po restarce procesor odczyta z eeproma numery i zawsze przypisze do tych samych.
Koniecznie trzeba ustawić watchdoga u mnie go nie ma ale ja steruje tylko wenylatorami w zasilaczu a nie piecem w domu wieć mi nic nie grozi.


Kary godnym jest danie tego Wait 3 w pętli doo loop
Zauważ że ja mam wait ale tylko na poczatku programu przed pętlą do loop i przed wystartowaniem timerów, później czas liczy timer 2 do migania diodami a timer 0 zwiększa zmienną czas

Kod: Zaznacz cały

Timer0_isr:
Load Timer0 , 216                                           'co Xms
Incr Czas
If Czas >= 100 Then
Set Flag0
Else
Reset Flag0
End If
Return


[ Dodano: 2010-07-25, 10:30 ]
Ten przykład który podałeś "wile wend" może być.
Zauważ że robisz konwersie temperatury na końcu pierwszej pętli do loop, więc pierwszy odczyt będzie 85 stopni.

[ Dodano: 2010-07-25, 10:45 ]
Zresztą masz tu gotowca:
http://mirley.firlej.org/prosty_sterownik_co

ODPOWIEDZ