[SOLVED] Adding button causing strange problems

I had a coding issue revolving around adding start and stop button, to replace a toggle switch, in my project. That has been resolved but has led to some very strange behavior. It was suggested I post the problem here so here goes. At the bottom is a link to the entire programming thread that got me to this point. Below is a summary of the problem.

Components are a Uno R3, an 8 channel relay board (using 5 of the relays), a 12 volt power supply outputting 12.27 volts. The power supply is typically powering 12 volt air solenoids via the relays as well as the Uno using the external power jack although, as you'll see below, I've tried several other combinations. At first I thought I may have damaged the Uno by making connections while it was powered up and possibly shorting something out. However I replaced the board and was diligent about not doing that and have the same issues with the second board.

Here's what's happening:

With only the processor powered by the usb (connected to my laptop) and both the start and stop buttons hooked up, and no 12 volt to the relays, everything appears to function correctly. The start button will start the system and the leds on the relays confirm the correct sequencing. Pressing the stop button will stop the system. All is right with the world except, of course, the solenoids and air cylinders aren't doing anything because there is no power to the solenoids.

With the processor and the relays powered by my 12 volt power supply and the stop button disconnected from the pin (currently pin 9) the start button starts the system and the relays, solenoids, and air cylinders all function correctly. The system will run the programmed number of cycles (currently 25) and then stop.

With the processor and the relays powered by my 12 volt power supply and the stop button connected to the pin (currently pin 9) the start button starts the system then random things happen. Typically it runs part of a cycle, firing a couple of cylinders, then stops. Pressing reset then start yields similar, but not necessarily exactly the same, results. It will run anywhere from a partial to full cycle then stop. I've confirmed the stop switch is not faulty and have even disconnect the other side of it from ground and get the same results. Going a step further simply plugging a jumper into pin 9, with nothing connected to or touching the other end, causes the same results.

And I have the same results as the last paragraph if I power the processor from the laptop and the relays from the 12 volt supply.

So why is one button (or more correctly one pin connection) messing everything up? The start button is on pin 12 and the stop button has been tried on pins 11, 10, & 9, on 2 different boards with no success.

I originally had the on/off toggle switch from the previous version connected to the ground pin on the digital side, next to pin 13. That is also where I currently have the start button grounded. I soldered up a male to multi female jumper so I could also connect the stop button there. The relay board ground is connected to the ground on the opposite side of the board as well as pins 2 through 6.

Thank you for any help you can offer!

Bill

Please supply the program and connection diagram.

Weedpharma

Sorry for the crappy diagram!

//Welder Version1 Rev0
//Includes relay closure to activate welding cycle
//Includes Serial Counting and Auto Shut off when runSize is reached
//Rev1A  pushbutton start and emergency stop  (NOT FUNCTIONING)


const int SolRelayA        = 2;   // Tip Loading Plate
const int SolRelayB        = 3;   // Activate Loading Cylinder
const int SolRelayC        = 4;   // Welder Clamps
const int SolRelayD        = 5;   // Activate Blade Lift Cyinder
const int WeldRelayA        = 6;   // Activate Welder Circuit
const int pushButtonStart        = 12;  //NO Momentary pushbutton to start
const int pushButtonStop        = 11;  //NO Latching pushbutton Estop Button
unsigned long previousMillis;
unsigned long timeDelay = 6000;
unsigned long printMillis = 0;
unsigned long currentMillis = 0;
int CycleStage = 0;
int startButton = 1;
int estopPushButton = 1;
int CycleCount = 0;
int runSize = 7;//number of cycles to run before stopping
int runState = 0; //has run been turned on. 0=Off, 1=O


void setup() {
  Serial.begin(9600);
  digitalWrite (SolRelayA,   HIGH); //Set Relay Pins High
  digitalWrite (SolRelayB,   HIGH);
  digitalWrite (SolRelayC,   HIGH);
  digitalWrite (SolRelayD,   HIGH);
  digitalWrite (WeldRelayA,   HIGH);
  pinMode (SolRelayA,      OUTPUT); //Set Relay Pins as Outputs
  pinMode (SolRelayB,      OUTPUT);
  pinMode (SolRelayC,      OUTPUT);
  pinMode (SolRelayD,      OUTPUT);
  pinMode (WeldRelayA,      OUTPUT);
  pinMode (pushButtonStart, INPUT_PULLUP);
  pinMode (pushButtonStop, INPUT_PULLUP);
}

void loop() {//open loop

  //if you // the next line then serial print will not be called
  //left in it will call the serial print lines used for diagnostics
  serialHelper();


  estopPushButton = digitalRead (pushButtonStop);
  startButton = digitalRead(pushButtonStart);
  currentMillis = millis();//update every loop



  if (estopPushButton == 0) {
    runState = 0;
  } else if ((startButton == 0) && (estopPushButton == 1)) {
    runState = 1;
  }

  if (runState == 1) {
    if (currentMillis - previousMillis > timeDelay) {
      CycleStage++;
      previousMillis = currentMillis;//reset timer
    }
    if (CycleCount >= runSize) {
      CycleStage = 0;
    }

    switch (CycleStage) {
      case 0:
        break;
      case 1: //Tip Loading Plate to Vertical
        digitalWrite (SolRelayA,   LOW);
        timeDelay = 1500;
        break;
      //Insert Tube into Welder
      case 2://if CycleStage==1 kinda of arguement
        digitalWrite (SolRelayB,   LOW);
        //delay (?);
        timeDelay = 1000;//update timeDelay for next step
        break;
      case 3://Activate Welder Clamps
        digitalWrite (SolRelayC,   LOW);
        // delay (?);
        timeDelay = 200;//update timeDelay for next step
        break;
      case 4://Start Weld Cycle
        digitalWrite (WeldRelayA,   LOW);
        // delay (?);
        timeDelay = 300;//update timeDelay for next step
        break;
      case 5://Extend Insertion Cylinder
        digitalWrite (SolRelayB,   HIGH);
        timeDelay = 500;//update timeDelay for next step
        //delay(?);
        break;
      case 6://Tip Loading Plate to Horizontal
        digitalWrite (SolRelayA,   HIGH);
        // delay(?);
        timeDelay = 1000;//update timeDelay for next step
        break;
      case 7://Extend Hopper Blade
        digitalWrite (SolRelayD,   LOW);
        //delay (?);
        timeDelay = 1000;//update timeDelay for next step
        break;
      case 8://Stop Weld Cycle,Retract Hopper Blade
        digitalWrite (SolRelayC,   HIGH);
        digitalWrite (SolRelayD,   HIGH);
        digitalWrite (WeldRelayA,   HIGH);

        //delay (?);
        timeDelay = 1000;//update timeDelay for next step
        break;
      case 9:
        digitalWrite (SolRelayA,   HIGH);
        digitalWrite (SolRelayB,   HIGH);
        digitalWrite (SolRelayC,   HIGH);
        digitalWrite (SolRelayD,   HIGH);
        digitalWrite (WeldRelayA,   HIGH);
        CycleCount = CycleCount + 1;
        timeDelay = 100;//9 is now going to loop back to 1
        CycleStage = 1; //go back to step one
        break;

    }//close switch

  } else { //runState == 0
    digitalWrite (SolRelayA,   HIGH);
    digitalWrite (SolRelayB,   HIGH);
    digitalWrite (SolRelayC,   HIGH);
    digitalWrite (SolRelayD,   HIGH);
    digitalWrite (WeldRelayA,   HIGH);
    previousMillis = currentMillis;//reset timer
  }
  //back in the main loop
}//close main loop

void serialHelper() {
  //timer is used to slow the prints to make reading easier on the eyes
  if (currentMillis - printMillis > 600) {
    Serial.print("startButton ");
    Serial.println(startButton);
    Serial.print("estopPushButton ");
    Serial.println(estopPushButton);
    Serial.print("runState ");
    Serial.println(runState);
    Serial.print("CycleStage ");
    Serial.println(CycleStage);
    Serial.print("delay ");
    Serial.println(timeDelay);
    Serial.print("CycleCount ");
    Serial.println(CycleCount);
    Serial.print("runSize ");
    Serial.println(runSize);
    Serial.println(" ");


    printMillis = currentMillis;//reset timer
  }
}

Here is a link to the relay board:
http://www.ebay.com/itm/4pcs-8-Channel-5V-Relay-Module-Board-Shield-for-Arduino-PIC-AVR-MCU-DSP-ARM-US-/191506024789?hash=item2c96a60955

20150824_224625.jpg

if (estopPushButton == 0) {
runState = 0;
} else if ((startButton == 0) && (estopPushButton == 1)) {
runState = 1;
}

What happens if both buttons ==1? It continues on with next statement with a non specific runState.

Weedpharma

It is not the buttons that are messing things up it is the solonoides. Do they have diodes across them?

They are generating interference and that makes your Arduino do wacky things.

By using the same power supply you are negating th isolation of the relay board.

So use a seprate power supply just for a test. If this fixes things then you can look at some heavy decoupling to restore the single power supply situation.

Arduino running on a 12volt solenoid supply.
And having to power five 5volt relays that draw ~80mA each.
That's asking for trouble.

First thing I would do is to give the relay board it's own 5volt/1A supply, with a $2.00 DC/DC buck converter powered from that 12volt source.
VCC jumper removed.
No ground connection between relay board and Arduino.
Now you have opto isolation.
Power the Arduino with a separate 9volt regulated plugpack (or USB).
Leo..

Thank you for the suggestions. I will work on separating the power supplies as suggested. The solenoids do not have diodes across them, can you elaborate on this so an electrical novice can follow it? :slight_smile:

Please don't take the following to be argumentative, I'm really just trying to figure things out and learn and sometimes "my" logical thinking gets in the way. If it has nothing to do with the buttons and is caused by the power supply/ solenoids then why does everything work correctly without the stop switch in place and, even more confusing to me, why does simply placing an unterminated jumper on the stop button pin have a negative effect?

The solenoids do not have diodes across them, can you elaborate on this so an electrical novice can follow it?

When a solenoid is on it has current flowing through it generating a magnetic field. When the current is turned off the magnetic field collapses. This causes magnetic field lines to cut the coil winding as it collapses, and that in turn generates a voltage in the coil. This voltage is in the opposite direction to that which caused the field in the first place. The result is a sudden and very large reverse voltage appearing on the coil winding. The job of this diode is to short out this voltage spike. If not in place then this voltage causes interference (EMI ) and possible damage to components.

why does simply placing an unterminated jumper on the stop button pin have a negative effect?

Because it is acting as an antenna for the interference from the coil.

Thanks Mike, that actually makes sense to me! :slight_smile: I understand that a diode is basically an electrical "check valve" so I understand how it would help. Am I correct in thinking that the closer it is to the coil the better it will do at preventing the problem or can I put it anywhere in the positive lead to the solenoid? And how do you choose the correct diode for a given situation?

Am I correct in thinking that the closer it is to the coil the better it will do at preventing the problem

Yes that is right, because if it is a distance away then the high voltage spike can travel along the wire to the diode and radiate electromagnetic interference while traveling.

And how do you choose the correct diode for a given situation?

Usually you pick a diode that has the same current capacity as the motor / solenoid takes when running normally.
That results in a diode that is strictly bigger than necessary but it is a good rule of thumb calculation.

Okay, so my solenoids are, acording to the info on them, 12 volt 4.8 watts 400mA

So something like this?

So something like this?

No nothing like that. That is a zener diode that is designed to break down at 12V, if you use that you will short out your power supply and generate a lot of heat.

acording to the info on them, 12 volt 4.8 watts 400mA

So a simple 1N4001 will do fine.

You should have a separate 5V supply for the relay coils, at least 500 mA.

Thats what the connector on the bottom right of the relay board (with yellow jumper) is for.

Would this be acceptable to power the relays? It's a few dollars more but easy to mount. Is the fact that it's 3 amps a problem?

http://www.ebay.com/itm/Waterproof-DC-DC-Converter-12V-Step-Down-to-5V-Power-Supply-Module-3A-15W-BLACK-/221667524607?hash=item339c69ffff

Question.....for powering the Adruino I can see 3 choices. 1) use a similar (or duplicate) step down transformer taken off the current 12 volt supply. 2) split the AC input off to another, separate 5 volt DC power supply, or 3) power it from a wall wart type power supply. But I believe number 3 is basically the same as number 2 except I'll be plugging 2 things into the wall outlet instead of one so for that reason it's less desirable. And option number 1 I'm assuming doesn't give me the isolation that we're looking for because the same 12 volt source is powering the solenoids and the Arduino, although separated by the step down transformer?

First off they are not "step down transformers" that term only applies to wound components.

You can run it all off one 12V supply which is what I would do if it were my project. Sure test it with two supplies to make sure you have no interaction from the solenoids but then drive it all from one supply and if you have problems at that you can add decoupling components to stop it.

Others might try and tell you different but that is what I would do.

Don't bother with that thing you linked to.

As explained before, power the relay module from your existing 12volt supply with a DC/DC converter like this.
Or with the one you linked to in post#10.
I would give the Arduino a separate supply, to prevent groundloop problems (opto isolation).
That could be a small 9volt regulated supply plugged into the DC jack, or a phone charger with USB socket (use your USB lead).
Leo..

I would give the Arduino a separate supply, to prevent groundloop problems

Ground loops can be prevented by not wiring up any loops in the ground path. This is normally only a problem with audio circuits however.

But don't I somehow need to get 5 volts to power the relay board instead of using the arduino 5 volts to power it? Do you disagree with this statement "First thing I would do is to give the relay board it's own 5volt/1A supply, with a $2.00 DC/DC buck converter powered from that 12volt source."?

That means: Don't power the relay COILS from Arduino's 5volt supply.

Power the coils from a 5volt DC/DC converter that is powered from your main 12volt supply.

12volt supply > 5volt DC/DC converter > 3-pin connector JD-VCC and ground. Jumper removed.

Arduino connected to VCC (on the long strip) and inputs.

Now the Arduino ONLY powers the indicator LEDs and the opto. NOT the coils.
Leo..

So the proper connections would be:

From the designated (2-6) digital pins of the Arduino to the appropriate input pins for the respective relays.
From the Arduino 5 volt pin to VCC on the relay board.

From the 5 volt power supply- Positive to relay board JD-VCC (jumper removed) and Negative to relay board Ground.

And do not connect Arduino ground to the relay board ground??

Just want to make sure I get this right!

Also, diodes are ordered. Hopefully I can chase all the gremlins away by the end of the week.