For those looking for a full SoC solution the meshbee from seeedstudios is promising. A powerful enough MCU with multiple DIOs SPI i2c and enough ram and flash to hold a large app with full zigbee profiles. For $20. It’s based on the jn5168 by NXP. I haven’t used it with ST yet (I’m in the process of switching from Wink to ST) but all the tools and SDKs are free, although you do have to jump through some hoops to get them.
Interesting. I’d be interested to see someone do a project with this, I don’t know that I’m 1337 enough to give it a try.
Hello everyone,
I’m using a ThingShield (the one sold by SmartThings) to allow me to perpetually monitor temperatures (and humidities) in the fridge, freezer, and both crispers with DHT22s. In addition, I have thermocouples going to the oven and broiler to monitor those so I can correlate the oven dial to the actual temperatures. (I do baking and need somewhat quantitative information)
Now, the hardware aspect is fine. The Arduino code, I think, is okay as well. However, I think I’m running into some trouble with the Groovy of the device type I made. Essentially, I have multiple temperature widgets
(and humidity ones too). It doesn’t seem to be populating these widgets with any numbers, just --.
I based it off of @jody.albritton’s JodyThing project.
So, a question from a snippit of my code:
valueTile(“tempFridge”,“device.temperature”,width: 1,height: 1, inactiveLabel: false){
state(“temperature”,label:$currentValue’,unit:“F”…
valueTile(“tempFreezer”, “device.temperature”,…
Do we still use device.temperature as the second component of the widget value tile for each one? Or should it be unique to each one, like fridgeDevice.temperature, freezerDevice.temperature? I’d be happy to furnish whatever other code I’ve written so folks can scrutinize it.
Thanks!
Christoph
If you look at the arduino code, you will notice that it is merely sending ST a string. So on the arduino you will need to set up multiple temperature senders.
instead of just currentTemperature on line 180:
int currentTemperature;
You need to define multiple temperature readings.
int currentTemperatureOne;
int currentTemperatureTwo;
The checkTemperature method on line 260 will also need to be modified to reflect the multiple temperatures.
In the device type you will need to modify the parse method to allow for multiple temperatures on line 122
} else if (value && value[0] == "t") {
result.name = "temperature";
result.value = value[1..-1];
result.unit = "F"
}
changes to
} else if (value && value[0] == "t") {
result.name = "temperatureOne";
result.value = value[1..-1];
result.unit = "F"
}else if( (value && value[0] == "t") {
result.name = "temperatureTwo";
result.value = value[1..-1];
result.unit = "F"
}
There are a few other places where you need to make the changes but this should give you the general idea. In your tiles you would access them by calling device.temperatureOne and device.temperatureTwo
@jodyalbritton Everything looks correct, taking your suggestions into account. The Arduino section is looking good and outputs great over Serial, but for some reason, the ST device type part isn’t working. Still seeing the ‘–’ where temperatures and humidities should be. Is there somewhere I can add log messages of what the is seeing?
I’ll enclose my code below, should you notice something.:
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: '${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: '${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: '${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: '${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: '${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: '${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:'${currentValue}% humidity', unit:""
}
valueTile("humidityFreezer", "device.humidityFreezer", width: 1, height: 1, inactiveLabel: false) {
state "humidity", label:'${currentValue}% humidity', unit:""
}
valueTile("humidityMoistcrisp", "device.humidityMoistcrisp", width: 1, height: 1, inactiveLabel: false) {
state "humidity", label:'${currentValue}% humidity', unit:""
}
valueTile("humidityOthercrisp", "device.humidityOthercrisp", width: 1, height: 1, inactiveLabel: false) {
state "humidity", label:'${currentValue}% humidity', unit:""
}
standardTile("refresh", "device.poll") {
state "default", label:'', 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
// 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
]
if (value in ["!on","!off"])
{
result.name = "switch"
result.value = value[1..-1]
// } else if (value && value[0] == "%") {
// result.name = "level"
// result.value = value[1..-1]
} else if (value && value[0] == "humidityFridge") {
result.name = "humidityFridge";
result.value = value[1..-1];
result.unit = "%"
} else if (value && value[0] == "humidityFreezer") {
result.name = "humidityFreezer";
result.value = value[1..-1];
result.unit = "%"
} else if (value && value[0] == "humidityOthercrisp") {
result.name = "humidityOthercrisp";
result.value = value[1..-1];
result.unit = "%"
} else if (value && value[0] == "humidityMoistcrisp") {
result.name = "humidityMoistcrisp";
result.value = value[1..-1];
result.unit = "%"
} else if (value && value[0] == "tempOven") {
result.name = "tempOven";
result.value = value[1..-1];
result.unit = "C"
} else if (value && value[0] == "tempBroiler") {
result.name = "tempBroiler";
result.value = value[1..-1];
result.unit = "C"
} else if (value && value[0] == "tempFridge") {
result.name = "tempFridge";
result.value = value[1..-1];
result.unit = "C"
} else if (value && value[0] == "tempFreezer") {
result.name = "tempFreezer";
result.value = value[1..-1];
result.unit = "C"
} else if (value && value[0] == "tempOthercrisp") {
result.name = "tempOthercrisp";
result.value = value[1..-1];
result.unit = "C"
} else if (value && value[0] == "tempMoistcrisp") {
result.name = "tempMoistcrisp";
result.value = value[1..-1];
result.unit = "C"
} else {
result.name = null;
}
// if ( (value && value[0] == "%") )
// {
// result.unit = "%"
// }
createEvent(name: result.name, value: result.value)
}
def poll() {
zigbee.smartShield(text: "poll").format()
}
And the Arduino:
//***************************************************************************** /// @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 6 #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("NO_NETWORK"); smartthing.shieldSetLED(2, 0, 0); // red break; case STATE_JOINING: if (isDebugEnabled) Serial.println("JOINING"); smartthing.shieldSetLED(2, 0, 0); // red break; case STATE_JOINED: if (isDebugEnabled) Serial.println("JOINED"); smartthing.shieldSetLED(0, 0, 0); // off break; case STATE_JOINED_NOPARENT: if (isDebugEnabled) Serial.println("JOINED_NOPARENT"); smartthing.shieldSetLED(2, 0, 2); // purple break; case STATE_LEAVING: if (isDebugEnabled) Serial.println("LEAVING"); smartthing.shieldSetLED(2, 0, 0); // red break; default: case STATE_UNKNOWN: if (isDebugEnabled) Serial.println("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("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 = (25 * 1000); unsigned long temperatureInterval = (25 * 1000); unsigned long reportInterval = (2 * 60 * 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(); } 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.readCelsius(); double cBroiler = thermocouple_broiler.readCelsius(); 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("Failed to read from one or more of the DHTs"); } else { Serial.print("Fridge Temp:"); Serial.println(tFridge); currentFridgeTemperature = tFridge; Serial.print("Freezer Temp:"); Serial.println(tFreezer); currentFreezerTemperature = tFreezer; Serial.print("Moist Crisper Temp:"); Serial.println(tMoistcrisp); currentMoistcrispTemperature = tMoistcrisp; Serial.print("Other Crisper Temp:"); Serial.println(tOthercrisp); currentOthercrispTemperature = tOthercrisp; } } void reportData() { Serial.println("Reporting data..."); // We must insist on actually having some data to send if (isnan(currentFridgeHumidity) || isnan(currentFridgeTemperature)) { Serial.println("We're not in a loop are we?"); checkData(); reportData(); return; } // Report humidity String humidityFridgeMessage = "humidityFridge"; humidityFridgeMessage.concat(currentFridgeHumidity); smartthing.send(humidityFridgeMessage); Serial.println(humidityFridgeMessage); String humidityFreezerMessage = "humidityFreezer"; humidityFreezerMessage.concat(currentFreezerHumidity); smartthing.send(humidityFreezerMessage); Serial.println(humidityFreezerMessage); String humidityOthercrispMessage = "humidityOthercrisp"; humidityOthercrispMessage.concat(currentOthercrispHumidity); smartthing.send(humidityOthercrispMessage); Serial.println(humidityOthercrispMessage); String humidityMoistcrispMessage = "humidityMoistcrisp"; humidityMoistcrispMessage.concat(currentMoistcrispHumidity); smartthing.send(humidityMoistcrispMessage); Serial.println(humidityMoistcrispMessage); // Report Temps String tempOvenMessage = "tempOven"; tempOvenMessage.concat(currentOvenTemperature); smartthing.send(tempOvenMessage); String tempBroilerMessage = "tempBroiler"; tempBroilerMessage.concat(currentBroilerTemperature); smartthing.send(tempBroilerMessage); String tempFridgeMessage = "tempFridge"; tempFridgeMessage.concat(currentFridgeTemperature); smartthing.send(tempFridgeMessage); String tempFreezerMessage = "tempFreezer"; tempFreezerMessage.concat(currentFreezerTemperature); smartthing.send(tempFreezerMessage); String tempOthercrispMessage = "tempOthercrisp"; tempOthercrispMessage.concat(currentOthercrispTemperature); smartthing.send(tempOthercrispMessage); String tempMoistcrispMessage = "tempMoistcrisp"; tempMoistcrispMessage.concat(currentMoistcrispTemperature); smartthing.send(tempMoistcrispMessage); } //***************************************************************************** void messageCallout(String message) { // if debug is enabled print out the received message if (isDebugEnabled) { Serial.print("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(); } }
The problem is with the string parsing on the device type. Because I had so few values, I could just pass my strings very simply. My temperature string looks like this t71. Humidity string looks like h29. ETC.
So when I evaluate
if (value && value[0] == "t")
The value[0] is just the first character of the string. Which in the case of temperature is the letter T.
You can just use different letters for each of yours instead of full names or pass an array instead of a string. If you look at the serial output, you will see what I am talking about.
@jodyalbritton Okay, the device type is going to be looking for A-J as the first character in the messages, and the Arduino is going to be sending A-J as the first character for each of the messages. Still nothing. I also cleared out myself using pin 6 on the Arduino just in case that was causing problems.
I added a log.debug at the top of the Parse section. But it looks like it’s just spitting out the ping catchall:
Parsing ‘catchall: 0104 0000 01 01 0140 00 FC76 00 00 0000 0A 00 0A70696E67’
Are you seeing the temps in the arduino serial output? I would put the log.debug in each of the else if sections.
log.debug result.value
If that is returning nil, then the parse is not working.
Chris,
Are you using an Arduino UNO R3 or a MEGA 2560? You may be running out of free memory on the UNO which will cause all sorts of strange behavior. I see in your code you’re using a lot of longish strings. Have you tried using the F() function to keep those strings in Flash memory instead of consuming your precious 2k of RAM on an UNO? The MEGA has 8k of RAM so it is less prone to these problems. Using a MEGA has other issues with the ThingShield. Let me know if you have any questions.
Also, you might want to use my very of the SmartThings Arduino library as we optimized it considerably for memory usage, performance, and added support for the MEGA. Take a look at my github ST_Anything repository. Link can be found above in one of my earlier posts.
Dan
Hey @ogiewon ,
I’m using a Yun, which as I understand it, has the guts of a Leonardo. I had to do some pin reassignment to make it work with the ST shield.
Looks like we may have made some progress, as it seems that ST is doing some parsing correctly. I added some log debug messages after each else, @jody.albritton. Strange, it seems to be reporting once, when the unit powers on. And weirdly, it’s not all the terms. This may be because something is holding the Arduino from sending it.
I should note that the serial output looks good for all the temps and humidities, so it’s not like they’re NAN. Just those three that it’s not seeing (and not parsing). The device widgets still have the ‘–’, I should also mention.
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:55 PM EDT: debug TS was H-2
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:55 PM EDT: debug -2
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:55 PM EDT: debug H-2
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:55 PM EDT: debug Parsing 'catchall: 0104 0000 01 01 0040 00 FC76 00 00 0000 0A 00 0A482D32’
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:54 PM EDT: debug TS was F24
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:54 PM EDT: debug 24
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:54 PM EDT: debug F24
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:54 PM EDT: debug Parsing 'catchall: 0104 0000 01 01 0040 00 FC76 00 00 0000 0A 00 0A463234’
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:54 PM EDT: debug TS was G39
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:54 PM EDT: debug 39
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:54 PM EDT: debug G39
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:54 PM EDT: debug Parsing 'catchall: 0104 0000 01 01 0040 00 FC76 00 00 0000 0A 00 0A473339’
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:54 PM EDT: debug TS was J39
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:54 PM EDT: debug 39
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:54 PM EDT: debug J39
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:54 PM EDT: debug Parsing 'catchall: 0104 0000 01 01 0140 00 FC76 00 00 0000 0A 00 0A4A3339’
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:54 PM EDT: debug TS was I38
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:54 PM EDT: debug 38
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:54 PM EDT: debug I38
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:54 PM EDT: debug Parsing 'catchall: 0104 0000 01 01 0140 00 FC76 00 00 0000 0A 00 0A493338’
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:50 PM EDT: debug TS was E25
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:50 PM EDT: debug 25
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:50 PM EDT: debug E25
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:50 PM EDT: debug Parsing 'catchall: 0104 0000 01 01 0140 00 FC76 00 00 0000 0A 00 0A453235’
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:49 PM EDT: debug TS was A40
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:49 PM EDT: debug 40
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:49 PM EDT: debug A40
79a0c8fd-2bcc-42d4-91b3-677a53af1fd7 8:19:49 PM EDT: debug Parsing ‘catchall: 0104 0000 01 01 0140 00 FC76 00 00 0000 0A 00 0A413430’
You guys are awesome, by the way. Don’t know whether you’re told that often enough.
The Yun only has 2.5k of RAM, so you may still be bumping into a memory fragmentation issue. I saw the same weird behavior as I added more sensors to a single UNO. You can free up a bunch of memory simply by using the F() feature in the Arduino compiler. Give it a shot. You’ve got nothing to lose but lots of RAM to gain!
Okay, well one issue I nipped, maybe, which was how often the loop was running the report function. Now, as far as using F() to economize the usage of the memory of this sucker - can you point me to a clear usage of its syntax?
Ceck out this great article
Much of your code calls functions that are dynamically allocating strings. This can lead to SRAM fragmentation. Once it’s fragmented, the application will behave strangely.
You can add the freeRam() function described earlier in this article to actually measure and display your SRAM usage as your application runs. Just print out the returned value periodically to the serial debug window.
Also, for some reason, it was adding libraries by default, like bridge, and YunServer, etc. I didn’t need those (at least yet).
Sketch uses 19,044 bytes (66%) of program storage space. Maximum is 28,672 bytes.
Global variables use 1,247 bytes (48%) of dynamic memory, leaving 1,313 bytes for local variables. Maximum is 2,560 bytes.
Looks better than it was.
Can’t figure out why it’s not seeing three of the parameters I send to parse (labelled B, C, and D). Everything looks fine with them.
Should also be reporting in ever 2 minutes, but isn’t. I may just clear out the loop section to the essentials to weed this out.
Yahtzee! I think we’re on a good track here because they’re cropping up on the widgets. Still not seeing them all yet, but I think this is fantastic progress. I think, also, @ogiewon, you are correct about quirky behaviour, when there is minimal free space. I will try to consolidate and reduce as much as possible for improved results.
So @scordinskyc, do you have everything working properly? Hopefully all is well.
I am willing to whip up an example of your Arduino project using my ST_Anything library. I could have the 4 DHT temperature sensors up and running on the Arduino, and reporting to a custom Device Type in the ST cloud in about 30 minutes or less, if you’re interested.
We’d have to add a new sensor type to my library to support your Adafruit thermocouples, but that wouldn’t take too much work. Just another .h and .cpp file.
Let me know if you’re interested. Happy to help.
Dan
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.
lGreat 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.