Beste CO-ers,

Ik heb het schematje van deze site gehaald in computer en microcontroller, http://www.circuitsonline.net/circuits/view/143

En het werkt prima, Het enige is; Ik wil het voor buiten gebruiken (de tempsensor dan) maar als hij onder 0 graden celsius komt gaat hij opeens naar 655 of 666 graden celsius en gaat dan steeds lager.

Hoe kan ik de code aanpassen zodat hij ook negatieve temperaturen kan weergeven?

Ik heb de .hex file van deze site gehaald.

Alvast bedankt ;-)

In de data sheet staat wel dat hij onder nul moet kunnen.

http://datasheets.maxim-ic.com/en/ds/DS18S20.pdf

Je kan op pagina 4 zien hoe je bits er ongeveer uit zien bij een bepaalde temp.
Ik heb ook zo'n ding, zelfs nog op breadbord staan.

Ik zal hem eens verlengen en buiten hangen kijken wat hij bij mij doet.

Ik lees dat hij bij 0 graden 0000 0000 0000 0000 is (binair) en bij -0.5 1111 1111 1111 1111 is.

Ik denk dat de microcontroller dan denkt dat hij op zijn max is ? en daar naar 655 graden gaat?

Ik zou het niet weten... zoveel staat er nou ook weer niet in die datasheet :p

Ik heb even geprobeerd er een paar draadjes aan te hangen maar die zijn te lang om naar buiten te kunnen helaas.

Ik kan me bordje niet uit het raam hangen want er zit nog meer op :P

Doet hij het binnen wel goed? heb je dat al eens geprobeerd?

De schakeling die hier op CO staat is _niet_ voor temperaturen onder nul ;) dan tript ie!

Op 8 januari 2009 11:24:49 schreef Boeip:
De schakeling die hier op CO staat is _niet_ voor temperaturen onder nul ;) dan tript ie!

Kan me er wel wat over herinneren ja.
Ik heb toen een andere versie gekocht, de b versie die kan wel onder nul
Let wel op dat de B versie anders werkt dan de D versie!

Edit:
Linkje naar mijn topic:
http://www.circuitsonline.net/forum/view/65423/1/ds

De schakeling hoeft ook niet onder 0, alleen de dallas natuurlijk. Ik denk dat alleen de software niet gemaakt is voor <0 graden celsius. Weet iemand wat ik moet veranderen in de software zodat hij gewoon tot onder de 0 gaat?

De dallas zelf kan tot -55 graden...

Dit is de .bas file:


Device 16F628A                ;Gebruik een 16F628A type
CONFIG WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF, HS_OSC ;INTRC_OSC_NOCLKOUT verwijderd
ALL_DIGITAL TRUE              ;Alle ingangen digitaal

declare XTAL 4          
declare LCD_RSPIN PORTB.0      ;RS pin declareren

        ;76543210              
TRISA = %11111110              ;i/o portA
TRISB = %11110111              ;i/o portB

print $FE,$40,$0E,$0A,$0E,$00,$00,$00,$00,$00

symbol schakelaar = PORTA.1        
Symbol dq = PORTA.2   ; inlees poort ds1820
DIM Temp AS WORD              ' Holds the temperature value 
DIM C AS BYTE                 ' Holds the counts remaining value 
DIM CPerD AS BYTE             ' Holds the Counts per degree C value   
Dim backlight0 as Byte         ;Variabele instellen
dim teller as byte

delayms 500 ;lcd stabalyse

clear

start:                 
backlight0 = eread 0            ;Eeprom backlight waarde opvragen
hpwm 1, backlight0, 2000

While 1 = 1
  print at 1,3, "Buitentemp."
  
  OWRITE DQ, 1, [$CC, $44]      ' Send Calculate Temperature command 
  REPEAT 
  DELAYMS 1000                  ' Wait until conversion is complete 
  OREAD DQ, 4, [C]              ' Keep reading low pulses until
  UNTIL C <> 0                  ' the DS1820 is finished.
  OWRITE DQ, 1, [$CC, $BE]      ' Send Read ScratchPad command
  OREAD DQ, 2,[Temp.LOWBYTE,Temp.HIGHBYTE, C, C, C, C, C, CPerD]
  ' Calculate the temperature in degrees Centigrade
  Temp = (((Temp >> 1) * 100) - 25) + (((CPerD - C) * 100) / CPerD)
  print at 2,5, DEC Temp / 100, ".", DEC2 Temp, 0, "C "
  for teller = 0 to 40
    if schakelaar = 0 then
      delayms 150
      goto honderd
    endif
    delayms 100
    inc teller
  next
  teller = 0    
Wend

honderd:        
cls
print at 1,1, "BL-Selecteren"
print at 2,1, "   100%"
hpwm 1, 255, 2000
  
while 1 = 1
  if schakelaar = 0 then
    delayms 150
    if schakelaar = 0 then
      backlight0 = 255
      delayms 1900
      goto memory
    else
      goto zesenzestig
    endif
  endif
wend

zesenzestig:          
cls
print at 1,1, "BL-Selecteren"  
print at 2,1, "   66%"
hpwm 1, 168, 2000
  
while 1 = 1         
  if schakelaar = 0 then  
    delayms 150
    if schakelaar = 0 then
      backlight0 = 168
      delayms 1900
      goto memory
    else
      goto drieendertig
    endif
  endif
wend

drieendertig:     
cls
print at 1,1, "BL-Selecteren"     
print at 2,1, "   33%"
hpwm 1, 84, 2000
  
while 1 = 1
  if schakelaar = 0 then   
    delayms 150 
    if schakelaar = 0 then
      backlight0 = 84
      delayms 1900
      goto memory
    else
      goto uit
    endif
  endif
wend

uit:       
cls
print at 1,1, "BL-Selecteren"   
print at 2,1, "   UIT"
hpwm 1, 0, 2000
 
while 1 = 1  
  if schakelaar = 0 then        
    delayms 150     
    if schakelaar = 0 then
      backlight0 = 0
      delayms 1900
      goto memory
    else
      goto honderd
    endif
  endif
wend

memory:
CLS
ewrite 0, [backlight0]           ;Eeprom geheugen schrijven
print at 1,1, "BL-Selecteren"
Print at 1,1, "     Opgeslagen!"
delayms 2500
CLS
goto start

[Bericht gewijzigd door Henry S. op (0%)]

Bij mij werkt de DS1820 prima onder 0 graden Celsius.

Hint: Het (grote) getal dat je krijgt als je onder 0 komt, kun je in je PIC Basic programma weer omrekenen zodat hij weer op 0 staat en een "-" voor de temperatuursweergave zetten als de temperatuur nog lager wordt.
Op de CD-ROM van picbasic.nl staan een paar voorbeeldjes met een DS1820 die temperaturen onder het vriespunt gewoon goed blijft weergeven.

Dus... even goed nadenken en je software aanpassen.

Ken PICbasic niet, maar kun je voor Temp niet gewoon een (signed) integer nemen i.p.v. een Word?
Dat zou het probleem toch ook oplossen? (1111111111111111 is signed gewoon -1)

Nee, het is de DS1820 zelf die ineens naar een totaal andere waarde gaat als de temperatuur onder het vriespunt komt.
Gewoon even uitpluizen en omrekenen.

Nee, het is de DS1820 zelf die ineens naar een totaal andere waarde gaat als de temperatuur onder het vriespunt komt.

Is geen totaal andere waarde, is gewoon signed logic. +0.5 is 0x0001, 0 is 0x0000, -0.5 is 0xFFFF...

Ok, ik was weer wat te kort door de bocht :o .
Ik heb het zelf al jaren voor elkaar met die negatieve temperaturen (en hogere resolutie) met een DS1820, en moet het daarom eerst weer nakijken om te weten hoe het ook al weer precies zit.

[Bericht gewijzigd door Frits Kieftenbelt op (67%)]

Heeft iemand enig idee wat ik aan de code moet veranderen?
Ik ben namelijk niet zo goed in programmeren... Ik kan zo goed als niets... (op software gebied dan;P)

Alvast bedankt.

Mooi moment om er mee te beginnen.

Als het klopt wat hierboven staat: -0.5 = 11...11, dan geeft ie gewoon een signed waarde in 2's complement. Da's niks bijzonders. De code werkt blijkbaar gewoon met unsigned getallen en interpreteert alles als positief.
Software aanpassen dus. Daar waar je de waarde gaat verwerken kijk je eerst of het negatief is, en reken je de waarde uit volgens het 2's compl principe. Hoogste bit 1? Dan alles inverteren en 1 erbij tellen.
111111 -> 000000 -> 000001 Dat schaal je weer zoals je ook positieve getallen schaalt (00001 zal +0.5 worden).

If temp > 5000 Then GoTo ondernul
ondernul:
tempnieuw = temp ^ %1111111111111111
temp = tempnieuw + 1
print At 1,1 ,"-"
Print At 1,2, Dec temp Dig 3,Dec temp Dig 2 ,".",Dec temp Dig 1 ' laat zien 0.1 resolutie

Ik heb wel een tip voor je. Laat je programma behalve de temperatuur ook de waarde van 'temp' (decimaal) op het lcd zetten en kijk dan wat er gebeurt wanneer hij onder nul komt.
Zo heb ik het zelf ook uitgevonden...

Wat ik al zei: Temp veranderen van een word in een integer is waarschijnlijk al genoeg?

Sorry, wat bedoel je met een integer?

Ik weet niks van PICbasic :P wel de "hardware" etc.

Hij bedoelt dat je van word naar byte moet gaan.

Hij bedoelt dat je van word naar byte integer moet gaan.
Word is alleen positief, integer is signed (+/-)

Klein vraagje,

Werkt het nu al, zo ja publiceer dan als het mogelijk is de syntax, doe je mij een groot plezier mee, ik loop tegen hetzelfde issue op.

bedankt mvrgrt,

Aad den Blaauwen

deze code komt van de engelse elektor mischien heb je hier iets aan

'* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
'* Universal thermostat -25/+75 C. by R.T.G. van Steenis *
'* Compiler : PicBasic Pro 2.45 *
'* B0 = Mode switch in (In) A0 = LCD Enable (Out) *
'* B1 = + switch in (In) A1 = LCD RS (Out) *
'* B2 = - switch in (In) A2 = "Warm" Output (Out) *
'* B3 = Not connected (Out) A3 = "Cold" Output (Out) *
'* B4 = LCD Bit 4 (Out) A4 = DQ DS1820 (In) *
'* B5 = LCD Bit 5 (Out) *
'* B6 = LCD Bit 6 (Out) *
'* B7 = LCD Bit 7 (Out PIC16F628 Code size = 1124 Words *
'* *
'* Oscillator XP (4 MHz.) - Power up timer enabled - MCR enable *
'* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

TRISA= %11110000 ' RA0..3=Outputs RA4=Input
TRISB= %00000111 ' RB0..RB2=Inputs, RB3..RB7=Outputs
CMCON=7 ' Disable comparators

DEFINE LCD_DREG PORTB ' LCD on port B
DEFINE LCD_DBIT 4 ' Data bits B4..B7
DEFINE LCD_RSREG PORTA ' RS on PORTA
DEFINE LCD_RSBIT 1 ' RS on A1
DEFINE LCD_EREG PORTA ' E on PORTA
DEFINE LCD_EBIT 0 ' E on A0
DEFINE LCD_BITS 4 ' LCD 4 bit mode
DEFINE LCD_LINES 2 ' 2 line LCD display

Temperature Var Word ' Temperature storage
TargetTemp Var Word ' Desired Temperature
Hyst Var Word ' Hystereris
V Var Word ' Var. for display
B1 Var Byte ' Byte for TargetTemp calculation
B2 Var Byte ' Byte for TargetTemp calculation
Count_Remain Var Byte ' Count remaining
Count_Per_C Var Byte ' Count per degree C
Sign Var Byte ' +/- sign
Mode Var Byte ' 0=Temp. display, 1=Set Temp, 2=Set Hysteresis
DQ Var PORTA.4 ' One-wire data pin

Data 46, 224, 20 ' Temp MSB, TEMP LSB, Hysteresis DIV 10

PORTA.2=0 ' Warm Output Low
PORTA.3=0 ' Cold Output Low
Mode=0 ' Temperature display mode

LCDOUT $FE, 1, $FE, $0C ' Clear display, cursor off

Read 0, B1 ' Read TargetTemp MSB
Read 1, B2 ' Read TargetTemp LSB
TargetTemp=B1*256+B2 ' Calculate TargetTemp value (Default=20.0 C.)
Read 2, B1 ' Read Hysteresis
Hyst=10*B1 ' Calculate Hysteresis value (Default= 2.0 C.)

MainLoop:
If PORTB.0=0 Then ' Mode switch pressed
Pause 50 ' Debounce
LcdOut $FE, $8F, "*" ' Show that command is accepted
If PORTB.0=0 Then MainLoop ' Wait until button is released
Mode=Mode+1 ' Increment mode
If Mode=2 Then ' Save Target Temperature (Mode1 -> Mode2)
Write 0, TargetTemp / 256 ' TargetTemp MSB
Write 1, TargetTemp MOD 256 ' TargetTemp LSB
EndIf
If Mode > 2 Then ' Save Hysteresis (Mode 2 -> Mode 0)
Mode=0 ' Only 0, 1, 2 are valid
Write 2, Hyst / 10 ' Divide Hyst value to fit in Byte
EndIf
EndIf

If Mode =1 Then ' Set Target Temperature
LcdOut $FE, $80, "SET TEMPERATURE " ' Show function
V=TargetTemp ' TargetTemp in V
GoSub SelectSign ' Select +/blank/-
GoSub DisplayTemp ' Display Target Temperature
If (PORTB.1=0) Or (PORTB.2=0) Then ' Up or Down button pushed
If PORTB.2=0 Then ' Down button
If TargetTemp > 7500 Then ' Not lower than -25 C. (10000-MinTemp * 100)
TargetTemp=TargetTemp-25 ' Decrease temperuture with 0.25 C.
EndIf
EndIf
If PORTB.1=0 Then ' Up button
If TargetTemp < 17500 Then ' Not higher than 75 C. (10000+MaxTemp * 100)
TargetTemp=TargetTemp+25 ' Increase temperature with 0.25 C.
EndIf
EndIf
GoSub SetTargetTemp ' Display TargetTemp and delay 0.25 Sec.
EndIf
EndIf

If Mode=2 Then ' Set Hysteresis
LcdOut $FE, $80, "HYSTERESIS " ' Show function
Sign=" " ' No sign
V= 10000+Hyst ' Set value for V
GoSub DisplayTemp ' Display Hysteresis
If (PORTB.1=0) Or (PORTB.2=0) Then ' Up or down button pushed
Sign=" " ' No sign for Hysteresis
If PORTB.2=0 Then ' Down button
If Hyst > 10 Then Hyst=Hyst-10 ' Not less than 0.1 C.
EndIf
If PORTB.1=0 Then ' Up button
If Hyst < 1000 Then Hyst=Hyst+10 ' Not more than 10.0 C.
EndIf
V= 10000+Hyst ' Set value for V
GoSub DisplayTemp ' Display Hysteresis
Pause 250 ' Delay 0.25 Sec.
EndIf
EndIf

If Mode > 0 Then MainLoop ' Setting TargetTemperature or Hysteresis

LcdOut $FE, $80, "TEMPERATURE " ' Show function

Output DQ ' Make Pin Output
DQ=0 ' OneWire line Low
PauseUs 480 ' Keep down for 480 µS
Input DQ ' Make Pin Input
PauseUs 70 ' Wait 70 µS
If DQ=1 Then ' No presence pulse from DS1820
LcdOut $FE, $1, "** No sensor! **" ' Show message
Pause 500 ' Wait 0.5 Sec.
GoTo MainLoop ' Check again
EndIf

OWOut DQ, 1, [$CC, $44] ' Start temperature conversion
WaitLoop: OWIn DQ, 4, [Count_Remain] ' Check for still busy converting
If Count_Remain = 0 Then WaitLoop ' Busy
OWOut DQ, 1, [$CC, $BE] ' Read the temperature
OWIn DQ, 0, [Temperature.LowByte, Temperature.HighByte, Skip 4, Count_Remain, Count_Per_C]
Temperature = (((Temperature >> 1) * 100) - 25) + (((Count_Per_C - Count_Remain) * 100) / Count_Per_C)
If Temperature > 32767 Then
Temperature= ~Temperature
V= 10000 - Temperature ' 25 C=12500 0 C=10000 -10 C=9000
Else
V= 10000 + Temperature
EndIf

If V < TargetTemp - Hyst Then ' Below Target temperature - Hysteresis
PORTA.2=1 ' Activate Warm Output
PORTA.3=0 ' Deactivate Cold Output
EndIf

If V > TargetTemp + Hyst Then ' Above Target temperature + Hysteresis
PORTA.2=0 ' Deactivate Warm output
PORTA.3=1 ' Activate Cold Output
EndIf

GoSub SelectSign ' +/blank/- Sign
GoSub DisplayTemp ' Temperature to LCD

GoTo MainLoop ' Do it forever

' SUBROUTINES:
'----------------------------------------
SelectSign:
If v = 10000 Then ' Temperature = 0 C.
Sign=" " ' No sign
Else
If v < 10000 Then ' <> 0
Sign="-" ' Temperature below 0 C.
Else
Sign="+" ' Temperature above 0 C.
EndIf
EndIf
Return

'----------------------------------------
DisplayTemp:
If V >= 10000 Then ' Above 0 C.
Temperature=V-10000
Else
Temperature=10000-V ' Below 0 C.
EndIf
LcdOut $FE, $C0, Sign, Dec (Temperature / 100), ".", DEC2 Temperature, " ",223,"C "
Return

'-----------------------------------------
SetTargetTemp:
V=TargetTemp
GoSub SelectSign
GoSub DisplayTemp
Pause 250
Return

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

Volgende code werkt goed voor proton heb getest door sensor in vrieskist te doen gaf netjes - aan


Device = 16F877
Config WDT_OFF, PWRTE_ON, HS_OSC
XTAL = 4

TRISA= %11111111                       
TRISB= %11111111 			

ALL_DIGITAL=true
PORTB_PULLUPS=true
OPTIMISER_LEVEL = 0

Declare LCD_TYPE 0
Declare LCD_DTPIN PORTD.4 ; Used for 4-line.
Declare LCD_ENPIN PORTD.3 ; e line
Declare LCD_RSPIN PORTD.2 ; r/s line
Declare LCD_INTERFACE 4 ; 4 bits interface

Temperature 	Var	Word		' Temperature storage
V		Var	Word		' Var. for display
Count_Remain 	Var 	Byte		' Count remaining
Count_Per_C 	Var	Byte		' Count per degree C
Sign		Var	Byte		' +/- sign
DQ		Var	PORTA.0		' One-wire data pin





Print $FE, 1, $FE, $0C                 ' Clear display, cursor off


MainLoop: 
GoSub MeetTemperatuur 



Print $FE, $80, "TEMPERATURE     "    ' Show function

 Output DQ             			' Make Pin Output
 DQ=0					' OneWire line Low
 DelayUS 480                            ' Keep down for 480 µS  
 Input DQ                               ' Make Pin Input
 DelayUS 70                             ' Wait 70 µS
 If DQ=1  Then                           ' No presence pulse from DS1820   
  Print $FE, $1, "** No sensor! **"    ' Show message
  
  DelayMS 500                             ' Wait 0.5 Sec. 
  GoTo MainLoop                         ' Check again
  EndIf

 

 

 

 GoSub SelectSign                       ' +/blank/- Sign 
 GoSub DisplayTemp                      ' Temperature to LCD

GoTo MainLoop				' Do it forever

' SUBROUTINES:
'----------------------------------------
MeetTemperatuur:
   OWrite DQ, 1, [$CC, $44]       		' Start temperature conversion
WaitLoop: ORead DQ, 4, [Count_Remain]	' Check for still busy converting
 If Count_Remain = 0 Then WaitLoop      ' Busy 
 OWrite DQ, 1, [$CC, $BE]		' Read the temperature
 ORead DQ, 0, [Temperature.LowByte, Temperature.HighByte, Skip 4, Count_Remain, Count_Per_C]
 Temperature = (((Temperature >> 1) * 100) - 25) + (((Count_Per_C - Count_Remain) * 100) / Count_Per_C)
 If Temperature > 32767 Then
  Temperature= ~Temperature
  V= 10000 - Temperature                ' 25 C=12500  0 C=10000  -10 C=9000 
 Else
  V= 10000 + Temperature
 EndIf
 Return

'----------------------------------------
SelectSign:
 If v = 10000 Then                      ' Temperature = 0 C.
  Sign=" " 				' No sign
 Else 
  If v < 10000 Then              	' <> 0
   Sign="-"				' Temperature below 0 C. 	
  Else
   Sign="+"				' Temperature above 0 C.
  EndIf
 EndIf
Return

'----------------------------------------
DisplayTemp:
 If V >= 10000 Then                     ' Above 0 C.      
  Temperature=V-10000                   
 Else                                   
  Temperature=10000-V                   ' Below 0 C. 
 EndIf
 Print $FE, $C0, Sign, Dec (Temperature / 100), ".", DEC2 Temperature, " ",223,"C "
Return
'----------------------------------------