You make yourself a nice hot cup of coffee, you take it with you to your desk, but since it is too hot to drink it immediately, you leave it there and continue with your work - next time you remember it, the coffee is already cold.
If you had a smart coaster to place your cup on, a coaster monitoring the temperature and notifying you before it gets too cold ...
SC² - Smart Cup CoasterThe idea of a:
- connected device to place a cup of coffee (or tea) on with
- contact-less temperature measurement and
- smart monitoring of cool down rate;
- Configurable via web interface and providing
- notification via email or text message before the beverage gets too cold;
- Based on an ESP8226 board (i.e. SparkFun ESP8266 Thing - Dev Board);
- Featuring the myDevice Cayenne IoT platform.
The prototype is based on:
- a Lolin V.3 NodeMCU ESP8266 microcontroller (ESP-12E),
- a TMP006 Contact-less Infrared Thermopile Sensor (datasheet) Breakout
- and a RGB (tri-color) LED - Common Anode
built into:
- an empty 10-disc cake box.
- The NodeMCU is placed and connected into a half-cut breadboard (400 pin);
- the TMP006 breakout is connected via four male-to-female jumper wires: GND to GND, SCL to D1, SDA to D2 and VIN to 3.3V;
- the RGB LED is placed and connected into the breadboard, the anode pins are connected through three 100 Ohm resistors to NodeMCU pins D5 - D7, common cathode is connected directly to a GND pin;
- the half-cut breadboard with the NodeMCU and the RGB is placed and fixed (hot glue) on the base inside the cake box;
- the TMP006 is placed and fixed (hot glue) on the center spindle;
- a hole is cut into the center of the cake box cover for the TMP006 sensor;
- another hole is cut into the side of the cake box for a power/USB cable;
Wiring diagram (Fritzing) and high-res pictures see here.
Features:
- Contact-less temperature reading from cup / glass placed on coaster using an infrared temperature sensor inside the coaster; no sensors to be fixed on vessel or to be put into liquid;
- Direct visualization of temperature via RGB LED (i.e. red = hot, green = ready, blue = cold);
- Embedded HTTP server exposing sensor reading as JSON data;
- myDevices - Cayenne integration enabling online monitoring, configuration and notification;
Function:
- After power-on the device tries to connect to a configured WiFi network and to the myDevices Cayenne platform (using the configured credentials see code / below).
- While initializing the LED is (low) red, after initialization and successful connection to the Cayenne platform, the LED lights up white for a second an then turns to green to signal status ready.
- When a cup with hot beverage (i.e. coffee, tea, hot chocolate etc.) is placed on the surface of the coaster the LED changes to red, if the cup's temperature is above a given threshold temperature or to blue, if its temperature is below.
- If the cup is removed from the coaster (i.e. for drinking), the LED changes back to green until it is placed back onto the coaster.
- While a warm/hot cup is "detected" (TMP006 object temperature reading is significant higher than the die temperature reading), difference temperature between the threshold temperature and the object temperature reading is calculated. If no cup is present, the difference temperature is always set to zero.
- Sensor readings (die temperature and object temperature) and the calculated difference temperature are published to a Cayenne dashboard (see here).
- The threshold temperature can be set with an actuator on the Cayenne dashboard and is stored persistently on the devices (using SPIFFS) .
- For notifications a trigger can be defined on the Cayenne dashboard monitoring the difference temperature and running if its value drops below zero (<0 !).
- Sensor readings (die temperature and object temperature) are also provided via a simple web service as JSON data - accessible via the URL http://scc.local/json when the device is connected to a WiFi network.
Code:
Find the full code here. It should explain itself. ;)
Some remarks:
- Using SPIFFS to store the threshold temperature value persistently: Unfortunately it seems not to be possible to retrieve back the value of an actuator using the Cayenne MQTT ESP8266 library (there is a also a community post regarding this topic). To retain a set threshold value after restarting the device, it is stored in the NodeMCU's flash memory using SPIFFS and written back to Cayenne. Please note, that if your have not already used SPIFF on your board, you have to format it once by uncommenting the appropriate lines.
void setup(void) {
/* ... */
// SPIFFS:
if ( sccThresholdTemperature < 0 ) {
useLocalStorage = true;
SPIFFS.begin();
/* SPIFFS format ***************************************/
/*
// The following lines have to be excuted ONLY ONCE!
// After SPIFFS is formatted ONCE these lines can be
// commented out.
Serial.println("Please wait for SPIFFS to be formatted ...");
SPIFFS.format();
Serial.println("SPIFFS formatted.");
File f0 = SPIFFS.open("/setup", "w");
if (!f0) {
Serial.println("SPIFFS open failed");
} else {
Serial.println("Writing to SPIFFS file ...");
f0.println(0);
f0.close();
}
/* SPIFFS format ************************************/
// open file for reading
File f = SPIFFS.open("/setup", "r");
if (!f) {
Serial.println("SPIFFS open failed!");
} else {
Serial.println("Reading from SPIFFS file ...");
String s = f.readStringUntil('\n');
sccThresholdTemperature = s.toInt();
f.close();
}
Cayenne.celsiusWrite(4, sccThresholdTemperature);
}
/* ... */
}
/* ... */
CAYENNE_IN_DEFAULT()
{
switch (request.channel) {
case 4:
sccThresholdTemperature = getValue.asInt();
if ( useLocalStorage ) {
File f = SPIFFS.open("/setup", "w");
if (!f) {
Serial.println("SPIFFS open failed");
} else {
f.println(sccThresholdTemperature);
f.close();
}
}
break;
}
}
- The SCC "logic": The logic providing the functionality is quite simple and heuristic. Since I didn't want to use an additional switch or sensor to detect the presence/absence of the cup, I decided to regard the difference of the sensor's die temperature and the measured object temperature.
// SCC logic
const int sccDieTmpObjTmpTolerance = 2;
int sccThresholdTemperature = -1;
float sccThresholdDifference = 0;
bool sccCupStatusChanged = false;
bool sccNoCup() {
return ( tmp006ObjectTempC - tmp006DieTempC
< sccDieTmpObjTmpTolerance
|| tmp006DieTempC > tmp006ObjectTempC ) ;
}
void loop() {
// Read sensor ...
readSensor();
// SCC logic
if ( sccNoCup() ) {
setColor(0, 255, 0); // green
if ( !sccCupStatusChanged ) {
sccCupStatusChanged = true;
sccThresholdDifference = 0;
}
} else {
if ( sccCupStatusChanged ) {
// Wait another cycle ..
delay(loopDelay);
// And read sensor again ...
readSensor();
sccCupStatusChanged = false;
}
sccThresholdDifference =
tmp006ObjectTempC - sccThresholdTemperature;
if ( sccThresholdDifference < 0 ) {
setColor(0, 0, 255); // blue
} else {
setColor(255, 0, 0); // red
}
}
/* ... */
}
myDevices - Cayenne IntegrationThis IoT device prototype publishes its up time and sensor readings to the cloud into a myDevices - Cayenne project SCC prototype.
- Temperature reading can be monitored on the Cayenne dashboard;
- Threshold temperature can be set and modified via widget from the dashboard;
- Custom triggers for notification via email or text message can be configured.
Setup:
Initially setting up an ESP8266 device to publish sensor readings to the Cayenne platform is straight forward following the instructions on the website: From the First Visit (page after signing up) or the Add Device page select (All Devices) SparkFun ESP8266 Thing Dev Board and follow the instructions to setup development environment, libraries (i.e. the Cayenne MQTT ESP8266 Library) and your device. See the Cayenne Documentation and the description for the Cayenne MQTT ESP8266 Library for more more details.
The SC² prototype device publishes/receives data to/from the Cayenne platform as follows:
- Device up-time (in milliseconds) is published on channel 0
- TMP006 die temperature reading (in *C) is published on channel 1
- TMP006 object (cup) temperature reading (in *C) is published on channel 2
- Temperature difference between threshold temperature and object temperature is published on channel 3
// Cayenne:
Cayenne.loop();
Cayenne.virtualWrite(0, millis());
// ^Channel 0: Uptime in ms
Cayenne.celsiusWrite(1, tmp006DieTempC);
// ^Channel 1: TMP006 sensor reading: die temperature in *C
Cayenne.celsiusWrite(2, tmp006ObjectTempC);
// ^Channel 2: TMP006 sensor reading: object temperature in *C
Cayenne.celsiusWrite(3, sccThresholdDifference);
// ^Channel 3: difference between object (cup) and threshold temperature
- Threshold temperature is received from channel 4
// Cayenne:
// Default function for processing actuator commands from the Cayenne Dashboard.
// Since the activation of the functions for specific channels,
// e.g. CAYENNE_IN(4) for channel 4 commands did not seem to work,
// we use the default function and a switch statement.
CAYENNE_IN_DEFAULT()
{
CAYENNE_LOG("CAYENNE_IN_DEFAULT(%u) - %s, %s", request.channel, getValue.getId(), getValue.asString());
//Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError("Error message");
switch (request.channel) {
case 4:
sccThresholdTemperature = getValue.asInt();
Serial.print("Threshold temperature changed to ");
Serial.print(sccThresholdTemperature);
Serial.println(" *C");
/* ... */
break;
}
}
The following screenshots show the setup procedure for the SC² prototype.
- It is just a proof-of-concept / just-for-fun prototype, but it actually works and has already "saved me" from a couple of cups of cold tea.
- A nicer, smaller, cooler housing for the device would be nice (although I noticed that the shape of the cake box cover is quite clever designed to prevent that spilled liquid drops through the hole for the sensor into the whole electronic stuff. ;o) ) ...
- Battery power ...
- More sophisticated setup for WiFi / MQTT parameters (through an initial AP with web interface) ...
- @Cayenne: Nice to have: More options to define more complex triggers with custom notification messages and the option to retrieve dashboard values back to the client ...
- ...
Comments