Hi,
I am all new to this forum, so please be nice.
And my idea of this post is to get a push in the right direction and then evolve on my own.
I have started a little project to improve my shooting skills.
The mechanic stuff is sorted, I made a small version with relays a few years ago.
My equipmentlist is as follows:
1 Arduino Uno
2 Dual Relay shields, Breaks both + and Ground to the motor.
2 Limitswitches, Magnetic type NO/NC
1 "Twist" button NO
1 12v Motor
What I want for the Arduino to do is.....
If Startswitch is turned, program start.
Will always start to the left,when limit switch left is reached stop.
Delay,then start to the right, when limit switch right is reached stop.
Delay. then repeat..... Until Startswitch is turned Off.
I have started but do not know how to get this sequence to run.
My code:
const int leftSwitch = 2; // Left Limit Swtich
const int rightSwitch = 3; // Right Limit Switch
const int MRight = 4; // Motor Right
const int MLeft = 5; // Motor Left
const int StartSwitch = 7; // Start Switch
int readingLeft; // Value Left switch
int readingRight; // Value Right switch
int readingStart; // Value Start switch
long edgedelay = 5000;
void setup() {
pinMode (leftSwitch, INPUT);
pinMode (rightSwitch, INPUT);
pinMode (MRight, OUTPUT);
pinMode (MLeft, OUTPUT);
pinMode (StartSwitch, INPUT);
}
void loop() {
// put your main code here, to run repeatedly:
readingLeft = digitalRead(leftSwitch);
readingRight = digitalRead(rightSwitch);
readingStart = digitalRead(StartSwitch);
start:
if (readingStart == HIGH)
goto Range;
if (readingStart == LOW)
goto start;
Range:
// Start motor to the left
digitalWrite (MLeft, HIGH);
//Limitswitch reached
if (readingLeft == HIGH);
digitalWrite (MLeft, LOW);
delay (edgedelay);
//Start motor to the right
digitalWrite (MRight, HIGH);
//Limitswitch reached
if (readingRight == HIGH);
digitalWrite (MRight, LOW);
delay (edgedelay);
goto start;
}
to move left,when limit switch left is reached stop, then delay
// Start motor to the left
digitalWrite (MLeft, HIGH);
// wait for Limitswitch reached - assume it goes HIGH at limit
while(digitalRead(leftSwitch) == LOW);
digitalWrite (MLeft, LOW);
delay (edgedelay);
I see you use goto statements in the code - try to avoid them as it leads to unstructured code
in particular your digitalRead() statements don't appear to be in your start: loop
It looks like what you need is a simple state machine.
Create a flag (bool type variable) showing which direction you're moving (true = right, false = left). Then toggling the switches triggers a delay and change of direction.
Something like:
bool direction = false;
loop() {
if (digitalRead(leftSwitch) == LOW && direction == false) {
direction = true; // change direction to right.
digitalWrite (MLeft, LOW); // Stop the motor.
delay(stopTime);
}
if (digitalRead(rightSwitch) == LOW && direction == true) {
direction = false; // change direction to left.
digitalWrite (MRight, LOW); // Stop the motor.
delay(stopTime);
}
if (direction) { // move right
digitalWrite (MRight, HIGH);
}
else { // move left
digitalWrite (MLeft, HIGH);
}
}
Now if it has to do other things as well, you have to use millis() based timing instead of the delay(). Look at the blink without delay example on how that works. You'll also have to add flags accordingly.
So I have tried to get this going but I dont get it.
It should be so simple but not for me.....
This is what i have tried:
const int leftSwitch = 2; // Left Limit Swtich
const int rightSwitch = 3; // Right Limit Switch
const int MRight = 4; // Motor Right
const int MLeft = 5; // Motor Left
const int StartSwitch = 7; // Start Switch
int readingLeft; // Value Left switch
int readingRight; // Value Right switch
int readingStart; // Value Start switch
long stopTime = 5000;
void setup() {
pinMode (leftSwitch, INPUT);
pinMode (rightSwitch, INPUT);
pinMode (MRight, OUTPUT);
pinMode (MLeft, OUTPUT);
pinMode (StartSwitch, INPUT);
bool direction = false;
}
void loop() {
bool direction = false;
if (digitalRead(leftSwitch) == LOW && direction == false) {
direction = true; // change direction to right.
digitalWrite (MLeft, LOW); // Stop the motor.
delay(stopTime);
}
if (digitalRead(rightSwitch) == LOW && direction == true) {
direction = false; // change direction to left.
digitalWrite (MRight, LOW); // Stop the motor.
delay(stopTime);
}
if (direction) { // move right
digitalWrite (MRight, HIGH);
}
else { // move left
digitalWrite (MLeft, HIGH);
}
}
Sanity check: how are your buttons wired? Do you have external pull up resistors wired with them? I notice you didn't enable the internal pullup resistors (by setting pinMode to INPUT_PULLUP rather than INPUT).
In loop() you start by setting direction to false. So every time loop() runs, direction is set back to false, and you try to set your motor to run to the left. Declare that variable global, i.e. at the top of your sketch. That way you keep the value as you set it in loop().
Another thing: you can safely merge the two if statements in one. The moment you detect the limit switch is triggered, you turn off one motor. That's also where you can turn on the other, instead of doing that in a separate if statement later. Makes the sketch more readable.
About the buttons, they are connected with Pullup resistors, (i dont really know what it is.)
I got something right this time.
But the sequence is wrong.
I need both relays to be switched off during the delay.
const int leftSwitch = 2; // Left Limit Swtich
const int rightSwitch = 3; // Right Limit Switch
const int MRight = 4; // Motor Right
const int MLeft = 5; // Motor Left
const int StartSwitch = 7; // Start Switch
bool direction = false;
int readingLeft; // Value Left switch
int readingRight; // Value Right switch
int readingStart; // Value Start switch
long stopTime = 5000;
void setup() {
pinMode (leftSwitch, INPUT);
pinMode (rightSwitch, INPUT);
pinMode (MRight, OUTPUT);
pinMode (MLeft, OUTPUT);
pinMode (StartSwitch, INPUT);
}
void loop() {
// bool direction = false;
if (digitalRead(leftSwitch) == LOW && direction == false) {
direction = true; // change direction to right.
digitalWrite (MLeft, LOW); // Stop the motor.
delay(stopTime);
}
if (digitalRead(rightSwitch) == LOW && direction == true) {
direction = false; // change direction to left.
digitalWrite (MRight, LOW); // Stop the motor.
delay(stopTime);
}
if (direction) { // move right
digitalWrite (MRight, HIGH);
}
else { // move left
digitalWrite (MLeft, HIGH);
}
}
const int leftSwitch = 2; // Left Limit Swtich
const int rightSwitch = 3; // Right Limit Switch
const int MRight = 4; // Motor Right
const int MLeft = 5; // Motor Left
const int StartSwitch = 7; // Start Switch
bool direction = false;
int readingLeft; // Value Left switch
int readingRight; // Value Right switch
int readingStart; // Value Start switch
long stopTime = 5000;
void setup() {
pinMode (leftSwitch, INPUT);
pinMode (rightSwitch, INPUT);
pinMode (MRight, OUTPUT);
pinMode (MLeft, OUTPUT);
pinMode (StartSwitch, INPUT);
digitalWrite (MLeft, HIGH); // Stop the motor.
digitalWrite (MRight, HIGH); // Stop the motor.
}
void loop() {
// bool direction = false;
if (digitalRead(leftSwitch) == LOW && direction == false) {
direction = true; // change direction to right.
digitalWrite (MLeft, HIGH); // Stop the motor.
delay(stopTime);
}
if (digitalRead(rightSwitch) == LOW && direction == true) {
direction = false; // change direction to left.
digitalWrite (MRight, HIGH); // Stop the motor.
delay(stopTime);
}
if (direction) { // move right
digitalWrite (MRight, LOW);
}
else { // move left
digitalWrite (MLeft, LOW);
}
}
Pull-up resistors make sure the pin is pulled to +5V, to give it a defined value when the switch is open. Otherwise your input readings will be random, and that gives all kinds of bad results.
You can save yourself a resistor by using the internal ones, and set the pin to INPUT_PULLUP.