Zrobiłem termometr z DS18B20 na AT89S8252. Chcę do niego dołożyć zegar ale kiedy włączam timer wewnętrzny procesora to mi sie wynik temperatury pierdzieli. Obydwa układy oddzielnie działają bez problemu. POMOCY! Co mam zrobić Dołączam program odczytu temperatury
Tak na wszelki wypadek mozesz poczekac wiecej niz 250 ms (sugeruje poczekac 750 ms tyle co dla DS18S20).Moja uwaga co do samego programu: nie znam sie na bascomie ale nie ma tam przypadkiem czegos takiego jak przesuniecie bitowe >> i << ? Przeciez zarzynasz ten biedny procek dzieleniem i mnozeniem arytmetycznym !
Oto i on :
'program obslugi termometru DS18B20 kompatybilnym z DS1822
'uwagi i komentarze prosze mailem mariuszk(_at_)altkom.com.pl
'Mariusz Ksiezak
Config 1wire = P1.0 'konfiguracja magistrali 1wire
Config Lcd = 16 * 2 'konfiguracja wyswietlacza
Deflcdchar 1 , 4 , 10 , 4 , 32 , 32 , 32 , 32 , 32 'znak stopnia
Dim T1 As Single
Dim T2 As Single
Dim B1 As Byte , B2 As Byte , R As Byte
Dim Tmp As String * 6
Dim Znak As String * 1
R = &HFF
Declare Sub 1wr 'podprogram resetujacy magistrale 1w
Cursor Off
Cls
Do
1wr 'podprogram 1wr
1wwrite &HCC 'komenda skip ROM
1wwrite &H44 'komenda convert T
Waitms 500
Waitms 500
1wr 'podprogram 1wr
1wwrite &HCC 'komenda skip ROM
1wwrite &HBE 'komenda read
Waitms 500
Waitms 500
B1 = 1wread() 'odczyt z termometru
B2 = 1wread()
1wr 'podprogram 1wr
If B2 >= 248 Then 'w przypadku temperatur ujemnych
B1 = R - B1 'Od 255 Odejmujemy B1
B2 = R - B2 'od 255 odejmujemy B2
Znak = "-"
Else
Znak = "+"
End If
T1 = B1 / 16 'Przesuniecie w pawo o 4 bajty
T2 = B2 * 16 'przesuniecie w lewo o 4 bajty
T1 = T1 + T2
Tmp = Fusing(t1 , ###.&&)
Lcd Znak ; Tmp ; Chr(1) ; "C "
Waitms 250
Loop
Sub 1wr 'podprogram resetujacy magistrale
1wreset
End Sub
Dopiero zaczynam programować w bascomie i nie wiem co to przesunięcie << i >>. Program ściągłem z elektrody i postanowiłem w nim nic nie ruszać bo mierzy fajnie.
Ok.Sprobuj tak
Dim minuta As Byte
Dim sekunda As Byte
Dim T1 As Single
Dim T2 As Single
Dim B1 As Byte , B2 As Byte , R As Byte
Dim Tmp As String * 6
Dim Znak As String * 1
R = &HFF
Declare Sub 1wr 'podprogram resetujacy magistrale 1w
Cursor Off
Cls
Do
1wr 'podprogram 1wr
1wwrite &HCC 'komenda skip ROM
1wwrite &H44 'komenda convert T
Waitms 250
Waitms 250
1wr 'podprogram 1wr
1wwrite &HCC 'komenda skip ROM
1wwrite &HBE 'komenda read
B1 = 1wread() 'odczyt z termometru
B2 = 1wread()
1wr 'podprogram 1wr
If B2 >= 248 Then 'w przypadku temperatur ujemnych
B1 = R - B1 'Od 255 Odejmujemy B1
B2 = R - B2 'od 255 odejmujemy B2
Znak = "-"
Else
Znak = "+"
End If
T1 = B1 / 16 'Przesuniecie w pawo o 4 bajty
T2 = B2 * 16 'przesuniecie w lewo o 4 bajty
T1 = T1 + T2
Waitms 500
sekunda=sekunda+1
if sekunda==60 Then
sekunda==0
minuta=minuta+1
End If
'tutaj wyswietlic na lcd godzine i sekunde'
Loop
Sub 1wr 'podprogram resetujacy magistrale
1wreset
End Sub
Zaznaczam ze moga byc bledy skladniowe bo nie znam sie na basicu w kazdym razie podalem ci idee.Jak wyswietlic wynik na lcd tez nie wiem.Troche to na pale ale jesli sam pomiar chodzi to to tez powinno.Sprawdz czy jest cos takiego jak przesuniecie bitowe bo naprawde powinno sie je stosowac a wydaje mi sie ze powinno byc bo to w koncu jezyk wysokiego poziomu.
No jesli korzystasz z przerwan timera to ok ja bym od razu tak zrobil ale niestety dla mnie basic to same krzaczki a ty mowiles za dopiero zaczyanasz wiec tak jest najprosciej.Ja nie wiem czy to tutaj jest ale robi sie tak ze procedura od przerwania od timera zwieksza jakas zmienna i jesli odliczy ustalony odcinek czasowy to sie ja zeruje i zwieksza nastepna wieksza wage.A moze napisz co ci nie chodzi ? Przstaje czytac temp czy jakies krzaki na wyniku czasu wyskakuja ?
A jak odlaczysz czujnik i podlaczysz z powrotem.Tzn nie musisz fizycznie go odlaczac a po prostu zewrzyj linie danych z masa.Blad wyglada co najmniej dziwnie.A co z tym wynikiem temp ? Wyskakuja krzaki czy np 85 stopni i nic wiecej ?
Do rangera :
Wpisałem twoj program do procka , podłaczyłem i nic ...
dalej 85oC. Co mogę jeszcze źle robić...
Dołączam mój schemat podłaczenie termometru do procka...
Aha jak linia nie jest podciągnięta do plusa przez opór to temperatura wynosi 0oC.
A ile na wynosic skoro 1-Wire to magistrala OC ? Po prostu przychodza same 0 i tyle.Problem z tym poamirem jest faktycznie dziwny biorac pod uwage ze osobno dzialaja a razem nie.Niestety podczas pisania programu w bascomie nie bardzo jest jak to zdiagnozowac a procki,wierzcie mi,wyprawiaja roooozne cuda .Pozdrowienia.
To normalne ze DS z zegarme sie wzajemnie chrzania...
Protokol 1wire jest oparty o czas!!! I musi miec bardzo dokladnie zachowane uzaleznienia czasowe. I stad sie bierze wzajemnie zaklocanie - czas chce sie dokladnie odmierzac to procek musi to robic ciagle, ale nie moze bo musi sie z dallasem komunikowac.
Sprobuj zrobic tak, ze najpierw wysylasz do dallasa rozkaz zeby zainicjowal pomiar, a odczyt zrob po jakies sekundzie.
Oczywiscie w miedzyczasie musisz wykonywac dalej program glowny (i przerwania zeby odmierzyc czas).
Wszystko byłoby fajnie jak bym wiedział jak sie za to zabrać.
Czytałem troche na ten temat w archiwalnych numerach Elektroniki ale tam jest opisany sposób odczytu na podstawie 1820 a na tym forum przeczytałem , że ds18b20 obsługuje sie troszke inaczej....
Z tym zasilaniem DSa to sie robi jakoś tak, że pin plusa zwiera się z masą a do 1wire podłącza się tranzystor npn tak żeby emiter był do 1wire colektor do +5V a baza do którejś nóżki procesora. I na tą nóżkę podaje sie napięcie w czasie kiedy z i do DS nie wysyła się żadnych kombinacji. Ale stwierdziłem, że nie będe sie w takie coś bawił i podłączyłem czujnik kablem A-V i wygląda jakby był podłączony dwoma żyłami
Wiec pewnie siada ci napiecie na czujniku podczas pracy timera.Tylko w taki sposob jestem w stanie to wyjasnic nie znajac dokladnej budowy tych funkcji do 1-Wire i timera.Podlacz normalnie zasilenie 5 V do czujnika i zobacz czy ci bedzie chodzic w taki sposob.Bez zadnego tranzystora po prostu trzeci kabel do zasilania.
Witam,
czy nie zapomniałeś zadeklarować w swoim programie portu 1wire?
Config 1wire = P1.1 ( tutaj twój port)
W twoim zamieszczonym wyżej kodzie nie ma tego, a być powinno.
Dziwią mnie także wasze problemy z czasem, ponadto magistrala I2c (zegar PCF) musi koniecznie być podciągnięta do plusa przez rezystory np. 10 k bo program stanie Ci w tym miejscu i mówiąc prosto "wyłoży się"
zmienne t1 i t2 dałeś jaki single?
do wyliczenia temperatury z dallasa nie trzeba używać liczby zmiennoprzecinkowej...co najwyżej integer.
Poza tym :
resetuj magistralę 1wire zawsze w procedurze odczytu !!!!!
zrobiłeś błąd:
Sub 1wr
1wreset
End Sub
kompilator zgubi się w tym miejscu, wszystko co dotyczy danego wejścia 1wire powinno odbywać się w obrębie jednej procedury, zresztą po co tworzyć "sub 1wr " tylko po to aby tam wpisać "1wreset"
to bez sensu..
Linia 1wire powinna być podciągnieta rezystorem do plusa ( ja stosuję od 1 do 2,2 k)
napisz mi co chcesz osiągnąć a podeśle tu sprawdzony kod
bo te wasze ( lekko mówiąc pomysły rozweseliły mnie trochę)
Pozdrawiam
witam
Rozweseliło mnie to , że tak naprawdę "Ranger" nie wyjaśnił dokładnie co i jak mu się pierdzieli.
Najzwyczajniej w świecie źle połączył dwa kody i wyszła mu jajecznica( bez urazy)
Jest wiele przykładów zegarków z termometrem , naprawdę cała masa.
Ale nie oto chodzi.
Wydaje mi się, że kolega "Ranger" powinien dokładniej wyjaśnić sytuację, powinien nawet wkleić lub opisać dokładniej swój program.
Dopiero wtedy można coś po zastanowieniu się i przeanalizowaniu programu doradzić. Nie chodzi tu o złamanie autorstwa jego programu, bo i tak źle działa. Ja osobiście wyprawiałe w życiu niejedne sztuczki z dallasami i nie miałem nigdy problemów z 1wire.
Czasem nie trzeba się martwić ponieważ sam kompilator wziął to na siebie.
Wymagany długi czas na konwersję można uzyskać w inny sposób, stosując jedną zmienną typu byte ( jako licznik)
można w ten sposób czytać temperaturę np. z 10 dallasów jednocześnie( warunek 3 przewody) w ciągu 1 sekundy
Moja rada. wklej tu swój soft a coś się znajdzie, mam na myśli błąd.
inaczej można zgadywać do śmierci, a na koniec okaże się że winę ponosi
"cegiełka " o której autor zapomniał powiedzieć.
pozdrawiam
witam,
skoro piszesz że czasem temperatura jest chwilowo wyświetlana poprawnie, przychodzą mi do głowy dwie rzeczy.
1. Może w procedurze/przerwaniu czasowym używasz tej samej zmiennej, w której trzymasz temperaturę...
2. Nie znam Bascom'a dlatego nie chce mi się analizować Twojego programu (sorry) więc tylko domyślam się o co może jeszcze chodzić: jak już wcześniej ktoś pisał, 1-wire jest protokołem o ścisłych zależnościach czasowych, więc zarówno wysyłając jak i odbierając pojedynczy bit musisz te zależności zachować. Jeśli np. przy wysyłaniu logicznej 1 ustawisz na linii "0", to musisz po max 15us ustawić "1". Jeśli podczas odmierzania tego czasu wywoła się przerwanie zegarowe-spóźnisz się i DS odczyta logiczne "0". To samo dotyczy odczytu. Mając tylko jedno źródło przerwania, sprawa jest prosta. Przed wysłaniem/odczytaniem każdego bitu sprawdź, czy masz wystarczająco dużo czasu do nadejścia tego przerwania (możesz przecież odczytać aktualną wartość timera).
Drugim rozwiązaniem jest na ten czas blokować przerwania, ale jeśli to ma być zegarek, to to rozwiązanie nie wchodzi w grę.