近期想diy一个双路温度计,上网翻到一篇老外的帖子,大致内容如下
基于esp8266 +max31855+blynk,详细代码如下:
//heat and food temp monitor
//MAX31855 (2 pieces)
//Blynk
//Piezo alarm - TBC
//OLED display
//OTA update = http://192.168.0.5/update
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <ESP8266HTTPUpdateServer.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <Wire.h>
#include <MAX31855.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <TimeLib.h>
#include <WidgetRTC.h>
#include "RunningMedian.h"
#define debug 1 // turns debugging serial prints on/off.
#define BLYNK_PRINT Serial //this is the debugging for Blynk
#define MISO 12 //data/"signal out"
#define SCK 13 // clock
#define heatCS 14 //chip select
#define foodCS 16 //chip select
#define piezoBuzzer 2 // pin for piezo buzzer, is ALSO the internal ESP8266 blue LED...
// NB - pins 4 & 5 are SDA & SCL for OLED on ESP8266
#define OLED_RESET 3 //CAREFUL OF CHANGING THIS PIN ASSIGNMENT!!!!!!!!! (try to remove it later on...)
#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH 16
static const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
B00000001, B11000000,
B00000001, B11000000,
B00000011, B11100000,
B11110011, B11100000,
B11111110, B11111000,
B01111110, B11111111,
B00110011, B10011111,
B00011111, B11111100,
B00001101, B01110000,
B00011011, B10100000,
B00111111, B11100000,
B00111111, B11110000,
B01111100, B11110000,
B01110000, B01110000,
B00000000, B00110000
};
Adafruit_SSD1306 display(OLED_RESET);
MAX31855 foodProbe = MAX31855(MISO, foodCS, SCK);
MAX31855 heatProbe = MAX31855(MISO, heatCS, SCK);
RunningMedian samplesFoodTemperature = RunningMedian(20); //this takes XX samples
RunningMedian samplesHeatTemperature = RunningMedian(20); //this takes XX samples
WidgetRTC rtc;
WiFiClient client;
ESP8266WebServer httpServer(80);
ESP8266HTTPUpdateServer httpUpdater;
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);
SimpleTimer timer;
const char* host = "esp8266_DUAL_MAX31855"; // will be "esp8266_XYZ.local/update" in web browser
const char* ssid = "abc";
const char* password = "123";
char authBlynk[] = "Costas_rulez";
int startHeat, heatTime, startHeatTime, heatTimerTimer;
int startFood, foodTime, startFoodTime, foodTimerTimer;
int heatTemperature, foodTemperature;
int medianHeatTemperature, medianFoodTemperature;
int heatTemperatureMax = 0;
int foodTemperatureMax = 0;
int displayFreq = 2000L; // sets display update frequency
int displayTimer2, displayTimer3; //timers to call display update functions
int tempChangeFreq = 120L * 1000L; //time period to check temp changes
int tempChangeTimer; //name of timer to call temp change calculation function
int previousHeatTemperature, previousFoodTemperature; // to track temp changes over time
int oldPreviousHeatTemperature, oldPreviousFoodTemperature;
int newHeatTemperature, newFoodTemperature;
int heatTempChangePercent, foodTempChangePercent; //the variables produced from the calculation
int foodWarningTemp, heatWarningTemp; //temp that the notify is set to go off at
int heatWarningOffset = 12; //this is how much below the full warning temp the "pre" warning temp is.
int foodWarningOffset = 4; //this is how much below the full warning temp the "pre" warning temp is.
int food_h, food_m, food_s; //used for the food timer
int heat_h, heat_m, heat_s; //used for the heat timer
int setMode; //this is for the Blynk menu widget with a few commands in it, like reset temps and changing the warning parameters...
unsigned long notifyPeriodHeat = 0;
const long notifyTimeHeat = 60L * 1000L; //means its XX seconds between Heat notifications
unsigned long notifyPeriodFood = 0;
const long notifyTimeFood = 60L * 1000L; //means its XX seconds between Food notifications
unsigned long tempChangePeriodFood = 0;
const long tempChangeTimeFood = 15L * 1000L; //means its XX seconds between Food calcs
unsigned long tempChangePeriodHeat = 0;
const long tempChangeTimeHeat = 15L * 1000L; //means its XX seconds between Heat calcs
BLYNK_WRITE(V1) // start heat timer button
{
startHeat = param.asInt();
if (startHeat == 1)
{
startHeatTime = now();
heatTimer();
}
}
void heatTimer()
{
heatTimerTimer = timer.setTimeout(20L * 1000L, heatTimer);// timing counts every XX seconds
if (startHeat == 1)
{
heat_s = (now() - startHeatTime);
heat_m = heat_s / 60;
heat_h = heat_s / 3600;
heat_s = heat_s - heat_m * 60;
heat_m = heat_m - heat_h * 60;
Blynk.virtualWrite(V5, heat_h, "h ", heat_m, "m");
}
}
BLYNK_WRITE(V2) // start food timer button
{
startFood = param.asInt();
if (startFood == 1)
{
startFoodTime = now();
foodTimer();
}
}
void foodTimer()
{
foodTimerTimer = timer.setTimeout(20L * 1000L, foodTimer);// timing counts every XX seconds
if (startFood == 1)
{
food_s = (now() - startFoodTime);
food_m = food_s / 60L;
food_h = food_s / 3600L;
food_s = food_s - food_m * 60L;
food_m = food_m - food_h * 60L;
Blynk.virtualWrite(V6, food_h, "h ", food_m, "m");
}
}
BLYNK_WRITE(V10) // food warning stepper
{
foodWarningTemp = param.asInt();
Blynk.virtualWrite(V4, foodWarningTemp, "'C");
}
BLYNK_WRITE(V9) // heat warning stepper
{
heatWarningTemp = param.asInt();
Blynk.virtualWrite(V3, heatWarningTemp, "'C");
}
BLYNK_WRITE(V0) // mode selection drop down menu
{
setMode = param.asInt();
{
if (setMode == 1) // reset max temps
{
foodTemperatureMax = 0;
heatTemperatureMax = 0;
Blynk.virtualWrite(V7, 0);
Blynk.virtualWrite(V8, 0);
}
else if (setMode == 2) // heat pre-warning offset up
{
heatWarningOffset = heatWarningOffset + 1;
Blynk.virtualWrite(V13, heatWarningOffset, "'C");
}
else if (setMode == 3) // heat pre-warning offset dwn
{
heatWarningOffset = heatWarningOffset - 1;
Blynk.virtualWrite(V13, heatWarningOffset, "'C");
}
else if (setMode == 4) // food pre-warning offset up
{
foodWarningOffset = foodWarningOffset + 1;
Blynk.virtualWrite(V14, foodWarningOffset, "'C");
}
else if (setMode == 5) // food pre-warning offset dwn
{
foodWarningOffset = foodWarningOffset - 1;
Blynk.virtualWrite(V14, foodWarningOffset, "'C");
}
else if (setMode == 6) // spare
{
///TBA
}
}
}
void readMAX31855HeatProbe()
{
heatTemperature = heatProbe.readThermocouple(CELSIUS);
Blynk.virtualWrite(V15, heatTemperature, "'C");
switch ((int) heatTemperature)
{
case FAULT_OPEN:
Serial.println("heatprobe: FAULT_OPEN");
break;
case FAULT_SHORT_GND:
Serial.println("heatprobe: FAULT_SHORT_GND");
break;
case FAULT_SHORT_VCC:
Serial.println("heatprobe: FAULT_SHORT_VCC");
break;
case NO_MAX31855:
Serial.println("heatprobe: NO_MAX31855");
break;
default:
Serial.print("heatprobe: ");
Serial.println(heatTemperature);
break;
}
medianHeatTemperature = samplesHeatTemperature.getMedian();
samplesHeatTemperature.add(heatTemperature);
if ((medianHeatTemperature < 888) && (heatTemperatureMax >= medianHeatTemperature))
{
Blynk.virtualWrite(V11, medianHeatTemperature);
}
else if ((medianHeatTemperature < 888) && (heatTemperatureMax < medianHeatTemperature))
{
Blynk.virtualWrite(V11, medianHeatTemperature);
heatTemperatureMax = medianHeatTemperature;
Blynk.virtualWrite(V7, heatTemperatureMax, "'C");
}
else if (medianHeatTemperature > 888)
{
Blynk.virtualWrite(V11, 999);
}
readMAX31855FoodProbe();
}
void readMAX31855FoodProbe()
{
foodTemperature = foodProbe.readThermocouple(CELSIUS);
Blynk.virtualWrite(V16, foodTemperature, "'C");
switch ((int) foodTemperature)
{
case FAULT_OPEN:
Serial.println("foodprobe: FAULT_OPEN");
break;
case FAULT_SHORT_GND:
Serial.println("foodprobe: FAULT_SHORT_GND");
break;
case FAULT_SHORT_VCC:
Serial.println("foodprobe: FAULT_SHORT_VCC");
break;
case NO_MAX31855:
Serial.println("foodprobe: NO_MAX31855");
break;
default:
Serial.print("foodprobe: ");
Serial.println(foodTemperature);
break;
}
medianFoodTemperature = samplesFoodTemperature.getMedian();
samplesFoodTemperature.add(foodTemperature);
if ((medianFoodTemperature < 888) && (foodTemperatureMax >= medianFoodTemperature))
{
Blynk.virtualWrite(V12, medianFoodTemperature);
}
else if ((medianFoodTemperature < 888) && (foodTemperatureMax < medianFoodTemperature))
{
Blynk.virtualWrite(V12, medianFoodTemperature);
foodTemperatureMax = medianFoodTemperature;
Blynk.virtualWrite(V8, foodTemperatureMax, "'C");
}
else if (medianFoodTemperature > 888)
{
Blynk.virtualWrite(V12, 999);
}
checkHeatTemp();
}
void checkHeatTemp()
{
unsigned long currentMillis = millis();
if ((medianHeatTemperature < heatWarningTemp) && ((medianHeatTemperature + heatWarningOffset) > heatWarningTemp))
{
if (((currentMillis - notifyPeriodHeat) > notifyTimeHeat) && (medianHeatTemperature < 888))
{
Blynk.notify(String("Heat temp APPROACHING warning temp: ") + medianHeatTemperature + ("'C - go check it..."));
notifyPeriodHeat = currentMillis;
}
}
else if (medianHeatTemperature >= heatWarningTemp)
{
if (((currentMillis - notifyPeriodHeat) > notifyTimeHeat) && (medianHeatTemperature < 888))
{
Blynk.notify(String("Heat temp getting TOOOO HIGHHH: ") + medianHeatTemperature + ("'C - go check it!!!"));
notifyPeriodHeat = currentMillis;
}
//runAlarmFunction();
}
Blynk.virtualWrite(V13, "-", heatWarningOffset, "'C");
checkFoodTemp();
}
void checkFoodTemp()
{
unsigned long currentMillis = millis();
if ((medianFoodTemperature < foodWarningTemp) && ((medianFoodTemperature + foodWarningOffset) > foodWarningTemp))// temp creeping up
{
if (((currentMillis - notifyPeriodFood) > notifyTimeFood) && (medianFoodTemperature < 169))
{
Blynk.notify(String("Food temp APPROACHING warning temp: ") + medianFoodTemperature + ("'C - go check it..."));
notifyPeriodFood = currentMillis;
}
}
else if (medianFoodTemperature >= foodWarningTemp)
{
if (((currentMillis - notifyPeriodFood) > notifyTimeFood) && (medianFoodTemperature < 169))
{
Blynk.notify(String("Food temp getting TOOO HIGGHHH: ") + medianFoodTemperature + ("'C - go check it!!!"));
notifyPeriodFood = currentMillis;
}
//runAlarmFunction();
}
Blynk.virtualWrite(V14, "-", foodWarningOffset, "'C");
displayUpdate1();
}
void checkTempChange()
{
previousHeatTemperature = heatTemperature;
previousFoodTemperature = foodTemperature;
timer.setTimeout(10000L, checkTempChange1);
}
void checkTempChange1()
{
oldPreviousFoodTemperature = previousFoodTemperature;
timer.setTimeout(10000L, checkTempChange2);
}
void checkTempChange2()
{
newHeatTemperature = heatTemperature;
heatTempChangePercent = (((newHeatTemperature - oldPreviousHeatTemperature) * 100) / newHeatTemperature);
Blynk.virtualWrite(V3, heatTempChangePercent, "%");
newFoodTemperature = foodTemperature;
foodTempChangePercent = (((newFoodTemperature - oldPreviousFoodTemperature) * 100) / newFoodTemperature);
Blynk.virtualWrite(V4, foodTempChangePercent, "%");
Blynk.virtualWrite(V17, oldPreviousFoodTemperature);
Blynk.virtualWrite(V18, newFoodTemperature);
}
void displayUpdate1()
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("ELAPSED HEAT TIME:");
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(32, 16);
display.print(heat_h);
display.print("h ");
display.print(heat_m);
display.println("m");
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 32);
display.println("ELAPSED COOK TIME:");
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(32, 48);
display.print(food_h);
display.print("h ");
display.print(food_m);
display.println("m");
display.display();
displayTimer2 = timer.setTimeout(displayFreq, displayUpdate2);
}
void displayUpdate2()
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("HEAT WARNING TEMP:");
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(32, 16);
display.print(heatWarningTemp);
display.print((char)247);
display.println("C");
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 32);
display.println("FOOD WARNING TEMP:");
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(32, 48);
display.print(foodWarningTemp);
display.print((char)247);
display.println("C");
display.display();
displayTimer3 = timer.setTimeout(displayFreq, displayUpdate3);
}
void displayUpdate3()
{
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("HEAT PROBE TEMP:");
if (medianHeatTemperature > 1000)
{
medianHeatTemperature = 0;
}
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(32, 16);
display.print(medianHeatTemperature);
display.print((char)247);
display.println("C");
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 32);
display.println("FOOD PROBE TEMP:");
if (medianFoodTemperature > 1000)
{
medianFoodTemperature = 0;
}
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(32, 48);
display.print(medianFoodTemperature);
display.print((char)247);
display.println("C");
display.display();
Serial.println(F("__________"));
}
void runAlarmFunction()
{ //tone(piezoBuzzer, 1000); // Send 1KHz sound signal...
//delay(1000); // ...for 1 sec
//noTone(piezoBuzzer); // Stop sound...
//delay(1000); // ...for 1sec
}
void setup()
{
Serial.begin(115200);
Serial.println(F(""));
Serial.println(F("Cooking heat & food temp MONITOR"));
Serial.print(F("File name: "));
Serial.println(__FILE__);
//Blynk.begin(authBlynk, ssid, password); // this is for roaming profile
Blynk.begin(authBlynk, ssid, password, IPAddress(192, 168, 0, 7));
ArduinoOTA.setHostname("Multi-MAX31855-Node08");
ArduinoOTA.onStart([]() {
Serial.println("Start");
});
ArduinoOTA.onEnd([]() {
Serial.println("\nEnd");
});
//ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
// Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
//});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
ArduinoOTA.begin();
Serial.println("Ready - OTA Success!!!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
MDNS.begin(host);
httpUpdater.setup(&httpServer);
httpServer.begin();
MDNS.addService("http", "tcp", 80);
String ipaddress = WiFi.localIP().toString();
String chipID = String(ESP.getChipId(), HEX);
char charChipID[10];
chipID.toCharArray(charChipID, sizeof(charChipID));
char charipaddress[16];
ipaddress.toCharArray(charipaddress, sizeof(charipaddress));
Serial.printf("Now open http://%s.local/update in your browser or \n", host);
Serial.printf("http://%s/update or http://%s.lan/update if you prefer.\n", charipaddress, charChipID);
Serial.println(F("Where's Blynk??"));
while (!Blynk.connect())
{
delay(50);
Serial.print(F(". "));
}
Serial.println(F(""));
Serial.println(F("Found some WiFi!"));
Serial.println(F("------------"));
Blynk.virtualWrite(V1, 0);
Blynk.virtualWrite(V2, 0);
Blynk.virtualWrite(V5, 0);
Blynk.virtualWrite(V6, 0);
Blynk.virtualWrite(V7, 0);
Blynk.virtualWrite(V8, 0);
Blynk.virtualWrite(V11, 0);
Blynk.virtualWrite(V12, 0);
Blynk.virtualWrite(V13, 0);
Blynk.virtualWrite(V14, 0);
bool isFirstConnect = true; // Keep this flag not to re-sync on every reconnection
BLYNK_CONNECTED(); // This function will run every time Blynk initial connection is established
{
if (isFirstConnect)
{
Blynk.syncAll();
isFirstConnect = false;
}
}
rtc.begin();
Serial.println(F("We operate under <SimpleTimer.h> now..."));
timer.setInterval(8000L, readMAX31855HeatProbe);
timer.setInterval(20L * 1000L, checkTempChange);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3_
display.display();
display.clearDisplay();
}
void loop()
{
Blynk.run(); // Initiates Blynk
timer.run(); // Initiates SimpleTimer
ArduinoOTA.handle();
httpServer.handleClient();
}
以上内容摘自www点blynk点cc 有兴趣的一起学习仿制
|