[Release] HubDuino v1.1.7 - Hubitat to Arduino / ESP8266 / ESP32 / ThingShield Integration (ST_Anything)

Okay, I'll give it a try then! What do you mean the issue is when the Ethernet is not serviced continuously? Doesnt the ethernet connection have to be serviced continuously in order for the interrupt sensors to work properly?

Within the ST_Anything architecture, the communications with the HUB are handled by another library called "SmartThingsEthernetW5500" (for a MEGA with a W5500 shield.)

In the loop() routine, you'll see the st::Everything::run() command being executed constantly.

void loop()
{
  //*****************************************************************************
  //Execute the Everything run method which takes care of "Everything"
  //*****************************************************************************
  st::Everything::run();
}

One of the things done inside the Everything's Run function, is the servicing of the Ethernet Server and Client. Also, with Run() is the servicing of all sensors and executors. It's just one big loop, where each device gets serviced based on its particular requirements. The only problem that can easily occur is when users add their own codewith blocking calls (e.g. delay()) within the loop() or callback() functions of the sketch. Nothing else will happen during this time. Users who decide to create their own ST_Anything Device classes also have to be wary of this issue.

Whether or not this is going to cause a big issue is somewhat dependent on the user's particular needs and what devices are included in the sketch.

Hope this helps explain it.

Ok, I could use some thoughts/guidance.

I currently have 3 Konnected esp8266 based boards that I'm bringing my alarm contacts in on. Even though I have diodes on the inputs, and the power is fed from a surge protector and UPS, I keep losing wifi modules.

As such, I pre-ordered the Konnected Pro-12, as it has an Ethernet port.

However then I started thinking that maybe I could just make my own with an arduino of some flavor.

Ideally what I want is a board (or multiple boards if I have to) to bring in 1 wired motion sensor and 15 open/close sensors. It would be nice to be able to drive my alarm siren like I can with my Konnected, but in a pinch I would give that up if that is the only thing I couldn't get to work.

Any thoughts on if this is doable? If so, any other thoughts on what hardware to get? There are a ton of options that can use an arduino ethernet shield, but as I've only used esp8266 before I'm not sure if there would be one 'super' board that might do what I need.

So, 16 digital inputs and one digital output, correct?

  • An Arduino MEGA 2560 + W5500 Ethernet2 shield would work.
  • A NodeMCU ESP32 (WiFi)would also probably work, but I am not sure if any of the GPIO pins would be problematic like some are on the ESP8266.
  • An ARDUINO NANO 33 IOT (WiFi) should also do the trick (need to verify its analog pins can be used as digital pins. This is true on the UNO/MEGA boards)

Using HubDuino/ST_Anything, you can implement contact sensors, alarms (sirens), switches, garage door controllers, motion sensors, temperature/humidity sensors, etc...

I personally use an Arduino MEGA + W5500 shield to monitor my door contact sensors, control two garage doors, monitor motion and measure temperature/humidity in my garage. Adding a siren would be trivial. I even have a Honeywell siren, but I have been lazy about hooking it up with a relay.

The real question is why are you losing NodeMCU ESP8266 modules? Do you still have an old alarm panel system running? Or have you replaced it with Konnected? If the former, I wonder what your circuit looks like to “tap into” the active 12v sensors with a 3.3v ESP8266. If the latter, not sure why they would die. Do you have any hypotheses?

I entirely replaced my alarm panel with konnected boards. I wish I knew why I was losing wifi boards, I really have no idea... I lost 2 or 3 before I installed diodes on the inputs, after lightening storms. Those I understood.

Then over the last year I've lost 3 more wifi boards. Really no idea why. And I am pretty confident that it is the wifi board, as replacing it fixes things... Putting the old one back repeats the issue.

Sometimes the entire board stops communicating, other times I just start losing some, but not all, of the input channels. Weird. They are cheap, so I've just kept replacing them, but it's getting old.

I verified the diodes on the inputs are installed correctly. Not sure there is much else I can do on the power input (surge protector + UPS now).

That is why I was thinking of just going with an Ethernet based board (I have a switch about 12" from the alarm panel).

This was my question as well. Your Konnected board came with a 12v power supply, and that is the supply you are using, correct? You have not bypassed any of the wiring to the inputs on the Konnected board?

I am curious though if the board is using 3.3v logic all the way through (output as well as input) of if the board is outputing 12v and then dividing down to 3.3v on the input to prevent voltage drop from being a factor. But at the currents we're talking about here, the voltage drop is going to be so negligable, it wouldn't make a difference. Measuring the voltage at one of the inputs would answer that question though.

Also, when you have changed your boards, you've only change the wifi module? It's possible that the power regulator on the base board is shot and that's what's causing the problem. I'm sure they're not running all of the sensors off the 3.3v regulator on the NodeMCU, so the base board has to have a power regulator to go from 12v down to 5v or 3.3v. So, I would check the voltage going to the header pins on the Konnected board as well to make sure that it isn't over 3.3v or 5v, depending on how the board is wired to provide power. I tried to look at a pic of the board to get the numbers off the power regulator but I couldn't get it blown up large enough to read them.

But it definitely sounds to me like a slight voltage problem. Nothing that is frying the board as soon as you plug it in but is slowly cooking it by overloading the GPIO pins.

The diodes won't protect you from slight over-voltages. Only from BIG spikes like lightning. But 4.3v will go through just fine and just slowly fry your board.

Ah so you are right. I would obviously need a 360' servo like this then. Can a 360' rotation be handled by HubDuino @ogiewon?

This servo would not have the necessary power to lift your shade. You need to look at steppers or DC motors. They have a lot more torque.

1 Like

Maybe I'll just go a powerful DC motor then and just use forward and reverse like I did for the water valve. I only need it to open and close e.g no half way functions so I could just time it and call it a day.

I've tried 2 different power supplies, had wifi boards go out on both of them.

Correct, just the wifi modules. I've never tried changing out the base plate boards, so it indeed could be something on that side (marginal regulator, insufficient ESD on inputs, other). On the 3 sets of boards I have, all of the bad wifi modules have been on boards #2 and #3 - never on #1... Which I think also supports that it is not the incoming power feed as they are all fed off the same power supply.

I have nothing against the Konnected boards. As I look to moving to an Ethernet connected model, though, it seemed like something I could just do myself relatively easy. I just need to sit down and think my way through it - could bring it into HE directly with this, dump it to MQTT, etc..

I have never tried it. I have no experience with it.

1 Like

I thought of something else last night. If the base board regulates the voltage to 5v and they are using the gpio pins direct with an internal pull-up resistor, if you have any shorts in the wires the current draw might be too high for the 3.3v regulator on the board. Most of them max out at 800-1000 mA.

You'd be able to tell if that is happening by taking one of your old board and trying to power it from the 3.3 v pin of one of the new boards. If the unit works, that means the 3.3v regulator on the board is dead.

I got all of the new pieces ordered this morning. Wish me luck lol.

Going to try an arduino mega, ethernet shield, and a 5v relay for driving the 12V siren. About $60 total.

Next step is to learn how to program an arduino. lol. I've looked at it before while tinkering with my general purpose ESP8266 board I bought for a different project. But I'm no expert by any means.

And if I keep having problems, I'll slap opto couplers on all the inputs and move on with my life.

Or, you could simply use HubDuino/ST_Anything and be up in running in less than an hour. No 'real' programming required. Just have to 'configure' the sketch. Happy to assist you with this to ensure a smooth experience.

That is actually my plan. :+1:

I did order 2xMega's, ethernet shields, and some alarm system door/window contacts so I'll have an extra set to tinker with in case I want to try dumping it to MQTT or some other wacky idea instead.

1 Like

Here is a quick example sketch that I believe will meet your requirements. I have not compiled or tested this sketch, so there is a possibility of a typo. This sketch is designed to handle 1 motion sensor, 15 contact sensors, and 1 simple alarm siren (alarm sound only, no separate strobe. If a separate strobe is desired, we can make a simple tweak.)

This should get you started. Let me know if you have any questions.

//******************************************************************************************
//  File: ST_Anything_JasonJoel_EthernetW5500.ino
//  Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
//
//  Summary:  This Arduino Sketch, along with the ST_Anything library and the revised SmartThings 
//            library, demonstrates the ability of one Arduino + Ethernet W5500 Shield to 
//            implement a multi input/output custom device for integration into Hubitat.
//            The ST_Anything library takes care of all of the work to schedule device updates
//            as well as all communications with the Ethernet W5500 Shield.
//
//            ST_Anything_JasonJoel implements the following ST Capabilities in multiples of 2 as a demo of what is possible with a single Arduino
//              - 1 x Motion devices (used to detect motion)
//              -15 x Contact Sensor devices (used to monitor magnetic door sensors)
//              - 1 x Alarm devices - 1 siren only, 1 siren and strobe (using simple digital outputs)
//
//            During the development of this re-usable library, it became apparent that the 
//            Arduino UNO R3's very limited 2K of SRAM was very limiting in the number of 
//            devices that could be implemented simultaneously.  A tremendous amount of effort
//            has gone into reducing the SRAM usage, including siginificant improvements to
//            the SmartThings Arduino library.
//
//            Note: The orignal 'Multiples' sketch was fully tested on an Arduino MEGA 2560 using the Ethernet2 W5500 Shield.
//    
//  Change History:
//
//    Date        Who            What
//    ----        ---            ----
//    2015-01-03  Dan & Daniel   Original Creation
//    2017-02-12  Dan Ogorchock  Revised to use the new SMartThings v2.0 library
//    2017-04-16  Dan Ogorchock  New sketch to demonstrate multiple SmartThings Capabilties of each type
//    2017-04-22  Dan Ogorchock  Added Voltage, Carbon Monoxide, and Alarm with Strobe
//    2017-04-22  Dan Ogorchock  Initial version for W5500 Ethernet2 Shield
//    2018-02-09  Dan Ogorchock  Added support for Hubitat Elevation Hub
//    2019-11-11  Dan Ogorchock  Custom version for JasonJoel
//
//******************************************************************************************
//******************************************************************************************
// SmartThings Communications Library for Arduino Ethernet W5500 Shield
//******************************************************************************************
#include <SmartThingsEthernetW5500.h>    //Library to provide API to the SmartThings Ethernet W5500 Shield

//******************************************************************************************
// ST_Anything Library 
//******************************************************************************************
#include <Constants.h>       //Constants.h is designed to be modified by the end user to adjust behavior of the ST_Anything library
#include <Device.h>          //Generic Device Class, inherited by Sensor and Executor classes
#include <Sensor.h>          //Generic Sensor Class, typically provides data to ST Cloud (e.g. Temperature, Motion, etc...)
#include <Executor.h>        //Generic Executor Class, typically receives data from ST Cloud (e.g. Switch)
#include <InterruptSensor.h> //Generic Interrupt "Sensor" Class, waits for change of state on digital input 
#include <PollingSensor.h>   //Generic Polling "Sensor" Class, polls Arduino pins periodically
#include <Everything.h>      //Master Brain of ST_Anything library that ties everything together and performs ST Shield communications

#include <PS_Illuminance.h>  //Implements a Polling Sensor (PS) to measure light levels via a photo resistor on an analog input pin 
#include <PS_Voltage.h>      //Implements a Polling Sensor (PS) to measure voltage on an analog input pin 
#include <PS_TemperatureHumidity.h>  //Implements a Polling Sensor (PS) to measure Temperature and Humidity via DHT library
#include <PS_Water.h>        //Implements a Polling Sensor (PS) to measure presence of water (i.e. leak detector) on an analog input pin 
#include <IS_Motion.h>       //Implements an Interrupt Sensor (IS) to detect motion via a PIR sensor on a digital input pin
#include <IS_Contact.h>      //Implements an Interrupt Sensor (IS) to monitor the status of a digital input pin
#include <IS_Smoke.h>        //Implements an Interrupt Sensor (IS) to monitor the status of a digital input pin
#include <IS_CarbonMonoxide.h> //Implements an Interrupt Sensor (IS) to monitor the status of a digital input pin
#include <IS_DoorControl.h>  //Implements an Interrupt Sensor (IS) and Executor to monitor the status of a digital input pin and control a digital output pin
#include <IS_Button.h>       //Implements an Interrupt Sensor (IS) to monitor the status of a digital input pin for button presses
#include <EX_Switch.h>       //Implements an Executor (EX) via a digital output to a relay
#include <EX_Alarm.h>        //Implements Executor (EX)as an Alarm capability with Siren and Strobe via digital outputs to relays
#include <S_TimedRelay.h>    //Implements a Sensor to control a digital output pin with timing/cycle repeat capabilities

//**********************************************************************************************************
//Define which Arduino Pins will be used for each device
//  Notes: Arduino communicates with both the W5500 and SD card using the SPI bus (through the ICSP header). 
//         This is on digital pins 10, 11, 12, and 13 on the Uno and pins 50, 51, and 52 on the Mega. 
//         On both boards, pin 10 is used to select the W5500 and pin 4 for the SD card. 
//         These pins cannot be used for general I/O. On the Mega, the hardware SS pin, 53, 
//         is not used to select either the W5500 or the SD card, but it must be kept as an output 
//         or the SPI interface won't work.
//         See https://www.arduino.cc/en/Main/ArduinoEthernetShield for details on the W5500 Sield
//**********************************************************************************************************
//"RESERVED" pins for W5500 Ethernet Shield - best to avoid
#define PIN_4_RESERVED            4   //reserved by W5500 Shield on both UNO and MEGA
#define PIN_1O_RESERVED           10  //reserved by W5500 Shield on both UNO and MEGA
#define PIN_11_RESERVED           11  //reserved by W5500 Shield on UNO
#define PIN_12_RESERVED           12  //reserved by W5500 Shield on UNO
#define PIN_13_RESERVED           13  //reserved by W5500 Shield on UNO
#define PIN_50_RESERVED           50  //reserved by W5500 Shield on MEGA
#define PIN_51_RESERVED           51  //reserved by W5500 Shield on MEGA
#define PIN_52_RESERVED           52  //reserved by W5500 Shield on MEGA
#define PIN_53_RESERVED           53  //reserved by W5500 Shield on MEGA


//Analog Pins

//Digital Pins
#define PIN_MOTION_1              24  //Hubitat Capability "Motion Sensor"

#define PIN_CONTACT_1             26  //Hubitat Capability "Contact Sensor"
#define PIN_CONTACT_2             27  //Hubitat Capability "Contact Sensor"
#define PIN_CONTACT_3             28  //Hubitat Capability "Contact Sensor"
#define PIN_CONTACT_4             29  //Hubitat Capability "Contact Sensor"
#define PIN_CONTACT_5             30  //Hubitat Capability "Contact Sensor"
#define PIN_CONTACT_6             31  //Hubitat Capability "Contact Sensor"
#define PIN_CONTACT_7             32  //Hubitat Capability "Contact Sensor"
#define PIN_CONTACT_8             33  //Hubitat Capability "Contact Sensor"
#define PIN_CONTACT_9             34  //Hubitat Capability "Contact Sensor"
#define PIN_CONTACT_10            35  //Hubitat Capability "Contact Sensor"
#define PIN_CONTACT_11            36  //Hubitat Capability "Contact Sensor"
#define PIN_CONTACT_12            37  //Hubitat Capability "Contact Sensor"
#define PIN_CONTACT_13            38  //Hubitat Capability "Contact Sensor"
#define PIN_CONTACT_14            39  //Hubitat Capability "Contact Sensor"
#define PIN_CONTACT_15            40  //Hubitat Capability "Contact Sensor"

#define PIN_ALARM_1               45  //Hubitat Capability "Alarm"

//Garage Door Pins 

//Pushbutton Pins

//******************************************************************************************
//W5500 Ethernet Shield Information
//****************************************************************************************** 
byte mac[] = {0x06,0x02,0x03,0x04,0x05,0x06}; //MAC address                       //  <---You must edit this line using the MAC address provided with your W5500 Shield!
IPAddress ip(192, 168, 1, 231);               //Arduino device IP Address         //  <---You must edit this line!
IPAddress gateway(192, 168, 1, 1);            //router gateway                    //  <---You must edit this line!
IPAddress subnet(255, 255, 255, 0);           //LAN subnet mask                   //  <---You must edit this line!
IPAddress dnsserver(192, 168, 1, 1);          //DNS server                        //  <---You must edit this line!
const unsigned int serverPort = 8090;         //port to run the http server on

// Hubitat Hub TCP/IP Address
IPAddress hubIp(192, 168, 1, 149);    // smartthings/hubitat hub ip               //  <---You must edit this line!

// Hubitat Hub Port
const unsigned int hubPort = 39501;   // hubitat hub port

//******************************************************************************************
//st::Everything::callOnMsgSend() optional callback routine.  This is a sniffer to monitor 
//    data being sent to ST.  This allows a user to act on data changes locally within the 
//    Arduino sktech withotu having to rely on the ST Cloud for time-critical tasks.
//    Do not add an delay(), or other blocking statements in this function.
//******************************************************************************************
void callback(const String &msg)
{
  //Uncomment if it weould be desirable to using this function
  //Serial.print(F("ST_Anything_Miltiples Callback: Sniffed data = "));
  //Serial.println(msg);
  
  //TODO:  Add local logic here to take action when a device's value/state is changed
  
  //Masquerade as the network to send data to the Arduino, as if from the Hubitat hub (uncomment and edit following line(s) as you see fit)
  //st::receiveSmartString("Put your command here!");  //use same strings that the Device Driver would send (e.g. "alarm1 siren", "alarm1 off")
}

//******************************************************************************************
//Arduino Setup() routine
//******************************************************************************************
void setup()
{
  //******************************************************************************************
  //Declare each Device that is attached to the Arduino
  //  Notes: - For details on each device's constructor arguments below, PLEASE REFER to the 
  //           corresponding header (.h) and program (.cpp) files.  Comments at the top of these
  //           files provide detailed documentation for each ST_Anything device class.
  //         - The name assigned to each device (1st argument below) must match the Groovy
  //           Device Driver names.  (Note: "temphumid" below is the exception to this rule
  //           as the DHT sensors produce both "temperature" and "humidity".  Data from that
  //           particular sensor is sent to the ST Hub in two separate updates, one for 
  //           "temperature" and one for "humidity")
  //         - The new Composite Device Handler is comprised of a Parent DH and various Child
  //           DH's.  The names used below MUST not be changed for the Automatic Creation of
  //           child devices to work properly.  Simply increment the number by +1 for each duplicate
  //           device (e.g. contact1, contact2, contact3, etc...)  You can change the Child Device
  //           LABELS to match your specific use case in the Hubitat admin web page on the hub.
  //******************************************************************************************
  //Polling Sensors 
  
  //Interrupt Sensors 
  static st::IS_Motion     sensor1(F("motion1"), PIN_MOTION_1, HIGH, false, 500); //May need to tweak the 'HIGH' & 'false' params depending on your sensor
  
  static st::IS_Contact    sensor2(F("contact1"), PIN_CONTACT_1, LOW, true, 500); //Configured to use internal pullup resistor, just wire contact 
  static st::IS_Contact    sensor3(F("contact2"), PIN_CONTACT_2, LOW, true, 500); //sensor to the pin and gnd on the Arduino board
  static st::IS_Contact    sensor4(F("contact3"), PIN_CONTACT_3, LOW, true, 500);
  static st::IS_Contact    sensor5(F("contact4"), PIN_CONTACT_4, LOW, true, 500);
  static st::IS_Contact    sensor6(F("contact5"), PIN_CONTACT_5, LOW, true, 500);
  static st::IS_Contact    sensor7(F("contact6"), PIN_CONTACT_6, LOW, true, 500);
  static st::IS_Contact    sensor8(F("contact7"), PIN_CONTACT_7, LOW, true, 500);
  static st::IS_Contact    sensor9(F("contact8"), PIN_CONTACT_8, LOW, true, 500);
  static st::IS_Contact    sensor10(F("contact9"), PIN_CONTACT_9, LOW, true, 500);
  static st::IS_Contact    sensor11(F("contact10"), PIN_CONTACT_10, LOW, true, 500);
  static st::IS_Contact    sensor12(F("contact11"), PIN_CONTACT_11, LOW, true, 500);
  static st::IS_Contact    sensor13(F("contact12"), PIN_CONTACT_12, LOW, true, 500);
  static st::IS_Contact    sensor14(F("contact12"), PIN_CONTACT_13, LOW, true, 500);
  static st::IS_Contact    sensor15(F("contact14"), PIN_CONTACT_14, LOW, true, 500);
  static st::IS_Contact    sensor16(F("contact15"), PIN_CONTACT_15, LOW, true, 500);

  //Special sensors/executors (uses portions of both polling and executor classes)

  //Executors
  static st::EX_Alarm      executor1(F("alarm1"), PIN_ALARM_1, LOW, true);  //may need to tweak the 'true' to 'false' depending on the 
                                                                                     //relay being used ('true' = Active LOW versus 'false' = Active HIGH)
    
  //*****************************************************************************
  //  Configure debug print output from each main class 
  //*****************************************************************************
  st::Everything::debug=true;
  st::Executor::debug=true;
  st::Device::debug=true;
  st::PollingSensor::debug=true;
  st::InterruptSensor::debug=true;

  //*****************************************************************************
  //Initialize the "Everything" Class
  //*****************************************************************************
  
  //Initialize the optional local callback routine (safe to comment out if not desired)
  st::Everything::callOnMsgSend = callback;
  
  //Create the SmartThings EthernetW5500 Communications Object
    //STATIC IP Assignment - Recommended
    st::Everything::SmartThing = new st::SmartThingsEthernetW5500(mac, ip, gateway, subnet, dnsserver, serverPort, hubIp, hubPort, st::receiveSmartString);
 
    //DHCP IP Assigment - Must set your router's DHCP server to provice a static IP address for this device's MAC address
    //st::Everything::SmartThing = new st::SmartThingsEthernetW5500(mac, serverPort, hubIp, hubPort, st::receiveSmartString);

  //Run the Everything class' init() routine which establishes Ethernet communications with the SmartThings Hub
  st::Everything::init();
  
  //*****************************************************************************
  //Add each sensor to the "Everything" Class
  //*****************************************************************************
  st::Everything::addSensor(&sensor1);
  st::Everything::addSensor(&sensor2);
  st::Everything::addSensor(&sensor3);
  st::Everything::addSensor(&sensor4); 
  st::Everything::addSensor(&sensor5); 
  st::Everything::addSensor(&sensor6);
  st::Everything::addSensor(&sensor7);
  st::Everything::addSensor(&sensor8);
  st::Everything::addSensor(&sensor9); 
  st::Everything::addSensor(&sensor10); 
  st::Everything::addSensor(&sensor11);
  st::Everything::addSensor(&sensor12);
  st::Everything::addSensor(&sensor13);
  st::Everything::addSensor(&sensor14); 
  st::Everything::addSensor(&sensor15); 
  st::Everything::addSensor(&sensor16); 
    
  //*****************************************************************************
  //Add each executor to the "Everything" Class
  //*****************************************************************************
  st::Everything::addExecutor(&executor1);
  
  //*****************************************************************************
  //Initialize each of the devices which were added to the Everything Class
  //*****************************************************************************
  st::Everything::initDevices();
}

//******************************************************************************************
//Arduino Loop() routine
//    Do not add an delay(), or other blocking statements in this function.
//******************************************************************************************
void loop()
{
  //*****************************************************************************
  //Execute the Everything run method which takes care of "Everything"
  //*****************************************************************************
  st::Everything::run();
}
2 Likes

How am I going to learn anything if you do all the work? :wink:

Thanks for this. I'm going to start parsing through it and learn something,

EDIT: I read through all of your README, and a few dozen Arduino example sketches. Seems pretty straight forward. Looking forward to giving it a go, because if I get this working I still have an ultrasonic level indicator I want to stick on my pool bleach tank.... :slight_smile:

1 Like

OK, might need a pointer. The sample Mega sketch you gave compiles fine - no issues there.

However, I thought I would play with the ESP8266 I have on-hand while I'm waiting for the Mega to arrive.

I can't get any of those sketches to even compile. Clearly something I'm doing wrong, but not sure what.

I tried loading "ST_Anything_Multiples_ESP8266WiFi", changing board in the IDE to "Generic ESP8266 Module" and verify, and right off the bat I get:

exit status 1
'D7' was not declared in this scope

I assume either the pin definitions were supposed to be loaded and weren't, or I was supposed to manually add them in the sketch but didn't.

If I remember correctly, you should be using NodeMCU 1.0 (12E) or something similar to that.

1 Like

I got it to load with Generic ESP8266 after uncommenting the pin assignment constants in the code. Now to make it actually do something useful. :slight_smile: