218 lines
5.0 KiB
C++
218 lines
5.0 KiB
C++
#include <LiquidCrystal_I2C.h>
|
|
#include <SoftwareSerial.h>
|
|
//temp sensor
|
|
#include <OneWire.h>
|
|
#include <DallasTemperature.h>
|
|
|
|
LiquidCrystal_I2C lcd(0x3F, 20, 4); //https://github.com/marcoschwartz/LiquidCrystal_I2C
|
|
|
|
OneWire oneWire(4); //OneWire Library (with Tim Stud)
|
|
DallasTemperature tsensor(&oneWire); //DallasTempratureSensor Library
|
|
SoftwareSerial wlan(6, 5); //RX, TX
|
|
|
|
long lastLCDupdate = millis();
|
|
boolean lcdchanged = true;
|
|
int temp = 0;
|
|
byte cancelcause = 0; //why is the heater off? -> 0= None, 1 = canceled (btn), 2= temp, 3=to long on, 4=tempmovement, 5=abort(inet)
|
|
long heating = -1;//millis() value when heater started
|
|
int starttemp = 0;
|
|
char status[21] = "--------------------";//dont forget \0 at the end
|
|
const byte padd = 6;//used in updateLCD(), used to determine how far left the right part of the screen should be
|
|
|
|
void setup() {
|
|
pinMode(2, OUTPUT);
|
|
pinMode(3, INPUT_PULLUP);
|
|
|
|
digitalWrite(2, LOW);
|
|
|
|
lcd.init(); // initialize the lcd
|
|
// Print a message to the LCD.
|
|
lcd.backlight();
|
|
lcd.setCursor(6, 0);
|
|
lcd.print("Autokocher");
|
|
lcd.setCursor(3, 1);
|
|
lcd.print("Yannis Gerlach");
|
|
|
|
delay(1000);
|
|
tsensor.begin();
|
|
|
|
Serial.begin(115200);//DEBUG
|
|
wlan.begin(9600);
|
|
|
|
updateLCD();
|
|
}
|
|
|
|
int getTemp() {
|
|
tsensor.requestTemperatures();
|
|
return (tsensor.getTempCByIndex(0) * 100);
|
|
}
|
|
|
|
void updateLCD() {
|
|
if (lcdchanged || heating > 0) {
|
|
lcd.clear();
|
|
lcd.clear();
|
|
lcd.backlight();
|
|
lcd.setCursor(0, 0);
|
|
lcd.print("Herd:");
|
|
lcd.setCursor(padd, 0);
|
|
lcd.print(heating > 0 ? "An" : "Aus");
|
|
lcd.setCursor(0, 1);
|
|
lcd.print("Temp:");
|
|
lcd.setCursor(padd, 1);
|
|
lcd.print(temp);
|
|
lcd.print("C");
|
|
lcd.setCursor(0, 2);
|
|
if (cancelcause != 0) {
|
|
lcd.print("Err :");
|
|
lcd.setCursor(padd, 2);
|
|
switch (cancelcause) {
|
|
case 1: lcd.print("Abbr-Btn."); break;
|
|
case 2: lcd.print("Tempzuhoch"); break;
|
|
case 3: lcd.print("Zeit"); break;
|
|
case 4: lcd.print("TempSensor"); break;
|
|
case 5: lcd.print("Abbr-INet."); break;
|
|
default: lcd.print("undef.");
|
|
}
|
|
} else if (heating > 0) {
|
|
lcd.print("An :");
|
|
lcd.setCursor(padd, 2);
|
|
lcd.print((millis() - heating) / 1000);
|
|
lcd.print("s");
|
|
}
|
|
|
|
lcd.setCursor(0, 3);
|
|
lcd.print(status);
|
|
lastLCDupdate = millis();
|
|
lcdchanged = false;
|
|
} else if (millis() - lastLCDupdate > 10000) {
|
|
lcd.noBacklight();
|
|
}
|
|
}
|
|
|
|
void sendStatus() {
|
|
wlan.print('r');//msg type
|
|
wlan.print(heating);//heater status
|
|
wlan.print('.');//delimiter
|
|
wlan.print(cancelcause);//error?
|
|
wlan.print('.');//delimiter
|
|
wlan.print(temp);//temp
|
|
wlan.print('\0');//EOT
|
|
}
|
|
|
|
//handle the conenction to the esp
|
|
void handleWLAN() {
|
|
if (status[0] == '-' || status[0] == ' ') { //TODO: this line does not work as intended???
|
|
/*Serial.print("requeststatus: ");
|
|
Serial.print(status[0]);
|
|
Serial.print(status[1]);
|
|
Serial.print(status[2]);
|
|
Serial.print(" ");
|
|
Serial.println(status);*/
|
|
wlan.write('s');
|
|
wlan.flush();
|
|
}
|
|
|
|
if (wlan.available()) {
|
|
char first = wlan.read();
|
|
if (first == 's') {
|
|
//status update
|
|
bool ava = true;
|
|
for (unsigned char i = 0; i < 20; i++) {
|
|
char old = status[i];
|
|
char new_ = ' ';
|
|
if (wlan.available() && ava) {
|
|
new_ = wlan.read();
|
|
Serial.print(new_);
|
|
Serial.print(new_, DEC);
|
|
Serial.println(new_, HEX);
|
|
if (new_ == '\0') {
|
|
ava = false;
|
|
new_ = ' ';
|
|
}
|
|
}
|
|
|
|
if (old != new_) {
|
|
lcdchanged = true;
|
|
status[i] = new_;
|
|
}
|
|
}
|
|
|
|
//status[2] = (rand()%10)+'a';//DEBUG
|
|
} else if (first == 'r') { //report
|
|
sendStatus();
|
|
} else if (first == 'a') { //abort!
|
|
setheater(false);
|
|
wlan.print('a');
|
|
} else if (first == 'g') { //go
|
|
if (heating < 0) { //heater off?
|
|
setheater(true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//security checks
|
|
void checkHeater() {
|
|
if (temp > 105) { //overtemp
|
|
cancelcause = 2;
|
|
setheater(false);
|
|
}
|
|
|
|
if (millis() - heating > 600000) { //longer than 10min on
|
|
cancelcause = 3;
|
|
setheater(false);
|
|
}
|
|
|
|
if (millis() - heating > 60000 && starttemp >= temp - 1) { //on for 60s and no temp did not change
|
|
cancelcause = 4;
|
|
setheater(false);
|
|
}
|
|
}
|
|
|
|
bool presed = false;
|
|
void loop() {
|
|
delay(25);
|
|
|
|
handleWLAN();
|
|
|
|
{
|
|
int old = temp;
|
|
temp = getTemp() / 100;
|
|
/* if(old != temp)
|
|
lcdchanged = true;*/
|
|
}
|
|
|
|
if ((millis() - lastLCDupdate) > 500) { //reprint LCD every 1/2 seconds
|
|
updateLCD();
|
|
}
|
|
|
|
//button pressed
|
|
if (digitalRead(3) == LOW) {
|
|
if (!presed) {
|
|
presed = true;
|
|
//toggle
|
|
if (heating > 0) {
|
|
cancelcause = 1;
|
|
}
|
|
setheater(heating < 0);//toggle heater
|
|
updateLCD();
|
|
}
|
|
} else {
|
|
presed = false;
|
|
}
|
|
|
|
if (heating > 0)
|
|
checkHeater();
|
|
}
|
|
|
|
void setheater(bool on) {
|
|
heating = on ? millis() : -1;
|
|
if (on) {
|
|
cancelcause = 0;
|
|
starttemp = temp;
|
|
}
|
|
digitalWrite(2, on);
|
|
digitalWrite(13, on);
|
|
lcdchanged = true;
|
|
}
|