PropBASIC subroutines are not low-level code; what they do is save space by compiling high-level commands like OWWRITE into one location. I haven't used PropBASIC in a long time, but I have used it and know it's possible.
I'm using a 1-Wire thermometer in my latest product development project, so I freshened up my code. Yes, this is Spin, but Spin is easy to read and the code is documented. You should be able to translate it to PropBASIC with just a little effort. At present, the code expects one device on the line so that it can read the serial number (1W search is a big chunk of code that I haven't adapted to Spin). After it has the serial number it uses that to read back the temperature; this will show you how to use the MATCH ROM command.
As has been suggested, all of the necessary details are in the device documentation.
Yes. Read the datasheet, especially the section I pointed you to, and compare that to Jon's spin code. It doesn't matter whether or not you write in spin; I don't either, but it isn't that difficult to figure out what his code is doing. Be aware that I haven't used one-wire devices in any of my projects, so this is as new to me as it is to you.
The datasheet example I pointed you to starts off with sending a reset. Jon's code starts off with ow.reset. That should make sense. PropBasic has OWRESET.
Next, the devices respond with a "presence" pulse. Apparently Jon doesn't bother to look for that. It just shows there are devices on the bus.
Next, send a MATCH ROM command. Jon does: ow.write(MATCH_ROM). Again, pretty obvious. MATCH_ROM is $55, as you know. In PropBasic, that's OWWRITE DQpin, $55\8.
Next, send the 64-bit serial number. Jon suggested you communicate a byte at a time, and he represents the s/n as an array of 8 bytes. His code uses a loop to transmit the array contents, a byte at a time.
Next, send the convert T command ($44). Nothing hard here, it's just ow.write(CVRT_TEMP). Naturally you need to change that into PropBasic syntax.
Now, if you had read that "1 Wire Bus System" section I suggested, you'd know that during a temperature conversion, the device will return a 0. When the conversion is done, it returns a 1. Jon uses a loop to continuously read the state of the line and tests to see if it has changed from 0 to 1. When it does, he knows the conversion is complete. The example talks about holding the line high, but that's if the device is powered through the data line which you apparently aren't doing since your working code doesn't have that step. If you power the device with a connection to the Vdd line, it's not necessary. That's all in the datasheet, which I took the time to look over. It's your project, shouldn't you take the time to study it?
In your previous attempts, instead of testing to see if the conversion was complete, you added PAUSE 750, which just waits long enough. The datasheeet states that the max conversion time is 750 ms, so either way should work. If the conversion completes in less than 750 ms, Jon's way won't waste extra time and will be faster.
So by now you've told a specific sensor to do a conversion, and it has data you want to read. If you look at the example, you'll see that to get those data, you need to repeat the process of sending the serial number. Jon repeats the ow.reset, ow.write(MATCH_ROM), and the loop to send the 8 bytes of the s/n.
You can take it from there. If you run into something in the Spin code you don't understand, look in the Propeller Manual, where Spin commands are documented. Use Google to find out how others have done things, and be prepared to experiment. You say your expertise isn't writing low-level code, but this really isn't all that low-level. Bean did the low-level part when he included the one-wire commands in PropBasic. Jon provided working code, which shows the steps to get data from a specific device on a 1-wire bus, and his code is pretty easy to match up to the datasheet example. If this all seems too complex, you need to back up and start with some simpler projects and work your way up to this.
[edit] Sorry that I wasn't paying attention to see if anyone else had posted, so I was referring to Jon's earlier post.
Not true. My reset() method looks for the presence pulse and provides a 2-bit line status response to the caller. The presence pulse is how my code knows there is something connected to the bus. Here's the PASM code for reset and presence detection.
' -----------------
' Reset 1-Wire bus
' -----------------
'
' %00 = bus short
' %01 = bad response; possible interference on bus
' %10 = good bus & presence detection
' %11 = no device
owreset mov value, #%11 ' assume no device
or dira, owmask ' bus low
mov usecs, #500 ' reset pulse
call #delayus
andn dira, owmask ' release bus
mov usecs, #5
call #delayus
test owmask, ina wc ' sample for short, 1W -> C
muxc value, #%10 ' C -> value.1
mov usecs, #70
call #delayus
test owmask, ina wc ' sample for presence, 1W -> C
muxc value, #%01 ' C -> value.0
mov usecs, #400
call #delayus
wrlong value, iopntr ' update hub
jmp #cmdexit
I shoulda known that was a bogus assumption! Thanks for the clarification, and the code.
[edit] I just checked the PropBasic docs, and OWRESET DQPin{,statusVar} suggests that Bean's reset probably tests the presence pulse too, and returns a value in statusVar.
Okay, I give. Where can I get the latest PropBASIC binary, and which IDE is best suited for it? You're doing things the hard way and I can't endure the pain any longer.
Discovery, why the reset after the command to read the scratchpad? That's not in the example, and I suspect it will derail the read. Also, you should not need the PAUSE 750 except after you send the convert command. That's to allow time for the temperature conversion, not the one-wire bus.
Jon, I still use the ancient version of PropBasic with BST. I think PropellerIDE now works with the current version of PropBasic, but I haven't used it.
Notice that in the code that works, you don't send a reset after the command to read the scratchpad.
In the code you are trying to get working, you do. Shouldn't that suggest you don't want to send that reset? Don't you think that resetting the device probably cancels the command you just sent?
Okay. I'm guessing you have a byte order problem with the 64-bit serial number. I didn't see the byte order clearly stated in the datasheet, but it does say that $10 is the family code for the device, which is the least significant byte.
Jon's most recent code appears to read the s/n in the same byte order as it sends it, and if you look at the left side of the flowchart on pg 16 of the datasheet (ROM commands), the $33 Read ROM appears to be LSB first. Your code send MSB first (the $10 family code is last, and I think that's backwards).
Since I don't have a DS18S20, I can't test my assumptions, but I think that might be the problem. Maybe Jon can shed some light on this.
I tried reversing the 64 bit ID earlier but that was with the 32, 24 and 24-bit configuration. I will reverse the code in the byte configuration. Hopefully, that will correct the problem.
The code compiles fine. My feeling is that there needs to be at least another instruction sent to the DS18S20 to complete the MATCH function. At this point I have no idea.
Try this code, replace with your serial number from your ds18b20.
Made with bst basic.
Well, basic is very difficult, spin is 10 times easier.
' Reads the temperature from a Dallas DS18B20
' Converts it to ascii and sends it to the PC
' Connect DS18B20 DQ pin to PIN 1 on the propeller
' Don't forget the 4.7K pullup resistor too...
'
DEVICE P8X32A, XTAL1, PLL16X
FREQ 80_000_000
' Define CONs
Baud CON "T115200"
' Define PINs
DQPin PIN 1 INPUT ' 1-Wire communication pin to DS18B20
TX PIN 30 HIGH ' Send data back to PC
' Define DATA (DATA, WDATA, LDATA)
Message DATA "The temperature is "
TempWhole DATA "1234."
TempFrac DATA "1234 Degrees C", 13, 0
' Define variables (LONGs only)
temp VAR LONG
value VAR LONG ' Temperature
' Start of main code
PROGRAM Start
Start:
' Main code loop
DO
' Perform a temperature conversion
OWRESET DQPin
OWWRITE DQPin, $44CC\16 ' SkipROM($CC) & Convert($44)
PAUSE 750 ' Wait for conversion
' Read temperature value
' OWRESET DQPin
' OWWRITE DQPin, $BECC\16 ' SkipROM($CC) & Read Scratch($BE)
' OWREAD DQPin, value\16
' Read temperature value
OWRESET DQPin
OWWRITE DQPin, $55\8 'Match($55)
OWWRITE DQPin, $3A13F128\32 'MATCH 64 bit serial number
OWWRITE DQPin, $A4000004\32 'Number backwards
OWWRITE DQPin, $BE\8 ' Read Scratch($BE)
OWREAD DQPin, value\16
' Sign extend value from 16 bits to 32 bits
\ SHL value,#16
\ SAR value,#16
' Convert value to ascii
temp = value / 16 ' Get whole value
tempWhole = STR temp, 4, 7 ' Signed leading spaces, no zero terminator
temp = value AND 15 ' Get fractional value
temp = temp * 625 ' 10000 / 16
tempFrac = STR temp, 4, 4 ' Unsigned leading zeros, no zero terminator
' Output temperature message to PC
SEROUT TX, Baud, Message
LOOP
END
28F1133A040000A4 my serial number
1 2 3 4 5 6 7 8 bytes
28 F1 13 3A 04 00 00 A4 serial number
8 7 6 5 4 3 2 1 bytes backward
A4 00 00 04 3A 13 F1 28 serial number backward
first send byte 1 to 4
OWWRITE DQPin, $3A13F128\32 'MATCH 64 bit serial number
then send byte 5 to 8
OWWRITE DQPin, $A4000004\32 'Number backwards
10848293020800D5 yours serial number
1 2 3 4 5 6 7 8 bytes
10 84 82 93 02 08 00 D5 serial number
8 7 6 5 4 3 2 1 bytes
D5 00 08 02 93 82 84 10 serial númber backwards
first send byte 1 to 4
OWWRITE DQPin, $93828410\32 'MATCH 64 bit serial number
then send byte 5 to 8
OWWRITE DQPin, $D5000802\32 'Number backwards
I would never have guessed that configuration of bytes.
You seem to be in tune with PropBasic and DS devices. You solved one of my two problems for upgrading my factory control system. The first was reading several temperatures in the process.
The second problem is reading the four analog voltages from the DS2450 and setting the four digital outputs for a DS2450. The match device is now understood...are there additional tricks for interfacing PropBasic with the DS2450?
Incidentally, how do I get the TX output from my Propeller Activity Board into the laptop computer for temperature display?
Comments
I'm using a 1-Wire thermometer in my latest product development project, so I freshened up my code. Yes, this is Spin, but Spin is easy to read and the code is documented. You should be able to translate it to PropBASIC with just a little effort. At present, the code expects one device on the line so that it can read the serial number (1W search is a big chunk of code that I haven't adapted to Spin). After it has the serial number it uses that to read back the temperature; this will show you how to use the MATCH ROM command.
As has been suggested, all of the necessary details are in the device documentation.
Yes. Read the datasheet, especially the section I pointed you to, and compare that to Jon's spin code. It doesn't matter whether or not you write in spin; I don't either, but it isn't that difficult to figure out what his code is doing. Be aware that I haven't used one-wire devices in any of my projects, so this is as new to me as it is to you.
The datasheet example I pointed you to starts off with sending a reset. Jon's code starts off with ow.reset. That should make sense. PropBasic has OWRESET.
Next, the devices respond with a "presence" pulse. Apparently Jon doesn't bother to look for that. It just shows there are devices on the bus.
Next, send a MATCH ROM command. Jon does: ow.write(MATCH_ROM). Again, pretty obvious. MATCH_ROM is $55, as you know. In PropBasic, that's OWWRITE DQpin, $55\8.
Next, send the 64-bit serial number. Jon suggested you communicate a byte at a time, and he represents the s/n as an array of 8 bytes. His code uses a loop to transmit the array contents, a byte at a time.
Next, send the convert T command ($44). Nothing hard here, it's just ow.write(CVRT_TEMP). Naturally you need to change that into PropBasic syntax.
Now, if you had read that "1 Wire Bus System" section I suggested, you'd know that during a temperature conversion, the device will return a 0. When the conversion is done, it returns a 1. Jon uses a loop to continuously read the state of the line and tests to see if it has changed from 0 to 1. When it does, he knows the conversion is complete. The example talks about holding the line high, but that's if the device is powered through the data line which you apparently aren't doing since your working code doesn't have that step. If you power the device with a connection to the Vdd line, it's not necessary. That's all in the datasheet, which I took the time to look over. It's your project, shouldn't you take the time to study it?
In your previous attempts, instead of testing to see if the conversion was complete, you added PAUSE 750, which just waits long enough. The datasheeet states that the max conversion time is 750 ms, so either way should work. If the conversion completes in less than 750 ms, Jon's way won't waste extra time and will be faster.
So by now you've told a specific sensor to do a conversion, and it has data you want to read. If you look at the example, you'll see that to get those data, you need to repeat the process of sending the serial number. Jon repeats the ow.reset, ow.write(MATCH_ROM), and the loop to send the 8 bytes of the s/n.
You can take it from there. If you run into something in the Spin code you don't understand, look in the Propeller Manual, where Spin commands are documented. Use Google to find out how others have done things, and be prepared to experiment. You say your expertise isn't writing low-level code, but this really isn't all that low-level. Bean did the low-level part when he included the one-wire commands in PropBasic. Jon provided working code, which shows the steps to get data from a specific device on a 1-wire bus, and his code is pretty easy to match up to the datasheet example. If this all seems too complex, you need to back up and start with some simpler projects and work your way up to this.
[edit] Sorry that I wasn't paying attention to see if anyone else had posted, so I was referring to Jon's earlier post.
[edit] I just checked the PropBasic docs, and OWRESET DQPin{,statusVar} suggests that Bean's reset probably tests the presence pulse too, and returns a value in statusVar.
The following is the actual code that compiles but does not read temperature. It appears to meet all the requirements in the data sheet.
OWRESET DQPin
PAUSE 750
OWWRITE DQPin, $55\8 'MATCH
OWWRITE DQPin, $D5\8
OWWRITE DQPin, $00\8
OWWRITE DQPin, $08\8
OWWRITE DQPin, $02\8
OWWRITE DQPin, $93\8
OWWRITE DQPin, $82\8
OWWRITE DQPin, $84\8
OWWRITE DQPin, $10\8
PAUSE 750
OWWRITE DQPin, $44\8 'CONVERT
PAUSE 750
OWWRITE DQPin, $55\8 'MATCH
OWWRITE DQPin, $D5\8
OWWRITE DQPin, $00\8
OWWRITE DQPin, $08\8
OWWRITE DQPin, $02\8
OWWRITE DQPin, $93\8
OWWRITE DQPin, $82\8
OWWRITE DQPin, $84\8
OWWRITE DQPin, $10\8
PAUSE 750
OWWRITE DQPin, $BE\8 'READ SCRATCH PAD
OWRESET DQPin
PAUSE 750
OWREAD DQPin, value\16
\SHL value,#16
\SAR value,#16
The ID of the DS18S20 was read by a BS2p and verified as correct.
I don't see a problem here.
Discovery
Jon, I still use the ancient version of PropBasic with BST. I think PropellerIDE now works with the current version of PropBasic, but I haven't used it.
OWRESET DQPin
PAUSE 750
OWWRITE DQPin, $44CC\16 'SKIP & CONVERT
OWRESET DQPin
PAUSE 750
OWWRITE DQPin, $BECC\16 'SKIP & READ SCRATCH PAD
OWREAD DQPin, value\16 'READ THE TEMPERATURE
\SHL value,#16
\SAR value,#16
No problem at all here.
Discovery
In the code you are trying to get working, you do. Shouldn't that suggest you don't want to send that reset? Don't you think that resetting the device probably cancels the command you just sent?
Discovery
Discovery
Jon's most recent code appears to read the s/n in the same byte order as it sends it, and if you look at the left side of the flowchart on pg 16 of the datasheet (ROM commands), the $33 Read ROM appears to be LSB first. Your code send MSB first (the $10 family code is last, and I think that's backwards).
Since I don't have a DS18S20, I can't test my assumptions, but I think that might be the problem. Maybe Jon can shed some light on this.
Discovery
OWRESET DQPin
PAUSE 750
OWWRITE DQPin, $55\8 'MATCH
OWWRITE DQPin, $10\8
OWWRITE DQPin, $84\8
OWWRITE DQPin, $82\8
OWWRITE DQPin, $93\8
OWWRITE DQPin, $02\8
OWWRITE DQPin, $08\8
OWWRITE DQPin, $00\8
OWWRITE DQPin, $D5\8
PAUSE 750
OWWRITE DQPin, $44\8 'CONVERT
PAUSE 750
OWWRITE DQPin, $55\8 'MATCH
OWWRITE DQPin, $10\8
OWWRITE DQPin, $84\8
OWWRITE DQPin, $82\8
OWWRITE DQPin, $93\8
OWWRITE DQPin, $02\8
OWWRITE DQPin, $08\8
OWWRITE DQPin, $00\8
OWWRITE DQPin, $D5\8
PAUSE 750
OWWRITE DQPin, $BE\8 'READ SCRATCH PAD
PAUSE 750
OWREAD DQPin, value\16
\SHL value,#16
\SAR value,#16
The code compiles fine. My feeling is that there needs to be at least another instruction sent to the DS18S20 to complete the MATCH function. At this point I have no idea.
Discovery
Made with bst basic.
Well, basic is very difficult, spin is 10 times easier.
Discovery
I don't understand the following code...
OWWRITE DQPin, $3A13F128\32 'MATCH 64 bit serial number
OWWRITE DQPin, $A4000004\32 'Number backwards
The ID number to match is 10848293020800D5.
How did you arrive at $3A... and $A4...?
Sincerely,
Discovery
Discovery
Perfect...that works!
I would never have guessed that configuration of bytes.
You seem to be in tune with PropBasic and DS devices. You solved one of my two problems for upgrading my factory control system. The first was reading several temperatures in the process.
The second problem is reading the four analog voltages from the DS2450 and setting the four digital outputs for a DS2450. The match device is now understood...are there additional tricks for interfacing PropBasic with the DS2450?
Incidentally, how do I get the TX output from my Propeller Activity Board into the laptop computer for temperature display?
Discovery