//****************************************************************************************** // File: ST_Anything_Doors_ThingShield.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 + SmartThings 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 SmartThings Shield. // // ST_Anything_Doors implements the following: // - 2 x Door Control devices (used as Garage Doors) // - 4 x Contact Sensor devices (used to monitor magnetic door sensors) // - 1 x Motion device (used to detect motion in the garage) // - 1 x Temperature/Humidity device (unsed to monitor temp & humidity in the garage) // // 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. The SmartThings library was also modified to // include support for using Hardware Serial port(s) on the UNO, MEGA, and Leonardo. // During testing, it was determined that the Hardware Serial ports provide much // better performance and reliability versus the SoftwareSerial library. Also, the // MEGA 2560's 8K of SRAM is well worth the few extra dollars to save your sanity // versus always running out of SRAM on the UNO R3. The MEGA 2560 also has 4 Hardware // serial ports (i.e. UARTS) which makes it very easy to use Hardware Serial instead // of SoftwareSerial, while still being able to see debug data on the USB serial // console port (pins 0 & 1). // // Note: We did not have a Leonardo for testing, but did fully test on UNO R3 and // MEGA 2560 using both SoftwareSerial and Hardware Serial communications to the // Thing Shield. // // Change History: // // Date Who What // ---- --- ---- // 2015-01-03 Dan & Daniel Original Creation // 2015-01-07 Dan Ogorchock Modified for Door Monitoring and Garage Door Control // 2015-03-28 Dan Ogorchock Removed RCSwitch #include now that the libraries are split up // 2015-03-31 Daniel O. Memory optimizations utilizing progmem // 2017-02-12 Dan Ogorchock Revised to use the new SMartThings v2.0 library // //****************************************************************************************** //****************************************************************************************** // SmartThings Library for Arduino Shield //****************************************************************************************** #include //Library to provide API to the SmartThings Shield //****************************************************************************************** // ST_Anything Library //****************************************************************************************** #include //Constants.h is designed to be modified by the end user to adjust behavior of the ST_Anything library #include //Generic Device Class, inherited by Sensor and Executor classes #include //Generic Sensor Class, typically provides data to ST Cloud (e.g. Temperature, Motion, etc...) #include //Generic Interrupt "Sensor" Class, waits for change of state on digital input #include //Generic Polling "Sensor" Class, polls Arduino pins periodically #include //Master Brain of ST_Anything library that ties everything together and performs ST Shield communications #include //Implements a Polling Sensor (PS) to measure Temperature and Humidity via DHT library #include //Implements an Interrupt Sensor (IS) to detect motion via a PIR sensor #include //Implements an Interrupt Sensor (IS) to monitor the status of a digital input pin #include //Implements an Interrupt Sensor (IS) and Executor to monitor the status of a digital input pin and control a digital output pin //****************************************************************************************** //Define which Arduino Pins will be used for each device // Notes: -Serial Communications Pins are defined in Constants.h (avoid pins 0,1,2,3 // for inputs and output devices below as they may be used for communications) // -Always avoid Pin 6 as it is reserved by the SmartThings Shield // //****************************************************************************************** //"RESERVED" pins for SmartThings ThingShield - best to avoid #define PIN_O_RESERVED 0 //reserved by ThingShield for Serial communications OR USB Serial Monitor #define PIN_1_RESERVED 1 //reserved by ThingShield for Serial communications OR USB Serial Monitor #define PIN_2_RESERVED 2 //reserved by ThingShield for Serial communications #define PIN_3_RESERVED 3 //reserved by ThingShield for Serial communications #define PIN_6_RESERVED 6 //reserved by ThingShield (possible future use?) //Motion and Temperature/Humidity Pins (Note: using Analog pins as Digital inputs) #define PIN_MOTION A0 #define PIN_TEMPERATUREHUMIDITY A1 #define PIN_CONTACT_FRONT_DBL_DOOR 5 #define PIN_CONTACT_DINING_RM_WNDW 7 #define PIN_CONTACT_LVNG_PATIO_DOOR 8 #define PIN_CONTACT_KTCH_NOOK_WNDW 9 #define PIN_CONTACT_SUN_ROOM_DOOR 10 #define PIN_CONTACT_SUN_ROOM_WNDW 11 #define PIN_CONTACT_BEDROOM1_WNDW 12 #define PIN_CONTACT_BEDROOM2_WNDW 13 #define PIN_CONTACT_GARAGE_DOOR 14 //If using SoftwareSerial (e.g. Arduino UNO), must define pins for transmit and receive #define pinRX 3 #define pinTX 2 //****************************************************************************************** //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. //****************************************************************************************** void callback(const String &msg) { Serial.print(F("ST_Anything 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) //st::receiveSmartString("Put your command here!"); //use same strings that the Device Handler would send } //****************************************************************************************** //Arduino Setup() routine //****************************************************************************************** void setup() { //****************************************************************************************** //Declare each Device that is attached to the Arduino // Notes: - For each device, there is typically a corresponding "tile" defined in your // SmartThings DeviceType Groovy code // - 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 // DeviceType Tile name. (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 Shield in two separate updates, one for // "temperature" and one for "humidity") //****************************************************************************************** //Polling Sensors //static st::PS_TemperatureHumidity sensor1(F("temphumid"), 120, 10, PIN_TEMPERATUREHUMIDITY, st::PS_TemperatureHumidity::DHT22); //Interrupt Sensors //static st::IS_Motion sensor2(F("motion"), PIN_MOTION, HIGH, false); //static st::IS_DoorControl sensor3(F("leftDoor"), PIN_CONTACT_LEFTGARAGE_DOOR, LOW, true, PIN_RELAY_LEFTGARAGE_DOOR, LOW, true, 1000); //static st::IS_DoorControl sensor4(F("rightDoor"), PIN_CONTACT_RIGHTGARAGE_DOOR, LOW, true, PIN_RELAY_RIGHTGARAGE_DOOR, LOW, true, 1000); static st::IS_Contact sensor1(F("FrontDoubleDoors"), PIN_CONTACT_FRONT_DBL_DOOR, LOW, true); static st::IS_Contact sensor2(F("DiningRoomWindows"), PIN_CONTACT_DINING_RM_WNDW, LOW, true); static st::IS_Contact sensor3(F("LivingRoomPatioDoor"), PIN_CONTACT_LVNG_PATIO_DOOR, LOW, true); static st::IS_Contact sensor4(F("KitchenNookWindows"), PIN_CONTACT_KTCH_NOOK_WNDW, LOW, true); static st::IS_Contact sensor5(F("SunRoomPatioDoor"), PIN_CONTACT_SUN_ROOM_DOOR, LOW, true); static st::IS_Contact sensor6(F("SunRoomWindows"), PIN_CONTACT_SUN_ROOM_WNDW, LOW, true); static st::IS_Contact sensor7(F("Bedroom1Windows"), PIN_CONTACT_BEDROOM1_WNDW, LOW, true); static st::IS_Contact sensor8(F("Bedroom2Windows"), PIN_CONTACT_BEDROOM2_WNDW, LOW, true); static st::IS_Contact sensor9(F("GarageDoor"), PIN_CONTACT_GARAGE_DOOR, LOW, true); //Executors //static st::EX_Switch executor1(F("sampleEX"), PIN_sampleEX, LOW, true); //***************************************************************************** // Configure debug print output from each main class // -Note: Set these to "false" if using Hardware Serial on pins 0 & 1 // to prevent communication conflicts with the ST Shield communications //***************************************************************************** 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 Thingshield Communications Object based on Arduino Model #if defined(ARDUINO_AVR_UNO) || defined(ARDUINO_AVR_NANO) || defined(ARDUINO_AVR_MINI) //Arduino UNO, NANO, MINI st::Everything::SmartThing = new st::SmartThingsThingShield(pinRX, pinTX, st::receiveSmartString); //Use Software Serial #elif defined(ARDUINO_AVR_LEONARDO) //Arduino Leonardo st::Everything::SmartThing = new st::SmartThingsThingShield(&Serial1, st::receiveSmartString); //Use Hardware Serial #elif defined(ARDUINO_AVR_MEGA) || defined(ARDUINO_AVR_MEGA2560) //Arduino MEGA 1280 or 2560 st::Everything::SmartThing = new st::SmartThingsThingShield(&Serial3, st::receiveSmartString); //Use Hardware Serial #else //assume user is using an UNO for the unknown case st::Everything::SmartThing = new st::SmartThingsThingShield(pinRX, pinTX, st::receiveSmartString); //Software Serial #endif //Run the Everything class' init() routine which establishes communications with SmartThings 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); //***************************************************************************** //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 //****************************************************************************************** void loop() { //***************************************************************************** //Execute the Everything run method which takes care of "Everything" //***************************************************************************** st::Everything::run(); }