Hello, I am new to Arduino, and starting my first "project". I'm trying to connect my rc receiver to an H-bridge (L298N) using an Arduino. I have tried multiple times, and can't even seem to get anything working. If anyone has done this before and is willing to show and explain what to do to get this working, that would be great. Thanks
Oh ok thanks. I did try to look on the internet, and couldn't find much. I might just need to start a little smaller, and go from there.
I am happy to hear this... it is the right way... here is a page full of programming electronics exercises.
Here is all my code. (That hasn't been working)
#include <Servo.h>
// Receiver input pins
const int CH1_PIN = 9; // Throttle signal from FlySky receiver
// L298N motor driver pins
const int IN1 = 5;
const int IN2 = 6;
const int ENA = 7;
// Variables for receiver input
int ch1Value = 0; // Holds the PWM signal from CH1 (1000-2000us)
int motorSpeed = 1;
void setup() {
// Set up L298N pins
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(ENA, OUTPUT);
// Initialize serial monitor for debugging
Serial.begin(9600);
// Set initial motor state to stop
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
analogWrite(ENA, 0);
}
void loop() {
// Read PWM signal from FlySky receiver (pulseIn returns width in microseconds)
ch1Value = pulseIn(CH1_PIN, HIGH, 25000); // Timeout of 25ms (FlySky sends every ~20ms)
Serial.println(ch1Value); // Debugging the signal
// Map the receiver signal (1000-2000us) to motor speed and direction
if (ch1Value > 1500) { // Forward
int forwardSpeed = map(ch1Value, 1500, 2000, 0, 255); // Map 1500-2000 to 0-255
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(ENA, forwardSpeed);
} else if (ch1Value < 1500) { // Backward
int backwardSpeed = map(ch1Value, 1500, 1000, 0, 255); // Map 1500-1000 to 0-255
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
analogWrite(ENA, backwardSpeed);
} else { // Stop (around 1500us)
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
analogWrite(ENA, 0);
}
delay(20); // Small delay to allow smooth signal processing
}
The goal is to use the RC controller to control a motor using the Arduino and motor driver. After connecting everything, and putting the code into the Arduino, the motor won't spin.
How would you do that? I have not tried that.
I will try to get to them. I am just trying one thing at a time.
Thank you for this seggestion. I did just tried that and only out 3&4 worked. I am going to try again but put the motor on 3 & 4.
Your mapped channel 1 value is (1500 to 2000) so any "throttle" above zero (ch1 > 1500) should enable the motor, with 1750 as midway and a 25 step deadband (1725 - 1775) to stop.
// Map the receiver signal (1000-2000us) to motor speed and direction
int lowPWM = 1500, highPWM = 2000, midPWM = (lowPWM + highPWM) / 2, deadband = 50;
if (ch1Value > midPWM + deadband && ch1Value < highPWM) { // Forward
int forwardSpeed = map(ch1Value, lowPWM, highPWM, 0, 255); // Map 1500-2000 to 0-255
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(ENA, forwardSpeed);
} else if (ch1Value > lowPWM && ch1Value < midPWM - deadband) { // Backward
int backwardSpeed = map(ch1Value, lowPWM, highPWM, 0, 255); // Map 1500-1000 to 0-255
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
analogWrite(ENA, backwardSpeed);
} else if (ch1Value >= midPWM - deadband / 2 && ch1Value <= midPWM + deadband / 2 ) { // Stop (around 1500us)
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
analogWrite(ENA, 255);
}
In all cases like this
I want to control device X with inputs from Y.
a key to success is divide and conquer.
The values derived from measuring the r/c pulses have nothing to do with the H-bridge. The r/c stuff needn't be complicate by thinking about what it will land end controlling. The H-bridge can't know or care where the numbers are coming from.
So… get the r/c input to produce plausible numbers, print them and work until they are correct.
Meanwhile or later, use numbers to control the H-bridge until you know how and what numbers work. Here again the serial monitor is your friend. You'll want to know how to solicit numbers and others things by serial sooner later, so now is as good a time as any to learn that first.
Then… connect the perfected number producing code to the perfected number consuming code and you are done.
This is a common structure for sketches like this. It is known generally as the IPO model, read about it in the abstract here
but the main idea is get all inputs, do some calculating and then do all outputs. It usually means you can get the parts working without the one part worrying about the others. By standing up replacements during development.
a7
I've been impressed with chatGPT 4, and although I have no intention of using it and passing off its work as my own, I thought it would be interesting to ask it to produce a take on my previous post. All I gave it was the post and an admonishment to try for fewer words.
By chatGPT
To control device X with inputs from Y, the key is to divide and conquer.
The values from the R/C pulses are independent of the H-bridge. Don’t overcomplicate things by thinking about the end goal too soon. The H-bridge doesn’t need to know where the numbers come from.
First, focus on getting the R/C input to generate correct numbers. Print and test them until they're right.
Next, use those numbers to control the H-bridge. The serial monitor will be crucial for troubleshooting—get comfortable with it early.
Once both parts (number generation and consumption) work as expected, connect them, and you’re done.
This approach follows the IPO model: Input → Process → Output. By isolating parts during development, you can focus on each individually without worrying about the whole system at once.
I didn't quibble, but might have asked it to say explicitly that the numbers to test the H-bridge aren't necessarily coming from the R/C code. I am sure we could have come to an agreement there.
a7
I see two major cycle-hogging loop-slowers in your process than can throw timing off.
ch1Value = pulseIn(CH1_PIN, HIGH, 25000); // Timeout of 25ms (FlySky sends every ~20ms)
and
delay(20);
What does FlySky send every ~20ms? A variable-length HIGH pulse to actuate a servo?
The RC receiver units run on their own, neither interferes with the other except when both use power, there is less power for either.
While you use pulseIn(), the other channel can't be read, you get interference through code blocking. There is another way to code that that finely interleaves reading both channels concurrently and moving servos to match.
Find out how fast your radio unit can transmit serial RX and if it's really fast, you can send changes to multiple axes and latches responsively. How fast can 4 to 6 chars be sent at 960/sec?
That is axis-label char, + or -, 1 to 3 digits and a 0. Only on change for any servo-axis. Or stepper-axis. Or if you want, Lights, etc. All on one channel, the higher the baudrate the more responsive it can be.
With an accelerometer on-board, RC plane has "The Ball" and could have rudder programmed in to center the ball and deliver coordinated flight automatically.
With IoT radio, high baud rates are possible up towards 700m. It would be possible to show the pilot data from the model, basic instrument readings like airspeed and density altitude. Look into 433kHz modules, cheap ones allow 300m but better ones go past 1km. Free use only allows so much power. Put the user's transmitter on a pole gets longer range.
There are affordable to cheap data radio systems, good
You might benefit from using library.
Here's one
or if your receiver outputs PPM
there are other libraries that do the same thing, those are just the first I found googling.
Decoding N channels of PWM is not the way to go.
a7
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.