[RELEASE] ST_Anything v2.9.7 - Arduino/ESP8266/ESP32 to ST via ThingShield, Ethernet, or WiFi

If you’re still looking for something to do, OTA updates from the Arduino IDE would be nice as well. :wink:

I looked at doing that at first and was getting a lot of compiling errors or it not showing in my IDE. Found out I had an old library that caused the issue but left it out. I couldn’t test this yet but try this out. https://github.com/zybeon/ST_Anything/blob/master/Arduino/Sketches/ST_Anything_Multiples_ESP8266WiFi/ST_Anything_MultiplesOTA_ESP8266WiFi

So just for fun, because I had one, I added a DHT to my garage door opener. I see it reporting data in the serial monitor, but the child device doesn’t seem to get created for the DHT. What am I missing?

Make sure you specify the temp and humidity device names in your setup() routine as shown below. The last two arguments really are no longer optional, as those names are sent to ST with the corresponding numeric values. The name must be un the form shown below. This is also noted in the ST_Anything ReadMe on Github.

static st::PS_TemperatureHumidity sensor7(F("temphumid1"), 15, 5, PIN_TEMPERATUREHUMIDITY_1, st::PS_TemperatureHumidity::DHT22,"temperature1","humidity1");

1 Like

Ahhh, I had followed the notes in the .h file and had skipped the last two arguments!

1 Like

All,

I am happy to announce that as of v2.8, ST_Anything now supports the ESP32 based boards. The ESP32 has ~23 GPIO pins available for your use, built-in WiFi, a dual core processor, and plenty of RAM and flash storage for large projects.

I have updated the ST_Anything ReadMe file with some high-level instructions on using the ESP32. It really is all that different from using the ESP8266 boards, however the Arduino IDE integration is performed via a more manual step. Be sure to download all of the latest Arduino code (libraries and sketches) from my GitHub to make sure you get all of the latest files. I have added a new ST_Anything_Multiples_ESP32WiFi.ino example sketch to help get you started. It demonstrates having 21 devices attached to a single ESP32!

I bought the following ESP32 for ~$13 from Amazon and it’s been working fine for 2 days so far :wink: I would recommend you run this on the workbench for a few days to ensure stability. I haven’t experienced any issues, but this new board is still a work in process for the Arduino IDE integration team.

Please see the following for directions to add support to the Arduino IDE. Please make sure you can get your ESP32 working within the Arduino IDE before attempting to use ST_Anything with it.

Finally, I would like to thank Joshua Spain for his contributions to getting ST_Anything to run on the ESP32!

Dan

4 Likes

Is it at all possible for this code to store my temperature readings for a couple minutes, then report the average? My DHT11 bounces quite a bit…

So I’m looking through the ST_Anything_Multiples_ESP32WiFi.ino example trying to prep it for my two 0 -10v sensors (temp & humidity) and a current sensing relay on a space heater in the garage (just a dry contact). Couple things and maybe this is my just not knowing (I don’t have the ESP32 yet):

  • I don’t see a temperature / humidity include except for the DTH device.
  • I do later see a Pin_Temperature_2 but its a digital pin.

So my question is do I setup my devices as Voltage then as SmartThings capabilities “Voltage Measurement” or “Temperature”? I would think voltage but then how would I display that as a temp/humidity later? I think based on the Polling Sensors section I can offset the values as I need them but again I’m confused on getting it from voltage to temp or humidity.

-Allan

ST_Anything currently supports three different temperature devices:

  1. DHT series Temperature and Humidity sensors (example in the ESP32 example sketch)
  2. Dallas Semiconductor 1-Wire DS18B20 Temperature sensor (example in the ESP32 example sketch)
  3. Adafruit Thermocouple board (not shown in the ESP32 example sketch)

None of these really will work for your application. However, there is a very easy option that does not require any code changes to get up and running

The easiest method to go directly from Analog Input “counts” (0 to 4095) to Degrees F/C or % Humidity is to simply use my PS_Voltage class (example included in the ESP32 example sketch.)

Here is the documentation from the top of the PS_Voltage.h file.

//			  Create an instance of this class in your sketch's global variable section
//			  For Example:  st::PS_Voltage sensor1("voltage1", 120, 0, PIN_VOLTAGE, 0, 1023, 0, 5);
//
//			  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
//				- int s_l - OPTIONAL - first argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output
//				- int s_h - OPTIONAL - second argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output
//				- int m_l - OPTIONAL - third argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output
//				- int m_h - OPTIONAL - fourth argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output

As you can see, the last 4 arguments are used by the Arduino map() function to scale the analog input into whatever engineering units you desire.

In the ESP32 example sketch, you will find a device declaration as follows:

static st::PS_Voltage sensor5(F("voltage1"), 60, 40, PIN_VOLTAGE_1, 0, 4095, 0, 3300);

Let’s pull apart the arguments:

  1. “voltage1” - This is the name of the device and is used by the Parent Device Handler to create a child device with “Voltage Measurement” capability. If we send “temperature1” we’ll get a Child Temperature Device. If we send “humidity1” we’ll get a Child Humidity Device.
  2. 60 - polling interval in seconds (don’t bombard the ST cloud with high frequency updates!)
  3. 40 - polling offset used to prevent all polling sensors from running at the exact same time. just shifts when the PS is read relative to other PS’s.
  4. PIN_VOLTAGE_1 - the Analog Input GPIO pin number you want to use on the board
  5. 0 - minimum input value to the map function
  6. 4095 - maximum input value to the map function
  7. 0 - minimum output value from the map function
  8. 3300 - maximum output value from the map function

So, in order to get things to work for your Temperature and Humidity sensors, we only need to make a few tweaks:

Temperature Sensor (0 to 3.3V (scaled by HW) corresponds to -40 to 140 Deg F)

#define PIN_TEMPERATURE_1 A0 static st::PS_Voltage sensor1(F("temperature1"), 60, 0, PIN_TEMPERATURE_1, 0, 4095, -40, 140);

Humidity Sensor (0 to 3.3V (scaled by HW) corresponds to 0 to 100 %)

#define PIN_HUMIDITY_1 A3 static st::PS_Voltage sensor2(F("humidity1"), 60, 5, PIN_HUMIDITY_1, 0, 4095, 0, 100);

Note: This will get you up and running in just a few minutes (be sure to comment out/remove all of the other devices in the setup() routine as you see fit. This will result in INTEGER only values being sent to SmartThings. You could get creative and create a modified PS_Voltage class that properly formats the results into floating point values (let me know if you need any help with that), but let’s at least try to get things working using the above method for initial testing.

Definitely possible to add some simple averaging to the DHT temperature measurement before transmitting. Would you also want averaging cornthe humidity value?

That would probably make sense as well, unless its just my DHT that’s screwed up. I have it sampling every 15 seconds or so, and it will bounce around by 5+ degrees in a still room.

Sounds like a plan. I’ll add an optional parameter for a filter constant. It will default to 100% so current users won’t have to change anything.

The value I send will be based on this simple equation:

filtered_value = (( 1 - filter_constant) * filtered_value) + (latest_value * filter_constant);

This will allow you select a filter constant between 5% and 100%.

100% will result in the latest value being sent every time the DHT is scanned - same as today.

50% will result in half of the latest value + half of the last value sent

etc…

What do you think?

2 Likes

That would be amazing. So for easy math, I select 10 second scan time with a 50% filter, it will report the average from the last 20 seconds to ST?

Also, any chance of pulling in @Vrpc’s commits for OTA updates?

I was trying to figure out where the conversion from Voltage to Temp or Humidity was and your example makes perfect sense. Just like the commercial/industrial controls world…voltage on one size with a scale, temp/humidity on the other with its scale.

I think I will mess with the voltage code and see if I can’t get a decimal place by switching the “int” to “float” and playing with that.

Hi Dan,

could you assist me in connecting an Adafruit SHT-31D temp humidity sensor using I2C
and a SODIAL 4 x 20 LCD ( Amazon ASIN: B00KBPQ8NW)
with a SODIAL I2C serial Interface Module Amazon ASIN: B00K67Y4CM

Being the Mode MCU ESP8266 is a 3.3 volt device, I would put a level shifter on the I2C bus between the NodeMCUesp8266 and the 5.0v olt devices on the I2C bus

I looked at the Adafriuit Max 31855 arduino example, using SPI, but need some assistance in the I2c connection and wire library

Your assistance is apprecated

Ben

This is my first time trying ST_Anything with a NodeMCU ESP8266. I think I followed the instructions properly. I’m using the ST_Anything_Multiples_ESP8266WiFi.ino sketch which I modified on each line that had a “You must edit this line” comment. The sketch seems to be running properly. I’ve only connected D2 (contact1) to ground to watch the debug window. It shows a changed state when D2 is connected to ground.

I was able to create a new device. On my iPhone, I gave it the IP address, port, MAC address and assigned two buttons. I clicked “Done”.

No child devices are created. I watched Live Logging. No joy. When I pulled down on the page, I got this message: getChildDevices(false), children=0

Basic info:
ESP8266 IP: 10.0.3.151
Smartthings Hub IP: 192.168.3.151
Port: 8090
MAC address matches NodeMCU’s MAC address with all caps and no separators.
Router IP: Tried both 192.168.3.1 and 10.0.3.151
Tried opening port 8090 on Mikrotik router.

I’m sure that I must have misconfigured something, but I don’t know what or where. Any advice?

Basically… But it’s a little bit more complicated than just the “last 20 seconds” worth of data.

See the following article, near the bottom of the page, for a more detailed explanation of the filter technique that I am using. It is lightweight and gets the job done. You simply adjust the filter constant from %5 to 100% to see the impact on the output value in ST. 5% will results in very slow changing values. 100% will result in the same behavior that is currently implemented (i.e. send the last read value from the sensor with no noise filtering.)

https://www.norwegiancreations.com/2015/10/tutorial-potentiometers-with-arduino-and-filtering/

I have the code basically complete, and it now outputs floating point values to SmartThings. On iOS it shows 1 decimal place in the ST Phone App. I’ll update GitHub later tonight when I am done with testing.

1 Like

99/100 times the MAC address is not typed into the Parent Device’s settings correctly. Also, double check your SmartThings HUB’s IP Address and make sure it is typed into the sketch correctly. Also, make sure you can ping both the ESP8266 and the HUB from another computer on the same network.

You do NOT need to forward any ports on your router.

Here is a map function that uses floating point numbers instead of integers.

float map_double(double x, double in_min, double in_max, double out_min, double out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Perhaps the PS_Voltage class should just use this instead of the Arduino built-in map() function as this actually provides a more flexible solution.

I’ll tweak PS_Voltage tonight to see how it behaves and will let you know.

In PS_Voltage.h couldn’t you just do:

	private:
		byte m_nAnalogInputPin;
		float m_nSensorValue, MAPPED_LOW, MAPPED_HIGH;
		const int SENSOR_LOW, SENSOR_HIGH;

and again in the constructor use float only for the mapped low and high then in the PS_Voltage.ccp use:

float m_nSensorValue=map(analogRead(m_nAnalogInputPin), SENSOR_LOW, SENSOR_HIGH, MAPPED_LOW, MAPPED_HIGH);

Or possible a math round command to reduce the float to 1 decimal before passing it?

Again pardon my ignorance if not. I do VB.Net programming so some of this makes sense but some doesn’t. I was going to try the above (my sketch compiles) and see what happens once I get my board tomorrow.