Is digitalWrite necessary for 12v solenoids with relays and mosfets?

The project I'm working on became a bit more complicated than anticipated, so I upgraded to a Mega this week. Now I'm thinking about upgrading the 12v side to IRFZ44N mosfets. Have been using two sets of 8-channel optocoupled relays, but want to gain some speed during different operations vs waiting between relay calls, and hoping it'll help in cleaning up the wiring a bit.

The relays control sixteen 12v solenoid & ball valves, which are used to control recirculation of different liquids & gases back into their given reservoirs. The liquids should not be mixed together, else a reaction could occur; one of them is an acid.

I want to dummy proof things a bit, speed up the process, and minimize residual liquids in the pipes. So, are the initial LOW/HIGH calls to the relays with digitalWrite to check the relays necessary?

int PINS[15] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19 }; // Pin 13 used by something else
void setup() {
 for (int j = 0; j <= 15; j++) {
    pinMode(PINS[j], INPUT_PULLUP);
    pinMode(PINS[j], OUTPUT);
  }
}
void loop(){
  for (int k = 15; k >= 0; k--) {
    if (k > 9) {
        digitalWrite(PINS[k], LOW);   // slower ball valves, allow 5 second openings.
        time_5_sec(); 
        digitalWrite(PINS[k], HIGH);  // close slowly too, but moving on while they do...
        time_1_sec();
    } else {
        digitalWrite(PINS[k], LOW);   // want to replace relays with mosfets for faster timing. 
        time_1_sec();
        digitalWrite(PINS[k], HIGH); 
        time_1_sec();
    }
  }
}

Note: The slower ball valves get called first, mostly because they were added last and control the different reservoirs.

Please look at forum usage and post your code using code tags an provide a circuit diagram ( hand drawn would be good )

You need to look at this aspect carefully , you cannot rely on the Arduino not going wrong if this is a safety issue - hard wire interlocking is a good move .
Any digital output will need a digital write signal to switch it .

If you're driving them directly from the Mega, you will need the IRLZ44N version.

You didn't post the entire sketch. Please auto format first, using ctrl-T to correct the lack of indentation for easy reading.

there is no dummy proof design.
Dumb things will happen.
But you could wire the relays in away, that the relay output either connects to the valve (NO) or forwards power to the next relay (NC of first relay to COM of second relay). With this wiring you could at least avoid that two valves get active at the same time even if two relays are active, as the first active relay interrupts power for the next relay.

Original post has been edited and the proper code tags added. Will draw up and upload the circuit diagram shortly.

You still didn't post the entire sketch.

Spent several hours trying to draw it out, but the diagrams were overly complicated, mostly due to my adding the various Power Sources to run the Relays separate from the Arduino, wiring, etc. If it's okay for now, I'll use a more simple word diagram. All valves are 12v, Normally Closed, and 2-wired. Current setup uses pins 3-19, but only showing pin 3 to keep it simple:

Arduino:
Pin 3 <----> Relay, pin 1 
5V    <----> Relay, pin vcc

Relay (5v side):
5v PS gnd     ----> Relay PS gnd
5v PS vcc     ----> Relay PS JD-VCC
Arduino 5v    ----> Relay VCC
Arduino Pin 3 <---> Relay Pin 1
    <--optocoupler-->
Relay (12v side):
Relay <-- COM/NO --> Solenoid & 12v PS

Solenoid (12v side):
12v pos --> Relay, COM
12v gnd --> D1, IN4007 +parallel+ solenoid --> Relay, NO

Some of this is redundant, but when I switch to mosfets:

Arduino, Pin 3 <----> Mosfet 1, gate && 10kΩ ----> 12v ground
Arduino, Gnd <------> 10kΩ && Mosfet 1, source --> 12v ground

Mosfet 1, Gate -----> Arduino, Pin 3 && 10kΩ ----> gnd
Mosfet 1, Drain ----> Solenoid 1 +parallel+ D1, IN4007
Mosfet 1, Source ---> 12v ground + Arduino ground (&& 10kΩ)

Solenoid 1, (left) ---> D1, IN4007 (flyback) +parallel+ 12v pos
Solenoid 1, (right) --> D1, IN4007 (flyback) +parallel+  Mosfet 1, Drain

Can understand your frustration but words just don’t cut it; you will lose the attention of 99.9% of helpers.

Using a proper schematic is the way you communicate with others regarding your wiring. :woozy_face:

Drawing a schematic for your project is the first thing that users should do and always seems to be the last thing that is done if at all :weary: .

2 Likes

For the mosfet, something like this:
https://adam-meyer.com/arduino/images/2012/03/rfp30n06le-arduino-solenoid.png

https://adam-meyer.com/arduino/N-Channel_MOSFET

You make every pin an OUTPUT. Making it an INPUT_PULLUP first does nothing.

What did you mean to accomplish with that?

Then your loop() function will forever open and close one valve at a time, with a certain time open and the a resting time before the next.

Which may be just a test at this time. If it is a test program, please say more about the real goal. The way you've coded the test is not a good point of departure for anything much more than you are doing, as those time_N_seconds() calls look like they block, that is your sketch goes brain dead for that period, and nothing else can be done.

If you switch to MOSFET, it's gonna be HIGH on the output pins that energizes the valve. Perhaps your relay board or the contacts you chose to use needed LOW to ultimately energize the valve.

Use the RFP30N06LE or make sure if you pick a different transistor that it too is a logic level MOSFET that can handle the current.

Most MOSFET circuits like that will show a small (100 ohm or so) resistor between the gate and the output pin, and as the drawing you link showed, a larger resistor from the pin to ground.

a7

In that case, you definitely need positional feedback from each and every valve and solenoid that you are using.

This turns on internal pull up,
and that is needed for relay modules with opto couplers that are active LOW.
It stops the relays from briefly activating (relay chatter) during bootup.

Not sure if it works that way in a for loop,
because you should first pull up all pins before setting them to OUTPUT.

This is of course a bad idea if you use mosfets.
You want the gates LOW on bootup.
For mosfets a pull down resistor is used.
Leo..

No, it does not.

Internal pull-ups are for inputs.

In any case, setting one pinMode and then immediately setting that pin to another pinMode will leave the pin in the last pinMode it was set to.

It makes no sense.

In the old days, there was no INPUT_PULLUP mode, so you will sometimes see

    pinMode(pin, INPUT);     // make it an input 
    digitalWrite(pin, HIGH); // turn on the internal pull-up

The effect of the OP's sequence is identical to that which would obtain if s/he left off the first line in the loop.

a7

This was originally written to cover the optocouplers, as Wawa pointed out. I eventually placed it all in an array + for loop to minimize sketch bloat; goal is simplicity and < 500 lines of code.

Safety additions were to reduce the handling of acids & chemicals by humans. I did this by adding a few more valves to control egress destinations, and one extra temperature check point. Once everything was added, it was apparent it was time to upgrade to the Mega and mosfets. And here I am...

Yes. it does.

The old way to stop chatter for those relay modules was

digitalWrite(pin, HIGH); // turn on pull up while pin is still an input
pinMode(pin, OUTPUT); // set pin to output

And it leaves the pin in a HIGH state.
Leo..

I would have used

for (int j = 0; j < 16; j++)  pinMode(PINS[j], INPUT_PULLUP); // first take care of pull up
for (int j = 0; j < 16; j++) pinMode(PINS[j], OUTPUT); // then set all to output

Leo..

Not for me. I'm out.

Yes, I see. THX for making me look closerly.

It is just a bit odd to write it that way, typically one would not obscure what was happening by using a pinMode() call where digitalWrite() would be clearer.

Although I may have complained about writing to a pin that was still in INPUT mode from the reset. :expressionless:

Indeed in direct port manipulation we see that the pullups are enabled by 1s in the port output register.

So pullups don't enter into it, it is a distraction to mention them. Distracted me anyway.


    digitalWrite(pin, HIGH);    // make it high
    pinMode(pin, OUTPUT);       // before you give it the ability to assert either logical condition

I will flog myself with a damp trout to atone.

a7