[DEPRECATED] ST_Anything - Arduino/ESP8266/ESP32

What else are you doing with the ESP8266? You just want to turn the bulletin LED on and off? What board are you using? Have you set up the device in ST and uploaded the sketch to your board? Can you post a copy of your sketch? have you uploaded all of the DTH into ST?

Figured it out (Hit my forehead). I was using the deprecated code. You learn something every day.

According to google: “In the world of software development, " deprecated " refers to functions or elements that are in the process of being replaced by newer ones.”

1 Like

Glad you figured it out. I was a little confused as to why you were using virtual switches and buttons, instead of just using the auto-created ST_Anything Child Device on your phone’s classic ST App.

Buen dia ogiewon,
He modificado una de tus librerias la EX_RGB_Dim y la modifique para manejar el led RGB Pixel WS2812B la he nombrado EX_RGB_Neo.

//******************************************************************************************
//  File: EX_RGB_Neo.h
//  Authors: Ariel Caicedo based on EX_RGB_Dim by Dan G Ogorchock
//
//  Summary:  EX_RGB_Neo is a class which implements the SmartThings "Color Control", "Switch", and "Switch Level" device capabilities.
//			  It inherits from the st::Executor class.
//
//			  Create an instance of this class in your sketch's global variable section
//			  For Example:  st::EX_RGB_Neo executor1("rgbSwitch1", PIN, true);
//
//			  st::EX_RGB_Neo() constructor requires the following arguments
//				- String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
//				- byte pin - REQUIRED - the Arduino Pin to be used as a digital output for Data
//			
//
//  Change History:
//
//    Date        Who            What
//    ----        ---            ----
//    2016-04-30  Dan Ogorchock  Original Creation
//    2018-08-14  Dan Ogorchock  Modified to avoid compiler errors on ESP32 since it currently does not support "analogWrite()"
//    2017-08-30  Dan Ogorchock  Modified comment section above to comply with new Parent/Child Device Handler requirements
//    2017-10-08  Allan (vseven) Modified original code from EX_RGB_Dim to be used for RGB lighting
//    2018-12-02  Ariel Caicedo  Modified original code from EX_RGB_Dim to be used for RGB lighting witch pixel WS2812B
//
//******************************************************************************************
#ifndef ST_EX_RGB_NEO
#define ST_EX_RGB_NEO

#include "Executor.h"
#include <Adafruit_NeoPixel.h>

namespace st
{
	class EX_RGB_Neo: public Executor
	{
		private:
			bool m_bCurrentState;	//HIGH or LOW
//			bool m_bInvertLogic;	//determines whether the Arduino Digital Output should use inverted logic
			byte m_nPin;		//Arduino Pin used as a PWM Output for Red
			String m_sCurrentHEX;	//HEX value of color currently set

			void writeRGBToPins();	//function to update the Arduino PWM Output Pins

		public:
			//constructor - called in your sketch's global variable declaration section
			EX_RGB_Neo(const __FlashStringHelper *name, byte pin, bool startingState = LOW);
			
			//destructor
			virtual ~EX_RGB_Neo();

			//initialization routine
			virtual void init();

			//SmartThings Shield data handler (receives command to turn "on" or "off" the switch along with HEX value for LEDs)
			virtual void beSmart(const String &str);
			
			//called periodically to ensure state of the switch is up to date in the SmartThings Cloud (in case an event is missed)
			virtual void refresh();
			
			//gets
			virtual byte getPin() const { return m_nPin; }

			virtual bool getStatus() const { return m_bCurrentState; } //whether the switch is HIGH or LOW
			virtual String getHEX() const { return m_sCurrentHEX; }	// color value in HEX

			//sets
			virtual void setPin(byte pin);
		
	};
}

#endif



//******************************************************************************************
//  File: EX_RGB_Neo.h
//  Authors: Ariel Caicedo based on EX_RGB_Dim by Dan G Ogorchock
//
//  Summary:  EX_RGB_Neo is a class which implements the SmartThings "Color Control", "Switch", and "Switch Level" device capabilities.
//			  It inherits from the st::Executor class.
//
//			  Create an instance of this class in your sketch's global variable section
//			  For Example:  st::EX_RGB_Neo executor1("rgbSwitch1", PIN, true);
//
//			  st::EX_RGB_Neo() constructor requires the following arguments
//				- String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
//				- byte pin - REQUIRED - the Arduino Pin to be used as a digital output for Data
//			
//
//  Change History:
//
//    Date        Who            What
//    ----        ---            ----
//    2016-04-30  Dan Ogorchock  Original Creation
//    2018-08-14  Dan Ogorchock  Modified to avoid compiler errors on ESP32 since it currently does not support "analogWrite()"
//    2017-08-30  Dan Ogorchock  Modified comment section above to comply with new Parent/Child Device Handler requirements
//    2017-10-08  Allan (vseven) Modified original code from EX_RGB_Dim to be used for RGB lighting
//    2018-12-02  Ariel Caicedo  Modified original code from EX_RGB_Dim to be used for RGB lighting witch pixel WS2812B
//
//******************************************************************************************
#include "EX_RGB_Neo.h"

#include "Constants.h"
#include "Everything.h"
#include <Adafruit_NeoPixel.h>

namespace st
{
//private
	void EX_RGB_Neo::writeRGBToPins()
	{
		int subStringR;
		int subStringG;
		int subStringB;

		if (m_bCurrentState == HIGH)
		{
		  // Our status is on so get the RGB value from the hex
            String hexstring = m_sCurrentHEX;
            long number = (long) strtol( &hexstring[1], NULL, 16);
            // Split them up into r, g, b values
            subStringR = number >> 16;
            subStringG = number >> 8 & 0xFF;
            subStringB = number & 0xFF;
        }
        else
        {
            // Status is off so turn off LED
            subStringR = 00;
            subStringG = 00;
            subStringB = 00;
        }
  /*    	if(m_bInvertLogic)
		{
        		// A hex value of 00 will translate to 255 for a common anode.  However the  
        		// ledcWrite seems to need a 256 to turn off so we are adding one here.
        		subStringR = 255 - subStringR + 1;
        		subStringG = 255 - subStringG + 1;
        		subStringB = 255 - subStringB + 1;
      	} */
		// Write to outputs.  Use ledc for ESP32, analogWrite for everything else.

		if (st::Executor::debug) {
			Serial.print(F("subString R:G:B = "));
			Serial.println(String(subStringR) + ":" + String(subStringG) + ":" + String(subStringB));
		}

		// Any adjustments to the colors can be done here before sending the commands.  For example if red is always too bright reduce it:
		// subStringR = subStringR * 0.95
        
        Adafruit_NeoPixel pixels = Adafruit_NeoPixel(1, m_nPin, NEO_GRB + NEO_KHZ800);
        pixels.begin(); // This initializes the NeoPixel library.
        pixels.setPixelColor(0, pixels.Color(subStringG, subStringR, subStringB)); // Moderately bright green color.
        pixels.show(); // This sends the updated pixel color to the hardware.
        
	}

//public
	//constructor
	EX_RGB_Neo::EX_RGB_Neo(const __FlashStringHelper *name, byte pin, bool startingState):
		Executor(name),
		m_bCurrentState(startingState)
	{
		setPin(pin);    
	}

	//destructor
	EX_RGB_Neo::~EX_RGB_Neo()
	{
	
	}
	
	void EX_RGB_Neo::init()
	{
		Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH ? F("on") : F("off")));
	}

	void EX_RGB_Neo::beSmart(const String &str)
	{
		String s=str.substring(str.indexOf(' ')+1);
		if (st::Executor::debug) {
			Serial.print(F("EX_RGB_Neo::beSmart s = "));
			Serial.println(s);
		}
		if(s==F("on"))
		{
			m_bCurrentState=HIGH;
		}
		else if(s==F("off"))
		{
			m_bCurrentState=LOW;
		}
		else //must be a set color command
		{
			s.trim();
			m_sCurrentHEX = s;
		}

		writeRGBToPins();

		Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH?F("on"):F("off")));
	}
	
	void EX_RGB_Neo::refresh()
	{
		Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH?F("on"):F("off")));
	}
	
	void EX_RGB_Neo::setPin(byte pin)
	{
		m_nPin = pin;
     	pinMode(m_nPin, OUTPUT);
        writeRGBToPins();
	}
}

I’ve done the same thing and it becomes unstable the more you add, it seems completely random but anywhere from 10 to 30 LEDs and it reboots the controller. From what I can tell you are only doing one as you are defining the object with 1 led with no way to change that. Have you tried multiples?

it only required a pixel, you would have to modify that library if you want more than one pixel, making changes in the arduino library and the ST controller

Hi Dan,

Got an issue I really hope you can help with!

So I have a ST_Anything setup running with 5 RC switches which all work as expected! I don’t use Switch 3 in its normal way, I pass it some dud RF values as I actually want to use another library for LightwaveRF for this switch using your callback function. Hope you’re still with me!

So I have the following callback function:

void callback(const String &msg)
{
  Serial.print(F("ST_Anything Callback: Sniffed data = "));
  Serial.println(msg);
  if(msg.startsWith("switch3 on")){
      lw_send(lighton);
      //lw_cmd(0,0,LW_LOCK,lwid);
  }
  if(msg.startsWith("switch3 off")){
      lw_send(lightoff); 
  }
}

Now this works great! If I change switch three within the Smartthings app then it trigger my Lightwave light as I would like it to…

BUT, here is the issue.

When I boot up my ESP8266 and leave it running without touching anything I get the following pattern:

Everything: Free Ram = 44248
Everything: Free Ram = 44248
Everything: Free Ram = 44248
Everything: Free Ram = 44248
Everything: Sending: switch1 off
ST_Anything Callback: Sniffed data = switch1 off
Everything: Sending: switch2 off
ST_Anything Callback: Sniffed data = switch2 off
Everything: Sending: switch3 off
ST_Anything Callback: Sniffed data = switch3 off
Everything: Sending: switch4 off
ST_Anything Callback: Sniffed data = switch4 off
Everything: Sending: switch5 off
ST_Anything Callback: Sniffed data = switch5 off
Everything: Free Ram = 44248
Everything: Free Ram = 44248

And it continues like this, now the weird thing is that these random messages do not cause any of the RC switches to turn off EXCEPT my custom one as the callback message is run and triggers the lw light off message.

Any ideas? This is driving me mad as the above switch off messages happen about every 5 minutes which means my lightwave light goes off every five minutes? Is the above normal, or can you think of anyway for me to change the callback to avoid this issue.

Thanks in advance!

Yes, inside the ST_Anything library you will find a file name “constants.h” which can can modify to disable the automatic 5 minute refreshes.

Here is the line of code which you will need to UN-Comment…

//#define DISABLE_REFRESH		//If uncommented, will disable periodic refresh of the sensors and executors states to the ST Cloud - improves performance, but may reduce data integrity

What I’m saying is I’ve already done what you’re proposing except when you declare it in the sketch you can enter how many LEDs you want to find. The problem is the more you add will cause the controller to crash. There’s a timing issue with the neopixel library. Its fine for a couple LEDs but more you have the bigger the chance the controller will crash.

Libraries: https://github.com/vseven/SmartThings_VSeven/blob/master/Modified_ST_Anything_Libraries/EX_RGBAddressable_Dim.h and https://github.com/vseven/SmartThings_VSeven/blob/master/Modified_ST_Anything_Libraries/EX_RGBAddressable_Dim.cpp

Example Sketch: https://github.com/vseven/SmartThings_VSeven/blob/master/Modified_ST_Anything_Libraries/ST_Anything_AddressableRGB_ESP8266WiFi.ino

Little better using something like this so you can define the number of LEDs in the sketch instead of hard coded in the library.

A general question for users of the ESP8266 NodeMCU and I2C bus sensors

Have you as users had any issues with I2C bus lockup? If so how did you handle the issue?

Dan, the default I2C pins of the ESP8266 NodeMCU are
D1=GPIO5=SCL, and D2=GPIO4=SDA.

May I ask why you chose pins
#define PIN_SDA D3 //works well on NodeMCU v1.0 board
#define PIN_SCL D4 //works well on NodeMCU v1.0 board

for your I2C connection? Any I2C Bus Lockup issues with D1 and D2?

I am having issues with trying to connect an ESP8266 to a K30 CO2 sensor via I2C.

In my previous adventure you helped me with a Leonardo project that used the K30 sensor, very nicely and reliably. Trying to move on from the ThingShield, to use the ESP8266NodeMCU

Thanks
Ben

Ben,

That’s a good question… If I recall correctly, I did experience some issues when using D1/D2 for I2C on the ESP8266. I have a NodeMCU ESP8266 board that has been running for months now using I2C on pins D3/D4 for a temperature/humidity sensor and it has never locked up. That same board also monitors 4 DS18B20 sensors (all on one pin) and 4 contact sensors.

Dan

Is it possible to update a variable in the sketch via the Smartthings app?

Fixed it! thank you so much!

Can you provide an example use-case for this? The ST App does not really allow for data entry. You can use a slider control to enter values from 0 to 99, that are then sent down to the ST_Anything sketch as a dimmer level… As far as I know, you cannot enter text into the ST App, except as a device setting. Again, those could be sent to the Arduino, if desired.

Help me understand what you’re trying to accomplish.

Are the DHT sensors working fine thru the Arduino serial monitor? I had DHT22 issues with ESP8266 and ESP32 boards until I found DHT librarys build specifically for the esp’s.

Yeah they were working fine through the monitor.
They’ve been up and running no problems for a while now :blush:

This is what I am trying to do as well. I have a nodemcu with an ultrasonic sensor and an rgb strip. I hacked the ultrasonic library so that I can poll the sensor every 100 milliseconds without interfering with the st poll of every minute. The rgb is set to display different colors depending on the ultrasonic sensor value.

I want to be able to change the distance values and the rgb color in the sketch with values from the app. I created some extra preferences in the st_anything app and was able to store some values. My assumption is that I need to create a variable and a reference like you posted a few days ago. I’m just not sure how or where to retrieve the variables.

The easiest way to do this is to add another callback function (e.g. callbackRcvd( const String &msg) ) to your sketch. The st::everything class supports two optional callbacks, one for data being sent to SmartThings, and another for data coming from SmartThings. My example sketches demonstrate the first one. But you can easily add the second one as well.

Here are the function pointer definitions from Everything.h.

			static void (*callOnMsgSend)(const String &msg); //If this function pointer is assigned, the function it points to will be called upon every time a string is sent to the cloud.		
			static void (*callOnMsgRcvd)(const String &msg); //If this function pointer is assigned, the function it points to will be called upon every time a string is received from the cloud.

In the example sketches, you’ll find the following line of code in the setup() routine. Just add another uniquely named callback function, and add it as follows…

  //Initialize the optional local callback routine (safe to comment out if not desired)
  st::Everything::callOnMsgSend = callback;
  st::Everything::callOnMsgRcvd = callbackRcvd;

Hopefully this makes sense for the Arduino changes. Within your new callback, you can grab the name/ value pairs being sent from ST and do whatever you want in your sketch.

On the groovy side, just add appropriate calls to send the properly formatted name/value pairs to the Arduino.

3 Likes

I am modernising our old drying cabinet the used to be controlled by a mecanical timer to be humidity controlled. Using a temp/humidity sensor I monitor the humidity level, and when it hits a specified setpoint the laundry should be dry, and the cabinets turns off. I will only use St_anything for operation indication in Smartthings.
My wish is to be able to change the humidity setpoint variable without physically connect to the Arduino with a USB-cord.

I am curious… What is being used to turn off the drying cabinet? Is the ST_Anything Arduino changing the value of an output to accomplish this? Or, are you letting SmartThings compare the humidity value against a target and then it turns off the power?

In any event, if you want to send the target data from ST to the Arduino running ST_Anything, follow the directions I outlined in the previous post.