ESP8266 Automatic Watering Circuit - low level trigger relay will turn on but won't turn off

Thread Starter

aaceith

Joined Dec 3, 2021
21
UPDATE: the sticking problem has gone away but I don't know why. I am using the Vin, which is a 4.6ish volt source, to power the pump. When the board is sensing but not pumping I measure a total draw of 30 mA using a USB J7-c digital tester. When the pump is activated but dry and not pumping water I measure 150 mA. If I immerse the pump in water, which is its intended design, the total circuit uses 300mA. I'm a little worried how much that number will jump when I add tubing. I have a feeling it will fry the board. Thoughts?

Hello, I'm new to using microcontrollers with relays. I purchased a kit on Amazon - https://www.amazon.com/dp/B09BMVS366?psc=1&ref=ppx_yo2ov_dt_b_product_details - that I want to control with an ESP8266 (specifically NodeMCU Amica / ESP8266MOD) following these instructions: https://poanchen.github.io/blog/202...system-that-is-connected-to-azure-iot-central. I am able to upload the software to the ESP8266, monitor the serial port to see the capacitive moisture sensor's reading and to calibrate the software to trigger the relay, which controls the pump. However, while both the software (via the serial monitor) and the relay (via the indicator lights) says I am turning the pump on and off, the relay stays on. I can get it to turn off by pulling the "In" pin or the VCC but it won't stop as it is supposed to do. I am using the "Vin" pin to power the relay, which measures 4.6V. I also tried powering it with the 3.3V pin from the 8266 and both result in the aforementioned situation.
Capacitive-Soil-Moisture-Sensor-ESP8266 diagram with relay.JPG
C-like:
const int AirValue = 733; // you might need to calibrate this number, instruction is down below

const int WaterValue = 355; // you might need to calibrate this number, instruction is down below

const int DrySoilMoisturePercentage = 50;

const int SoilMoisturePin = A0;

const int RelayPin = D2;

int soilMoistureValue = 0;

int soilmoisturepercent = 0;


void setup() {

  Serial.begin(9600);

  pinMode(SoilMoisturePin, INPUT);

  pinMode(RelayPin, OUTPUT);

  digitalWrite(RelayPin, HIGH);

}


void loop() {

  soilMoistureValue = analogRead(SoilMoisturePin);

  soilmoisturepercent = map(soilMoistureValue, AirValue, WaterValue, 0, 100);

  Serial.print(soilmoisturepercent);

  Serial.println("%");

  if (soilmoisturepercent <= DrySoilMoisturePercentage) {

    Serial.println("Water pumps running...");

    digitalWrite(RelayPin, LOW);

    delay(1000);

    }

  if (soilmoisturepercent >= DrySoilMoisturePercentage) {

    Serial.println("Water pumps stopped...");

    digitalWrite(RelayPin, HIGH);

    delay(1000);

    }

}
 
Last edited:

sghioto

Joined Dec 31, 2017
5,378
First , the relay module Vcc should be 5 volts not 3.3 as shown in your drawing.
Second thing to check is the voltage on the Vin pin when ON and OFF.
 
Last edited:

kaindub

Joined Oct 28, 2019
125
I think your logic is reversed. Should it not be to turn on pump by going high and off by going low. Also why do you initialise the relay output to high.
 

leven85

Joined Aug 30, 2022
1
I think its wired wrong, wired to be on when the relay is not activated and off when it is activated, but the 3.3V you are feeding it is too low to actually pull the relay, only light up the led.
 

Ya’akov

Joined Jan 27, 2019
9,069
I think its wired wrong, wired to be on when the relay is not activated and off when it is activated, but the 3.3V you are feeding it is too low to actually pull the relay, only light up the led.
See above, the module is designed as active low. The input needs to be pulled down to turn the relay on. The 3.3V supply is a separate question, and it could be a problem (though the author of the article it is taken from says he is using 3V3).

The odd part is the choice active low logic. It would mean if the MCU goes dead the pump would fail on. This doesn't seem to be a good design.
 

kaindub

Joined Oct 28, 2019
125
I think the way the relay board works is that when Vin is not connected to anything, the relay is off. When Vin is shorted to grounded, the relay operates.
With no power to the MCU, the relay is off.
Its not really active low.
I dont see a voltage regulator on the relay logic board, therefore I think the base of a transitor, or a gate of a fet is being pulled to ground to operate the relay.
In that case, the digital output of the MCU needs to be set as an input(high impedance) for off, and set to digital ouput and set to low to turn relay on.
 

Irving

Joined Jan 30, 2016
3,843
Wired like that, your motor will kill your 3.3v rail and cause all sorts of odd issues. Power it from the 5v Vin pin, if you're using USB to power it all, or better a separate 5v supply.

Secondly, as already noted, the relay is a 5v component. It won't reliably pull in on 3.3v. Again power it from the 5v rail.

Confusingly those boards appear to be low-level triggered, i.e relay closes when input is low and open when input high or open-circuit. See here for similar module. So your logic would appear to be correct.
 
Last edited:

Ya’akov

Joined Jan 27, 2019
9,069
I think the way the relay board works is that when Vin is not connected to anything, the relay is off. When Vin is shorted to grounded, the relay operates.
With no power to the MCU, the relay is off.
Its not really active low.
I dont see a voltage regulator on the relay logic board, therefore I think the base of a transitor, or a gate of a fet is being pulled to ground to operate the relay.
In that case, the digital output of the MCU needs to be set as an input(high impedance) for off, and set to digital ouput and set to low to turn relay on.
The module is active low. Pulling the pin down to ground turns on the relay. In this case the choice was made to connect the pump's supply to the NC contact that means when the relay is on (pin low) the pump is off. When the relay is off, the NC contact closes and the pump runs.

Sorry about the confused communication. The problem is the logic is reversed by the choice of the NC contact. Since this means a failure of input to the pin turns on the pump, this is not failsafe. You are correct that pulling the pin down turns off the pump, but it turns on the relay to do that.
 

Irving

Joined Jan 30, 2016
3,843
In this case the choice was made to connect the pump's supply to the NC contact that means when the relay is on (pin low) the pump is off. When the relay is off, the NC contact closes and the pump runs.
But the motor is on the NO contact, isn't it?

1665754946187.png1665754516266.png
 
Last edited:

sghioto

Joined Dec 31, 2017
5,378
One possible reason for the relay staying on is if the Vcc of the relay module is 4.6 volts but the control voltage is 3 volts from the ESP8266. The transistor on the relay board is probably not switching OFF completely and the relay stays activated due to the lower dropout voltage. The LED though would appear to operate normally.
 

Irving

Joined Jan 30, 2016
3,843
This is the line that's confusing. Is he connecting a constant 4.6 volts to the Vin pin as power instead of the Vcc pin? Or does he means power from the Vin pin of the ESP8266?
Vin as in the 5v rail on the Nano ESP8266 - confusingly his drawing shows its on the 3.3v rail - though he does say later he's tried both...
 
Last edited:

Irving

Joined Jan 30, 2016
3,843
One possible reason for the relay staying on is if the Vcc of the relay module is 4.6 volts but the control voltage is 3 volts from the ESP8266. The transistor on the relay board is probably not switching OFF completely and the relay stays activated due to the lower dropout voltage. The LED though would appear to operate normally.
Good call!
1665759235643.png



Fix....
1665759202575.png
 
The odd part is the choice active low logic. It would mean if the MCU goes dead the pump would fail on. This doesn't seem to be a good design.
And the relay module seems a very odd choice of component to turn the little pump on and off. The relay is nice if you are looking to isolate the processor from the pump and turn a high power pump on and off, but this is only a 3 to 4.5V pump drawing 280mA. I don't know the current output of the processor digital output pins but even a small signal reasonably high gain NPN transistor, with resistor from processor into base, emitter to ground and pump connected between the 4.5V supply and collector would be simpler and easy to test. If indicator diodes are important, use two other output pins - with resistors in series to make sure they are not pushed beyond their current limit.
 
Hello, I'm new to using microcontrollers with relays. I purchased a kit on Amazon - https://www.amazon.com/dp/B09BMVS366?psc=1&ref=ppx_yo2ov_dt_b_product_details - that I want to control with an ESP8266 (specifically NodeMCU Amica / ESP8266MOD) following these instructions: https://poanchen.github.io/blog/202...system-that-is-connected-to-azure-iot-central. I am able to upload the software to the ESP8266, monitor the serial port to see the capacitive moisture sensor's reading and to calibrate the software to trigger the relay, which controls the pump. However, while both the software (via the serial monitor) and the relay (via the indicator lights) says I am turning the pump on and off, the relay stays on. I can get it to turn off by pulling the "In" pin or the VCC but it won't stop as it is supposed to do. I am using the "Vin" pin to power the relay, which measures 4.6V. I also tried powering it with the 3.3V pin from the 8266 and both result in the aforementioned situation.
View attachment 278262
C-like:
const int AirValue = 733; // you might need to calibrate this number, instruction is down below

const int WaterValue = 355; // you might need to calibrate this number, instruction is down below

const int DrySoilMoisturePercentage = 50;

const int SoilMoisturePin = A0;

const int RelayPin = D2;

int soilMoistureValue = 0;

int soilmoisturepercent = 0;


void setup() {

  Serial.begin(9600);

  pinMode(SoilMoisturePin, INPUT);

  pinMode(RelayPin, OUTPUT);

  digitalWrite(RelayPin, HIGH);

}


void loop() {

  soilMoistureValue = analogRead(SoilMoisturePin);

  soilmoisturepercent = map(soilMoistureValue, AirValue, WaterValue, 0, 100);

  Serial.print(soilmoisturepercent);

  Serial.println("%");

  if (soilmoisturepercent <= DrySoilMoisturePercentage) {

    Serial.println("Water pumps running...");

    digitalWrite(RelayPin, LOW);

    delay(1000);

    }

  if (soilmoisturepercent >= DrySoilMoisturePercentage) {

    Serial.println("Water pumps stopped...");

    digitalWrite(RelayPin, HIGH);

    delay(1000);

    }

}
Note that these two lines are a problem if soilmoisturepercent is 50 because they are both true and the code will toggle the relay control on and off at the speed of the code loop.
if (soilmoisturepercent <= DrySoilMoisturePercentage)
if (soilmoisturepercent >= DrySoilMoisturePercentage)

I would probably change this line to not be equal like this;
if (soilmoisturepercent > DrySoilMoisturePercentage)
 

Thread Starter

aaceith

Joined Dec 3, 2021
21
I think your logic is reversed. Should it not be to turn on pump by going high and off by going low. Also why do you initialise the relay output to high.
It may very well be. This is the circuit diagram and programming of a blog poster whose work I'm trying to duplicate. I thought the same thing that the activation of the pump should be high.
 
Top