Hi everyone,
I have a problem with a incubator project I've been working on. It has automatic egg turning (motor from a microwave), PID logic for heating and a fan (from a microwave), which is always on. The "schematic" for the AC part is:
I have also a lcd screen (16x2) displaying temperature, humidity level and day of incubation. Sometimes the lcd start displaying random numbers, and if I reset Arduino Uno everything goes back to normal except the day counter that gives something like "Day : 30581". The egg turner keeps working fine even with this problem. My guess is that I'd need a snubber circuit because when I disconnect the fan, the lcd shows "Day : -25401" (or something similar) for a moment. In the past sometimes the lcd completly froze, and the Arduino with it, but it was due to a faulty cable of the screen (don't know how that could happen).
The full code is:
#include <DS1302RTC.h>
#include <TimeLib.h>
#include <DallasTemperature.h>
#include <EEPROM.h>
#include <PID_v1.h>
#include <Wire.h>
#include <OneWire.h>
#include <LiquidCrystal_I2C.h>
#define pinData 7 // Temperature sensor Pin
#define SSR 6 // Pin that triggers the Solid State Relay for the heating element
#define cycletime 1000
DS1302RTC RTC( 2, 3, 4 );
unsigned long t_0; //time at the beginning of the incubation (UNIX time)
unsigned long t_1; //time at the latest egg tuning
unsigned long t_2; //current time
unsigned long t_turner; //time between egg turnings
int Position = 0; //
int Day = 0; //day
LiquidCrystal_I2C led(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
double Setpoint, Input, Output; // Define Variables
double Kp = 130, Ki = 3, Kd = 0; // PID parameters
float temperature = 0;
float t_WB = 0; //wet bulb temperature
int humid; // relative humidity
unsigned long LastTemperatureResponse = 0;
unsigned long lastPIDCalculation = 0;
float prevTemperature = -9999.0;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
OneWire ourWire(pinData);
DallasTemperature sensors(&ourWire);
// Addresses of 2 DS18B20s
uint8_t sensor_temp[8] = {0x28, 0xC8, 0xE3, 0x79, 0x97, 0x21, 0x03, 0x3A };
uint8_t sensor_um[8] = { 0x28, 0xF0, 0x44, 0x94, 0x97, 0x06, 0x03, 0x6F };
void setup()
{
Setpoint = 37.7; // initialize the variables we're linked to
myPID.SetOutputLimits(0, cycletime);
myPID.SetSampleTime(cycletime);
myPID.SetMode(AUTOMATIC);
Serial.begin(115200);
pinMode(SSR, OUTPUT);
digitalWrite(SSR, LOW);
sensors.begin(); // initialize sensors
t_0 = 1632378000;
//t_1 = t_0; //uncomment, load sketch, comment, reload sketch
RTC.haltRTC(false);
RTC.writeEN(false);
EEPROM.put(0, t_0);
EEPROM.get(35, t_1);
t_turner = 21600; // turn every six hours
tmElements_t tm;
tm.Hour = 9; // set the tm structure
tm.Minute = 21;
tm.Second = 30;
tm.Day = 23;
tm.Month = 9;
tm.Year = 2021 - 1970; // tmElements_t.Year is the offset from 1970.
// RTC.write(tm); // set the RTC from the tm structure
led.clear();
// Set the clock to run-mode, and disable the write protection
// Setup LCD to 16x2 characters
led.begin(16, 2);
pinMode(8, INPUT); //limit switch 1
pinMode(9, INPUT); //limit switch 2
pinMode(12, OUTPUT); //motor
digitalWrite(12, HIGH);
}
void loop()
{
t_2 = RTC.get();
//turner();
humidity();
day_counter();
lcd();
if (millis() - LastTemperatureResponse >= cycletime) {
temperature = sensors.getTempC(sensor_temp);
Input = (double)temperature;
myPID.Compute();
lastPIDCalculation = millis();
Serial.print(temperature);
Serial.print(" , ");
Serial.print(Output / 50);
Serial.print(" , ");
Serial.print(humid);
Serial.print(" , ");
Serial.print(t_1);
Serial.print(" , ");
Serial.print(t_0);
Serial.print(" , ");
Serial.print(t_2-t_1);
Serial.print(" , ");
Serial.print(t_2);
Serial.print(" , ");
Serial.print(t_2 - t_0);
//Serial.print(" , ");
//Serial.print(now());
Serial.println();
sensors.requestTemperatures();
LastTemperatureResponse = millis();
}
control();
}
void control() {
if ((millis() <= (lastPIDCalculation + Output)) || (Output == cycletime)) {
// Power on:
digitalWrite(SSR, HIGH);
} else {
// Power off:
digitalWrite(SSR, LOW);
}
// delay(10);
}
void lcd() {
led.setCursor(0, 0);
led.print("T: ");
led.print(temperature);
led.print(" RH: ");
led.print(humid);
led.print(" ");
led.setCursor(0, 1);
led.print("Day: ");
led.print(Day);
led.print(" ");
}
void turner() {
switch (Position) {
case 0:
if (t_2 - t_1>= t_turner ) {
digitalWrite(12, LOW); //turner motor
if (digitalRead(8) == LOW && digitalRead(9) == HIGH) { //limit switches check
Position = 1;
} else {
Position = 2;
}
}
break;
case 1:
if (digitalRead(9) == LOW) {
digitalWrite(12, HIGH);
Position = 0;
t_1=t_2;
EEPROM.put(35, t_1);
}
break;
case 2:
if (digitalRead(8) == LOW) {
digitalWrite(12, HIGH);
Position = 0;
t_1=t_2;
EEPROM.put(35, t_1);
}
break;
}
}
void humidity() {
t_WB = sensors.getTempC(sensor_um);
humid = (t_WB / temperature - 0.45) * 170.5;
}
void day_counter() {
Day=((t_2-t_0)/60/60/24)+1; //day
}
Do you have an idea of why I have this problem? The day counter loop is in the very last line of code. Let me know if you need additional info/schematics. Thank you