dallas 1 wire.. does it matter which pin I define?
-
- Posts: 35
- Joined: 22 August 2009, 16:34 PM
dallas 1 wire.. does it matter which pin I define?
on a ZX-328n does it matter which pin I define as my dallas 1 wire pin? and can I define more than one pin as a 1 wire pin?
I am going to have 3 temperature sensors on the controller... and I know I can chain them, however im trying to make it easy if a sensor goes bad i dont have to deal with code that finds out the new sensor's address, I can just hook it up and go...
if I want to run them parasitically do I just need to set my DQ pin as zxinputtristate after my 1 wire command? or will the ZX release the line after the 1 wire command and the pullup can hold it high for the conversion?
-Christopher
I am going to have 3 temperature sensors on the controller... and I know I can chain them, however im trying to make it easy if a sensor goes bad i dont have to deal with code that finds out the new sensor's address, I can just hook it up and go...
if I want to run them parasitically do I just need to set my DQ pin as zxinputtristate after my 1 wire command? or will the ZX release the line after the 1 wire command and the pullup can hold it high for the conversion?
-Christopher
Re: dallas 1 wire.. does it matter which pin I define?
Any I/O pin will work and you can use as many as you wish.cadillackid wrote:on a ZX-328n does it matter which pin I define as my dallas 1 wire pin? and can I define more than one pin as a 1 wire pin?
The 1-wire command will leave the output in zxInputTriState mode so you needn't do anything.cadillackid wrote:if I want to run them parasitically do I just need to set my DQ pin as zxinputtristate after my 1 wire command?
The sample code below may be useful as a starting point. The reported values correlate well with a nearby digital thermometer when the DS18S20 is powered. However, in parasitic mode the reported values seem to be several degrees high. I don't know why this occurs but it could be an issue with the timing.
Code: Select all
' This code is intended for the DS18S20 temperature chip. The
' code assumes the presence of a single device on the 1-wire bus.
Const owPin as Byte = 14 ' the pin to which the DQ line is connected
Sub Main()
Dim temp as Single
Do
temp = readTemp()
Debug.Print "The temperature is "; Fmt(temp, 1); "*C";
Debug.Print ", "; Fmt((temp + 40.0) * (9.0 / 5.0) - 40.0, 1); "*F"
Call Delay(1.0)
Loop
End Sub
'
'' readTemp
'
' Request a temperature conversion and read the result. The
' return value is in degrees Centigrade.
'
Function readTemp() as Single
Dim b as Byte
Dim data(1 to 9) as Byte
' initialize the 1-wire interface (return value is the "presence" bit)
b = Reset1Wire(owPin)
Call Delay(0.750)
' initiate a conversion
data(1) = &Hcc ' "skip ROM" command
data(2) = &H44 ' conversion command
Call Put1WireData(owPin, data, 2)
' delay to allow for the conversion
Call Delay(0.750)
' send another reset pulse
b = Reset1Wire(owPin)
' prepare to read the data
data(1) = &Hcc ' "skip ROM" command
data(2) = &Hbe ' "read scratchpad" command
Call Put1WireData(owPin, data, 2)
' read the data
Call Get1WireData(owPin, data, 9)
' compute the temperature
Dim ival as Integer Alias data(1)
readTemp = CSng(ival) / 2.0
End Function
- Don Kinzer
-
- Posts: 35
- Joined: 22 August 2009, 16:34 PM
interesting you mention the correlation between parasite and Vdd power.. I have a mixture in my home automation system and have noticed that they vary quite a bit even in similar vicinity... .. so I looked through my setup and sure enough the variances come from ones that are powered versus parasite... i think I'll just power them all... its pretty easy to do...
the biggest issue ive ever had with these sensors even in my basic stamp was setting the resolution from 12 bit to 9 bit... somehow I never can get the hang of just sending the 2 bits to it that are required so it never takes... I end up hooking them to a program on a PC through a DS9097u and setting resolution that way.....
have you ever changed resolution on them?
for HVAC apps 9 bit is good enough and they are faster in that mode....
-Christopher
the biggest issue ive ever had with these sensors even in my basic stamp was setting the resolution from 12 bit to 9 bit... somehow I never can get the hang of just sending the 2 bits to it that are required so it never takes... I end up hooking them to a program on a PC through a DS9097u and setting resolution that way.....
have you ever changed resolution on them?
for HVAC apps 9 bit is good enough and they are faster in that mode....
-Christopher
-
- Posts: 57
- Joined: 27 July 2009, 14:20 PM
- Location: Groningen, The Netherlands
- Contact:
-
- Posts: 35
- Joined: 22 August 2009, 16:34 PM
the DS18B20 are the ones I use and are configurable resolution... I buy them from Crystalfontz.. they are already on a whip and have connectors attached... much easier for me than having to fab up whips onto the TO-92 package... of course they ship as 12 Bit and I want them at 9 bit...
I probably have 30 of these things in service around my House... some of them have been out in the rain for close to 5 years without fail(I dip them in clear fingernail polish.. seals but doesnt insulate)...
-Christopher
I probably have 30 of these things in service around my House... some of them have been out in the rain for close to 5 years without fail(I dip them in clear fingernail polish.. seals but doesnt insulate)...
-Christopher
-
- Posts: 35
- Joined: 22 August 2009, 16:34 PM
how long does a reset1wire usually take?
do I need to wait 750 milliseconds before issuing the conversion command?
is that time so that the bus can stabilize back at its high pullup state?
im going to use the 9 bit mode so I wont likely wait .750 seconds for a conversion... however jusdt wondering about the reset..
-Christopher
do I need to wait 750 milliseconds before issuing the conversion command?
is that time so that the bus can stabilize back at its high pullup state?
im going to use the 9 bit mode so I wont likely wait .750 seconds for a conversion... however jusdt wondering about the reset..
-Christopher
Reset1Wire() consumes about 1mS. An additional delay may be required, depending on your device, for it to become ready to respond to read/write operations. The datasheet for the DS18S20, for example, doesn't mention any required delay after a reset before read/write operations may take place.cadillackid wrote:how long does a reset1wire usually take?
The datasheet for the DS18S20 indicates that the maximum time required for a conversion is 750mS. That's why the example code delays that long before reading the result. I believe that there is a way to determine when the conversion is complete. If so, implementing that would allow the defined delay to be eliminated.cadillackid wrote:do I need to wait 750 milliseconds before issuing the conversion command? is that time so that the bus can stabilize back at its high pullup state?
- Don Kinzer
-
- Posts: 35
- Joined: 22 August 2009, 16:34 PM
Ok so im a little bit confused here... it "LOOKS" like my 1 wire is working but im getting some wierd values and not understanding part of the code....
so here is a snippet of the code im running..
I have 1 sensor connected and powered to my ZX board....
here is the output I get from the above program:
this sensor is still in its factory default of 12 bit config i havent changed it.. when i convert the "19" to degrees F its in the right vicinity of being correct... within a degree so I know im reading the sensor... but why am I getting the 137.5?? and what does that part of the code do? im confused?
also trying to figure out how I will read negative numbers.... (these are heatpumps and the freon line temps will go below freezing in defrost cycles)
so here is a snippet of the code im running..
Code: Select all
c = reset1wire(supplypin)
call delay (0.1)
if c=0 then
supply(1)=&Hcc
supply(2)=&H44
call put1wiredata(supplypin,supply,2)
debug.print "Supply Air Sensor Present"
' delay to allow for the conversion
Call Delay(0.750)
' prepare to read the data
c = reset1wire(supplypin)
supply(1) = &Hcc ' "skip ROM" command
supply(2) = &Hbe ' "read scratchpad" command
Call Put1WireData(supplypin, supply, 2)
' read the data
Call Get1WireData(supplypin, supply, 9)
' compute the temperature
Dim ival as Integer Alias supply(1)
debug.print "raw data:";supply(1)
supplyairc = CSng(ival) / 2.0
debug.print "supply temp:";supplyairc
Else
debug.print "No Supply Air Sensor"
supplyairc=99.9
end if
here is the output I get from the above program:
Code: Select all
>Getting temp
Supply Air Sensor Present
raw data:19
supply temp:137.5
also trying to figure out how I will read negative numbers.... (these are heatpumps and the freon line temps will go below freezing in defrost cycles)
The code needs to be changed for the DS18B20 because the values it returns have different meaning than for the DS18S20.cadillackid wrote:but why am I getting the 137.5?? and what does that part of the code do?
For the DS18S20, the temperature value is returned in the first two of the nine scratchpad bytes. This value is a signed 16-bit value that expresses the temperature in units of 0.5*C. Consequently, +25*C will be represented as the value 50 while -10*C will be represented as -20. The example code (reproduced in part below) exploits the Alias feature of ZBasic to allow the first two bytes of the data in the buffer to be treated as a 16-bit Integer value. The second line in the excerpt below then converts the value from units of 0.5*C to 1*C.
Code: Select all
' compute the temperature
Dim ival as Integer Alias data(1)
readTemp = CSng(ival) / 2.0
Code: Select all
' compute the temperature
Dim ival as Integer Alias data(1)
readTemp = CSng(ival) / 16.0
The datasheet indicates that the returned value is a 16-bit signed value so representing negative temperature levels is no problem. You should modify your code to output both bytes of the raw temperature data rather than only the low byte.cadillackid wrote:also trying to figure out how I will read negative numbers.
Code: Select all
' compute the temperature
Dim ival as Integer Alias supply(1)
debug.print "raw data:";ival
supplyairc = CSng(ival) / 16.0
debug.print "supply temp:";supplyairc
- Don Kinzer
Also note that if you change the resolution you also need to change the conversion formula:
Code: Select all
t = CSng(ival) / 16.0 ' 12-bit mode
t = CSng(ival) / 8.0 ' 11-bit mode
t = CSng(ival) / 4.0 ' 10-bit mode
t = CSng(ival) / 2.0 ' 9-bit mode
- Don Kinzer
-
- Posts: 35
- Joined: 22 August 2009, 16:34 PM
that makes total sense and my value (though the temp seems low) is working better now... I just cant seem for the life of me to get the resolution changed to 9 bits... this is the code im trying to do it with... but seems my config register never "takes"
yes its a little messy but its test code so go easy on me....
here is the reading I get when I take a conversion after the above code and write out the scratchpade..
my config register is still 127 instead of 31 indicating those 2 resolution bits never got set....
have you ever changed res?
-Christopher
Code: Select all
f = reset1wire(supplypin)
call delay (0.1)
if f=0 then
supplyres(1)=&Hcc 'skip ROM
supplyres(2)=&H4e 'write 0's to the scratchpad on the chip
supplyres(3)=75 'set the Th and Tl registers
supplyres(4)=70
supplyres(5)=31 'set the config register at 31 which sets resolution to 9 bits
call put1wiredata(supplypin,supplyres,5)
debug.print "Supply Air Sensor Present"
' delay to allow for the writing
Call Delay(0.200)
' send a reset to the device after writing
f = reset1wire(supplypin)
' prepare to read the data
supplyres(1) = &Hcc ' "skip ROM" command
supplyres(2) = &Hbe ' "read scratchpad" command
Call Put1WireData(supplypin, supplyres, 2)
' read the data just for "sequence sake"
Call Get1WireData(supplypin, supplyres, 9)
call delay(0.2)
f = reset1wire(supplypin)
' prepare to copy the data to EEPROM
supplyres(1) = &Hcc ' "skip ROM" command
supplyres(2) = &H48 ' "copy scratchpad" command
Call Put1WireData(supplypin, supplyres, 2)
debug.print "Supply air resolution Changed"
Else
debug.print "No Supply Air Sensor"
end if
here is the reading I get when I take a conversion after the above code and write out the scratchpade..
Code: Select all
>Getting temp
Supply Air Sensor Present
raw data:282
supply temp:17.625
config register127
th register78
tl register70
have you ever changed res?
-Christopher
-
- Posts: 35
- Joined: 22 August 2009, 16:34 PM
Ok i found the problem...
it looks like doing 1 wire in one task or subroutine while there is outputcaptureex or inputcaptureex going on causes issues.. im guessing with timer0....
when I set it up to suspend the routine that talks to the A/C units while I set the resolution it worked like a champ..
I also had noticed that doing conversions was real hit or miss..
so now I just have the routine that talks to the HVAC units call the 1 wire routine after it is done capturing data from the A/C unit so that only 1 wire OR capturing / outputting is going on, not both at the same time.. and all is good..
-Christopher
it looks like doing 1 wire in one task or subroutine while there is outputcaptureex or inputcaptureex going on causes issues.. im guessing with timer0....
when I set it up to suspend the routine that talks to the A/C units while I set the resolution it worked like a champ..
I also had noticed that doing conversions was real hit or miss..
so now I just have the routine that talks to the HVAC units call the 1 wire routine after it is done capturing data from the A/C unit so that only 1 wire OR capturing / outputting is going on, not both at the same time.. and all is good..
-Christopher
The problem is not with Timer0, which is used for the RTC, but with Timer1 which is used for all timed I/O routines.cadillackid wrote:it looks like doing 1 wire in one task or subroutine while there is outputcaptureex or inputcaptureex going on causes issues.. im guessing with timer0....
Unfortunately, the calling sequence for some of the I/O routines has no provision for returning a success/failure code and if the timer that is needed is already being used the routine may just return with no indication of there being a problem. You can work around this issue by making sure that the timer is available before issuing the call. For example:
Code: Select all
Call LockTask()
If (Semaphore(Register.Timer1Busy)) Then
Register.Timer1Busy = False
'invoke I/O routine here that uses Timer1
End If
Call UnlockTask()
Code: Select all
Do
Call LockTask()
If (Semaphore(Register.Timer1Busy)) Then
Register.Timer1Busy = False
'invoke I/O routine here that uses Timer1
Call UnlockTask()
Exit Do
Else
Call Sleep(0) ' this will unlock the task
End If
Loop
- Don Kinzer
-
- Posts: 35
- Joined: 22 August 2009, 16:34 PM
this all makes sense now.. I guess I thought a timer was a read only property that a routine would use to get timing for I/O..
so I assumed that all I/O could occur simultaneously and on multiple pins at once...
I was running a task that talked to the HVAC unit using inputcapture and outputcapture..
I was running a task that set the value of a digital Pot using shiftout
I was running a task that talked to the dallas 1 wire temp sensors...
all were separate tasks running alongside each other..
the main program was what handled serial I/O to the host controller and adjusted variables which the tasks used in their various functions...
I can now see they were all stomping on each other because each needed exclusive use of the timer...
I realized after re evaluating, that I dont need lightning speed nor do I need multi-tasking for each separate I/O function...
so I simply have a single task that handles All I/O and each I/O item is called sequentially after the previous one finishes... the air conditioning unit likes a minimum of 100 ms after each exchange, and there is no maximum.. I can unplug the line for 5 minutes to the A/C unit and then reconnect and it doesnt care it will talk back to me when I talk to it..
so I do all my I/O sequentially and it all works like a champ...
I played around with locking and unlocking tasks and seemed like everytime I ended up in my ZX locking up or a task somewhere in oblivian where it quit responding.. so thats when I went to the sequemtial approach..
-Christopher
so I assumed that all I/O could occur simultaneously and on multiple pins at once...
I was running a task that talked to the HVAC unit using inputcapture and outputcapture..
I was running a task that set the value of a digital Pot using shiftout
I was running a task that talked to the dallas 1 wire temp sensors...
all were separate tasks running alongside each other..
the main program was what handled serial I/O to the host controller and adjusted variables which the tasks used in their various functions...
I can now see they were all stomping on each other because each needed exclusive use of the timer...
I realized after re evaluating, that I dont need lightning speed nor do I need multi-tasking for each separate I/O function...
so I simply have a single task that handles All I/O and each I/O item is called sequentially after the previous one finishes... the air conditioning unit likes a minimum of 100 ms after each exchange, and there is no maximum.. I can unplug the line for 5 minutes to the A/C unit and then reconnect and it doesnt care it will talk back to me when I talk to it..
so I do all my I/O sequentially and it all works like a champ...
I played around with locking and unlocking tasks and seemed like everytime I ended up in my ZX locking up or a task somewhere in oblivian where it quit responding.. so thats when I went to the sequemtial approach..
-Christopher