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 
Lithium
Zeg me wat je nodig hebt en ik zal je vertellen hoe je zonder kunt
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 
Lithium
Zeg me wat je nodig hebt en ik zal je vertellen hoe je zonder kunt
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 
Doet hij het binnen wel goed? heb je dat al eens geprobeerd?
Lithium
Zeg me wat je nodig hebt en ik zal je vertellen hoe je zonder kunt
Op 8 januari 2009 11:24:49 schreef Boeip:
De schakeling die hier op CO staat is _niet_ voor temperaturen onder nuldan 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%)]
Frits Kieftenbelt
Ohm sweet Ohm | www.picbasic.nl
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.
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
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)
Frits Kieftenbelt
Ohm sweet Ohm | www.picbasic.nl
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.
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
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...
Frits Kieftenbelt
Ohm sweet Ohm | www.picbasic.nl
Ok, ik was weer wat te kort door de bocht
.
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.
EdwinNadorp
Koop hier uw kristallen bol - in 2008 ga ik m'n projecten afmaken, echt waar ....... nouja in 2009 dan ..... ehh 2010 ....
flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
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...
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Hij bedoelt dat je van word naar byte integer moet gaan.
Word is alleen positief, integer is signed (+/-)
blaauwad
I like the smell of melting solderwire
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
'-----------------------------------------
flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
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
'----------------------------------------