The more I think about it the more you are right. 0.1 resolution isn’t going to matter that much considering the Uno or Mega would get 0.15 (0.2 rounded) resolution. Especially since my local Micro Center has the Mega on sale for $10. Just have to figure out how to Wifi enable it (little confused on that part).
Yes, adding WiFi to an UNO or MEGA is not as straightforward as it should be. As you can tell, I have tried using the ESP01 as a WiFi shield. And I have tried the Adafruit ATWINC1500 breakout board as well. Neither are 100% reliable. The NodeMCU ESP8266 seems to be much more reliable when it comes to WiFi. You could try one of those to see what type of resolution you’d get out of its 10bit ADC input. You can get 2 of them for about $18 on Amazon!
Yeah, I just got two of them with the Konnected Security project. Sad that I’d need two more just to pick up two analog inputs (one per board) while the Mega could do a bunch.
Gonna see if I can get Ethernet out there before I buy two more devices. I have the enclosure…maybe I’ll flash a old cheap router with DD-WRT and make it a client bridge so I can just plug in devices in the garage.
I believe the ESP32 has 18 analog pins https://learn.adafruit.com/adafruit-huzzah32-esp32-feather/overview
The ESP32 does look like an ideal next platform. Multiple 12bit analog inputs, 2 8bit analog outputs, a bunch of digital I/O, WiFi, Bluetooth, etc… Unfortunately, I haven’t picked one up to test with and to add support for in ST_Anything. The Arduino IDE support for the ESP32 still seems like a work in progress (many more steps involved versus the ESP8266).
I’ll need to add it to my ToDo list!
Update: I just ordered the HiLetgo ESP32 dev board from Amazon for $12.99. Looks like this one is finally a breadboard-friendly version of an ESP32.
Yes, you can see/use decimal precision with SmartThings. It is a function of the DTH and the device. In fact, many of the SmartThings temperature devices send at least 1 decimal digit of precision for F temperatures; many actually pass that through in the sendEvent(name: temperature, value: temp, …) call, but the default tiles tend to truncate the precision when displaying them. FWIW, they used to simply drop the digit (temperature.toInteger()), but most now seem to do the right thing (Math.round(temperature.toDouble())).
ST Compatible Load Cell For Gas Bottle?
@ogiewon - I will happily buy the same board if you want me to test things. I have some fairly accurate input/output devices (0 - 10v in 0.01v increments) and I could test my temperature sensors against known good values for accuracy.
@storageanarchy - I known I’ve seen it. Actually kinda annoys me that .1 deg isn’t the standard. I’ll have to look into it.
I’ll keep you posted on my progress. The new ESP32 board should arrive tomorrow. By the end of the week I should know one way or another if there are going to be any issues getting ST_Anything to run properly on it.
Good news! I have released ST_Anything with support for the ESP32! Give it a try and let me know how it goes for you!
Awesome, got one on order. Wish I could find a nice base for it like the Lolin NodeMCU Base for the ESP8266 but I have a couple breadboards I can use for now. Now to start researching what I’m doing.
So I’ve been doing some experimenting and I’ll put it here for anyone looking to convert a voltage signal into SmartThings. The ESP32 is very inaccurate at the top and bottom of the scale and not great in between. For example my humidity sensor was putting out 0 - 3.3v and we had rain today. So the sensor was reading around 96% and the ESP saw 3.23 volts but was reading 4095 (100%). Same issue on the low range, 0 - 5% humidity didn’t register (not that we’d ever see that low). I’m also having the same issue with my temperature. For example:
Actual temperature reading: 64.4*
Actual voltage output: 1.922 v
Temperature reading from ESP32: 54.3*
The scaling is -40 to 140 for the 0 - 3.3v input. So at 64.3* the voltage should be, based on the slope, about 1.912 and I’m at 1.922. I’ll call that close enough. Yet I’m getting a reading of 54.3* which is way more then a 0.01v difference.
After some searching I found some articles that showed the ESP32’s ADC wasn’t very good at the extremes of either end (https://www.esp32.com/viewtopic.php?t=1045). So based on that I changed the voltage output on both sensors to 0.52v - 2.85v and the ADC inputs to 512-3584. Once I made this change I got the following results:
Actual temperature: 63.7* (1.882v) - ESP temperature: 54.7
Actual humidity: 97.8% (2.815v) - ESP humidity: 95.8%
The voltage measurements * slope plus offset are within 1% so the issue appears to be with the ESP32 ADC’s. So I figured each ESP might be different. I reset the mapping and pushed a even .250v signal to each input and got the following:
Temperature input: 129
Humidity input: 128
Well they are almost the same…thats promising. I then pushed a 3.0v signal to each:
Temperature input: 3889
Humidity input: 3863
Not as promising but ok. As I watch it however my voltage didn’t change but the inputs jumped around from 3860 - 3900. So I backed it down to 2.9v:
Temperature input: 3667
Humidity input: 3671
and they weren’t bouncing as much. So based on that I setup my scaling for temperature as 128 - 3670 = -40 - 140* and for humidity 128 - 3670 = 0 - 100% and got this:
Actual temperature: 63.7* - ESP temperature: 56.1*
Actual humidity: 97.8% - ESP humidity: 96.1%
Double checking the voltage I have 1.80 which based on that slope (0.25v - 2.9v = -40 - 140*) I should have 1.78v, a degree or so off but not 8* which leads me to believe the ESP32 is not very linear at all and wont work for my current project. Hopefully there will be firmware updates to fix this but for now I wouldn’t recommend it for highly accurate analog inputs.
It is working just fine for binary inputs. Haven’t tried the outputs…don’t really have anything I need to but I might just for testing. Also will try a smaller range and see if thats more accurate along with checking about firmware updates.
I wonder if the non-linearity can be corrected via a software calibration function? You would simply take the analog input value and run it through a mathematical function to correct for the non-linearity. Could also add a noise filter to prevent the value from jumping around so much.
Yeah, some forums on the ESP32 said they were going to try and correct it through software, some things said they already have. There is nowhere to get a predone firmware file and attempts to make one myself (using a Ubuntu VM) failed on the Make step (following https://nodemcu.readthedocs.io/en/dev-esp32/en/build/). Its a new chip…might just have to wait a little.
Some peoples posts show the 10-bit and 11-bit resolution a little more linear. I’ll try to figure out how to change the resolution and see if that helps. 11 bit would be fine if it works. 10 I lost resolution but a loss of 0.1 or 0.2 degrees is a lot better then being off by 8*. Also going to go through and map out everything from 0 to 3.3 in 0.1v increments just for my own sake. Based on the slope I know what it “should” be and I can see how far off it is.
@ogiewon - I was reading up here (https://esp-idf.readthedocs.io/en/v2.0/api/peripherals/adc.html#overview) and it says I need to send a command to change the resolution and attenuation like this:
Where would be the best place to call this? By default ATTEN is set to “ADC_ATTEN_11db” which allows up to a 3.9v input yet it’s only rated for 3.3 (which might throw off the scaling) so I’m thinking of trying “ADC_ATTEN_6db” and limiting my output to 2.2 volts and seeing if that gets it tighter. Also might try the width down to 11Bit or even 10 and see if it’s more accurate.
After some research about he ADC’s being inaccurate and posts that vaguely alluded to the fact that there were fixes in the programming I decided to rebuild the ESP32 firmware from the latest development branch which was a whole ordeal (had to build a virtual Ubuntu linux virtual machine, download the repo, install a bunch of pre-reqs, etc but end result is it worked). After I got the updated firmware installed I reset my controller to push out 0 - 3.27v (it seemed to push a little high at the top of the range) to the ESP32. I didn’t change my scaling on the ADC so it was still 128-3670. Now:
Actual temperature: 70.0* - ESP temperature: 71.0*
Actual humidity: 69.9% - ESP humidity: 70.3%
Way closer but it was using scaling that it shouldn’t need… So I changed my scaling back to 0 - 4095 and the numbers went back to being off by 4 - 5%. Maybe I’m just in a sweet spot where the numbers line up better. I’m not sure but with this new firmware something changed and all the testing I did before will have to be redone.
I’ll map out the scaling when I have a couple hours to kill.
I have wondered about how to update my ESP32 firmware. Do you have a link to the instructions?
Glad to hear they’ve improved the ADC calibration!
Either they’ve improved it or I it’s just a coincidence because I was closer to the middle of both ranges so it seemed more accurate. I’m going to run it through it’s paces, set the range on both the ADC and the sensor to 0 - 4095, push voltage to it, and record the results. Should be able to graph it and see whats going on. Still might have to play with the attenuation and width also.
Here is the basics of the instructions but they aren’t super helpful: https://nodemcu.readthedocs.io/en/dev-esp32/en/build/ . I’ll PM you a writeup I made.
So more testing and more disappointment. I went through and mapped out every voltage from 0.0 through 3.3 in 0.05 increments and it is definately not linear. Not only that its really noisy in certain spots. I’m going to see how I can change the sampling down to 11 or 10 bit and also the attenuation down from the current setting of 11db down to 6db. I don’t think I can do it through the sketch (I tried but I don’t exactly know what I’m doing) so I’m going to look in the source code where the settings are (12-bit and -11db is the default) and if I have to change it there and recompile. Here are the results of my testing.
Gonna post on the ESP32 forums and see what comes of this.
I have implement two new features to my PS_Voltage class which may help reduce the amount of noise from the ESP32’s analog to digital converter.
- Oversampling - you can now supply an additional NumSamples argument to allow the AI to be read repeatedly until the number you specify. The value is summed and then divided to provide a single average value. This new optional argument defaults to “1” for backwards compatibility.
- Lowpass Filtering - you can now supply an additional FilterConstant argument to implement a simple lowpass noise filter. Valid values are from 100 to 5, where 100 means use 100% of the newest value (i.e. no filtering), and 5 would mean use 5% of the newest value plus 95% of the previous value to obtain the value reported to ST.
Please grab the latest code from my GitHub repository and give it a try to see if this helps reduce the variability in the ESP32’s signal. If this works, maybe we can try to tackle the non-linearity issue with a correction algorithm.
Here is a section from the comments section detailing the arguments:
// For Example: st::PS_Voltage sensor1("voltage1", 120, 0, PIN_VOLTAGE, 0, 1023, -40, 140, 20, 80); // // st::PS_Voltage() constructor requires the following arguments // - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name // - long interval - REQUIRED - the polling interval in seconds // - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time // - byte pin - REQUIRED - the Arduino Pin to be used as an analog input // - double s_l - OPTIONAL - first argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output // - double s_h - OPTIONAL - second argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output // - double m_l - OPTIONAL - third argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output // - double m_h - OPTIONAL - fourth argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output // - byte numSamples - OPTIONAL - defaults to 1, number of analog readings to average per scheduled reading of the analog input // - byte filterConstant - OPTIONAL - Value from 5% to 100% to determine how much filtering/averaging is performed 100 = none (default), 5 = maximum // // Filtering/Averaging // // Filtering the value sent to ST is performed per the following equation // // filteredValue = (filterConstant/100 * currentValue) + ((1 - filterConstant/100) * filteredValue)
Thanks, I will definitely give it a try this weekend. I don’t think you want to try and fix the linear issue…it appears hardware related and I’m hoping ESP can fix that. But this should help the noise/bouncing I’m seeing with a constant voltage.
More reading of the ESP32 firmware GitHub has multiple people saying at -11db the signal is very non-linear but at -6db its flatter (https://github.com/espressif/esp-idf/issues/164 for example). Also saw someone post examples of exactly that (https://www.esp32.com/viewtopic.php?t=1045) and in that thread someone else had the almost same results as I did so that makes me feel a little better about things. There is a graph comparing -0db, -6db, and -11db in that same thread that gives me hope on the -6db setting.