DS18B20 + Bascom - dziwny wynik pomiaru temperatury

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
Denar
-
Posty: 18
Rejestracja: 13 sty 2013, 14:12
Lokalizacja: Wlkp

DS18B20 + Bascom - dziwny wynik pomiaru temperatury

Post autor: Denar » 28 sty 2013, 12:06

Witam.
Przeszukałem wiele wątków i przykładowych programów ale nie mogę znaleźć przyczyny mojego problemu. Próbuję uruchomić prosty termometr na Atmega32 (płytka testowa) z wykorzystaniem czujnika DS18B20. Komunikacja po 1-Wire. Poniżej kod źródłowy:

Kod: Zaznacz cały

Config Lcdpin = Pin , Rs = Porta.0 , E = Porta.1 , Db4 = Porta.2 , Db5 = Porta.3 , Db6 = Porta.4 , Db7 = Porta.5
Config Lcd = 16 * 2
Config 1wire = Pinb.0

Dim Bd(9) As Byte
Cursor Off
Dim T As Integer
Dim Ulamek As Integer


Cls

Do
Gosub Pomiar

Locate 1 , 1
Lcd T ; "." ; Ulamek

Loop

End

Pomiar:

1wreset
1wwrite &HCC
1wwrite &H44

Waitms 2000

1wreset
1wwrite &HCC
1wwrite &HBE

Bd(1) = 1wread(9)
1wreset
T = Makeint(bd(1) , Bd(2))
T = T * 10
T = T / 16

Ulamek = T Mod 10
T = T / 10
Return
Jeśli kod jest dobry to być może rozdzielczość czujnika wynosi 12 bit-ów, a program odczytuje tylko 9 ale nie mam pojęcia jak zmienić jego rozdzielczość. Wyświetlacz pokazuje różne wartośći (typu: "-115.-3") i reaguje na zmianę temperatury.

Awatar użytkownika
c4r0
Moderator
Posty: 2150
Rejestracja: 13 kwie 2004, 19:56
Lokalizacja: z lasu
Kontakt:

Post autor: c4r0 » 28 sty 2013, 18:18

Jeśli masz inne ustawienia rozdzielczości to na pewno nie będzie to dobrze działać. A czytałeś notę katalogową tego czujnika? Tam jest napisane jak ustawić rozdzielczość i jak zapisać ustawienia w pamięci czujnika. Jakby co to możesz też rozdzielczość ustawić sobie moim programem, jak zbudujesz ten prosty interface:
http://c4r0.elektroda.eu/_hv/index.php? ... b20&lang=1

Denar
-
Posty: 18
Rejestracja: 13 sty 2013, 14:12
Lokalizacja: Wlkp

Post autor: Denar » 28 sty 2013, 21:00

Zmieniłem rozdzielczość komendą "&H4E" na wartość 31 (9 bit) ale nic mi to nie pomogło. Czy posiada ktoś w swoich zasobach kod z działającym programem dla DS18B20 na bascom? Będę mógł wykluczyć błąd programowy i szukać przyczyny w sprzęcie.

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

Post autor: Pikczu » 28 sty 2013, 22:51

Jest taka opcja szukaj na forum to po pierwsze primo.
Po drugie primo tu jest mój kod który jest w dziale DIY
https://forum.elportal.pl/viewtopic.php?t=9910

Kod: Zaznacz cały

'$sim
'*******************************************************************************
 '------------------------------ATmega8-----------------------------------------
'------------------------------3xDS18b20----------------------------------------
'--------------------------2x PWM controlled FAN--------------------------------
'-------------------------- UART controlled ------------------------------------
'-------------------------Auto and manual mode----------------------------------
'-----------------------------Version: 2.0--------------------------------------
'-------------------------- Flash used 66%--------------------------------------
'------------------------By Pawel L. aka Pikczu---------------------------------
'--------------------------------2010-------------------------------------------
'*******************************************************************************
'DALLAS DS18B20 ROM and scratchpad commands''''''''''''''''''''''''''
'1wwrite....
'&H 33 read rom - single sensor
'&H 55 match rom, followed by 64 bits
'&H CC  skip rom
'&H EC  alarm search  - ongoining alarm >TH <TL
'&H BE  read scratchpad
'&H 44  convert T
'*******************************************************************************
'*******************************************************************************

$prog &HFF , &H3F , &HD9 , &H00                             ' generated. Take care that the chip supports all fuse bytes.
$regfile = "m8def.DAT"                                      'uc type
$crystal = 11059200                                         'crystal frequency
$baud = 9600
Config Serialin = Buffered , Size = 20
'Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Config Portd.1 = Output                                     'TX
Config Portd.0 = Input                                      'RX

Config Portd.6 = Input                                      'PUSHBUTTON
Portd.6 = 1                                                 'PULL UP
Config 1wire = Portd.2                                      '1Wire
Config Portd.7 = Output                                     'BUZZER
Portd.7 = 0                                                 'initial status
Config Portb.0 = Output                                     'STATUS LED
Portb.0 = 0                                                 'initial status
Config Portb.1 = Output                                     'oc1a
Config Portb.2 = Output                                     'oc1b

'*******************************************************************************
'****************************Variables*****************************************
Dim B As Byte                                               'beep
Dim Index As Byte                                           'index
Dim Ile As Byte                                             'How many ds sensor found on 1 wire bus
Dim I1(2) As Byte                                           'Array for 2 bytes read from DS sensor
Dim I2(2) As Byte                                           'Array for 2 bytes read from DS sensor
Dim I3(2) As Byte                                           'Array for 2 bytes read from DS sensor
Dim Dsx(8) As Byte                                          'Array for 8 bytes read from DS during registration
Dim Ds1(8) As Byte                                          'Array for 8 bytes from Ds 1
Dim Eds1(8)as Eram Byte At &H10                             'Space in eeprom  to write 1 ds data
Dim Ds2(8) As Byte                                          'Array for 8 bytes from Ds 2
Dim Eds2(8) As Eram Byte At &H20                            'Space in eeprom  to write  2 ds data
Dim Ds3(8) As Byte                                          'Array for 8 bytes from Ds 3
Dim Eds3(8) As Eram Byte At &H30                            'Space in eeprom  to write 3 ds data
Dim Ds_y As Byte                                            'used just for registering ds
Dim Temp1 As Integer                                        'variable to keep value temp1
Dim Temp_1 As Byte
Dim Temp2 As Integer                                        'variable to keep value temp2
Dim Temp_2 As Byte
Dim Temp3 As Integer                                        'variable to keep value temp3
Dim Temp_3 As Byte
Dim T_array(2) As Byte                                      'master and slave temperature array
Dim T_a_m As Byte                                           'Temp array max value
Dim Speed1 As Byte                                          'PWM variable
Dim Speed2 As Byte                                          'PWM variable
Dim Mod_e As Bit                                            'variable for auto/manual mode
Dim Czas As Word                                            'variable for counting time
Dim Czas2 As Byte                                           'variable counting time for flash and beep
Dim H1 As Byte                                              'variable
Dim H2 As Byte                                              'variable
Dim Flag0 As Bit                                            'Flag for timer 0
Dim Flag1 As Bit                                            'flag
Dim Flag2 As Bit                                            'flag temp changed
Dim Serial_flag As Byte                                     'flag set if char received from serial
Dim Y As Single
Dim Z As Single


'*******************************************************************************
'*******************************************************************************
Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1
Enable Interrupts
Enable Oc1a
Enable Oc1b
Config Timer0 = Timer , Prescale = 1024
Config Timer2 = Timer , Async = Off , Prescale = 1024
On Timer2 Timer2_isr                                        'interrupt timer2 for  flash and beep

'*******************************************************************************
'*******************************************************************************
Wait 1
Print "Restart"
Wait 1

Debounce Pind.6 , 0 , Zapisz , Sub                          'register DS sensors
Wait 1                                                      '
Ile = 1wirecount()                                          'ile czujnków w ukladzie
Wait 1                                                      'short delay                                             '
Enable Timer2
Flag1 = 0                                                   'flag set to 0 just in case
For B = 1 To Ile                                            'now depend how many sensors flash and beep
Start Timer2                                                'now start timer2 just to count delay time
Gosub Flash                                                 'jump to flash
Gosub Beep                                                  'jump to beep
Bitwait Flag1 , Set                                         'if flag set timer2 counted delay (line 318)
Czas2 = 0                                                   'reset czas2

Next B
Stop Timer2                                                 'now stop timer2
     Czas2 = 0                                              'reset czas2 variable
Disable Timer2
'*************************Read from Eeprom *************************************
'*******************************************************************************
For Index = 1 To 8
    Ds1(index) = Eds1(index)                                'read numbers from eeprom for ds sensors after power up
    Ds2(index) = Eds2(index)                                'read numbers from eeprom for ds sensors after power up
    Ds3(index) = Eds3(index)                                'read numbers from eeprom for ds sensors after power up
Next Index
     Index = 0
'*******************************************************************************
'After power Up first reading will be 85 degrees, is necessarily to convert temp
'*************konwersja temp dla wszystkich dsow********************************
1wreset
1wwrite &HCC                                                'skip all
1wwrite &H44
'*******************************************************************************
'*******************************************************************************
Pwm1a = 255                                                 'set fan speed to max just to test it
Pwm1b = 255                                                 'set fan speed to max just to test it
Wait 2
Pwm1a = 0
Pwm1b = 0




'***************************Ustawienie Timera0**********************************
Load Timer0 , 216
On Ovf0 Timer0_isr
Enable Timer0
'*******************************************************************************
'****************************Poczatek Petli*************************************
Czas = 0
Do

If Czas >= 100 Then

   Disable Timer0

   1wreset
   1wwrite &H55
   1wwrite Ds1(1) , 8                                       'sending address of first ds sensor
   1wwrite &HBE
   I1(1) = 1wread(2)


   1wreset
   1wwrite &H55
   1wwrite Ds2(1) , 8                                       'sending address of second ds sensor
   1wwrite &HBE
   I2(1) = 1wread(2)

   1wreset
   1wwrite &H55
  1wwrite Ds3(1) , 8                                        'sending address of third ds sensor
   1wwrite &HBE
   I3(1) = 1wread(2)


   Temp1 = I1(2)                                            'Most significant byte of temp
   Shift Temp1 , Left , 8                                   'shift left
   Temp1 = Temp1 + I1(1)
   Shift Temp1 , Right , 4

   Temp2 = I2(2)                                            'Most significant byte of temp
   Shift Temp2 , Left , 8                                   'shift left
   Temp2 = Temp2 + I2(1)
   Shift Temp2 , Right , 4

   Temp3 = I3(2)                                            'Most significant byte of temp
   Shift Temp3 , Left , 8                                   'shift left
   Temp3 = Temp3 + I3(1)
   Shift Temp3 , Right , 4
'  ****konwersja temp dla wszystkich dsow**

   1wreset
   1wwrite &HCC                                             'skip all
   1wwrite &H44

   Czas = 0
   Enable Timer0                                            'all DS do covert T
   Gosub Flash
End If                                                      'end if czas>=100 odczyt temperatury z ds

If Temp_1 <> Temp1 Or Temp_2 <> Temp2 Or Temp_3 <> Temp3 Then
Temp_1 = Temp1
T_array(1) = Temp1
       Temp_2 = Temp2
       T_array(2) = Temp2
          Temp_3 = Temp3
                 Print "Master T= " ; Temp_2 ; "C " ; "Slave T= " ; Temp_1 ; "C " ; "Trafo T= " ; Temp_3 ; "C"
Set Flag2
End If



If Mod_e = 0 Then                                           'mode = Auto

         If Flag2 = 1 Then                                  'if flag2 =1 new temperature value
         T_a_m = Max(t_array(1))                            'pick up from array max value of temp
         Y = 8.75 * T_a_m                                   ' do maths
         Y = Y - 182.5
        ' Speed1 = Abs(y)
          Speed1 = Y
                 If T_a_m <= 30 Then                        'if temperature array max value smaller than 30 then
                 Speed1 = 0                                 'fan speed = 0
                 End If                                     '
                     If T_a_m >= 50 Then                    'if temperature array max value greater or equal 50 then
                        Speed1 = 255
                     End If
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
          Z = 7 * Temp_3                                    'same as above but just for small fan and internal temp value
         Z = Z - 95
          Speed2 = Z
          If Temp_3 <= 25 Then
          Speed2 = 0
          End If
              If Temp_3 >= 50 Then
                 Speed2 = 255
              End If

         Print "Radiator Fan=" ; Speed1

         Print "Case Fan=" ; Speed2
         Reset Flag2
         Pwm1a = Speed1
         Pwm1b = Speed2
         End If
'Pwm1a = Speed1
'Pwm1b = Speed2
End If


Serial_flag = Ischarwaiting()                               'if some char in buffer then set serialflag

If Serial_flag = 1 Then                                     '
   Index = Inkey()                                          'copy char from buffer to index
         If Index = 097 Or Index = 065 Then                 ' if char = a or A
            Print "MODE:"auto ""                            'print in terminal window mode was change to auto
            Temp_1 = Temp1
            Temp_2 = Temp2
            Temp_3 = Temp3
            Print "Slave T= " ; Temp_1 ; "C " ; "Master T= " ; Temp_2 ; "C " ; "Internal T= " ; Temp_3 ; "C"
           Reset Mod_e                                      'set mode flag to 0
           Set Flag2
         End If

             If Index = 109 Or Index = 077 Then
             Print "MODE:"manual ""
             Set Mod_e
             Temp_1 = Temp1
             Temp_2 = Temp2
             Temp_3 = Temp3
             Print "Slave T= " ; Temp_1 ; "C " ; "Master T= " ; Temp_2 ; "C " ; "Internal T= " ; Temp_3 ; "C"
             Input "Input Speed value for radiator Fan=" , Speed1

             If Speed1 < 80 Then
             Speed1 = 0
             End If
             If Speed1 > 255 Then
             Speed1 = 255
             End If
                Pwm1a = Speed1
                Input "Input Speed Value for Case Fan=" , Speed2
                 If Speed2 < 80 Then
             Speed2 = 0
             End If
             If Speed2 >= 255 Then
             Speed2 = 255
             End If
                      Pwm1b = Speed2

             End If
Clear Serialin
End If

Enable Timer0
Loop

End
'*******************************************************************************
'*****************************SUBS**********************************************
'*******************************************************************************

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

'******************************Timer2_isr:**************************************
'*******************************************************************************
Timer2_isr:
Load Timer2 , 255
Incr Czas2
If Czas2 = 4 Then                                           'Acive
         Reset Portb.0
               Reset Portd.7
End If

If Czas2 >= 16 Then                                         'not active
   Flag1 = 1
End If

Return

'**********************************FlashBeep************************************
'*******************************************************************************

Fb:                                                         'Flash beep
Enable Timer2

Flag1 = 0                                                   'reset flag
Toggle Portd.7                                              'change to opposite level
Toggle Portb.0                                              'change to opposite level
Bitwait Flag1 , Set                                         'wait for confirmation bit from timer2
Czas2 = 0                                                   'set to 0 time counted by timer2

Return
'********************************BEEP*******************************************
'*******************************************************************************
Beep:
Flag1 = 0
Toggle Portd.7
Return
'********************************FLASH******************************************
'*******************************************************************************
Flash:
Flag1 = 0
Toggle Portb.0

Return
'********************************ZAPISZ*****************************************
'*******************************************************************************
Zapisz:
Czas = 0                                                    'wyzerownaie licznika czasu od timera0
Gosub Fb                                                    'skocz do flash beep
Print "Rejstracja"                                          '  wyswietla w terminalu
Disable Interrupts                                          'wylacz przerwania
Ds_y = 0                                                    'wyzeroj zmienna ilosc czojnikow ds

Do                                                          'poczatek petli rejstracyjnej
Dsx(1) = 1wsearchfirst()                                    'szukaj ds na magistrali
If Err = 0 Then                                             'jesli znalazl ds-a
   Incr Ds_y                                                'zwieksz ds_y o 1
        Select Case Ds_y:                                   'w zaleznosci ktory to ds
   Case 1:                                                  'pierwszy ds
     For Index = 1 To 8                                     'zapisz jego dane do eeprom
     Eds1(index) = Dsx(index)
     Next Index                                             'i tak 8 razy
     Print "Registered DS1 as Master "                      'no i potwierdz
           Enable Interrupts                                'wlacz przerwania
           Gosub Fb                                         'skocz do flash beep
           Disable Timer2                                   'juz po to wylacz tiemr 2
           Enable Timer0                                    'Wlacz timer0
        Bitwait Flag0 , Set                                 'czekaj na flage od timera 0
        Disable Timer0                                      'wy³acz timer0
       Disable Interrupts                                   'wylacz przerwania
   Czas = 0                                                 'wyzerownaie licznika czasu od timera0
   Case 2:                                                  'dla ds-a 2
     For Index = 1 To 8                                     'zapisz jego dane do eeprom
     Eds2(index) = Dsx(index)
     Next Index                                             'i tak 8 razy
     Print "Registered DS2 as Slave "
           Enable Interrupts                                'wlacz przerwania
           Gosub Fb                                         'skocz do flash beep
           Gosub Fb                                         'skocz do flash beep
           Disable Timer2                                   'juz po to wylacz timer 2
           Enable Timer0
        Bitwait Flag0 , Set                                 'czekaj na flage od timera 0
        Disable Timer0                                      'wylacz timer0
        Disable Interrupts                                  'wylacz przerwania
        Czas = 0                                            'wyzerownaie licznika czasu od timera0
  Case 3:                                                   'dla ds-a 3
     For Index = 1 To 8                                     'zapisz jego dane do eeprom
     Eds3(index) = Dsx(index)
     Next Index                                             'i tak 8 razy
     Print "Registered DS3 as internal  "                   'no i potwierdz
           Enable Interrupts                                'wlacz przerwania
           Gosub Fb                                         'skocz do flash beep
           Gosub Fb                                         'skocz do flash beep
           Gosub Fb                                         'skocz do flash beep
           Disable Timer2
           Enable Timer0                                    'juz po to wylacz timer 2
           Bitwait Flag0 , Set                              'czaekja na flage od timera 0
           Disable Timer0                                   'wylacz timer0
           Disable Interrupts                               'wylacz przerwania
            Czas = 0                                        'wyzerownaie licznika czasu od timera0
   End Select                                               'koniec wyboru ds-ow
End If                                                      'koniec warunklu
Loop Until Ds_y = 3                                         'koniec petli do 3-ech
Enable Interrupts                                           'wlacz przerwania
Return                                                      'powrot
'*******************************************************************************
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
'Y = 8.75 * X -182.5    range from 30 up to 50 degree
'y=predkosc
'x= temp

'Y = 7 * x-95   range from 25 up to 50

'****************************************************************************** 

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

Post autor: Pikczu » 29 sty 2013, 22:37

Pierwsza sprawa twój kod działa dobrze.
Do odczytania temperatury z JEDNEGO czujnik an linii 1Wire wystarczy odczytać tylko dwa pierwsze bajty a reszta jest nie potrzebna do uzyskania temperatury.
czyli wystarczy zrobić :
Bd(1) = 1wread(2) ' tylko dwa bajty z informacją o temp.
tablica Bd(9) -nie musi mieć 9 bajtów tylko może mieć dwa
Dim Bd(2) As Byte
Druga sprawa dziwne wartości pokażą się jeśli nie będziesz miał rezystora 4.7k jako pull up do +5V na magistrali 1Wire.

Ze zmianą rozdzielczości sprawa jest prosta trzeba odczytać 5 bajt i zmienić bity 6 i 7
najpierw odczytujesz za pomocą komendy [&H33] zmieniasz bity w bajcie 5 i zapisujesz za pomocą komendy write [&H4E] jeśli się nie mylę.
Załączniki
DS18B20 memory map1.jpg
DS18B20 memory map2.jpg
DS18B20 memory map2.jpg (39.23 KiB) Przejrzano 17469 razy
DS18B20 memory map3.jpg
Ostatnio zmieniony 30 sty 2013, 12:31 przez Pikczu, łącznie zmieniany 1 raz.

Awatar użytkownika
c4r0
Moderator
Posty: 2150
Rejestracja: 13 kwie 2004, 19:56
Lokalizacja: z lasu
Kontakt:

Post autor: c4r0 » 29 sty 2013, 23:05

Pikczu pisze:dwa pierwsze byte-y
Mamy takie słowo w naszym języku jak bajt: http://www.sjp.pl/bajt A jeśli go nie lubisz to zamiast dorabiać jakieś -y lepiej wszystko pisz po angielsku :)

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

Post autor: Pikczu » 30 sty 2013, 12:29

Szczegół i drobnostka ale jak tak bardzo szczypie Cię to w oczy to już zmieniam.

Awatar użytkownika
c4r0
Moderator
Posty: 2150
Rejestracja: 13 kwie 2004, 19:56
Lokalizacja: z lasu
Kontakt:

Post autor: c4r0 » 31 sty 2013, 18:32

Szczegół i zasadniczo się nie lubię czepiać, ale ten akurat szczegół jakoś wyjątkowo mnie szczypie, nie wiem czemu :P Dzięki za zmianę.

Denar
-
Posty: 18
Rejestracja: 13 sty 2013, 14:12
Lokalizacja: Wlkp

Post autor: Denar » 06 maja 2013, 17:50

Witam po dłuższej przerwie. Po wpisaniu i uruchomieniu kilku programów (prawidłowych na 100%) dochodzę do wniosku, że probem polega na błędnym kompilowaniu bądź innym problemie z software. Również w innych programach czy poleceniach wychodzą różne nieprzewidziane krzaczki lub brak działania. Dla przykładu podam prosty programik, który miał w zamiarze wyświetlać cyfry na 7-mio segmentowym LED. Uszczupliłem polecenia to tego stopnia, żeby wykluczyć błędy w pętlach, odczytów przycisków ect do niezbędnego minimum. Oto najprostrza forma, a jednak nie działa:

Config Portb = 255
Portb = &B11111111
EEDR = 5
Portb = Lookup (EEDR , Tabela)
Tabela:
Data 192 , 249 , 164 , 176 , 153 , 146 , 130 , 248 , 128 , 144

Powinno (tylko dla przykładu) wyświetlić "5", mimo to nic się nie wyświetla. Błąd połączenia wykluczam na 100%. Przy innych wartościach &Bxxxxxxxx ładnie pokazuje.
Więc osobiście stawiam na problem czysto software-owy. Co o tym sądzicie?
Pozdrawiam

29DR194
-
Posty: 1
Rejestracja: 07 maja 2013, 10:39
Lokalizacja: Dublin

Post autor: 29DR194 » 07 maja 2013, 10:44

Twój program działa tylko mu nie pozwalasz skończyć
Mylisz się co do tego co powinien wyświetlić nie 5 a 146
Program działa tak jak jest napisany.
Nie piszesz starannie swoich programów i dlatego cierpisz.
wystarczy dodać jedną linie kodu aby przeszedł dalej i wyświetlił wartość.
NOP -no operation

Kod: Zaznacz cały

$Regfile="2313def.dat"
$Crystal=4000000
$hwstack=40
$swstack=16
$framesize=32

Config Portb = 255
Portb = &B11111111

EEDR = 5  'index

portb= Lookup(EEDR, Tabela)
nop



Tabela:
Data 192 , 249 , 164 , 176 , 153 , 146 , 130 , 248 , 128 , 144
'     0   , 1   , 2  , 3   , 4    , 5    , 6  , 7,    8 ,   9    INDEX


PS To ja pikczu tylko zablokowałem sobie stare konto.

Denar
-
Posty: 18
Rejestracja: 13 sty 2013, 14:12
Lokalizacja: Wlkp

Post autor: Denar » 07 maja 2013, 17:35

29DR194, dzięki za podpowiedź. Nie mniej dodanie NOP nic nie pomogło :???:

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

Post autor: Pikczu » 07 maja 2013, 20:46

Udało mi się odblokować konto. Wracając do tematu coś źle robisz o czym nie piszesz.
Sprawdź to na symulatorze.

Ps: dodaj END po nop

fourup
-
Posty: 4
Rejestracja: 26 lut 2013, 16:02
Lokalizacja: Kraków
Kontakt:

Post autor: fourup » 16 maja 2013, 13:12

Trochę starawy ten kotlet, ale odgrzeję go jednak...

@Denar, a po co Ci oddzielanie części całkowitej od ułamkowej dla wyświetlenia wskazania?
Da się to zrobić inaczej. Może więcej kodu, ale prostsze (przynajmniej dla mnie):

Kod: Zaznacz cały

' ------------------------------------------------------------------------------
Sub Czytaj_temperature:
   1wreset                                                  'podprogram 1wr
   1wwrite &HCC
   1wwrite &H44
'   Waitms 250
'   Waitms 250
   1wreset                                                  'podprogram 1wr
   1wwrite &HCC
   1wwrite &HBE
   B1 = 1wread()
   B2 = 1wread()
   1wreset                                                  '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 , " ###.&")
   Tmp = Znak + Tmp

   If Err = 1 Then Tmp = "blad"

End Sub Czytaj_temperature
' ------------------------------------------------------------------------------
I temperaturę wyświetlam:

Kod: Zaznacz cały

   Lcd Tmp ; Chr(0) ; "C  "
gdzie Chr(0) jest zdefiniowanym wcześniej znakiem stopni (°)

Z tego kodu zawsze korzystam w swoich programach i zawsze się sprawdza. Drobne zmiany dochodzą, jeśli jest więcej niż jeden DS, ale to nie na ten wątek.
Sprawdź sobie...

Jeśli otrzymasz wskazanie +85.0 lub -0.0, i nie będzie reakcji na zmianę temperatury (np. kiedy weźmiesz DS i zaciśniesz go w dłoni), oznacza to że masz źle podłączony lub uszkodzony czujnik.
DS18B20 pokazuje +85°C kiedy ma podłączony GND i Out (brak napięcia na VCC).
Kiedy podłączysz tylko VCC i Out (brak masy) - wtedy uzyskasz odczyt +0°C
Niestety, są to układy dość czułe na odwrócenie polaryzacji zasilania. Czasem to przeżywają, ale większość przypadków kończy się śmiercią dallasa... :(
Sprawdź sobie jakie masz napięcie pomiędzy VCC i GND, ale nie na wyjściu z płytki, tylko bezpośrednio na nogach Dallasa (powinno być ok. 5V, jeśli podajesz napięcie z płytki). Jeśli napięcie jest właściwe - to musisz podmienić czujnik.

Kolejna rzecz: po co czekasz aż 2 sekundy na odczyt :?: :!: skoro maksymalny czas konwersji wynosi 750ms (w trybie 12bit), a w rozdzielczości 9bit mniej, niż 100ms.

Kod wklejony wyżej działa poprawnie nawet z wyłączonym opóźnieniem, zarówno na prockach AT8, jak i AT32.

ODPOWIEDZ