Beer Fermentation Controller Problems

Hello everybody. First time posting on this forum and new Arduino user as well. I have found an amazing amount of knowledge on this forum related to my project. However, I am experiencing an issue with my project that I can't quite figure out. My project is this:

I have a mini fridge that I have converted into a larger chamber that I wish to control the inside temperature with an Arduino. I also wish to log the temperature in a database on my LAN. The mini fridge has a start up amperage of 6.3A and running amps of 1.5. I have attached my diagram that I used in Fritzing. I am also new to Fritzing and could not find the LCD or the SSR that I am using. The parts that I am using are:

Arduino Uno with ethernet shield
Sainsmart 4-Channel Solid State Relay (link)
2x10k resistors
4.7k resistor
Dallas waterproof temp sensor
Sainsmart 20x4 lcd (link)
mini - fridge
heat element (link)

Everything works great when no load (fridge or heat element is not plugged in) is hooked up to the SSR. However, when I hook up the loads and everything is working fine, as soon as the fridge turns off my arduino freezes. It's only when the fridge shuts OFF that I have the problem. Sometimes I will get random crazy characters on the screen. Other times it will just be unresponsive.

I have tried very hard to research this problem on these forums and elsewhere to no avail. Some suggested a diode on the SSR and others a dedicated 5v power supply for the SSR. I'm unsure how to fix this problem. I don't think it is a code problem as the Arduino seems to be unresponsive only when load is attached but I will attach it anyways. I have tried moving the SSR away from the arduino as I heard on this forum that EMI could be an issue but that still doesn't fix the problem.

#include <OneWire.h>
#include <Wire.h>
#include <SPI.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
#include <Ethernet.h>
#include <Time.h>
//#include <rtc_clock.h>
#define BACKLIGHT_PIN 13
#define HEAT 6
#define COOL 7

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 2

// 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);

const int increaseButtonPin = 3;
const int decreaseButtonPin = 5;
const float differential = 1;


float currentTemp, celsius;
float setPoint = 60;
int incButtonPushCounter = 0;
int decButtonPushCounter = 0;
int increaseState = 0;
int decreaseState = 0;
int lastIncButtonState = 0;
int lastDecButtonState = 0;
int WindowSize = 2000;
static bool buttonIncPressedBefore = false;
static bool buttonDecPressedBefore = false;
int buttonIncTime = 0;
int buttonDecTime = 0;


// Ethernet Setup Stuff...
byte mac[] = { 
  0xB0, 0xDF, 0x3A, 0x84, 0xDB, 0x9C  };
//I made one up here it should be 
//listed on your ethernet shield box
//EthernetServer server(80); // place your server IP address here
// Initialize the Ethernet client library
// with the IP address and port of the server 
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;
IPAddress ip(192,168,1,18);
char state = 'I';

byte serverName[] = {
  192, 168, 1, 17}; // Database server IP




void setup(void)
{
  // start serial port
  Serial.begin(9600);
  Serial.println("Dallas Temperature IC Control Library Demo");

  // Start up the library
  sensors.begin(); 
  // IC Default 9 bit. If you have troubles consider upping it 12. Ups the delay giving the IC more time to process the temperature measurement

  pinMode(BACKLIGHT_PIN, OUTPUT);
  digitalWrite(BACKLIGHT_PIN,HIGH);
  lcd.begin(20,4);
  pinMode(HEAT,OUTPUT);
  pinMode(COOL,OUTPUT);
  pinMode(increaseButtonPin, INPUT);
  pinMode(decreaseButtonPin, INPUT);
  digitalWrite(HEAT,HIGH);
  digitalWrite(COOL,HIGH);
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);

  //Serial.print("server is at ");
  //Serial.println(Ethernet.localIP());


}



void loop(void)
{

  increaseState = digitalRead(increaseButtonPin);
  decreaseState = digitalRead(decreaseButtonPin);
  lcd.home();
  // call sensors.requestTemperatures() to issue a global temperature 
  // request to all devices on the bus
  sensors.requestTemperatures(); // Send the command to get temperatures
  celsius = sensors.getTempCByIndex(0);
  currentTemp = 1.8*celsius + 32;
  // Why "byIndex"? You can have more than one IC on the same bus. 0 refers to the first IC on the wire
  lcd.print("Current Temp: ");
  lcd.print(currentTemp);
  lcd.setCursor(0,1);
  lcd.print("Set Point: ");
  lcd.print(setPoint);
  state = checkTemp(currentTemp, setPoint);



  if(abs(millis()-buttonIncTime)>20){
    if(increaseState == 0){
      buttonIncPressedBefore = true;
      setPoint = setPoint + 1;
      buttonIncTime = millis();
      //lcd.print(setPoint);

    }
  }
  if(abs(millis()-buttonDecTime)>20){
    if(decreaseState == 1){
      buttonDecPressedBefore = true;
      setPoint = setPoint - 1;
      //lcd.print(setPoint);
      buttonDecTime = millis();
    }
  }

  //  if(buttonDecPressedBefore && abs(millis()-buttonDecTime)>100){
  //    setPoint = setPoint - 1;
  //    buttonDecPressedBefore = false;
  //  }

  //  if(buttonIncPressedBefore && abs(millis()-buttonIncTime)>100){
  //    setPoint = setPoint + 1;
  //    buttonIncPressedBefore = false;
  //  }

//  Serial.print("Millis=");
//  Serial.println(millis());
//  Serial.print("buttonIncTime=");
//  Serial.println(buttonIncTime);
//  Serial.print("Diff");
//  Serial.println(abs(millis()-buttonIncTime));
//  Serial.print("Temp = ");
//  Serial.println(currentTemp);
  Serial.print("IncreaseState = ");
  Serial.println(increaseState);
  Serial.print("DecreaseState = ");
  Serial.println(decreaseState);







  if(state == 'H')
  {
    lcd.setCursor(0,3);
    lcd.print("Heating");
  }

  if(state == 'C')
  {
    lcd.setCursor(0,3);
    lcd.print("Cooling");
  }
  if(state == 'I')
  {
    lcd.setCursor(0,3);
    lcd.print("       ");
    lcd.setCursor(0,3);
    lcd.print("Idle");   
  }
  if(second() == 59)
  {
    lcd.setCursor(10,3);
    lcd.print("Data Sent");
    write2DB();
  }
  else
  {
    lcd.setCursor(10,3);
    lcd.print("          ");    
  }
  decreaseState = lastDecButtonState;
  increaseState = lastIncButtonState;
}

char checkTemp(float currentTemp, float setPoint){

  float currentDiff = abs(currentTemp-setPoint);
  if((currentTemp < setPoint) && (currentDiff > differential) && second() == 59){
    digitalWrite(HEAT,LOW);
    digitalWrite(COOL,HIGH);
    state = 'H';
  }
  if((currentTemp > setPoint) && (currentDiff > differential) && second() == 59){
    digitalWrite(COOL,LOW);
    digitalWrite(HEAT,HIGH);
    state = 'C';
  }
  // If currentTemp is within +/- differential then shut off
  if((currentTemp > setPoint - differential) && (currentTemp < setPoint + differential)){
    digitalWrite(HEAT,HIGH);
    digitalWrite(COOL,HIGH);
    state = 'I';
  }
  return state;


}

void write2DB(){




  client.connect(serverName, 80);



  // Make a HTTP request:  Sends information to "data.php" which lives on the RPi.
  client.print("GET http://192.168.1.17/tempControl/data.php?"); //place your server address here
  Serial.print("Sent Temp:  ");  //  
  Serial.println(currentTemp);
  client.print("Temp=");
  client.print(currentTemp);  // 
  client.print("&&");
  client.print("SetPoint=");
  client.print(setPoint);
  client.println(" HTTP/1.1");
  client.println("Host: http://192.168.1.17");
  client.println( "Content-Type: application/x-www-form-urlencoded" );
  client.println( "Connection: close" );
  client.println();
  client.println();
  client.stop();
  //delay(300);



}

Thank you very much for your help.

Those are not very bad suggestions: diode over SSR, dedicated 5V for relays, moving the SSR away from the Arduino. But that is for normal relays.
Are they normal relays or solid state relays ?

These are solid state relays : OMRON 2/4/8-Ch 5V Solid State Relay | SainSmart – SainSmart.com
But your link is to normal relays.

Those displays are known to be sensitive for electronic noise. So you have to try to figure out if only the display is going nuts and the Arduino is still working, or that the Arduino is going bad.

How is the Arduino powered ?

Could you reduce ram usage with the 'F()' macro ?
Every Serial.print() and Serial.println() and client.print() and client.println() can be converted to this:

Serial.print(F("IncreaseState = "));
client.print(F("GET http://192.168.1.17/tempControl/data.php?"));

stvoffutt:
Hello everybody. First time posting on this forum and new Arduino user as well. I have found an amazing amount of knowledge on this forum related to my project. However, I am experiencing an issue with my project that I can't quite figure out. My project is this:

I have a mini fridge that I have converted into a larger chamber that I wish to control the inside temperature with an Arduino. I also wish to log the temperature in a database on my LAN. The mini fridge has a start up amperage of 6.3A and running amps of 1.5. I have attached my diagram that I used in Fritzing. I am also new to Fritzing and could not find the LCD or the SSR that I am using. The parts that I am using are:

Arduino Uno with ethernet shield
Sainsmart 4-Channel Solid State Relay (link)
2x10k resistors
4.7k resistor
Dallas waterproof temp sensor
Sainsmart 20x4 lcd (link)
mini - fridge
heat element (link)

Everything works great when no load (fridge or heat element is not plugged in) is hooked up to the SSR. However, when I hook up the loads and everything is working fine, as soon as the fridge turns off my arduino freezes. It's only when the fridge shuts OFF that I have the problem. Sometimes I will get random crazy characters on the screen. Other times it will just be unresponsive.

I have tried very hard to research this problem on these forums and elsewhere to no avail. Some suggested a diode on the SSR and others a dedicated 5v power supply for the SSR. I'm unsure how to fix this problem. I don't think it is a code problem as the Arduino seems to be unresponsive only when load is attached but I will attach it anyways. I have tried moving the SSR away from the arduino as I heard on this forum that EMI could be an issue but that still doesn't fix the problem.

#include <OneWire.h>

#include <Wire.h>
#include <SPI.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
#include <Ethernet.h>
#include <Time.h>
//#include <rtc_clock.h>
#define BACKLIGHT_PIN 13
#define HEAT 6
#define COOL 7

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 2

// 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);

const int increaseButtonPin = 3;
const int decreaseButtonPin = 5;
const float differential = 1;

float currentTemp, celsius;
float setPoint = 60;
int incButtonPushCounter = 0;
int decButtonPushCounter = 0;
int increaseState = 0;
int decreaseState = 0;
int lastIncButtonState = 0;
int lastDecButtonState = 0;
int WindowSize = 2000;
static bool buttonIncPressedBefore = false;
static bool buttonDecPressedBefore = false;
int buttonIncTime = 0;
int buttonDecTime = 0;

// Ethernet Setup Stuff...
byte mac[] = {
  0xB0, 0xDF, 0x3A, 0x84, 0xDB, 0x9C  };
//I made one up here it should be
//listed on your ethernet shield box
//EthernetServer server(80); // place your server IP address here
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;
IPAddress ip(192,168,1,18);
char state = 'I';

byte serverName[] = {
  192, 168, 1, 17}; // Database server IP

void setup(void)
{
  // start serial port
  Serial.begin(9600);
  Serial.println("Dallas Temperature IC Control Library Demo");

// Start up the library
  sensors.begin();
  // IC Default 9 bit. If you have troubles consider upping it 12. Ups the delay giving the IC more time to process the temperature measurement

pinMode(BACKLIGHT_PIN, OUTPUT);
  digitalWrite(BACKLIGHT_PIN,HIGH);
  lcd.begin(20,4);
  pinMode(HEAT,OUTPUT);
  pinMode(COOL,OUTPUT);
  pinMode(increaseButtonPin, INPUT);
  pinMode(decreaseButtonPin, INPUT);
  digitalWrite(HEAT,HIGH);
  digitalWrite(COOL,HIGH);
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);

//Serial.print("server is at ");
  //Serial.println(Ethernet.localIP());

}

void loop(void)
{

increaseState = digitalRead(increaseButtonPin);
  decreaseState = digitalRead(decreaseButtonPin);
  lcd.home();
  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus
  sensors.requestTemperatures(); // Send the command to get temperatures
  celsius = sensors.getTempCByIndex(0);
  currentTemp = 1.8*celsius + 32;
  // Why "byIndex"? You can have more than one IC on the same bus. 0 refers to the first IC on the wire
  lcd.print("Current Temp: ");
  lcd.print(currentTemp);
  lcd.setCursor(0,1);
  lcd.print("Set Point: ");
  lcd.print(setPoint);
  state = checkTemp(currentTemp, setPoint);

if(abs(millis()-buttonIncTime)>20){
    if(increaseState == 0){
      buttonIncPressedBefore = true;
      setPoint = setPoint + 1;
      buttonIncTime = millis();
      //lcd.print(setPoint);

}
  }
  if(abs(millis()-buttonDecTime)>20){
    if(decreaseState == 1){
      buttonDecPressedBefore = true;
      setPoint = setPoint - 1;
      //lcd.print(setPoint);
      buttonDecTime = millis();
    }
  }

//  if(buttonDecPressedBefore && abs(millis()-buttonDecTime)>100){
  //    setPoint = setPoint - 1;
  //    buttonDecPressedBefore = false;
  //  }

//  if(buttonIncPressedBefore && abs(millis()-buttonIncTime)>100){
  //    setPoint = setPoint + 1;
  //    buttonIncPressedBefore = false;
  //  }

//  Serial.print("Millis=");
//  Serial.println(millis());
//  Serial.print("buttonIncTime=");
//  Serial.println(buttonIncTime);
//  Serial.print("Diff");
//  Serial.println(abs(millis()-buttonIncTime));
//  Serial.print("Temp = ");
//  Serial.println(currentTemp);
  Serial.print("IncreaseState = ");
  Serial.println(increaseState);
  Serial.print("DecreaseState = ");
  Serial.println(decreaseState);

if(state == 'H')
  {
    lcd.setCursor(0,3);
    lcd.print("Heating");
  }

if(state == 'C')
  {
    lcd.setCursor(0,3);
    lcd.print("Cooling");
  }
  if(state == 'I')
  {
    lcd.setCursor(0,3);
    lcd.print("      ");
    lcd.setCursor(0,3);
    lcd.print("Idle"); 
  }
  if(second() == 59)
  {
    lcd.setCursor(10,3);
    lcd.print("Data Sent");
    write2DB();
  }
  else
  {
    lcd.setCursor(10,3);
    lcd.print("          ");   
  }
  decreaseState = lastDecButtonState;
  increaseState = lastIncButtonState;
}

char checkTemp(float currentTemp, float setPoint){

float currentDiff = abs(currentTemp-setPoint);
  if((currentTemp < setPoint) && (currentDiff > differential) && second() == 59){
    digitalWrite(HEAT,LOW);
    digitalWrite(COOL,HIGH);
    state = 'H';
  }
  if((currentTemp > setPoint) && (currentDiff > differential) && second() == 59){
    digitalWrite(COOL,LOW);
    digitalWrite(HEAT,HIGH);
    state = 'C';
  }
  // If currentTemp is within +/- differential then shut off
  if((currentTemp > setPoint - differential) && (currentTemp < setPoint + differential)){
    digitalWrite(HEAT,HIGH);
    digitalWrite(COOL,HIGH);
    state = 'I';
  }
  return state;

}

void write2DB(){

client.connect(serverName, 80);

// Make a HTTP request:  Sends information to "data.php" which lives on the RPi.
  client.print("GET http://192.168.1.17/tempControl/data.php?"); //place your server address here
  Serial.print("Sent Temp:  ");  // 
  Serial.println(currentTemp);
  client.print("Temp=");
  client.print(currentTemp);  //
  client.print("&&");
  client.print("SetPoint=");
  client.print(setPoint);
  client.println(" HTTP/1.1");
  client.println("Host: http://192.168.1.17");
  client.println( "Content-Type: application/x-www-form-urlencoded" );
  client.println( "Connection: close" );
  client.println();
  client.println();
  client.stop();
  //delay(300);

}




Thank you very much for your help.

Build a snubber circuit on the AC side of the relay, that should remove the noise when turning off the fridge.

mart256:
Build a snubber circuit on the AC side of the relay, that should remove the noise when turning off the fridge.

Or better, use a SSR.

Peter_n:
Are they normal relays or solid state relays ?

These are solid state relays : OMRON 2/4/8-Ch 5V Solid State Relay | SainSmart – SainSmart.com
But your link is to normal relays.

Thanks for the reply. Wow, I could have swore that this was an SSR but I guess made an uneducated purchase... So, I do have a standard relay NOT a SSR.

Now that is out of the way, the arduino is freezing/hanging completely. I monitored the database and the serial monitor once while this was happening and it indeed was not sending data to the DB and not printing anything within the serial monitor.

mart256:
Build a snubber circuit on the AC side of the relay, that should remove the noise when turning off the fridge.

I am not familiar with a snubber circuit. I tried googling snubber circuit and was kind of overwhelmed. Could you point me in the right direction for my application?

Would using a SSR instead fix this problem? I feel pretty dumb thinking I had a SSR the whole time...

Yes, a SSR stops conducting as the mains voltage goes to zero, so causes no transients.

A snubber for relay contacts consists of a mains-rated capacitor of say 1µF in series with a resistor - perhaps 100 ohms, also mains-rated.

For a mains snubber circuit I use 47nF or 100nF and 47 ohm to 220 ohm.
The capacitor and resistor in series, and that parallel to the relay contact. It is used to avoid sparks, and it will also lengthen the lifetime of the relay contacts a lot.

How is the Arduino powered ? What is connected to the Arduino GND ?
I also have doubts about the breadboard. They can have bad contacts.
The heating element is only 30Watt. I wonder if it has been made right, is could be a big coil.