Basically, I have a BLDC motor and ESC controlled by the Arduino uno. I'm using a 3 state switch to control Forward/neutral/reverse. I connected the switch common connection to 5v and the other sides to pins 11 and 12. However, when I run my code, it just constantly loops my first for loop and my switch has no effect. I also have a hall sensor I'm trying to use to stop it so that's why the attachInterrupt is there, but I do not know if that is going to work yet because of the previous problem.
#include <Servo.h>
Servo ESC; // create servo object to control the ESC
boolean CTRL = false;
boolean StateA=false;
boolean StateB=false;
boolean STOP=false;
byte Pos=90;
byte FMax = 180;
byte RMax = 0;
int pos = 0; // variable to store the servo position
void setup() {
Serial.begin(57600);
attachInterrupt(0, magnet_detect, RISING); //Initialize hall sensor to interrupt pin (digital pin 2)
// Attach the ESC on pin 9
ESC.attach(9,1000,2000); // (pin, min pulse width, max pulse width in microseconds)
}
void loop() {
StateA=digitalRead(11);
StateB=digitalRead(12);
if (StateA && !CTRL && !STOP){
for (pos = 90; pos <= 110; pos += 1) { // goes from 90 degrees to 180 degrees
ESC.write(pos); // tell motor speed in variable 'pos'
delay(200); // waits 200ms for the servo to reach the position
}
CTRL=!CTRL;
}
if (StateB && CTRL && !STOP){
for (pos = 90; pos <= 60; pos -= 1) { // goes from 90 degrees to 0 degrees
ESC.write(pos); // tell motor speed in variable 'pos'
delay(200); // waits 200ms for the servo to reach the position
}
CTRL=!CTRL;
}
if (StateA && CTRL && !STOP){
ESC.write(FMax);
}
if (StateB && !CTRL){
ESC.write(RMax);
}
if(!StateA && !StateB) {
ESC.write(90);
STOP = false;
}
if (STOP) {
ESC.write(90);
}
}
void InterruptSR() {
STOP = !STOP;
}
void magnet_detect() //Function to stop motor once hall sensor detects a magnet
{
pos <= 90;
ESC.write(pos);
}
I recommend INPUT_PULLUP and connect the switch terminals to GND. Unless you have pulldown resistors the way you have it wired the inputs will float with NC.
When I am beginning a project I write a simple sketch to test each piece of hardware. In this case write 3 sketches: one for the switch, one for the hall effect sensor, and one for the servo. That way when you test your final code you can be sure the hardware and wiring are NOT the problem if it doesn't work.
You do not need an interrupt for the hall effect sensor. I would just recommend reading the sensor at the beginning of loop().
200ms for the servo to move 1 degree is excessive. 20 degrees of movement will take 4 seconds. 30 degrees will take 6 seconds the way you have it coded. If you really need it move that slow that is fine; however, your program will be completely stalled during these movements, which may or may not be a problem.
I took out the Hall sensor stuff, and tried with just the acceleration code and switches. I added a pull down resistor as well and I get no response at all. Also I know the acceleration code works just fine, I have tested this many times.
#include <Servo.h>
Servo ESC; // create servo object to control the ESC
int pos = 90; // variable to store the servo position
int stateA = digitalRead(11); // variables for reading the switches status
int stateB = digitalRead(12);
void setup() {
Serial.begin(57600);
ESC.attach(9,1000,2000); // (attach to pin 9, min pulse width, max pulse width in microseconds)
if (stateA == LOW) { // if swith in forward postion run motor forward a set speed
for (pos = 90; pos <= 110; pos += 1) { // goes from 0 degrees to 180 degrees
ESC.write(pos); // tell motor speed in variable 'pos'
delay(20); // waits 200ms for the servo to reach the position
}
if (stateB == HIGH) { // if switch in rear position run motor backwards at set speed
for (pos = 90; pos <= 60; pos -= 1) { // goes from 90 degrees to 0 degrees
ESC.write(pos); // tell motor speed in variable 'pos'
delay(200); // waits 200ms for the servo to reach the position
}
}
else { // motor off, mid position
pos <= 90;
ESC.write(pos);
}
}
}
void loop()
{
try this sketch for testing the switches separately from anything else
trying to be quick by combining too early too many things will turn out to slow you down because there are multiple things that are wrong.
trying this then trying that without knowing it slows you down too
For all future steps take the time to do separated tests and take time to learn the basics.
This will speed up finishing your project
const byte stateA_pin = 11; // use constants for IO-pin NOT direct numbers
const byte stateB_pin = 12;
int stateA; // variables for reading the switches status
int stateB;
unsigned long myTestTimer;
// helper-function for easy to use non-blocking timing
boolean TimePeriodIsOver (unsigned long &expireTime, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - expireTime >= TimePeriod ) {
expireTime = currentMillis; // set new expireTime
return true; // more time than TimePeriod) has elapsed since last time if-condition was true
}
else return false; // not expired
}
void setup() {
Serial.begin(115200); // start serial interface
Serial.println( F("Setup-Start") );
pinMode(stateA_pin, INPUT);
pinMode(stateB_pin, INPUT);
}
void loop() {
// reading the switches status must be done INSIDE loop
stateA = digitalRead(stateA_pin);
stateB = digitalRead(stateB_pin);
if ( TimePeriodIsOver(myTestTimer,1000) ) {
// if 1000 milliseconds = one second have passed by
Serial.print("digitalRead("); // print title and state of IO-pin to the serial monitor
Serial.print(stateA_pin);
Serial.print(")=stateA=");
Serial.println(stateA);
Serial.print("digitalRead(");
Serial.print(stateB_pin);
Serial.print(")=stateB=");
Serial.println(stateB);
}
}
Be the change you want to see in the world
best regards Stefan
With the if statement formatted properly you can see how they are nested. Is this what you intended? Unless stateA==LOW you will never get to the if (stateB == HIGH). These ifs were NOT nested in your original code. This is why properly formatted and indented code is important.
if (stateA == LOW) { // if swith in forward postion run motor forward a set speed
for (pos = 90; pos <= 110; pos += 1) { // goes from 0 degrees to 180 degrees
ESC.write(pos); // tell motor speed in variable 'pos'
delay(20); // waits 200ms for the servo to reach the position
}
if (stateB == HIGH) { // if switch in rear position run motor backwards at set speed
for (pos = 90; pos <= 60; pos -= 1) { // goes from 90 degrees to 0 degrees
ESC.write(pos); // tell motor speed in variable 'pos'
delay(200); // waits 200ms for the servo to reach the position
}
}
else { // motor off, mid position
pos <= 90;
ESC.write(pos);
}
}
So with this code, it is like you said, it will only go to next if statement when stateA == HIGH. How can I make it progress to the next if statement without needing the first if statement's condition to be met?
#include <Servo.h>
Servo ESC; // create servo object to control the ESC
int pos = 90; // variable to store the servo position
const byte stateA_pin = 10; // use constants for IO-pin NOT direct numbers
const byte stateB_pin = 11;
int stateA; // variables for reading the switches status
int stateB;
void setup() {
pinMode(stateA_pin, INPUT);
pinMode(stateB_pin, INPUT);
ESC.attach(9,1000,2000); // (attach to pin 9, min pulse width, max pulse width in microseconds)
}
void loop()
{
Serial.begin(115200);
stateA = digitalRead(stateA_pin);
stateB = digitalRead(stateB_pin);
if (stateA == HIGH) { // if swith in forward postion run motor forward a set speed
for (pos = 90; pos <= 110; pos += 1) { // goes from 0 degrees to 180 degrees
Serial.print("digitalRead("); // print title and state of IO-pin to the serial monitor
Serial.print(stateA_pin);
Serial.print(")=stateA=");
Serial.println(stateA);
ESC.write(pos); // tell motor speed in variable 'pos'
delay(20); // waits 200ms for the servo to reach the position
}
if (stateB == HIGH) { // if switch in rear position run motor backwards at set speed
for (pos = 90; pos <= 110; pos += 1) { // goes from 90 degrees to 0 degrees
Serial.print("digitalRead(");
Serial.print(stateB_pin);
Serial.print(")=stateB="); Serial.println(stateB);
ESC.write(pos); // tell motor speed in variable 'pos'
delay(20); // waits 200ms for the servo to reach the position
}
}
else { // motor off, mid position
pos <= 90;
ESC.write(pos);
}
}
}
if (stateA == HIGH) { // if swith in forward postion run motor forward a set speed
for (pos = 90; pos <= 110; pos += 1) { // goes from 0 degrees to 180 degrees
Serial.print("digitalRead("); // print title and state of IO-pin to the serial monitor
Serial.print(stateA_pin);
Serial.print(")=stateA=");
Serial.println(stateA);
ESC.write(pos); // tell motor speed in variable 'pos'
delay(20); // waits 200ms for the servo to reach the position
} // closing curly brace of for-loop
// if-condition still INSIDE if-condition if (stateA == HIGH) {
if (stateB == HIGH) { // if switch in rear position run motor backwards at set speed
for (pos = 90; pos <= 110; pos += 1) { // goes from 90 degrees to 0 degrees
Serial.print("digitalRead(");
Serial.print(stateB_pin);
Serial.print(")=stateB="); Serial.println(stateB);
ESC.write(pos); // tell motor speed in variable 'pos'
delay(20); // waits 200ms for the servo to reach the position
} // closing curly brace of for-loop
} // closing curly brace of if (stateB == HIGH)
// else still INSIDE if-condition if (stateA == HIGH) {
else { // motor off, mid position
pos <= 90;
ESC.write(pos);
} // closing curly brace of else
} // clsoing curly brace of if (stateA == HIGH) {
well this is one of the rare cases where I'm just asking back
After showing you that your second if-condition is
inside
your first if-condition
What do you think?
Be the change you want to see in the world
best regards Stefan