Issue: Relays Not Responding Properly (Upd: Help on Electrical Cirtcuit Issue)

Board: ESP32
Peripherals:

  • 1 x DHT22
  • 2 x Relays

Project Details:

  • Project is a Relay, Temperature and Humidity Control.
  • Uses Blynk in order to Control the Project.
  • Consists in a ESP32 with a DHT22 and 2 Relays.

Problem:
Unable to toggle any of the 2 Relays.

1. Thinking that ESP32 could not be sufficient to power the Relays; I've tried Powering them with external 5v Power from Computer USB Port - (Dangerous if something go Wrong; but it was the only alternative at the moment).

2. Already Checked that Relays are Initialized.

3. Already Checked Blynk App Configuration.

4. Attempting to Debug using Serial.print:
a) Confirms that the Blynk Events Run Properly.
b) Values Passed are Correct

5. I've changed Blynk App Button Configuration to toggle the Relays without VPINS (using Digital Instead): Interestingly nothing Changes.

6. Using VPINS on Blynk Application; I can see that Relays Green Led (Circuit Closed) Dim when State is OFF and get Brighter when state is ON.

7. Testing the Relays on Arduino Uno or Nano with Physical Button confirms the Relays are Working properly.

8. Tried the same with a Different ESP32 Module; but No Success.

9. Tried Different Pins (Same result in most cases; however I noticed that some Pins won't even slightly dim the Relay Led.

10. Alternatively: Tried using ESP8266 (NodeMCU); Couldn't get the DHT22 to work. Gave up on the Awfull Module.

At this Point I'm Completely Lost as the code seems to be working properly.
ESP32 GPIO Pins don't seem to be working correctly... It's driving me Crazy.
Does anyone know why this happens and what I could try to figure this out?

Debug Update:
Partialy answering my own Question: The problem definitely resides in the Circuit.

Notes:
Initially, I was getting the Power from the 3v3 and GND Pins.
Since I couldnt get any response from there; I changed the wires to the other side of the board.
I was then getting Power on the Power Input Pins Side (that is: GND and VIN) on ESP32.
But that only gave me a slight idea the this could be a Power Issue (by seeing the Relay Leds Dim slightly).
After posting my question above; I moved the GND wire and Plugged it in the GND on Power Input Pins side; and for my surprise the Relays toggle the Light but don't Open or Close the Relay Circuit (No Clicks).
It then occurred me that Ground could be an Issue (for some reason I do not yet understand.
I ended up in jumping a wire over both grounds; now the Relays toggle 1 at a time. That is: a second relay will only toggle if the other is OFF.

Can anyone with more electical experience explain me why and point me out in the right direction?

Thanks in advance.

@xrtekk

Your topic was Moved to it's current location / section as it is more suitable.

Could you also take a few moments to Learn How To Use The Forum.

Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

Perhaps your relay module requires 5V signals, and AFAIR the ESP works on 3.3V only.

Here's the problem:

We have absolutely no idea what you mean when you refer to "relays" because you have not cited them with images or Web references. Nor have you demonstrated how you are connecting them or what you are using as a power supply .

So we have absolutely no idea what you are doing wrong.

How could we? :roll_eyes:

If you are using a "suitable" external supply for the relays you must ensure you have a COMMON GROUND back to the ESP.

ballscrewbob:
If you are using a "suitable" external supply for the relays you must ensure you have a COMMON GROUND back to the ESP.

Sorry, that is actually the point!

If using the common active-low relay modules with the "VCC JD-VCC" jumper then you most definitely should not connect the "GND" to the Arduino or ESP ground, only to the relay power supply and at the very relay power supply output terminal (which may however, also feed the Arduino/ ESP).

But you are trying to steal my thunder! The critical point is to induce the OP to talk sense and give actual usable information in order to figure out what he is attempting to do. :astonished:

For LOW true opto-isolated relay boards there should be only 1 Vcc wire from Arduino to relay board + 1 wire for each relay "in" terminal, NO GND. If it's a HIGH true type, 1 GND + 1 for each "in", NO VCC. Opto-isolated boards must NEVER have BOTH Vcc AND GND connected to Arduino, that defeats the isolation.

Look at this schematic:
With 5V on Vcc (JD-VCC jumper removed), the indicator LED (IN1) drops 1.8V, the opto LED drops another 1.2V, total = 3V, the current limit resistor (1k) drops the remaing 2V. Now imagine Vcc is only 3.3V, after the 3V drop from the 2 LEDs there is only 0.3V left, the 1k CL resistor allows only 300µA to flow through the opto's LED, not enough to illuminate it and fully trigger the phototransistor that turns on the relay transistor, so no workum.
Solution? Put 5V on Vcc, the 3.3V MCU output pins can safely handle the 2 or 3mA current.

OptoRelayChannelData-575.jpg

OptoRelayChannelData-575.jpg

The schematic is very unsafe :frowning:
The LED should be connected in parallel to the opto coupler diode, and both should be powered by the controller Vcc. Even better the LED should sit on the secondary side, in parallel to the relay, so that it can also indicate power loss or other malfunctions.

Higher voltage can cause current through the controller avalanche or protection diodes, what can make the relay switch on permanently or burn the transistor. Users already observed an Arduino powered by signals on input pins, even with no Vcc applied to the controller.

DrDiettrich:
The schematic is very unsafe :frowning:

Not at all. :sunglasses: But we really have "let the cat out of the bag" now and given the full answer without the OP having to put any effort into understanding the situation. :roll_eyes:

As JCA34F explains, you supply "VCC" from the 5 V supply to the ESP and the threshold voltage of the two LEDs precludes the ESP from ever being subject to greater than its 3.3 V supply.

DrDiettrich:
Higher voltage can cause current through the controller avalanche or protection diodes, what can make the relay switch on permanently or burn the transistor. Users already observed an Arduino powered by signals on input pins, even with no Vcc applied to the controller.

It is by no means obvious to which "transistor" you are referring here. You will not get "phantom powering" because you are supplying the input to the opto-coupler from the 5 V (pre-regulator) supply on the ESP module. The only way the ESP could lose power while the 5 V was still present is if the regulator fails and then everything goes wrong. :astonished:

I do agree that people report being confused when using these relay modules, when the green LED operates but the relay does not, indicating failure of supply to JD-VCC, but the module often has a "pilot" LED to indicate this.

The relay module obviously works well only with Vcc=5V, at 3.3V the voltage drop on the diodes will prevent proper operation.

The LED should be connected in parallel to the opto coupler diode, and both should be powered by the controller Vcc.

The opto LED would clamp the voltage at 1.2V, the "IN" led with a forward voltage of 1.8V would not light.

Greetings;

Thank you all for your replies.

Fixed:

  1. Relays not Toggling
    [Fix 1]: The dupont wires had a gap in Relay Ground Pin.
    [Fix 2]: Re-Written the Whole Project into 1 Class. (I Guess Arduino IDE is not very Capable of Identifying problems to user like Visual Studio and still Flashes the Project without Checking the problems).
    Both fixes above solved the Relay Toggling Issue.

Current Project Issues:
At this point I have only 1 problem:

  • I have 2 relays and even though they are declared to initialize in LOW state (OFF / Open Circuit) 1 of them is ALWAYS ON when project initializes.
    No matter what pins I chose; in some cases it will either not toggle any at all or initialize 1 of the relays ON.

Remarks:
Circuit:

  • The DHT22 uses a 4.7ohm to 10k ohm Resistor between Power and Data (See: Circuit).

On Blynk App:

  • App Contains a LCD, 2 Buttons, 2 Gauges; a Terminal and a Notification Gadjet.
  • Buttons are Set to States: 0 - 1

As requested above; I'm sharing my circuit (attached) and my code.

/********************************
* Includes
********************************/

#include "BlynkSimpleEsp32.h"
#include "DHTesp.h"
#include "SimpleTimer.h"
#define stateLed 2

/********************************
* Member Variables
********************************/
bool debugEnabled = true;

String serialData;
String messageLine;

#define BLYNK_PRINT Serial  // Set Serial Output for Debug Prints (NOT Teminal Widget)
#define BLYNK_DEBUG         // Uncomment this to see detailed prints
#define dhtPin 17

#define relay1Pin 22
#define relay2Pin 23

// Blynk App Pushbutton Status (Relay Intial State)
int relay1State = LOW;
int relay2State = LOW;

#define DBG_TRM  V0 // VPIN for Terminal Widget.
#define SEN_EDG  V1 // VPIN for Min/Max DHT Readings (Assigned to LCD Widget).
#define SEN_TMP  V2 // VPIN for Actual DHT22 Temperature Readings.
#define SEN_HUM  V3 // VPIN for Actual DHT22 Humidity Readings.
#define REL_FAN1 V4 // VPIN for Fan 1 Relay.
#define REL_FAN2 V5 // VPIN for Fan 2 Relay.

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "myAuth";
char ssid[] = "mySSID";
char pass[] = "myPassword";

SimpleTimer timer;
WidgetLCD lcd(SEN_EDG);
WidgetTerminal terminal(DBG_TRM);
DHTesp dht;

float minTmp = 0;
float maxTmp = 0;
float minHum = 0;
float maxHum = 0;

/*****************************************
* Module Ready Led (Wifi / Bluetooth Led)
*****************************************/

/* Enable On Board WiFi Status Led */
void TogStateLed(bool state) 
{
 switch(state)
 {
   case true: digitalWrite(stateLed, LOW); break; 
   case false: digitalWrite(stateLed, HIGH); break;
 }
}

/********************************
* Blynk Serial Terminal
********************************/

void TerminalSend(String msg)
{
 // Send Message to Terminal Widget.
 terminal.println(msg);
 
 // Ensure that Data was Sent out of Device.
 terminal.flush();
}

/********************************
* DHT22 Functionality
********************************/

float Temperature() { return dht.getTemperature(); }
float Humidity() { return dht.getHumidity(); }

float GetTemperature()
{    
 float tmp = Temperature();
 
 if (tmp < minTmp) { minTmp = tmp; }
 else { maxTmp = tmp; }

 return tmp;
}

/* Retrieve Sensor Temperature & Set Min. & Max. Variables. */
float GetHumidity()
{  
 float hum = Humidity();
 
 if (hum < minHum) { minHum = hum; }
 else { maxHum = hum; }

 return hum;
}

/********************************
* Blynk Timer Event Methods
********************************/

/* Send Relay States to Blynk. */
void SendRelayStates()
{
 Blynk.virtualWrite(relay1Pin, relay1State);
 Blynk.virtualWrite(relay2Pin, relay2State);

 Serial.println("R1: " + (String)relay1State);
 Serial.println("R2: " + (String)relay2State);
}

void SendTemperature() { Blynk.virtualWrite(SEN_TMP, GetTemperature()); TerminalSend("Retrieving: Temperature"); }
void SendHumidity() { Blynk.virtualWrite(SEN_HUM, GetHumidity()); TerminalSend("Retrieving: Humidity"); }
void SendMaxValues()
{  
 TerminalSend("Retrieving: Min. & Max. DHT Values");

 int xMinTmp = minTmp;
 int xMaxTmp = maxTmp;
 
 int xMinHum = minHum;
 int xMaxHum = maxHum;
 
 // X (Row), Y (Column), String
 String tmp = "T: " + (String)xMinTmp + "ºC" + "  |  " + (String)xMaxTmp + "ºC";
 String hum = "H: " + (String)xMinHum + "%"  + "   |  " + (String)xMaxHum + "%";
 
//  String tmp = "T:" + (String)minTmp + "ºC " + (String)maxTmp + "ºC";
//  String hum = "H: " + (String)minHum + "% " + (String)maxHum + "%";
 
 lcd.clear();
 lcd.print(0, 0, tmp);
 lcd.print(0, 1, hum);
}

/* Notify User if Sensor Temperature Reached the Lowest or Highest Setting */
void NotifyOnTemperature()
{  
 if (Temperature() > 29)
 {
   TerminalSend("\n\n   NOTIFICATION: High Temperature \n\n");
   Blynk.notify("High Temperature"); 
 }
 
 else if (Temperature() <= 21)
 {
   TerminalSend("\n\n   NOTIFICATION: Low Temperature \n\n");
   Blynk.notify("Low Temperature");
 }
}

/* Notify User if Sensor Temperature Reached the Lowest or Highest Setting */
void NotifyOnHumidity()
{  
 if (Humidity() > 80)
 { 
   TerminalSend("\n\n   NOTIFICATION: High Humidity \n\n");
   Blynk.notify("High Humidity");
 }
 
 else if (Temperature() <= 20)
 {
   TerminalSend("\n\n   NOTIFICATION: Low Humidity \n\n");
   Blynk.notify("Low Humidity");
 }
}

/********************************
* Blynk Events
********************************/

/* Toggle Relay 1 : Occurs when VPIN Button is Pressed in Application */
BLYNK_WRITE(REL_FAN1)
{
 TerminalSend("Toggling: Relay #1");
 
 if (relay1State != param.asInt())
 {
   // param.asInt() means: assigning incoming value from pin V4 to a variable in this case relayState
   relay1State = !relay1State;             // Toggle state.
   digitalWrite(relay1Pin, relay1State);   // Relay control pin.
 } 
}

/* Toggle Relay 2 : Occurs when VPIN Button is Pressed in Application */
BLYNK_WRITE(REL_FAN2)
{
 TerminalSend("Toggling: Relay #2");
 
 if (relay2State != param.asInt())
 {
   // param.asInt() means: assigning incoming value from pin V5 to a variable in this case relayState
   relay2State = !relay2State;             // Toggle state.
   digitalWrite(relay2Pin, relay2State);   // Relay control pin.
 }
}


/********************************
* Setup & Loop
********************************/
/* Instantiate WiFi Led */
void StateLed_Init()
{
 pinMode(stateLed, OUTPUT);
 digitalWrite(stateLed, HIGH);
}

bool Init_Relays()
{
   /* Init Relays */
 pinMode(relay1Pin, OUTPUT);
 pinMode(relay2Pin, OUTPUT);
   
 // digitalWrite(relay1Pin, relay1State);
 // digitalWrite(relay2Pin, relay2State);

 // delay(100);
 
 return true;
}

bool Init_DHT22()
{
 // Initialize temperature sensor
 dht.setup(dhtPin, DHTesp::DHT22);

 // Set DHT Initial Edge Values
 minTmp = Temperature();
 maxTmp = Temperature();

 minHum = Humidity();
 maxHum = Humidity();
 
 // Delay Sligthly to Allow the DHT Sensor to Start and Perform the Initial Reading.
 delay(2000);

 return true;
}

bool Init_Serial()
{
 /* Init Serial */
 if (debugEnabled) { Serial.begin(115200); }
 
 delay(1000);
 
 return true;
}

void setup() 
{
 StateLed_Init();
 
 if (Init_Relays() && Init_DHT22())
 {
   if (Init_Serial())
   {
     /* Init Blynk and Wifi*/
     Blynk.begin(auth, ssid, pass);
     
     // Set a Task to Timer (Run every x Seconds).
     timer.setInterval(2000L,  SendTemperature);
     timer.setInterval(2000L,  SendHumidity);
     timer.setInterval(2000L,  SendMaxValues);
     timer.setInterval(150L,   SendRelayStates);
     timer.setInterval(30000L, NotifyOnTemperature);
     timer.setInterval(30000L, NotifyOnHumidity);
     

 
     TerminalSend("Module Initialized");   
   }
 }
}

void loop() 
{
 if (Serial.available() == 0)
 {
   Blynk.run();
   timer.run();
 }

 if (Serial.available() > 0)
 {
//    serialData = Serial.read();
//    messageLine = messageLine + serialData;
//    TerminalSend(messageLine);
 }
}

And we are no closer to the answer, as we still do not know what relay modules these are. :roll_eyes:

JCA34F:
The opto LED would clamp the voltage at 1.2V, the "IN" led with a forward voltage of 1.8V would not light.

Don't forget the separate resistor for each LED.

Can you please describe where/how you defined the relay objects and their initial state?

Hi,
Where in void setup() do you run;

bool Init_Relays()
{
   /* Init Relays */
 pinMode(relay1Pin, OUTPUT);
 pinMode(relay2Pin, OUTPUT);
  
 // digitalWrite(relay1Pin, relay1State);
 // digitalWrite(relay2Pin, relay2State);

 // delay(100);
 
 return true;
}

Have you written some basic simple code to operate the relays.
That is code WITHOUT BLYNK or any other functions.

You need to put some Serial.print statements in your code to trace what is happening.

Can you please tell us your electronics, programming, arduino, hardware experience?

Thanks.. Tom... :slight_smile:


@Tom:
Thanks for your prompt repply.

Regarding my Experience:

  • Arduino & C++: around 2 years or so. Occasionally doing a few projects
  • Electronics: Mostly what I've learned in school a long time ago and self experience from hobbies.
  • Programming: 7 years C#.

Regarding your post:
Not sure if I understood what you meant.
Relays are initiated as you see bellow.
And Blynk Button Syncronization is done at:

void SendRelayStates() {...}

/* Init Relays */
bool Init_Relays()
{
 pinMode(relay1Pin, OUTPUT);
 pinMode(relay2Pin, OUTPUT);
   
 // digitalWrite(relay1Pin, relay1State);
 // digitalWrite(relay2Pin, relay2State);

 // delay(100);
 
 return true;
}

void setup() 
{  
 if (Init_Relays() && Init_DHT22()) // <--- Initialized the Relays
 {
   if (Init_Serial())
   {
     // Init Blynk and Wifi.
     Blynk.begin(auth, ssid, pass);
     
     // Set a Task to Timer (Run every x Seconds).
     timer.setInterval(2000L,  SendTemperature);
     timer.setInterval(2000L,  SendHumidity);
     timer.setInterval(2000L,  SendMaxValues);
     timer.setInterval(150L,   SyncStates);
     timer.setInterval(30000L, NotifyOnTemperature);
     timer.setInterval(30000L, NotifyOnHumidity);
     
     TerminalSend("Module Initialized");

     // (Ready) Turn Built In LED ON.
     Init_StateLed();
   }
 }