Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 16:34 09 May 2024 Privacy Policy
Jump to

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: Netherlands
Posts: 12
Posted: 05:38am 02 Nov 2012
Copy link to clipboard 
Print this post

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 Kingdom
Posts: 3674
Posted: 12:51pm 02 Nov 2012
Copy link to clipboard 
Print this post

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: Netherlands
Posts: 12
Posted: 02:14pm 02 Nov 2012
Copy link to clipboard 
Print this post

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 States
Posts: 1421
Posted: 04:02pm 02 Nov 2012
Copy link to clipboard 
Print this post

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.


Edited by CircuitGizmos 2012-11-04
Micromites and Maximites! - Beginning Maximite
 
jman

Guru

Joined: 12/06/2011
Location: New Zealand
Posts: 711
Posted: 07:01pm 02 Nov 2012
Copy link to clipboard 
Print this post

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: Netherlands
Posts: 12
Posted: 01:15pm 03 Nov 2012
Copy link to clipboard 
Print this post

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: Australia
Posts: 66
Posted: 07:46pm 19 Jul 2013
Copy link to clipboard 
Print this post

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


  ThierryP said   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

'snip


Thierry
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3674
Posted: 08:27pm 19 Jul 2013
Copy link to clipboard 
Print this post

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: Australia
Posts: 66
Posted: 04:59am 21 Jul 2013
Copy link to clipboard 
Print this post

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


To reply to this topic, you need to log in.

© JAQ Software 2024