Arduino has some strange reactions

Well, needless to say I have some gremlins in the panel that I need to work out. I took the time to go back and print in all of my I/O so that I could get a better idea on the serial bus what it was doing, or what it was being told to do. To keep it simple, on a low voltage, and logic level this works perfectly. With just the arduino and a sainsmart 4 relay board, usb cable, it does exactly what I intend.

The problem however is that in the small control box I also have also have an AC transformer for some solenoids, as well as a large AC contactor, ac bus and I'm switching larger relays with the sainsmart board with AC loads. I did my best to keep everything away from each other but inevitably in a small panel there is only so much you can do to not cross LV/HV wiring.

Anyhow, my first question when reading the serial bus and this happens quite randomly, but the arduino seems to restart for the lack of better terms when I am switching off a high voltage output. But it happens completely randomly and with no rhyme or reason. I did notice however is that the serial bus shows this:

Exhibit A: A snippet of the code it's running including a snippet from the setup to show the serial start

void setup() {
// Initialize the pins, define digital I/O Pin Usage
//Inputs
pinMode(S1, INPUT);
pinMode(S2, INPUT);
pinMode(S3, INPUT);
pinMode(S4, INPUT);
//Outputs
pinMode(K1, OUTPUT);
pinMode(K2, OUTPUT);
pinMode(K3, OUTPUT);
pinMode(K4, OUTPUT);
digitalWrite(S1, HIGH);
digitalWrite(S2, HIGH);
digitalWrite(S3, HIGH);
digitalWrite(S4, HIGH);
Serial.begin(9600);
Serial.println("System Initialized");
}

// Begin Water Tank 1 Logic
  if (digitalRead(S1) == LOW && curS == 0) 
  {
    Serial.println("Water Tank 1 Low");
    digitalWrite(K1, HIGH);
    Serial.println("Solenoid 1 Open");
    delay(3000);
    digitalWrite(K4, HIGH);
    Serial.println("Pump On");
    Serial.println("Filling Water Tank 1");
    curS = S1;  
  }
  else if (digitalRead(S1) == HIGH && curS == S1) 
  {
    Serial.println("Water Tank 1 Full");
    digitalWrite(K4, LOW);
    Serial.println("Pump Off");
    delay(3000);
    digitalWrite(K1, LOW);
    Serial.println("Solenoid 1 Closed");
    curS = 0;
  }

Exhibit B: The serial Monitor

Water Tank 1 Low
Solenoid 1 Open
Pump On
Filling Water Tank 1
Water TùSystem Initialized

^^ What would cause this last line?

What drew me to this was that sometimes when switching one output off, it would turn another one on, but again randomly. When I got my meter out and checked the input driving the output turned on randomly, it wasn't being driven low, even though the output was being driven by the arduino, being high. Weird to say the least, I think these two issues could be related.

Thanks for your help.

^^ What would cause this last line?

A reset?

A snippet of the code it's running

That was a snippet of an answer, BTW.

Weird to say the least, I think these two issues could be related.

Not weird just lack of supply decoupling.

AWOL:

^^ What would cause this last line?

A reset?

A snippet of the code it's running

That was a snippet of an answer, BTW.

That's what I thought, so what could cause the arduino to reset without being told to? Besides loss/lack of appropriate power obviously.

cncb:
That's what I thought, so what could cause the arduino to reset without being told to? Besides loss/lack of appropriate power obviously.

All your serial prints suggest you could be running out of ram. Without seeing your full code it is tough to say. You really should keep your serial.print strings in PROGMEM like this:
Serial.print(F("stays in flash"));

James,

Thanks for your response. I've enclosed the entire sketch for viewing with the serial prints modified as you suggested. It is at 3,752 bytes in sketch size. I really don't need all these serial prints to be honest, it was more about debugging and trying to see if it would help indicate my issues. As it stands this reset issue is my only one. As far as I can tell the arduino isn't resetting though, is there something else that would cause this? Thanks guys.

/*
  Water Controller
*/

// Digital Input Pin Constants
const int S1 = 2;    // Float Switch 1
const int S2 = 3;    // Float Switch 2
const int S3 = 4;    // Manual Switch 1 (Junction Box)
const int S4 = 5;    // Manual Switch 2 (Enclosure)
// Digital Output Pin Constants
const int K1 = 6;    // Relay K1 - Solenoid for Tank 1
const int K2 = 7;    // Relay K2 - Solenoid for Tank 2
const int K3 = 8;   // Relay K3 - Solenoid for Manual Use
const int K4 = 9;   // Relay K4 - Water Pump Relay

// Variables that will Change
int curS;

void setup() {
 // Initialize the pins, define digital I/O Pin Usage
   //Inputs
  pinMode(S1, INPUT);
  pinMode(S2, INPUT);
  pinMode(S3, INPUT);
  pinMode(S4, INPUT); 
   //Outputs
  pinMode(K1, OUTPUT);
  pinMode(K2, OUTPUT);
  pinMode(K3, OUTPUT);
  pinMode(K4, OUTPUT);
  digitalWrite(S1, HIGH);
  digitalWrite(S2, HIGH);
  digitalWrite(S3, HIGH);
  digitalWrite(S4, HIGH);
  Serial.begin(9600);
  Serial.println(F("System Initialized"));
}

void loop() {
// Begin Water Tank 1 Logic
  if (digitalRead(S1) == LOW && curS == 0) 
  {
    Serial.println(F("Water Tank 1 Low"));
    digitalWrite(K1, HIGH);
    Serial.println(F("Solenoid 1 Open"));
    delay(3000);
    digitalWrite(K4, HIGH);
    Serial.println(F("Pump On"));
    Serial.println(F("Filling Water Tank 1"));
    curS = S1;  
  }
  else if (digitalRead(S1) == HIGH && curS == S1) 
  {
    Serial.println(F("Water Tank 1 Full"));
    digitalWrite(K4, LOW);
    Serial.println(F("Pump Off"));
    delay(3000);
    digitalWrite(K1, LOW);
    Serial.println(F("Solenoid 1 Closed"));
    curS = 0;
  }
// Begin Water Tank 2 Logic
  if (digitalRead(S2) == LOW && curS == 0) 
  {
    Serial.println(F("Water Tank 2 Low"));
    digitalWrite(K2, HIGH);
    Serial.println(F("Solenoid 2 Open"));
    delay(3000);
    digitalWrite(K4, HIGH);
    Serial.println(F("Pump On"));
    Serial.println(F("Filling Water Tank 2"));
    curS = S2;
  }
  else if (digitalRead(S2) == HIGH && curS == S2) 
  {
    Serial.println(F("Water Tank 2 Full"));
    digitalWrite(K4, LOW);
    Serial.println(F("Pump Off"));
    delay(3000);
    digitalWrite(K2, LOW);
    Serial.println(F("Solenoid 2 Closed"));
    curS = 0;
  }  
// Begin Manual Switch 1 Logic
  if (digitalRead(S3) == LOW && curS == 0) 
  {
    Serial.println(F("Misc. Water Valve Open"));
    digitalWrite(K3, HIGH);
    delay(20);
    curS = S3;  
  }
  else if (digitalRead(S3) == HIGH && curS == S3) 
  {
    Serial.println(F("Misc. Water Valve Closed"));
    digitalWrite(K3, LOW);
    delay(20);
    curS = 0;
  } 
// Begin Manual Switch 2 Logic
  if (digitalRead(S4) == LOW && curS == 0)
  {
    Serial.println(F("Manual Pump Switch On"));
    digitalWrite(K4, HIGH);
    curS = S4;
    delay(20);
  }
  else if (digitalRead(S4) == HIGH && curS == S4)
  {
    Serial.println(F("Manual Pump Switch Off"));
    digitalWrite(K4, LOW);
    delay(20);
    curS = 0;
  }
}

is there something else that would cause this

OK I will try again:-
http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html

Probably not a memory issue. (Keep in mind the "sketch size" reported is PROGMEM and has nothing to do with RAM usage).

Either it is a logic issue, or as Mike keeps pointing out, a power supply de-coupling issue.

Might be helpful to explain what you've done in that area.

The point is that he said:-

To keep it simple, on a low voltage, and logic level this works perfectly. With just the arduino and a sainsmart 4 relay board, usb cable, it does exactly what I intend.

The problem however is that in the small control box I also have also have an AC transformer for some solenoids, as well as a large AC contactor, ac bus and I'm switching larger relays with the sainsmart board with AC loads.

So it works by itself but not in the presence of AC loads.
If that is not a decoupling issue banged to rights then I don't know what is.

It can't be a memory issue because it works correctly when it is by itself.

I've been investigating it a bit after you mentioned the power de-coupling.

Here are a few observations I made testing it:

1: The issues only happen (and quite consistently) when I have a solenoid load attached, and with my AC contactor switched. I have 3 switches, 2 of which do the same thing turning on a solenoid and a single contactor for the pump. The third only opens the third solenoid, doesn't require the pump. So it only happens when outputs to the contactor (120VAC) and the solenoid (24VAC) are on at the same time.

  1. The problems always arise when the loads are switched OFF, not switched on.

  2. I've tried this system with powering on the arduino, and relay board from a completely isolated power source (bench power supply) from the rest of the system, as well as isolating the arduino from the relay board as well and get the same problems. When switching off the contactor and a solenoid it always causes other false triggers, sometimes only a flash and sometimes running an entire cycle of the sketch.

  3. I've also tried isolating, bringing the inputs nearly completely outside the panel to see if it's a noise issue having some of these logic and high voltage conductors in the same wire duct. Also tried isolating bringing the solenoid outputs outside the box when running them and it still has the same problems.

Any input would be greatly appreciated. I'm hoping I can resolve these bugs! Thanks.

  1. The problems always arise when the loads are switched OFF, not switched on.

That is when the flyback voltage from an inductor will be the greatest. That is what triggers a gasoline engine spark plug to fire. It is not the application of the current to the ignition coil (points closing) that fires the plug, it is the removal of the current (points opening).

Maybe an opto-isolator would help with that.

edit: And a flyback diode. I have also used a small value capacitor in parallel with the control coil to absorb some of the voltage spike.

The flyback diode makes sense, but all of my loads except for the LED pilot lights are AC loads (24VAC solenoids, 24VAC Contactor coil), so I can't use a diode on the load. And all of my relays are dry contacts anyways, so they are a bit more simple. I tried isolating the inputs and outputs outside the panel to rule out noise, and also tried powering the arduino/relay board with an independent variable bench supply and still get the same reactions. It's really odd.

It's really odd.

No it is not odd, it is exactly what is to be expected.

You have given little detail of how things are wired up either by photographs or schematically. You say you have isolated them but clearly you have not. Without details of what you have done we can't tell where you have gone wrong.

When ever you switch a load AC or DC you generate interference. If that interference is too great it will reset your system. You have to reduce that interference at source and also try and keep it out of your circuit with good design and layout.

To see what you can do about AC loads just google:- snubber circuit design

Oh, don't get me wrong, it's not that I don't expect it; it's just that I am a bit frustrated with not being able to see the obvious just yet. But as always it's part of the challenge. Here is a photo of inside the controller.

From top to bottom:

Top Left: 120 to 24VAC control transformer for solenoids
Top Right: 4 Channel Sainsmart Relay Board
Upper DIN Rail: Protected AC Bus, AC to 12VDC PSU, and a protected DC BUS, followed by slim Finder Interface Relays
Lower DIN Rail: Line Bus including single pole circuit breaker, AC contactor, Motor terminal, and I/O field terminals. Arduino uno with screw shields are on the middle right

On the door is a selector switch, and 4 LED pilot lights for status.

I will post a detailed schematic tomorrow. But if you had any initial thoughts, any help will be appreciated. I will research on the snubber circuit as you referenced, thanks for that.

Very neat setup, but I can't see where the extra decoupling is. Supply decoupling needs to be physically close to the device you are trying to decouple. So I was expecting to see a series inductor in the arduino's supply and a capacitor either side.

Thanks. There is no decoupling capacitor on the supply input for the arduino, I suppose I should really try that out. What would you suggest is a good type/value capacitor to start with? I'm powering the arduino with 12VDC from the din rail power supply. I've attached the spec sheet for reference, and as well as the schematic. Thanks for your help.

Spec sheet on the power supply attached.

dr-15-spec.pdf (248 KB)

Try a 100uF capacitor each side of a 1mH choke.
Also put this on the 5V line out from the arduino to the relay board.
You said earlier you have tried to isolate things, how have you tried to accomplish this?

So put a 100uF electrolytic cap on the power supply input (in parallel), as well as the 5VDC out to the relay board the same way? How do I wire the choke in? Thanks for your help.

The way the Pi circuit is shown here.
http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html
The inductor is in series with the supply with a capacitor to ground on each side of the inductor.