Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : Multiple 1-Wire devices on same bus?
Author | Message | ||||
ThierryP Newbie Joined: 12/04/2012 Location: NetherlandsPosts: 12 |
Is it possible to read sensor values from more than one 1-wire devices (DS18B20) on the same bus? Has anyone done that? In http://www.thebackshed.com/forum/forum_posts.asp?TID=4741&KW =Onewire there's example code and Iandaus suggests/mentions that this is possible? How? Thanks Thierry |
||||
JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 3804 |
Er... this is a good time to read about 1-wire and google's really good for finding stuff :) It matters how you power them but do some reading and see. John |
||||
ThierryP Newbie Joined: 12/04/2012 Location: NetherlandsPosts: 12 |
Oh, I did google on this and indeed found that it is possible and how to wire that. Problem is that I have not found ways of addressing multiple devices with MMBasic, other than searching for them and finding that they are connected on the 1-wire bus. Sorry, perhaps I should have clearly stated that I wanted to do this in MMBasic. Thierry |
||||
CircuitGizmos Guru Joined: 08/09/2011 Location: United StatesPosts: 1425 |
I haven't tested 1-wire devices on the Maximite, although I am very familiar with them. OWWRITE lets you select a Maximite pin and send data down that pin. If there is only a single 1-wire device on that line, then you don't need to specifically address that device using the device serial number. If there are multiple devices on that line, then to select a specific device you have to address that device using the device serial number. ' Reset device (flag = 1) on pin 3 ' Write 2 bytes "SkipRom" (&hCC) and "Read Scratchpad" (&HBE) OWWRITE 3, 1, 2, &HCC, &HBE ' DS18B20 read 2 bytes of temperature OWREAD 3, 0, 2, byte1, byte2 This single device example is from memory, so I hope I get it right. For multiple devices either you have to search to get the serial numbers for all of the devices on the Maximite pin, or do what I do and temporarily hook them to one pin to get their serial numbers. Then hardcode the serial numbers for each device when they are all on one Maximite pin. Check out the 1-wire documentation for your specific device for the commands that you would use INSTEAD of the 'skip ROM' command to address a device by serial number. You do specifically read them 1 device at a time. Each one uniquely addressed by their own serial number. Micromites and Maximites! - Beginning Maximite |
||||
jman Guru Joined: 12/06/2011 Location: New ZealandPosts: 711 |
hi Are you short of I/O pins ? If not why not use another pin with the next 1wire device on it. John |
||||
ThierryP Newbie Joined: 12/04/2012 Location: NetherlandsPosts: 12 |
I've done as advised and now have 3x DS1820 devices connected on same 1-Wire bus with one 4k7 pull-up resistor to Vcc=3.3V. No long wires yet, will add ~3m wires between MCU and each of the devices. Following program is written in MMBasic 4.0 for Maximite, Duinomite, ... : 'Based on 1WDS1820.BAS 29 March 2012b by Ian Deney
'Example for three DS18X20 devices on the same 1-wire bus 'can be extended to larger number of Devices 'powered mode only 'Devices ID's are hardcoded 'MMBAsic 4.0 'ThierryP 03 November 2012 Pin=18 Dim ar(3,8) '---Device 0 is a DS18B20: ar(0,0)=40 : ar(0,1)=15 : ar(0,2)=8 : ar(0,3)=81 ar(0,4)=3 : ar(0,5)=0 : ar(0,6)=0 : ar(0,7)=183 '---Device 1 is a DS18S20: ar(1,0)=16 : ar(1,1)=215: ar(1,2)=22: ar(1,3)=84 ar(1,4)=2 : ar(1,5)=8 : ar(1,6)=0 : ar(1,7)=181 '---Device 2 is a DS18S20: ar(2,0)=16 : ar(2,1)=146: ar(2,2)=148: ar(2,3)=83 ar(2,4)=2 : ar(2,5)=8 : ar(2,6)=0 : ar(2,7)=229 main: OWReset Pin,presence ' reset If presence = 0 Then Error "No devices found" For Dev=0 To 2 OWReset Pin ' start conversion OWWrite Pin,8,9,&h55,ar(Dev,0),ar(Dev,1),ar(Dev,2),ar(Dev,3),ar(Dev, 4),ar(Dev,5),ar(Dev,6),ar(Dev,7) OWWrite Pin,0,1,&h44 t = Timer ' wait until conversion is done Do If Timer - t > 1000 Then Error "Sensor not responding" OWRead Pin, 4 , 1 , b ' conversion done? Loop Until b = 1 'read temperature from scratchpad and convert to degrees C + or - ' command read data OWWrite Pin,1,9,&h55,ar(Dev,0),ar(Dev,1),ar(Dev,2),ar(Dev,3),ar(Dev, 4),ar(Dev,5),ar(Dev,6),ar(Dev,7) OWWrite Pin,0,1,&hbe OWRead Pin, 2, 2, T1, T2 ' get the data OWReset Pin ' calculate temp depending on device in use If ar(Dev,0)=40 Then 'DS18S22 or DS18B20 is 12 bit If T2 And &b1000 Then 'negative temp 'make 2s complement (1s complement+1) T2 = (T2 Xor &b11111111) T1 = (T1 Xor &b11111111)+1 If T1=1 Then T2=T2+1 'add the carry if required Value = ((T2 And &b111) * 256 + T1) / 16 Value = -Value Else 'positive temp Value = ((T2 And &b111) * 256 + T1) / 16 EndIf ElseIf ar(Dev,0)=16 Then 'DS18S20 or DS1820 is 9bit or calc to 12bit If T2 And &b10000000 Then 'if MSB of T2=1 then negative 'Read 12bit resolution and adjust 'read scratchpad using matchrom to get Count Remaining @byte 7 OWWrite Pin,1,9,&h55,ar(Dev,0),ar(Dev,1),ar(Dev,2),ar(Dev,3),ar(Dev, 4),ar(Dev,5),ar(Dev,6),ar(Dev,7) OWWrite Pin,0,1,&hbe OWRead Pin,0,8,a,b,c,d,e,f,g,h COUNTREM=g 'truncate 0.5deg value (or use integer division \) T1t = T1 And &b11111110 T1t=T1t / 2 'make whole degrees 'add compensation values read from scratchpad T1t16=T1t*16 'make lsb 1/16 degree Value12 = T1t16 -4 +(16 - COUNTREM) 'add 12 bit value 'take 2s complement T1C = (Value12 Xor &b11111111111) + 1 Value = T1C/16 'make decimal value in degrees Value = -Value Else 'positive temp Value = T1 / 2 '9bit value 'Read 12bit resolution and adjust 'read scratchpad using matchrom OWWrite Pin,1,9,&h55,ar(Dev,0),ar(Dev,1),ar(Dev,2),ar(Dev,3),ar(Dev, 4),ar(Dev,5),ar(Dev,6),ar(Dev,7) OWWrite Pin,0,1,&hbe OWRead Pin,0,8,a,b,c,d,e,f,g,h COUNTREM=g T1t = T1 And &b11111110 'truncate 0.5deg(or use integer division \) Value = T1t/2 Value = Value - 0.25 + (16 - COUNTREM) /16 '12 bit value EndIf EndIf Print "Device:"; Dev; " type:"; ar(Dev,0); " Temp:" ; Format$(Value,"% 1.2f") Next Dev Print "------------------------------" Pause 10000 GoTo main Thierry |
||||
Blackened Regular Member Joined: 11/08/2012 Location: AustraliaPosts: 66 |
Forgive me for asking what is possibly obvious for you guys. I've used the previous piece of code in my current project. I'm going through it a line at a time as I have struggled to get my head fully around the whole 1-wire and DS18B20 saga I've changed it a bit so far, getting rid of the array for sensor IDs and using DATA:READ. So far so good. My question is..... can the hex constants be used in the following manner: match_rom = &h55 OWWrite Pin,8,9,match_rom,aa,bb,cc,dd,ee,ff,gg,hh I'm assuming so, but this stuff fries my brain. I wish I did this sort of thing for a living hey. Also, what are the differences between the various flavours of DS18x20 sensors? I intend to optimise the code as I only use the 18B version (and only have the 18B datasheet) and don't need to test for other types. Thanks everyone |
||||
JohnS Guru Joined: 18/11/2011 Location: United KingdomPosts: 3804 |
Using match_rom should be OK. Sorry, I've only used the B variant (not from MMBasic) so can't help with the variants. John |
||||
Blackened Regular Member Joined: 11/08/2012 Location: AustraliaPosts: 66 |
I've been messing around with the 1-wire DS18B20 temperature sensors and have come up with the following code that suits my particular application better than the generic code that has been posted on the forum. This is more suitable for multiple sensors on a single bus, the more sensors, the more time will be saved if all devices are instructed to perform a conversion simultaneously. The only drawback that I see is that you can't test for completion, only wait the maximum time (plus a little longer). This is tested and is working on my setup. If anyone else tries it and finds a problem please let me know Interestingly, replacing the hex constants with easier (IMHO) to follow variable names worked perfectly with the exception of &hbe scratchpad read. I got the error "Variable not a one dimensional numeric array or a string". Thoughts anyone? I hope someone finds this useful. 'Peter Angus July 2013
'Temperature conversion formula hacked version from ThierryP 03 November 2012 'Get temperature from multiple ds18b20 sensors 'externally powered on a single bus '12bit accuracy but conversion is done in parallel 'to speed up reading all sensors. 'reduced accuracy will further improve response time bus_pin = 1 active = 0 skip_rom = &hcc convert = &h44 sensors = 3 dim temp(1,sensors) 'retain all temperatures after reading 'Sensor data for testing data 40,15,51,172,4,0,0,213 data 40,166,121,172,4,0,0,75 data 40,120,35,172,4,0,0,180 owreset bus_pin,active if active = 1 then owwrite bus_pin,1,2,skip_rom,convert pause 800 'ensure all sensors have performed a conversion for i = 0 to (sensors-1) read a,b,c,d,e,f,g,h 'get the sensor ID fields temp(0,i) = DS18B20_readtemp(bus_pin,a,b,c,d,e,f,g,h) print "sensor #" i " = " temp(0,i) next i endif restore end 'read the temperature from a specified DS18B20 'inputs are pin number of 1-wire signal bus, and 8 ID inputs 'devices must have already been instructed to perform a conversion function DS18B20_readtemp (aPin,aa,bb,cc,dd,ee,ff,gg,hh) Local T1,T2,temp local match_rom match_rom = &h55 'read temperature from scratchpad and convert to degrees C + or - OWWrite aPin,1,9,match_rom,aa,bb,cc,dd,ee,ff,gg,hh 'write a match rom request OWWrite aPin,0,1,&hbe 'instruct a scratchpad read OWRead aPin, 2, 2, T1, T2 'read the scratchpad data If T2 And &b1000 Then 'negative temp 'make 2s complement (1s complement+1) T2 = (T2 Xor &b11111111) T1 = (T1 Xor &b11111111)+1 If T1=1 Then T2=T2+1 'add the carry if required temp = ((T2 And &b111) * 256 + T1) / 16 temp = -temp Else 'positive temp temp = ((T2 And &b111) * 256 + T1) / 16 EndIf DS18B20_readtemp = temp End function |
||||
Print this page |