[DEPRECATED] ST_Anything - Arduino/ESP8266/ESP32

Dan,
I’ll give it a try once I receive my Sonoff switch. I like your approach because you make use of the GPIOs. I believe the other Sonoff thread treats the Sonoff as a basic smart switch, but I want to use it for much more.

1 Like

Hi, can someone point me in the direction of a really simple, idiots guide to installing and using this please? I’ve been using SmartThings for over a year, I’m using the IDE, added device handlers for Sonoff devices, flashed them etc and got them working. But this project has me beat, utterly lost.

I live in the UK so I can’t add the GitHub repository, I have added all the device handlers manually. I have an Arduino Mega 2560 + ESP board. Uploaded the ST_Anythings_Multiples_MEGAWiFIESP edited to join my wireless, and it works/joins my wireless network.

When I go to add a thing on my phone app nothing is found. If I add a device manually through the IDE and choose Parent_ST_Anything_Thingshield, it appears in SmartThings on my mobile app (Apple IOS 11.2.1). If I then go to add a thing, it finds the Arduino board. When I click on the device in the app and select configure, nothing happens, configure doesn’t open? If I click on the cog, it only gives me the option to add the number of buttons - I don’t know what this means? I’ve logged out/in the app, re-booted my SmartThings hub, checked and rebooted the Arduino, re-uploaded the Arduino. Am I missing something? I can see from the console log that the Arduino is trying to send logging to the Smart hub. And, it tells me what settings to add into the app.

eg
Enter the following three lines of data into ST App on your phone!
localIP = 10.0.1.33
serverPort = 8090
MAC Address = XX:20:A6:05:EC:XX

SSID = MyWifiSSID
PASSWORD = MyPassword
hubIP = 10.0.1.3
hubPort = 39500

SmartThingsWiFiEsp: Intialized

Everything: init ended
Everything: Free RAM = 6420
Everything: adding sensor named contact1
Everything: Free RAM = 6406
Everything: adding sensor named contact2
Everything: Free RAM = 6406
Everything: initDevices started
Everything: Free RAM = 6420
Everything: initDevices ended

Help? Sorry if this is kindergarten stuff…

Gary

Looks like you may have used the ThingShield version of the Parent Device Handler. Try using the Ethernet Parent Device handler, as that device will allow you to enter the device specific settings (Arduino IP, MAC, Port).

“Configure” just updates some settings. That tile could probably be removed as I’ve added that functionality into the Gear Icon Settings page.

Make sure you enter the MAC address in all UPPERCASE without any delimiters.

The ReadMe in my Github is pretty thorough, but does assume some familiarity with Arduino programming as well as SmartThings IDE usage. If you have any feedback, I am always looking for help on documentation. Feel free to submit a Pull Request if you have any improvements to help other users.

Issue with polling times on my Feather MO board (wifi101), Seems that some of my polling sensor are firing off twice several seconds apart at the 5min polling interval. See the IDE logger below.

CODE:
static st::PS_DS18B20_Temperature sensor1(F(“temperature1”), 480, 0, DS18B20, false, 10, 1);
static st::PS_Voltage sensor2(F(“voltage1”), 300, 10, VBATPIN, 0, 1023, 0, 6435, 3, 50);
static st::PS_Voltage sensor4(F(“voltage2”), 300, 20, SolarVolt, 0, 1023, 0, 7900, 3, 50);

LOGGER example: Voltage1
‎2‎:‎39‎:‎38‎ ‎PM: debug Parsing: voltage1 3881.72
‎2‎:‎39‎:‎30‎ ‎PM: debug Parsing: voltage1 3880.22
‎2‎:‎34‎:‎38‎ ‎PM: debug Parsing: voltage1 3873.02
‎2‎:‎34‎:‎30‎ ‎PM: debug Parsing: voltage1 3869.11
‎2‎:‎29‎:‎37‎ ‎PM: debug Parsing: voltage1 3863.37
‎2‎:‎29‎:‎30‎ ‎PM: debug Parsing: voltage1 3860.29

This happen with both voltage1 and 2 sensors. The temperature interval is supposed to be 8min but it all over the place between 2min to 5min but it doesn’t double send like the voltage. And I have another voltage3 sensor(for a sketch born variable) which I don’t use the polling but do manually at a set interval of 5min and that one sends at correct interval using:

if (millis() - (st_pollTimerPIRcountTotal) > st_pollInterval) {
String strTemp("voltage3 " + strResult);
st::Everything::sendSmartString(strTemp);

For now board is close to the router for testing so there’s no connection hang ups. Timing issue? Do I need a short delay somewhere? Any suggestions to test I can try it.

PS… Unrelated but I change the wifi library to send RSSI every 5+min

Thanks

@kampto

I am not sure what is causing your timing issues. Can you post your entire sketch (use the Preformatted Text formatting option (< / >) when pasting code into the forums.) All of my polling sensor fire on time and only once per interval. Sometimes the offset value gets a little messed up, causing mutiple sensors to fire in quick succession, but that’s never caused the double firing you’re seeing, or the irregular timing.

To change the RSSI reports from once a minute to once every 5 minutes, simply modify the following section of code in your SmartThingsWiFi101.cpp library file.

from

			if (RSSIsendInterval < 60000)
			{
				RSSIsendInterval = RSSIsendInterval + 1000;
			}

to

			if (RSSIsendInterval < 300000)
			{
				RSSIsendInterval = 300000;
			}

Here’s the code. Sensors are 1 temp, 1 motion, 2 voltage, and 1 motion counter(voltage3).

    /////////////////////////// Define Board Pins  ///////////////// pins 8,7,4,2 internally used for SPI WiFI ///
    // GND - this is the common ground for all power and logic
    // BAT - this is the positive voltage to/from the JST jack for the optional Lipoly battery
    // USB - this is the positive voltage to/from the micro USB jack if connected
    // EN - this is the 3.3V regulator's enable pin. It's pulled up, so connect to ground to disable the 3.3V regulator
    // 3V - this is the output from the 3.3V regulator, it can supply 600mA peak
    // RST - this is the Reset pin, tie to ground to manually reset the AVR, as well as launch the bootloader manually
    // #0 / RX - GPIO #0, also receive (input) pin for Serial1 (hardware UART), also can be analog input
    // #1 / TX - GPIO #1, also transmit (output) pin for Serial1, also can be analog input 
    // #2 - Reserved for the ENable pin for the WiFi module, by default pulled down low, set HIGH to enable WiFi
    // #4 - Reserved for the Reset pin for the WiFi module, controlled by the library
    const byte DS18B20 = 5; // Pin-5, GPIO 
    const byte PIR = 6; // Pin-6, GPIO, Output of PIR module
    // #7 - Reserved for the IRQ interrupt request pin for the WiFi module, controlled by the library
    // #8 - Reserved for the Chip Select pin for the WiFi module, used to select it for SPI data transfer
    // #9 - Reserved for A7 with internal V divider, LiPo Bat
    // #10 // Pin-10, GPIO
    // #11 // Pin-11, GPIO
    // #12 // Pin-12, GPIO
    // #13 // Pin-13, GPIO,  GPIO 13 and hooked to red led
    // #20 / SDA - GPIO #20, also the I2C (Wire) data pin. There's no pull up on this pin by default so when using with I2C, you may need a 2.2K-10K pullup.
    // #21 / SCL - GPIO #21, also the I2C (Wire) clock pin. There's no pull up on this pin by default so when using with I2C, you may need a 2.2K-10K pullup.
    // A0 - This pin is analog input A0 but is also an analog output due to having a DAC 
    const byte SolarVolt = A1; 
    // ADC 2 or GPIO 
    // ADC 3 or GPIO
    // ADC 4 or GPIO
    // ADC 5 or GPIO 
    const byte VBATPIN = A7; // ADC In, labeled as D9, internal V divider to battery, 

    ///////////////////////////////// SET VARIABLE STARTING VALUES ///////////////////////////
    float bat_volt = 0; // LiPo bat
    unsigned int PIRcount = 0; // Counter
    byte PIRstate = 0;  // use 1 and 0 to trigger counter 

    /////////////////////////////////////// SET TIMERS ////////////////////////////////////////////
    unsigned long ResetTime = 864000000; // Reset board after 10 days
    unsigned long st_pollInterval = 300000; // Wait time before puplishing internal sketch variable to ST
    unsigned long st_pollTimerPIRcountTotal = 0; 

    // **************************************************  ST ANYTHING LIBRARYS ***********************************************************
    #include <SmartThingsWiFi101.h>    //Library to provide API to the SmartThings WiFi 101 Shield

    #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_Generic.h>      // Use Library dated 12/9/17 minumum
    #include <PS_DS18B20_Temperature.h>  //Implements a Polling Sesnor (PS) to measure Temperature via DS18B20 libraries 
    #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_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
    #include <EX_Switch_Dim.h>   //Implements an Executor (EX) for a switch (on/off) and pwm output (level) uses 2 digital output pins

    ///////////////////////////////// Other Librarys /////////////////////////////////// 
    #include <Adafruit_SleepyDog.h>  // Use this to add a watchdog incase of SW hang ups, will reset board
    #include <Adafruit_ASFcore.h>  // Required for sleepy dog on SAMD21 boards only
    #include <avr/dtostrf.h> // required to use dtostrf feature.  Puts floats into strings, Only needed for SAM21 boards?


    //********************************** WiFi101 Information  ****************************************** 
    String str_ssid     = "...............";                            //  <---You must edit this line!
    String str_password = ".................";  //Network password (use for WPA, or use as key for WEP)  //  <---You must edit this line!
    IPAddress ip(192, 168, .............);       //Device IP Address       //  <---You must edit this line!
    IPAddress gateway(192, 168, 0, 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, 0, 1);  //DNS server               //  <---You must edit this line!
    const unsigned int serverPort = 8090; // port to run the http server on

    // Smartthings hub information
    IPAddress hubIp(192,168,.........);       // smartthings hub ip      //  <---You must edit this line!
    const unsigned int hubPort = 39500;   // smartthings hub port

    //************************************************ SET-UP ************************************************//
    void setup()
    {
    //POLLING SENSORS
      static st::PS_DS18B20_Temperature sensor1(F("temperature1"), 480, 0, DS18B20, false, 10, 1); // 1=One sensor
      //static st::PS_Water               sensor2(F("water1"), 300, 0, PIN_WATER_1, 200);
      //static st::PS_TemperatureHumidity sensor3(F("temphumid1"), 300, 0, PIN_TEMPERATUREHUMIDITY_1, st::PS_TemperatureHumidity::DHT22,"temperature4","humidity4"); // use # that wont confict with DS18B20's
      static st::PS_Voltage             sensor2(F("voltage1"), 300, 10, VBATPIN, 0, 1023, 0, 6435, 3, 50); // LipO battery, internal Vdivier is divided by 2*3.3V
      static st::PS_Voltage             sensor4(F("voltage2"), 300, 20, SolarVolt, 0, 1023, 0, 7900, 3, 50);  //Solar/USB in MVolts, V Dvider; R1 1Mohm, R2 680Kohm
       
    //INTERUPT SENSORS
      static st::IS_Motion              sensor3(F("motion1"), PIR, HIGH, false, 500);  // DI LOW mean inactive, false=no pullup
      //static st::IS_Contact             sensor3(F("contact1"), PIR, HIGH, false, 100); // Low = Closed, true = internal pull-up, Trigger delay time=500
      //static st::IS_Contact             sensor4(F("contact2"), PUMP, HIGH, false, 500); // 
      //static st::IS_DoorControl         sensor15(F("doorControl1"), PIN_DOORCONTROL_CONTACT_1, LOW, true, PIN_DOORCONTROL_RELAY_1, LOW, true, 1000);
      //static st::IS_Button              sensor12(F("button1"), PIN_BUTTON1, 1000, LOW, true, 500);
        
    //SPECIAL sensors/executors (uses portions of both polling and executor classes)
      //static st::S_TimedRelay           sensor6(F("relaySwitch1"), ST_PURGEBUTTON, LOW, false, 3000, 0, 1); // Low = init stae, false = no inverted logic, 30000, on time
      
    //EXECUTORS
      //static st::EX_Switch              executor1(F("switch1"), PURGEBUTTON, LOW, false);  // LOW = "initial state off", false = no inverted logic
         
    //******************************** 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 *********************************************
     WiFi.setPins(8,7,4,2);  //  WiFi.setPins(chipSelect, irq, reset, enable)  Configure pins for Adafruit ATWINC1500 Feather MO
      
       st::Everything::callOnMsgSend = callback;  //Initialize the optional local callback routine (safe to comment out if not desired)
       
       //Create the SmartThings WiFi101 Communications Object //STATIC IP Assignment, Set router to assign static - Recommended
       st::Everything::SmartThing = new st::SmartThingsWiFi101(str_ssid, str_password, ip, gateway, subnet, dnsserver, serverPort, hubIp, hubPort, st::receiveSmartString);
       
       st::Everything::init(); //Run the Everything class' init() routine which establishes Ethernet communications with the SmartThings Hub
         
    //*********************************** Add each sensor to the "Everything" Class ******************************************
      
      st::Everything::addSensor(&sensor1);
      st::Everything::addSensor(&sensor2);
      st::Everything::addSensor(&sensor3);
      st::Everything::addSensor(&sensor4); 
       /*****  Rest Not used in this project ********* 
      st::Everything::addSensor(&sensor5); 
      st::Everything::addSensor(&sensor6);
      st::Everything::addSensor(&sensor7);
      st::Everything::addSensor(&sensor8);
       */

    //************************************ Add each executor to the "Everything" Class ***************************************
      //st::Everything::addExecutor(&executor1);
      //st::Everything::addExecutor(&executor2);
      //st::Everything::addExecutor(&executor3);
        
     st::Everything::initDevices();  //Initialize each of the devices which were added to the Everything Class

  int countdownMS = Watchdog.enable(16000); //(Max is 16sec) Sleepy_Dog,  Make sure to reset the watchdog in sketch before countdown expires or the board will reset
      
    } // ***** End SetUp

    //**************************************** BEGIN LOOP FUNCTIONS ********************************************
    void loop()
    {
      Watchdog.reset();  // Continously zero the watchdog timer so the board doesnt reset. If skecth hangs then board will reset.
      st::Everything::run();  //Execute the Everything run method which takes care of "Everything"
      st_PIRmotion(); // Send PIR sensor data skecth variables to ST
      SerialDiag();  // Run Serial data for IDE display
      if (millis() > ResetTime) {NVIC_SystemReset();} // processor software reset after timer expires
    } // ***** End Loop

    //********************************** ST PIR Motion Polling in Sketch ************************************
    void st_PIRmotion()  
    {
     if (millis() - st_pollTimerPIRcountTotal > st_pollInterval) {
       String strResult(PIRcount); // Add variable into string.
       String strTemp("voltage3 " + strResult);
       st::Everything::sendSmartString(strTemp); 
       delay(5); // Give it time to send
       st_pollTimerPIRcountTotal = millis() ; // reset poll counter so it wait for next trigger or timed interval
        }
     if (digitalRead(PIR) == LOW) { PIRstate = 0; } // If low prevent counter from Incrimenting, PIRstate = 0
     else if (digitalRead(PIR) == HIGH && PIRstate == 0) {PIRcount++; PIRstate = 1; st_pollTimerPIRcountTotal = 0; }  // Increment and force count publish 
     
    }  
    //**************************************  Serial Diagnostics for USB IDE ******************************************
    void SerialDiag(void)
    {
     //map function cant do floats so use this math if decimals needed:  Y= (((X) - (in_min)) * ((out_max) - (out_min)) / ((in_max) - (in_min)) + (out_min))
     bat_volt = (((analogRead(VBATPIN)) - (0)) * ((6435) - (0.0)) / ((1023) - (0.0)) + (0.0));  //use internal 100K / 100K V divider and covert to V

      Serial.println(F("...........Serial Com Diagnostcs Start............."));
      // print the SSID of the network you're attached to:
      Serial.print("SSID: ");  Serial.println(WiFi.SSID());

      // print your WiFi shield's IP address:
      IPAddress ip = WiFi.localIP(); // Attached wifi IP Address
      Serial.print("IP Address: ");  Serial.println(ip);

      // print the received signal strength:
      long rssi = WiFi.RSSI(); // DBm for winc1500 wifi signal strength
      Serial.print("signal strength (RSSI):"); Serial.print(rssi); Serial.println(" dBm");
      
      Serial.println("******************************");
      Serial.println(bat_volt, 3); Serial.println(F(" V Battery "));
      Serial.print(F(" PIR DI ................")); Serial.println(digitalRead(PIR)); 
      Serial.print(PIRcount); Serial.println(F(" Motion Counts "));
      Serial.println("******************************");
      }

    //********************************************************* ST CallBack ***********************************************************
    //st::Everything::callOnMsgSend() optional callback routine.  A sniffer to monitor data being sent to ST.  Grab data for local use in sketch

    void callback(const String &msg)
    {
      String strTemp = msg;
      Serial.print(F("ST_Anything Callback: Sniffed data = "));
      Serial.println(msg);
     
      //Masquerade as the ThingShield to send data to the Arduino, as if from the ST Cloud (uncomment and edit following line)
      //st::receiveSmartString("Put your command here!");  //use same strings that the Device Handler would send
     
    /// PIRCount
      if (strTemp.startsWith("voltage3")) {
        strTemp.remove(0,10);  // 13 is the space after temperature1, remove 0 to 13th character
        Serial.print(F("ST CallBack PIRcount ............................. ")); Serial.println(strTemp);
        }
    }

First thing I noticed is the “delay(5)” in the PIR code. Do not add delays like that as they screw up ST communications.

Try that and let me know if anything changes. I can look more over the weekend if the problem persists.

Hi Dan

Thanks for your help, using the Ethernet Shield has worked, I’m confused why I’m using the ethernet shield for the ESP WiFi, but I can live with that :+1:

In the serial logging window I can see it’s connected to SmartThings because when I press refresh through the app on my phone, I can see the request and data sent - see below

Handling request from ST. tempString = refresh
Everything: Received: refresh
Everything: Sending: switch1 off
Everything: Sending: switch2 off
Everything: Sending: alarm1 off
Everything: Sending: alarm2 off
Everything: Sending: contact1 open
Everything: Sending: contact2 open

The issue I have now, is that none of the child device tiles are being created in the app under the Arduino Shield. I’ve left all names, titles, labels etc at default so as not to cause any issue. All the device handlers are in the IDE under devices and published “to me”. As before I’ve logged out/in the app etc but none of the child devices are being automatically created.

Bit more investigation, no matter how many times I enter the IP etc into the parent device, either through the phone app or IDE Device page, every time I click on Recently I get the Parent Device not configured etc error. The correct details are being displayed in the IDE and app though? I saw an error saying it couldn’t create the child devices because the Parent hadn’t been configured? It has, exactly as per the original serial debug message, with the MAC in caps etc.

Thanks again for you help.

@ogiewon, I’ve been playing more with the new ST_Anything with the RSSI reporting. In WebCore, I am trying to subscribe to the RSSI events so I can plot it over time in a fuel stream.

However, there do not seem to be any “events” associated with RSSI. I tried this:

image

but I never get any updates even though the rssi is changing. I am able to read the current value so If I set a simply time and log it every 5 min, it’s fine. Just curious if this is something on your side, ST side, or WC?

Thanks again for implementing RSSI!

EDIT - I think i found it it. On line 118 of Parent_ST_Anything_Ethernet, you have:

results = createEvent(name: name, value: value, displayed: false)

I think you are missing the square brackets to create the map in createEvent(). Should be like so:

results = createEvent([name: name, value: value, displayed: false])

correct? not sure why those words are bolded…

EDIT 2: Nope. Still doesn’t work…

Removing the 5ms delay doesnt change anything, so took it out anyway. Also I removed the poll interval for that manual send of the PIR motion count incrementer and had it just immediately update when motion is sensed. No change either. Voltage1 and 2 are still double sending several seconds apart around the specified poll interval. Will keep playing with it. Thanks…

Sounds like you’re making good progress. The reason for using the ST_Anything Parent Ethernet device handler, is that it know how to communicate with LAN connected devices. Cat5 and WiFi devices all end up communicating over Ethernet to the ST Hub. The ST_Anything Parent Thingshield device handler is only to be used with the old SmartThings Thingshield for Arduino. Since the Thingshield is no longer sold, I added the Ethernet support to my libraries.

As for your lack of child devices… a few things for you to check:

  1. in your sketch, are you sure you have the correct IP address for your ST Hub?
  2. are you sure you have the correct MAC address typed into the Parent Device settings? All UPPERCASE and no delimiters. Valid characters are A-F and 0-9.
  3. can you ping both the ST hub and the Arduino from a third computer on the same network?

Based on the data you provided, ST is able to communicate to your Arduino. The problem appears to be in the communications from the Arduino to ST. This is where the Hub IP Address and Arduino MAC address are of critical importance.

As for the annoying error message you’re seeing, it will continue to pop up until the initial message in the recently list scrolls off. Sorry for the annoyance. You can safely ignore it.

Dan,

Thank you for the great explanation and I apologize for the delayed response. I’ve been able to pursue the I2C implementation this week. A little background on my setup: I’ve a preexisting alarm panel that integrates contact and motion sensors to three separate keypads before a common return line communicates with the main control panel. I was able to utilize your ST_Anything code with W5100 to integrate the sensors that terminate direct to the main control panel, however most of the remaining sensors are utilizing a 2 wire scheme, thus my interest in I2C to communicate with the Arduino/ST Anything at the main panel. I would like to use a wired communication protocol for security, stability, and reliability vs ESP8266 and the reason I went the W5100 route.

I spent the better part of this week developing a I2C communication network with an Arduino and PDF8574 I2C bus. I’ve been able to emulate basic contact sensors and serial output to show some functionality. The problem is trying to incorporate it in your ST_Anything code. I’ve been able to alter the sketch to include the necessity I2C communication and when live logging with serial output, I see that the test contact responds accordingly. However, ST fails to see any changes with any of the contacts when performing this test (i.e all service states are unchanged). I can only see the I2C sensors change on the Arduino IDE serial output based on code inserted at the end of the sketch (see code below).

My network shows connection to Arudino/W5100 setup and returns the appropriate IP. I was hoping you could look at the ST_Anything sketch and let me know if you see anything wrong? Any feedback would be greatly appreciated.

Thanks again!

S

//******************************************************************************************
// File: ST_Anything_Multiples_EthernetW5100.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 W5100 Shield to
// implement a multi input/output custom device for integration into SmartThings.
// The ST_Anything library takes care of all of the work to schedule device updates
// as well as all communications with the Ethernet W5100 Shield.
//
// ST_Anything_Multiples implements the following ST Capabilities in multiples of 2 as a demo of what is possible with a single Arduino
// - 2 x Door Control devices (used typically for Garage Doors - input pin (contact sensor) and output pin (relay switch)
// - 2 x Contact Sensor devices (used to monitor magnetic door sensors)
// - 2 x Switch devices (used to turn on a digital output (e.g. LED, relay, etc…)
// - 2 x Water Sensor devices (using an analog input pin to measure voltage from a water detector board)
// - 2 x Illuminance Measurement devices (using a photoresitor attached to ananlog input)
// - 2 x Voltage Measurement devices (using a photoresitor attached to ananlog input)
// - 2 x Smoke Detector devices (using simple digital input)
// - 2 x Carbon Monoxide Detector devices (using simple digital input)
// - 2 x Motion devices (used to detect motion)
// - 2 x Temperature Measurement devices (Temperature from DHT22 device)
// - 2 x Humidity Measurement devices (Humidity from DHT22 device)
// - 2 x Relay Switch devices (used to turn on a digital output for a set number of cycles And On/Off times (e.g.relay, etc…))
// - 2 x Button devices (sends “pushed” if held for less than 1 second, else sends “held”
// - 2 x Alarm devices - 1 siren only, 1 siren and strobe (using simple digital outputs)
// - 2 x Dimmer Switch devices - uses 2 digital outputs, one for on/off and one for pwm level
// - 2 x MQ-2 Smoke Detector devices (using simple analog input compared to user defined limit)
//
// 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: This sketch was fully tested on an Arduino MEGA 2560 using the Ethernet W5100 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-07-04 Dan Ogorchock Added MQ-2 based Smoke Detection
// 2018-01-05 SawKyrom Added I2C utilizing PCF8574 bus
//******************************************************************************************
//******************************************************************************************
// SmartThings Library for Arduino Ethernet W5100 Shield
//******************************************************************************************
#include <SmartThingsEthernetW5100.h> //Library to provide API to the SmartThings Ethernet W5100 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 <PS_MQ2_Smoke.h> //Implements an Polling Sensor (PS) to monitor the status of an analog input pin from a MQ2 sensor
#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
#include <EX_Switch_Dim.h> //Implements an Executor (EX) for a switch (on/off) and pwm output (level) uses 2 digital output pins

//******************************************************************************************
// i2C Library with PCF8574 Bus
//******************************************************************************************
#include <Wire.h> //Required for I2C communications
#include “PCF8574.h” //Required for PCF8574

/** PCF8574 instance /
PCF8574 expander;
//
*********************************************************************************************************
//Define which Arduino Pins will be used for each device
// Notes: Arduino communicates with both the W5100 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 W5100 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 W5100 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/ArduinoEthernetShieldV1 for details on the W5100 Sield
//**********************************************************************************************************

//“RESERVED” pins for W5100 Ethernet Shield - best to avoid
#define PIN_4_RESERVED 4 //reserved by W5100 Shield on both UNO and MEGA
#define PIN_1O_RESERVED 10 //reserved by W5100 Shield on both UNO and MEGA
#define PIN_11_RESERVED 11 //reserved by W5100 Shield on UNO
#define PIN_12_RESERVED 12 //reserved by W5100 Shield on UNO
#define PIN_13_RESERVED 13 //reserved by W5100 Shield on UNO
#define PIN_50_RESERVED 50 //reserved by W5100 Shield on MEGA
#define PIN_51_RESERVED 51 //reserved by W5100 Shield on MEGA
#define PIN_52_RESERVED 52 //reserved by W5100 Shield on MEGA
#define PIN_53_RESERVED 53 //reserved by W5100 Shield on MEGA

//Analog Pins
//#define PIN_WATER_1 A0 //SmartThings Capability “Water Sensor”
//#define PIN_WATER_2 A1 //SmartThings Capability “Water Sensor”
//#define PIN_ILLUMINANCE_1 A2 //SmartThings Capability “Illuminance Measurement”
//#define PIN_ILLUMINANCE_2 A3 //SmartThings Capability “Illuminance Measurement”
#define PIN_VOLTAGE_1 A4 //SmartThings Capability “Voltage Measurement”
//#define PIN_VOLTAGE_2 A5 //SmartThings Capability “Voltage Measurement”
//#define PIN_SMOKE_3 A8 //SmartThings Capability “Smoke Detector”
//#define PIN_SMOKE_4 A9 //SmartThings Capability “Smoke Detector”

//Digital Pins
//#define PIN_TEMPERATUREHUMIDITY_1 22 //SmartThings Capabilities “Temperature Measurement” and “Relative Humidity Measurement”
#define PIN_MOTION_1 23 //SmartThings Capability “Motion Sensor”
#define PIN_MOTION_2 24 //SmartThings Capability “Motion Sensor”
#define PIN_MOTION_3 25 //SmartThings Capability “Motion Sensor”
#define PIN_CONTACT_1 26 //SmartThings Capability “Contact Sensor”
#define PIN_CONTACT_2 27 //SmartThings Capability “Contact Sensor”
#define PIN_CONTACT_3 28 //SmartThings Capability “Switch”
#define PIN_CONTACT_4 29 //SmartThings Capability “Switch”
#define PIN_CONTACT_5 30 //SmartThings Capability “Relay Switch”
#define PIN_CONTACT_6 31 //SmartThings Capability “Relay Switch”
#define PIN_CONTACT_7 32 //SmartThings Capability “Smoke Detector”

// ADDING EXPANDER PIN DEFINITION

//#define PIN_CONTACT_8 PCF8574::PCF8574(0) //SmartThings Capability “Contact Sensor”

#define PIN_SMOKE_1 33 //SmartThings Capability “Smoke Detector”
#define PIN_ALARM_1 34 //SmartThings Capability “Alarm”
//#define PIN_ALARM_2 40 //SmartThings Capability “Alarm”
//#define PIN_STROBE_2 41 //SmartThings Capability “Alarm”
//#define PIN_CO_1 42 //SmartThings Capability “Carbon Monoxide Detector”
//#define PIN_CO_2 43 //SmartThings Capability “Carbon Monoxide Detector”

//Dimmer Switch Pins
/*
#define PIN_DIMMERLEVEL_1 44 //SmartThings Capability “Switch Level” NOTE: MUST BE A PWM CAPABLE PIN!
#define PIN_DIMMERSWITCH_1 45 //SmartThings Capability “Switch”
#define PIN_DIMMERLEVEL_2 46 //SmartThings Capability “Switch Level” NOTE: MUST BE A PWM CAPABLE PIN!
#define PIN_DIMMERSWITCH_2 47 //SmartThings Capability “Switch”
*/

//Garage Door Pins
/*#define PIN_DOORCONTROL_CONTACT_1 35 //SmartThings Capabilty “Door Control”
#define PIN_DOORCONTROL_RELAY_1 36 //SmartThings Capabilty “Door Control”
#define PIN_DOORCONTROL_CONTACT_2 37 //SmartThings Capabilty “Door Control”
#define PIN_DOORCONTROL_RELAY_2 38 //SmartThings Capabilty “Door Control”
*/

//Pushbutton Pins
//#define PIN_BUTTON1 48 //SmartThings Capabilty Button / Holdable Button
//#define PIN_BUTTON2 49 //SmartThings Capabilty Button / Holdable Button

//I2C Expander Pins

//******************************************************************************************
//W5100 Ethernet Shield Information
//******************************************************************************************
//Notes: Byte 8 bit value (-128 to 127) vs Int 32 bit value
//Notes: mac[] array which contains hexidecimal values in this case
byte mac[] = {0x06,0x12,0x24,0x36,0x48,0x06}; //MAC address, leave first octet 0x06, change others to be unique // <—You must edit this line!
IPAddress ip(192, 168, 1, 1); //Arduino device IP Address // <—You must edit this line! DONE
IPAddress gateway(192, 168, 1, 1); //router gateway // <—You must edit this line! DONE
IPAddress subnet(255, 255, 255, 0); //LAN subnet mask // <—You must edit this line! DONE
IPAddress dnsserver(192, 168, 1, 1); //DNS server // <—You must edit this line! DONE
const unsigned int serverPort = 8090; // port to run the http server on “unsigned” function limits numbers to positive values

// Smartthings hub information
IPAddress hubIp(192,168,1,1); // smartthings hub ip // <—You must edit this line! DONE
const unsigned int hubPort = 39500; // smartthings 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.
//******************************************************************************************
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 ThingShield to send data to the Arduino, as if from the ST Cloud (uncomment and edit following line(s) as you see fit)
//st::receiveSmartString(“Put your command here!”); //use same strings that the Device Handler would send
}

//******************************************************************************************
//Arduino Setup() routine
//******************************************************************************************
void setup()
{

/* Start I2C bus and PCF8574 instance */
expander.begin(0x20);
//expander.begin(0x21);

/* Setup some PCF8574 pins for demo */

expander.pinMode(0, INPUT);
expander.pinMode(1, INPUT);
expander.digitalWrite(0, LOW);
expander.digitalWrite(1, LOW);

//******************************************************************************************
//Declare each Device that is attached to the Arduino
// Notes: - For each device, there is typically a corresponding “tile” defined in your
// SmartThings Device Hanlder Groovy code, except when using new COMPOSITE Device Handler
// - For details on each device’s constructor arguments below, please refer to the
// corresponding header (.h) and program (.cpp) files.
// - The name assigned to each device (1st argument below) must match the Groovy
// Device Handler 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 rename the Child Devices
// to match your specific use case in the ST Phone Application.
//******************************************************************************************

//FORMAT Notes:
// static means member in the class is statis and only one cope of the member exist no matter how many objects are created
// :: scope resolution operator with st being the class(namespace)
//Polling Sensors
//static st::PS_Water sensor1(F(“water1”), 60, 0, PIN_WATER_1, 200);
//static st::PS_Water sensor2(F(“water2”), 60, 10, PIN_WATER_2, 200);
//static st::PS_Illuminance sensor3(F(“illuminance1”), 60, 20, PIN_ILLUMINANCE_1, 0, 1023, 0, 1000);
//static st::PS_Illuminance sensor4(F(“illuminance2”), 60, 30, PIN_ILLUMINANCE_2, 0, 1023, 0, 1000);
//static st::PS_TemperatureHumidity sensor5(F(“temphumid1”), 60, 40, PIN_TEMPERATUREHUMIDITY_1, st::PS_TemperatureHumidity::DHT22,“temperature1”,“humidity1”);
//static st::PS_TemperatureHumidity sensor6(F(“temphumid2”), 60, 50, PIN_TEMPERATUREHUMIDITY_2, st::PS_TemperatureHumidity::DHT22,“temperature2”,“humidity2”);
static st::PS_Voltage sensor7(F(“voltage1”), 60, 55, PIN_VOLTAGE_1, 0, 1023, 0, 5000);
//static st::PS_Voltage sensor8(F(“voltage2”), 60, 57, PIN_VOLTAGE_2, 0, 1023, 0, 5000);
//static st::PS_MQ2_Smoke sensor23(F(“smoke3”), 10, 3, PIN_SMOKE_3, 300);
//static st::PS_MQ2_Smoke sensor24(F(“smoke4”), 10, 5, PIN_SMOKE_4, 300);

//Interrupt Sensors
static st::IS_Motion sensor9(F(“motion1”), PIN_MOTION_1, HIGH, true, 500); // changed from HIGH, false to LOW, true
static st::IS_Motion sensor10(F(“motion2”), PIN_MOTION_2, HIGH, false, 500);
// FORMAT st::IS_Contact (const __FlashStringHelper *name, byte pin, bool iState, bool internalPullup, long numReqCounts) :
// InterruptSensor(name, pin, iState, internalPullup, numReqCounts) //use parent class’ constructor
static st::IS_Contact sensor11(F(“contact1”), PIN_CONTACT_1, LOW, true, 500);
static st::IS_Contact sensor12(F(“contact2”), PIN_CONTACT_2, LOW, true, 500);
static st::IS_Contact sensor13(F(“contact3”), PIN_CONTACT_3, LOW, true, 500);
static st::IS_Contact sensor14(F(“contact4”), PIN_CONTACT_4, LOW, true, 500);
static st::IS_Contact sensor15(F(“contact5”), PIN_CONTACT_5, LOW, true, 500);
static st::IS_Contact sensor16(F(“contact6”), PIN_CONTACT_6, LOW, true, 500);
static st::IS_Contact sensor17(F(“contact7”), PIN_CONTACT_7, LOW, true, 500);

// Expander Pin Test!!!
// ATTEMPTING TO ADD I2C CONTACT PINS

static st::IS_Contact sensor18(F(“contact8”), expander.digitalRead(0), LOW, true, 500);
static st::IS_Contact sensor19(F(“contact9”), expander.digitalRead(1), LOW, true, 500);

//static st::IS_Smoke sensor13(F(“smoke1”), PIN_SMOKE_1, HIGH, true, 500);
//static st::IS_Smoke sensor14(F(“smoke2”), PIN_SMOKE_2, HIGH, true, 500);
//static st::IS_DoorControl sensor15(F(“doorControl1”), PIN_DOORCONTROL_CONTACT_1, LOW, true, PIN_DOORCONTROL_RELAY_1, LOW, true, 1000);
//static st::IS_DoorControl sensor16(F(“doorControl2”), PIN_DOORCONTROL_CONTACT_2, LOW, true, PIN_DOORCONTROL_RELAY_2, LOW, true, 1000);
//static st::IS_Button sensor17(F(“button1”), PIN_BUTTON1, 1000, LOW, true, 500);
//static st::IS_Button sensor18(F(“button2”), PIN_BUTTON2, 1000, LOW, true, 500);
//static st::IS_CarbonMonoxide sensor19(F(“carbonMonoxide1”), PIN_CO_1, HIGH, true, 500);
//static st::IS_CarbonMonoxide sensor20(F(“carbonMonoxide2”), PIN_CO_2, HIGH, true, 500);

//Special sensors/executors (uses portions of both polling and executor classes)
//static st::S_TimedRelay sensor21(F(“relaySwitch1”), PIN_TIMEDRELAY_1, LOW, true, 3000, 0, 1);
//static st::S_TimedRelay sensor22(F(“relaySwitch2”), PIN_TIMEDRELAY_2, LOW, true, 3000, 0, 1);

//Executors
//static st::EX_Switch executor1(F(“switch1”), PIN_SWITCH_1, LOW, true);
//static st::EX_Switch executor2(F(“switch2”), PIN_SWITCH_2, LOW, true);
static st::EX_Alarm executor3(F(“alarm1”), PIN_ALARM_1, LOW, true);
//static st::EX_Alarm executor4(F(“alarm2”), PIN_ALARM_2, LOW, true, PIN_STROBE_2);
//static st::EX_Switch_Dim executor5(F(“dimmerSwitch1”), PIN_DIMMERSWITCH_1, PIN_DIMMERLEVEL_1, LOW, false);
//static st::EX_Switch_Dim executor6(F(“dimmerSwitch2”), PIN_DIMMERSWITCH_2, PIN_DIMMERLEVEL_2, LOW, false);

//*****************************************************************************
// 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 EthernetW5100 Communications Object
//STATIC IP Assignment - Recommended
st::Everything::SmartThing = new st::SmartThingsEthernetW5100(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::SmartThingsEthernetW5100(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); //voltage1
//st::Everything::addSensor(&sensor8);
st::Everything::addSensor(&sensor9); //motion1
st::Everything::addSensor(&sensor10); //motion2
st::Everything::addSensor(&sensor11); //contact1
st::Everything::addSensor(&sensor12); //contact2
st::Everything::addSensor(&sensor13); //contact3
st::Everything::addSensor(&sensor14); //contact4
st::Everything::addSensor(&sensor15); //contact5
st::Everything::addSensor(&sensor16); //contact6
st::Everything::addSensor(&sensor17); //contact7
st::Everything::addSensor(&sensor18); //contact8 EXPANDER PIN FRONT DOOR
st::Everything::addSensor(&sensor19); //contact9 EXPANDER PIN Study Window
//st::Everything::addSensor(&sensor20);
//st::Everything::addSensor(&sensor21);
//st::Everything::addSensor(&sensor22);
//st::Everything::addSensor(&sensor23);
//st::Everything::addSensor(&sensor24);

//*****************************************************************************
//Add each executor to the “Everything” Class
//*****************************************************************************
//st::Everything::addExecutor(&executor1);
//st::Everything::addExecutor(&executor2);
st::Everything::addExecutor(&executor3);
//st::Everything::addExecutor(&executor4);
//st::Everything::addExecutor(&executor5);
//st::Everything::addExecutor(&executor6);

//*****************************************************************************
//Initialize each of the devices which were added to the Everything Class
//*****************************************************************************
st::Everything::initDevices();
}

//******************************************************************************************
//Arduino Loop() routine
//******************************************************************************************
void loop()
{

//*****************************************************************************
//Execute the Everything run method which takes care of “Everything”
//*****************************************************************************
st::Everything::run();

//if (expander.digitalRead(0)==LOW) {
//Serial.println(“Contact P0 is closed”);
//}
//else {
//Serial.println(“Contact P0 is open”);
//}
//delay(250);
//if (expander.digitalRead(0)==LOW) {
//Serial.println(“Contact P0 is closed”);
//}
//else {
//Serial.println(“Contact P0 is open”);
//}
//delay(250)
}

Steve,

Good question! I just tried using webCore to send me a push notification each time the RSSI value changes, and I am getting nothing as well. Remember when I said that I found it odd that the value tile in the SmartThings phone app didn’t seem to update on its own? I wonder of the two issues are related? Seems like the RSSI value changing is not raising events for some reason…???

Do you know of any other example device handlers that have RSSI and work as you’d expect? Might be good to compare against to see what is different.

Dan

@SawKyrom

I took a very quick look at your sketch. It appears you’re attempting to pass in a value, not a pin, to the IS_Contact sensors in your setup() routine. This is not going to work as it is simply configuring the IS_Contact to read either pin 0 or pin 1. Not exactly the behavior you’re looking for.

In order to incorporate your I2C devices, I believe you may need to add new C++ class modeled after the existing IS_Contact class. The current IS_Contact class inherits from the InterruptSensor class which actually handles much of the work regarding reading I/O pins. So, you may need to create your own “InterruptSensor_I2C” class and a “IS_Contact_I2C” class which inherits from your “InterruptSensor_I2C” class.

Hopefully this makes sense? I haven’t thought this 100% through, but it should give you some things to think about.

Dan

I’ll try loading your sketch on my MKR1000 to see how it behaves this weekend.

On one of my devices I have i2c current sensor and use this to send the data from inside the sketch.

if (millis() - st_pollTimerTotal > st_Interval) // poll interval
{
String strResult(current); // Add variable into string.
String strTemp("voltage3 " + strResult);
st::Everything::sendSmartString(strTemp);
st_pollTimerTotal = millis() ;
}

I suppose you could use a “contact” or other instead of the “voltage” class

Thanks again Dan… I really appreciate your feedback. You are correct that I was trying to point the contact sensor input to the pin corresponding on the PCF8574. I assumed that was the function in your

static st::IS_Contact sensor12(F(“contact2”), PIN_CONTACT_2, LOW, true, 500);

code line when defined the PIN_CONTACT to a particular pin on the Arduino board. Thus I was trying to point the new sensor to the corresponding pin of the PCF8574 (i.e. sensorx = expander.pin(x)) via the I2C protocol reads with SDA/SCL inputs. I initially had trouble locating the specific pin. However, the bench test was working appropriate with expander.digitalRead(x) nomenclature and was clearly output real time results (open/close). I will take a look at your IS_Contact class and see if I can reverse engineer a new class specifically for those contact sensors. I would of thought that these sensors would work and behave exactly like the original.

Also, I reconnected everything with IC2 attached and all the direct connect sensors are working again.

Once more, thank you for all the advice and the prompt reply. I hope I can get this to work.

Saw

Thanks Kampto… I’ll play with the code as well to see if I get any output to ST environment. It may be a polling issue.

S

Here was the Arduino IDE showing all the contacts registering. Contact 8, 9 are the I2C contacts added with PCF8574. So maybe the problem is not the data being parsed, but the status not being read properly???

Everything: Sending: motion1 active
Everything: Sending: motion2 active
Everything: Sending: contact1 open
Everything: Sending: contact2 closed
Everything: Sending: contact3 open
Everything: Sending: contact4 open
Everything: Sending: contact5 open
Everything: Sending: contact6 open
Everything: Sending: contact7 open
Everything: Sending: contact8 open
Everything: Sending: contact9 open
Everything: Sending: voltage1 1730.21
Everything: Free Ram = 6046

in the normal IS_Contact device, a pin # is passed in when the device is created. That pin # is used internally by a digitalRead() Arduino standard call to retrieve a value.

When you pass in “expander.digitalRead(0)”, I believe you are passing into the IS_Contact constructor a “value” of your I2C contact. The value will be either HIGH or LOW (I.e. 1 or 0).

So, the normal IS_Contact sensor code is now executing standard Arduino digitalRead() calls against what you passed in to it, which it thinks is pin 0 or 1.

Make sense?

You could perform all of the work for your I2C sensors inside the Arduino sketch, however the same logic you need to add to the sketch could simply be incorporated into a new C++ class. Adding new classes is how ST-Anything was designed to be expanded. It is your decision on how you’d like to proceed.