Hi All,
I have searched the Forum but haven't found anything exactly like my intended use case. I'd like to program an Arduino to control an RC ESC. The RC ESC has reverse. However I'd like to have a separate switch for forward and reverse. Just for clarification I am not talking about switching the polarity of the ESC's output. Instead, I want the Arduino's PWM output to be dependent on the position of the foward/reverse switch as follows:
I'd like to use an ebike throttle and I have a circuit board to convert that to an RC PWM output, if Arduino can read that as an input. Or I could connect the ebike throttle directly to the Arduino, if it can read 0-5 volts directly, in which case the Input PWM column above would change accordingly.
Once again, the switch would not be used to change the the wiring of the ESC output. Instead I want the Arduino to read the position of the switch and then output a PWM signal depending on the input from the throttle and the input from the position of the switch.
If working correctly, the setup would behave much like a children's ride on toy, with one throttle pedal and a separate switch that controls direction (FWD or REV).
I understand the conditional logic part of the code you sent, but have a few questions.
Does the digitalRead() function read the position of the FWD/REV switch or the incoming PWM throttle signal? And what is the meaning of its value being set to "HIGH"?
Maybe I should have expanded a bit. I want the throttle to be continuous from the zero point to the max point in each direction (either forward or reverse). So I'm guessing I'll need some kind of for loop?
The simple example I posted would change the direction of rotation of the motor attached to the ESC with no speed control so it would run at full speed. It was an example of simple direction control
It would be easy to add an analogRead() to read the throttle position and apply that to the ESC output depending on the position of the switch, but that would be dangerous
Suppose that the motor is running at full throttle forward and the user flips the forward/reverse switch. Should the motor immediately slam into reverse ? Probably not, so what should happen ?
Here I will distinguish between throttle position reverse and motor reverse.
The RC ESC has a brake that it normally goes into if you slam the throttle to full throttle position reverse from throttle position forward. Then the user has to go back to neutral point and after that it will go into motor reverse if the throttle is again pointed towards throttle position reverse. So there's already a little bit of a Fail-Safe built-in. However it would be nice if Arduino could detect a change in the position of the FWD/REV switch and then implement a 3-second pause, for example.
So for each iteration of the loop, it would check to see what the analog reading is from the throttle pin and then it would output PWM to the ESC differently depending on the position of the FWD/REV switch. I have no idea how to program the pause in if the switch changes.
The Arduino loop() function will do the looping for you
You need to detect the change of switch position to invoke the delay
The value that you write to the ESC needs to change depending upon the switch position and what analogRead() returns
If you really are a complete "noob" then don't jump into this project. Start by looking at the examples in the IDE, understanding the structure of an Arduino sketch and building towards you project
read an input pin and print its state
read an input pin and print a message when it changes state
read in input pin and print a message when it becomes LOW
Try the Servo examples
read an analogue input and print its values
read an analogue input and move the servo based on the value read
investigate the use of the delay() function and consider alternatives
Stitch together what you have learned into a first attempt at you your project
debug tour project using Serial.print() statements
when it is working consider possible improvements/enhancements
byte servoPin = 9; // signal pin for the ESC.
byte potentiometerPin = A0; // analog input pin for the potentiometer (ebike throttle in my case-not sure what to change).
Servo servo;
void setup() {
servo.attach(servoPin);
servo.writeMicroseconds(1500); // send "stop" signal to ESC. Also necessary to arm the ESC.
delay(7000); // delay to allow the ESC to recognize the stopped signal.
}
void loop() {
int potVal = analogRead(potentiometerPin); // read input from potentiometer.
if (digitalRead(switchPin) == HIGH)
{
int pwmVal = map(potVal,0, 1023, 1500, 2000); // maps potentiometer values to PWM value.
servo.writeMicroseconds(pwmVal); // Send signal to ESC.
}
else
{
int pwmVal = map(potVal,0, 1023, 1500, 1000); // maps potentiometer values to PWM value.
servo.writeMicroseconds(pwmVal); // Send signal to ESC.
}
Much of that looks OK. When posting code here please Auto Format it in the IDE to improve its layout and post it here using code tags to make it easier to read and copy. If you right click in the IDE there is an option top "Copy for forum" that adds the code tags to the copied code automatically ready for posting
Here is the formatted version. I'm not able to test it yet but will do so soon.
#include <Servo.h>
int ESCPin = 9; // signal pin for the ESC.
int switchPin = A1; // analog input pin for the FWD/REV switch.
int potPin = A0; // analog input pin for the potentiometer (ebike throttle in my case-not sure what to change).
Servo servo;
void setup() {
servo.attach(ESCPin);
servo.writeMicroseconds(1500); // send "stop" signal to ESC. Also necessary to arm the ESC.
delay(2000); // delay to allow the ESC to recognize the stopped signal and arm.
}
void loop() {
int potVal = analogRead(potPin); // read input from potentiometer.
if (digitalRead(switchPin) == HIGH) {
int pwmVal = map(potVal,0, 1023, 1500, 2000); // maps potentiometer values to PWM value.
servo.writeMicroseconds(pwmVal); // Send signal to ESC.
}
else {
int pwmVal = map(potVal,0, 1023, 1500, 1000); // maps potentiometer values to PWM value.
servo.writeMicroseconds(pwmVal); // Send signal to ESC.
}
}
It is a matter of personal choice but this is how I have Auto Format set up to format code as I think it shows the code blocks more clearly
#include <Servo.h>
int ESCPin = 9; // signal pin for the ESC.
int switchPin = A1; // analog input pin for the FWD/REV switch.
int potPin = A0; // analog input pin for the potentiometer (ebike throttle in my case-not sure what to change).
Servo servo;
void setup()
{
servo.attach(ESCPin);
servo.writeMicroseconds(1500); // send "stop" signal to ESC. Also necessary to arm the ESC.
delay(2000); // delay to allow the ESC to recognize the stopped signal and arm.
}
void loop()
{
int potVal = analogRead(potPin); // read input from potentiometer.
if (digitalRead(switchPin) == HIGH)
{
int pwmVal = map(potVal, 0, 1023, 1500, 2000); // maps potentiometer values to PWM value.
servo.writeMicroseconds(pwmVal); // Send signal to ESC.
}
else
{
int pwmVal = map(potVal, 0, 1023, 1500, 1000); // maps potentiometer values to PWM value.
servo.writeMicroseconds(pwmVal); // Send signal to ESC.
}
}
A question for you
Is there a pulldown resistor on the switch pin to keep it LOW when not expressly switched to HIGH or is it floating at an unknown voltage, maybe LOW, maybe HIGH ?
Consider using INPUT_PULLUP in the pinMode() for the switch pin to activate the built in pullup resistor and change the circuit to take the pin LOW when teh switch is turned on