EmonTH & DS18b20's

Well, here we go again lol.

I got my EmonTH's today and started playing with one. One of them I want to have monitor the T&H using the onboard DHT22, as well as two DS18b20's. In the Github repository for the EmonTH, I found the 'emonTH_DHT22_dual_DS18B20' sketcha nd thought 'Awesome! All I need to do is change the DS18B20 addresses and of fI go!'. Well, not so much.

That Dual DS18b20 script is apparently based on the 'emonTH_DHT22_DS18B20', which on looking closer seems to not be the one that came on the EmonTH. It seems the original FW is actually 'emonTH_DHT22_DS18B20_RFM69CW'. But when I loaded the Dual DS18b20 sketch up, it didn't work, and the serial output is flaky.

 

I get this in the output (garbled text and all):

emo‹…: OpenEnergyMonѽɹorg
Node: 19 Freq: 433Mhz Network: 210
üTWÖÑ•‘DHT22 temp & humidity sensor
½Õ¹‘DS18B20 External 1
Found DS18B20 External2
emonTH payload:
  Battery voltage: 0.60V
  External sensor 1: 25.60C
  External sensor 2: 25þ

 

After some more looking and comparing, it seems the hardware or at least coding of the dual ds18b20 sketch is not much like the newer sketch. at the very least, pin assignments seemt o be quite different. I've been trying to 'graft' things over from the 'emonTH_DHT22_dual_DS18B20' sketch to the and so far I haven't been able to get it to compil e'emonTH_DHT22_DS18B20_RFM69CW'

 

This is the error log from the most recent attempt to compile:

emonTH_DHT22_DS18B20_RFM69CW:65: error: redefinition of 'const int time_between_readings'
emonTH_DHT22_DS18B20_RFM69CW:62: error: 'const int time_between_readings' previously defined here
emonTH_DHT22_DS18B20_RFM69CW.ino: In function 'void setup()':
emonTH_DHT22_DS18B20_RFM69CW:146: error: assignment of read-only variable 'nodeID'
emonTH_DHT22_DS18B20_RFM69CW:147: error: assignment of read-only variable 'nodeID'
emonTH_DHT22_DS18B20_RFM69CW:148: error: assignment of read-only variable 'nodeID'
emonTH_DHT22_DS18B20_RFM69CW:149: error: assignment of read-only variable 'nodeID'
emonTH_DHT22_DS18B20_RFM69CW:156: error: 'struct Payload' has no member named 'temp'
emonTH_DHT22_DS18B20_RFM69CW:161: error: 'struct Payload' has no member named 'temp'
emonTH_DHT22_DS18B20_RFM69CW:238: error: 'numSensors' was not declared in this scope
emonTH_DHT22_DS18B20_RFM69CW:242: error: 'allAddress' was not declared in this scope
emonTH_DHT22_DS18B20_RFM69CW.ino: In function 'void loop()':
emonTH_DHT22_DS18B20_RFM69CW:289: error: 'numSensors' was not declared in this scope
emonTH_DHT22_DS18B20_RFM69CW:289: error: 'allAddress' was not declared in this scope
emonTH_DHT22_DS18B20_RFM69CW:292: error: 'allAddress' was not declared in this scope
emonTH_DHT22_DS18B20_RFM69CW:296: error: 'struct Payload' has no member named 'temp'
emonTH_DHT22_DS18B20_RFM69CW:297: error: 'struct Payload' has no member named 'temp_external'
emonTH_DHT22_DS18B20_RFM69CW:309: error: 'struct Payload' has no member named 'temp'
emonTH_DHT22_DS18B20_RFM69CW:324: error: 'struct Payload' has no member named 'temp_external'
emonTH_DHT22_DS18B20_RFM69CW:325: error: 'struct Payload' has no member named 'temp'
emonTH_DHT22_DS18B20_RFM69CW:332: error: 'struct Payload' has no member named 'temp'

 

Any tips to get this working right? I'm goign to keep plugging away at it and see if I can get it, but as usual, any help would be apprecaited.

Robert Wall's picture

Re: EmonTH & DS18b20's

You need to get rid of those errors starting at the top. Note the error is usually on the line it gives, but sometimes it can be one or more lines before.

Over time, the way things are done has changed in detail, but the objective has remained pretty much the same.

"redefinition of 'const int time_between_readings'" means you've got that twice. That's not legal.

"assignment of read-only variable 'nodeID'" means it's defined as a const (unchangeable) but now you're trying to give it a new value (or maybe the same value again).

"'struct Payload' has no member named 'temp'" means you're referring to something that's not there in the Payload. Either the name has changed or you haven't added it in the definition of Payload.

"....was not declared in this scope" means (probably) it's a new/different name for a quantity, or you've forgotten to declare it. The concept of 'scope' is too long to spell out here, a C / C++ programming tutorial will help you (e.g.http://www.relisoft.com/book/index.htm).

I've had to be fairly general because I don't know what changes you've made to provoke those errors.

davekramkowski's picture

Re: EmonTH & DS18b20's

I think I'm going to throw in the towel here. I copied everything that I could see that seemed relevant from the newer sketch to the dual DS18B20 sketch; Changed it to the JeeLib.h rather than RFu_JeeLib.h, added in the dip switch code, changed the nodeID from 'const int' to 'int', and probably a few other things I can't think of, and after fighting through a bunch of compile errors, I was able to get it to compile and write to the TH, but still no go. I actually thought it somehow fried the radio in it as after loading it up, it still wasn't getting to the EmonHUB. Turns out it was the fact that I had change dht payload structure; apparently the payload didn't match to the EmonHUB was ignoring it.

With the attached sketch, I'm still getting a messed up boot over the serial:

emo‹…: OpenEnergyMonѽɹorg
Node: 19 Freq: 433Mhz Network: 210
üTWÖÑ•‘DHT22 temp & humidity sensor
Unable to find address for DS18B20 External 1... check hard coded address
Unable to VË‹address for DS18B20 External 2... check hard coded address
emonTH payload:
  Battery voltage: 3.20V
  External sensor 1:  not present
  External sensor 2:  not preÿ

It just locks up there and never moves again.

Any clues? I feel like an infant trying to build a race motor in trying to piece the two sketches together...

Robert Wall's picture

Re: EmonTH & DS18b20's

I too see the corrupted serial output - it's usually caused by printing too much to the serial terminal!

For a start, you don't need the DIP switch code. The switches are there so that people without programmers can change the Node ID. If you've got a programmer, you can define it in the code and not bother with the switches.

Those last 2 error messages say it can't find your 2 sensors, so the sketch is designed to stop there and do nothing more. Having failed to find your sensors, it's doing exactly as it should!

You need to get the two external sensors to respond. Obviously I can't check the addresses of your sensors - did you get the addresses using the "Temperature Search" sketch from here?
(I can't test this as I haven't got a spare sensor.)

Which version of the emonTH do you have - in other words, is
  const int DS18B20_PWR = 5;
  const int DHT_PWR = 6;
correct for your hardware version? (What you have should be correct for V1.4 & 1.5.)

What happens when it tries to read a sensor is:
1. It turns the power on: digitalWrite(DS18B20_PWR, HIGH);
2. Tells the sensors to initialise: sensors.begin();
3. Sees if a sensor is at the address you give: sensors.getAddress(EXT_SENSOR1, 0);
4. Tell you what it found,
5. Turns the power off: digitalWrite(DS18B20_PWR, LOW);

If you have a multimeter, you could extend the delay after the power is turned on (to give you time to see something!) and check the power supply to the sensor.

pb66's picture

Re: EmonTH & DS18b20's

Could the serial corruption be due to the Serial connection being accessed (tested for) before the baud is set ?

debug = Serial ? 1 : 0;
if (!debug) 
    return; 
Serial.begin(9600);

I know what this is trying to do, but does it work 100% ?

Paul

davekramkowski's picture

Re: EmonTH & DS18b20's

I have 1.5.2 TH's. It doesn't see the DS sensors because at that time, they were not connected (only the DHT22 was), When connected, it finds them both, but it still doesn't work.. If I 'm not mistaken, the code is written so that if it doesn't find ANY sensors it stops and sleeps forever. t did have the DHT22 attached, so it had a sensor and could coninue.
 

Robert Wall's picture

Re: EmonTH & DS18b20's

Knowing what you don't have connected makes a difference, believe it or not! It does help people to help you if you don't hide material facts like that.

I've converted back to RFu_JeeLib (because my emonTH is that sort) and you're right about it should work with only the DHT22, your sketch seems to work for me like that (notwithstanding the corrupted serial output). When I wrote the last post, I hadn't noticed that "üTWÖѕ‘DHT22 temp & humidity sensor" was the correct number of characters for "Detected DHT22 temp & humidity sensor".

Note that the last output line isn't printed until the next set of readings 5 minutes or so later. You can put Serial.flush() at the end of print_payload() if you wish.

So barring a soldering fault on the radio module (and haven't you had it transmitting, in which case that's improbable), I can't see why the sketch doesn't work for you.

davekramkowski's picture

Re: EmonTH & DS18b20's

I wouldn't call it hiding. Forgetting to mention or simply leaving that detail out, sure. Hiding indicates ill intent. :)

Yes, it's been transmitting fine - I loaded up the original sketch last night and it's been happily reporting to the base all night and all day today.

So I missed that the older sketch was polling every 5 minutes - I changed that to 1 and uploaded it; It seems it doesn't hang, but instead does keep polling data (lots of errors in the serial output still though), but it's not transmitting (Or at least it doesn't seem to be). It never checks in with the base. And it may be a coincidence, but it seemed like it may have been somehow interfering with the other TH's. While the modified firmware was running, the other two stayed out of contact a lot longer than they usually do. They normally don't get more than 65 seconds out or so. With his one up, they were approaching 90-180 seconds out.

Robert Wall's picture

Re: EmonTH & DS18b20's

You do have a 433 MHz network?

And you have got the payload set up correctly - 5 signed integers - in emonHub?

Bearing in mind I'm using a different library, I can't see anything that might mean that this one is blocking the others, and mine certainly is only transmitting when it's expected. (With 'minutes' set to 5, it actually waited 4' 45" between transmissions.)

[Paul:

  debug = Serial ? 1 : 0;                              
  if (!debug)
    return;
  Serial.begin(9600);

makes no difference. The docs say all but the Leonardo always return true, so I guess "Serial" for the Uno does nothing except return anyway.]

dBC's picture

Re: EmonTH & DS18b20's

I too see the corrupted serial output - it's usually caused by printing too much to the serial terminal!

That sounds bogus to me.  How much is "too much"?

Note that the last output line isn't printed until the next set of readings 5 minutes or so later. You can put Serial.flush() at the end of print_payload() if you wish.

If you do, does that cure the data corruption problem?

It sounds like you might be putting the CPU to sleep while it's busy transmitting on the UART.    If that's not snyc'd up with the current byte completing I'd expect you'd see the corruption you're seeing.

 

Robert Wall's picture

Re: EmonTH & DS18b20's

Download the sketch and try it yourself - it's attached to the 3rd post in this thread.

dBC's picture

Re: EmonTH & DS18b20's

I don't have any suitable hardware to run it on, and I assume it would need quite a bit of modification to run on anything I do have.    But I repeat my question for anyone who does:

Does calling Serial.flush() before going to sleep cure the data corruption problem?

Robert Wall's picture

Re: EmonTH & DS18b20's

"Does calling Serial.flush() before going to sleep cure the data corruption problem?"

No, looking at the printout, the major corruption is the first that is sent in setup( ). Everything in loop( ) is OK for me (but not for Dave, he's using the expanded JeeLib whereas I'm using RFu_JeeLib).

I'm not familiar with the way the compiler arranges the code and data, but in my experience string corruption is the first symptom of running out of memory. I do note that the print call in question is inside a function, so that's a bit more stack used than normal.

[EDIT] "Does calling Serial.flush() before going to sleep cure the data corruption problem?"

That triggered a thought. No it doesn't, but calling it after each block of printing does cure the corruption problem. Whether that's after printing or before it does anything with the OneWire bus, I'm not sure.

[Edit 2]

Attached the file with Serial.flush(); inserted.

davekramkowski's picture

Re: EmonTH & DS18b20's

Is it possible that it actually is transmitting data, but there's corruption there too, causing the Base to ignore the packets?

Robert Wall's picture

Re: EmonTH & DS18b20's

I didn't see any - but I didn't look past the 1st 6 bytes.

davekramkowski's picture

Re: EmonTH & DS18b20's

Hmm. Well, I don't know where to go from here. I'm an IT administrator by day, am proficient in networking, Windows server OSes and functions, virtualization, security, firewalls, etc, but I cant grasp the arduino coding. I started trying to play with PIC micro controllers a few years ago, and no matter what I read, I couldn't grasp that. Without a walk through tutorial, I couldn't even make a LED blink. About a year ago, addressable LED Pixels & arduinos caught my attention, but as with the PICs, I just can't grasp it no matter what I read. I haven't even been able to figure out how to make a pixel blink or change colors. The only way I can do anything with the Aduinos is if I find something out on the web that'll do what I want.

The last arduino/Atmega 328p based project I attempted I essentially tossed in the bin because as soon as I deviated from the original creators coding in the slightest degree, it fell apart like a hose of cards. I still have the PCBs I designed and had made, as the tep nodes work well as standalone units, but the intent was to transmit back to a RPi (by way of an arduino) and that part just kept failing miserably.

If it's REAL simple, like on the TX, changing the calibration values for the CTs or its address, that I can get, but when it comes to how all the code works, I'm totally lost. The copy & pasting I've been doing is just taking WAGs and see what happens. I've been able to clear up errors that prevents it from compiling with the help of google, but it doesn't help me understand how it all works, and as evidenced by my attempts with the TX & this, it doesn't mean it WILL work. So this makes for two emon related things that I've tried to customize and make and totally failed at (the first being hardcoding DS18b20 addresses into the TX).

It's so frustrating. The Arduinos (and arduino based things such as the emon products) are so cool and flexible, but despite my tech background, I can't grasp what is arguably (by some) simpler than the things I do on a daily basis. I guess everyone has their niche, and this just isn't mine.

dBC's picture

Re: EmonTH & DS18b20's

No, looking at the printout, the major corruption is the first that is sent in setup( )

But print_welcome_message() enqueues a bunch of strings to the serial port and immediately calls dodelay() right? In fact there are calls to dodelay() all over the place without any regard for what's in the output queue.

Did you try a single call to Serial.flush() inside dodelay(), before it does anything else?  That would ensure that you never put the CPU to sleep right while it's trying to clock out the 10-bits of a UART byte.

I'm not familiar with the way the compiler arranges the code and data,

The code lives in flash, and is executed from flash, so you can't corrupt that unless you try really hard (like the bootloader does).  

.data lives below .bss, so if the stack is trampling over your strings it's probably already taken out your static variables on the way down.

Robert Wall's picture

Re: EmonTH & DS18b20's

I'm only trying by remote control to debug a sketch that isn't written the way I might have done it in the first place, using (slightly) different hardware! The reason I put the flush() in 'everywhere' is the Arduino documentation is wonderfully unclear about what happens when the serial port isn't open (debug became false), so I put it in only where debug is true. dodelay( ) appears to be everywhere, but in fact it misses one!

Dave: I've managed networks in the past, so I understand where you're coming from. You think big. In this area, you need to think small! I'll do my best to steer you through, assuming that's what you'd want? It WILL work - together we'll battle it into submission.

I'm using an emonGLCD running a 'Debugger' sketch - it just receives radio packets and displays them as bytes. That's showing exactly the same as the serial display, so I'm reasonably confident that it's not sending rubbish (at least not now):

emonTH : OpenEnergyMonitor.org
Node: 19 Freq: 433MHz Network: 210
Detected DHT22 temp & humidity sensor
Unable to find address for DS18B20 External 1... check hard coded address
Unable to find address for DS18B20 External 2... check hard coded address
emonTH payload: 
  Battery voltage: 0.00V
  External sensor 1:  not present
  External sensor 2:  not present
  Internal DHT22 temperature: 19.50C, Humidity: 65.30% 

In the photo, bytes 0&1 are 0 0 (battery voltage)
bytes 2&3 are 8d 02 = 653 (= 65.3 * 10 = humidity)
bytes 4&5 are c3 00 = 195 (=19.5 * 10 = internal temp)
the rest (external sensors) are zero.

 

If you've loaded that file and you're still having trouble at this point, what does your emonhub.conf file say about Node 20?
You need it to be looking for either 5 signed integers, or the default ("datacode = " instead of "datacodes = ...", meaning any number of signed integers)

[[20]]
    nodename = emonTH
    firmware = mod2.ino
    hardware = emonTH
    [[[rx]]]
       names = battery, humidity, intTemp, extTemp1, extTemp2
       datacodes = h, h, h, h, h
       scales = 0.1, 0.1, 0.1, 0.1, 0.1
       units = V, %, C, C, C
davekramkowski's picture

Re: EmonTH & DS18b20's

Robert, what I had in the emonhub config with the changed code for that TH was:

 

    nodename = emonTH_2
    firmware = emonTH_DHT22_DS18B20.ino
    hardware = emonTH_(Node_ID_Switch_DIP1:ON_DIP2:OFF)
    [[[rx]]]
       names = battery, humidity, internalTemp, externalTemp1, externalTemp2
       datacode = h
       scales = 0.1,0.1,0.1,0.1,0.1
       units = V,%,C,C,C

 

Essentially identical to what you posted other than the 'externalTemp1' and the firmware name, which is how the sensors are listed in the firmware, although I'm assuming those don't really matter if they match as that info isn't actually transmitted.

My question now is which would really be the better approach? Trying to modify the 'emonTH_DHT22_dual_DS18B20' to work on the emonTH 1.5.2 that should be running the 'emonTH_DHT22_DS18B20_RFM69CW' code, or modifying the 'emonTH_DHT22_DS18B20_RFM69CW' code to make the multiple DS18b20's work on that? I'm kind of thinking the latter would be the better approach. This way we're starting out with code that is meant for that exact hardware and works as it should, rather than trying to take the older code that does things in different ways and modifying it to work on the newer hardware - Obviously, I was able to get it to doing something, but for example, the dip switches didn't seem to be functioning - Yes, I know they're not required, but why not have them working?

 

 

Robert Wall's picture

Re: EmonTH & DS18b20's

"datacode = h" will accept any number of signed integers, whereas I'd specified the exact number. As you say, both versions are essentially equivalent so it doesn't matter which one you use.

Which sketch we start with also shouldn't matter, we ought to end up with something that works either way. Have you had chance to try the "mod2" version that I'd changed? Without the external sensors, that is now behaving properly (for me at least but bear in mind I have a V1.4 emonTH, so it's using a different JeeLib).

I'd like you to try that one, but long-term we'll go with later version if that's which you prefer.

The DIP switches aren't mission-critical, we can worry about those once the important bit is working.

davekramkowski's picture

Re: EmonTH & DS18b20's

I just loaded that one up and the serial output is now clear, however, nothing is getting to the base.

Interestingly, it seems like it doesn't care about hte DS18b20 addresses - When I initially loaded the sketch, it had one correct address and one incorrect one (one of the sensors I was using earlier was still on my desk, the other got placed somewhere, so I got the address of another one and hooked it up). Witht he wrong address, it still was giving me a temp reading off both, not complaining of a missing address or anything. I'm not sure if that's supposed to work that way...

 

 

emonTH : OpenEnergyMonitor.org
Node: 20 Freq: 433MHz Network: 210
Detected DHT22 temp & humidity sensor
Found DS18B20 External 1
Found DS18B20 External 2
emonTH payload:
  Battery voltage: 0.40V
  External sensor 1: 24.80C
  External sensor 2: 24.60C
  Internal DHT22 temperature: 25.00C, Humidity: 36.90%

 

 

[[20]]
    nodename = emonTH_2
    firmware = emonTH_DHT22_DS18B20.ino
    hardware = emonTH_(Node_ID_Switch_DIP1:ON_DIP2:OFF)
    [[[rx]]]
       names = battery, humidity, internalTemp, externalTemp1, externalTemp2
       datacode = h
       scales = 0.1,0.1,0.1,0.1,0.1
       units = V,%,C,C,C

Robert Wall's picture

Re: EmonTH & DS18b20's

My emonPi isn't receiving either, but I haven't yet had time to find out why. The emonTH is certainly transmitting the right things, but I've not has the Pi long and I haven't had time to do much with it.

davekramkowski's picture

Re: EmonTH & DS18b20's

Well, with the attached Mod4 sketch, I've gotten *somewhere*. I get sane text in the serial output, and I get *some* data on the base.

01
emonTH - Firmware V1.6.1
OpenEnergyMonitor.org
RFM69CW Init>
Node: 20 Freq: 433Mhz Network: 210
Detected DHT22 temp & humidity sesnor
Detected 2 DS18B20
DS18B20 and DHT22 found, assuming DS18B20 is external sensor
emonTH payload:
  Battery voltage: 3.20V
  External sensor 1:  not present
  External sensor 2:  not present
  Internal DHT22 temperature: 25.70C, Humidity: 34.50%

 

I don't know what the '01' in the first line is about, and for some reason I haven't figured out, it's saying that the external sensors are both not present in the serial output, although it's sending data back to the base for the DHT22 and one of the DS18b20's.

With the 'Mod5' sketch, after probably an hour of messing around and resolving errors, I got it to compile, and uploaded it. The serial output is broken though:

01
emonTH - Firmware V1.6.1
OpenEnergyMonitor.org
RFM69CW Init>
Node: 20 Freq: 433Mhz Network: 210
Detected DHT22 temp & humidity sesnor
Detected 2 DS18B20
DS18B20 and DHT22 found, assuming DS18B20 is external sensor
emonTH payload:
  Battery voltage: 3.20V
  External sensor 1:  not present
  External sensor 2:  not preÿ¹Ñ5
                                   Internal DHT22 temperature: 26.60C, Humidity: 34.40%

emonTH payload:
  Battery voltage: 3.20V
  External sensor 1:  not present
  External sensor 2:  not preÿ¹Ñ5
                                   Internal DHT22 temperature: 26.60C, Humidity: 34.90%

 

But it IS transmitting some data over to the base - it's sending battery and DHT22 readings over, but no DS18b20 readings...

 

Edit: I looked at the one that you added 'Serial.flush();' to and added that in all the same places in the 'Mod5' sketch, and now have sane serial output:

01
emonTH - Firmware V1.6.1
OpenEnergyMonitor.org
RFM69CW Init>
Node: 20 Freq: 433Mhz Network: 210
Detected DHT22 temp & humidity sesnor
Detected 2 DS18B20
DS18B20 and DHT22 found, assuming DS18B20 is external sensor
emonTH payload:
  Battery voltage: 3.20V
  External sensor 1:  not present
  External sensor 2:  not present
  Internal DHT22 temperature: 26.30C, Humidity: 35.90%

davekramkowski's picture

Re: EmonTH & DS18b20's

Holy Mackerel! I may have actually gotten it!

With the attached 'Mod8' sketch, I am getting mostly sane serial output, and it's sending all the data over to the base:

01
emonTH - Firmware V1.6.1
OpenEnergyMonitor.org
RFM69CW Init>
Node: 20 Freq: 433Mhz Network: 210
üTWÖÑ•‘DHT22 temp & humidity sensor
Found DS18B20 External 1
Found DS18B20 External 2
emonTH payload:
  Battery voltage: 3.20V
  External sensor 1: 25.50C
  External sensor 2: 25.10C
  Internal DHT22 temperature: 25.60C, Humidity: 36.90%

emonTH payload:
  Battery voltage: 3.20V
  External sensor 1: 31.70C
  External sensor 2: 25.00C
  Internal DHT22 temperature: 25.60C, Humidity: 36.80%

 

With the 'Mod7' sketch, I got similar results, except it wasn't respecting the hardcoded addresses for the DS18b20s (they were swapped), so took a guess and commented out

 EXT_SENSOR1_PRESENT = sensors.getAddress(EXT_SENSOR1, 0);
 EXT_SENSOR2_PRESENT = sensors.getAddress(EXT_SENSOR2, 1);

which gave me 'Mod8' and reporting the sensors in their proper places. I don't know why 'Detected DHT22 temp & humidity sensor; is partially garbled - I tried adding 'Serial.flush();' in a few places that 'seemed' right, but no change.

davekramkowski's picture

Re: EmonTH & DS18b20's

Ok, did some more testing - it seems that the hardcoded addresses in the sketch aren't doing anything. I added a third sensor, and all the displays were right, but I knocked out one of the other two sensors when connecting the third, and it was still showing 1 & 2, with 3 not connected, but it was either 1 or 2 and three that were connected. I also note that if I change one to a bogus address, it still brings up data for all three sensors. It doesn't complain about not being able to find that address. They also arent' in the order that they are specified, so it would seem that while I'm getting data, I'm still missing something that actually make suse of the hardcoded addresses.

 

 

Robert Wall's picture

Re: EmonTH & DS18b20's

I'm looking only at your ...mod8 sketch. I can't see why it should be ignoring the hardcoded addresses - IF the library is doing what the comments claim.

In initialise_DS18B20(), it calls sensors.getAddress(EXT_SENSOR1, 1) which says it checks that the sensor in question is at that address. But the name of the method worries me. Why is it called "getAddress" and not "checkAddress" or "proveAddress" if it's doing what it claims? More to the point, it uses the OneWire::search method, and that searches for the next available device, and THAT overwrites the address you gave it.

Then in take_ds18b20_reading () it does temp1=(sensors.getTempC(EXT_SENSOR1)). But if that sensor address "EXT_SENSOR1" was changed by getAddress, the address you set at the top has been overwritten, which would explain what you're seeing. So I think the comment that explains what the method does is misleading.

That's how I read the code. The way to prove this would be to set a completely bogus address, then print it immediately before and after the call to getAddress(). But I think that's beyond your knowledge at present.

I'll try to get hold of a couple of DS18B20s so that I can experiment.

But I think you shouldn't be using the RFM69 sketch as your starting point, because it's going to need a lot more effort to change that to use hard-coded addresses than it will be to change the older sketch to use the RFM69CW and the DIP switches.

davekramkowski's picture

Re: EmonTH & DS18b20's

How your stating it is pretty muck how I read it too. However, I also posted this over on the arduino forums, and in short, I'm told that 'getAddress changes value of EXT_SENSORx' is the problem - 'sensors.getAddress(EXT_SENSOR1, 0) does not check if the sensor whose address is in EXT_SENSOR1 is present. It finds the first sensor on the bus (i.e. at index 0) and stores its address in EXT_SENSOR1 thereby overwriting what you had initialized it to.' That acutaully makes sense... They linked to code here that they say does work that way - it looks largely identical to the Emon code, except for the lack of the 'sensors.getAddress(EXT_SENSOR1, 0)'.

Later on, I'll load the sketch in tha tlink up into one of my Arduinos and see what I get from it.

davekramkowski's picture

Re: EmonTH & DS18b20's

So I tried out the sketch in the linked article, and it worked 100%. With the proper addresses, it pulled readings from the proper sensors, and if I put in a bogus address, it gave me a failure for that snesor.

So it would seem the answer is to remove the following lines and work from ther eto get it to work:

EXT_SENSOR1_PRESENT = sensors.getAddress(EXT_SENSOR1, 0);
EXT_SENSOR2_PRESENT = sensors.getAddress(EXT_SENSOR2, 1);

EXT_SENSOR1_PRESENT = EXT_SENSOR1_PRESENT ? EXT_SENSOR1_PRESENT : sensors.getAddress(EXT_SENSOR1, 1);
EXT_SENSOR2_PRESENT = EXT_SENSOR2_PRESENT ? EXT_SENSOR2_PRESENT : sensors.getAddress(EXT_SENSOR2, 0);

The question there is how do we get it to detect the presence of the sensors? Or maybe we don't - for these purposes, personally, I'm fine if we don't do a 'detect the sensors and adjust' the way it's doing... If I say there are sensors 1, 2 & 3 and it only finds 1 & 3, I'm fine with it continuing on and guiving no data...

Robert Wall's picture

Re: EmonTH & DS18b20's

What "they" were trying to do (I think) was to put the sensors in the same places in the array each time. I haven't studied the Dallas library in great detail, but from what I've managed to work out so far, the manufacturer's algorithm for searching addresses involves querying the bus with partial addresses and seeing what responds, and because of the way that addresses are transmitted, the addresses get recognised in "reverse order", i.e. as I think I said some way up this thread, they are recognised and sorted Least Significant Bit first. So when written MSB first, the addresses appear to be in random order when in fact they're not, and given the correct sorting algorithm, the order can be predicted. I don't see anything in that sketch (the one that uses getAddress) that will prevent the order changing when a sensor fails to respond. So your hard-coded addresses and getAddress( ) commented out does what you want.

What might work for you is (quote from DallasTemperature.cpp):

// attempt to determine if the device at the given address is connected to the bus
bool DallasTemperature::isConnected(uint8_t* deviceAddress)

I assume it returns true if the sensor is connected. You could try

if (sensors.isConnected(EXT_SENSOR1))
{
 Serial.println("Sensor 1 present");
 // and/or whatever you want in here to read the temperature and send it
}
else
{
 Serial.println("Sensor 1 not found");
 // and/or send an identifiable invalid value
}

or something like that, either to tell you or to send a recognisable invalid value that you can deal with as you want.

davekramkowski's picture

Re: EmonTH & DS18b20's

I think I got it.... With the attached sketch, I get the following:

01
emonTH - Firmware V1.6.1
OpenEnergyMonitor.org
RFM69CW Init>
Node: 20 Freq: 433Mhz Network: 210
üTWÖÑ•‘DHT22 temp & humidity sensor
Unable to find address for DS18B20 External 1... check hard coded address
Unable to find address for DS18B20 External 2... check hard coded address
Unable to find address for DS18B20 External 3... check hard coded address
emonTH payload:
  Battery voltage: 0.00V
  External sensor 1: 23.80C
  External sensor 2: 24.20C
  External sensor 3: 23.70C
  Internal DHT22 temperature: 24.00C, Humidity: 41.90%

emonTH payload:
  Battery voltage: 0.00V
  External sensor 1: 23.80C
  External sensor 2: 30.00C
  External sensor 3: 23.70C
  Internal DHT22 temperature: 24.00C, Humidity: 41.60%

And it's sending the valid data over to EmonCMS. I'll have to do a little more experimentation, but it seems to be working right.

Oddly, with the check for address in the beginning, with the valid addresses, it says it can't find it, but with an INVALID address, it says it found the sensor. But the expected sensors are respinding. When I put in an invalid address, that sensor in the list reads '0'. I had moved the 'setResolution' up into 'void setup' as it is in that other tutorial, but I was getting '85' from all three DS18b20's, which I believe has somethign to do with powerup. I moved the 'setResolution' back down into the 'void take_ds18b20_reading' section and it then returned valid values.

The sketch is a filthy train wreck, in need of much cleaning, but it seems to be working. It might be nice to get the search in the beginning working, but honestly, it it can't be done with the way the hardcoding is set up, I can certainly live with that.

 

Edit: After a little testing, the addressing is definitely working. I took three different temperatures of water (Hot, warm, cold) and dropped one of each of the three probes in each one (1 in hot, 2 in warm, 3 in cold) and then moved which external sensor was each address and the readings moved around as expected.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.