After reading around, I got my EmonTX reading multiple DS18B20 sensors. When I first connected two, it read real funky, like double the proper value. That may have had something to do with one being on the screw terminals and the other on the RJ45. I put both probes on the RJ45 and now, finally, have two proper temperature readings. The problem is, they are auto detected, so on a reboot, it's entirely possible that the sensors could swap positions depending on which one answers first. From reading, I know it's possible to specify 'Temp1' is sensor 'x', 'Temp2' is sensor 'y' and so on, but I have not found anything that makes sense with regards to setting an EmonTX 3.4 running firmware 1.8 to register specific addresses as specific sensors.
Does anyone have a EmonTX v3.4 sketch that is set up and working with multiple DS18B20 sensors that are explicitly addressed?
Re: EmonTX & Multiple DS18B20
Probably not, but you could connect each sensor in turn and run the "temperature_search" sketch that queries its address, then steal the code from the emonTx V2 "emontx_temperature_power" sketch that addresses the sensors individually, and graft it into the V3.4 sketch.
(Both in emonTxFirmware/emonTxV2/emonTx_temperature_examples on GitHub)
Re: EmonTX & Multiple DS18B20
I have the addresses - I found a sketch out on the internet and loaded it onto an Uno and got the addresses of the two sensors I now have connected to the TX. The problem is making it work on the TX. I already looked at the sketch you referenced, but I have no idea how to make that work with the 3.4. The code is way different.
Re: EmonTX & Multiple DS18B20
Way different? Really?
First, add the array defining the addresses of your two sensors.
Next, look at the 'if' block controlled by "if (DS18B20_STATUS==1)"
In there, all you need is to take out the line "float temp=...." and include in its place
emontx.temp[0] = sensors.getTempC(address_T1) * 10;
emontx.temp[1] = sensors.getTempC(address_T2) * 10;
You can include the bounds check on each if you wish. I haven't tested that (on account of not having two sensors) but I think it's OK.
Re: EmonTX & Multiple DS18B20
You're talking with someone who's a complete moron when it comes to coding. I've been trying to learn Arduino for a while, but I just haven't 'caught on'. If it's clearly spelled out, I can handle it, but unless we're talking about real small changes, I'm pretty much lost.
To me, the code in the EmonTXv2 and v3 look WAY different....
I'll give it a shot, but I have my doubts that I'll do it right...
Re: EmonTX & Multiple DS18B20
I have no way of knowing what your level of knowledge is, so at first sight the two probably look a lot different. But when you look in detail, you'll see almost exactly the same thing in each.
In small steps then:
1.
Find the array in the V2 sketch. You want the first 2 elements:
DeviceAddress address_T1 = { 0x28, 0x22, 0x70, 0xEE, 0x02, 0x00, 0x00, 0xB8 };
DeviceAddress address_T2 = { 0x28, 0x85, 0x7A, 0xEE, 0x02, 0x00, 0x00, 0xDC };
Just above them is "DallasTemperature sensors(&oneWire);" Find that in the V3.4 sketch and copy those lines to just beneath it.
2.
What I wrote above is slightly wrong - the sketch on GitHub has been changed!
Go down to loop( ) in the V2 sketch, and to the 'if' block in the v3.4 sketch.
Find "sensors.requestTemperatures();" in both.
In the V2, see how the temperature is actually read: "sensors.getTempC(address_T1)" ?
In the V3.4 sketch, can you see much the same thing, but it's inside a "for" loop getting all the sensors? The only difference there is in the V2, you have one sensor's address repeated 4 times, and in the V3.4, you have the sensors in turn but with the addresses that it picked up in setup( ). The actual reading is got by a function right at the bottom of the sketch, that also includes the range check. You can do the same range check similarly if you wish:
float temp=(sensors.getTempC(address_T1);
if ((temp<125.0) && (temp>-55.0)) emontx.temp[0] = temp * 10;
temp=(sensors.getTempC(address_T2);
if ((temp<125.0) && (temp>-55.0)) emontx.temp[1] = temp * 10;
So instead of getting all the sensors in the loop, by replacing that line with 2 pairs of lines that specify the exact address of each sensor in turn, then check the result, you'll get the same sensor each time because its address is hard-coded. You put those two temperatures into a temporary variable, then if it's in-range, store the temperature × 10 into the temp[ ] array inside the emontx structure.
The other bits that might be worrying you are "digitalWrite(DS18B20_PWR, HIGH);" and the corresponding "digitalWrite(DS18B20_PWR, LOW);" - those turn the power to the sensors on and off, and that wasn't done in the V2. "Sleepy" is to allow the sensor to stabilise, because it's not powered continuously now.
Re: EmonTX & Multiple DS18B20
Ok - Made some changes... Added the following:
// By using direct addressing its possible to make sure that as you add temperature sensors
// the temperature sensor to variable mapping will not change.
// To find the addresses of your temperature sensors use the: **temperature_search sketch**
DeviceAddress address_T1 = { 0x28, 0xFF, 0xD9, 0x47, 0x64, 0x14, 0x04, 0x0E };
DeviceAddress address_T2 = { 0x28, 0xFF, 0x9F, 0x40, 0x64, 0x14, 0x04, 0xFD };[/code]
underneath
//Setup DS128B20
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
byte allAddress [MaxOnewire][8]; // 8 bytes per address
byte numSensors;
and removed ' float temp=(sensors.getTempC(allAddress[sensor]));' and replaced it with
emontx.temp[0] = sensors.getTempC(address_T1) * 10;
emontx.temp[1] = sensors.getTempC(address_T2) * 10;
When I compiled it, it failed due to the 'if' line under it, so I commented that out and it compiled. When uploaded, according to the serial monitor, it detected both sensors, but was only reporting Sensor 1. Sensor 2 was reporting '0'. Uploaded the previous sketch and it was back to operating right.... so I obviously missed somthing....
Re: EmonTX & Multiple DS18B20
I must be exceptionally dense lol. I attempted to follow your instructions (read through them several times and back and forth in bits and pieces along with going between the v2 and v3.4 sketches), and I still can only get it to report the first sensor. Below is the serial output with the attached script loaded. I tried a few different things, all with the same result. Obviously I'm missing and/or misunderstanding something....
Re: EmonTX & Multiple DS18B20
You've left the old 'read the sensors all together' line in:
for(byte j=0;j<numSensors;j++) emontx.temp[j]=get_temperature(j);
so that's probably overwriting sensor T2.
Re: EmonTX & Multiple DS18B20
I might actually have finally gotten it...
I started off with commenting that line out, and it then was reporting values for two temp probes, but only two digits:
So that was reporting to EmonCMS as 2.2 & 1.8. It would seem the 'float' section at the end wasn't doing anything. So I changed the getTempC lines to read the following:
Now it was reporting three digits and thus a more proper reading to EmonCMS, BUT..... the values wouldn't change... and turned out to be a bit off from actual. I held one of the probes in my hand and the value didn't fluctuate at all.
Loaded my original sketch back in and the probe reacted quickly to me holding it:
I then un-commented out the 'sensors.requestTemperatures();' (I forget why I had commented it out) and then it started returning better values, but still only two digits (I removed the '* 10' from the sensorsGetTemp line thinking maybe the lack of the 'requestTemperatures' line somehow caused the float line to not work). So I added the * 10 back in and now I seem to be getting proper readings.
Does everything seem ok, and/or is there anything left hang around that might cause issues and should be cleaned up?
Re: EmonTX & Multiple DS18B20
That looks OK - if it works, it works!
You won't get a warning (or a default value) if a sensor goes AWOL or a value that's clearly silly, but you can add that as you get the hang of programming.
If it's important to you to put that in now, then after you've got the temperature, you need to something like:
if ((emontx.temp[0] > 125.0) || (emontx.temp[0] < -30.0))
emontx.temp[0] = 300.0;
That will report the value fixed 300.0 if the temperature is greater than 125° or less than 30°. (And likewise for the second.)
[I was actually just starting to look at doing it a neater way, possibly using the non-volatile RAM to store the values indefinitely.]
Re: EmonTX & Multiple DS18B20
Well, it seems that there might be something wrong with my modifications to the sketch. About 12 hours ago, the TX stopped reporting. I just looked at my EmonCMS and noticed it. Checked TX and no led blinking. The reset button brought it back. Maybe its a fluke, but its been rock solid until this. We'll see if it happens again...
Re: EmonTX & Multiple DS18B20
Well, it did it again. dropped off about 8 hours ago. Any ideas what might be causing it? I never had it drop off until i loaded this firmware modified for hardcoded sensors.
Re: EmonTX & Multiple DS18B20
I did look at the sketch and I didn't spot anything out of place, how long does it run for after a reset before it stops reporting?
Re: EmonTX & Multiple DS18B20
The first time it went just under 15 hours before going AWOL (Aug23 @ 11:05am to Aug 24 @ 1:48am). The second time was about 57 hours (Aug 23 @ 14:00 to Aug 25 @ 23:30). The varying timeframes seem odd, but prior to the sketch change, it had been up for 8 days, With the reason it went down prior being to test and calibrate the Wattcore CTs.
Re: EmonTX & Multiple DS18B20
Not consistent then. I'd be inclined to drop a small delay, say 10 ms (or maybe more, I haven't got the time for a transmission in my head!), between the two getTemps, just in case it's trying to fire off the second request while the last data for the first is still coming in, and see if that helps.
I'll have another look at the sketch, but unless there's something deeply buried, I think it's OK.
Re: EmonTX & Multiple DS18B20
I assume adding a delay between the readings would be accomplished bu adding 'delay(50);'(where 50 in this example is 50ms, I assume?) between 'emontx.temp[0] = sensors.getTempC(address_T1) * 10;' and 'emontx.temp[1] = sensors.getTempC(address_T2) * 10;'?
Re: EmonTX & Multiple DS18B20
Yes, that's correct. I don't know that it will work (and I can't investigate because as I mentioned before, I don't have 2 temperature sensors), but as the OneWire is a serial protocol, it's worth a try.
Re: EmonTX & Multiple DS18B20
Hi Dave, this is what I came up with for my heat pump monitoring. It is based on the emontx.v2 code.
The data struct and DS18x20 Library Initilization code goes before setup(), and I think Emontx.v3 uses 5 for ONE_WIRE_BUS, you may need to change this, and as Robert suggested you need to copy the addresses of the DS devices and paste them into the DeviceAddress array. You can change the airIn/airOut names to better describe your sensor locations.
BTW, when you send the sensors.requestTemperatures() command, all devices on the buss immediately measure and store the temperature in their internal register, and the getTempC() command returns the addressed devices temperature it measured at the time it received the requestTemp command so it's best to send this immediately before the getTemp sequence unless you have a reason to defer.
My device has been up for a few months without failure, so hope this helps.
Re: EmonTX & Multiple DS18B20
The delay between device reads needs to be chosen to suit DS18B20 resolution (9-bit = 93.75ms, 10-bit = 187.5ms, 11-bit = 375ms & 12-bit = 750ms)
Re: EmonTX & Multiple DS18B20
Thanks, Dominator. I see JPM doesn't include a delay - is it taken care of in the library so that getTemp doesn't return until the transmission is complete, or is there a danger that the bus hasn't settled when the next interrogation is sent? I'm inclined to think that the locking up is not related to having two sensors, but was worth a try. Can either of you see anything wrong with Dave's sketch, because I can't.
Re: EmonTX & Multiple DS18B20
Thanks guys. unfortunately, it went on a walkabout again this afternoon.... So in teh interests in ruling things out, I've loaded up the original unmolested sketch and I'm going to run that for a while and see if the problem goes away or not.
Re: EmonTX & Multiple DS18B20
I dont know anything about programming, and even less about Arduino.
But i have an idea about how to handle the multiple sensor issue if they keep getting mixed up when resetting the unit.
Since all Dallas sensors have a unique serial number, the code should be designed in such way that uploading sensor data to the emoncms should be done in a certain order of serial numbers for the sensors.
For example the lowest serial number first, and then rising.
This way you don't need to write a special sketch with the ID of every sensor, the code in the emonTX will make sure that sensor data uploads in the same order every time.
If the serials in production are always produced with increasing serial number, this will make it very easy to sort out also if one unit needs to be changed due to technical problems. Just make sure the serials of the sensors are in the same numerical order as befor and the data in emoncms will be unchanged.
This all works if the serials are in fact numbers and not letter, but probably you can sort them both by letter and by number anyways.
Anyone knows if this will work?
//J
Re: EmonTX & Multiple DS18B20
I've got a sketch that stores the serial numbers in EEPROM the first time it is used, thereafter it reads from EEPROM instead of checking the sensors. It's not a bullet-proof arrangement, I'm working on it. And I can see flaws in your idea too, Goodfidelity, when replacing a sensor. Sorting isn't good enough! It probably needs a merge of both your approach and mine. You need to check each one as it's detected and then insert the 'new replacement' in the place previously occupied by one that's now missing, or presumably at the end if it's genuinely 'new'.
Re: EmonTX & Multiple DS18B20
I agree to your points Robert.
The way i thought about it actually has some things that are required.
- Serialnumbers of the sensors must be increasing in production phase. So that a new sensor won't have a lower number then old sensors.
- If a sensor is dead/defect, you might have to rearrange the sensors physically, when adding the new sensor. So that the order of the sensors are still the same physically on the point where you are measuring.
This means that if you replace one sensor, you might have to move around all the other sensors in the house or what ever object you are measuring.
Example:
- #1 Kitchen
- #2 Living room
- #3 Garage
Now sensor number two fails, this menas a new sensor will come in with the serial number #4.
If you just swap it, it will be:
- #1 Kitchen
- #4 Living room
- #3 Garage
This will be reported wrong to the emoncms if the sketch is programmed the way i suggest. And it will mix up the livingroom with the garage.
So the sensors will have to be rearranged in this order for it to work:
- #1 Kitchen
- #3 Living room
- #4 Garage
This way it will still keep sorting the sensors in the correct order, and feeding the data to the correct feed in emoncms. It basically means putting the new sensor in the garage, and moving the garage sensor to the living room.
This is not a perfect idea, and i dont know anything about programming. To me the very best idea is to have multiple one wire ports on the board, and assign each port to a feed. And whatever you measure on this port with a one wire unit will be logged to the same feed in emoncms.
I dont know what will happen if a humiditysensor is swapped for a temperaturesensor, or how to handle that. But i really like the idea of having multiple ports on the board instead of using the same one wire bus for all of them.
My idea was just the first thing that came to mind. I am sure that a good programmer can handle this easier or more bullet proof.
//J
Re: EmonTX & Multiple DS18B20
Expanding on how I think your and my ideas merged would work using your example:
The program starts up and reads sensors 1, 2 & 3 and places the serial numbers in EEPROM. Each time it starts up, it flags all the sensors as 'potentially missing', reads the numbers off the sensors and as they are found in EEPROM, it cancels the flag. If the sensor isn't in EEPROM, it's new.
Then, when all the sensors have been detected, if there's one missing and one new, it assigns the new serial number to the missing location. If there isn't a missing one, it adds it as no.4. If there are missing sensors but no new ones, we know there's a problem. The way around two or more failing simultaneously is to always use the lowest place first, so the replacement sensors have to be installed one at a time, first one first. So in your example, if both Kitchen & Garage have failed, you must replace the kitchen one first (else they get swapped!).
The OneWire bus was invented for good reason. The problem with multiple OneWire buses is, apart from losing out on versatility, they cost I/O pins and connectors, and that's expensive as, on top of the raw cost of the connectors, it makes the pcb and the case larger and more expensive too.
Re: EmonTX & Multiple DS18B20
Guys,
I think you are making this more complicated than it needs to be.
I've had 5 sensors on my heat bank for the last couple of years with no failures and only occasionally a mis-read (as far as I can tell only 2 or 3 times).
Given your sensors are in different rooms (in my case different places on the heat bank) they will show different temperatures. It is far easier to simply find out the addresses of the sensors on the 1 wire bus during setup and then read each of them in turn in the main loop using the addresses you found and send the temperature readings to emoncms.
In emoncms according to the temperatures reported you can easily work out which input is which. If there are 2 or more reporting similar temperatures, simply drop one of them in a glass of cold water. It will soon be obvious from the input page which one that is. Label it, say 'kitchen' and move on to the next one. They don't change over time because the addresses of the sensors are unique and preset.
You don't need to preset the addresses of the sensors in the code. And in the case of a failure, all you have to do is just replace the sensor, the code will automatically pick up the new sensor if you restart the emonTx or whatever you are running the code on. If there is any change in the order in which they are found on the bus then you simply change the inputs in emoncms to make sure they are named correctly again.
Here are some snippets of code.
// DS18B20 sensor data
#define MAXSENSORS 5 // maximum number of sensors on the one wire bus
byte DS18B20Address [MAXSENSORS][8]; // 8 bytes per address
float temperatures [MAXSENSORS]; // latest temperature readings
int numTempSensors; // number of sensors detected
int nextTempSensor; // used to work out which sensor to read next - read one every main loop
OneWire oneWire(13); // One wire object
DallasTemperature tempSensors(&oneWire);
In setup
// set up the Dallas Temp sensors find out how many are connected and get their Ids
tempSensors.begin();
numTempSensors=(tempSensors.getDeviceCount());
Serial.print("Number of sensors: "); Serial.println(numTempSensors);
int j=0; // search for one wire devices and
// copy to device address arrays.
while ((j < numTempSensors) && (oneWire.search(DS18B20Address[j]))) j++;
// now turn off WaitforConversion so that any RequestTemperatures returns asap
// the read next temperatures routine will be attached to a 750Ms timer
// so the temperature readings will always be ready
tempSensors.setWaitForConversion(false); // turn off the wait for conversion
tempSensors.setResolution (12); // set global resolution to 12 bit
tempSensors.requestTemperatures(); // Do command to start conversions
nextTempSensor=0; // initialise the counter used to select first sensor to read
and a routine to read the next sensor
// Routine to get next temperature reading. Called every 750Ms by attaching to a timer.
void readnexttemp()
{
// get temperature from next sensor and reset counter to zero when all read
// routine activated every 750Ms
// a requestTemperatures has been sent with waitForConversion OFF
// so get temperature reading for next sensor which should be ready
float temp=(tempSensors.getTempC(DS18B20Address[nextTempSensor]));
// if reading is within range for the sensor convert float to int and save it
if ((temp<125.0) && (temp>-40.0)) temperatures[nextTempSensor]=(temp*10);
else errorcode = 60 + nextTempSensor +1;
Serial.print("Sensor number: "); Serial.print(nextTempSensor);
Serial.print(" temperature: "); Serial.println(temperatures[nextTempSensor]*0.1);
// get ready to read the next sensor at the next interval
// if we have cycled through all of the sensors, detach the routine from the timer
// the timer for the bigger loop will reattach this routine to the timer again
if (nextTempSensor == (numTempSensors -1)) {
nextTempSensor = 0;
NextTempTimer.detach ();
}
else {
nextTempSensor++;
tempSensors.requestTemperatures(); // Send the command to start conversion
}
}
Re: EmonTX & Multiple DS18B20
The problem is people who don't have a programmer to program their emonTx. It's been said several times before that hard coding the address is the safe way, but that is an option that is only available with a programmer. It's also been asserted several times that the order in which the sensors respond is not deterministic.
Having just studied the algorithm (explained in detail in http://pdfserv.maximintegrated.com/en/an/AN937.pdf (Section C3, p.51)) I think that's not true, but without spending a lot more time on it, it's not clear to me what the order is in which the devices are discovered. I don't have the patience to step through the algorithm for enough devices to see a pattern, so until I do, I have to conclude that if a device is replaced, all the devices may be discovered subsequently in a different order, so the original problem - getting allocated different slots by the emonTx sketch - persists.
The point of keeping the same locations in the same slots is so that it's not necessary to swap things around in emonCMS (and in the process foul up the historical data, which has also been asserted).
If it's possible to write a function/method that will solve the problem and not force users to buy a programmer and learn how to use it (and haven't you noticed that there are increasing numbers of users who aren't keen to assemble hardware and program?) then I see no harm in that.
[BTW, I know temperatures change relatively slowly, but waiting 23¾ years (750 Ms = 750 × 10+6 s is a bit much!]
[Edit]
Having looked again, it appears that the order that sensors are discovered is low address to high address when the bit order of the address is reversed.
Re: EmonTX & Multiple DS18B20
Robert, thanks for catching my typo! Indeed even in this inclement weather my heat bank warms and cools faster than that.
Interestingly, this afternoon, I disconnected my 5 DS18B20s on the heat bank from my emonTx and connected them to the esp8266 controller I'm building to manage the backup firing of the boiler better.
They came out in exactly the same order as they had been on the emonTx and connecting them back to the emonTx they were still in the same order.
As for losing the data if they were to switch around, surely we'd be talking feeds here not inputs, so if one did switch as an input to emonCMS and that input was then realigned to the feed you wouldn't lose data. If you see what I mean.
Simon
Re: EmonTX & Multiple DS18B20
Hi guys!
The problem can be solved in the emoncms to, as stated above.. If the ID of the temperature sensor is associated with one feed, there should not be a problem to create a function that will allow a new temperature sensor to be associated with the same feed.
Two important things here:
1. User don't want to loose historical data or continuity in feed when temperature sensor is replaced.
2. User wants to be able to replace temperature sensor with no programming what so ever of the emon unit.
If both can be solved inside the emoncms, thats just a nice thing =)
Until then, it needs to be adressed in the Emon hardware, wich probably is a pain for most users.. Even experienced users will still need to waste time on the process. And time is valueble.
//J
Re: EmonTX & Multiple DS18B20
Well, it's been about 10 days since I loaded the original sketch up to the EmonTX and there hasn't been a hiccup since, so there has to be *something* about the one I modified to hard code the sensor addresses that was making it take a walk in the park.
Since it seems the sensors always load up in the same order, it would seem that theyr may be loaded up in S/N order?
Re: EmonTX & Multiple DS18B20
See my edit above - the order is determined by the serial number, but in a way that's not obvious.
Re: EmonTX & Multiple DS18B20
Yeah, I missed that post - when you say 'when the byte order is reversed', do you mean like this (where the bracketed line is the original s/n, and the 0x has been replaced with a '.'):
{28.FF.D9.47.64.14.04.0E}
0E.04.14.64.47.D9.FF.28
{28.FF.9F.40.64.14.04.FD}
FD.04.14.64.40.9F.FF.28
Re: EmonTX & Multiple DS18B20
No, I said bit order, not byte order.
The sensor sends the address least significant bit first, and the search handles the sensor addresses one bit at a time. You need to read the description in the data sheet, then check the flow chart in the Library documentation. The latter claims it implements the same algorithm, and it looks like it, but I didn't check it in detail.
So if the serial nos ended 0x7E and 0x31, 0x7E would come before 0x31 because what we see as the least significant bit, it regards as the most significant.