# Συζήτηση Κυκλωμάτων > Ψηφιακά Κυκλώματα > Μικροελεγκτές >  >  συνδεση με dallas18s20(ασκηση 5η)

## billtech

γεια σας και παλι....ανοιξα αυτο το τοπικ σαν μια αλλη ασκηση για τους pic.
εχω ενα dallas18s20 και προσπαθω να διαβασω την θερμοκρασια του με τον pic16f877a αλλα μου βγαζει στη οθονη παντα 85 βαθμους.και οταν το αφαιρεσω παει στους μηδεν οπως ειιναι το σωστο.αρα λογικα εχω εποικηνωνια με το θερμομετρο.εχω βαλει το προγραμμα που δεινει η microbasic αλλα παλι τιποτα.στο παραδειγμα χρησιμοποιει το ds1820.εχουν διαφορες αυτα τα δυο μεταξυ τους?
εδω εχω το κωδικα που χρησιμοποιησα.

program onewire
dim i, j1, j2 as byte
    text      as string[6]
    tmp_sign  as byte
main:
   text   = "Temp:"
   adcon1 = 255                     ' configure RA5 pin as digital I/O
   PORTA  = 255                     ' initialize porte to 255
   PORTb  =   0                     ' initialize portb to 255
   TRISA  = 255                     ' designate porte as input
   TRISb  =   0                     ' designate portb as output
   Lcd_Config(PORTB,7,6,5,4,PORTB,2,1,3) ' Lcd_Init_EP5, see Autocomplete
   LCD_Cmd(LCD_CLEAR)                    ' Clear display
   LCD_Cmd(LCD_CURSOR_OFF)               ' Turn cursor off
   lcd_out(1, 1, text)
   lcd_chr(2, 12, 223)              ' 'degree' character
   lcd_chr(2, 13, "C")

   while TRUE
     ow_reset(PORTA, 5)             ' onewire reset signal
     ow_write(PORTA, 5, $CC)        ' issue command to DS1820
     ow_write(PORTA, 5, $44)        ' issue command to DS1820
     delay_us(120)
     i = ow_reset(PORTA, 5)
     ow_write(PORTA, 5, $CC)        ' issue command to DS1820
     ow_write(PORTA, 5, $BE)        ' issue command to DS1820

     j1 = ow_read(PORTA, 5)         ' get result
     j2 = ow_read(PORTA, 5)         ' get result (assuming the temperature is positive)

     if j2 = $FF then
       tmp_sign = "-"               ' temperature sign
       j1= j1 or $FF                ' complement of two
       j1= j1 + $01
     else
       tmp_sign = "+"
     end if
     j2 = (j1 and $01) * 5          ' Get decimal value
     j1 = j1 >> 1                   ' Get temp value

     ByteToStr(j1, text)            ' whole number
     lcd_chr(2, 7, tmp_sign)
     lcd_chr(2, 8, text[1])
     lcd_chr(2, 9, text[2])
     lcd_chr(2, 10, 46)             ''.'

     ByteToStr(j2, text)            ' decimal
     lcd_chr(2, 11, text[2])

     Delay_ms(500)
   wend                             'endless loop
end.

----------


## hardcode

Αύξησε την καθυστέρηση μετα την εντολή convert $44 σε 750ms και ξαναδοκίμασε.

----------


## briko

το ds18s20 εχει 9 bit αναλυση ενω το DS18B20 εχει 12 bit αναλυση 
και εγω ειχα το ιδιο προβλημα μεχρι που εβαλα σωστα την εντολη const 
παρακατω εχω το προγραμμα που εχει και ελεγχο για συγκεκρημενη θερμοκρασια

program onewire

' Set TEMP_RESOLUTION to the corresponding resolution of your DS18x20 sensor:
'  18S20: 9  (default setting can be 9,10,11,or 12)
'  18B20: 12
const TEMP_RESOLUTION as byte = 12

dim
  j as byte
  temp as word
  temp100 as integer
  text as string[5]           ' "00.00"

sub procedure Read_Temperature()
dim buf as longint
  Ow_Reset(PORTA,5)            ' Onewire reset signal
  Ow_Write(PORTA,5,0xCC)       ' Issue command SKIP_ROM
  Ow_Write(PORTA,5,0x44)       ' Issue command CONVERT_T
  Delay_ms(400) ' *****
  Ow_Reset(PORTA,5)
  Ow_Write(PORTA,5,0xCC)       ' Issue command SKIP_ROM
  Ow_Write(PORTA,5,0xBE)       ' Issue command READ_SCRATCHPAD
  Delay_us(120)  ' *****
  j    = OW_Read(PORTA,5)      ' Get temperature LSB
  temp = OW_Read(PORTA,5)      ' Get temperature MSB

  buf = (temp * 256) + j ' *****
  buf = (buf * 100) div 16 ' *****
  temp100 = Integer(buf) ' *****

  temp = temp << 8
  temp = temp + j              ' Form the 2byte variable
end sub


sub procedure Write_Temp(dim temp2write as word)
const
  RES_SHIFT as byte = TEMP_RESOLUTION - 8            ' depends on sensor's resolution
dim
  temp_whole as byte
  temp_fraction as word
  temp_whole = temp2write >> RES_SHIFT               ' determine whole number

  text[0] =(temp_whole div 10) mod 10 + 48           ' prepare temp_whole for LCD
  text[1] = temp_whole mod 10 + 48

  temp_fraction = temp2write << (4-RES_SHIFT)        ' determine fraction
  temp_fraction = temp_fraction and 0x000F
  temp_fraction = temp_fraction * 625

  text[3] =  temp_fraction div 1000 + 48             ' prepare temp_fraction for LCD
  text[4] = (temp_fraction div 100) mod 10 + 48

  Lcd_Out(2,1,text)                                  ' display temperature
end sub

' ----Main----

main:
  TRISD = 0           ' Configure pins of PORTD as output
  text    = "00.00"
  ADCON1  = 7                 ' configure PORTA as digital I/O

  Lcd_Config(PORTB, 3, 2, 1, 0, PORTB, 4, 6, 5) ' Initialize LCD connected to PORTB
  Lcd_Cmd(LCD_CLEAR)                            ' Send command to LCD "clear display"
  Lcd_Cmd(LCD_CURSOR_OFF)                       ' Send command cursor off
  Lcd_Out(1,1,"temperature")

  while true
    Read_Temperature()
    Write_Temp(temp)
    Delay_ms(100)

    if temp100 <= 2850 then ' if room <= temp then open a rele
      PORTD = %00000001 ' Turn ON diodes on PORTB
    else PORTD = %00000000 'else close rele
    end if

  wend
end.

----------


## electroman

> Αύξησε την καθυστέρηση μετα την εντολή convert $44 σε 750ms και ξαναδοκίμασε.



Ναι συμφωνώ και εγώ. Το DS18S20 έχει conversion time 750ms. Εγώ του βάζω καθυστέρηση περίπου ένα δευτερόλεπτο έτσι για να είμαι σίγουρος.

----------


## billtech

το εκανα..και απλα αλλαξε η ενδειξη.απλα μενη η ενδειξη στο 0,0.

----------


## briko

υποθετω οτι το ds το βαζεις φυσικα στο Α5

----------


## billtech

εννοειται!!  :Smile:

----------


## briko

πηρες δηλαδη το δικο μου προγραμμα και το εβαλες στην microbasic αλλαξες το const απο 12 σε 9 και εχεις ακομα προβλημα ; (απο οτι ειπες εχεις το 18S20 με αναλυση 9digit)   δοκιμασε αν θες να βαλεις διαφορες διαφορες τιμες στο const 9-10-11-12

----------


## billtech

το εκανα μολις τωρα φιλε μου...
σε καθε τιμη βαζει αλλη τιμη στη οθονη..αλλα σταθερα ομως.
12--->10,62
11-->22,50
10-->44,κατι
9--->85

----------


## briko

σε βαζω σε txt το προγραμμα για να το κανεις copy paste

----------


## billtech

το εβαλα και αυτο τωρα...αλλα παλι τα ιδια...αφου και πριν το δικο σου copy paste το εκανα αλλα παλι τα ιδια εβγαζε.
το κυκλωμα που εκανα εγω ειναι με το ds να πηγαινει στο 7πιν και μια αντισταση στη ταση.και η οθονη απο τα ποδαρακια της Β πορτας.

----------


## briko

καταρχας θα πρεπει να εχεις στην πρωτη γραμμη του display την λεξη θερμοκρασια (οπως φαινετε και στην εικονα) αν οχι τωτε θα πρεπει να ψαξεις τις επαφες pic με display
μετα θαδεις αν εχεις τροφοδοσια στο ds και στην αντισταση R10 (5V) και στην επαφη VCC (5V)

----------


## billtech

στο Vcc  του DS εχω 5βολτ οπως και στο ακρο της αντιστασης..
στο Dq εχω 1.50βολτ και 5βολτ οποτε στελνει δεδομενα στον επεξεργαστη.
και εχω συνεχεια σταθερη θερμοκρασια στο LCD 10,62βαθμους.
και οποτε αλλαζω το const αλλαζει και αυτο.
στη πρωτη γραμμη εχω τη λεξη THERMOKRASIA
και ακριβως απο κατω εχω την θερμοκρασια..ο θεος να τη κανει..

----------


## briko

ρε μπας και ειναι καμενο το ds
(αν πασεις το ds με το δαχτυλο αλλαζει εστω και κατα κατι η ενδειξη)

----------


## billtech

οχι δεν αλλαζει...και εμενα μου περασε απο το μυαλο να σου πω την αληθεια...
αλλα οταν το αφαιρεσω απο το RA5 τοτε μου βγαζει 0 θερμοκρασια γιαυτο και ειχα αμφιβολιες..θα το δοκιμασω και θα σου πω.

----------


## billtech

μπα...
δεν εχει διαφορα...
το δοκιμασα και εβαλα αλλο..αλλα παλι τα ιδια...
κατι αλλο φταιει..και δεν ξερω τι ρε γμτ.

----------


## billtech

αυτο ειναι το κυκλωμα που εκανα...
οι τιμες ειναι σταθερες παντα...αναλογως με το const αναιβενει η πεφτει η σταθερη τιμη στη εξοδο.
που ειναι το λαθος δεν ξερω.

----------


## briko

δεν μπορω να καταλαβω τιποτε οποτε αρχιζω να λεω  διαφορα.
 μια πυθανοτητα ειναι να εχει βαλει αναποδα το Vcc με την γη (foto1).
το 85 βαθμοι που σου εβγαλε καποια στιγμη ειναι το reset του ds (foto2)
 τωρα τι αλλο μπορει να συμβαινει ? να μην ταιριαζει το δικοσου ds  (αν δεν κανω λαθος εχεις το ds18s20 ενω εγω το ds18b20) oι διαφορες τους ειναι απ'οτι λεει η microelektronica μονον στην εντολη const 9,10,11,12 bit 
εγω αλλαξα στο προγραμμα μου την εντολη const αλλα σαν αποτελεσμα επαιρνα τρελες τιμες αλλα τουλαχιστον αλλαζαν οταν επιανα με το δαχτυλο το ds και ζεστενονταν

----------


## billtech

τα ποδαρακια ειναι ιδια με τον ds18s20.
μεχρι χτες ειχα πανω μια αντισταση 10Κ.ψες την εκανα 4Κ7 και ειχα συνεχεια 15C.ενω πριν ειχα συνεχεια 10.50C.
θα χαζεψω...τι φταιει ρε γμτ..καποια λεπτομερια που δεν την βλεπουμε.

----------


## DT200

θα σου στείλω το πρόγραμμα που χρησιμοποιώ εγώ για να δοκιμάσεις.
ΠΡΟΣΟΧΗ το 18S20 θα το βάλεις στο RE2 .

edit: το πρόγραμμα τρέχει στα 8MHz




```
'program Onewire
const TEMP_RESOLUTION as byte = 9
dim
  j as byte
  temp as word
  text as string[10]            ' "000.0000`C"

sub procedure Read_Temperature()
  Ow_Reset(PORTE,2)             
  Ow_Write(PORTE,2,0xCC)       
  Ow_Write(PORTE,2,0x44)       
  Delay_us(120)

  Ow_Reset(PORTE,2)
  Ow_Write(PORTE,2,0xCC)       
  Ow_Write(PORTE,2,0xBE)      
  Delay_ms(400)

  j    = OW_Read(PORTE,2)       
  temp = OW_Read(PORTE,2)      
  temp = temp << 8
  temp = temp + j              
end sub

sub procedure Write_Temp(dim temp2write as word)
const
  RES_SHIFT as byte = TEMP_RESOLUTION - 8          
dim
  temp_whole as byte
  temp_fraction as word

  if ((temp and 0x8000) > 0) then                  
     text[0] = '-'
     temp2write = (not temp2write) + 1
  end if
  temp_whole = temp2write >> RES_SHIFT         

  if (temp_whole div 100) then
     text[0] = temp_whole div 100  + 48
  end if
  text[1] =(temp_whole div 10) mod 10 + 48         
  text[2] = temp_whole mod 10 + 48

  temp_fraction = temp2write << (4-RES_SHIFT)       
  temp_fraction = temp_fraction and 0x000F
  temp_fraction = temp_fraction * 625

  text[4] =  temp_fraction div 1000 + 48            
  text[5] = (temp_fraction div 100) mod 10 + 48
  text[6] = (temp_fraction div 10)  mod 10 + 48
  text[7] =  temp_fraction mod 10 + 48

  Lcd_Out(2,3,text)                                  
end sub


main:
  text    = "000.000000"
  text[8] = 223                                     
  text[9] = "C"                                     
  ADCON1  = 7                                        

  Lcd_Config(PORTB,3,2,1,0,PORTB,4,7,5)             
  Lcd_Cmd(LCD_CLEAR)
  Lcd_Cmd(LCD_CURSOR_OFF)
  Lcd_Out(1,1,"Temperature")                     
  while true
    Read_Temperature()
    Write_Temp(temp)
    Delay_ms(1000)
  wend
end.
```

----------


## billtech

φιλε μου DT200 βγαζει 285,0000.σταθερα ομως

----------


## DT200

αν δεν το έχεις πάρει από τον zip, πάρτο 
και κάνε ακόμα μία δοκιμή.

Υ.Γ. ελπίζω να έχεις κάνει στο PC επανεκκίνηση, πάντα βοηθάει.
       δεν κάνω πλάκα !

----------


## billtech

τα ιδια παντελακη μου,,,τα ιδια παντελη μου..
δεν αλλαζει αυτο με τιποτα

----------


## billtech

παιδια οταν κανω compile μου ολοκληρωνει την μετατροπη αλλα βγαζει και τα 3 παρακατω μυνηματα παραλληλα.τι σημαινουν?παιζουν ρολο?

14:5 H-11 Hint: Variable 'buf (Read_Temperature)' has been eliminated by optimizer onewire1.pbas

39:1 H-11 Hint: Variable 'temp_whole (Write_Temp)' has been eliminated by optimizer onewire1.pbas

40:1 H-11 Hint: Variable 'temp_fraction (Write_Temp)' has been eliminated by optimizer onewire1.pbas

ο κωδικας ειναι ο παρακατω που παλευω:

program onewire1
' Set TEMP_RESOLUTION to the corresponding resolution of your DS18x20 sensor:
' 18S20: 9 (default setting can be 9,10,11,or 12)
' 18B20: 12
const TEMP_RESOLUTION as byte = 9

dim
j as byte
temp as word
temp100 as integer
text as string[5] ' "00.00"
'------------------------------------------------------------------------------
sub procedure Read_Temperature()
dim buf as longint
Ow_Reset(PORTA,5) ' Onewire reset signal
Ow_Write(PORTA,5,0xCC) ' Issue command SKIP_ROM
Ow_Write(PORTA,5,0x44) ' Issue command CONVERT_T
Delay_ms(1000) ' *****
Ow_Reset(PORTA,5)
Ow_Write(PORTA,5,0xCC) ' Issue command SKIP_ROM
Ow_Write(PORTA,5,0xBE) ' Issue command READ_SCRATCHPAD
Delay_ms(5) ' *****
j = OW_Read(PORTA,5) ' Get temperature LSB
temp = OW_Read(PORTA,5) ' Get temperature MSB

buf = (temp * 256) + j ' *****
buf = (buf * 100) div 16 ' *****
temp100 = Integer(buf) ' *****

temp = temp << 8
temp = temp + j ' Form the 2byte variable
end sub

'------------------------------------------------------------------------------
sub procedure Write_Temp(dim temp2write as word)

const RES_SHIFT as byte = TEMP_RESOLUTION - 8 ' depends on sensor's resolution
dim
temp_whole as byte
temp_fraction as word
temp_whole = temp2write >> RES_SHIFT ' determine whole number

text[0] =(temp_whole div 10) mod 10 + 48 ' prepare temp_whole for LCD
text[1] = temp_whole mod 10 + 48

temp_fraction = temp2write << (4-RES_SHIFT) ' determine fraction
temp_fraction = temp_fraction and 0x000F
temp_fraction = temp_fraction * 625

text[3] = temp_fraction div 1000 + 48 ' prepare temp_fraction for LCD
text[4] = (temp_fraction div 100) mod 10 + 48

Lcd_Out(2,1,text) ' display temperature
end sub
'-------------------------------------------------------------------------------
' ----Main----

main:
TRISB = 0 ' Configure pins of PORTB as output
text = "00.00"
ADCON1 = 7 ' configure PORTA as digital I/O

Lcd_Config(PORTB,7,6,5,4,PORTB,2,1,3) ' Initialize LCD connected to PORTB
Lcd_Cmd(LCD_CLEAR) ' Send command to LCD "clear display"
Lcd_Cmd(LCD_CURSOR_OFF) ' Send command cursor off
Lcd_Out(1,1,"temperature")

while true
Lcd_Out(1,1,"temperature")
Read_Temperature()
Write_Temp(temp)
Delay_ms(1000)
Lcd_Cmd(LCD_CLEAR) ' Send command to LCD "clear display"


wend
end.

τι λετε?

----------


## DT200

αυτό είναι το .hex που 
παράγω εγώ και δεν βγάζει κανένα μήνυμα.
για δοκίμασε το (μην προσπαθήσεις να κάνεις 
καμία τροποποίηση , κατευθείαν προγραμματισμό)

----------


## billtech

αν μπορεις ξανα ανεβασε το αλλα τα ποδαρακια της οθονης να ειναι αυτα που χρησιμοποιω εγω..γιατι δεν μπορω να τα βαλω αλλου για τεχνικους λογους..
Lcd_Config(PORTB,7,6,5,4,PORTB,2,1,3) ' Initialize LCD connected to PORTB
σε ευχαριστω

----------


## DT200

ωχ !!! συγνώμη , το ξέχασα  :Blushing: 

μην μπερδευτείς , το θερμόμετρο στο RA5

----------


## billtech

φιλε μου το φωρτωσα και βγαζει παλι +85 βαθμους.σταθερα ομως.

----------


## DT200

σου έγραψα ένα πρόγραμμα για τον 16F628A @ 4MHz 
και είσοδο στο Pin RA1.
καλή τύχη   :Cool: 



```
program onewire

dim i, j1, j2 as byte
    text      as string[6]
    tmp_sign  as byte

main:
   CMCON=255
   text   = "Temp:"
   PORTA  = 255
   TRISA  = 255
   Lcd_Config(PORTB,3,2,1,0,PORTB,4,7,5)
   lcd_cmd(LCD_CURSOR_OFF)
   lcd_out(1, 1, text)
   lcd_chr(2, 12, 223)
   lcd_chr(2, 13, "C")

   while TRUE
     ow_reset(PORTA, 1)
     ow_write(PORTA, 1, $CC)
     ow_write(PORTA, 1, $44)
     delay_us(120)
     i = ow_reset(PORTA, 1)
     ow_write(PORTA, 1, $CC)
     ow_write(PORTA, 1, $BE)

     j1 = ow_read(PORTA, 1)
     j2 = ow_read(PORTA, 1)

     if j2 = $FF then
       tmp_sign = "-"
       j1= j1 or $FF
       j1= j1 + $01
     else
       tmp_sign = "+"
     end if
     j2 = (j1 and $01) * 5
     j1 = j1 >> 1

     ByteToStr(j1, text)
     lcd_chr(2, 7, tmp_sign)
     lcd_chr(2, 8, text[1])
     lcd_chr(2, 9, text[2])
     lcd_chr(2, 10, 46)

     ByteToStr(j2, text)
     lcd_chr(2, 11, text[2])

     Delay_ms(500)
   wend
end.
```

----------


## billtech

φιλε μου δεν δουλεψε...παλι...παλι εβγαλε 85βαθμους.
το προγραμματισα και με το δικο σου hex και με το δικο μου..με το δικο μου βγαζει 27,5βαθμους.
στο δικο μου τα 120us τα εκανα 850ms οπως λεει και το datasheet.συγκεκριμενα στο  datasheet λεει 750ms.
λοιοπν..το αφηνουμε εδω..και περιμενω τα 18b20.αν ερθει.
καλυτερα παμε στο ρολοι που με καιεει τωρα..
ευχαριστω.

----------


## briko

το delay εγω το εχω στα 50 msec και παιζει κανονικα .
δεν ειναι τοσο σημαντικο και το εβαλα 50 διοτι ειχα 2 ds και επρεπε να κανω και μια μετατροπη σε υγρασια οποτε εβγενε μεγαλος χρονος και εκει αρχισα τις αλλαγες.  Γνωμη παντος ειναι οτι εχεις καμενα τα ds και οτεν παρεις τα νεα θα εχεις αμεση ανταποκριση

----------


## billtech

μακαρι φιλε μου...
θα δειξει...
αν και χτες ηρθαν καινουρια 18s20 και εβαλα και απο αυτα και μου κανουν τα ιδια..
τωρα εκανα πριν λιγες μερες παραγγελια 18b20 να ερθουν...
να δουμε..
λεω και εγω...τοση γκατεμια?ελεος..
θα δειξει φιλε μου...

----------


## billtech

γεια σας παιδια..
εκανα αυτο εδω τελικα και φενεται να παιζει καλα...στα θετικα..πως να το κανω ομως να παιζει και στα αρνητικα?γιατι αυτο που εχει στα παραδειγματα δεν παιζει καλα..ισως να φταιει κατι αλλο αλλα δεν το νομιζω.πως να το κανω να πηγαινει στα αρνητικα?



```
program onewire_new

'For PIC18F452 this programm
' Set TEMP_RESOLUTION to the corresponding resolution of your DS18x20 sensor:
' 18S20: 9 (default setting can be 9,10,11,or 12)
' 18B20: 12
const TEMP_RESOLUTION as byte = 12

dim
j as byte
temp as word
temp100 as integer
text as string[5] ' "00.00"
'------------------------------------------------------------------------------
                            ' Read_Temperature
                            
sub procedure Read_Temperature()
dim buf as longint
Ow_Reset(PORTA,5) ' Onewire reset signal
Ow_Write(PORTA,5,0xCC) ' Issue command SKIP_ROM
Ow_Write(PORTA,5,0x44) ' Issue command CONVERT_T
Delay_ms(1000) ' *****

Ow_Reset(PORTA,5)
Ow_Write(PORTA,5,0xCC) ' Issue command SKIP_ROM
Ow_Write(PORTA,5,0xBE) ' Issue command READ_SCRATCHPAD
Delay_ms(5) ' *****

j = OW_Read(PORTA,5) ' Get temperature LSB
temp = OW_Read(PORTA,5) ' Get temperature MSB

buf = (temp * 256) + j ' *****
buf = (buf * 100) div 16 ' *****
temp100 = Integer(buf) ' *****

temp = temp << 8
temp = temp + j ' Form the 2byte variable
end sub

'------------------------------------------------------------------------------
'                         Write_Temp

sub procedure Write_Temp(dim temp2write as word)

const RES_SHIFT as byte = TEMP_RESOLUTION - 8 ' depends on sensor's resolution
dim
temp_whole as byte
temp_fraction as word
temp_whole = temp2write >> RES_SHIFT ' determine whole number

text[0] =(temp_whole div 10) mod 10 + 48 ' prepare temp_whole for LCD
text[1] = temp_whole mod 10 + 48

temp_fraction = temp2write << (4-RES_SHIFT) ' determine fraction
temp_fraction = temp_fraction and 0x000F
temp_fraction = temp_fraction * 625

text[3] = temp_fraction div 1000 + 48 ' prepare temp_fraction for LCD
text[4] = (temp_fraction div 100) mod 10 + 48

Lcd_Out(2,1,text) ' display temperature
end sub
'-------------------------------------------------------------------------------
'                           Main

main:
TRISB = 0 ' Configure pins of PORTB as output
text = "00.00"
ADCON1 = 7 ' configure PORTA as digital I/O

Lcd_Config(PORTB,7,6,5,4,PORTB,2,1,3) ' Initialize LCD connected to PORTB
Lcd_Cmd(LCD_CLEAR) ' Send command to LCD "clear display"
Lcd_Cmd(LCD_CURSOR_OFF) ' Send command cursor off
Lcd_Out(1,1,"temperature")

while true
Read_Temperature()
Write_Temp(temp)

wend
end.
```

----------


## briko

Οι  θετικές τιμές εξηγούνται με την μετατροπή των 12 bit (τελευταίων) σε δεκαδικό και πολλαπλασιασμό του με το 0,0625 (ανάλυση του ds για 12 bit ) 
Οι αρνητικές όμως δεν μπορώ να βρω πως γίνετε 
Αν υπάρχει κάποιος ας βοηθήσει και από εκεί και περά είναι εύκολο να γίνει και η σωστή ένδειξη για αρνητικές τιμές θερμοκρασίας

----------


## billtech

ε? δηλαδη?
και τωρα ακομα που δουλευει αυτο το προγραμμα προσπαθω να καταλαβω πως κανει την μετατροπη με το << δεν καταλαβα τι παιζει ακομα...θελω βοηθεια πανω σε αυτα.

----------


## BOOMER

Οι αρνητικές τιμές είναι σε "συμπλήρωμα του δύο" αν θυμάμαι από τα φοιτιτικά μου χρόνια. Οπότε για να βρούμε πόσο είναι αντιστρέφουμε το λογικό των bits και προσθέτουμε μετά 1. Μετά μετατρέπουμε κανονικά σε δεκαδικό. Ελπίζω να βοήθησα

----------


## billtech

παιδια επειδη δεν αντεχω αλλο θελω τα φωτα σας για αλλη μια φορα.
φιλε BOOMER σε ευχαριστω για την πληροφορια που μου θυμησες.
αλλα...
εχω δυο κωδικες για τον DS18B20. ο ενας δουλευει και ο αλλος οχι.
δεν μπορω να καταλαβω γιατι.θεωρητικα επρεπε να δουλεψει.
μπορειτε να μου πειτε γιατι?
ποιο κατω αναιωβαζω τους δυο κωδικες.

αυτος δουλευει:



```
program onewire_new

'For PIC18F452 this programm
' Set TEMP_RESOLUTION to the corresponding resolution of your DS18x20 sensor:
' 18S20: 9 (default setting can be 9,10,11,or 12)
' 18B20: 12
const TEMP_RESOLUTION as byte = 12

dim
j as byte
temp as word
temp100 as integer
text as string[5] ' "00.00"
'------------------------------------------------------------------------------
                            ' Read_Temperature
                            
sub procedure Read_Temperature()
dim buf as longint
Ow_Reset(PORTA,5) ' Onewire reset signal
Ow_Write(PORTA,5,$CC) ' Issue command SKIP_ROM
Ow_Write(PORTA,5,$44) ' Issue command CONVERT_T
Delay_ms(1000) ' *****

Ow_Reset(PORTA,5)
Ow_Write(PORTA,5,$CC) ' Issue command SKIP_ROM
Ow_Write(PORTA,5,$BE) ' Issue command READ_SCRATCHPAD
Delay_ms(5) ' *****

j = OW_Read(PORTA,5) ' Get temperature LSB
temp = OW_Read(PORTA,5) ' Get temperature MSB

buf = (temp * 256) + j ' *****
buf = (buf * 100) div 16 ' *****
temp100 = Integer(buf) ' *****

temp = temp << 8
temp = temp + j ' Form the 2byte variable
end sub

'------------------------------------------------------------------------------
'                         Write_Temp

sub procedure Write_Temp(dim temp2write as word)

const RES_SHIFT as byte = TEMP_RESOLUTION - 8 ' depends on sensor's resolution
dim
temp_whole as byte
temp_fraction as word
temp_whole = temp2write >> RES_SHIFT ' determine whole number

text[0] =(temp_whole div 10) mod 10 + 48 ' prepare temp_whole for LCD
text[1] = temp_whole mod 10 + 48

temp_fraction = temp2write << (4-RES_SHIFT) ' determine fraction
temp_fraction = temp_fraction and 0x000F
temp_fraction = temp_fraction * 625

text[3] = temp_fraction div 1000 + 48 ' prepare temp_fraction for LCD
text[4] = (temp_fraction div 100) mod 10 + 48

Lcd_Out(2,1,text) ' display temperature
end sub
'-------------------------------------------------------------------------------
'                           Main

main:
TRISB = 0 ' Configure pins of PORTB as output
text = "00.00"
ADCON1 = 7 ' configure PORTA as digital I/O

Lcd_Config(PORTB,7,6,5,4,PORTB,2,1,3) ' Initialize LCD connected to PORTB
Lcd_Cmd(LCD_CLEAR) ' Send command to LCD "clear display"
Lcd_Cmd(LCD_CURSOR_OFF) ' Send command cursor off
Lcd_Out(1,1,"temperature")
Lcd_Out(2,7,"C")
Lcd_chr(2,6,223)

while true
Read_Temperature()
Write_Temp(temp)

wend
end.
```

----------


## billtech

αυτος δεν μου δουλευει:



```
program temp

dim i, j1, j2 as byte
    text      as string[6]
    tmp_sign  as byte

main:

   text   = "Temp:"
   adcon1 = 255                     ' configure RA5 pin as digital I/O
   PORTA  = 255                     ' initialize porte to 255
   PORTb  =   0                     ' initialize portb to 255
   TRISA  = 255                     ' designate porte as input
   TRISb  =   0                     ' designate portb as output
   Lcd_Config(PORTB,7,6,5,4,PORTB,2,1,3)
   lcd_cmd(LCD_CURSOR_OFF)
   lcd_out(1, 1, text)
   lcd_chr(2, 12, 223)              ' 'degree' character
   lcd_chr(2, 13, "C")

   while TRUE
     ow_reset(PORTA, 5)             ' onewire reset signal
     ow_write(PORTA, 5, $CC)        ' issue command to DS1820
     ow_write(PORTA, 5, $44)        ' issue command to DS1820
     delay_us(120)
     i = ow_reset(PORTA, 5)
     ow_write(PORTA, 5, $CC)        ' issue command to DS1820
     ow_write(PORTA, 5, $BE)        ' issue command to DS1820

     j1 = ow_read(PORTA, 5)         ' get result
     j2 = ow_read(PORTA, 5)         ' get result (assuming the temperature is positive)
'********************************************************************************************
     if j2 = $FF then
       tmp_sign = "-"               ' temperature sign
       j1= j1 or $FF                ' complement of two
       j1= j1 + $01
     else
       tmp_sign = "+"
     end if
     j2 = (j1 and $01) * 5          ' Get decimal value
     j1 = j1 >> 1                   ' Get temp value

     ByteToStr(j1, text)            ' whole number
     lcd_chr(2, 7, tmp_sign)
     lcd_chr(2, 8, text[1])
     lcd_chr(2, 9, text[2])
     lcd_chr(2, 10, 46)             ''.'

     ByteToStr(j2, text)            ' decimal
     lcd_chr(2, 11, text[2])
'*******************************************************************************************
     Delay_ms(500)
   wend                             'endless loop
end.
```

----------


## briko

> Οι αρνητικές τιμές είναι σε "συμπλήρωμα του δύο" αν θυμάμαι από τα φοιτιτικά μου χρόνια. Οπότε για να βρούμε πόσο είναι αντιστρέφουμε το λογικό των bits και προσθέτουμε μετά 1. Μετά μετατρέπουμε κανονικά σε δεκαδικό. Ελπίζω να βοήθησα




εχεις δικιο ευχαριστω για την απαντηση 








> ε? δηλαδη?
> και τωρα ακομα που δουλευει αυτο το προγραμμα προσπαθω να καταλαβω πως κανει την μετατροπη με το << δεν καταλαβα τι παιζει ακομα...θελω βοηθεια πανω σε αυτα.



αν μπορεις να περιμενεις λιγο θα σου δωσω ενα πολυ πιο απλο προγραμμα απο θα καταλαβεις ακριβως πως δουλευει το συστημα 
το << ειναι μεταφορα του διαδικου αριθμου (byte)δεξια η αριστερα >> τοσα ψηφεια οσα του λες

----------


## briko

Το ds σαν αποτέλεσμα βγαζει 0000 0001 1001 0001 στους 25.0625 βαθμούς C
Αυτό όπως βλέπεις είναι 2 BYTE , 1 BYTE to 0000 0001 και                        
                                                          δεύτερο το 1001 0001
Όταν κάνουμε εισαγωγή το J τότε εισάγουμε το τελευταίο σημαντικό τμήμα μιας λέξης WORD  και σαν temp το πρώτο τμήμα της  λέξης
Αυτά τα 2 κομμάτια πρέπει να τα βάλουμε σε μια σειρά    για αν έχουν την σωστή αξία 
Δηλαδή 2 BYTE = 1 WORD
Αυτό γίνετε με 2 τρόπους.
 ο πρώτος και ο ποιο απλός είναι περνούμε το temp και το πολλαπλασιάζουμε με το 256 και προσθέτουμε το J δηλαδή στο διάδικο σύστημα το 256 είναι        1 0000 0000 όποτε αν πολλαπλασιάσουμε το 0000 0001 (temp) με το 1 0000 0000 τότε γίνετε 0000 0001 xxxx xxxx εάν τώρα προσθέσουμε και το J γίνετε ο σωστός αριθμός που μας δίνει το ds                                      δηλαδή 0000 0001 1001 0001 
Στο δεκαδικό σύστημα αυτός ο αριθμός είναι το 401 επί το 0.0625 βγαίνει ο 25.0625
Πολλαπλασιάζοντας το 401 με το 100 και διαιρώντας με το 16 βγάζουμε αποτέλεσμα 2506.25   και ο integer του αριθμού δηλαδή το άκαιρο τμήμα του είναι 2506 αυτό που χρειαζόμουν για τον έλεγχο παρακάτω της θερμοκρασίας 
Αν αντί για 100 διαιρούσα μόνον με το 16 χωρίς να πολλαπλασιάσω τότε θα έβγαινε 250625  ολόκληρος ο αριθμός.
Ο δεύτερος τρόπος είναι με μετάθεση ψηφιων    temp = temp << 8
δηλαδή το temp το εισάγουμε και το μεταφέρουμε μέσα στο WORD 8 ψηφία ΑΡΙΣΤΕΡΑ και στο τέλος προσθέτουμε   temp = temp + j    δηλαδή 
xxxx xxxx 0000 0001 με την εντολή <<8 γίνετε                                    0000 0001 xxxx xxxx και προθέτοντας το  j γίνετε 0000 0001 1001 0001 



 το υπόλοιπο του προγράμματος με το mod και τα υπόλοιπα δεν τα κατάλαβα και εγώ όποτε έφτιαξα δίκες μου εντολές απεικονίσεις με το temp να το διαιρώ με το 100 και να κάνω μια εντολή   FloatToStr(tair, tairstring)
και   Lcd_Out(1,1,tairstring)

εάν κάποιος  μπορεί να εξηγήσει λίγο το τμήμα με το MOD θα ήμουν ευγνώμων 

ευχαριστώ

----------


## billtech

νομιζω κανεις ενα λαθος...νομιζω..
το πρωτο byte  δειχνει μονο το προσιμο της θερμοκρασιας.
ειναι παντα 0000 0000 η 1111 1111
αυτο το διαβασα στο datasheet.
αρα δεν μπορει να εχει 0000 0001 1001 0001

----------


## billtech

μα την παναγια δεν καταλαβαινω τιποτα.
στο κομματι του κωδικα που δουλευει READ κανει το διαβασμα και το μετατρεπει κιολας.οταν ομως παει στη οθονη να το μετατρεψει και να το εμφανισει δεν χρησιμοποιει κανενα απο τους καταχωρητες που εχουν τις τιμες πανω.που του βρισκει τις τιμες? δεν καταλαβαινω τιποτα...
ας βρεθει καποιος να το εξηγησει γιατι θα τρελλαθω.
οπως επισης και οτι κανει 2 φορες την μετατροπη για να το κανει σε integer.

----------


## briko

Από το πρώτο byte μόνον τα 4 πρώτα bit είναι 0 η 1 ανάλογα με το πρόσημο θερμοκρασίας όχι όλο άλλωστε η ανάλυση του ds είναι 12 bit 8 από το δεύτερο και 4 από το πρώτο

----------


## billtech

οχι φιλε μου...γιατι οπως βλεπεις στους πινακες που αναιβαζω που τους πηρα απο το datasheet ειναι και τα 8 bit.

----------


## briko

ποιο datasheet για ποιο ds διαβαζεις
ξεκαθαρισε πρωτα ποιο ds εχεις και μετα κατεβασε το σωστο manual η δες την φωτο που ειχα ανεβασει εγω σε καποια πρωηγουμενη σελιδα

----------


## billtech

εχεις δικιο φιλε μου...λαθος datasheet κοιτουσα.
ωραια το βρηκα το σωστο.
αυτα που μου ειπες τα καταλαβα και εγω. αυτα με το << αλλα αυτα με το *256 δεν ασχοληθηκα για να μην ταραξουν τα νευρα μου.
παρακατω ομως? πως καταλαηγει στη οθονη η θερμοκρασια?

----------


## briko

ειναι 2 τροποι που καταλυγουν στο ιδιο αποτελεσμα

----------


## briko

program onewire

' Set TEMP_RESOLUTION to the corresponding resolution of your DS18x20 sensor:
'  18B20: 12
const TEMP_RESOLUTION as byte = 12

dim	
  j1  as byte
  temp1  as word
  tair  as float
   tairstring  as string[5]

sub procedure Read_Temperature()
dim buf1  as longint
  Ow_Reset(PORTA,5)                 ' Onewire reset signal
  Ow_Write(PORTA,5,0xCC)            ' Issue command SKIP_ROM
  Ow_Write(PORTA,5,0x44)            ' Issue command CONVERT_T
  Delay_ms(200)

Ow_Reset(PORTA,5)
  Ow_Write(PORTA,5,0xCC)            ' Issue command SKIP_ROM
  Ow_Write(PORTA,5,0xBE)            ' Issue command READ_SCRATCHPAD
  Delay_us(600)

    j1    = OW_Read(PORTA,5)        ' Get temperature LSB
    temp1 = OW_Read(PORTA,5)        ' Get temperature MSB


buf1 = (temp1 * 256) + j1         ' buf=16bit word
  buf1 = (buf1 * 100) div 16      'περνουμε τα 4 πρωτα ψηφεια της θερμοκρασιας 2506
    tair=buf1/100                'το 2506 το κανουμε 25,06
end sub


main:
  TRISD = 0                                      ' Configure pins of PORTD as output
  ADCON1  = 7                                    ' configure PORTA as digital I/O
  PORTD = %00000000

   Lcd_Config(PORTB, 3, 2, 1, 0, PORTB, 4, 6, 5) ' Initialize LCD connected to PORTB easypic5

     Lcd_Cmd(LCD_CLEAR)                          ' Send command to LCD "clear display"
     Lcd_Cmd(LCD_CURSOR_OFF)                     ' Send command cursor off

  while true
    Read_Temperature()
    FloatToStr(tair, tairstring)
    Lcd_Out(1,1,tairstring)
    Lcd_Chr(1, 6, 223)               'εκτυπωση του χαρακτηρα 'degree'
  Lcd_Chr(1, 7, "C")

   if tair <= 26.50 then                'ελεγχουμε αν η θερμοκρασια ειναι   <= tair (26.50°C)????
    SetBit(PORTD, 2)                     'και ενεργοποιουμε την PORTD, 2 (1)
      else  ClearBit(PORTD, 2)           'αλλιως  την μηδενιζουμε
    end if

     wend
end.



ενα πολυ απλο προγραμμα με πολυ απλη εκτυπωση (δεν εχει αρνητικες θερμοκρασιες)

----------


## briko

program onewire

' Set TEMP_RESOLUTION to the corresponding resolution of your DS18x20 sensor:
'  18B20: 12
const TEMP_RESOLUTION as byte = 12

dim
  j1  as byte
  temp1  as word
  tair  as float
   tairstring  as string[5]

sub procedure Read_Temperature()
dim buf1  as longint
  Ow_Reset(PORTA,5)                 ' Onewire reset signal
  Ow_Write(PORTA,5,0xCC)            ' Issue command SKIP_ROM
  Ow_Write(PORTA,5,0x44)            ' Issue command CONVERT_T
  Delay_ms(200)

Ow_Reset(PORTA,5)
  Ow_Write(PORTA,5,0xCC)            ' Issue command SKIP_ROM
  Ow_Write(PORTA,5,0xBE)            ' Issue command READ_SCRATCHPAD
  Delay_us(600)

    j1    = OW_Read(PORTA,5)        ' Get temperature LSB
    temp1 = OW_Read(PORTA,5)        ' Get temperature MSB


      buf1 = (temp1 * 256) + j1         ' buf=16bit word


     if (buf1 and $8000) = 0x8000 then
     Lcd_Chr(1, 1, "-")
     Buf1 = not buf1 + 1
     end if

    buf1 = (buf1 * 100) div 16      ''περνουμε τα 4 πρωτα ψηφεια της θερμοκρασιας  2506
    tair=buf1/100                'το 2506 το κανουμε 25,06

end sub


main:
  TRISD = 0                                      ' Configure pins of PORTD as output
  ADCON1  = 7                                    ' configure PORTA as digital I/O
  PORTD = %00000000

   Lcd_Config(PORTB, 3, 2, 1, 0, PORTB, 4, 6, 5) ' Initialize LCD connected to PORTB easypic5

     Lcd_Cmd(LCD_CLEAR)                          ' Send command to LCD "clear display"
     Lcd_Cmd(LCD_CURSOR_OFF)                     ' Send command cursor off

  while true
    Read_Temperature()
    FloatToStr(tair, tairstring)
    Lcd_Out(1,2,tairstring)
    Lcd_Chr(1, 7, 223)               ''εκτυπωση του χαρακτηρα  'degree'
  Lcd_Chr(1, 8, "C")

   if tair <= 26.50 then                ''ελεγχουμε αν η θερμοκρασια ειναι   <= tair (26.50°C)????
    SetBit(PORTD, 2)                     ''και ενεργοποιουμε την  PORTD, 2 (1)
      else  ClearBit(PORTD, 2)           ''αλλιως  την μηδενιζουμε
    end if

     wend
end.



και με ενδυξη αρνητικης θερμοκρασιας
δεν το εχω δοκιμασει αλλα πρεπει να παιζει

----------


## billtech

συγνωμη το  const TEMP_RESOLUTION as byte = 12 που το χρισημοποιεις?
γιατι το βαζεις?

----------


## briko

αν δεν σ'αρεσει βγαλτην ειναι μονον για ενδηξη ψηφιων

----------


## billtech

λοιπον το δοκιμασα αυτο με το + και -.
φενεται να δουλευει αλλα οχι και τοσο καλα...
δηλαδη τι θελω να πω για να μην παρεξηγηθω.
οταν εμφανιζει τη κανονικη θερμοκρασια εμφανιζει το παρακατω:
" 22,67*C9" αυτο το 9 η οτι αλλο ειναι που μεταβαλλεται γιατι το βγαζει εκει?βγαινει απο τη μετατροπη FloatToStr?
τα αρνητικα δεν πανε τοσο καλα.θα το κοιταξω και εγω λιγακι τωρα το απογευμα.
σε ευχαριστω για την βοηθεια.

----------


## billtech

```
program temp

' Set TEMP_RESOLUTION to the corresponding resolution of your DS18x20 sensor:
' 18B20: 12

const TEMP_RESOLUTION as byte = 12

dim
j1 as byte
temp1 as word
tair as float
tairstring as string[5]

'******************************************************************************
'                                Read_Temperature
sub procedure Read_Temperature()
dim buf1 as longint
Ow_Reset(PORTA,5) ' Onewire reset signal
Ow_Write(PORTA,5,$CC) ' Issue command SKIP_ROM
Ow_Write(PORTA,5,$44) ' Issue command CONVERT_T
Delay_ms(200)

Ow_Reset(PORTA,5)
Ow_Write(PORTA,5,$CC) ' Issue command SKIP_ROM
Ow_Write(PORTA,5,$BE) ' Issue command READ_SCRATCHPAD
Delay_us(600)

j1 = OW_Read(PORTA,5) ' Get temperature LSB
temp1 = OW_Read(PORTA,5) ' Get temperature MSB

buf1 = (temp1 * 256) + j1 ' buf=16bit word

if (buf1 and $8000) = 0x8000 then
Lcd_Chr(1, 1, "-")
Buf1 = not buf1 + 1
end if

buf1 = (buf1 * 100) div 16 ''&#240;&#229;&#241;&#237;&#239;&#245;&#236;&#229; &#244;&#225; 4 &#240;&#241;&#249;&#244;&#225; &#248;&#231;&#246;&#229;&#233;&#225; &#244;&#231;&#242; &#232;&#229;&#241;&#236;&#239;&#234;&#241;&#225;&#243;&#233;&#225;&#242; 2506
tair=buf1/100 '&#244;&#239; 2506 &#244;&#239; &#234;&#225;&#237;&#239;&#245;&#236;&#229; 25,06

end sub

'********************************************************************************
main:
TRISB = 0 ' Configure pins of PORTB as output
ADCON1 = 7 ' configure PORTA as digital I/O

Lcd_Config(PORTB,7,6,5,4,PORTB,2,1,3) ' Initialize LCD connected to PORTB
Lcd_Cmd(LCD_CLEAR) ' Send command to LCD "clear display"
Lcd_Cmd(LCD_CURSOR_OFF) ' Send command cursor off
Lcd_Out(2,1,"temperature")

while true
Read_Temperature()

FloatToStr(tair, tairstring)

Lcd_chr(1,2,tairstring[0])
Lcd_chr(1,3,tairstring[1])
Lcd_chr(1,4,tairstring[2])
Lcd_chr(1,5,tairstring[3])
Lcd_chr(1,6,tairstring[4])

Lcd_Chr(1, 7, 223) ''&#229;&#234;&#244;&#245;&#240;&#249;&#243;&#231; &#244;&#239;&#245; &#247;&#225;&#241;&#225;&#234;&#244;&#231;&#241;&#225; 'degree'
Lcd_Chr(1, 8, "C")

wend
end.
```


ετσι εμφανιζει σωστα την θερμοκρασια...θα δοκιμασω και τα αρνητικα,

----------


## billtech

λοιπον...επειδη το παλεψα λιγο για τα αρνητικα νομιζω καταλαβα που κανουμε ενα λαθος...δεν πρεπει να κανουμε την πραξη και με τα 16bit.αλλα με τα 12.
μπορει να μας δουλευει στα θετικα αλλα δουλευει γιατι τα πρωτα 4 ειναι μηδενικα..οταν ομως γινουν ασσοι (αρνητικα) τοτε δεν δουλευει σωστα.
καταλαβες τι εννοω?
αλλα δεν βρηκα πως να κανω πραξη με τα 12bit.
σκεφτηκα μονο μια κινηση αλλα δεν την δοκιμασα. αφου ελεγξουμε αν ειναι θετικο η αρνητικο αυτο που περνουμε να πηγαινουμε να μηδενιζουμε τα 4 πρωτα bit.

----------


## briko

και ολοκληρωμένο το πρόγραμμα για να βγαίνουν και οι αρνητικοί αριθμοί σωστά



```
program temp

' Set TEMP_RESOLUTION to the corresponding resolution of your DS18x20 sensor:
' 18B20: 12

const TEMP_RESOLUTION as byte = 12

dim
j1 as byte
temp1 as word
tair as float
tairstring as string[5]

'******************************************************************************
'                                Read_Temperature
sub procedure Read_Temperature()
dim buf1 as longint
Ow_Reset(PORTA,5) ' Onewire reset signal
Ow_Write(PORTA,5,$CC) ' Issue command SKIP_ROM
Ow_Write(PORTA,5,$44) ' Issue command CONVERT_T
Delay_ms(200)

Ow_Reset(PORTA,5)
Ow_Write(PORTA,5,$CC) ' Issue command SKIP_ROM
Ow_Write(PORTA,5,$BE) ' Issue command READ_SCRATCHPAD
Delay_us(600)

j1 = OW_Read(PORTA,5) ' Get temperature LSB
temp1 = OW_Read(PORTA,5) ' Get temperature MSB

buf1 = (temp1 * 256) + j1 ' buf=16bit word

if (buf1 and $8000) = 0x8000 then
Lcd_Chr(1, 1, "-")
Buf1 = not buf1 + 1
buf1 = buf1 and $7ff    '!!!!!!!!!!!!!!!
end if

buf1 = (buf1 * 100) div 16 ''?aniioia oa 4 ?nuoa ocoaea oco eaniienaoeao 2506
tair=buf1/100 'oi 2506 oi eaiioia 25,06

end sub

'********************************************************************************
main:
TRISB = 0 ' Configure pins of PORTB as output
ADCON1 = 7 ' configure PORTA as digital I/O

Lcd_Config(PORTB, 3, 2, 1, 0, PORTB, 4, 6, 5) ' Initialize LCD connected to PORTB easypic5
'Lcd_Config(PORTB,7,6,5,4,PORTB,2,1,3) ' Initialize LCD connected to PORTB
Lcd_Cmd(LCD_CLEAR) ' Send command to LCD "clear display"
Lcd_Cmd(LCD_CURSOR_OFF) ' Send command cursor off
Lcd_Out(2,1,"temperature")

while true
Read_Temperature()

FloatToStr(tair, tairstring)

Lcd_chr(1,2,tairstring[0])
Lcd_chr(1,3,tairstring[1])
Lcd_chr(1,4,tairstring[2])
Lcd_chr(1,5,tairstring[3])
Lcd_chr(1,6,tairstring[4])

Lcd_Chr(1, 7, 223) ''aeoo?uoc oio ?anaeocna 'degree'
Lcd_Chr(1, 8, "C")

wend
end.
```

----------


## billtech

θα το δοκιμασω αυριο φιλε μου.
σε ευχαριστω.

----------


## Stergios_[.gr]

To έχει δοκιμάσεις κανένας με το EASYPIC6 και τον PIC16F887?
Εγώ παλεύω εδώ πέρα, και ακόμα παίρνω το σταθερό 085.0000°C
 -.- Με το έτοιμο παράδειγμα -.-

----------


## billtech

> To έχει δοκιμάσεις κανένας με το EASYPIC6 και τον PIC16F887?
> Εγώ παλεύω εδώ πέρα, και ακόμα παίρνω το σταθερό 085.0000°C
>  -.- Με το έτοιμο παράδειγμα -.-



Στεργιε αμα διαβασεις ολο αυτο το θελω ισως βγαλεις ακρη.

----------


## Stergios_[.gr]

Ψάχνω Βασίλη, θα επιστρέψω με περισσότερα.. Αυτήν την στιγμή κοιτάω για την πράξη με τα 12ΒΙΤ...Για να δούμε..

Προς το παρόν ο κώδικας, που δίνει η ΜikroBASIC, αλλά βγάζει πρόβλημα (πάντα " 085.0000°C "):



```
program PIC16F887_DS18B20
' *
' * Project name:
'     OneWire (Interfacing the DS1820 temperature sensor - all versions)
' * Copyright:
'     (c) Mikroelektronika, 2009.
' * Revision History:
'     20080930:
'       - initial release;
'       - 20090720 - modified by Slavisa Zlatanovic;
' * Description:
'     This code demonstrates one-wire communication with temperature sensor
'     DS18x20 connected to RA5 or RE2 pin.
'     MCU reads temperature from the sensor and prints it on the Lcd.
'     The display format of the temperature is "xxx.xxxx°C". To obtain correct
'     results, the 18x20"s temperature resolution has to be adjusted (constant
'     TEMP_RESOLUTION).
' * Test configuration:
'     MCU:             PIC16F887
'                      http://ww1.microchip.com/downloads/en/DeviceDoc/41291F.pdf
'     Dev.Board:       EasyPIC6
'                      http://www.mikroe.com/en/tools/easypic6/
'     Oscillator:      HS, 8.0000 MHz
'     Ext. Modules:    DS18x20, LCD 2x16
'                      http://www.mikroe.com/en/tools/components/
'     SW:              mikroBasic PRO for PIC
'                      http://www.mikroe.com/en/compilers/mikrobasic/pro/pic/
' * NOTES:
'     - Place DS1280 jumper (J11) in the right position(RE2).
'     - Pulling up PORTE and turning off PORTE LEDs may be required.
' *

' Lcd module connections
dim LCD_RS as sbit at RB4_bit
    LCD_EN as sbit at RB5_bit
    LCD_D4 as sbit at RB0_bit
    LCD_D5 as sbit at RB1_bit
    LCD_D6 as sbit at RB2_bit
    LCD_D7 as sbit at RB3_bit
    LCD_RS_Direction as sbit at TRISB4_bit
    LCD_EN_Direction as sbit at TRISB5_bit
    LCD_D4_Direction as sbit at TRISB0_bit
    LCD_D5_Direction as sbit at TRISB1_bit
    LCD_D6_Direction as sbit at TRISB2_bit
    LCD_D7_Direction as sbit at TRISB3_bit
' End Lcd module connections

'  Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor:
'  18S20: 9  (default setting can be 9,10,11,or 12)
'  18B20: 12
const TEMP_RESOLUTION as byte = 12

dim text as char[9]
    temp as word
    tempLSB as byte
    tempMSB as byte

sub procedure Display_Temperature( dim temp2write as word )
const RES_SHIFT = TEMP_RESOLUTION - 8

dim temp_whole as byte
    temp_fraction as word

    text = "000.0000"
    ' Check if temperature is negative
    if (temp2write and 0x8000) then
        text[0] = "-"
        temp2write = not temp2write + 1
    end if

    ' Extract temp_whole
    temp_whole = word(temp2write >> RES_SHIFT)

    ' Convert temp_whole to characters
    if ( temp_whole div 100 ) then
      text[0] = temp_whole div 100  + 48
    else
      text[0] = "0"
    end if

    text[1] = (temp_whole div 10)mod 10 + 48               ' Extract tens digit
    text[2] =  temp_whole mod 10        + 48               ' Extract ones digit

    ' Extract temp_fraction and convert it to unsigned int
    temp_fraction  =  word(temp2write << (4-RES_SHIFT))
    temp_fraction  = temp_fraction and 0x000F
    temp_fraction  = temp_fraction * 625

    ' Convert temp_fraction to characters
    text[4] = word(temp_fraction div 1000)    + 48         ' Extract thousands digit
    text[5] = word((temp_fraction div 100)mod 10 + 48)     ' Extract hundreds digit
    text[6] = word((temp_fraction div 10)mod 10  + 48)     ' Extract tens digit
    text[7] = word(temp_fraction mod 10)      + 48         ' Extract ones digit

    ' Print temperature on Lcd
    Lcd_Out(2, 5, text)
end sub

main:
  ANSEL  = 0                                               ' Configure AN pins as digital I/O
  ANSELH = 0
  
  TRISC = %00000000
  PORTC = %00000000

  text = "000.0000"
  Lcd_Init()                                               ' Initialize Lcd
  Lcd_Cmd(_LCD_CLEAR)                                      ' Clear Lcd
  Lcd_Cmd(_LCD_CURSOR_OFF)                                 ' Turn cursor off
  Lcd_Out(1, 1, " Temperature:   ")

  Lcd_Chr(2,13,223)                                        ' Print degree character, "C" for Centigrades
                                                           ' Different Lcd displays have different char code for degree
  Lcd_Chr(2,14,"C")                                        ' If you see greek alpha letter try typing 178 instead of 223

  '--- Main loop
  while (TRUE)
    PORTC.0 = NOT PORTC.0

    '--- Perform temperature reading
    Ow_Reset(PORTE, 2)                                     ' Onewire reset signal
    Ow_Write(PORTE, 2, 0xCC)                               ' Issue command SKIP_ROM
    Ow_Write(PORTE, 2, 0x44)                               ' Issue command CONVERT_T
    Delay_us(820)

    Ow_Reset(PORTE, 2)
    Ow_Write(PORTE, 2, 0xCC)                               ' Issue command SKIP_ROM
    Ow_Write(PORTE, 2, 0xBE)                               ' Issue command READ_SCRATCHPAD

    tempLSB =  Ow_Read(PORTE, 2)                           ' Get TEMPERATURE LSB
    tempMSB = Ow_Read(PORTE, 2)                            ' Get TEMPERATURE MSB
    temp =                                                 '(tempMSB*256)+tempLSB

    '--- Format and display result on Lcd

    Display_Temperature(temp)

    Delay_ms(520)
  wend
end.
```


Αλλαγές στον κώδικα:
- ένα LED που αναβοσβήνει στην PORTC.0
- Διόρθωση στο delay　κατά την μετατροπή της θερμοκρασίας σε delay_ms(800)

----------


## billtech

αν θυμαμαι καλα...δεν κανουν στον ιδιο κωδικα ολα τα 18x20 νομιζω εμενα με ιδιο κωδικα δεν επαιζε το 18b20 ενω το 18s20 επαιζε.η το αναποδο ητανε? παντως επαιζε σημασια σε εμενα αυτη η λεπτομερια.

----------


## Stergios_[.gr]

Χμμ... Εντ δε στρανγκλ κοντίνιουζ...

----------


## Stergios_[.gr]

*Καλά, θα τρελαθούμε εντελώς!! 

ΚΑΜΕΝΟ DS18B20!!

* :Cursing: *Γ@ΜΩ την τρέλα μου Γ@ΜΩ!!* :Cursing: 

όλα καλά, λειτουργεί με καινούργιο DS..

----------


## Stergios_[.gr]

Έτοιμο. Λειτουργεί τέλεια, έχει και αυτόματη μετατόπιση του "-" για τις αρνητικές τιμές.




```
program PIC16F887_DS18B20
' *
' * Project name:
'     OneWire (Interfacing the DS1820 temperature sensor - all versions)
' * Copyright:
'     (c) Mikroelektronika, 2009.
' * Revision History:
'     20080930:
'       - initial release;
'       - 20090720 - modified by Slavisa Zlatanovic;
'       - 20100806 - expanded by NuMcA (www.numca.gr)
' * Description:
'     This code demonstrates one-wire communication with temperature sensor
'     DS18x20 connected to RA5 or RE2 pin.
'     MCU reads temperature from the sensor and prints it on the Lcd.
'     The display format of the temperature is "xxx.xxxx°C". To obtain correct
'     results, the 18x20"s temperature resolution has to be adjusted (constant
'     TEMP_RESOLUTION).
' * Test configuration:
'     MCU:             PIC16F887
'                      http://ww1.microchip.com/downloads/en/DeviceDoc/41291F.pdf
'     Dev.Board:       EasyPIC6
'                      http://www.mikroe.com/en/tools/easypic6/
'     Oscillator:      HS, 8.0000 MHz
'     Ext. Modules:    DS18x20, LCD 2x16
'                      http://www.mikroe.com/en/tools/components/
'     SW:              mikroBasic PRO for PIC
'                      http://www.mikroe.com/en/compilers/mikrobasic/pro/pic/
' * NOTES:
'     - Place DS1280 jumper (J11) in the right position(RE2).
'     - Pulling up PORTE and turning off PORTE LEDs may be required.
' *

' Lcd module connections
dim LCD_RS as sbit at RB4_bit
    LCD_EN as sbit at RB5_bit
    LCD_D4 as sbit at RB0_bit
    LCD_D5 as sbit at RB1_bit
    LCD_D6 as sbit at RB2_bit
    LCD_D7 as sbit at RB3_bit
    LCD_RS_Direction as sbit at TRISB4_bit
    LCD_EN_Direction as sbit at TRISB5_bit
    LCD_D4_Direction as sbit at TRISB0_bit
    LCD_D5_Direction as sbit at TRISB1_bit
    LCD_D6_Direction as sbit at TRISB2_bit
    LCD_D7_Direction as sbit at TRISB3_bit
' End Lcd module connections

'  Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor:
'  18S20: 9  (default setting can be 9,10,11,or 12)
'  18B20: 12
const TEMP_RESOLUTION as byte = 12

dim text as string[9]
    temp, tempLSB, tempMSB as word
    temperature as bit[16]


sub procedure Display_Temperature( dim temp2write as word )
const RES_SHIFT = TEMP_RESOLUTION - 8

dim temp_whole as byte
    temp_fraction, temp_neg_test as word
    negative as bit
    
    negative = %0

    text = " 000.0000"                                     ' Format TEXT output

    temp_neg_test = temp2write >> 12                       ' Check if temperature is negative
    if (temp_neg_test and %1111) then
        text[0] = "-"
        temp2write = not temp2write + 1
        negative = %1
    end if

    temp_whole = word(temp2write >> RES_SHIFT)             ' Extract temp_whole

                                                           ' Convert temp_whole to characters
    if ( temp_whole div 100 ) then                         ' Extract hundrends
      text[1] = temp_whole div 100  + 48
    else                                                   ' If not any,
      text[1] = " "                                        ' show nothing
    end if

    text[2] = (temp_whole div 10)mod 10 + 48               ' Extract tens digit
    if text[2] = "0" then
       text[2] = " "
    end if

    text[3] =  temp_whole mod 10        + 48               ' Extract ones digit

    temp_fraction  =  word(temp2write << (4-RES_SHIFT))    ' Extract temp_fraction and convert it to unsigned int
    temp_fraction  = temp_fraction and 0x000F
    temp_fraction  = temp_fraction * 625
                                                           ' Convert temp_fraction to characters
    text[5] = word(temp_fraction div 1000)    + 48         ' Extract thousands digit
    text[6] = word((temp_fraction div 100)mod 10 + 48)     ' Extract hundreds digit
    text[7] = word((temp_fraction div 10)mod 10  + 48)     ' Extract tens digit
    text[8] = word(temp_fraction mod 10)      + 48         ' Extract ones digit

' ADDITIONAL FORMATING before displaying on LCD,
' Removes zeros and inserts - infront of negative number.
' example "-008.9876" --> "  -8.9876"
    if (text[1] = " ") then
       if (text[2] = " ") then
          text[0] = " "
          text[1] = " "
          if (negative and %1) then
              text[2] = "-"
          else
              text[2] = " "
          end if
       else
          text[0] = " "
          if (negative and %1) then
             text[1] = "-"
          else
             text[1] = " "
          end if
       end if
    else
        if (negative and %1) then
           text[1] = "-"
        else
           text[1] = " "
        end if
    end if

    ' Print temperature on Lcd
    Lcd_Out(2, 4, text)
end sub

main:
  ANSEL  = 0                                               ' Configure AN pins as digital I/O
  ANSELH = 0
  
  TRISC = %00000000
  PORTC = %00000000

  text = " 000.0000"
  Lcd_Init()                                               ' Initialize Lcd
  Lcd_Cmd(_LCD_CLEAR)                                      ' Clear Lcd
  Lcd_Cmd(_LCD_CURSOR_OFF)                                 ' Turn cursor off
  Lcd_Out(1, 1, " Temperature:   ")

  Lcd_Chr(2,13,223)                                        ' Print degree character, "C" for Centigrades
                                                           ' Different Lcd displays have different char code for degree
  Lcd_Chr(2,14,"C")                                        ' If you see greek alpha letter try typing 178 instead of 223

' MAIN
  while (TRUE)
    PORTC.0 = NOT PORTC.0                                  ' Blink status LED
    
    ' PERFORM TEMPERATURE READING
    Ow_Reset(PORTE, 2)                                     ' Onewire reset signal
    Ow_Write(PORTE, 2, 0xCC)                               ' Issue command SKIP_ROM
    Ow_Write(PORTE, 2, 0x44)                               ' Issue command CONVERT_TEMPERATURE
    Delay_ms(750)

    Ow_Reset(PORTE, 2)
    Ow_Write(PORTE, 2, 0xCC)                               ' Issue command SKIP_ROM
    Ow_Write(PORTE, 2, 0xBE)                               ' Issue command READ_SCRATCHPAD
    delay_ms(5)

    tempLSB =  Ow_Read(PORTE, 2)                           ' Get TEMPERATURE LSB
    tempMSB = Ow_Read(PORTE, 2)                            ' Get TEMPERATURE MSB
    temp = (tempMSB << 8) + tempLSB                        ' Create TEMP (16bit)

' Use these lines to test TEMP, and disable "temp = (tempMSB << 8) + tempLSB".
    'temp = %0000011111010000                              ' +125
    'temp = %0000010101010000                              ' +85*   (RESET VALUE)
    'temp = %0000000110010001                              ' +25.0625
    'temp = %0000000010100010                              ' +10.125
    'temp = %0000000000001000                              ' +0.5
    'temp = %0000000000000000                              '  0
    'temp = %1111111111111000                              ' -0.5
    'temp = %1111111101011110                              ' -10.125
    'temp = %1111111001101111                              ' -25.0625
    'temp = %1111110010010000                              ' -55

    
    
    Display_Temperature(temp)                              ' Format and Display TEMPERATURE on LCD

    Delay_ms(520)
  wend
end.
```


Διορθώσεις:
- Τα άχρηστα μηδενικά πριν την θερμοκρασία απενεργοποιήθηκαν, και το πρόσημο προβάλλεται πάντα πριν τον αριθμό. (πχ "-001.2345°C" ---> "  -1.2345°C"),
- LED ένδειξης στην PORTC.0
- Ρύθμιση καθυστέρησης για την μετατροπή στα 750ms,

Σχηματικό και Φωτογραφίες:
DS18b20_PIC16F887.JPG Εικόνα0063 (Medium).jpg Εικόνα0064 (Medium).jpg Εικόνα0065 (Medium).jpg

----------


## billtech

να φανταστω οτι ολο αυτο ειναι με την microbasic pro ε?
γτ απο οσο ξερω sbit δεν εχει η απλη.

αληθεια τι κανει η sbit?
και η TRISB3_bit?

καλο ειναι παντως Στεργιε!!!αμα σου δουλευει εισαι μια χαρα!!!

----------


## Stergios_[.gr]

Τα SBIT είναι ΒΙΤ που δηλώνονται με δεσμευμένη διεύθυνση.
Μπορείς να καλείς όποιο ΒΙΤ μιας SFR θέλεις με αυτόν τον τρόπο. Βολεύει στις ρυθμίσεις οθόνης (έτσι το έκανε η MikroBASIC στο tutorial, έτσι το έκανα και εγώ  :Smile:  )

Η δήλωση έγινε COPY + PASTE από το tutorial....
 
Δουλεύει, ορίστε και το ΗΕΧ:

----------


## billtech

εγω ρωτησα γτ δεν ασχοληθηκα με την pro.
thnks παντως.

----------


## herctrap

να ρωτησω και εγω κατι 

εχουμε δυο ds18b20 

σε ενα σημειο το καλωδιου υπαρχει παγος (-30 κελσιου)

Υπαρχει ποτε πιθανοτητα να επηρεασει τις μετρησεις ?
*Οχι να μην φτασει ποτε το σημα στο uC αλλα να περνουμε μετρηση +-2βαθμους


????????

----------


## briko

όχι πολύ άπλα όχι 
έχεις ψηφιακό σήμα που δεν επειρεαζετε σχεδόν από τίποτε

----------


## billtech

αληθεια. μια αλλη ερωτηση. πως διαβαζουμε δευτερο ή τριτο θερμομετρο στη ιδια γραμμη?
διαβασα καποια πραματα αλλα δεν εβγαλα ακρη.
το εχει κανει κανεις αυτο?

----------


## briko

κάπου στο forum της mikroe υπήρχε ένα παράδειγμα (στην απλή basic όχι στην pro)

----------


## billtech

μπηκα στην σελιδα της Mikroe και κοιταξα αυτο με τα δυο η παραπανο DS18B20 στην ιδια γραμμη αλλα δεν καταλαβα πολλα (ισως λογω αγγλικων) για το πως γινετε. Το εχει κανει κανεις που να ειναι στα ελληνικα καποια βοηθεια ρε παιδια?

----------

