Arduino Shield Suggestions?

Yes, @ogiewon and @jody.albritton, we’re looking great. You guys are great. It has told me already that the thermostat element in my oven is vastly off. Messing with the timing of the reports also improved the behaviour of the program. Also your suggestions about putting some variables in F() space to reduce the footprint of the program helped very much, causing it to report every element necessary.

So this program and hardware project is important for two reasons, one of which is having more precise baking temperatures in the oven, and the other to let me know when my 2.5 year old has opened the fridge or freezer and is letting the cold air out. Or other unforeseen events. There switches that can be installed as well to help give more information. I’ll try to rig alarms with thresholds.

As for your idea to refactor it to work with your custom library and device type, sure. I’ll probably kick myself when you’ll whip it up in like 20 minutes. I set out with Jody’s code, which is why I didn’t pay much mind to your project initially.

l

Great to see everything’s working as desired. If you can share your Arduino sketch and Groovy Device Type code, I should be able to convert everything over to my library so you can compare and contrast the two approaches and decide which way you’d like to proceed.

@ogiewon 's code is much more optimized than my code. I threw mine together in a weekend and posted it because there was not a real good example of an arduino with multiple sensors.

I should really dump this in a Github repo.

Arduino code:



//*****************************************************************************
/// @file
/// @brief
///   Arduino SmartThings Shield Kitchen temp probes
/// @note
///              ______________
///             |              |
///             |         SW[] |
///             |[]RST         |
///             |         AREF |--
///             |          GND |--
///             |           13 |--X Othercrisp DHT
///             |           12 |--X Moistcrisp DHT
///             |           11 |--X Fridge DHT
///           --| 3.3V      10 |--X Freezer DHT
///           --| 5V         9 |--
///           --| GND        8 |--
///           --| GND          |
///           --| Vin        7 |--X CLK
///             |            6 |--X CS
///           --| A0         5 |--X DO for Broiler
///           --| A1    ( )  4 |--X DO for Oven
///           --| A2         3 |--X THING_RX
///           --| A3  ____   2 |--X THING_TX
///           --| A4 |    |  1 |--
///           --| A5 |    |  0 |--
///             |____|    |____|
///                  |____|
///
//*****************************************************************************
#include    //TODO need to set due to some weird wire language linker, should we absorb this whole library into smartthings
#include 
#include 
//thermocouple additions
#include "SPI.h"
#include "Adafruit_MAX31855.h"




//*****************************************************************************
// Pin Definitions    | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
//                    V V V V V V V V V V V V V V V V V V V V V V V V V V V V V
//*****************************************************************************
//For the Yun, have to reassign RX pin
#define PIN_THING_RX    8
#define PIN_THING_TX    2
#define DHT_FREEZER_PIN 10
#define DHT_FRIDGE_PIN 11
#define DHT_MOISTCRISP_PIN 12
#define DHT_OTHERCRISP_PIN 13

#define DHTTYPE DHT22

//tcouple additions

#define DO_oven 4
#define DO_broiler 5
#define CS 9
#define CLK 7

DHT dhtFreezer(DHT_FREEZER_PIN, DHTTYPE);
DHT dhtFridge(DHT_FRIDGE_PIN, DHTTYPE);
DHT dhtMoistcrisp(DHT_MOISTCRISP_PIN, DHTTYPE);
DHT dhtOthercrisp(DHT_OTHERCRISP_PIN, DHTTYPE);

//tcouple additions


Adafruit_MAX31855 thermocouple_oven(CLK, CS, DO_oven);
Adafruit_MAX31855 thermocouple_broiler(CLK, CS, DO_broiler);

//*****************************************************************************
// Global Variables   | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
//                    V V V V V V V V V V V V V V V V V V V V V V V V V V V V V
//*****************************************************************************
SmartThingsCallout_t messageCallout;    // call out function forward decalaration
SmartThings smartthing(PIN_THING_RX, PIN_THING_TX, messageCallout);  // constructor

bool isDebugEnabled;    // enable or disable debug in this example
int stateLED;           // state to track last set value of LED
int stateNetwork;       // state of the network



//*****************************************************************************
// Local Functions  | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
//                  V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V
//*****************************************************************************
void on()
{
    stateLED = 1;                 // save state as 1 (on)
    smartthing.shieldSetLED(0, 0, 2);
    smartthing.send("on");        // send message to cloud
}

//*****************************************************************************
void off()
{
    stateLED = 0;                 // set state to 0 (off)
    smartthing.shieldSetLED(0, 0, 0);
    smartthing.send("off");       // send message to cloud
}


//*****************************************************************************
void setNetworkStateLED()
{
    SmartThingsNetworkState_t tempState = smartthing.shieldGetLastNetworkState();
    if (tempState != stateNetwork)
    {
        switch (tempState)
        {
        case STATE_NO_NETWORK:
            if (isDebugEnabled) Serial.println(F("NO_NETWORK"));
            smartthing.shieldSetLED(2, 0, 0); // red
            break;
        case STATE_JOINING:
            if (isDebugEnabled) Serial.println(F("JOINING"));
            smartthing.shieldSetLED(2, 0, 0); // red
            break;
        case STATE_JOINED:
            if (isDebugEnabled) Serial.println(F("JOINED"));
            smartthing.shieldSetLED(0, 0, 0); // off
            break;
        case STATE_JOINED_NOPARENT:
            if (isDebugEnabled) Serial.println(F("JOINED_NOPARENT"));
            smartthing.shieldSetLED(2, 0, 2); // purple
            break;
        case STATE_LEAVING:
            if (isDebugEnabled) Serial.println(F("LEAVING"));
            smartthing.shieldSetLED(2, 0, 0); // red
            break;
        default:
        case STATE_UNKNOWN:
            if (isDebugEnabled) Serial.println(F("UNKNOWN"));
            smartthing.shieldSetLED(0, 2, 0); // green
            break;
        }
        stateNetwork = tempState;
    }
}

//*****************************************************************************
// API Functions    | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
//                  V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V
//*****************************************************************************
void setup()
{
    // setup default state of global variables
    isDebugEnabled = true;
    stateLED = 0;                 // matches state of hardware pin set below
    stateNetwork = STATE_JOINED;  // set to joined to keep state off if off


    //DHT 11


    // setup hardware pins




    dhtFreezer.begin();
    dhtFridge.begin();
    dhtMoistcrisp.begin();
    dhtOthercrisp.begin();

    if (isDebugEnabled)
    { // setup debug serial port
        Serial.begin(9600);         // setup serial with a baud rate of 9600
        Serial.println(F("setup.."));  // print out 'setup..' on start
        ////give the sensor some time to calibrate
        //Serial.print("calibrating sensor ");
        //for (int i = 0; i < calibrationTime; i++){
        //  Serial.print(".");
        //  delay(1000);
        //}
        //Serial.println(" done");
        //Serial.println("SENSOR ACTIVE");
        delay(50);
    }
}

//*****************************************************************************

// Keep Track of Sensor Readings
//int   currentLight;

int   currentFridgeHumidity;
int   currentFreezerHumidity;
int   currentMoistcrispHumidity;
int   currentOthercrispHumidity;
int   currentOvenTemperature;
int   currentBroilerTemperature;
int   currentFridgeTemperature;
int   currentFreezerTemperature;
int   currentMoistcrispTemperature;
int   currentOthercrispTemperature;



// Intervals
unsigned long   humidityInterval = (2 * 5 * 1000);
unsigned long   temperatureInterval = (2 * 5 * 1000);
unsigned long   reportInterval = (2 * 5 * 1000);

unsigned long   lastHumidityCheckAt = 0;
unsigned long   lastTempCheckAt = 0;
unsigned long   lastReportAt = 0;


void loop()
{
    // run smartthing logic
    smartthing.run();

    // Timing code
    unsigned long currentMillis = millis();

    // First and at checkInterval
    if (currentMillis - lastHumidityCheckAt > humidityInterval || lastHumidityCheckAt == 0)
    {
        lastHumidityCheckAt = currentMillis;

        // Do a check
        checkHumidity();

    }
    if (currentMillis - lastTempCheckAt > temperatureInterval || lastTempCheckAt == 0)
    {
        lastTempCheckAt = currentMillis;

        // Do a check
        checkTemperature();

    }



    // First and at reportInterval
    if (currentMillis - lastReportAt > reportInterval || lastReportAt == 0)
    {
        lastReportAt = currentMillis;

        // Do a report
        reportData();

    }

    // setNetworkStateLED();
    // checkHumidity();
    // checkTemperature();

    // delay(5000);









}
void checkData()
{
    checkHumidity();
    checkTemperature();


}

void checkHumidity()
{


    Serial.println("Checking humidity...");

    // Read humidity
    float hFreezer = dhtFreezer.readHumidity();
    float hFridge = dhtFridge.readHumidity();
    float hMoistcrisp = dhtMoistcrisp.readHumidity();
    float hOthercrisp = dhtOthercrisp.readHumidity();



    // Discard any data that is NaN
    if (isnan(hFreezer) || isnan(hFridge) || isnan(hMoistcrisp) || isnan(hOthercrisp))
    {
        Serial.println("Failed to read from one or more of the DHTs");
    }
    else {

        Serial.print("Fridge Humidity:");
        Serial.println(hFridge);
        currentFridgeHumidity = hFridge;

        Serial.print("Freezer Humidity:");
        Serial.println(hFreezer);
        currentFreezerHumidity = hFreezer;

        Serial.print("Moist Crisper Humidity:");
        Serial.println(hMoistcrisp);
        currentMoistcrispHumidity = hMoistcrisp;

        Serial.print("Other Crisper Humidity:");
        Serial.println(hOthercrisp);
        currentOthercrispHumidity = hOthercrisp;
    }




}

void checkTemperature()
{
    Serial.println("Checking temperature...");

    // Read temperature

    //Tcouples first

    double cOven = thermocouple_oven.readFarenheit();
    double cBroiler = thermocouple_broiler.readFarenheit();

    if (isnan(cOven) || isnan(cBroiler)){
        Serial.println("Error with Tcouple(s)");

    }
    else {
        Serial.print("Tcouple Oven Temp:");
        Serial.println(cOven);
        currentOvenTemperature = cOven;

        Serial.print("Tcouple Broiler Temp:");
        Serial.println(cBroiler);
        currentBroilerTemperature = cBroiler;
    }

    //DHTs next
    float tFreezer = dhtFreezer.readTemperature(true);
    float tFridge = dhtFridge.readTemperature(true);
    float tMoistcrisp = dhtMoistcrisp.readTemperature(true);
    float tOthercrisp = dhtOthercrisp.readTemperature(true);


    // Discard any data that is NaN
    if (isnan(tFreezer) || isnan(tFridge) || isnan(tMoistcrisp) || isnan(tOthercrisp))
    {
        Serial.println(F("Failed to read from one or more of the DHTs"));
    }
    else {
        Serial.print(F("Fridge Temp:"));
        Serial.println(tFridge);
        currentFridgeTemperature = tFridge;

        Serial.print(F("Freezer Temp:"));
        Serial.println(tFreezer);
        currentFreezerTemperature = tFreezer;

        Serial.print(F("Moist Crisper Temp:"));
        Serial.println(tMoistcrisp);
        currentMoistcrispTemperature = tMoistcrisp;

        Serial.print(F("Other Crisper Temp:"));
        Serial.println(tOthercrisp);
        currentOthercrispTemperature = tOthercrisp;
    }

}

void reportData()
{
    Serial.println(F("Reporting data..."));

    // We must insist on actually having some data to send
    if (isnan(currentFridgeHumidity) || isnan(currentFridgeTemperature) || isnan(currentFreezerHumidity) || isnan(currentOthercrispHumidity) || isnan(currentMoistcrispHumidity) || isnan(currentOvenTemperature) || isnan(currentBroilerTemperature) || isnan(currentFreezerTemperature) || isnan(currentOthercrispTemperature) || isnan(currentMoistcrispTemperature)) {



        Serial.println(F("We're not in a loop are we?"));

        checkData();
        reportData();
        return;
        }

        Serial.println("Messages to be delivered to ST");

    // Report humidity

    String humidityFridgeMessage = "A";
    humidityFridgeMessage.concat(currentFridgeHumidity);
    smartthing.send(humidityFridgeMessage);
    Serial.println(humidityFridgeMessage);

    String humidityFreezerMessage = "B";
    humidityFreezerMessage.concat(currentFreezerHumidity);
    smartthing.send(humidityFreezerMessage);
    Serial.println(humidityFreezerMessage);

    String humidityOthercrispMessage = "C";
    humidityOthercrispMessage.concat(currentOthercrispHumidity);
    smartthing.send(humidityOthercrispMessage);
    Serial.println(humidityOthercrispMessage);

    String humidityMoistcrispMessage = "D";
    humidityMoistcrispMessage.concat(currentMoistcrispHumidity);
    smartthing.send(humidityMoistcrispMessage);
    Serial.println(humidityMoistcrispMessage);

    // Report Temps
    String tempOvenMessage = "E";
    tempOvenMessage.concat(currentOvenTemperature);
    smartthing.send(tempOvenMessage);
    Serial.println(tempOvenMessage);

    String tempBroilerMessage = "F";
    tempBroilerMessage.concat(currentBroilerTemperature);
    smartthing.send(tempBroilerMessage);
    Serial.println(tempBroilerMessage);

    String tempFridgeMessage = "G";
    tempFridgeMessage.concat(currentFridgeTemperature);
    smartthing.send(tempFridgeMessage);
    Serial.println(tempFridgeMessage);


    String tempFreezerMessage = "H";
    tempFreezerMessage.concat(currentFreezerTemperature);
    smartthing.send(tempFreezerMessage);
    Serial.println(tempFreezerMessage);

    String tempOthercrispMessage = "I";
    tempOthercrispMessage.concat(currentOthercrispTemperature);
    smartthing.send(tempOthercrispMessage);
    Serial.println(tempOthercrispMessage);

    String tempMoistcrispMessage = "J";
    tempMoistcrispMessage.concat(currentMoistcrispTemperature);
    smartthing.send(tempMoistcrispMessage);
    Serial.println(tempMoistcrispMessage);

}


//*****************************************************************************
void messageCallout(String message)
{
    // if debug is enabled print out the received message
    if (isDebugEnabled)
    {
        Serial.print(F("Received message: '"));
        Serial.print(message);
        Serial.println("' ");
    }

    // if message contents equals to 'on' then call on() function
    // else if message contents equals to 'off' then call off() function
    if (message.equals("on"))
    {
        on();
    }
    else if (message.equals("off"))
    {
        off();
    }

    else if (message.equals("poll"))
    {
        reportData();
    }


}

And for the Groovy:

metadata {
    // Automatically generated. Make future change here.
    definition (name: "Christoph Multi Thermometers", namespace: "scordinskyc", author: "Christopher Scordinsky") {
        capability "Refresh"
        capability "Polling"
        capability "Temperature Measurement"
        capability "Relative Humidity Measurement"
        capability "Sensor"



        fingerprint profileId: "0104", deviceId: "0138", inClusters: "0000"
    }



    // Simulator metadata
    simulator {
        // status messages
      //  status "ping": "catchall: 0104 0000 01 01 0040 00 6A67 00 00 0000 0A 00 0A70696E67"
        //status "hello": "catchall: 0104 0000 01 01 0040 00 0A21 00 00 0000 0A 00 0A48656c6c6f20576f726c6421"
    }

    // UI tile definitions
    tiles {


        valueTile("tempOven", "device.tempOven", width: 1, height: 1, inactiveLabel: false) {
            state("temperature", label: 'Oven ${currentValue}°F', unit:"F", backgroundColors: [
                    [value: 31, color: "#153591"],
                    [value: 44, color: "#1e9cbb"],
                    [value: 59, color: "#90d2a7"],
                    [value: 74, color: "#44b621"],
                    [value: 84, color: "#f1d801"],
                    [value: 95, color: "#d04e00"],
                    [value: 96, color: "#bc2323"]
                ]
            )
        }
        valueTile("tempBroiler", "device.tempBroiler", width: 1, height: 1, inactiveLabel: false) {
            state("temperature", label: 'Broiler ${currentValue}°F', unit:"F", backgroundColors: [
                    [value: 31, color: "#153591"],
                    [value: 44, color: "#1e9cbb"],
                    [value: 59, color: "#90d2a7"],
                    [value: 74, color: "#44b621"],
                    [value: 84, color: "#f1d801"],
                    [value: 95, color: "#d04e00"],
                    [value: 96, color: "#bc2323"]
                ]
            )
        }
        valueTile("tempFridge", "device.tempFridge", width: 1, height: 1, inactiveLabel: false) {
            state("temperature", label: 'Fridge\n${currentValue}°F', unit:"F", backgroundColors: [
                    [value: 31, color: "#153591"],
                    [value: 44, color: "#1e9cbb"],
                    [value: 59, color: "#90d2a7"],
                    [value: 74, color: "#44b621"],
                    [value: 84, color: "#f1d801"],
                    [value: 95, color: "#d04e00"],
                    [value: 96, color: "#bc2323"]
                ]
            )
        }
        valueTile("tempFreezer", "device.tempFreezer", width: 1, height: 1, inactiveLabel: false) {
            state("temperature", label: 'Freezer\n${currentValue}°F', unit:"F", backgroundColors: [
                    [value: 31, color: "#153591"],
                    [value: 44, color: "#1e9cbb"],
                    [value: 59, color: "#90d2a7"],
                    [value: 74, color: "#44b621"],
                    [value: 84, color: "#f1d801"],
                    [value: 95, color: "#d04e00"],
                    [value: 96, color: "#bc2323"]
                ]
            )
        }
        valueTile("tempOthercrisp", "device.tempOthercrisp", width: 1, height: 1, inactiveLabel: false) {
            state("temperature", label: 'Other Crisper\n${currentValue}°F', unit:"F", backgroundColors: [
                    [value: 31, color: "#153591"],
                    [value: 44, color: "#1e9cbb"],
                    [value: 59, color: "#90d2a7"],
                    [value: 74, color: "#44b621"],
                    [value: 84, color: "#f1d801"],
                    [value: 95, color: "#d04e00"],
                    [value: 96, color: "#bc2323"]
                ]
            )
        }
        valueTile("tempMoistcrisp", "device.tempMoistcrisp", width: 1, height: 1, inactiveLabel: false) {
            state("temperature", label: 'Moist Crisper\n${currentValue}°F', unit:"F", backgroundColors: [
                    [value: 31, color: "#153591"],
                    [value: 44, color: "#1e9cbb"],
                    [value: 59, color: "#90d2a7"],
                    [value: 74, color: "#44b621"],
                    [value: 84, color: "#f1d801"],
                    [value: 95, color: "#d04e00"],
                    [value: 96, color: "#bc2323"]
                ]
            )
        }

        valueTile("humidityFridge", "device.humidityFridge", width: 1, height: 1, inactiveLabel: false) {
            state "humidity", label:'Fridge\n${currentValue}% humidity', unit:""
        }

        valueTile("humidityFreezer", "device.humidityFreezer", width: 1, height: 1, inactiveLabel: false) {
            state "humidity", label:'Freezer\n${currentValue}% humidity', unit:""
        }

        valueTile("humidityMoistcrisp", "device.humidityMoistcrisp", width: 1, height: 1, inactiveLabel: false) {
            state "humidity", label:'Moist\nCrisper ${currentValue}% humidity', unit:""
        }

        valueTile("humidityOthercrisp", "device.humidityOthercrisp", width: 1, height: 1, inactiveLabel: false) {
            state "humidity", label:'Other\nCrisper ${currentValue}% humidity', unit:""
        }





        standardTile("refresh", "device.poll") {
            state "default", label:'Refresh', action:"device.poll()", icon:"st.secondary.refresh"
        }


        main (["tempOven", "tempBroiler", "tempFridge", "tempFreezer","tempMoistcrisp", "tempOthercrisp","humidityFridge", "humidityFreezer", "humidityMoistcrisp", "humidityOthercrisp"])
        details(["tempOven", "tempBroiler", "tempFridge", "tempFreezer","tempMoistcrisp", "tempOthercrisp","humidityFridge", "humidityFreezer", "humidityMoistcrisp", "humidityOthercrisp"])
    }
}

Map parse(String description) {

    def value = zigbee.parse(description)?.text
    log.debug "Parsing '${description}'"
    // Not super interested in ping, can we just move on?
    if (value == "ping" || value == " ")
    {
        return
    }

    def linkText = getLinkText(device)
    def descriptionText = getDescriptionText(description, linkText, value)
    def handlerName = value
    def isStateChange = value != "ping"
    def displayed = value && isStateChange

    def result = [
        value: value,
        handlerName: handlerName,
        linkText: linkText,
        descriptionText: descriptionText,
        isStateChange: isStateChange,
        displayed: displayed
    ]

    log.debug  result.value

    if (value in ["!on","!off"])
    {
        result.name  = "switch"
        result.value = value[1..-1]
    //    log.debug result.value

//  } else if (value && value[0] == "%") {
//      result.name = "level"
//      result.value = value[1..-1]
    






    } else if (value && value[0] == "A") {
        result.name = "humidityFridge";
        result.value = value[1..-1];
        result.unit = "%"
    //    log.debug 'HFridge' 
    //    log.debug result.value

    } else if (value && value[0] == "B") {
        result.name = "humidityFreezer";
        result.value = value[1..-1];
        result.unit = "%"
     //   log.debug 'HFreez' 
     //   log.debug result.value

    } else if (value && value[0] == "C") {
        result.name = "humidityOthercrisp";
        result.value = value[1..-1];
        result.unit = "%"
     //   log.debug 'HOthCr' 
     //   log.debug result.value

    } else if (value && value[0] == "D") {
        result.name = "humidityMoistcrisp";
        result.value = value[1..-1];
        result.unit = "%"
    //    log.debug 'HMoisCr' 
    //    log.debug result.value



    } else if (value && value[0] == "E") {
        result.name = "tempOven";
        result.value = value[1..-1];
        result.unit = "F"
     //   log.debug 'TOv' 
     //   log.debug result.value


    } else if (value && value[0] == "F") {
        result.name = "tempBroiler";
        result.value = value[1..-1];
        result.unit = "F"
    //    log.debug 'TBroiler'
    //    log.debug  result.value


    } else if (value && value[0] == "G") {
        result.name = "tempFridge";
        result.value = value[1..-1];
        result.unit = "F"
   //     log.debug 'TFridge'
   //     log.debug  result.value


    } else if (value && value[0] == "H") {
        result.name = "tempFreezer";
        result.value = value[1..-1];
        result.unit = "F"
     //   log.debug 'TFreezer'
     //   log.debug  result.value


    } else if (value && value[0] == "I") {
        result.name = "tempOthercrisp";
        result.value = value[1..-1];
        result.unit = "F"
   //     log.debug 'TOtherCrisp'
   //     log.debug result.value


    } else if (value && value[0] == "J") {
        result.name = "tempMoistcrisp";
        result.value = value[1..-1];
        result.unit = "F"
   //     log.debug 'TMoistCrisp'
   //     log.debug result.value

    } else {
        result.name = null;
        log.debug  result.value
    }


//  if ( (value && value[0] == "%") )
//  {
//      result.unit = "%"

//  }
    log.debug result.descriptionText
    createEvent(name: result.name, value: result.value)


}



def poll() {
    zigbee.smartShield(text: "poll").format()
    }

@scordinskyc , @jody.albritton

Chris,
I have updated my Github Repo at https://github.com/DanielOgorchock/ST_Anything with everything you need to try the multiple temperature monitoring project using my ST_Anything library.

Follow the ReadMe at the repo for details of getting the basic library installed. You will want to copy ALL of the libraries (excluding the \ST_Anything_RCSwitch and \RCSwitch libraries) into your Arduino\libraries folder.
NOTE: My library uses a different DHT library versus the one Chris used originally. You must use the \DHT library from my REPO for the DHT sensors to work properly. Also, you must use my new and improved version of the \SmartThings library for the code to compile properly. The new \SmartThings library is 100% backwards compatible, but contains new features and optimizations.

You’ll want to grab the Sketches\ST_Anything_Temperatures folder and copy to your Arduino\Sketches folder. Also, copy and paste the Groovy\ST_Anything_Temperature.device.groovy code into the ST IDE as a new Device Type. I preserved Chris’ tiles and layout, but rewrote the guts of the parse routine. It is now much simpler. This Device Type also has a preferences section you can use to set the polling interval to the DHT and Thermocouple sensors on the Arduino. After setting the preferences in the ST App on your phone, simply press the Configure tile to send the new poll rates to the Arduino. These values will not persist through an Arduino reboot though. I have set the DHT’s to poll every 30 seconds and the Thermocouples every 10 seconds by default in the sketch. (Read the comments in the new PS_AdafruitThemocouple.h file to understand what all of the arguments of the constructor are used for.)

Since you are using an Arduino YUN, you’ll need to modify the libraries\ST_Anything\constants.h file to set the correct Tx and Rx pins for the SmartThings shield. The library is pretty smart when using an UNO or a MEGA, but the YUN will require you to change line 103 of constants.h to reflect the Rx pin you’re using on the YUN (which I believe is pin 8 based on your sketch.)

I do not believe you should have to change any of your existing wiring, as I preserved all of the PIN assignments. The only files I believe you will need to change are “constants.h” and “ST_Anything_Temperatures.ino” (this assumes the new Adafruit Thermocouple code works as expected!)

Have fun and let me know what you think!

Dan

3 Likes

I posted a general topic but figured I’d stir some folks up here to get some sort of response maybe.

Any suggestions? Previous projects? Thanks!

Fantastic. And sorry for the delay getting back. Always busy during the week.

Looks like it’s working very well. Doesn’t seem like there are any issues at all. I have to go looking through your code to see how it works. Very modularized. Thank you so much for all your help!

1 Like

Chris,

Glad to hear it is working for you. Let me know if you have any questions.

I made some improvements to the main “ST_Anything” library today. You may want to grab the latest code just to be up to date.

Dan

Hey Dan,

I was going to follow up. The Arduino is behaving quirky, like not communicating at all with the ST base. I’m thinking it’s due to it being low on memory. Your package and associate libraries ring in at 79% of the device’s memory. Any ideas about how to slim some of the bits you contributed down?

Christopher

@scordinskyc

Hi Christoper,

Something seems to be amiss… Here is what I get on an Arduino UNO R3 which only has 2K of SRAM (versus the YUN with 2.5K of SRAM) I wonder if the YUN uses more SRAM by default for the libraries it needs to include to communicate between the Linux CPU and the Arduino CPU?

Sketch uses 19,974 bytes (61%) of program storage space. Maximum is 32,256 bytes.
Global variables use 1,252 bytes (61%) of dynamic memory, leaving 796 bytes for local variables. Maximum is 2,048 bytes.

Did you download my version of the SmartThings library for the ThingShield from my Github repository? The orginal one from ST was not optimized for memory usage. We reduced it compile-time SRAM usage by ~150 bytes, and eliminated another 255 bytes of SRAM that was temporarily allocated every time a message was sent to the hub. That’s about a 400 byte savings at peak usage times.

I’ll take a look at the code to see if it can be optimized further… FYI - Program space can be basically used to its mazimum. The real issue is the dynamic memory. Please let me know how much you have free at compile time, and how much the sketch reports as Free Ram in the Serial Monitor window when it is running.

Dan

Hey Dan,

This is what I get when I compile it for the Yun:

Sketch uses 22,534 bytes (78%) of program storage space. Maximum is 28,672 bytes.
Global variables use 1,221 bytes (47%) of dynamic memory, leaving 1,339 bytes for local variables. Maximum is 2,560 bytes.

As far as I know, the bridging libraries have to be called specifically, include Bridge.h and such.

Christopher,

When the sketch is running, how much “Free Ram” is reported periodically in the Serial Monitor window of the Arduino IDE?

Your YUN has a ton a SRAM free at compile time, especially compared to my UNO due to the YUN having 2.5K versus 2K for the UNO. I’d really like to know how much is free when the sketch is running. My UNO has ~500 bytes of free RAM while the sketch is running, versus 835 bytes free at compile time.

Sketch uses 19,962 bytes (61%) of program storage space. Maximum is 32,256 bytes.
Global variables use 1,213 bytes (59%) of dynamic memory, leaving 835 bytes for local variables. Maximum is 2,048 bytes.

I have made some minor improvements to my PS_TemperatureHumidity sensor code to reduce memory usage at runtime. Also, the author of the DHT library had a minor improvement in his code. I have uploaded these changed files to my GitHub repository.

Grab the following files:

  • dht.h, and dht.cpp and place in your DHT library folder
  • PS_TemperatureHumidity.h and PS_TemperatureHumidity.cpp and place in your ST_Anything_TemperatureHumidity library folder

I was able to squeak another ~38 bytes of SRAM by making these changes.

Hi Andrew, it would be great if you could make one shield compatible with the Wino board (https://www.kickstarter.com/projects/krom/wino-board-the-tiny-10-arduino-with-wifi/description) or make a similar board using M0 or M3 chip compatible with the arduino wiring language and the build in zigbee chip.

I would really like to see a beaglebone black OR Raspberry Pi add-on.

But does it have to be hardware? Both of these platforms will run a number of different operating systems, and both have great support for networking. So really all you need is a network API, right?

What about an RS232 based interface with loadable support modules, so I could do things like plug one into my Roomba’s serial port and execute commands using my smartthings app. I think all you need to do this is a zigbee to RS232 module, and some software. For the developers, an expect-like scripting environment would allow this interface to be adaptable to just about anything with an RS232 serial port. I know a lot of people that would buy that… It might be outside of your home-user consumer market, but a cloud based wireless RS232 interface could be interesting. You could certainly do a lot of weird things with it. And RS232/usb is an easy compatibility layer that you could use to connect to a LOT of different products including just about every thing with a CPU.

So while I like the idea of a shield, that limits you to one small family of target devices. If you use a standards based interface in wide distribution, like usb/rs232, you can connect THAT to ANYTHING almost.

The ThingShield is essentially a Zigbee to Serial communications device already. By connecting it to an Arduino, you can then interface it to anything you’d like, including RS232 devices. Some folks have created a SmartThings to X10 bridge using this setup, which uses an RS232 shield along with the ThingShield.

Can you use this as an alternative for the TAPT Phillips Hue remote ?

I doubt you’d want to use the ThingShield to try and replicate the Phillips Hues Tap Remote. I don’t have a Hue setup, just GE Link and Cree Connected light bulbs, which are paired directly to my SmartThings hub.

You could use an Arduino + ThingShield as a multiple button remote control to send SmartThings commands directly, which would then in turn be handled by a SmartApp. But packaging would be challenging. The Minimote would handle this same method pretty easily, as that is exactly what it is designed to do.

What is your end-goal that you have in mind?

I need a physical button to turn the Hue bulbs in a room on/off… if the Minimote can do the same function, i will use it

thanks for the suggestion

Assuming your Hue bulbs are somehow integrated with SmartThings already, I would think the Minimote would probably suit your needs. (Note: I have neither the Hue bulbs or Minimote, so no first hand experience.)

Check out the discussion about it here:

If you haven’t already, check out this topic: