![]() |
Forum Index : Microcontroller and PC projects : Multiple onewire devices
![]() ![]() ![]() ![]() |
|||||
Author | Message | ||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
I've run out of ideas. You could try your sensors individually but I expect that they will all show power = 0 Jim VK7JH MMedit |
||||
Chopperp![]() Guru ![]() Joined: 03/01/2018 Location: AustraliaPosts: 1097 |
@Geoffg Thanks for that. Sorry, my sensor did not respond to your program using pin GetTemp(2). Sensor not responding If I change OneWire Read PinNbr, 4 , 1 , b ' conversion done? to OneWire Read 2, 4 , 1 , b ' conversion done? I get with (no delay) The temperature is 85 which seems strange Brian ChopperP |
||||
Chopperp![]() Guru ![]() Joined: 03/01/2018 Location: AustraliaPosts: 1097 |
@TJ Can you please sent a zipped copy of your program to make sure I haven't done something stupid? Brian ChopperP |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
onewire_search3.zip I don't think it will help. If you are seeing power = 0, that is where the problem is. Re Geoff's code. 85 degrees is the startup value. I'm taking the dogs to the beach so no more playing this morning. Jim VK7JH MMedit |
||||
Chopperp![]() Guru ![]() Joined: 03/01/2018 Location: AustraliaPosts: 1097 |
Thanks Jim ChopperP |
||||
Chopperp![]() Guru ![]() Joined: 03/01/2018 Location: AustraliaPosts: 1097 |
More playing. From the Manual TEMPR START pin [, precision] This command will start the measurement on the temperature sensor. The program can then attend to other duties while the measurement is running and later use the TEMPR() function to get the reading. If the TEMPR() function is used before the conversion time has completed the function will wait for the remaining conversion time before returning the value. I think the code below is a valid test for using the TEMPR START Command & then waiting for TEMPR() to respond. Firstly, it times & prints out a normal TEMPR(3) reading. Then, for each precision value: It uses the TEMPR START command & times its operation. It then takes the TEMPR(3) readings after a delay starting at 0 & incrementing by 100mS to 800mS and then calculates the time for the TEMPR(3) reading. The delay is equivalent to "doing other duties" from the Manual quoted above. (Note I've changed from PIN 2 to PIN 3 & MM EDIT Line numbers shown) 1 OPTION EXPLICIT 2 DIM INTEGER t1, t2, x, y, delay 3 4 t1 = TIMER 5 PRINT "Temp ", TEMPR(3); 'normal TEMPR reading 6 PRINT " Time " , TIMER - t1 'time for reading 7 PRINT 8 PRINT 9 10 11 PRINT "Set Time Temp Reading Time" 'headings for printed readings 12 FOR delay = 0 TO 800 step 100 'pause times before reading 13 PRINT "Delay = " delay 14 15 FOR x = 0 TO 3 ' TEMPR precision values 16 t1 = TIMER ' set t1 to timer 17 TEMPR START 3, x ' start temperature conversion 18 PRINT TIMER - t1; ""; ' print setup time 19 PAUSE delay ' delay before reading temp 20 t2 = TIMER ' set t2 = TIMER 21 PRINT TEMPR(3);" "; ' print temperature value 22 PRINT TIMER - t2 ' print conversion / reading time 23 PAUSE 100 24 NEXT x 'next precision value 25 PRINT 26 NEXT delay 'next delay value The results below show the progressive reduction in the TEMPR(3) reading times (mS) as the delay times ("doing other duties") are increased as per the manual. They also show that the sensor is behaving as it should using the standard MMBasic codes & functions. Temp 21.75 Time 212 Set Time Temp Reading Time Delay = 0 6 22 103 6 21.75 204 6 21.75 404 6 21.6875 804 Delay = 100 6 22 4 6 21.75 104 6 21.75 304 6 21.75 704 Delay = 200 6 22 4 6 21.75 4 6 21.75 204 6 21.75 604 Delay = 300 6 22 4 6 21.75 4 6 21.75 104 6 21.75 504 Delay = 400 6 22 4 6 21.75 4 6 21.75 4 6 21.75 404 Delay = 500 6 22 4 6 21.75 4 6 21.75 4 6 21.8125 304 Delay = 600 6 22 4 6 21.75 4 6 21.75 4 6 21.75 204 Delay = 700 6 22 4 6 21.75 4 6 21.75 4 6 21.75 104 Delay = 800 6 22 4 6 21.75 4 6 21.875 4 6 21.8125 4 I've still got to work out the ONEWIRE stuff. Brian ChopperP |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
Your logic is not valid for the builtin TEMPR command. In the command to start conversion: A timer is set depending on the requested resolution ds18b20Timers[pin] = ds18b20Timer + (100 << precision); // set the timer count to wait for the conversion In the function to retrieve temperature: if(ds18b20Timers == NULL || ds18b20Timers[pin] == 0) { // the TIMR command has not used Init_ds18b20(pin, 1); // the default is 10 bits uSec(200000); // and 200mS conversion } else { // the TIMR command has been used while(ds18b20Timer < ds18b20Timers[pin]); // wait for the conversion ds18b20Timers[pin] = 0; } MMBasic either waits 200mS if it is a simple read or waits until the timer times out if the TEMPR START has been used first. The TEMPR command is setup for a single DS18B20 that is within specs and works for either Passive or 3 wire mode by waiting the expected time. That covers the vast majority of cases. Anything other than a bog standard DS18B20, you have to roll your own. Try this. Connect a 4.7 k between 2 convenient pins and a single DS18B20 on a different pin PinNbr = 37 PinCtrl = 33 ' 4.7k between PinCtrl and PinNbr realPin = 42 ' sensor fitted here (with pullup) setpin PinCtrl, dout pin(PinCtrl)=1 print "Line held high" ONEWIRE RESET PinNbr print "E= ";MM.ONEWIRE ONEWIRE WRITE PinNbr, 1,2,&hcc, &hb4 ONEWIRE READ PinNbr,4,1,power print "P= ";power print "E= ";MM.ONEWIRE pin(PinCtrl)=0 print "Line held low" ONEWIRE RESET PinNbr print "E= ";MM.ONEWIRE ONEWIRE WRITE PinNbr, 1,2,&hcc, &hb4 ONEWIRE READ PinNbr,4,1,power print "P= ";power print "E= ";MM.ONEWIRE setpin PinCtrl, off print "Line floating" ONEWIRE RESET PinNbr print "E= ";MM.ONEWIRE ONEWIRE WRITE PinNbr, 1,2,&hcc, &hb4 ONEWIRE READ PinNbr,4,1,power print "P= ";power print "E= ";MM.ONEWIRE print "Line attached to sensor" ONEWIRE RESET realPin print "E= ";MM.ONEWIRE ONEWIRE WRITE realPin, 1,2,&hcc, &hb4 ONEWIRE READ realPin,4,1,power print "P= ";power print "E= ";MM.ONEWIRE timer = 0 print GetTemp(realPin) print timer ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Function to get the temperature from a Dallas DS18B20. ' The DS18B20 is connected to the pin specified by PinNbr ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Function GetTemp (PinNbr) Local T1, T2, b, t OneWire Reset PinNbr ' reset OneWire Write PinNbr, 1, 2, &hcc, &h44 ' start conversion Pause 100 t = Timer Do If Timer - t > 1000 Then Error "Sensor not responding" OneWire Read PinNbr, 4 , 1 , b ' conversion done? Loop Until b = 1 OneWire Write PinNbr, 1, 2, &hcc, &hbe ' command read data OneWire Read PinNbr, 2, 2, T1, T2 ' get the data GetTemp = ((T2 And &b111) * 256 + T1) / 16 If T2 And &b1000 Then GetTemp = -GetTemp ' adjust if negative End Function My results: Line held high E= 0 P= 1 E= 0 Line held low E= 1 P= 0 E= 1 Line floating E= 0 P= 1 E= 0 Line attached to sensor E= 1 P= 1 E= 1 21.875 728.65 Jim VK7JH MMedit |
||||
Geoffg![]() Guru ![]() Joined: 06/06/2011 Location: AustraliaPosts: 3292 |
Chopper. There is no point timing the speed of reading a sensor. I don't think that you properly read my reply . Geoff Graham - http://geoffg.net |
||||
Chopperp![]() Guru ![]() Joined: 03/01/2018 Location: AustraliaPosts: 1097 |
OK. Not feeling the best today. Just went & had a COVID test to see if it is that. 4k7 between 6 & 7. DS18B20 on 3 Added normal TEMPR(3) from command line Line held high E= 0 P= 1 E= 0 Line held low E= 1 P= 0 E= 1 Line floating E= 1 P= 0 E= 1 Line attached to sensor E= 1 P= 0 E= 1 Error : Sensor not responding > > print tempr(3) 23 Using a 28 pinner on a Grogster's Wireless Node Board. Will Go & try it out on the CMM2 Thanks Brian ChopperP |
||||
Chopperp![]() Guru ![]() Joined: 03/01/2018 Location: AustraliaPosts: 1097 |
@ Geoff I can understand some of it I think. Not well ATM. Reading & understanding are two different things. The TEMPR START timing is meaningless, I can see that I think. What it does show to me (I think) is that the higher the precision, the longer it takes to get a reading & if you do go do other stuff after the TEMPR START, you have some idea as to how long you've got until the reading is available. Anyway, I'm happy with the normal operation reading the Sensors. I was interested in running more than one sensor off the same input & when Jim posted his ONEWIRE code the other week, I thought that looks interesting. I decided to have a look at it yesterday & found it wasn't going as expected. So I wondered how the sensors were responding to the normal basic codes. Thanks for the input. Brian ChopperP |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
I still think your sensors are in parasitic mode. Are they encased or can you see the designation on the sensor? ![]() https://datasheets.maximintegrated.com/en/ds/DS18B20-PAR.pdf Unfortunately, they use the same family code as the 'normal' ones so can't use software to see. But they DO work OK so not a big deal. Jim VK7JH MMedit |
||||
Chopperp![]() Guru ![]() Joined: 03/01/2018 Location: AustraliaPosts: 1097 |
OK, The "P's" have it!!!!!!!!!!!!!!!!!!!!!!!! Checked out about a dozen of them. All P's Trap for the ignorant... Just tried on the CMM2 before reading your last message with the same results. (obviously) May order some real ones to see how they go. Thanks Jim. I hope it wasn't too much of a time wasting exercise for you. Maybe need a note in the various manuals. Brian ChopperP |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
You can still have a string of them. You could write a 'start' routine to start all at once then come back later to read the results, just like the inbuilt TEMPR function. Parasitic power is OK but not for really high temperatures or long runs. Just don't mix them with normal ones. It would make like too difficult. Jim VK7JH MMedit |
||||
Chopperp![]() Guru ![]() Joined: 03/01/2018 Location: AustraliaPosts: 1097 |
Thanks Jim For long runs, I just lower the resistor value until they work reliably. ![]() I was intending to go 3 wire when I eventually replace the CMM1 with the CMM2. Will need new sensors for that. Brian. ChopperP |
||||
Geoffg![]() Guru ![]() Joined: 06/06/2011 Location: AustraliaPosts: 3292 |
You learn something every day, however I'm now slightly confused. Why do they make a special parasitic powered version when the "normal" version can work in both three wire and parasitic modes anyway? Geoff Geoff Graham - http://geoffg.net |
||||
Chopperp![]() Guru ![]() Joined: 03/01/2018 Location: AustraliaPosts: 1097 |
Good question Geoff. Looking up RS now. Have in their blurb for a normal unit DS18B20+ :- "They feature a 1-Wire communication interface and powered from that data line". May have to give them a call check if they are the real deal or not. Brian ChopperP |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
I guess the parasitic is a few cents cheaper. Or they have a strange warped sense of humor. Jim VK7JH MMedit |
||||
Chopperp![]() Guru ![]() Joined: 03/01/2018 Location: AustraliaPosts: 1097 |
More playing 1-wire trying to get the grips with it. For the Parasitic Mode (Power = 0) I added SELECT CASE to set Tconv according to the Bit value (precision) in the ow_Tempr() function. The timing values are the same as the manual which are on the conservative side of the specifications. Full Code ' one-wire search and read mutiple devices on one pin ' also should read DS18S20 and DS1820 as well as DS18B20 ' tested on CMM2 and micromite ' TassyJim August2020 ' search based on code by jman and maximite source code ' ' OPTION EXPLICIT DIM NextRomCode$ DIM INTEGER t,b, pinN = 3 DIM FLOAT tp PRINT TEMPR(pinN) PRINT ow_Tempr(pinN) DO NextRomCode$ = ow_search(PinN) IF NextRomCode$<>"" THEN FOR b = 9 TO 12 t = TIMER tp = ow_Tempr(PinN,b,NextRomCode$) PRINT NextRomCode$;" ";INT(TIMER-t-30);" ";tp NEXT b ENDIF LOOP UNTIL NextRomCode$ = "" ' ow_search() given pin number, returns all onewire devices found one at a time, ' as a string. After the last device, the next call will return an empty string. ' If there are no devices found "None found" is returned. ' Anything other than zero for the second parameter will cause the counter to reset, ' retrieving the first device FUNCTION ow_search(PinNbr AS INTEGER,f%) AS STRING LOCAL INTEGER i, RomNum, rom_byte_mask, id_bit, cmp_id_bit, Last_zero LOCAL INTEGER search_direction, id_bit_number LOCAL RomCode$ STATIC INTEGER LastDeviceFlag, LastDiscrepancy, last_RomNum IF f% <> 0 THEN ' reset for a new search last_RomNum = 0 LastDeviceFlag = 0 LastDiscrepancy = 0 'LastFamilyDiscrepancy = 0 ENDIF ONEWIRE RESET PinNbr IF LastDeviceFlag = 1 THEN RomCode$ = "" last_RomNum = 0 LastDeviceFlag = 0 LastDiscrepancy = 0 'LastFamilyDiscrepancy = 0 ELSE RomNum = 0 id_bit_number = 1 rom_byte_mask = 1 last_zero = 0 ONEWIRE WRITE PinNbr,1,1,&HF0 'Send the Search ROM command (FO) DO ONEWIRE READ PinNbr, 4 , 2, id_bit, cmp_id_bit 'Get response from device IF (id_bit = 1 AND cmp_id_bit = 1) THEN ' shouldn't happen LastDeviceFlag = -1 EXIT DO ENDIF IF id_bit <> cmp_id_bit THEN search_direction = id_bit ' no conflict IF ((id_bit = 0) AND (cmp_id_bit = 0)) THEN ' conflict IF id_bit_number = LastDiscrepancy THEN 'id_bit_number = LastDiscrepancy then take "1" path search_direction = 1 ELSEIF id_bit_number > LastDiscrepancy THEN 'id_bit_number > LastDiscrepancy then take the "0" path search_direction = 0 ELSE ' id_bit_number < LastDiscrepancy then take same path as last time IF (last_RomNum AND rom_byte_mask) > 0 THEN search_direction = 1 ELSE search_direction = 0 ENDIF ENDIF IF search_direction = 0 THEN Last_zero = id_bit_number 'If last_zero < 9 Then LastFamilyDiscrepancy = last_zero ENDIF ENDIF ' add bit to rom code or leave at zero if search_direction = 0 IF search_direction = 1 THEN RomNum = RomNum OR rom_byte_mask ONEWIRE WRITE PinNbr,4,1,search_direction ' send 1 or 0 as search direction id_bit_number = id_bit_number+1 ' increment id_bit_number rom_byte_mask = rom_byte_mask << 1 LOOP UNTIL id_bit_number > 64 'Check for next bit IF LastDeviceFlag = -1 THEN LastDeviceFlag = 1 RomCode$ = "None found" ELSE LastDiscrepancy = last_zero IF LastDiscrepancy = 0 THEN LastDeviceFlag = 1 last_RomNum = RomNum RomCode$ = "" FOR i = 1 TO 8 RomCode$ = RomCode$ + HEX$((RomNum AND &hFF),2) RomNum = RomNum>>8 NEXT i ENDIF ENDIF ow_search = RomCode$ END FUNCTION ' bit (9-12) is optional and defaults to 10 ' probe$ is optional if only one probe attached ' probe$ format = "2862D8F105000018" ' time taken is ~30mS plus conversion time FUNCTION ow_Tempr(PinNbr AS INTEGER, bit AS INTEGER, probe$) AS FLOAT LOCAL FLOAT T1 LOCAL INTEGER t, n, power, romcode, Tconv LOCAL INTEGER c1,c2,c3,c4,c5,c6,c7,c8 LOCAL INTEGER d1,d2,d3,d4,d5,d6,d7,d8 select case bit case 0 bit = 10 Tconv = 200 case <= 9 bit = 9 Tconv = 100 case = 10 Tconv = 200 case = 11 Tconv = 400 case = 12 Tconv = 800 case > 12 bit = 12 Tconv = 800 end select ONEWIRE RESET PinNbr IF MM.ONEWIRE = 0 THEN ' no device T1 = 1000 ELSE ONEWIRE WRITE PinNbr, 1,2,&hcc, &hb4 ONEWIRE READ PinNbr,4,1,power PRINT "Power = ";power " "; IF probe$ = "" THEN ' romcode not specified so go get it. ONEWIRE WRITE PinNbr,1,1,&h33 'read ROM code ONEWIRE READ PinNbr,0,8,c1,c2,c3,c4,c5,c6,c7,c8 ELSE romcode = VAL("&h"+probe$) c8 = romcode AND &hFF romcode = romcode >> 8 c7 = romcode AND &hFF romcode = romcode >> 8 c6 = romcode AND &hFF romcode = romcode >> 8 c5 = romcode AND &hFF romcode = romcode >> 8 c4 = romcode AND &hFF romcode = romcode >> 8 c3 = romcode AND &hFF romcode = romcode >> 8 c2 = romcode AND &hFF romcode = romcode >> 8 c1 = romcode AND &hFF ENDIF IF c1=34 OR c1=40 THEN n = ((bit-9)<< 5) + 31 ' set resolution config byte ONEWIRE WRITE PinNbr,1,9,&h55,c1,c2,c3,c4,c5,c6,c7,c8 ONEWIRE WRITE PinNbr,0,4, &h4e , &hFF,&hFF,n ENDIF ONEWIRE WRITE PinNbr,1,9,&h55,c1,c2,c3,c4,c5,c6,c7,c8 IF power = 0 THEN ONEWIRE WRITE PinNbr,8,1, &h44 'apply strong pullup for passive ELSE ONEWIRE WRITE PinNbr,0,1, &h44 ENDIF 'read external when bit goes hi, for parasitic just wait IF power = 0 THEN PAUSE Tconv ELSE t = TIMER DO IF TIMER - t > 1000 THEN T1 = 1001 EXIT DO ENDIF ONEWIRE READ PinNbr, 4, 1, n ' conversion done? LOOP UNTIL n = 1 'print int(timer - t);" "; ENDIF ENDIF IF T1 < 1000 THEN 'read scratchpad ONEWIRE WRITE PinNbr,1,9,&h55,c1,c2,c3,c4,c5,c6,c7,c8 ONEWIRE WRITE PinNbr,0,1,&hbe ' command read data ONEWIRE READ PinNbr,2,8,d1,d2,d3,d4,d5,d6,d7,d8 IF c1 = 34 OR c1 = 40 THEN ' DS18S22 or DS18B20 t= d1 + (d2 << 8) t = t AND (&hFFFF <<(12-bit)) IF t > 32767 THEN t = t - 65536 T1 = t/16 ELSEIF c1 = 16 THEN ' DS18S20 or DS1820 t= d1 + (d2 << 8) IF t > 32767 THEN t = t - 65536 ' T1 = t/2 ' 9 bit T1 = (t >> 1) - 0.25 + (d8 - d7)/d8 ' using extended precision data ELSE T1 = 1002 ENDIF ENDIF ow_Tempr = T1 END FUNCTION results for 5 sensors. All "P's" 24 Power = 0 -0.25 Power = 0 28C02D81070000B9 111 24.5 Power = 0 28C02D81070000B9 212 24.5 Power = 0 28C02D81070000B9 412 24.5 Power = 0 28C02D81070000B9 812 24.375 Power = 0 28900381070000CD 111 24.5 Power = 0 28900381070000CD 212 24.25 Power = 0 28900381070000CD 412 24.375 Power = 0 28900381070000CD 812 24.3125 Power = 0 2838240107000040 112 24.5 Power = 0 2838240107000040 212 24.5 Power = 0 2838240107000040 412 24.5 Power = 0 2838240107000040 812 24.375 Power = 0 2832F9800700006B 112 24.5 Power = 0 2832F9800700006B 212 24.5 Power = 0 2832F9800700006B 412 24.375 Power = 0 2832F9800700006B 812 24.375 Power = 0 28750281070000C2 112 24 Power = 0 28750281070000C2 212 24.25 Power = 0 28750281070000C2 412 24.25 Power = 0 28750281070000C2 812 24.25 ChopperP |
||||
TassyJim![]() Guru ![]() Joined: 07/08/2011 Location: AustraliaPosts: 6283 |
That works if you know that your attached devices are DS18B20s Other variants have different timing choices and there are plenty of devices sold as DS18B20 that have questionable timing. (I got into trouble calling them fakes) I did think about fine tuning the timing but decided it was safer to stick with "slow and steady wins the race" For your situation, changing the timing is worthwhile. Jim VK7JH MMedit |
||||
Chopperp![]() Guru ![]() Joined: 03/01/2018 Location: AustraliaPosts: 1097 |
Yes, the mod is specific to my needs & they did work with shorter times. I was wondering why all readings were taking the same length of time. Using onewire with multiple devices means you have to get the codes & find out which one is which is obviously done individually but you need track of them. Also, if a sensor is replaced, it's code is needed & software updated accordingly. One thing I found out yesterday when playing & reading the data sheets & the manual etc was about the strong pull-up that is used in the parasitic mode. I was always under the impression that you really needed an external deice to do that. (not that I did). It dawned on me that the data input gets changed to an output & set high for the period required. It even says this for flag 8 in Appendix C. More playing. Thanks. Brian ChopperP |
||||
![]() ![]() ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |