I have a linear actuator I'm trying to expand and contract until it hits a limit switch. If it extends and hits the limit switch it should stop and reverse direction, contracting until it hits the other limit switch. For testing purposes I have disconnected the actuator and am only using the motor controller which has indicator LEDs for direction/duty cycle (they get brighter or dimmer depending upon pwm).
#include <RBD_Timer.h>
#include <RBD_Button.h>
const int INA = 28; // for motor controller
const int INB = 34; // wut he said ^
const int PWM = 4;
RBD::Button flexLimit(36, false); // i have resistors wired in series
RBD::Button extendLimit(38, false); // so I don't need the pull-up resistors on the board
boolean homed = false;
boolean ableToMove = false;
void setup() {
Serial.begin(115200);
pinMode(INA,OUTPUT);
pinMode(INB,OUTPUT);
pinMode(PWM,OUTPUT);
Serial.print("Able to move: ");
Serial.println(ableToMove);
}
void loop() {
if(!homed) {
homePosition();
Serial.println("Ready");
Serial.println();
ableToMove = true;
}
}
void homePosition() {
Serial.println("Homing...");
if(extendLimit.isReleased()) {
Serial.println("Extending...");
setDir(1);
while(extendLimit.isReleased()) {
Serial.println("Extend pwm");
analogWrite(PWM, 200);
}
Serial.println("End pwm1");
analogWrite(PWM, 0);
setDir(0);
}
homed = true;
}
void setDir(int d) {
Serial.println("setting direction");
switch(d) {
case 0: // off?
digitalWrite(INA,LOW);
digitalWrite(INB,LOW);
break;
case 1: // contract actuator (extension)
digitalWrite(INA,HIGH);
digitalWrite(INB,LOW);
break;
case 2: // extend actuator (flexion)
digitalWrite(INA,LOW);
digitalWrite(INB,HIGH);
break;
case 3: // locked?
digitalWrite(INA,HIGH);
digitalWrite(INB,HIGH);
break;
}
}
Serial output:
Able to move: 0
Homing...
Ready
No switches are pressed nor do any indicator LEDs turn on
What I want:
Since no switches are on at start the motor driver should set the direction and give power to the motor which would be indicated by a red LED turning on. When I press the switch the LED should turn off.
What's going on?
This is my first post so let me know if you need more or less or different information.
I assumed the homePosition() function would first test if the limit switch isReleased() and then execute the body of the if statement. If the body of the if statement has been executed properly it would be homed. The body of the if statement is not being executed and I don't know why. Or perhaps I misunderstood your comment?
We know that homeposition() completed because back at loop() it prints "ready".
Maybe look at your wiring or make a test sketch too see extendlimit.isreleased() is working as you think.
Get in the habit of coding without using loops. Rely on the arduino loop() function to do that for you - each pass through, you only do what you need to do right now.
void loop() {
if(I'm moving forward) {
if(it's time to start moving backward) {
do what I have to do to start moving backward;
}
}
else {
if(it's time to start moving forward again) {
do what I have to do to start moving forward;
}
}
do whatever I have to do to make movement happen in the current direction;
this might be nothing, or it might involve working out stepper timings.
}
I was only intending to have a loop in the homePosition function. The rest would be controlled by the difference in time using millis(). I only want the homePosition function to run once at the beginning of the program. I don't know where the motor will be when it starts. I could change the code to run through without a while loop and when it gets to the limit switch I can change the homed variable to true that way. What's the advantage?
Duly noted. And with that in mind I changed my code a bit. Used for loops on pin 13 as indicators but those will be gone in production.
The point of using the button library was so I didn't have to write my own debounce function. I don't seem to need it in this code. The only thing I'm questioning is why I have to hold the limit switch for 2 mississippi's in order for my homePosition function to read it as HIGH. After I home the actuator I will continue to contract and extend it and if it continues to extend for 2 seconds while my program reads the limit switch position it will break.
While you're not extended, you're running a for loop WITH A DELAY:
if(!extendLimitReached) { // not extended yet
if(digitalRead(38) == LOW) { // not on the extended limit
for(int i = 0;i < 255;i++) { // what is this?????
analogWrite(13, i); // and this ??????
delay(10); // AND A DELAY?? 255 times??
}
} else if(digitalRead(38) == HIGH) { // now EXTENDED
Serial.println("Extend limit reached");
extendLimitReached = true; // see - we're now extended
}
}
You really need to work on this - I'm really unsure of your intent.
That's a totally legit point. I was using pin 13's LED to give visual confirmation that I was reaching the correct points in my code. I realize the loop and delay is causing problems so I replaced it with actual code (setting direction and pwm). Code runs smoother and switch is immediately read. I'm using a different button library now btw.
Code:
void homePosition() {
byte extendLimitState = extendLimit.checkButton(extendLimitPin);
if(!extendLimitReached) {
if(!extendLimitState) { //digitalRead(38) == LOW) if equals 0, not pressed or held or w/e
Serial.println("Extend limit not reached");
setDir(1);
analogWrite(PWM, 250);
} else if(extendLimitState) { //digitalRead(38) == HIGH) if not 0, its pressed or held or w/e
Serial.println("Extend limit reached");
setDir(0);
analogWrite(PWM, 0); // should I set pwm before setting direction?
extendLimitReached = true;
}
} else if(extendLimitReached) {
if(!timerSet) {
startTime = millis();
timerSet = true;
Serial.println("Timer set");
}
if(millis() - startTime < 500) {
Serial.println("Contracting...");
setDir(2);
analogWrite(PWM, 250); // do I need to set direction every time?
} else {
setDir(0);
analogWrite(PWM, 0);
homed = true;
}
}
}
Problem now is that the inidcator LED does not turn on when extending but does turn on when contracting. extendLimitState is equal to 0 at start and the serial output reads "Extend limit not reached."