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 : More then one TEMPR START?
Author | Message | ||||
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9072 |
Is there any way to have more then one of these? The one works well, but if you have several sensors to check, in a GUI program you can't really be waiting around for 200ms while each sensor is checked. That's where TEMPR START comes in, and it works great, but it won't allow you to have more then one at a time. If you try to start more then one sensor, you get an error message. This creates a problem in that you can read ONE in the background, but all the others force the code to wait for 200mS(or 100mS if you use the zero option), during which time, touch on the LCD is ignored. It is quite easy to trip up the GUI because of the long wait for the 18B20's - even if you space them out in the main loop(s). Is there any way to do more then one? Any plans to add this ability? For now, I am simply not using two of three sensors, preferring to concentrate on the main system sensor for the fansink - it gets the priority for now. Smoke makes things work. When the smoke gets out, it stops! |
||||
Phil23 Guru Joined: 27/03/2016 Location: AustraliaPosts: 1664 |
Dunno Grog, I've got 6 & 8 DS18B20's on my 2 MM's but I don't use Temp(). They are all on the same pin & I send the command for them to initialise etc, then read them consecutively. Those functions are in a thread somewhere. Could do with that last bit of polishing though. Initialise them. [Code] '========================OneWire Temperature Functions========================= 'Sub Initialises all DS18B20 Sensors on the Bus 'The below will set the resolution 'Onewire Write PinTmp, 2, 5, &HCC, &H4E,&H00,&H00,&HXX ' 9 bit=0.5 :1f - 93.75ms '10 bit=0.250 :3f - 187.5ms '11 bit=0.125 :5f - 375.0ms '12 bit=0.0625:7f - 750.0ms ' Sub InitTemp Onewire Write PinTmp, 2, 5, &HCC, &H4E,&H00,&H00,&H7F 'Set the Resolution of all Sensors OneWire Write PinTmp, 1, 2, &HCC, &H44 'Start Conversion on all Sensors End Sub [/code] Read them. [Code]'Function Returns the Termerature for the Serial# passed. Function ReadTemp(TsSerial As Integer) As Float Ts1=(TsSerial >> 48) and &hFF : Ts2=(TsSerial >> 40) and &hFF : Ts3=(TsSerial >> 32) and &hFF Ts4=(TsSerial >> 24) and &hFF : Ts5=(TsSerial >> 16) and &hFF : Ts6=(TsSerial >> 8) and &hFF : Ts7=(TsSerial) and &hFF 'OneWire Write PinTmp, 1, 10, &H55,&H28,Ts1,Ts2,Ts3,Ts4,Ts5,Ts6,Ts7,&H44 'Check sensor is ready Timer=0 : Status=0 Do If Timer > 1000 Then Error "Sensor Error" OneWire Read PinTmp,4,1,Status ' Conversion status Loop Until Status = 1 ' Do ' 'Just pause for a second ' Loop Until Timer>1000 OneWire Write PinTmp,1,10, &H55,&H28,Ts1,Ts2,Ts3,Ts4,Ts5,Ts6,Ts7,&HBE OneWire Read PinTmp, 2, 2, LTemp, HTemp 'Calculate the Temp in C ReadTemp=((HTemp And &b111) * 256 + LTemp) / 16 ' If HTemp And &b1000 Then ReadTemp=-ReadTemp 'Adjust if negative If HTemp And &b1000 Then ReadTemp=(ReadTemp-128) 'Adjust if negative ' Print ReadTemp ' Print HTemp,LTemp ' Print Bin$(HTemp,8),Bin$(LTemp,8) ' End Function [/code] Phil. Edit:- Other bits are, [Code] 'Sensor Serial Numbers Dim Integer TsAmb=&HFFA667A815016F 'Sensor0 Ambient Air Temp Dim Integer TsCur=&H74413C0700005E 'Sensor1 Water Temp Dim Integer TsInp=&HBF4C3B07000053 'Sensor2 Panel Input Temp 'Dim Integer TsOut=&H901C3B07000054 'Sensor3 Panel Output Temp FAILED & Changed. Dim Integer TsOut=&H1D854A07000097 'Sensor3 Panel Output Temp Dim Integer TsPan=&H28123D07000059 'Panel Temp[/code] [Code]Sub ReadSensors if timer>5000 then RBOX 0,209,40,30,4,,RGB(Red) 'Set Left Status LED to Red whilst reading temps TmpAmb=ReadTemp(TsAmb) TmpCur=ReadTemp(TsCur) TmpInp=ReadTemp(TsInp) TmpOut=ReadTemp(TsOut) TmpPan=ReadTemp(TsPan) ReadSolar Timer=0 RBOX 0,209,40,30,4,,RGB(Gray) Endif End Sub [/code] Catch is needing to code the serial#'s. |
||||
Phil23 Guru Joined: 27/03/2016 Location: AustraliaPosts: 1664 |
Wonder if you could send this to each different pin and then just use Temp() if you have them on different pins. Then you don't need to go down the serial# road. [Code]'========================OneWire Temperature Functions========================= 'Sub Initialises all DS18B20 Sensors on the Bus 'The below will set the resolution 'Onewire Write PinTmp, 2, 5, &HCC, &H4E,&H00,&H00,&HXX ' 9 bit=0.5 :1f - 93.75ms '10 bit=0.250 :3f - 187.5ms '11 bit=0.125 :5f - 375.0ms '12 bit=0.0625:7f - 750.0ms ' Sub InitTemp Onewire Write PinTmp, 2, 5, &HCC, &H4E,&H00,&H00,&H7F 'Set the Resolution of all Sensors OneWire Write PinTmp, 1, 2, &HCC, &H44 'Start Conversion on all Sensors End Sub[/code] Phil. |
||||
disco4now Guru Joined: 18/12/2014 Location: AustraliaPosts: 844 |
I think you could used SETTICK 300, ReadTemps,4 The ReadTemps SUB would have say three/six states kept track of with a global variable. Each time its called it will do either a TEMP START or a TEMPR for the 18B20's in a round robin type of thing. As it only does one of TEMP START or TEMPR is is never blocking and hands back control immediately. State 1 TEMP START 18B20 No1 State 2 TEMPR No 1 and set flag to say it updated State 3 TEMP START 18B20 No2 State 4 TEMPR No 2 and set flag to say it updated State 5 TEMP START 18B20 No3 State 6 TEMPR No 3 and set flag to say it updated They would sequentially complete in background with minimal effect on the main loop. Regards Gerry Latest F4 Latest H7 |
||||
Geoffg Guru Joined: 06/06/2011 Location: AustraliaPosts: 3165 |
Brilliant suggestion Gerry, I was scrolling to the bottom of the thread to say a similar thing but you had beaten me to it. Geoff Geoff Graham - http://geoffg.net |
||||
lizby Guru Joined: 17/05/2016 Location: United StatesPosts: 3022 |
What is the reason for only allowing one TEMPR START at a time? I thought one of the major reasons for the DS18B20 having the start feature built in was so that multiple sensors could be started (as they apparently can with OneWire), and then read quickly after the appropriate time had passed. That's to say that I thought that whatever TEMPR START would do was "fire and forget" for the pin involved, so that multiple ones on different pins would not be blocked. PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
Paul_L Guru Joined: 03/03/2016 Location: United StatesPosts: 769 |
What will happen if I have multiple DS18B20 sensors but they are each connected to different pins? I was planning on starting them all in a loop then going back and reading them all in a second loop. I will be using an array to hold the pin numbers and the data collected. The code will look something like this. WaitEnd%=TIMER + 800 for i=1 to 19 ' start 19 sensors TEMPR START Td(i,2),3 ' Td(n,2) contains the pin number next i DO : LOOP UNTIL (TIMER > WaitEnd%) for i=1 to 19 ' read 19 sensors Zd(i,1)= (TEMPR(Zd(i,2))*9/5)+32 ' Td(n,1) contains the temp data next i Will this work or will the second pass through the START loop return an error? Paul_L |
||||
Phil23 Guru Joined: 27/03/2016 Location: AustraliaPosts: 1664 |
Slight tangent Geoff, But can you explain what TEMPR START does in low level terms? I presuming it's doing a bit more than just these 2 commands, like maintains some other status etc. [/code] Onewire Write PinTmp, 2, 5, &HCC, &H4E,&H00,&H00,&H7F 'Set the Resolution of all Sensors OneWire Write PinTmp, 1, 2, &HCC, &H44 'Start Conversion on all Sensors [/code] Could help me improve my approach. Thanks Phil. |
||||
Geoffg Guru Joined: 06/06/2011 Location: AustraliaPosts: 3165 |
The DS18B20 is a difficult thing to work with because you have to start the conversion and then wait a considerable time (in microcontroller terms) for it to finish the conversion THEN you can read the temperature. The original TEMPR() function just sat there twiddling its thumbs in a loop waiting for a specific number of microseconds for the conversion to finish. My thinking was that this would not be a problem because you only needed to measure temperature every few minutes. However, locking up the interpreter even once a minute did turn out to be a problem. TEMPR START was the answer to this. What it does is send the start command to the DS18B20 then starts a counter running. Later, when the TEMPR() function is called it just checks the counter and if it has reached the allocated time it will request the temperature from the DS18B20. If the counter is still running it will wait for it to finish before requesting the temperature. Because background counters soak up CPU time I only implemented one counter for the DS18B20 timer (so Paul_L your program would not work). I could have implemented more but then all users of the Micromite would suffer a small performance penalty as every microsecond MMBasic would have to check a number of counters to see if they needed to be updated, even if the TEMPR command had not been used. Measuring temperature using the DS18B20 has been far more popular than I anticipated so something better is needed. You can query the DS18B20 to tell if it is busy and that would be the ideal solution - the TEMPR() function could do that and no counters would be needed. I had trouble getting this to work reliably last time but it is worth further investigation. Another possibility is to rewrite the code to use just one counter. I'm heading off overseas again, this time to New Zealand (its a tough life ), and I will have a look at it when I get back - so there will be a fix sooner or later. While I am at it, I will have a look at implementing multiple sensors on the one wire - but that is messy and might not be practical. Geoff P.S. If anyone lives around Taupo or Palmerston North let me know. We might be able to get together to say hello. Geoff Graham - http://geoffg.net |
||||
Paul_L Guru Joined: 03/03/2016 Location: United StatesPosts: 769 |
Well, that's a fine kettle of fish I've gotten into. @Geoffg - I only need one counter since I'm starting all the sensors building a reading simultaneously and I can implement that easily enough with a loop. The 800 ms delay for the sensors to build an 11 bit return word is not a serious problem. Some of Phil's code seems to use lower level functions to start the DS18B20s building their return word. Do you think I should try to use Phil's method or should I await your return from NZ? How was your trip to Canada? Paul_L |
||||
Geoffg Guru Joined: 06/06/2011 Location: AustraliaPosts: 3165 |
Without going through your code in detail it seems that you are using native DS18B20 commands sent via the 1-wire functions. In that case none of my comments apply, they only apply to the TEMPR command and function. Note that you cannot mix the two. Canada was great, went dog sledding, curling, snow shoeing, etc. Stuff that you cannot do in Oz. Geoff Geoff Graham - http://geoffg.net |
||||
lizby Guru Joined: 17/05/2016 Location: United StatesPosts: 3022 |
This is to confirm Phil23's suggestion that this can be done with onewire commands with one DS18B20 per pin (so no need to know the serial number). After starting the conversion and pausing 1000ms (can be less depending on resolution sought), each read of the temperature takes about 10 or 11 milliseconds (including printing the result). I did this with 3 DS18B20s using Grogster's sweet Explore-28 PCB, just arrived yesterday. [code] dim Temp1 as float, HTemp as integer, LTemp as integer pause 1000 I2C open 100, 1000 pause 1000 print "temperatures from 3 DS18B20s using onewire start Commands" for i = 1 to 5 ' using Phil23 code, post 2: http://www.thebackshed.com/forum/forum_posts.asp?TID=9419&PN=1 ' and from DaveC166 post 11: http://www.thebackshed.com/forum/forum_posts.asp?TID=6898 Onewire Write 2, 2, 5, &HCC, &H4E,&H00,&H00,&H7F 'Set the Resolution OneWire Write 2, 8, 2, &HCC, &H44 'Start Conversion Onewire Write 3, 2, 5, &HCC, &H4E,&H00,&H00,&H7F 'Set the Resolution OneWire Write 3, 8, 2, &HCC, &H44 'Start Conversion Onewire Write 4, 2, 5, &HCC, &H4E,&H00,&H00,&H7F 'Set the Resolution OneWire Write 4, 8, 2, &HCC, &H44 'Start Conversion print ""x print " TIMER before pause = "+str$(timer) pause 1000 print " TIMER after pause = "+str$(timer) ' print "Temp1 "+str$(DS18B20(2))+" TIMER="+str$(timer) onewire write 2, 1, 2, &HCC, &HBE onewire read 2, 2, 2, LTemp, HTemp Temp1=((HTemp And &b111) * 256 + LTemp) / 16 If HTemp And &b1000 Then Temp1=(Temp1-128) 'Adjust if negative print str$(i)+" Temp1 "+str$(Temp1)+" TIMER="+str$(timer) onewire write 3, 1, 2, &HCC, &HBE onewire read 3, 2, 2, LTemp, HTemp Temp1=((HTemp And &b111) * 256 + LTemp) / 16 If HTemp And &b1000 Then Temp1=(Temp1-128) 'Adjust if negative print str$(i)+" Temp2 "+str$(Temp1)+" TIMER="+str$(timer) onewire write 4, 1, 2, &HCC, &HBE onewire read 4, 2, 2, LTemp, HTemp Temp1=((HTemp And &b111) * 256 + LTemp) / 16 If HTemp And &b1000 Then Temp1=(Temp1-128) 'Adjust if negative print str$(i)+" Temp3 "+str$(Temp1)+" TIMER="+str$(timer) pause 3000 next i print "Done" end [/code] Here's the output. [code] > run temperatures from 3 DS18B20s using onewire start Commands TIMER before pause = 9612322 TIMER after pause = 9613329 1 Temp1 26 TIMER=9613339 1 Temp2 25.875 TIMER=9613349 1 Temp3 23.625 TIMER=9613360 TIMER before pause = 9616382 TIMER after pause = 9617388 2 Temp1 26 TIMER=9617398 2 Temp2 25.8125 TIMER=9617408 2 Temp3 23.625 TIMER=9617419 TIMER before pause = 9620441 TIMER after pause = 9621447 3 Temp1 25.9375 TIMER=9621457 3 Temp2 25.8125 TIMER=9621469 3 Temp3 23.625 TIMER=9621480 TIMER before pause = 9624501 TIMER after pause = 9625507 4 Temp1 25.875 TIMER=9625517 4 Temp2 25.8125 TIMER=9625528 4 Temp3 23.625 TIMER=9625539 TIMER before pause = 9628561 TIMER after pause = 9629567 5 Temp1 25.875 TIMER=9629577 5 Temp2 25.75 TIMER=9629588 5 Temp3 23.625 TIMER=9629599 Done [/code] PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
WhiteWizzard Guru Joined: 05/04/2013 Location: United KingdomPosts: 2794 |
Hi Lance (and all), Thanks for sharing this. Just one little thing to make the 'timings' easier to read; can I simply suggest that you add TIMER=0 immediately before the line that prints the very first 'time' i.e. 'TIMER before pause....' Great work . . . WW For everything Micromite visit micromite.org Direct Email: whitewizzard@micromite.o |
||||
lizby Guru Joined: 17/05/2016 Location: United StatesPosts: 3022 |
WW--I like to keep TIMER as a free-running count of the number of milliseconds passed since the program started (with the understanding that with 4-byte integers it will overflow in 50 days). In this example, setting TIMER=0 would make the output clearer, but in general, rather than TIMER=0, I like this construction in a loop: endTime%=TIMER+delayTime% . . . IF TIMER => endTime% THEN Lance PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
Print this page |