Relay Shield Issues

I am new to working in this environment. I do have a basic understanding of how electronics work. I have built a controller to monitor the nutrient solution for my hydroponics and turn on 4 peristaltic pumps to make corrections based on the sensor readings and set parameters. Then posting to Thingspeak so I can remote monitor the system.

Hardware
elegoo mega 2560
sunfounder ethernet shield
keyesstudio 4 relay shield
Gravity PH Sensor
Gravity TDS Sensor
Gaohou DS18B20 Waterproof Digital Temp Sensor with Adaptor module for Arduino
DHT11
SunFounder IIC I2C TWI Serial 2004 20x4 LCD Module Shield for Arduino R3 Mega2560
4 Gikfun 12V peristaltic pumps

9V power supply for board Or USB (one or the other)
separate 12V power supply (for Pumps)

I removed pin 4 from the relay shield as this was in conflict with the ethernet shield and activate it from pin 22 on the mega.

Everything works flawlessly until I hook up the 12V to the com screw to the relay to power the pumps.
What is happening is the code runs until it gets to the pump control . Then it either freezes or gets through but then skips the send to thinkspeak portion of the code and returns to the beginning and then freezes.
When I remove the power to the pumps it works fine.

I tried using a second relay shield and have gotten the same results.

Any help would be greatly appreciated.

Posting Code in Reply

Auto Doser.pdf (206 KB)

[code]
#include <EEPROM.h>
#include <DFRobot_PH.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SimpleDHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SD.h>
#include <SPI.h>
#include "GravityTDS.h"
#include <Ethernet.h>
#include <ThingSpeak.h>

#define ONE_WIRE_BUS 3//////////////////////////////////// Temp sensor D3
#define TdsSensorPin A1 //////////////////////////////////  EC Sensor
LiquidCrystal_I2C lcd(0x27, 20, 4);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
GravityTDS gravityTds;
int pinDHT11 = 2; //////////////////////////////////////// Temp & Humidity Sensor
SimpleDHT11 dht11(pinDHT11);
float temperature = 25, tdsValue = 0;
float envtemp;
float envhum;
float ctemp;
float CEC;
float CPH;
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192, 168, 0, 177);
IPAddress myDns(192, 168, 0, 1);

EthernetClient client;
unsigned long myChannelNumber = 1284020;
const char * myWriteAPIKey = "EN78TLXBN2XZCGNT";




/////////   Set These Variables ////////////////

float PH_SET = 9.3;  //         Desired PH Level
float PH_Range = .5; //         Allowable Deviation From Desired PH

float EC_SET = 1.1; //          Desired EC Level
float EC_Range = .250;  //        Allowable Deviation From Desired EC


int PH_Up_Dose_Time = 2; ///        PH Up Pump Run Time in seconds
int PH_Down_Dose_Time = 2; //       PH Down Pump Run Time in seconds
float Ph_Wait_Time = 2; ////        Time Delay After PH Adjustment in seconds
float PH_Pump_Wait = 2; //          Delay after PH Adjustment


int EC_Dose_Time = 2; //         set EC pump dose Run times in seconds
int EC_Wait_time = 2; //          set time to wait between dosing
int EC_Pump_Wait = 2; //          Time after dosing to allow for mixing


float ectrig = EC_SET - EC_Range;
float uptrig = PH_SET - PH_Range;
float downtrig = PH_SET + PH_Range;

int PHUP = 22;
int PHDOWN = 24;
int EC_A = 7;
int EC_B = 6;

// Code for video 4 (pH sensing - Aquaponics and Hydroponics)
int sensorPin = A3; /////////////////////////////////////////////////////// select the analog input pin for the pH sensor
int sensorValue = 0; // variable to store the value coming from the sensor
float ad7 = 282.0; // change this value to the one on serial monitor when in pH7 buffer
float ad4 = 395.0; // change this value to the one on serial monitor when in pH4 buffer

int Nut_Add;
int Up_Add;
int Down_Add;


///////////////////////////////////////////////////////////////////////////////////////
void setup(void)
{
  // start serial port
  Serial.begin(9600);
  lcd.begin();
  Serial.println("Dallas Temperature IC Control Library Demo");
  sensors.begin();
  // Ethernet.init(10);
  // start the Ethernet connection:
  Serial.println("Initialize Ethernet with DHCP:");
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // Check for Ethernet hardware present
    if (Ethernet.hardwareStatus() == EthernetNoHardware) {
      Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
      while (true) {
        delay(1); // do nothing, no point running without Ethernet hardware
      }
    }
    if (Ethernet.linkStatus() == LinkOFF) {
      Serial.println("Ethernet cable is not connected.");
    }
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, ip, myDns);
  } else {
    Serial.print("  DHCP assigned IP ");
    Serial.println(Ethernet.localIP());
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);

  ThingSpeak.begin(client);  // Initialize ThingSpeak
  gravityTds.setPin(TdsSensorPin);
  gravityTds.setAref(5.0);  //reference voltage on ADC, default 5.0V on Arduino UNO
  gravityTds.setAdcRange(1024);  //1024 for 10bit ADC;4096 for 12bit ADC
  gravityTds.begin();  //initialization

  pinMode(PHUP, OUTPUT);
  pinMode(PHDOWN, OUTPUT);
  pinMode(EC_A, OUTPUT);
  pinMode(EC_B, OUTPUT);

  lcd.setCursor(0, 0);
  lcd.print("PH =");
  lcd.setCursor(9, 0);
  lcd.print("Temp=");
  lcd.setCursor(0, 1);
  lcd.print("EC =");
  lcd.setCursor(0, 2);
  lcd.print("Pump ");
  lcd.setCursor(5, 2);
  lcd.setCursor(0, 3);
  lcd.print("Env T=");
  lcd.setCursor(6, 3);
  lcd.setCursor(13, 3);
  lcd.print("H= ");
  lcd.setCursor(14, 3);
}

/////////////////////////////////////////////////////////////////////////////////////////
void loop()

{

  if (Nut_Add != 0) {
    Nut_Add = 0;
  }
  if (Up_Add != 0) {
    Up_Add = 0;
  }
  if (Down_Add != 0) {
    Down_Add = 0;
  }

  Serial.print(" Add Val ");
  Serial.print(Nut_Add); Serial.print(Up_Add); Serial.println(Down_Add);


  Get_Temp();
  lcd.setCursor(15, 0);
  lcd.print(ctemp, 1);
  
  Get_EC();
  lcd.setCursor(4, 1);
  lcd.print(CEC, 3);
  
  Get_pH();
  lcd.setCursor(4, 0);
  lcd.print(CPH, 2);
  // ph.calibration(phvoltage, phtemperature);          // calibration process by Serail CMD
  
  Get_EnvTH();
  lcd.setCursor(7, 3);
  lcd.print(envtemp, 1);
  lcd.setCursor(16, 3);
  lcd.print(envhum, 0);


  Serial.print("Main Loop Temp ");
  Serial.println(ctemp);
  Serial.print("Main Loop EC ");
  Serial.println(CEC);
  Serial.print("Main Loop PH = ");
  Serial.println(CPH);
  Serial.print("Main Loop Enviroment ");
  Serial.print(envtemp); Serial.print(" *F, ");
  Serial.print(envhum, 0); Serial.println(" H ");


 // if ((CEC <= ectrig))
 // {
    Nut_Add = 1;
    lcd.setCursor(6, 2);
    lcd.print("Part A");
    Serial.println ("Nut A on");
    digitalWrite(EC_A, HIGH);
     delay(EC_Dose_Time * 1000);
    digitalWrite(EC_A, LOW);
    lcd.setCursor(6, 2);
    lcd.print("Off      ");
    Serial.println ("Nut A off");
    delay(EC_Wait_time * 1000);

    Serial.println("Nut B On ");
    digitalWrite(EC_B, HIGH);
    lcd.setCursor(6, 2);
    lcd.print("Part B");
     delay(EC_Dose_Time * 1000);
    digitalWrite(EC_B, LOW);
    lcd.setCursor(6, 2);
    lcd.print("Off      ");
    Serial.println("Nut B Off ");
    delay(EC_Wait_time * 1000);
 
    delay(EC_Pump_Wait * 1000);
 // }

  //if (CEC >= ectrig) {


 // if ((CPH <= uptrig))
 // {
    Serial.println("Up Pump On ");
    Up_Add = 1;
    lcd.setCursor(6, 2);
    lcd.print("UP  ");
    digitalWrite(PHUP, HIGH);
    delay(PH_Up_Dose_Time * 1000);
    digitalWrite(PHUP, LOW);
    lcd.setCursor(6, 2);
    lcd.print("Off  ");
    Serial.println("Up Pump Off ");
    delay(PH_Pump_Wait * 1000);
 // }

 // if ((CPH >= downtrig )  )
 // {
    Serial.println("Down Pump On");
    Down_Add = 1;
    lcd.setCursor(6, 2);
    lcd.print("Down");
    digitalWrite(PHDOWN, HIGH);
    delay(PH_Down_Dose_Time * 1000);
    digitalWrite(PHDOWN, LOW);
    lcd.setCursor(6, 2);
    lcd.print("Off  ");
    Serial.println("Down Pump Off ");
    delay(PH_Pump_Wait * 1000);
 // }
  // }

[/code]

Part2

  Write_SD;
  Send_Thingspeak();
  Serial.print(" Add Val ");
  Serial.print(Nut_Add); Serial.print(Up_Add); Serial.println(Down_Add);
}

void Get_Temp()
{
  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus
  // Serial.print("Requesting temperatures...");
  sensors.requestTemperatures(); // Send the command to get temperatures
  // Serial.println("DONE");
  // 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.
  // Serial.print("Temperature for the device 1 (index 0) is: ");
  // Serial.println(sensors.getTempFByIndex(0));
  ctemp = sensors.getTempFByIndex(0);
  //  Serial.println(ctemp);
  delay(1000);
}
////////////////

void Get_EC()
{
  temperature = ctemp;  //add your temperature sensor and read it
  gravityTds.setTemperature(temperature);  // set the temperature and execute temperature compensation
  gravityTds.update();  //sample and calculate
  tdsValue = gravityTds.getTdsValue();  // then get the value
  Serial.print(tdsValue, 0);
  Serial.println("ppm");
  CEC = (tdsValue * 2) / 1000;
  delay(1000);
}
////////////////

void Get_pH()
{
  int currentValue = 0;
  for (int i = 0; i < 10; i++)
  {
    currentValue += analogRead(sensorPin);
    delay(100);
  }
  sensorValue = (currentValue / 10);
  Serial.println(sensorValue);
  float m = (-3.0 / (ad4 - ad7));
  //Serial.println(m);
  float c = 7 - (m * ad7);
  //Serial.println(c);
  float a = ((m * sensorValue) + c);
  Serial.print("PH = ");
  Serial.println(a);
  CPH = a;
  delay(500);
}

////////////////////////////////////////

void Get_EnvTH()
{
  // start working...
  // Serial.println("=================================");
  // Serial.println("Sample DHT11...");

  // read without samples.
  byte temperature = 0;
  byte humidity = 0;
  int err = SimpleDHTErrSuccess;
  if ((err = dht11.read(&temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
    //    Serial.print("Read DHT11 failed, err="); Serial.print(SimpleDHTErrCode(err));
    //    Serial.print(","); Serial.println(SimpleDHTErrDuration(err)); delay(1000);
    return;
  }

  //  Serial.print("Sample OK: ");
  //  Serial.print((int)temperature); Serial.print(" *C, ");
  envtemp = ((temperature * 9.0) / 5.0 + 32);
  // Serial.print(envtemp); Serial.println(" *F, ");
  //  Serial.print((int)humidity); Serial.println(" H");
  envhum = humidity;
  //  Serial.println(envhum, 0);

  // DHT11 sampling rate is 1HZ.
  delay(1500);
}

/////////////////////////////////////////

void Send_Thingspeak()
{
  // set the fields with the values
  ThingSpeak.setField(1, envtemp);
  ThingSpeak.setField(2, envhum);
  ThingSpeak.setField(3, CPH);
  ThingSpeak.setField(4, CEC);
  ThingSpeak.setField(5, ctemp);
  ThingSpeak.setField(6, Nut_Add);
  ThingSpeak.setField(7, Up_Add);
  ThingSpeak.setField(8, Down_Add);



  // write to the ThingSpeak channel
  int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
  if (x == 200) {
    Serial.println("Channel update successful.");
  }
  else {
    Serial.println("Problem updating channel. HTTP error code " + String(x));
  }
  delay(20000);
}

///////////////    SD Card Write  ////////////////////////////

void Write_SD() {

  File RELKA_Main;

  if (SD.begin())
  {
    Serial.println("SD card ready");
  } else
  {
    Serial.println("SD card failed");
    return;
  }


  RELKA_Main = SD.open("RELKA.txt", FILE_WRITE);
  if (RELKA_Main) {
    Serial.println("Writing to file...");
    RELKA_Main.print(envtemp);
    RELKA_Main.print(",");
    RELKA_Main.print(envhum);
    RELKA_Main.print(",");
    RELKA_Main.print(CPH);
    RELKA_Main.print(",");
    RELKA_Main.print(CEC);
    RELKA_Main.print(",");
    RELKA_Main.println(ctemp);
    RELKA_Main.close(); // close the file
    Serial.println("Done.");
  }
  else {
    Serial.println("error opening test.txt");
  }
}

Missing schematic and more details on your power supply.

Also be aware that TDS and pH tend to seriously mess with one another when placed in the same liquid, unless on fully electrically isolated circuits.

Does that relay module have user settable jumpers ? Some do to allow the relay coils to be powered by a separate power source.

But, just to be clear, if there is no 12 volt power supply connected, everything (apart from the pumps) appears to work flawlessly. The relay lights come on as expected etc. etc. ? As soon as the 12 volt supply is connected to the relays, the error occurs. Is that all correct ?

You said the issues shows itself when you make a connection to the COM screw terminal of the relay module. Try removing the connections to the 4 pumps then, add the pumps back one at a time testing at each stage to see if the error appears.

You appear to be powering the Mega from a 9V power source, hopefully of sufficient rating to handle the relay module.

6v6gt:
Does that relay module have user settable jumpers ? Some do to allow the relay coils to be powered by a separate power source.

But, just to be clear, if there is no 12 volt power supply connected, everything (apart from the pumps) appears to work flawlessly. The relay lights come on as expected etc. etc. ? As soon as the 12 volt supply is connected to the relays, the error occurs. Is that all correct ?

You said the issues shows itself when you make a connection to the COM screw terminal of the relay module. Try removing the connections to the 4 pumps then, add the pumps back one at a time testing at each stage to see if the error appears.

You appear to be powering the Mega from a 9V power source, hopefully of sufficient rating to handle the relay module.

Sorry I got locked out yesterday for some reason when I tried to reply to you.
Yes everything runs great indicator lights activate until I hook the 12V to the pumps.
No the relay shield does not have any jumpers.
I tried un-hooking relays and doing one at a time - no luck
The power source for the Mega is a 9V 1A wall plug transformer.
It has the same issues when hooked via USB to computer.
The schematic is the attachment in original post.
Thank you

livinggreens:
. . .
Yes everything runs great indicator lights activate until I hook the 12V to the pumps.
No the relay shield does not have any jumpers.
I tried un-hooking relays and doing one at a time - no luck
. . .

Even with only one pump connected, this issue shows up ? If you had not said that you've replaced the relay board, I'd have suspected that.

According to this, https://www.amazon.com/Gikfun-Peristaltic-Connector-Aquarium-Analytic/dp/B01IUVHB8E the pumps are only 80mA at 12 volts. I guess the relay coils consume a similar current to the pump.

I'd simply replace the relay board with 4 NPN transistors each with a 330 ohm base resistor, in a low side switch configuration. You should also reverse a diode (say 1N4148) across the terminals of each motor (flyback diode).

Maybe also explain how you modified the relay boards to isolate digital pin 4.

I will try that suggestion.

Relay pin 4 I bent out so as not to connect to ethernet shield through the headers. Then put a jump wire from the Mega pin 22 to the Relay pin 4

Thank you

Got it working needed a 1n4007 diode on the motors. Working great now.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.