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!
-
M@ciej
- Użytkownik
- Posty: 736
- Rejestracja: 13 sie 2005, 21:38
- Lokalizacja: Szczecin
Post
autor: M@ciej » 19 kwie 2009, 8:57
Witam.
Mam taki problem:
Zmontowałem prosty 2-czujnikowy termometr na DS18B20, sterowany prockiem Atmega8 z wyświetlaczem. Program przepisałem z książki M. Wiązani "Programowanie mikrokokntrolerów w języku Bascom". Niestety odczytana temperatura z obu układów jest błędna, i pokazuje -70°C w temperaturze pokojowej.
Nie wiem,gdzie tkwi błąd. W książce program jest opisany na podstawie DS1820, tymczasem ja mam DS18B20, czy w tym tkwi różnica?
Pozdrawiam

-
kaliska5
- Użytkownik
- Posty: 348
- Rejestracja: 01 maja 2008, 8:24
- Lokalizacja: z nienacka
-
Kontakt:
Post
autor: kaliska5 » 19 kwie 2009, 9:39
A masz rezystor podciągający linie do + ?U mnie tez działy się takie rzeczy bez rezystora dałem rezystor i spokój
-
M@ciej
- Użytkownik
- Posty: 736
- Rejestracja: 13 sie 2005, 21:38
- Lokalizacja: Szczecin
Post
autor: M@ciej » 19 kwie 2009, 10:13
Mam rezystor SMD 4,7kΩ wpięty pomiędzy +5V a linię.
-
kaliska5
- Użytkownik
- Posty: 348
- Rejestracja: 01 maja 2008, 8:24
- Lokalizacja: z nienacka
-
Kontakt:
Post
autor: kaliska5 » 19 kwie 2009, 10:28
Wiec problemu bym szukał w programie możesz pokazać kod . Nie jestem specjalista ale ostatnio zrobiłem sobie taki termometr i tez miałem podobne problemy
-
M@ciej
- Użytkownik
- Posty: 736
- Rejestracja: 13 sie 2005, 21:38
- Lokalizacja: Szczecin
Post
autor: M@ciej » 19 kwie 2009, 11:24
Mogłem pokopać adresy.W sumie wzięte z wspomnianej książki.
Oto kod:
Kod: Zaznacz cały
Declare Sub Odcz_temp(czujnik As Byte) 'procedura odczytu temp. z czujnika
Declare Sub Zapisz_id 'procedura zapisu ID do DS1820
Dim Temperatura(2) As Byte 'tablica na zmierzoną temperature
Dim Id(8) As Byte '8-elementowa tablica na numer ID
Dim I As Byte 'zmienne licznikowe
Dim J As Byte
Dim K As Byte
Dim Nukl As Byte 'liczba układów
Set _lcd
Cls
Nukl = 1wirecount() 'odczytujemy liczbe ukladow
If S1 = 0 Then
Lcd "Liczba ukladow:" ; Nukl
If Nukl > 0 Then
Id(1) = 1wsearchfirst() 'odczytanie numeru seryjnego ID
For I = 1 To 8
Writeeeprom Id(i) , I 'zapis ID pierwszego ukladu do eepromu
Next I
End If
If Nukl > 1 Then
Id(1) = 1wsearchnext() 'odczyt drugiego ukladu
J = 0
For I = 9 To 16
Incr J
Writeeeprom Id(j) , I
Next I
End If
Lowerline
Lcd "Prog OK. Zresetuj!"
Do
Loop
End If
Do
Home
For K = 1 To Nukl
Call Odcz_temp(k)
If Temperatura(2) = 0 Then 'temp. dodatnia
Lcd "Temp" ; K ; ": " ; Temperatura(1) ; Chr(0) ; "C"
Else
Lcd "Temp" ; K ; ": -" ; Temperatura(1) ; Chr(0) ; "C"
End If
Lowerline
Next K
Loop
End
Sub Odcz_temp(czujnik As Byte)
If Czujnik = 1 Then
For I = 1 To 8
Readeeprom Id(i) , I 'odczyt ID 1. czujnika z pamięci EEPROM (komórki 1-8)
Next I
End If
If Czujnik = 2 Then
J = 0
For I = 9 To 16
Incr J
Readeeprom Id(j) , I 'odczyt ID 2. czujnika z pamięci eeprom (komórki 9-16)
Next I
End If
1wreset 'reset/inicjalizacja magistrali 1-wire
Call Zapisz_id
1wwrite &H44 'komenda startu pomiaru temp.
Waitms 750 'czas na konwersje temp. w ukladzie DS
1wreset 'reinicjalizacja 1-wire
Call Zapisz_id 'wybranie czujnika przez zapis do niego ID aktualnie obsługiwanego układu
1wwrite &HBE 'komenda odczytu układu
Temperatura(1) = 1wread(2) 'odczyt zmierzonej temperatury
1wreset 'reinicjalizacja
If Err = 1 Then 'jeśli brak układu (zmienna ERR=1) to
Cls
Lcd "Brak układow!"
Lowerline
Lcd "Zrestartuj"
Do
Loop
End If
If Temperatura(2) > 0 Then 'jeśli wieksza od 0, to temp. ujemna
Temperatura(1) = 256 - Temperatura(1) 'przeliczenie temp. ujemnej
End If
Temperatura(1) = Temperatura(1) / 2 'przeliczenie temp. bo czujnik zwraca 2x za wysoką
End Sub
Sub Zapisz_id
1wwrite &H55 'wysłanie komendy do zapisu ID układu
For I = 1 To 8
1wwrite Id(i) 'wysłanie do czujników ID z tablicy
Next I
End Sub
-
c4r0
- Moderator
- Posty: 2150
- Rejestracja: 13 kwie 2004, 19:56
- Lokalizacja: z lasu
-
Kontakt:
Post
autor: c4r0 » 19 kwie 2009, 12:12
M@ciej pisze:W książce program jest opisany na podstawie DS1820, tymczasem ja mam DS18B20, czy w tym tkwi różnica?
Tak, jest różnica i pewnie w tym tkwi problem. Coś tam się inaczej robiło na 1-wire.
-
gwozdex
- Użytkownik
- Posty: 879
- Rejestracja: 24 lut 2006, 10:04
- Lokalizacja: Czechowice-Dziedzice
-
Kontakt:
Post
autor: gwozdex » 19 kwie 2009, 13:46
Nie wiem dokładnie gdzie ale należy przesunąć o jeden bit wynik pomiaru temp. przez DS1820 aby otrzymać poprawne wskazanie dla DS18B20. Jes to dosłownie jedna linijka kodu więcej. Szczegółów można szukać w książce "Mikroporocesorowa ośla łączka"
-
M@ciej
- Użytkownik
- Posty: 736
- Rejestracja: 13 sie 2005, 21:38
- Lokalizacja: Szczecin
Post
autor: M@ciej » 19 kwie 2009, 14:41
Mam cykl artykułów w EdW na temat M.O.Ł., zaraz tam poszukam.
-
RcTomek
- Moderator
- Posty: 243
- Rejestracja: 27 wrz 2007, 21:15
- Lokalizacja: Głogów / Wrocław
Post
autor: RcTomek » 19 kwie 2009, 17:16
Różnica między DS1820 i DS18B20 jest taka, że ten drugi ma możliwość pomiaru temperatury z większą rozdzielczością. Część ułamkowa jest zapisana na czterech bitach LSB, natomiast w DS1820 tylko na jednym (dokładność +/-0.5oC). Wystarczy więc odczytaną wartość odpowiednio przesunąć.
-
M@ciej
- Użytkownik
- Posty: 736
- Rejestracja: 13 sie 2005, 21:38
- Lokalizacja: Szczecin
Post
autor: M@ciej » 19 kwie 2009, 17:44
Poświęcenie nieco czasu lekturze Mikroprocesorowej Oślej Łączki oraz nieco więcej na napisanie programu zaowocowało programikiem odczytującym poprawnie temperaturę z 1-4 czujników. Gdyby zastosować większy wyświetlacz, zmieściłoby się więcej niż 4 danych na ekranie. Ja miałem 2x20.
Chętnym udostępnię kod.
Dzięki wszystkim za pomoc

-
Arko
- -
- Posty: 16
- Rejestracja: 02 gru 2006, 11:04
- Lokalizacja: okolice Kielc
-
Kontakt:
Post
autor: Arko » 20 kwie 2009, 17:29
tu masz opisane pozdro
Kod: Zaznacz cały
' C032d Proste wykorzystanie DS18x20 - jumper J2 B-C
'przestawiona kolejność poleceń konwersji i odczytu powoduje, że widać,
' iż po podaniu zasilania T=85oC i że podczas konwersji można
' odczytać stan SCRETHPAD-a, ale ze "starym" wynikiem
Config 1wire = Portd.5 : Dim Odczyt(2) As Byte , A As Byte ,
Dim Licznik As Byte , T As Integer
Cls : Lcd "Termometr" : Lowerline : Lcd Licznik : Wait 2
Do
Incr Licznik ' tylko po to, żeby pokazać, iż program "żyje"
1wreset : 1wwrite &HCC : 1wwrite &HBE 'polecenie odczytu DS18x20
Odczyt(1) = 1wread(2) 'odczytaj dwa pierwsze bajty - temperaturę
T = Odczyt(2) ' starszy bajt temperatury
Shift T , Left , 8 'przesuń w lewo o 8 miejsc
T = T + Odczyt(1) 'w zmiennej Integer jest dziwna "ułamkowa" wartość
Shift T , Right , 4 'zamiast dzielić przez 16 przesuń w prawo
' Shift T , Right , 1 'dla kostek DS18S20, DS1820 przesuń o 1 bit
Cls : Lcd "Temp=" ; T ; "oC" 'wyświetl wynik - liczbę całkowitą
Lowerline : Lcd Licznik 'w dolnej linii wyświetl stan licznika
1wreset ' dopiero teraz daj polecenie konwersji:
1wwrite &HCC 'polecenie SKIP ROM, bo pojedyncza kostka
1wwrite &H44 ' dokonaj konwersji - zmierz temperaturę
Wait 1 'po cyklu pracy poczekaj
Loop
-
M@ciej
- Użytkownik
- Posty: 736
- Rejestracja: 13 sie 2005, 21:38
- Lokalizacja: Szczecin
Post
autor: M@ciej » 20 kwie 2009, 18:29
Wow, procedura krótsza od mojej, ale nie wiem, jak ją "podłączyć" do pozostałej części programu, bo odczyt temperatury to tylko jedna z funkcji, jaką ma pełnić projektowane urządzenie.
Niemniej dzięki i również pozdrawiam

-
tomson
- -
- Posty: 29
- Rejestracja: 26 lut 2007, 18:02
-
Kontakt:
Post
autor: tomson » 05 maja 2009, 16:57
@M@ciej
Nie chcę się madrzyć ale wydaje mi się że temperatura(1) powinna być podzielona przez 16 a nie jak u ciebie przez 2
znajdź tą linijkę w swoim kodzie i sprawdź moje przypuszczenie
-
M@ciej
- Użytkownik
- Posty: 736
- Rejestracja: 13 sie 2005, 21:38
- Lokalizacja: Szczecin
Post
autor: M@ciej » 05 maja 2009, 20:00
Z tego co wiem, to są dwa podejścia. Albo z dzieleniem przez 16, albo z przesuwaniem bitów. Ja zastosowałem ten drugi sposób i jak na razie dobrze działa. Poczytaj w EdW, bo stamtąd brałem tą metodę z przesuwaniem.
Pozdrawiam.
-
*zaba*
- -
- Posty: 3
- Rejestracja: 15 gru 2008, 20:15
- Lokalizacja: Pawłowice
Post
autor: *zaba* » 28 maja 2009, 22:09
Witam to ja mogę udostępnić jeszcze krótszy kod z jakiejś tam książki i napewno działa testowałem
Kod: Zaznacz cały
$crystal = 1000000 'deklaracja częstotliwo?ci pracy kwarcu
$regfile "m8def.dat" 'model procesora dla którego jest ten program
Deflcdchar 1 , 14 , 17 , 17 , 14 , 32 , 32 , 32 , 32 ' definicja znaki stopnia
Config 1wire = Portc.5 ' konfiguracja portu PD.5 jako wej?cia magistrali 1-wire
Dim Odczyt(2) As Byte , A As Byte , Licznik As Byte , T As Integer , T1 As Single , Napis As String * 5
'Deklaracja wszystkich zmiennych potrzebnych do pracy programu
Do
1wreset 'reset
1wwrite &HCC 'jedna kostka, więc wykorzystujemy rozkaz SKIP ROM
1wwrite &H44 'dokonaj konwersji
Waitms 750 'przeczekaj czas konwersji
1wreset 'reset
1wwrite &HCC 'rozkaz adresowy SKIP ROM
1wwrite &HBE 'rozkaz funkcyjny - polecenie odczytu DS18x20
Odczyt(1) = 1wread(2) 'odczytaj dwa pierwsze bajty
T = Odczyt(2) 'przepisz starszy bajt do zmiennej typu Integer
Shift T , Left , 8 'przesuń ten bajt w lewo na wyższe pozycje
T = T + Odczyt(1) 'przepisz - dodaj młodszy bajt
T1 = T * 0.0625 'wyra? w stopniach Celsjusza, wynik wpisz do zmiennej Single
Napis = Fusing(t1 , "#.#")
Cls : Cursor Off : Lcd "* Temperatura *"
Lowerline
Lcd "Wynik: " ; Napis ; " " ; Chr(1) ; "C" 'wy?wietl wynik ze zmiennej Single
Loop : End