I'm going to jump right in and be detailed as possible:
Project components:
Funduino uno R3
12V power supply 5A
AQMH3615NS switching relay board with PWM
limit switch (using NO and C connections)
12V linear actuator with a 10% duty cycle
Here's what I want to accomplish as a FSM:
(state 1) NO movement
(state 2) linear actuator move down at set speed for desired time
(state 3) timer - interruptable (I'm learning blinkwithoutdelay example still here)
(state 4) linear actuator move up at set speed for desired time
To make it slightly more complex, I am programming a limit switch to change certain states or the absence of the trigger as well over a certain time.
Pics: Overview of Setup, relay wiring setupArduino wiring setup
NOTE: I moved the limit switch wire from A0 to 12 and am using the internal pullup resistor on the board - which was harder info the learn about than imagined.
Arduino ports used:
inputs:
5v: 5v output from relay (green wire)
12: NO limit switch to GND (purple)
outputs:
3: PWM control for relay
7:IN1 on switching relay (white)
8:IN2 on switching relay (blue)
GND: Ground output to relay and limit switch (black)
Relay wiring:
block1
9-36V: power from power supply (red)
PGND: Ground from power supply (black)
block 2
out1: switching 2 wire DC motor (red)
out2: Switching 2 wire DC motor (black)
Orange block
com: GND output from Arduino (black)
in2: output from arduino#8 (blue)
in1: output from arduino#7 (white)
PWM: output from Arduino#3 (red)
5V0: output TO Arduino 5V IN(blue)
#define pwm 3
#define in1 7
#define in2 8
const int delaya = 800;
const int delayT = 230000;
const int delayup = 4000;
const int delaydown = 7000;
unsigned long chrono = millis();
// constants won't change. They're used here to set pin numbers:
const int buttonPin = 12; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
// variables will change:
int button = 0; // variable for reading the pushbutton status
int rotDirection = 0;
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT_PULLUP);
pinMode(pwm, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
// Set initial rotation direction
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
}
enum CT {WAIT, DOWN, UP, TIMER }; //The 4 possible states of the CT
CT ctstate = WAIT; //Start state is WAIT
void goup() {
if (millis() - chrono >= delaya) {
chrono - millis();
digitalWrite(ledPin, HIGH);
digitalWrite(in1,LOW) ;
digitalWrite(in2,HIGH) ;
analogWrite(pwm,255) ;/* setting pwm of the motor --255= 100% 64= 25% */
delay (2500); /* timer of 4 seconds - uninterruptable */
}
}
void godown() {
if (millis() - chrono >= delaya) {
chrono - millis();
digitalWrite(ledPin, HIGH);
digitalWrite(in1,HIGH) ;
digitalWrite(in2,LOW) ;
analogWrite(pwm,64) ;/* setting pwm of the motor --255= 100% 64= 25% */
delay (7000);/* timer of 7 seconds - uninterruptable */
}
}
void timer() {
if (millis() - chrono >= delayT) {
chrono - millis();
delay (12000);
}
}
void CTtesterstate() { //The CT state machine
switch (ctstate) { //Depending on the state
case WAIT: { //State is WAIT
if (button == LOW) //If a button has been pressed
ctstate = DOWN; //State is now DOWN
break; //Get out of switch
}
case DOWN: { //State is Down
godown();
if (button == LOW) //If a button is pressed
ctstate = UP; //State is now UP
else ctstate = TIMER;
break; //Get out of switch
}
case TIMER: { //State is TIMER
if (button == LOW)
ctstate = UP;
else timer();
ctstate = UP; //State is now UP
break; //Get out of switch
}
case UP: { //State is UP
goup();
ctstate = WAIT; //State is now Wait
break; //Get out of switch
}
}
}
void loop() {
// read the state of the pushbutton value:
button = digitalRead(buttonPin);
// check if the pushbutton is pressed. If it is, the button is low:
if (button == LOW) {
// turn LED on:
digitalWrite(ledPin, HIGH);
} else {
// turn LED off:
digitalWrite(ledPin, LOW);
}
CTtesterstate(); //GO - run
}
Currently, the movements work as desired. The issue I am encountering is the button trigger starts the FSM from the WAIT state to the DOWN. From there, the states continue to change even without the button triggering the change. I've spent days learning and have been developing the code to make a more robust program to achieve my goals. I'm looking for some guidance on:
- Why the states keep changing
- if my use of chrono and millis for the timer makes sense.