So I am currently using this code to run an RC car, it communicates just fine I would like to control the output a lot better though.
When the trigger is all the way down (Full speed forward) I get 1948
When the trigger is at rest I get roughly 1480
When the trigger is all the way forward (Full speed reversed) I get 920
I dont know what it is currently outputting for voltage but I need it ranging 0v to 5v.
0v being all the way reversed (920); 2.5v being stopped at rest (1480); and full speed(1948) to be 5v
I am getting these numbers from the channel inputs
/* This is the code for controlling any R/C car with an airplane transmitter written by Vishnu Chaitanya Karpuram. Enjoy!! */
int motor1Left = 5;// defines pin 5 as connected to the motor
int motor1Right= 6;// defines pin 6 as connected to the motor
int motor2forward = 7;// defines pin 7 as connected to the motor
int motor2Backward = 8;// defines pin 8 as connected to the motor
int channel1 = 9; // defines the channels that are connected
int channel2 = 10;// to pins 9 and 10 of arduino respectively
int Channel1 ; // Used later to
int Channel2 ; // store values
void setup ()
{
pinMode (motor1Left, OUTPUT);// initialises the motor pins
pinMode (motor1Right, OUTPUT);
pinMode (motor2forward, OUTPUT);
pinMode (motor2Backward, OUTPUT);// as outputs
pinMode (channel1, INPUT);// initialises the channels
pinMode (channel2, INPUT);// as inputs
Serial.begin (9600); // Sets the baud rate to 9600 bps
}
void loop ()
{
Channel1 = (pulseIn (channel1, HIGH)); // Checks the value of channel1
Serial.println (Channel1); //Prints the channels value on the serial monitor
if (Channel1 > 1300 && Channel1 < 1500 ) /*If these conditions are true, do the following. These are the values that I got from my transmitter, which you may customize according to your transmitter values */
{
digitalWrite (motor1Left, LOW); // Sets both the
digitalWrite (motor1Right, LOW);// motors to low
}
if (Channel1 < 1300) // Checks if Channel1 is lesser than 1300
{
digitalWrite (motor1Left, HIGH);// Turns the left
digitalWrite (motor1Right, LOW); // motor forward
}
if (Channel1 > 1500) // Checks if Channel1 is greater than 1500
{
digitalWrite (motor1Left, LOW);// Turns the right
digitalWrite (motor1Right, HIGH);// motor forward
}
Channel2 = (pulseIn (channel2, HIGH)); // Checks the value of channel1
Serial.println (Channel2); //Prints the channels value value on the serial monitor
if (Channel2 > 1300 && Channel1 < 1500 ) // If these conditions are true, do the following
{
digitalWrite (motor2forward, LOW);// Sets both the
digitalWrite (motor2Backward, LOW);// motors to low
}
if (Channel2 < 1300) // Checks if Channel2 is lesser than 1300
{
digitalWrite (motor2forward, LOW);// Turns the back wheels
digitalWrite (motor2Backward, HIGH);// motor backward
}
if (Channel2 > 1500) // Checks if Channel2 is greater than 1500
{
digitalWrite (motor2forward, HIGH);// Turns the back wheels
digitalWrite (motor2Backward, LOW);// motor backward
}
}
I am using a motor controller currently to power the motors and if I can get a steady voltage output to work with this code that would be amazing. Any help is appreciated.
Have a look at the map() function. It will allow you to get an output between 0 and 255 (or between 255 and 0) from your input range. You can then use this output to provide the parameter for analogRead() to get a PWM output proportional to your input
The numbers you are getting correspond to the width of 5V control pulses which would be roughly 1000us full reverse, 1500us neutral, 2000us full forward (your equipment may deviate slightly, or perhaps your trim isn't centered). If you are wanting to get away from using the motor controller (ESC) you are likely going to struggle to get a true variable voltage between 0 and 5V.
Realistically the simplest way to drive a motor in one direction is to control the "on" time using PWM via analogWrite(). An analogWrite(0) is 0% duty cycle (zero on time), analogWrite(127) would give you 50% duty cycle, and of course analogWrite(255) would be 100% duty cycle. These would roughly equate to the 0V, 2.5V, and 5V you are looking for; however I am really unsure at this point how the 0v becomes reverse though.
EDIT: I misread you question. You can use the analogWrite instead of digitalWrite to control the speed of the motors.
BH72:
Realistically the simplest way to drive a motor in one direction is to control the "on" time using PWM via analogWrite(). An analogWrite(0) is 0% duty cycle (zero on time), analogWrite(127) would give you 50% duty cycle, and of course analogWrite(255) would be 100% duty cycle. These would roughly equate to the 0V, 2.5V, and 5V you are looking for; however I am really unsure at this point how the 0v becomes reverse though.
I can do it this way; however, I would like to be able to slowly go forward rather than it going forward at one speed. My motor controller (Sabertooth 2x32) just works that way with its voltage (0 being reversed, 5 being forward, 2.5 stopped) so I just need to conform to its requirements.
Edit: Just got your edit, going to give it a try
Edit2: Going to have to use the map() UKHeliBob was talking about it looks like. I don't think I set up the analogwrite correctly.
If your motor controller won't accept PWM as an input (analogWrite) then the question becomes more of converting PWM to steady voltage (which would require additional components).
Be aware though that you can only use analogWrite() on certain pins dependent on your microprocessor.
This is an example of the map function that UKHeliBob spoke of, it would take the 920-1948 that you are getting as input and map it to a scale of 0-255 for use in analogWrite (this also shows correct use of analogWrite).
int motor1= 7;// defines pin 5 as connected to the motor FRONT MOTOR STEERING
int motor2 = 8;// defines pin 8 as connected to the motor REAR MOTOR
int channel1 = 9; // defines the channels that are connected
int channel2 = 10;// to pins 9 and 10 of arduino respectively
int analogOutputF ;
int Channel1 ; // Used later to
int Channel2 ; // store values
void setup() {
pinMode (motor1, OUTPUT);// initialises the motor pins
pinMode (motor2, OUTPUT);
pinMode (channel1, INPUT);// initialises the channels
pinMode (channel2, INPUT);// as inputs
Serial.begin (9600); // Sets the baud rate to 9600 bps
}
void loop() {
Channel1 = (pulseIn (channel1, HIGH)); // Checks the value of channel1
//Serial.println (Channel1); //Prints the channels value on the serial monitor
Channel2 = (pulseIn (channel2, HIGH)); // Checks the value of channel1
//Serial.println (Channel2); //Prints the channels value on the serial monitor
analogOutputF = map(Channel2, 1000, 2000, 120, 250);
analogWrite(motor2,analogOutputF);
Serial.println (analogOutputF);
}
And for any electrical questions I have a 24v battery powering the MC. The MC has a 5v and ground that I am using for the arduino to get power, then the RC transmitter is wired into the 5v output of the arduino and the ground of the arduino. The pins shouldn't matter but they can be found in the code above.
Yes unplugging it from my computer does help out with the issue but it is still extremely jumpy.