Hello all, I am in need of some help ASAP.
I am trying to make an automated "Blower/Cleaner" for our assembly line. I am running into a problem where whenever 24V is supplied to the circuit, the Arduino acts weird. in the code i have it set so that when the button is held, the relay will turn on, then off, then on, then off again and will wait until the button has been released for 750ms before allowing the cycle to be repeated.
when the pneumatic solenoid is supplied power however, the cycle is as follows: relay turns on, waits, turns off, then the cycle repeats without needing to release the button.
Even if you start with the power supply off and turn it on while its running, as soon as the power is turned on, it skips the second delay.
We have tried this on both a genuine Arduino Uno r3 and a knock off Arduino Nano with identical results.
I have been scratching my head at this for close to a week now so any help is mighty appreciated.
worth noting:
-
currently I am using a separate power supply for the Arduino and the solenoid for ease however the problem persist with the circuit assembled as in the diagram.
-
I will not be able to pull up the exact relay from online as I wasn't here when it was ordered.
-
I initially tried with no kickback diode, then just a diode, then what you see on the diagram.
-
The solenoid is a Festo cpe14-M1CH-3GLS-1/8 24v pneumatic solenoid.
everything seems to work ok when 24v supplied during the first half of the cycle, however every time the second cycle messes up.
Its my first time posting here so if I missed something lmk.
Any help is appreciated, so thanks in advance.
Edit:
I ended up replacing the relay with a BS170 Mosfet. I did end up running into another issue but someone on reddit helped me out.
In conclusion I believe it was the relay causing issues, even with the kickback diode. Not sure why I and my coworker have both had no issues previously using relays with Arduino's but hey. The problem is solved so I'm not complaining. the only thing I can think of is that, 2 inductive loads is better (worse) than one.
Anyways, thanks all for the help.
/*****************************************************************************
******************************************************************************
A short script to activate a solenoid in a specific pattern
to remove foreign debris from part# 22.60.055.028-00.
Uses a potentiometer to control the timing of the relay.
Iluminates LED's to inform the operator of the machine's operation.
******************************************************************************
*****************************************************************************/
// Declaring the pins for IO:
const byte relay = 8;
const byte ready_led = 9;
const byte working_led = 7;
const byte limit_switch = 2;
const byte potentiometer = A0;
// Variables to keep track of the states of outputs:
int relay_state = HIGH;
int working_state;
int ready_state = HIGH;
// Variables to declare how long to open the pneumatic solenoid:
int delay1 = 1000;
int delay2 = (delay1 + 1000);
int delay3 = delay2;
int wait = 750;
// Variables to keep track of time:
int start;
int wait_start;
int current;
int difference;
// Variables to keep track of what is happening globally:
bool e_stop = false;
bool done = false;
void setup() {
Serial.begin(9600);
// Declaring pins as either inputs or outputs:
pinMode(relay, OUTPUT);
pinMode(ready_led, OUTPUT);
pinMode(working_led, OUTPUT);
pinMode(limit_switch, INPUT);
// Declaring an interupt on the pin corresponding to the limit switch:
attachInterrupt(digitalPinToInterrupt(limit_switch), emergency_stop, RISING);
}
void loop() {
current = millis();
// Updating each pin every time the programe loops:
digitalWrite(relay, relay_state);
digitalWrite(ready_led, ready_state);
digitalWrite(working_led, working_state);
// Using the potentiometer_map() function to determine the time to wait during delay3:
delay3 = (potentiometer_map() + delay2);
// If an E stop even has been triggered, wait a moment before resetting:
if (e_stop == true) {
digitalWrite(ready_led, LOW);
digitalWrite(working_led, HIGH);
delay(2000); // wait 2 seconds
digitalWrite(working_led, LOW);
done = false; // Set "done" to false so that we can continue cleaning parts
e_stop = false; // set "e+stop" to false so we don't enter this loop again unless anouther E stop is called
ready_state = HIGH;
working_state = LOW;
digitalWrite(ready_led, ready_state);
digitalWrite(working_led, working_state);
}
wait_start = millis(); // Keep track of time so we know how much has passed
while (done && digitalRead(limit_switch)) { // while we have completed the the timed loop and the switch is released
ready_state = HIGH;
if (current - wait_start >= wait) { // If the current time - the time when we started is the amount of time we want to wait, then set done to false to start anouther loop
done = false;
}
current = millis();
}
if (!digitalRead(limit_switch)) { // If the switch is pressed
delay(1000); // Wait briefly
start = millis(); // start keeping strack of time
while (!done && !digitalRead(limit_switch)) { // while not done and the switch is held a part is in the nest
// Set the lights to "working status":
working_state = HIGH;
ready_state = LOW;
// Figure out how much time has elapsed:
current = millis();
difference = (current - start);
if (difference < delay1 && !e_stop) { // If the diffence in time is less than delay1 and no E stop has been declared
relay_state = LOW; // Relay on
Serial.println("\nON 1");
Serial.println(difference);
}
else if (difference > delay1 && difference < delay2 && !e_stop) { // If the diffence in time is greater than delay1, less than delay2, and no E stop has been declared
relay_state = HIGH; // Relay off
Serial.println("\nOFF 2");
Serial.println(difference);
}
else if (difference > delay2 && difference < delay3 && !e_stop) { // If the diffence in time is greater than delay2, less thean delay3, and no E stop has been declared
relay_state = LOW; // Relay on
Serial.println("\nON 3");
Serial.println(difference);
}
else { // Otherwise wait in a ready state
Serial.println("\nOFF 4");
relay_state = HIGH;
working_state = LOW;
ready_state = HIGH;
start = current;
wait_start = current;
done = true;
}
// Update the outputs every time this loop cycles to make sure everything shows correctly:
digitalWrite(relay, relay_state);
digitalWrite(ready_led, ready_state);
digitalWrite(working_led, working_state);
}
}
}
int potentiometer_map() { // Maps the value read from the potentiometer into a value between 500 and 10,000 milliseconds
return (map(analogRead(potentiometer), 0, 1023, 500, 10000));
}
void emergency_stop() { // This function is called by an interrupt every time the switch is released, and if the process wasn't completed it waits a moment to reset
if (!done) {
Serial.println("E STOP!");
e_stop = true;
done = true;
relay_state = HIGH;
digitalWrite(relay, HIGH);
ready_state = LOW;
digitalWrite(ready_led, ready_state);
} else {
return;
}
}