I come to ask for your help because I have a big problem on my project. I have fridges controlled by arduino leonardo. Fridge compressors must be activated if the temperature is too high. My problem is that randomly the temperature isn't read correctly and she stay fixed. The consequence is that the arduio believes that it is at the right temperature and does not send the signal to stop or activate the compressor. It's a big problem because I find my fridges at -12 or 30 ° C. I noted that when I reset Arduino with the reset button the problem is clear.
For this reason I search one software solution to reset regularly my arduino leonardo ( like to press the button).
Thank you for your answers.
Hi,
Thank you for your answers.
This is my program
/
#include <EEPROM.h>
#include <Wire.h>
#include <PID_v1.h>
#include <OneWire.h>
#include <DallasTemperature.h>
//Define Variables for the Menu
int Heater;
int recByte=0;
int startFlag=0;
int tempWriteFlag=0;
int regFlag=0;
int heaterFlag=0;
int ColdUnitState;
int AirPumpState;
//Define Variables we'll be connecting to
volatile long onTime = 0;
// Data wire is plugged into port 10 on the Arduino
#define ONE_WIRE_BUS 10
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// InputOutput
#define Relay_Heater 4
#define Relay_ColdUnit 5
#define Relay_AirPump 6
#define InPumpFromRPI 13
//Define Variables we'll be connecting to
double Setpoint, Input, Output;
//Specify the links and initial tuning parameters
double Kp=500, Ki=0.5, Kd=0.01;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
int WindowSize = 10000;
unsigned long windowStartTime;
// maximum difference between input and setpoint accepted before switching on
// or off the compressor
float threshold = 0.25f;
// Defines when next the compressor might be switched on or off
long nextUpdate = 0;
// Defines delays between compressor status modification
int updateDelay = 5000;
// Alarm (when ringing) tone management
const int maxAlarmTone = 880;
const int minAlarmTone = 440;
int alarmTone = minAlarmTone;
const int alarmSpeed = 20;
const int alarmPin = 11;
const float maxTempDiff = 2.0f;
void setup()
{
windowStartTime = millis();
//Enable the Outputpin
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(alarmPin, OUTPUT);
pinMode(13, INPUT);
//Enable the serial port
Serial.begin(9600);
//initialize the variables we're linked to from the EEPROM
Heater = EEPROM.read(1);
Setpoint = EEPROM.read(0);
//tell the PID to range between 0 and the full window size
myPID.SetOutputLimits(0, WindowSize);
//turn the PID on
myPID.SetMode(AUTOMATIC);
// Depending on how the PCM is managed by the atmega on the arduino,
// the value might need a sync - ms
sensors.setWaitForConversion(true);
}
void loop()
{
digitalWrite(Relay_Heater,Heater);// Toggle Heater
if(digitalRead(InPumpFromRPI) == 1)
{
digitalWrite(Relay_AirPump,LOW); //Disable the airExtraction.
AirPumpState=0;
}
else
{
digitalWrite(Relay_AirPump,HIGH); //Eanble the airExtraction.
AirPumpState=1;
}
// call sensors.requestTemperatures() to issue a global temperature
// request to all devices on the bus.
sensors.requestTemperatures(); // Send the command to get temperatures
// After we got the temperatures, we can print them here.
// We use the function ByIndex, and as an example get the temperature from the first sensor only.
float newInput = sensors.getTempCByIndex(0);
Serial.println(newInput); // control of newInput value
bool readErr = newInput==DEVICE_DISCONNECTED_C;
if (!readErr) {
Input = newInput;
}
//*******************************
else{
Serial.println("probleme d'actualisation");
oneWire.reset();
delay(2000);
}
//****************************
// Alarm management
if (readErr || abs(Input-Setpoint)>=maxTempDiff) {
alarmTone += alarmSpeed;
if (alarmTone>maxAlarmTone) {
alarmTone = minAlarmTone;
}
tone(alarmPin, alarmTone);
} else {
noTone(alarmPin);
}
/************************************************
* turn the output pin on/off directly based on input
************************************************/
long now = millis();
if (now>=nextUpdate) {
nextUpdate = now + updateDelay;
Serial.println(windowStartTime);
if((windowStartTime>900000) && ((Input>17)||(Input<5))// try to stop compressor and heater if temp is out of range
{
digitalWrite(Relay_ColdUnit,LOW); //disable the compresor
ColdUnitState=0;
digitalWrite(Relay_Heater,1);//disable heater
Heater=1;
Serial.println("Probleme de temperature compresseur et chauffage sont desactives");
}
else if (Input <( Setpoint - threshold)) {
digitalWrite(Relay_ColdUnit,LOW); //disable the compresor
ColdUnitState=0;
}
else if (Input > (Setpoint + threshold))
{
digitalWrite(Relay_ColdUnit,HIGH); //Enable the compresor
ColdUnitState=1;
}
}
/************************************************
* Send the information on the serial
************************************************/
Serial.print("Setpoint: ");Serial.print(Setpoint); Serial.print(" ");
Serial.print("Input: ");Serial.print(Input); Serial.print(" ");
//Serial.print("Output: ");Serial.print(Output); Serial.print(" ");
//Serial.print("kp: ");Serial.print(myPID.GetKp());Serial.print(" ");
//Serial.print("ki: ");Serial.print(myPID.GetKi());Serial.print(" ");
//Serial.print("kd: ");Serial.print(myPID.GetKd());Serial.println();
//Serial.print("ColdUnitState: ");Serial.print((onTime > (now - windowStartTime))); Serial.print(" ");
//Serial.print("OnTme: ");Serial.print(onTime); Serial.print(" ");
Serial.print("ColdUnit: ");if(ColdUnitState==1){Serial.print("On");}else{Serial.print("Off");};Serial.print(" ");
Serial.print("Heater: ");if(Heater==1){Serial.print("Off");}else{Serial.print("On");};Serial.print(" ");
Serial.print("AirPump: ");if(AirPumpState==1){Serial.print("On");}else{Serial.print("Off");};Serial.print(" ");
Serial.print("\n\r");
// Interative serial Menu:
if(Serial.available()>0){
// store received byte
recByte=Serial.read();
// Serial.println(recByte, DEC);
if(recByte=='0')
{
Serial.print("Menu started\n\r");
startFlag=1;
Serial.print("Tip:(1) Update Setpoint \n\r");
Serial.print("Tip:(2) Read Setpoint \n\r");
Serial.print("Tip:(3) Toogle Heater \n\r");
Serial.print("Tip:(4) Exit \n\r");
Serial.flush();
while(Serial.available()==0);
}
else if((recByte=='1')&&(startFlag==1))
{
tempWriteFlag=1;
}
else if((recByte=='2')&&(startFlag==1))
{
Serial.print("Temp [C°] \n\r");
Serial.print(Setpoint);
Serial.print("\n\r");
}
else if((recByte=='3')&&(startFlag==1))
{
heaterFlag=1;
}
else if((recByte=='4')&&(startFlag==1))
{
Serial.print("Exit \n\r");
}
else
{
Serial.print("Invalid!\n\r");
}
// Heater Toogle
if((startFlag==1)&&(heaterFlag==1))
{
Serial.print("typ: On(1), Off(2) \n\r");
Serial.flush();
while(Serial.available()==0);
regFlag = Serial.parseInt();
if (regFlag == 1)
{
EEPROM.write(1,0);
Serial.print("Heater Enable \n\r");
}
else if (regFlag == 2)
{
EEPROM.write(1,1);
Serial.print("Heater Disable \n\r");
}
Heater=EEPROM.read(1);
heaterFlag=0;
startFlag=0;
}
//Updat Setpoint
if((startFlag==1)&&(tempWriteFlag==1))
{
Serial.print("Update Temp ? Yes:1, No:2 \n\r");
Serial.flush();
while(Serial.available()==0);
regFlag = Serial.parseInt();
//Temp. update
if (regFlag == 1)
{
Serial.print("Typ the new val(1050 = 10,5 [C°] & 1 [C°]= 100 etc..): \n\r");
while(Serial.available()==0);
Setpoint = Serial.parseInt();
Setpoint = Setpoint/100;
EEPROM.write(0,Setpoint);
Serial.print("New Temp [C°] \n\r");
Serial.print(Setpoint);
Serial.print("\n\r");
}
else if (regFlag == 2)
{
Serial.print("Exit \n\r");
}
tempWriteFlag=0;
startFlag=0;
}
}
}
I haven't got the PID library so I can't try to compile your code. However, it doesn't auto format correctly.
The formatting goes weird after this statement:
if ((windowStartTime > 900000) && ((Input > 17) || (Input < 5)) // try to stop compressor and heater if temp is out of range