Polarity changer Send single pulse to start and single pulse to stop

Hi

To open a solenoid valve I need to send a 1 sec signal polarity +-
to close it another 1 sec signal with polarity changed -+
Valve can not have load more than a few sec, no load while running.

To initiate I use smart house actuator, the actuator sends 5V (HIGH) signal from start until stop.

relay module
image

Idea:

Under is my code, I strugle to find a way to only send 1 signal for swith solonoid valve on, and 1 signal for off.

I also strugle to understand if I need a int (xxx) in setup.

Any who can help me with the code?

// Credit: https://www.youtube.com/watch?v=BQOji4i4PEc
// https://www.instructables.com/DIY-Relay-switch-motor-controller-Arduino/
// Card: WeMos D1 mini Pro
// Relay module to change polarity
// Solenoid mentioned under can NOT have continually load, only a 1 sec signal
// Smart house sends continuously HIGH (+5V) to switch on water. 
// Solenoid needs 9V to operate +-= ON  -+=OFF
// This HIGH give a 1 sec pulse from relay module +- to an water valve solenoid. 
// When smart house sends LOW a 1 sec pulse -+ to an water valve solenoid

#define ON 7        //"Water on" is defined as pin #7 ---//
#define OFF 8       //"Water off" is defined as pin #8//
#define SIGNAL 9    //5V signal from smart house, high start water, low stop water as pin #9// 


void setup() { //Setup runs once//

  pinMode (SIGNAL,INPUT); //read input from smart house actuator
  pinMode(ON, OUTPUT); //Set ON as an output//
  pinMode(OFF, OUTPUT); //Set OFF as an output// 
   
  int SIGNAL =
}

void loop() { //Loop runs forever//

/*
 * Issue, how to only send a ON signal for 1 sec while SIGNAL read is high?
 * Code under sends 1 sec on for each loop
 */

}
  if (SIGNAL = HIGH){
    digitalWrite(ON,HIGH);   //Wather on, 1 sec pulse - wather is runnning// 
    delay(1000)              //sends +- to solonoid
    digitalWrire(OFF,LOW)     // swithc of signal to solnoid actuator
    digitalWrire(ON,LOW)      // swithc of signal to solnoid actuator
  }                             
  else{
    digitalWrite(OFF,LOW);    // swithch of wather
  }                               



You may get some idea from Fig-1 how to open/close the solenoid valve.


Figure-1:

Sample Codes:

for(int i= 2; i< 6; i+=)
{
    pinMode(i, OUTPUT);  //DPin-2 to 5 are outputs
}

for(nt i = 0; i<6; i+=)
{
     digitalWrtie(i, LOW);  //all relays are OFF
}

digitalWrite(2, LOW);
digitalWrite(3, LOW);  
delay(1000);                 //Solenois Valves receives +/- power from 9V for 1-sec
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);

 digitalWrite(4, LOW);
digitalWrite(5 LOW);  
delay(1000);                 //Solenois Valves receives -/+ power from 9V for 1-sec
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
2 Likes

You only need to use 2 relays... connect NO and NC to gnd and 9V, respectively, on both. Then connect the solenoid to the two armature contacts.

2 Likes

That would certainly do; but, at the cost of clarity.

1 Like

Sometimes the relay module that people post an image of, is not the same one they actually have. :slight_smile:

I don't know why people do things like that, but often they do...

1 Like

Hi

thanks for your input.

I'm not so skilled in reading arduino code but I don't see how to use this, maybe I missunderstand.

As I understand are you using 4 relays. I'm planning to use only 2, from WeMos pin D5 and D6
D7 reads the SIGNAL (High or Low)

The part under I understand, but with 2 relays it is different from what I need

digitalWrite(2, LOW);
digitalWrite(3, LOW);  
delay(1000);                 //Solenois Valves receives +/- power from 9V for 1-sec
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);

 digitalWrite(4, LOW);
digitalWrite(5 LOW);  
delay(1000);                 //Solenois Valves receives -/+ power from 9V for 1-sec
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);

My issues is as follow:

  1. How to send a 1 sec high only one time in the loop when SIGNAL is high
    2 How to send a 1 sec low only one time after SIGNAL is low
  2. Maybe pins 4-5-6 is a bad choice, but so fare it gives the story.

Here is my updated code:

#define SIGNAL 4    //5V signal from smart house, high start water, low stop wather// 
#define ON 5        //"Water on" is defined as pin #5 ---//
#define OFF 6       //"Wather off" is defined as pin #6//


void setup() { //Setup runs once//

  pinMode (SIGNAL,INPUT); //read input from smart house acutuator
  pinMode(ON, OUTPUT); //Set ON as an output//
  pinMode(OFF, OUTPUT); //Set OFF as an output// 
   
  int SIGNAL =
}

void loop() { //Loop runs forever//

/*
 * Issue, how to only send a ON signal for 1 sec while SIGNAL read is high?
 * Code under sends 1 sec on for each loop
 */

}
  if (SIGNAL = HIGH){
    digitalWrite(ON,HIGH);   //Wather on, 1 sec pulse - wather is runnning// 
    delay(1000)              //sends +- to solonoid
    digitalWrire(OFF,LOW)     // swithc of signal to solnoid actuator
    digitalWrire(ON,LOW)      // swithc of signal to solnoid actuator
  }                             
  else{
    digitalWrite(OFF,LOW);    // swithch of wather
  }     

Here is my pin and connections

You have the circuit that I suggested. I don't have time to look at the code. Are you comfortable with the switching logic? It would be like:

Solenoid active (+) - in1=0 in2=1
Solenoid active (-) - in1=1 in2=0
Solenoid not active - in1=0 in2=0 or in1=1 in2=1

Hi, in my case the relay board is the one I have.

Hi again aarg

Then I did not understand the relay layout.

If you can look at the code I would appreciate it.

I'm new to programing Arduino, stated to think about it a few months ago.

My previous programming skills are from 1980-1985 with Basic on a Commodore 64, then in 1990 Pascal. After 1991 I have done no programming. Yes, I'm pretty old :slight_smile: but eager to relearn my skills after my kids moved out. I also played a lot with TTL integrated circuits and 7 segments LED in the 80's.

I don't think it's necessary. At least, to answer the question of how to operate the solenoid. Basically, you can create three functions that send the + pulse, the - pulse, and turn it off. You can then use those in some code to operate the solenoid, you can pick blocking or non-blocking timing as you desire.

Here are the functions (I'm really just coding what is given in post #7).

void solenoid_plus_set() {
 digitalWrite(5, LOW);
 digitalWrite(6, HIGH); 
}
void solenoid_minus_set() {
 digitalWrite(5, HIGH);
 digitalWrite(6, LOW); 
}
void solenoid_off() {
 digitalWrite(5, LOW);
 digitalWrite(6, LOW); 
}

A blocking pulse generation would look like:

void solenoid_plus_pulse() {
 solenoid_plus_set();
 delay(1000);
 solenoid_off();
}

Then I did not understand the relay layout.

Your diagram looks correct at first sight. So I think either you do understand, or you can understand by looking it over some more.

1 Like

Hi again, thanks for your help to understand

The Princip, as I understand you try to explain me, is to make a code like this, with my words, not perfect code.

**PSAUDO CODE .....  MY OWN WORDS**


#define SIGNAL 4      // +3.3V signal from smart house, high start water, low stop wather// 
#define RELAY1 5        // "Water on" is defined as pin #5 ---//
#define RELAY2 6       // "Wather off" is defined as pin #6//

void setup() { //Setup runs once//

  pinMode(SIGNAL, INPUT); //read input from smart house acutuator, high or low +3.3V
  pinMode(RELAY1, OUTPUT); //Set RELAY1 as an output//
  pinMode(RELAY2, OUTPUT); //Set RELAY2 as an output// 
  int input = digitalRead(SIGNAL);
}

void loop(){

if SIGNAL=HIGH then RELAY1 LOW + RELAY2 HIGH      //switch solenoid on
delay(1000)
and 
if RELAY1 is HIGH and RELAY2 is LOW then      //disable load to solenoid
RELAY1=LOW and RELAY2=LOW


if SIGNAL=LOW then switch on RELAY1 HIGH + switch RELAY2 LOW  //switch solenoid off
delay(1000)
and 
if RELAY1 is HIGH and RELAY2 is LOW then      //disable load to solenoid
RELAY1=LOW and RELAY2=LOW
}

M

You need to decide whether to use pseudocode or C/C++. That is a mixture of the two that doesn't help. You're also unable to write unambiguous pseudocode. So I suggest sticking to C.

I think you are trying to say this:

if SIGNAL=HIGH
{
RELAY1 LOW + RELAY2 HIGH      //switch solenoid on
delay(1000)
if RELAY1 is HIGH and RELAY2 is LOW then      //disable load to solenoid
    RELAY1=LOW and RELAY2=LOW
}
else
{
switch on RELAY1 HIGH + switch RELAY2 LOW  //switch solenoid off
delay(1000)
if RELAY1 is HIGH and RELAY2 is LOW then      //disable load to solenoid
    RELAY1=LOW and RELAY2=LOW
}

Which is clearer, but doesn't follow the relay logic I handed you.

Please walk through this code. What happens when the signal is dormant (remains off for a while)? I'll tell you - the 'else' clause is repeated over and over in loop(), which means the solenoid will continuously toggle. I doubt that is what you want.

1 Like

Hi

thanks again. I will study your code and do a new try.

Sorry for not be able to write clear syntax, I'm trying as good as I can, hopefully it will improve over time.

I used this relay logic:

Solenoid active (+) - in1=0 in2=1
Solenoid active (-) - in1=1 in2=0
Solenoid not active - in1=0 in2=0 or in1=1 in2=1

Where
in1 = RELAY1 (pin D5)
in2=RELAY2 (pin D6)

and commands to switch

on: RELAY1=LOW + RELAY2=HIGH
off: RELAY1=HIGH + RELAY2=LOW
not active: RELAY1=LOW + RELAY2=LOW

You did not use this relay logic:

void solenoid_plus_pulse() {
 solenoid_plus_set();
 delay(1000);
 solenoid_off();
}

You put the commands into inline code, but also inserted an inexplicable 'if' clause. I'm not really sure what you wanted it to do.
The code I gave you is runnable, why don't you just use it...

1 Like

Hi again

I had a break true, I think understood the function and calls.

Next step is to avoid the relay to switch on and off each second when SIGNAL is low (no more water needed in my garden. For this I need some kind of code that understands that SIGNAL has been LOW more than 1 sec, and then disable the to functions that trigger that trigger RELAY1 high and after 1 sec switchs off RELAY1 in the loop.

If loop:

if (SIGNAL = LOW) {
solenoid_minus_set();
delay(1000);
solenoid_off();
}

Function:

void solenoid_minus_set() { // switch off -+
digitalWrite(RELAY1, HIGH);
digitalWrite(RELAY2, LOW);
}

Function:

void solenoid_off() { //disable relays
digitalWrite(RELAY1, LOW);
digitalWrite(RELAY2, LOW);
}

This code compilates:

int SIGNAL = D5;      // +3.3V signal from smart house, high start water, low stop wather
int RELAY1 = D6;      // to COM1 relay is defined as pin #6
int RELAY2 = D7;      // to COM2 relay is defined as pin #7

void setup() { //Setup runs once//
  pinMode(SIGNAL, INPUT);  //read input from smart house acutuator, high or low +3.3V / 0V
  pinMode(RELAY1, OUTPUT); //Set RELAY1 as an output//
  pinMode(RELAY2, OUTPUT); //Set RELAY2 as an output//
  int input = digitalRead(SIGNAL);
}

void solenoid_plus_set() {      // swith on +- 
  digitalWrite(RELAY1, LOW);
  digitalWrite(RELAY2, HIGH);
}
void solenoid_minus_set() {     // switch off -+
  digitalWrite(RELAY1, HIGH);
  digitalWrite(RELAY2, LOW);
}
void solenoid_off() {           //disable relays
  digitalWrite(RELAY1, LOW);
  digitalWrite(RELAY2, LOW);
}

void loop()
{
  if (SIGNAL = HIGH) {
    solenoid_plus_set();
    delay(1000);
    solenoid_off();
  }
  if (SIGNAL = LOW) {
    solenoid_minus_set();
    delay(1000);
    solenoid_off();
    // STOP RUNNING to avoid RELAY2 to svitch on/off each 1000 mill, GO TO DEEP SLEAP AND WAIT FOR SIGNAL=HIGH
    // https://playground.arduino.cc/Learning/ArduinoSleepCode/
    //}
  }
}

Okay, write it. It's not our job to write code for you.

By the way, you have missed a point... this logic:

  if (SIGNAL = HIGH) {
...
  }
  if (SIGNAL = LOW) {
...
}

is why the 'else' statement exists. Also you have used assignment = , not a test for equality ==.
It must be

  if (SIGNAL == HIGH) {
...
  }
  if (SIGNAL == LOW) {
...
}

Stop and think for a moment. If it is HIGH, can it be LOW at the same time? Of course not! So you really have

  if (SIGNAL == HIGH) {
...
  }
  else {
...
}
1 Like

Hi

I have mede the circuit and it runs, but it don't change state when I connect D5 to pin +3.3v, also tried to connect to Ground.

System reads only SIGNAL=HIGH (output to serial monitor)
And the function

solenoid_off();

dont kick in

image

I have tried to connect D5 to ground, no change.

I have also tested SIGNAL on D4 and A0, same result.

Q to you:
Why don't relay operation change when I give 3.3v to pin D5 (and D4, A0)?

What is the magic solution

Code

int SIGNAL = D5;      // +3.3V signal from smart house, high start water, low stop wather
int RELAY1 = D6;      // to COM1 relay is defined as pin #5
int RELAY2 = D7;      // to COM2 relay is defined as pin #6


void setup() { //Setup runs once//
  Serial.begin(57600);
  Serial.println();
  Serial.println("Starting...");
  pinMode(SIGNAL, INPUT);  //read input from smart house acutuator, high or low +3.3V / 0V
  pinMode(RELAY1, OUTPUT); //Set RELAY1 as an output//
  pinMode(RELAY2, OUTPUT); //Set RELAY2 as an output//
  int input = digitalRead(SIGNAL);
}

void solenoid_plus_set() {      // swith on +-
  digitalWrite(RELAY1, LOW);
  digitalWrite(RELAY2, HIGH);
}
void solenoid_minus_set() {     // switch off -+
  digitalWrite(RELAY1, HIGH);
  digitalWrite(RELAY2, LOW);
}
void solenoid_off() {           //disable relays
  digitalWrite(RELAY1, LOW);
  digitalWrite(RELAY2, LOW);
}

void loop()
{

  if (SIGNAL = HIGH) {
    Serial.print("SIGNAL HIGH 2 sek");
    Serial.println();
    solenoid_plus_set();
    delay(2000);
    solenoid_off();
  }
  //delay(5000);
  if (SIGNAL = LOW) {
    Serial.print("SIGNAL LOW 4 sek");
    Serial.println();
    solenoid_minus_set();
    delay(4000);
    solenoid_off();
    Serial.print("Delay 6 sek");
    delay(6000);

    // STOP RUNNING to avoid RELAY2 to svitch on/off each 1000 mill, GO TO DEEP SLEAP AND WAIT FOR SIGNAL=HIGH
    // https://playground.arduino.cc/Learning/ArduinoSleepCode/
  }
}

Read the advice you're given? I told you, you are using assignment statements instead of test for equality. I gave examples. You are too difficult to work with, so someone else will have to help you.

Hi aarg
Sorry to hear, I did try to ask and code, but not easy to get it when my experience is from a Commodore64 in 1980

Anyway, thanks for your help! I will go on to make this work.

Here is the latest code, works except that it always reeds LOW, also when I connect 3.3v to D5 SIGNAL, same when connect to ground.

int SIGNAL = D5;      // +3.3V signal from smart house, high start water, low stop wather
int RELAY1 = D6;      // |to COM1 relay is defined as pin #6
int RELAY2 = D7;      // to COM2 relay is defined as pin #7


void setup() { //Setup runs once//
  Serial.begin(57600);
  Serial.println();
  Serial.println("Starting...");
  pinMode(SIGNAL, INPUT);  //read input from smart house acutuator, high or low +3.3V / 0V
  pinMode(RELAY1, OUTPUT); //Set RELAY1 as an output//
  pinMode(RELAY2, OUTPUT); //Set RELAY2 as an output//
  int input = digitalRead(SIGNAL);
}

void solenoid_plus_set() {      // swith on +-
  digitalWrite(RELAY1, LOW);
  digitalWrite(RELAY2, HIGH);
}
void solenoid_minus_set() {     // switch off -+
  digitalWrite(RELAY1, HIGH);
  digitalWrite(RELAY2, LOW);
}
void solenoid_off() {           //disable relays
  digitalWrite(RELAY1, LOW);
  digitalWrite(RELAY2, LOW);
}

void loop()
{

  if (SIGNAL == HIGH) {
    Serial.print("SIGNAL HIGH 2 sek");
    Serial.println();
    solenoid_plus_set();
    delay(2000);
    solenoid_off();
  }
  //delay(5000);
  else {
    Serial.print("SIGNAL LOW 4 sec delay");
    Serial.println();
    solenoid_minus_set();
    delay(4000);
    solenoid_off();
    Serial.print("Solenoid off, delay 5 sek");
    Serial.println();
    delay(5000);

    // STOP RUNNING to avoid RELAY2 to svitch on/off each 1000 mill, GO TO DEEP SLEAP AND WAIT FOR SIGNAL=HIGH
    // https://playground.arduino.cc/Learning/ArduinoSleepCode/
  }
  Serial.print("Loop done.......................!");
  Serial.println(); Serial.println();
}

Same serial print when connect D5 to 3.3V

image

Fixed V0.1 :slight_smile:

Next step, V0.1, fine tuning regarding power up due to all system will be powered off while not in ON status. V0.1 starts with both relays HIGH.

Code:

const int SIGNAL = D5;
#define RELAY1 D6      // to COM1 relay is defined as pin #5
#define RELAY2 D7      // to COM2 relay is defined as pin #6
boolean lastStatus = 0;
boolean value = 0;


void setup() { //Setup runs once//
  delay(2000); // wait for power up
  Serial.begin(57600);
  Serial.println();
  Serial.println("Starting...");
  pinMode(SIGNAL, INPUT);  //read input from smart house acutuator, high or low +3.3V / 0V
  pinMode(RELAY1, OUTPUT); //Set RELAY1 as an output//
  pinMode(RELAY2, OUTPUT); //Set RELAY2 as an output//
  //int input = digitalRead(SIGNAL);

}

void solenoid_plus_set() {      // swith on +-
  digitalWrite(RELAY1, HIGH);
  digitalWrite(RELAY2, LOW);
}
void solenoid_minus_set() {     // switch off -+
  digitalWrite(RELAY1, LOW);
  digitalWrite(RELAY2, HIGH);
}
void solenoid_off() {           //disable relays
  digitalWrite(RELAY1, HIGH);
  digitalWrite(RELAY2, HIGH);
}

void main_loop_action() {
  if (value == 1) {
    Serial.print("Status: Water ON");
    Serial.println();
    solenoid_plus_set();
    delay(500);
    solenoid_off();
  }
    else {
    Serial.print("Stats: Water OFF");
    Serial.println();
    solenoid_minus_set();
    delay(500);
    solenoid_off();
    // Serial.print("Solenoid off, delay 5 sek");
    Serial.println();
    delay(500);

    // STOP RUNNING to avoid RELAY2 to svitch on/off each 1000 mill, GO TO DEEP SLEAP AND WAIT FOR SIGNAL=HIGH
    // https://playground.arduino.cc/Learning/ArduinoSleepCode/
  }
  Serial.print("Loop done...........................................................!");
  Serial.println(); Serial.println();
}

void loop()
{
  value = digitalRead(SIGNAL);

  boolean currentStatus = value;

  Serial.print("SIGNAL value (1=Water on, 0=water off): ");
  Serial.println( value );

  if (lastStatus == currentStatus) {
    Serial.print("Loop done...........................................................!");
    Serial.println(); Serial.println();
    delay(500);
  }
  else {
    lastStatus = currentStatus;
    main_loop_action();
  }
}