Troubleshooting a simple logic driven MOSFET switch circuit

Thread Starter

Zurn

Joined Mar 4, 2019
115
Hi all,

I've assembled the following circuit to control the power timing for a small pump and solenoid.

Flo-Jet-Pump-Timer.jpeg



It's very simple: the Arduino turns the pump ON and the solenoid OFF for an hour and 40 minutes, then turns the pump OFF and the solenoid ON for 20 minutes. This program repeats indefinitely. Problem is when set to these particular conditions, the pump OFF/solenoid ON part only lasts 10 seconds rather than 20 minutes. Very strange.

I've tested the Arduino part thoroughly with LEDs, so I've ruled out any code errors. I'm just wondering if anyone sees something in my circuit design that might lead to the error described above. I've used this circuit with these components many times and haven't encountered this problem.
 

djsfantasi

Joined Apr 11, 2010
9,131
Hi all,

I've assembled the following circuit to control the power timing for a small pump and solenoid.

View attachment 298605



It's very simple: the Arduino turns the pump ON and the solenoid OFF for an hour and 40 minutes, then turns the pump OFF and the solenoid ON for 20 minutes. This program repeats indefinitely. Problem is when set to these particular conditions, the pump OFF/solenoid ON part only lasts 10 seconds rather than 20 minutes. Very strange.

I've tested the Arduino part thoroughly with LEDs, so I've ruled out any code errors. I'm just wondering if anyone sees something in my circuit design that might lead to the error described above. I've used this circuit with these components many times and haven't encountered this problem.
Without your code I can’t respond. Please use code tags when responding. They can be found under the menu pulled up by the three dot icon.

Plus, which Arduino model are you using? Is it a Nano? Yes, it makes a difference.
 

Thread Starter

Zurn

Joined Mar 4, 2019
115
Right... yes it's an Arduino Nano. Here's the code:

Code:
#include <Time.h>
#include <TimeLib.h>

#define TIME_HEADER  "T"   //Header tag for serial time sync message

/*PUMP ON TIME CONFIGURATION*/
const int ontimedays = 0;      //Days
const int ontimehours = 1;    //Hours   //was 1 hour and 40 mins
const int ontimemins = 40;      //Minutes
const int ontimesecs = 0;      //Seconds

/*PUMP OFF TIME CONFIGURATION*/
const int offtimedays = 0;
const int offtimehours = 0;
const int offtimemins = 20;             
const int offtimesecs = 0;

const int pumpPin = 2;
const int solePin = 3;

void offDelay(uint32_t);
uint32_t onTimeCalc(uint32_t, uint32_t, uint32_t, uint32_t);
uint32_t ontime;
uint32_t offTimeCalc (uint32_t, uint32_t, uint32_t, uint32_t);
uint32_t offtime;

void setup() {
  Serial.begin(9600);
  delay(1000);
 
  ontime = onTimeCalc(ontimedays, ontimehours, ontimemins, ontimesecs); //Maxtime variable is configured and stored in seconds
  offtime = offTimeCalc (offtimedays, offtimehours, offtimemins, offtimesecs);

  if (ontime > 0) {
    Serial.print("Pump will turn off ");
    Serial.print(ontime);
    Serial.println(" milliseconds after unit is powered on");
  }
  else {
    Serial.println("Unable to calculate pump timer");
  }

  pinMode(pumpPin, OUTPUT); //Set exit pin to output
  pinMode(solePin, OUTPUT);
  pinMode(13, OUTPUT);         //LED monitor

  digitalWrite(pumpPin, HIGH); //Initialize pump to be ON at startup
  digitalWrite(solePin, LOW);
  digitalWrite(13, HIGH);
}

void loop() {
  uint32_t crtime = 0;  //Current time
  uint32_t stime = 0;   //Start time
  uint32_t etime = 0;   //Elapsed time
  int eflag = 0;   //Exit Flag
  int lflag = 0;  //Loop flag

  delay(500);

  /*Anchor drop ops*/
  Serial.println("POWER ON, begin timer");
  stime = millis(); //

  while (1){
    while (lflag == 0) {
      delay(1000);                         //delays time check for once a second
      crtime = millis();                   //checks current time
      etime = crtime - stime;              //calculates elapsed time
 
      if (etime > ontime) {
        eflag = 1;
      }
 
      if (eflag >= 1) {
        Serial.println("Pump OFF");
        digitalWrite(pumpPin, LOW);
        digitalWrite(solePin, HIGH);
        lflag = 1;
      }
    }

    offDelay(offtime);

    Serial.println("Pump ON");
    digitalWrite(pumpPin, HIGH);
    digitalWrite(solePin, LOW);
    
    stime = millis();
    eflag = 0;
    lflag = 0;
  }
}

void offDelay(uint32_t offTimer){
  uint32_t crtime = 0;  //Current time
  uint32_t stime = 0;   //Start time
  uint32_t etime = 0;   //Elapsed time
  int eflag = 0;   //Exit Flag
 

  stime = millis();

  while(eflag == 0){
    delay(1000);
    crtime = millis();                   //checks current time
    etime = crtime - stime;              //calculates elapsed time
 
    if (etime > offTimer) {
      eflag = 1;
    }
  }

  eflag = 0;
}


//Calculates ontime variable in milliseconds
uint32_t onTimeCalc(uint32_t ontimeday, uint32_t ontimehour, uint32_t ontimemin, uint32_t ontimesec) {
  uint32_t time;
  uint32_t dd, hh, mm, ss;

  dd = ontimeday * 86400000;
  hh = ontimehour * 3600000;
  mm = ontimemin * 60000;
  ss = ontimesec * 1000;

  time = dd + hh + mm + ss;

  return time;
}

//Calculates offtime variable in milliseconds
uint32_t offTimeCalc(uint32_t offtimeday, uint32_t offtimehour, uint32_t offtimemin, uint32_t offtimesec) {
  uint32_t time;
  uint32_t dd, hh, mm, ss;

  dd = offtimeday * 86400000;
  hh = offtimehour * 3600000;
  mm = offtimemin * 60000;
  ss = offtimesec * 1000;

  time = dd + hh + mm + ss;

  return time;
}
 

Thread Starter

Zurn

Joined Mar 4, 2019
115
Have you checked to make sure the solenoid is operating correctly?

IE: Not drawing too much current.
This is a great question, given that I just tested it without the solenoid attached and everything worked fine.

Unfortunately I don't have the solenoid with me at the moment. It's a cheap 12V one off amazon though, doesn't even have a model number. I did check it's current draw before I hooked it up - drew 550mA. How it's behaving now I can't say, but it certainly seems like the most likely culprit given the evidence...

The confusing thing is that even if there's something wrong with the solenoid, it doesn't explain why the pump would turn back on (i.e. the D2 pin on the arduino would go HIGH again) after only 10 seconds. Very strange.

Something I should have stressed from the beginning though: this error condition has only been described to me by the person I built this system for. I've yet to actually see it happen with my own eyes.
 

ElectricSpidey

Joined Dec 2, 2017
2,642
Well, that's about 6.6 watts on your regulator...is it on a heatsink?

After reading your edit...

Is the pump the first thing that comes on after the micro boots? If so, it would do exactly that after a regulator going into and coming out of protection mode.
 
Last edited:

Alec_t

Joined Sep 17, 2013
14,014
Do you have back-emf protection diodes across the solenoid coil and across the pump motor? Methinks switching voltage spikes could be interfering with the Nano operation, perhaps resetting it prematurely.
Do you have a star ground arrangement for the coil, pump, Nano and its supply?
 

Thread Starter

Zurn

Joined Mar 4, 2019
115
All excellent observations!

The regulator does not have a heatsink on it. Rookie mistake. However, I'm going to replace it with a fancy dc-dc converter for the sake of robustness.

Both the pump and the coil do not have back emf protection diodes. I'll add that as well.

Hopefully one of those two does the trick.
 

djsfantasi

Joined Apr 11, 2010
9,131
Re: your code
The way it is written, there is no need to have separate functions for onTimeCalc and offTimeCalc. You are passing the on and off time constants to the function. Thus, you can use different local variable names inside the function and use the same code in both cases.

In fact, this could be causing a problem. You define the on and off times as constants. There may be some confusion as function parameters are treated as variables but you have them also defined as constants. Since they are global variables, there is no need to pass them as parameters. That’s if you keep two functions. This problrm doesn’t exist if you have one function using local variables to which the constants are passed.

Re: Back-EMF Protection Diodes
Without them, there is a good chance you MOSFETs have been damaged. And possibly the Nano D2 and D3 pins.
 
Top