1

I have an arduino to control an irrigation system, consisting on one pump (called "bomba" on the code) and 5 12V water valves.

Each valve controls one irrigation circuit and the idea is to open each one sequentially during one minute and then move on to the next one.

The code is this:

const int TIEMPO_RIEGO = 64; // seconds

const int TRIGGER = 5;

const int BOMBA = 6;
const int CIRCUITO_1 = 8;
const int CIRCUITO_2 = 9;
const int CIRCUITO_3 = 10;
const int CIRCUITO_4 = 11;
const int CIRCUITO_5 = 12;

const int CIRCUITOS_ACTIVOS[] = {
  CIRCUITO_1,
  CIRCUITO_2,
  CIRCUITO_3,
  CIRCUITO_4,
  CIRCUITO_5,
};

void _abrirValvula(int circuito, int t) {
    digitalWrite(circuito, HIGH);
    digitalWrite(BOMBA, HIGH);
    unsigned long waitTime = t * 1000L;
    delay(waitTime);
    digitalWrite(BOMBA, LOW);
    digitalWrite(circuito, LOW);
}

void cicloRiegoCompleto() {
  int numeroDeCircuitos = sizeof(CIRCUITOS_ACTIVOS) / sizeof(CIRCUITOS_ACTIVOS[0]);
  for (int i=0; i<numeroDeCircuitos; i++){
    _abrirValvula(CIRCUITOS_ACTIVOS[i], TIEMPO_RIEGO);
  }
}

void setup() {
  pinMode(BOMBA, OUTPUT);
  pinMode(CIRCUITO_1, OUTPUT);
  pinMode(CIRCUITO_2, OUTPUT);
  pinMode(CIRCUITO_3, OUTPUT);
  pinMode(CIRCUITO_4, OUTPUT);
  pinMode(CIRCUITO_5, OUTPUT);
  pinMode(TRIGGER, INPUT);
}

void loop() {
  if (digitalRead(TRIGGER) == HIGH) {
   cicloRiegoCompleto(); 
  }
}

On the pin 5 (TRIGGER) I have a raspberry pi connected that is connected to the internet also, so, when I send it a message from mi phone, it puts 3.3V on that pin and starts the process.

It has been working great for like a month or so but, a few days ago, the pump didn't stop when it should, and was still working hours after it started.

I pull the plug and, when I turn it on again, it worked correctly again for another 2 or 3 days.

But today it hasn't stop again. I have check that the pump has been working for around 15 minutes until I pulled the plug, and the first valve (CIRCUITO_1) has been opened the whole time, looks like the for loop is stuck in the first iteration.

So can it be some problem with the delay function?

For some reason it is waiting way more than it should?

It works sometimes and sometimes it doesn't so it makes me think: can it be some weird overflow issue?

  • The code seems legit to me. Can you log on the pi, when exactly it turns it's output on and off? Just to see, if that works correctly. – chrisl Aug 15 '19 at 7:34
  • When you have this problem, what is the state of the logic output of the Pi? – Edgar Bonet Aug 15 '19 at 7:36
  • The pi turns its output HIGH during only one second, and then it is LOW again. But, even if it were HIGH the whole time, it should loop through each valve instead of being stuck in the first one forever. – Enuff Aug 15 '19 at 7:46
  • How are you interfacing the pumps to the Arduino? Can you post a circuit diagram? Also, how are you powering the pumps? Are they powered separately from the Arduino, or is the Arduino sourcing its power from the same circuit that the pumps are? – GMc Aug 15 '19 at 8:42
  • The valves are controlled via mosfets IRL510 (or IRL540? don't remember right now), the pump with a 5V arduino relay. Everything is powered from a 15A 12V power supply, using a step-down for the raspberry and the relay power. I'll try to upload a diagram this evening. – Enuff Aug 15 '19 at 8:49
1

Do you have 10k resistors between gate and ground on your MOSFETs? You might be suffering from residual charge on your MOSFET gate keeping it on when it should be off.

| improve this answer | |
  • 1
    Yep, and also flyback diodes on each valve. – Enuff Aug 16 '19 at 8:00
1

Based on your experience with the system and the source of the Nanos, the best and quickest test I can think of is to swap in a another Nano to find out whether if the problem remains or disappears.

| improve this answer | |
0

It has been working great for like a month or so ... it makes me think: can it be some weird overflow issue?

It's hardly a software issue then. Nothing in your code would change after a month of operating. And if you turn the power off and on again then it would "forget" about the previous month.

So can it be some problem with the delay function?

No.


I suggest looking at the hardware, or the code on the Pi.

| improve this answer | |
  • That makes sense. The pi code looks fine but, should I just check the mosfet circuit part or the arduino itself too? What I mean: Is it possible for an arduino to break in some way that it gets stuck randomly on a line of code? Or if the arduino was broken it wouldn't work at all? – Enuff Aug 15 '19 at 8:45
  • I doubt it would get "stuck" on a line of code. The processor runs or it doesn't. I would use a meter to test that the output is being set in the way you expect. – Nick Gammon Aug 15 '19 at 23:23
0

You may have a problem in the casting of the variable t vs the variable waittime. t is an int and waittime is a long so when you multiply t by 1000L you may be picking up a couple of extra bytes used by other parts of the code:

For instance if t is stored at location 0x100:0x101 in RAM, and some other variable or random data is stored at 0x102:0x103, you pass 100 to the function in variable t which you expect multiplies into waittime as 100,000mS or 100S, but if the data stored at 0x102:0x103 for instance is randomly 0xFFFF, the multiplication into waittime actually works out to (100*65536)+65535 = 6,619,135mS or 1.83 hours.

The way around this is to either pass a long in the function or recast t to match waittime:

waittime = (long) t * 1000L;

Note that the order of the bytes depends on how the compiler handles variable storage.

| improve this answer | |
  • 1
    Compilers don't overwrite memory just because you cast something. That would be pretty bad behaviour if they did. Maybe if you cast a pointer into a different sort of pointer, but this is just an ordinary variable. – Nick Gammon Aug 21 '19 at 6:58
  • The cast and multiply are almost certainly done in registers, and the variable waitTime is unlikely to ever have any discrete existence, as the product of the multiply will be left in registers or immediately pushed onto the stack as the argument to delay(), and is never referred to again. – JRobert Aug 21 '19 at 22:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.