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

arduino
alarm
dth_misc
esp8266
esp32

(Seth Miller) #2367

Thanks Dan. I started doing this initially but I was hoping to take advantage of the great code that has already been written. For example, I modified the PS_Ultrasonic::getData() function to only send the string to ST if a parameter is not set. That way I can call it all I want without sending the string to ST. The only thing I can’t figure out is how to call the PS_Ultrasonic::getData() function directly.


(Dan) #2368

In your sketch, you should be able to simply call the device’s getData() function using the following as a guideline. The problem you’re most likely having is one of scope of the variables. Since the devices are declared in the setup() routine, you will need a global variable to hold a reference to the PS_Ultrasonic object to be able to use it in the loop() routine.

Before (outside of) your setup() routine, declare a variable as follows:

st::PS_Ultrasonic* ultrasonicDevice;

in your setup() routine you should have something similar to the first line below. Add the second line to your setup() routine.

  //Polling Sensors
  static st::PS_Ultrasonic  sensor1(F("ultrasonic1"), 60, 0, PIN_ULTRASONIC_T, PIN_ULTRASONIC_E);

 //Add this line
  ultrasonicDevice = &sensor1;

In your loop() routine you should be able to simple call

ultrasonicDevice->getData()

Hopefully these changes make sense. Let me know how it goes for you.


(Seth Miller) #2369

This is exactly what I was looking for. I’ll try it tonight. If I submit a pull request when it’s done, is this something you would merge? If so, should it be added to the current ultrasonic library, or should it be completely separate?


(Dan) #2370

You can submit a pull request. I’ll need to look at your changes to evaluate how generic they are, especially for existing users. Backwards compatibility is always very important.


#2371

Hello Dan,

Thanks for your hard work on developing this nice library. I am building a small project for my house to control a bunch of relay switches in addition to several temperature/ultrasonic sensors. As I need quite a few inputs and outputs, I chose to use an arduino mega2560 with ESP-01 as the wifi link. The setup is quite straightforward. However, I noticed that the switch devices do not always respond. When I pressed the swtich button in the SmartThings App, it sometimes got stuck in the TurningOn or TurningOff state. Whenever this happened, the relay could not switch accordingly. When I monitored the Serial outputs (with debug enable), it did not show the entry for the “switch on” command as it should for a successful switching event like below. So I guess somehow the command got lost during communication, and it happens randomly. All the polling sensors, on the other hand, seem to be working well.

Handling request from ST. tempString = switch3 on
Everything: Received: switch3 on
EX_Switch::beSmart s = on
Everything: Sending: switch3 on

As a control test, I loaded the same codes to a nodemcu (ESP-12E), and all the switches always work as expected. Do you have any suggestions on what could be the problem? Thanks!


(Dan) #2372

I have never found the Arduino MEGA + ESP01 to be a very reliable communications solution. The Arduino MEGA + W5100 Ethernet Shield is very reliable. Also, as you have already found, the NodeMCU ESP8266 is also a very reliable solution. The NodeMCU ESP32 is also pretty good, and it offers quite a bit more I/O vs the ESP8266.

I tried for a few months to get the MEGA + ESP01 to be reliable, but I was never successful. I am always hopeful that someone else with rise to the challenge and figure out if there is a better way to do it and issue a pull request to the ST_Anything GitHub repository.

Another option might be to use a Raspberry Pi, running my son’s much newer OmniThing project. It does not yet support all of the same devices as ST_Anything, but it runs on a Pi, or ESP8266, with very reliable WiFi connectivity.


(Matthew Sanders) #2373

I’m new to this project and would greatly appreciate anyone’s assistance. My goal is to merely turn the LED on the ESP8266 off and on with smartthings. What I’ve done is created a virtual switch in smartthings and tried to integrate it using the “Button Controller” app. When I hit refresh in the app, my serial port on the ESP8266 updates, however, the switch remains off. Can anyone provide me with a clue for what I need to do?

Thanks
Matt


#2374

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?


(Matthew Sanders) #2375

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.”


(Dan) #2376

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.


(Ariel Mauricio Caicedo Linares) #2377

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();
	}
}

(Allan) #2378

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?


(Ariel Mauricio Caicedo Linares) #2379

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


(Gary) #2380

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!


(Dan) #2381

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

(Allan) #2382

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.


(Ben Wolodko) #2383

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


(Dan) #2384

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


(Tommy Saaek) #2385

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


(Gary) #2386

Fixed it! thank you so much!