Arduino Uno with relay not looping with high delay

Hello! First post, so forgive me if I miss something that I should include.

I'm trying to power a 12v water pump to run every 3 hours for 15 minutes (the exact timing is not a big deal, a few minutes early or late would be fine). Every code I've tried works at first, but ultimately stops after the first loop (unless I turn the delay wayy low).

I've tried the blinkWithoutDelay example, and a few different codes:

const uint8_t       pinWATER_PUMP_RELAY         = 3;

const uint8_t       WATER_PUMP_OFF              = LOW;
const uint8_t       WATER_PUMP_ON               = HIGH;

const unsigned long ONE_SECOND                  = 1000UL;
const unsigned long ONE_MINUTE                  = 60UL * ONE_SECOND;
const unsigned long ONE_HOUR                    = 60UL * ONE_MINUTE;
const unsigned long THREE_HOURS = 3UL * ONE_HOUR;
const unsigned long WATER_PUMP_TIME_ON          = 15UL  * ONE_MINUTE;
const unsigned long WATER_PUMP_TIME_NEXT_CYCLE  = THREE_HOURS - WATER_PUMP_TIME_ON;
void setPump(uint8_t state)
{
    digitalWrite(pinWATER_PUMP_RELAY, state);
}
void cycleWaterPump()
{
    setPump(WATER_PUMP_ON);
    delay(WATER_PUMP_TIME_ON);
    setPump(WATER_PUMP_OFF);
}
void loop()
{
    cycleWaterPump();
    delay(WATER_PUMP_TIME_NEXT_CYCLE);
}
void setup()
{
    pinMode(pinWATER_PUMP_RELAY, OUTPUT);
    setPump(WATER_PUMP_OFF);
}

And (ignore the timings here,

const int PumpPin = 3;
constexpr unsigned long OffDuration = 20000;// OFF time for Pump
constexpr unsigned long OnDuration = 3000;// ON time for Pump
constexpr unsigned long PumpTimes[] {OffDuration,OnDuration};
void setup()
{
  pinMode(PumpPin, OUTPUT); // define LEDpin as output
  digitalWrite(PumpPin, LOW); // set initial state
}
void loop() 
{
  static unsigned long timeStamp=millis();  
  if (millis()-timeStamp>=PumpTimes[digitalRead(PumpPin)]) 
  {
    timeStamp=millis(); 
    digitalWrite(PumpPin,digitalRead(PumpPin)^1); 
  }
}

And the very first thing I tried, the most basic code of them all:

const int RELAY_PIN = 3;  // the Arduino pin, which connects to the IN pin of relay
// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin as an output.
  pinMode(RELAY_PIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
  digitalWrite(RELAY_PIN, LOW);
  delay(14400000 );
  digitalWrite(RELAY_PIN, HIGH);
  delay(780000);
}```


Both the relay and Arduino Uno board are using a 12v power cable, and with small time delays it works fine.

Any advice is greatly appreciated, thanks!

Great work - first post, using code tags. :+1:

I’d start by suggesting you look at getting rid of the delays…

Use millis() timing, then you can do other things or monitor the progress while the processor is doing ‘nothing’

The idea is you do things when they’re due… not sit around doing absolutely nothing.

EDIT: Thanks, I didn’t see the re-post of new code.

As you suggest, it’s worth shortening the periods so you can test more easily… minutes at a time mihpght be easier.

1 Like

Correct me if I'm wrong, but the second code I tried used millis did it not?

const int PumpPin = 3;
constexpr unsigned long OffDuration = 14400000 ;// OFF time for Pump
constexpr unsigned long OnDuration = 780000;// ON time for Pump
constexpr unsigned long PumpTimes[] {OffDuration,OnDuration};
void setup()
{
  pinMode(PumpPin, OUTPUT); // define LEDpin as output
  digitalWrite(PumpPin, LOW); // set initial state
}
void loop() 
{
  static unsigned long timeStamp=millis();  
  if (millis()-timeStamp>=PumpTimes[digitalRead(PumpPin)]) 
  {
    timeStamp=millis(); 
    digitalWrite(PumpPin,digitalRead(PumpPin)^1); 
  }
}

Perhaps I did something wrong there (aside from those times I was using for shorter tests), I can give it another shot and report back tomorrow (lil late here in EST).

Edit: I missed your edit, sorry! The only problem I have with that is that shorter times seem to work fine, I figured it might be a number limit but if I'm not mistaken it can handle MS up to 49 days.

What kind of relay? Do you have a kickback diode in parallel with the pump leads?
A suggestion, UNTESTED.

unsigned long timer,
              cycleTime = 10800000, // 3 hours
              onTime = 9900000; // 3 hours - 15 minutes
const byte relayPin = 3;
void setup()
{
   pinMode(relayPin,OUTPUT);
}
void loop()
{
   if(millis() - timer > cycleTime)
     timer += cycleTime;
   digitalWrite(relayPin,millis() - timer > onTime);
}

Do I need a kickback diode in this?

For simplicity sake, I followed this guide pretty closely, the only thing I switched from the supply list was the pump and a 12v power cable for the Arduino instead of 9. The relay is using the 5 volt pin (tested with a multimeter), and it has a 5 volt coil so that part should match up.

As for that code sample, I will test it out tomorrow. Like I said, everything above that I tried worked fine for short periods (if I did a 1 min on 5 mins off, etc.), I only noticed issues with the high values so I will leave it set to 3 hours.

Sorry for the delayed response, but still no dice there.

I ended up taking an arduino free approach and got an outlet timer that could run on an interval.

Hello jgilbrook

Consider.

/* BLOCK COMMENT
  - https://forum.arduino.cc/t/arduino-uno-with-relay-not-looping-with-high-delay/1104600
*/
#define ProjectName "Arduino Uno with relay not looping with high delay"
// I am too lazy to type
#define usl unsigned long
// make variables
constexpr int PumpPin {9};
// make structures
struct TIMER
{
  usl span[2];
  usl now;
};
TIMER pumpTimer {{3*60*60*1000,15*60*1000},0};
// tools
void heartBeat(int LedPin)
{
  static bool setUp = false;
  if (!setUp) pinMode (LedPin, OUTPUT), setUp = !setUp;
  digitalWrite(LedPin, (millis() / 1000) % 2);
}
void setup()
{
  Serial.begin(115200);
  Serial.print(ProjectName), Serial.print(" in "), Serial.println(__FILE__);
  pinMode(PumpPin,OUTPUT);
}
void loop()
{
  usl currentMillis = millis();
  heartBeat(LED_BUILTIN);
  if (currentMillis-pumpTimer.now>=pumpTimer.span[digitalRead(PumpPin)]);
  {
    pumpTimer.now=currentMillis;
    digitalWrite(PumpPin,digitalRead(PumpPin)==HIGH?LOW:HIGH);
  }
}


This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.