I have many question , i'm obviously not really good to code......
This is what im trying to do
I have an arduino with a motor shield r3 to control an electric linear actuator .
I have a npn NO sensor in the middle position
i have two input from a "computer"
input 1 switch to high to get it retracted
input 2 switch to high to extend
when input 1 and 2 are high it needs to go in the middle , same when input 1 and 2 are low
this is the non working code i have so far :
int section1 = 5; // input section 1
int section2 = 6;// input section 2
int millieu = 7;
int pwm = 3;
int sens = 12;
int lastState ;
void setup() {
pinMode (section1, INPUT);
pinMode (section2, INPUT);
pinMode (millieu, INPUT);
pinMode (pwm, OUTPUT);
pinMode (sens, OUTPUT);
lastState = 3 ;
}
void loop() {
if (digitalRead(section1) == HIGH) {
analogWrite(pwm, 255);
digitalWrite(sens, HIGH);
lastState = 1;
} else if (digitalRead(section2) == HIGH) {
analogWrite(pwm, 255);
digitalWrite(sens, LOW);
lastState = 2;
}
else if (digitalRead(section1) == HIGH && digitalRead(section2) == HIGH && digitalRead(millieu) == LOW )
{
analogWrite(pwm, 0);
}
else {
if (digitalRead(millieu) == LOW) {
analogWrite(pwm, 0);
//digitalWrite(sens, LOW);
//lastState = 1;
return;
}
switch (lastState) {
case 1:
analogWrite(pwm, 255);
digitalWrite(sens, LOW);
break;
case 2:
analogWrite(pwm, 255);
digitalWrite(sens, HIGH);
break;
default :
analogWrite(pwm, 255);
digitalWrite(sens, HIGH);
//delay (8000);
lastState = 1;
break;
}
Have you got pulldown resistors on the inputs to keep them at a known (LOW) state except when activated by taking them HIGH ?
Looking at the code I notice that it will always detect when section1 or section2 are HIGH before testing whether both are HIGH. In other words, if either are HIGH it will never test for both. Put the combined test first
Without keeping track of which side of middle you are on, there is no way to know if you should extend or retract.
Here is my first guess at how it has to be done. Each time the center is passed, keep track of which side of center the actuator is on (EXTENDED or RETRACTED). Then, when it comes time to head for center, we know which way to go.
const int RetractPin = 5; // input section 1
const int ExtendPin = 6; // input section 2
const int MiddleSensorPin = 7;
const int MotorPowerPin = 3;
const int MotorDirectionExtendPin = 12;
boolean LastCentered = false;
enum Positions
{
UNKNOWN,
RETRACTED,
CENTERED,
EXTENDED
} Position = UNKNOWN;
enum Directions
{
STOPPED,
RETRACTING,
CENTERING,
EXTENDING
} Direction = STOPPED;
void setup()
{
pinMode(RetractPin, INPUT);
pinMode(ExtendPin, INPUT);
pinMode(MiddleSensorPin, INPUT_PULLUP); // Open Collector
if (digitalRead(MiddleSensorPin) == LOW)
{
Position = CENTERED;
LastCentered = true;
}
digitalWrite(MotorPowerPin, LOW); // Off
pinMode(MotorPowerPin, OUTPUT);
pinMode(MotorDirectionExtendPin, OUTPUT);
}
void Extend()
{
digitalWrite(MotorDirectionExtendPin, HIGH);
digitalWrite(MotorPowerPin, HIGH);
Direction = EXTENDING;
}
void Retract()
{
digitalWrite(MotorDirectionExtendPin, LOW);
digitalWrite(MotorPowerPin, HIGH);
Direction = RETRACTING;
}
void loop()
{
boolean retract = digitalRead(RetractPin) == HIGH;
boolean extend = digitalRead(ExtendPin) == HIGH;
boolean centered = digitalRead(MiddleSensorPin) == LOW;
if (centered != LastCentered)
{
// The middle sensor has changed state
LastCentered = centered;
// If the center sensor just went active
if (centered && Direction == CENTERING)
{
digitalWrite(MotorPowerPin, LOW); // Off
Position = CENTERED;
Direction = STOPPED;
}
// If the center sensor just went inactive
// (we just passed center)
if (!centered && Direction == RETRACTING)
Position = RETRACTED;
if (!centered && Direction == EXTENDING)
Position = EXTENDED;
}
if (retract == extend)
{
// Head to the middle
if (Position == RETRACTED)
{
Extend();
Direction = CENTERING;
}
if (Position == EXTENDED)
{
Retract();
Direction = CENTERING;
}
}
else if (retract)
{
Retract();
}
else if (extend)
{
Extend();
}
}
Curious too..
what happens if you over or under drive a linear actuator?
do they have built in stops?
kind of thinking they don't or maybe all are not the same, so depends on actuator..
lol, so i guess, i was kind of thinking right, not all do..
and if it doesn't results in a damaged actuator and a very heavy bail of hay drops on @tinybear ..
hope he's ok!!
LOL , i'm still alive , have been away for the weekend , thx a lot for the code , i'm gonna work to understand it and test it .
Yes the actuator have limit switches so no worries for that part
I tried your code , just changed from low to high for sensor as i will use a npn instead
const int RetractPin = 5; // input section 1
const int ExtendPin = 6; // input section 2
const int MiddleSensorPin = 7;
const int MotorPowerPin = 3;
const int MotorDirectionExtendPin = 12;
boolean LastCentered = false;
enum Positions
{
UNKNOWN,
RETRACTED,
CENTERED,
EXTENDED
} Position = UNKNOWN;
enum Directions
{
STOPPED,
RETRACTING,
CENTERING,
EXTENDING
} Direction = STOPPED;
void setup()
{
pinMode(RetractPin, INPUT);
pinMode(ExtendPin, INPUT);
pinMode(MiddleSensorPin, INPUT_PULLUP); // Open Collector
if (digitalRead(MiddleSensorPin) == HIGH)
{
Position = CENTERED;
LastCentered = true;
}
digitalWrite(MotorPowerPin, LOW); // Off
pinMode(MotorPowerPin, OUTPUT);
pinMode(MotorDirectionExtendPin, OUTPUT);
}
void Extend()
{
digitalWrite(MotorDirectionExtendPin, HIGH);
digitalWrite(MotorPowerPin, HIGH);
Direction = EXTENDING;
}
void Retract()
{
digitalWrite(MotorDirectionExtendPin, LOW);
digitalWrite(MotorPowerPin, HIGH);
Direction = RETRACTING;
}
void loop()
{
boolean retract = digitalRead(RetractPin) == HIGH;
boolean extend = digitalRead(ExtendPin) == HIGH;
boolean centered = digitalRead(MiddleSensorPin) == HIGH;
if (centered != LastCentered)
{
// The middle sensor has changed state
LastCentered = centered;
// If the center sensor just went active
if (centered && Direction == CENTERING)
{
digitalWrite(MotorPowerPin, LOW); // Off
Position = CENTERED;
Direction = STOPPED;
}
// If the center sensor just went inactive
// (we just passed center)
if (!centered && Direction == RETRACTING)
Position = RETRACTED;
if (!centered && Direction == EXTENDING)
Position = EXTENDED;
}
if (retract == extend)
{
// Head to the middle
if (Position == RETRACTED)
{
Extend();
Direction = CENTERING;
}
if (Position == EXTENDED)
{
Retract();
Direction = CENTERING;
}
}
else if (retract)
{
Retract();
}
else if (extend)
{
Extend();
}
}
It works on most scenario but one , when it retract and pin 5 get back to LOW it doesnt reach center , it stays retracted , i still quite new to arduino and programming , i cant pin point where the problem is
It works the other way around though
When first turned on the Arduino has no way of knowing the position of the actuator. Only by passing through the center does it know if it is on the RETRACTED side of the center or the EXTENDED side of the center. Without knowing that, there is no way to know which way to go to get back to CENTERED.
If something different is happening, I can help you add Serial output to the sketch to determine why it won't center after a retract.