Introduction
How many times have you made a cup of coffee or tea and it’s been too hot to drink, and then by the time you get to it, it’s become too cold?![Frown :( :(]()
I love drinking tea and most of the times I have burned my mouth.![Mad :mad: :mad:]()
My Solution:
A Smart coaster to place your cup on, a coaster monitoring the temperature and notifying you before it gets too cold.
If you place a cup of hot tea/coffee on it, it will start a timer program which shows you, when it is ready to drink. A RGB led will be present to show if the temperature is right or not.
I am using Thermo 6 MAX31875 click board as it would be the perfect solution for this project due to the low power consumption.
If you go through the code i have explained everything in detail and you will know that this prototype device can not only be used to monitor your hot beverages temperature but also can be used to monitor the temperature of cold beverages so that you will always enjoy your drinks at optimum temperature and be happy!!![Wink ;) ;)]()
BOM
Software
Instructions
In Standby mode, and between conversions, the power supply current is typically 500nA. During a conversion, the typical supply current increases to 80μA. The duration of a conversion depends on the conversion resolution selected in the Configuration register. A 10-bit conversion requires 35ms (typical). Each 1-bit increase in resolution doubles the conversion time, and each 1-bit decrease halves the conversion time. Therefore, if 12-bit resolution is selected, the conversion time will typically be 140ms.
The conversion rate is also selectable, and, along with resolution, helps to set the conversion duty cycle and
average power supply current. As an example, 10-bit
conversions occurring at a rate of one conversion per second will result in an average power supply current of
IAVE = 80μA x 0.035 + 0.5μA x 0.965 = 2.8μA.
As you can see all the components from regulator to the microcontroller and sensor consume low power. Atmega328p was used due to the ease of programming via the Arduino IDE and also you can program it to consume extremely low power.![Cool :cool: :cool:]()
I have also added battery monitoring feature if the battery level falls below 20% our rgb led will go through yellow, cyan and purple colour when you start your device to notify you that the battery is low.![Cool :cool: :cool:]()
Maxim has a nice video tutorial on this thermo 6 click board:-
https://www.maximintegrated.com/en/products/analog/sensors-and-sensor-interface/MAX31875.html
Now they have made a tutorial using their microcontroller programmed via mbed so i searched the repository and got the following code which was edited to work with Arduino boards:-
https://os.mbed.com/teams/MaximIntegrated/code/MAX31875_demo/file/bc0f96339b73/main.cpp/
Video
Let's see your project in action! Paste the YouTube link here and it will automatically be embedded.
Working Demo Video of the prototype:-
Schematics
Source Code
Arduino MAX31875 Interfacing
Main Code with all the electronic components
CAD Files
I haven't made the 3d case yet but as soon as it gets designed and printed i will upload it.
How many times have you made a cup of coffee or tea and it’s been too hot to drink, and then by the time you get to it, it’s become too cold?

I love drinking tea and most of the times I have burned my mouth.

My Solution:
A Smart coaster to place your cup on, a coaster monitoring the temperature and notifying you before it gets too cold.
If you place a cup of hot tea/coffee on it, it will start a timer program which shows you, when it is ready to drink. A RGB led will be present to show if the temperature is right or not.
I am using Thermo 6 MAX31875 click board as it would be the perfect solution for this project due to the low power consumption.
If you go through the code i have explained everything in detail and you will know that this prototype device can not only be used to monitor your hot beverages temperature but also can be used to monitor the temperature of cold beverages so that you will always enjoy your drinks at optimum temperature and be happy!!

BOM
- Atmega328p mirocontroller. [Quantity - 1] (Arduino Uno Microcontroller)
- Thermo 6 click board based on the Maxim Integrated MAX31875 temperature sensor. [Quantity - 1]
- LED - RGB Diffused Common Anode. [Quantity - 1]
- 28 Pin - DIP IC Socket/Base. [Quantity - 1]
- 40 pin Female and Male Berg strip. [Quantity - 1 each]
- HT7533A-1 3.3V 100mA Low Power LDO. [Quantity - 1]
- 9v Battery. [Quantity - 1]
- 9v Battery Snap Connector. [Quantity - 1]
Software
- Arduino IDE
Instructions
- MAX31875 Features:-
Tiny, 0.84mm x 0.84mm x 0.35mm WLP
Excellent Temperature Accuracy -
I2C and SMBus Support
Selectable PEC for Reliable Communications
Up to 1MHz Bus Speed
+1.6V to +3.6V Power Supply Voltage
Excellent Temperature Accuracy -
±1.5°C from +10°C to +45°C (±0.5°C Typical)
±2°C from -10°C to +100°C (±0.6°C Typical)
±3°C from -20°C to +125°C (±1°C Typical)
<10μA Average Power Supply Current±2°C from -10°C to +100°C (±0.6°C Typical)
±3°C from -20°C to +125°C (±1°C Typical)
I2C and SMBus Support
Selectable PEC for Reliable Communications
Up to 1MHz Bus Speed
+1.6V to +3.6V Power Supply Voltage

- MAX31875 Typical Application Circuit:-

- MAX31875 Power Consumption:-
In Standby mode, and between conversions, the power supply current is typically 500nA. During a conversion, the typical supply current increases to 80μA. The duration of a conversion depends on the conversion resolution selected in the Configuration register. A 10-bit conversion requires 35ms (typical). Each 1-bit increase in resolution doubles the conversion time, and each 1-bit decrease halves the conversion time. Therefore, if 12-bit resolution is selected, the conversion time will typically be 140ms.
The conversion rate is also selectable, and, along with resolution, helps to set the conversion duty cycle and
average power supply current. As an example, 10-bit
conversions occurring at a rate of one conversion per second will result in an average power supply current of
IAVE = 80μA x 0.035 + 0.5μA x 0.965 = 2.8μA.
- RGB LED (Common Anode) Typical Circuit:-

- Atmega328p Microcontroller Pinout:-

- HT7533A-1 3.3V LDO:-

As you can see all the components from regulator to the microcontroller and sensor consume low power. Atmega328p was used due to the ease of programming via the Arduino IDE and also you can program it to consume extremely low power.

I have also added battery monitoring feature if the battery level falls below 20% our rgb led will go through yellow, cyan and purple colour when you start your device to notify you that the battery is low.

Maxim has a nice video tutorial on this thermo 6 click board:-
https://www.maximintegrated.com/en/products/analog/sensors-and-sensor-interface/MAX31875.html
Now they have made a tutorial using their microcontroller programmed via mbed so i searched the repository and got the following code which was edited to work with Arduino boards:-
https://os.mbed.com/teams/MaximIntegrated/code/MAX31875_demo/file/bc0f96339b73/main.cpp/
Video
Let's see your project in action! Paste the YouTube link here and it will automatically be embedded.
Working Demo Video of the prototype:-
Schematics

Source Code
Arduino MAX31875 Interfacing
Code (Text):
- [/FONT]
- /*
- * This Arduino code reads the temperature values from
- * Thermo 6 MAX31875 click board and prints it serially at 9600 baud rate
- */
- #include <Wire.h>
- #define SERIAL_BAUD 9600
- #define TEMP_ADDRESS 0x48
- #define TEMP_REG 0x00
- #define CONFIG_REG 0x01
- void configTemp(void)
- {
- //creates an array to store the values to be written to the configuration register
- //values chosen will program the MAX31875 for 8 conversions/second and 12-bit resolution
- char data[3] = {CONFIG_REG, 0x00, 0x66};
- Wire.beginTransmission(TEMP_ADDRESS);
- Wire.write(data[0]);
- Wire.write(data[1]);
- Wire.write(data[2]);
- Wire.endTransmission();
- }
- int readTemp(void)
- {
- int temp_raw = 0;
- char data[2] = {TEMP_REG, 0};
- //the first I2C command sets the MAX31875 to point to the temperature register
- Wire.beginTransmission(TEMP_ADDRESS);
- Wire.write(data[0]);
- Wire.write(data[1]);
- Wire.endTransmission();
- //wait for temperature readings to happen
- delay(100);
- //request temperature reading from sensor
- Wire.requestFrom(TEMP_ADDRESS, 2);
- //receive temperature reading from sensor
- if (2 <= Wire.available()) { // if two bytes were received
- temp_raw = Wire.read(); // receive high byte (overwrites previous reading)
- temp_raw = temp_raw << 8; // shift high byte to be high 8 bits
- temp_raw |= Wire.read(); // receive low byte as lower 8 bits
- //Serial.println(temp_raw); // print the reading
- }
- //returns the 16-bit raw temperature reading
- return temp_raw;
- }
- void setup() {
- Wire.begin();
- Serial.begin(SERIAL_BAUD);
- Serial.println("MAX31875 Interfacing Code");
- //write the configuration register
- configTemp();
- }
- void loop() {
- /*
- //This if uncommented will let you know about all the I2C devices connected on the Arduino
- //Also the address of the devices
- Serial.println("I2C Scanner");
- byte error, address;
- int nDevices;
- Serial.println("Scanning...");
- nDevices = 0;
- for (address = 1; address < 127; address++)
- {
- // The i2c scanner uses the return value of the Write.endTransmisstion to see if a device did acknowledge to the address.
- Wire.beginTransmission(address);
- error = Wire.endTransmission();
- if (error == 0)
- {
- Serial.print("I2C device found at address 0x");
- if (address < 16) {
- Serial.print("0");
- }
- Serial.print(address, HEX);
- Serial.println(" !");
- nDevices++;
- }
- else if (error == 4)
- {
- Serial.print("Unknown error at address 0x");
- if (address < 16) {
- Serial.print("0");
- }
- Serial.println(address, HEX);
- }
- }
- if (nDevices == 0) {
- Serial.println("No I2C devices found\n");
- }
- else {
- Serial.println("Done.\n");
- }
- */
- int temperature_raw;
- float temperature_C;
- temperature_raw = readTemp();
- Serial.print("Temperature in raw:- ");
- Serial.println(temperature_raw);
- if(temperature_raw != 0)
- {
- temperature_C = temperature_raw/256.0;
- Serial.print("Temperature in Celsius:- ");
- Serial.println(temperature_C);
- }
- else {
- Serial.println("Temp Read Error ");
- }
- delay(2500); //2500 milliseconds delay
- }
- [FONT=Georgia]
Main Code with all the electronic components
Code (Text):
- [/FONT]
- #include <Wire.h>
- /*
- * Serial baud rate for debugging program using Serial Monitor
- */
- #define SERIAL_BAUD 9600
- #define Red_Pin 11
- #define Green_Pin 10
- #define Blue_Pin 9
- //comment this line if using a Common Cathode LED
- #define COMMON_ANODE
- //Optimum Temperature For Hot Beverages (Changes from person to person)
- const int hot_max = 80; //in celsius above this can cause significant scald burns.
- const int hot_min = 60; //in celsius below this it will be luke warm not good to drink
- //Optimum Temperature For Cold Beverages (Changes from person to person)
- const int cold_max = 12; //in celsius above this drink will not seem cold enough to enjoy
- const int cold_min = 3; //in celsius below this it will be too cold
- #define voltSensePin A0
- uint16_t minVolt = 3399 + 100;
- uint16_t maxVolt = 9000;
- float dividerRatio = 3.404858;
- byte batLevel = 0;
- /*
- * MAX31875 Temperature Sensor I2C address
- */
- #define TEMP_ADDRESS 0x48
- /*
- * Address of Temperature Register
- * The temperature data format is 16 bits,
- * two’s complement,
- * and
- * the register is read out in 2 bytes: an upper byte and a lower byte.
- *
- */
- #define TEMP_REG 0x00
- /*
- * Address of Configuration Register
- * Configuration register contains 16 bits of data
- * and
- * initiates single conversions (1-shot),
- * enables bus timeout, controls shutdown, sets the data format,
- * and
- * selects the automatic conversion rate.
- */
- #define CONFIG_REG 0x01
- float temperature_C;
- float room_temp;
- void configTemp(void)
- {
- /*
- * Default Power-On Reset (POR) Configuration of Configuration Register
- * 0x0040 means -
- * Normal data format
- * 0.25 conversions per second
- * Timeout enabled
- * 10-bit (0.25°C) resolution
- */
- /*
- * For our work here we are setting following Configuration of Configuration Register
- * 0x0066 means -
- * Normal data format
- * 8 conversions per second
- * Timeout enabled
- * 12-bit (0.0625°C) resolution
- */
- char data[3] = {CONFIG_REG, 0x00, 0x66};
- Wire.beginTransmission(TEMP_ADDRESS);
- Wire.write(data[0]); //Configuration Register Address
- Wire.write(data[1]); //Data High
- Wire.write(data[2]); //Data Low
- Wire.endTransmission();
- }
- uint16_t readTemp(void)
- {
- uint16_t temp_raw = 0;
- char data[2] = {TEMP_REG, 0};
- //the first I2C command sets the MAX31875 to point to the temperature register
- Wire.beginTransmission(TEMP_ADDRESS);
- Wire.write(data[0]);
- Wire.write(data[1]);
- Wire.endTransmission();
- //wait for temperature readings to happen
- delay(100);
- //request temperature reading from sensor
- Wire.requestFrom(TEMP_ADDRESS, 2);
- //receive temperature reading from sensor
- if (2 <= Wire.available())
- {
- // Check if two bytes were received
- temp_raw = Wire.read(); // receive high byte (overwrites previous reading)
- temp_raw = temp_raw << 8; // shift high byte to be high 8 bits
- temp_raw |= Wire.read(); // receive low byte as lower 8 bits
- //Serial.println(temp_raw); // print the reading
- }
- //returns the 16-bit raw temperature reading
- return temp_raw;
- }
- void setRGBColor(int redValue, int greenValue, int blueValue)
- {
- #ifdef COMMON_ANODE
- redValue = 255 - redValue;
- greenValue = 255 - greenValue;
- blueValue = 255 - blueValue;
- #endif
- analogWrite(Red_Pin, redValue);
- analogWrite(Green_Pin, greenValue);
- analogWrite(Blue_Pin, blueValue);
- }
- void batteryLevelMeasure(){
- long sensorValue = analogRead(voltSensePin);
- delay(50);
- sensorValue = 0;
- for (int i=0; i<10; i++)
- {
- sensorValue = sensorValue + analogRead(voltSensePin);
- delay(50);
- }
- sensorValue = sensorValue/10;
- //Serial.print("Raw Analog Value at A0:- ");
- //Serial.println(sensorValue);
- float batVolt = sensorValue * (3.3 /1024);
- batVolt = batVolt * 1000; //in milli volts
- //Serial.print("Battery Voltage at A0:- ");
- //Serial.println(batVolt);
- batVolt = batVolt * dividerRatio;
- uint16_t batRead = batVolt;
- Serial.print("Battery Voltage:- ");
- Serial.println(batVolt);
- if (batRead <= minVolt)
- {
- batLevel = 0;
- }
- else if (batRead >= maxVolt) {
- batLevel = 100;
- }
- else {
- long data = batRead - minVolt;
- data = data * 100;
- data = data / (maxVolt-minVolt) ;
- batLevel = data;
- }
- Serial.print("BL,");
- Serial.println(batLevel);
- }
- void setup() {
- pinMode(Red_Pin, OUTPUT);
- pinMode(Green_Pin, OUTPUT);
- pinMode(Blue_Pin, OUTPUT);
- Wire.begin(); //For ESP8266 Default I2C pins:- GPIO pins 4(SDA) and 5(SCL).
- Serial.begin(SERIAL_BAUD);
- Serial.println("");
- Serial.println("Smart Coaster");
- //write the configuration register
- configTemp();
- delay(100);
- uint16_t temperature_raw = readTemp();
- if(temperature_raw != 0)
- {
- room_temp = temperature_raw/256.0;
- Serial.print("Room Temperature in Celsius:- ");
- Serial.println(room_temp);
- }
- Serial.print("Between ");
- Serial.print(hot_min);
- Serial.print(" degree celsius & ");
- Serial.print(hot_max);
- Serial.print(" degree celsius ");
- Serial.print("temperature is the ");
- Serial.println("Optimum Hot Temperature to Drink");
- Serial.print("Greater than ");
- Serial.print(hot_max);
- Serial.print(" degree celsius ");
- Serial.print("temperature is ");
- Serial.println("Too Hot Temperature to Drink");
- Serial.print("Less than ");
- Serial.print(hot_min);
- Serial.print(" degree celsius ");
- Serial.print("temperature is ");
- Serial.println("Luke warm to Drink will not taste that great");
- setRGBColor(255, 0, 0); // Red Color
- delay(100);
- setRGBColor(0, 255, 0); // Green Color
- delay(100);
- setRGBColor(0, 0, 255); // Blue Color
- delay(100);
- setRGBColor(255, 255, 255); // White Color
- delay(500);
- batteryLevelMeasure();
- if (batLevel < 20)
- {
- setRGBColor(255, 255, 0); // yellow (turn red and green on)
- delay(100);
- setRGBColor(0, 255, 255); // Cyan (turn green and blue on)
- delay(100);
- setRGBColor(255, 0, 255); // Purple (turn red and blue on)
- delay(100);
- }
- setRGBColor(0, 0, 0); // turn off the rgb led
- delay(500);
- }
- void setRGBHot(float temp)
- {
- if (temp <= hot_max && temp >= hot_min)
- {
- setRGBColor(0, 255, 0); //Green Colour - Optimum Hot Temperature to Drink
- Serial.println("Optimum Hot Temperature to Drink");
- }
- else if (temp > hot_max)
- {
- setRGBColor(255, 0, 0); // Red Color - Too Hot Temperature to Drink
- Serial.println("Too Hot Temperature to Drink");
- }
- else if (temp < hot_min)
- {
- setRGBColor(0, 0, 255); //Blue Colour - Luke warm to Drink will not taste great
- Serial.println("Luke warm to Drink will not taste great");
- }
- }
- void setRGBCold(float temp)
- {
- if (temp <= cold_max && temp >= cold_min)
- {
- setRGBColor(0, 255, 0); //Green Colour - Optimum Cold Temperature to Drink
- Serial.println("Optimum Cold Temperature to Drink");
- }
- else if (temp > cold_max)
- {
- setRGBColor(255, 0, 0); // Red Color - Too Hot Temperature to Drink
- Serial.println("Cold Drink will not taste great");
- }
- else if (temp < cold_min)
- {
- setRGBColor(0, 0, 255); //Blue Colour - Luke warm to Drink will not taste great
- Serial.println("Too Cold Temperature to Drink");
- }
- }
- long previousMillis = 0; // will store last time temperature was checked and RGB LED was updated
- long intervalTime = 5000; // interval at which temperature was checked (milliseconds)
- void loop()
- {
- unsigned long currentMillis = millis();
- if(currentMillis - previousMillis >= intervalTime)
- {
- Serial.println("");
- //Serial.print("Temperature in raw:- ");
- uint16_t temperature_raw = readTemp();
- //Serial.println(temperature_raw);
- if(temperature_raw != 0)
- {
- temperature_C = temperature_raw/256.0;
- Serial.print("Temperature in Celsius:- ");
- Serial.println(temperature_C);
- Serial.print("Hot Beverage:- ");
- setRGBHot(temperature_C);
- }
- else {
- Serial.println("Temp Read Error ");
- }
- // save the last time you checked the temperture and updated the RGB LED
- previousMillis = currentMillis;
- }
- }[/FONT]
- [FONT=Georgia]
- [FONT=Georgia]
I haven't made the 3d case yet but as soon as it gets designed and printed i will upload it.