Bouw een Betrouwbare Arduino RC-ontvanger voor Modellen & Projecten
In deze tutorial leer je hoe je een Arduino-gebaseerde RC-ontvanger bouwt. Na het bouwen van mijn DIY Arduino RC-zender in een eerdere video, kreeg ik veel verzoeken om een speciale ontvanger te maken, dus hier is hij.
Je kunt de volgende video bekijken of de geschreven tutorial hieronder lezen.
Deze twee apparaten communiceren nu eenvoudig met elkaar en we kunnen ze gebruiken om allerlei dingen draadloos te besturen. Ik leg uit hoe alles werkt aan de hand van een paar voorbeelden. In het eerste voorbeeld gebruiken we deze Arduino RC-ontvanger om een eenvoudige auto met twee DC-motoren te besturen. In het tweede voorbeeld laat ik zien hoe je brushless-motoren en servo's kunt besturen, componenten die veel voorkomen in commerciële RC-vliegtuigen, boten, auto's, enz. Als we weten hoe we ze moeten besturen, kunnen we veel RC-modellen eenvoudig aanpassen en besturen met onze eigen custom-gebouwde Arduino-zender.

Als derde voorbeeld laat ik zien hoe ik dit Arduino-gebaseerde RC-systeem heb aangepast en gebruikt om een commerciële RC-auto te besturen.
Arduino RC-ontvanger Schakelschema
Laten we beginnen met het bekijken van het schakelschema van dit systeem. De radiocommunicatie is gebaseerd op de NRF24L01-transceivermodules.

De zender stuurt continu data van zijn bedieningselementen: de joysticks, knoppen, potentiometers en wisselschakelaars. We ontvangen deze data met de ontvanger. Voor meer details over de werking van deze Arduino-zender kun je mijn andere gedetailleerde tutorial erover raadplegen.
We kunnen hier ook vermelden dat deze RC-ontvanger niet noodzakelijkwerkt met alleen deze specifieke zender die ik bouwde. Het kan werken met elke andere vergelijkbare opstelling bestaande uit een Arduino-bord en een NRF24L01-module.

Desondanks is de "hersenen" van deze RC-ontvanger een Arduino Pro Mini-bord. Voor de voeding kunnen we de VCC-pin gebruiken waaraan we 5V aansluiten, of de RAW-pin waaraan we 6 tot 12V kunnen aansluiten. Let op dat er twee versies van de Arduino Pro Mini zijn: de versie die ik hier gebruik werkt op 5V, de andere op 3.3V. De NRF24L01-module werkt op 3.3V, dus we hebben een spanningsregelaar nodig. Ik gebruik de AMS1117-spanningsregelaar, die 3.3V levert vanuit ingangen van 5V tot 12V.
Je kunt de benodigde componenten voor deze Arduino RC-ontvanger via de onderstaande links verkrijgen:
- NRF24L01 Transceiver Module
- NRF24L01 + PA + LNA
- AMS1117 3.3V Spanningsregelaar
- Pin Headers Man + Vrouw Amazon / Banggood / AliExpress
- Arduino Pro Mini
- Arduino Pro Mini zoals ik gebruikte
Voor de communicatie met de Arduino gebruikt de NRF24L01-module het SPI-protocol, plus twee extra digitale pinnen. Hierdoor blijven er 9 digitale pinnen over die als uitgangskanalen kunnen dienen, waarvan twee de RX- en TX-pinnen zijn. Het is de moeite waard om op te merken dat deze pinnen losgekoppeld moeten zijn van alles tijdens het uploaden van een sketch naar het Arduino-bord. Daarom heb ik het mogelijk gemaakt om ze via aparte pinheaders te verbinden of te verbreken. We kunnen ook de analoge ingangen als digitale uitgangen gebruiken, dus ondanks dat dit Arduino-bord vrij klein is, hebben we veel uitgangen of kanalen beschikbaar.
PCB-ontwerp
Om de schakeling compact te houden, ontwierp ik een custom PCB met de gratis online ontwerpsoftware EasyEDA. Ik plaatste de 8 kanalen recht naast een 5V- en een Ground-rail, zodat we servo's en ESC's er direct op kunnen aansluiten. Kanaal nummer 9 bevindt zich op een aparte positie, nabij de VCC-pin van de Arduino, zodat we bijvoorbeeld een ESC kunnen gebruiken om de Arduino te voeden via de Battery Eliminator Circuit (BEC) die 5V levert. Natuurlijk kunnen we elke andere kanaal hiervoor gebruiken, aangezien de VCC-pin ook verbonden is met die 5V-rail.

Wat kanalen 7 en 8 betreft, zien we hier dat ze onderbroken zijn door deze pinheaders. Als we ze willen gebruiken, hoeven we de twee pinnen alleen maar met elkaar te verbinden. De programmeerheader zit in de rechterbovenhoek en de 100uF condensator dient zowel voor de spanningsregelaar als voor de NRF24L01-module. In de linkerbovenhoek van de PCB plaatste ik de analoge pinnen.
Nog een opmerking: sommige Arduino Pro Mini-borden kunnen een andere pin-indeling hebben, daarom heb ik een extra versie van de PCB opgenomen zodat je kunt kiezen welke bij jouw bord past.

Hier is een link naar de projectbestanden van deze PCB. Na het voltooien van het ontwerp genereerde ik de benodigde Gerber-bestanden voor de productie.
Gerber-bestanden:
Vervolgens bestelde ik de PCB bij JLCPCB, die ook de sponsor van deze video is.

We kunnen eenvoudig het Gerber-bestand slepen en neerzetten. Zodra het geüpload is, kunnen we onze PCB bekijken in de Gerber-viewer. Als alles klopt, selecteren we de gewenste eigenschappen voor onze PCB. Dat is alles, nu kunnen we onze PCB bestellen tegen een redelijke prijs. Let op: als het je eerste bestelling is bij JLCPCB, kun je tot 5 PCB's voor slechts $2 krijgen.

PCB-assemblage
Na enkele dagen zijn de PCB's aangekomen. De kwaliteit is geweldig en alles komt precies overeen met het ontwerp.

Nu kunnen we de PCB assembleren. Eerst solderen we de pinheaders van het Arduino-bord. Een handige manier is om een breadboard te gebruiken om de pinheaders vast te zetten, zodat het bord stevig blijft tijdens het solderen. Zoals eerder gezegd, kunnen de pinnen afhankelijk van je bord iets afwijken, hou daar rekening mee.

Er zijn ook enkele Ground-pins die we vrij moeten laten omdat er sporen op de PCB eronderheen lopen. Na het solderen van het Arduino-bord knipte ik de overbodige pinlengtes af.
Vervolgens plaatste ik alle andere pinheaders op hun plaats. We hebben zowel mannelijke als vrouwelijke pinheaders nodig, maar de keuze is aan jou. Het is echter een goed idee om mannelijke pinheaders te gebruiken voor de digitale kanalen, aangezien servo-motoren en ESC-verbindingen vrouwelijk zijn, zodat we ze gemakkelijk kunnen aansluiten.

De spanningsregelaar is een SMD-component, dus ik gebruikte wat Blue-Tack lijm om hem vast te houden tijdens het solderen. Tot slot, na het solderen van de twee condensators, kunnen we de NRF24L01-module op de juiste pinheaders plaatsen.

Afhankelijk van de toepassing of de benodigde bereik, kunnen we kiezen tussen de standaardmodule met onboard antenne, of de variant waarmee we een grotere antenne kunnen verbinden en een draadloze communicatie van tot 700 meter in open ruimte kunnen bereiken. Zo, onze Arduino RC-ontvanger is nu klaar en we kunnen hem voor alles gebruiken wat we willen.
Voor het programmeren van de ontvanger, of het verbinden van de Arduino Pro Mini met de computer, kunnen we een USB-naar-seriële UART-interface gebruiken die verbonden wordt met de programmeerheader.

In het Arduino IDE Tools-menu selecteren we het Arduino Pro of Pro Mini-bord, de juiste processerversie, de poort en de programmeermethode "USBasp".

Nu kunnen we code naar de Arduino uploaden.
Voorbeeld 1 – Arduino RC-auto
Ok, nu bekijken we het eerste voorbeeld.

Het is een eenvoudige auto met twee 12V DC-motoren. In eerdere video's heb ik al getoond hoe het werkt en hoe je het bouwt.
Zie ook: L298N Motordriver & Arduino Interface, Hoe Het Werkt, Codes, Schema's
Deze keer gebruiken we onze nieuwe Arduino RC-ontvanger voor de besturing. Voor het aansturen van de DC-motoren gebruiken we de L298N motordriver en voor de voeding 3 Li-ion accu's die ongeveer 12V leveren.

Je kunt de benodigde componenten voor dit voorbeeld via de onderstaande links verkrijgen:
- L298N Driver
- 12V High Torque DC Motor
- DC Motor met Plastic Tire Wheel
- Breadboard en Jump Wires
De verbindingen zijn heel simpel: de 12V van de accu's gaan naar de 12V-pin op onze ontvanger, en de zes besturingspinnen van de driver gaan naar de 6 kanalen. We moeten hier opmerken dat om de snelheid van de motoren te kunnen regelen, we een PWM-signaal moeten geven aan de Enable A en Enable B pinnen van de driver. Op onze ontvanger kunnen kanalen 2, 3, 6 en 9 PWM-signalen uitvoeren, dus ik verbond de Enable-pinnen van de driver met kanalen 2 en 6 in dit geval.
Laten we eens kijken naar de Arduino-code.
/* Arduino RC Receiver - Car Example by Dejan, www.HowToMechatronics.com Library: TMRh20/RF24, https://github.com/tmrh20/RF24/ */
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define enA 9 // Arduino pin D9 - CH6 op PCB - PWM output
#define in1 8 // D8 - CH5
#define in2 7 // D7 - CH4
#define in3 6 // D6 - CH3
#define in4 4 // D4 - CH1
#define enB 5 // D5 - CH2 - PWM output
RF24 radio(3, 2); // nRF24L01 (CE, CSN)
const byte address[6] = "00001";
unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;
// Max size of this struct is 32 bytes
struct Data_Package {
byte j1PotX;
byte j1PotY;
byte j1Button;
byte j2PotX;
byte j2PotY;
byte j2Button;
byte pot1;
byte pot2;
byte tSwitch1;
byte tSwitch2;
byte button1;
byte button2;
byte button3;
byte button4;
};
Data_Package data; // Create a variable with the above structure
int steering, throttle;
int motorSpeedA = 0;
int motorSpeedB = 0;
void setup() {
pinMode(enA, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
// Serial.begin(9600);
radio.begin();
radio.openReadingPipe(0, address);
radio.setAutoAck(false);
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_LOW);
radio.startListening(); // Set the module as receiver
resetData();
}
void loop() {
// Check whether we keep receiving data, or we have a connection between the two modules
currentTime = millis();
if ( currentTime - lastReceiveTime > 1000 ) {
// If current time is more then 1 second since we have received the last data, that means we have lost connection
resetData(); // If connection is lost, reset the data. It prevents unwanted behavior, for example if a drone has a throttle up, if we lose connection it can keep flying away if we dont reset the function
}
// Check whether there is data to be received
if (radio.available()) {
radio.read(&data, sizeof(Data_Package)); // Read the whole data and store it into the 'data' structure
lastReceiveTime = millis(); // At this moment we have received the data
}
// Parse the data from the Joystick 1 to the throttle and steering variables
throttle = data.j1PotY;
steering = data.j1PotX;
// Throttle used for forward and backward control
// Joystick values: 0 to 255; down = 0; middle = 127; up = 255
if (throttle < 110) {
// Set Motor A backward
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
// Set Motor B backward
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
// Convert the declining throttle readings for going backward from 110 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
motorSpeedA = map(throttle, 110, 0, 0, 255);
motorSpeedB = map(throttle, 110, 0, 0, 255);
} else if (throttle > 140) {
// Set Motor A forward
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
// Set Motor B forward
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
// Convert the increasing throttle readings for going forward from 140 to 255 into 0 to 255 value for the PWM signal for increasing the motor speed
motorSpeedA = map(throttle, 140, 255, 0, 255);
motorSpeedB = map(throttle, 140, 255, 0, 255);
}
// If joystick stays in middle the motors are not moving
else {
motorSpeedA = 0;
motorSpeedB = 0;
}
// Steering used for left and right control
if (steering < 110) {
// Convert the declining steering readings from 140 to 255 into increasing 0 to 255 value
int xMapped = map(steering, 110, 0, 0, 255);
// Move to left - decrease left motor speed, increase right motor speed
motorSpeedA = motorSpeedA - xMapped;
motorSpeedB = motorSpeedB + xMapped;
// Confine the range from 0 to 255
if (motorSpeedA < 0) {
motorSpeedA = 0;
}
if (motorSpeedB > 255) {
motorSpeedB = 255;
}
}
if (steering > 140) {
// Convert the increasing steering readings from 110 to 0 into 0 to 255 value
int xMapped = map(steering, 140, 255, 0, 255);
// Move right - decrease right motor speed, increase left motor speed
motorSpeedA = motorSpeedA + xMapped;
motorSpeedB = motorSpeedB - xMapped;
// Confine the range from 0 to 255
if (motorSpeedA > 255) {
motorSpeedA = 255;
}
if (motorSpeedB < 0) {
motorSpeedB = 0;
}
}
// Prevent buzzing at low speeds (Adjust according to your motors. My motors couldn't start moving if PWM value was below value of 70)
if (motorSpeedA < 70) {
motorSpeedA = 0;
}
if (motorSpeedB < 70) {
motorSpeedB = 0;
}
analogWrite(enA, motorSpeedA); // Send PWM signal to motor A
analogWrite(enB, motorSpeedB); // Send PWM signal to motor B
}
void resetData() {
// Reset the values when there is no radio connection - Set initial default values
data.j1PotX = 127;
data.j1PotY = 127;
data.j2PotX = 127;
data.j2PotY = 127;
data.j1Button = 1;
data.j2Button = 1;
data.pot1 = 1;
data.pot2 = 1;
data.tSwitch1 = 1;
data.tSwitch2 = 1;
data.button1 = 1;
data.button2 = 1;
data.button3 = 1;
data.button4 = 1;
}Code language: Arduino (arduino)
Beschrijving: Eerst moeten we de SPI- en RF24-bibliotheek includen, enkele pinnen definiëren, het radio-object en de datastructuur waarin we de binnenkomende data van de zender opslaan. In de setup-sectie definiëren we de pin-uitgangen en starten we de radiocommunicatie. Voor meer details over de werking en wat elke regel doet, kun je mijn gedetailleerde NRF24L01-tutorial raadplegen.
In de loop-sectie controleren we constant of we data ontvangen en zo ja, lezen we die binnenkomende data. Als we even kijken naar de zendercode, zien we welke data hij verstuurt. Hij leest de data van al zijn bedieningselementen (joysticks, potentiometers, knoppen) en stuurt die als één pakket naar de ontvanger.
Zodra we die data gelezen hebben, kunnen we er mee doen wat we willen. In dit geval gebruiken we de Y-as-waarde van Joystick 1 voor de gaspedal (throttle) en de X-as-waarde voor de sturing. Ik zet deze data in aparte throttle- en steering-variabelen. De waarden van de joysticks lopen van 0 tot 255. Als we de joystick omlaag duwen, zetten we de bestuurpinnen van de driver zo dat de auto achteruit rijdt, en gebruiken we de throttle-waarde voor de snelheid. Hetzelfde principe geldt voor vooruit, links en rechts. Ik heb al een gedetailleerde tutorial over hoe deze auto werkt, dus raadpleeg die voor beter begrip. Aan de onderkant van de code zien we de resetData()-functie, die alle waarden terugzet naar hun initiële standaardwaarden, zodat de auto stopt bij verlies van de radioverbinding.
Voorbeeld 2 – Arduino RC-ontvanger: Servo's en Brushless-motoren Besturen
Oké, nu gaan we verder met het tweede voorbeeld: servo's en brushless-motoren besturen met deze Arduino RC-ontvanger.

Voor het besturen van brushless-motoren hebben we een ESC (Electronic Speed Controller) nodig. De Arduino communiceert met de ESC via slechts één pin. Om de ESC te besturen, stuurt de Arduino een specifiek PWM-signaal naar de ESC, waarmee de ESC de motoraansturing regelt. De ESC levert via dezelfde verbinding 5V door de Battery Eliminator Circuit (BEC), zodat we onze ontvanger er ook mee kunnen voeden.
Zie ook: Arduino Brushless Motor Control Tutorial | ESC | BLDC
Wat servo-motoren betreft, hebben ze hetzelfde type aansluitingen als de ESC en we kunnen ze gewoon op elke beschikbare kanaal aansluiten.

Je kunt de benodigde componenten voor dit voorbeeld via de onderstaande links verkrijgen:
- Brushless Motor
- ESC 30A
- Li-Po accu
- MG996R Servo Motor
De invoersignalen voor het besturen van zowel servo's als brushless-motoren via ESC's zijn bijna identiek. Ze gebruiken een specifiek 50Hz PWM-signaal dat eenvoudig gegenereerd kan worden met de Arduino Servo-bibliotheek.
Let op: Bij het gebruik van MG996R servo's met deze opstelling kunnen er problemen optreden in de schakeling en de Arduino Pro Mini verbranden. Ze kunnen een hogere stroom trekken wat spanningspieken op de 5V-rail kan veroorzaken. De Arduino Pro Mini zou tot 5.5V op de 5V-pin moeten kunnen aan, maar bij die pieken kan de Arduino verbranden. Ik had dit probleem tijdens het testen, en iemand in de reacties rapporteerde hetzelfde. Een oplossing zou het plaatsen van grotere decoupling-condensatoren bij de servo's kunnen zijn, maar ik ben niet zeker en heb het niet getest. Wees je van dit probleem bewust.
Aan de andere kant, in het voorbeeld gebruikte ik twee andere MG996R servo's die de Arduino niet verbrandden, waarschijnlijk omdat ze geen zulke hoge pieken veroorzaakten. Ik gebruikte dit voorbeeld ook met 4 kleinere S90 servo's en dat werkte zonder problemen.
Zie ook: Hoe Servo Motor Werkt & Hoe Servo's te Besturen met Arduino
/* DIY RC Receiver - Servos and Brushless motors control by Dejan, www.HowToMechatronics.com Library: TMRh20/RF24, https://github.com/tmrh20/RF24/ */
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Servo.h>
RF24 radio(3, 2); // nRF24L01 (CE, CSN)
const byte address[6] = "00001";
unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;
Servo esc; // create servo object to control the ESC
Servo servo1;
Servo servo2;
int escValue, servo1Value, servo2Value;
// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
byte j1PotX;
byte j1PotY;
byte j1Button;
byte j2PotX;
byte j2PotY;
byte j2Button;
byte pot1;
byte pot2;
byte tSwitch1;
byte tSwitch2;
byte button1;
byte button2;
byte button3;
byte button4;
};
Data_Package data; // Create a variable with the above structure
void setup() {
Serial.begin(9600);
radio.begin();
radio.openReadingPipe(0, address);
radio.setAutoAck(false);
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_LOW);
radio.startListening(); // Set the module as receiver
resetData();
esc.attach(10); // Arduino digital pin D10 - CH9 on PCB board
servo1.attach(4); // D4 - CH1
servo2.attach(5); // D5 - CH2
}
void loop() {
// Check whether we keep receiving data, or we have a connection between the two modules
currentTime = millis();
if ( currentTime - lastReceiveTime > 1000 ) {
// If current time is more then 1 second since we have received the last data, that means we have lost connection
resetData(); // If connection is lost, reset the data. It prevents unwanted behavior, for example if a drone has a throttle up, if we lose connection it can keep flying away if we dont reset the function
}
// Check whether there is data to be received
if (radio.available()) {
radio.read(&data, sizeof(Data_Package)); // Read the whole data and store it into the 'data' structure
lastReceiveTime = millis(); // At this moment we have received the data
}
// Controlling servos
servo1Value = map(data.j2PotX, 0, 255, 0, 180); // Map the receiving value form 0 to 255 to 0 to 180(degrees), values used for controlling servos
servo2Value = map(data.j2PotY, 0, 255, 0, 180);
servo1.write(servo1Value);
servo2.write(servo2Value);
// Controlling brushless motor with ESC
escValue = map(data.j1PotY, 127, 255, 1000, 2000); // Map the receiving value form 127 to 255 to 1000 to 2000, values used for controlling ESCs
esc.writeMicroseconds(escValue); // Send the PWM control signal to the ESC
}
void resetData() {
// Reset the values when there is no radio connection - Set initial default values
data.j1PotX = 127;
data.j1PotY = 127;
data.j2PotX = 127;
data.j2PotY = 127;
data.j1Button = 1;
data.j2Button = 1;
data.pot1 = 1;
data.pot2 = 1;
data.tSwitch1 = 1;
data.tSwitch2 = 1;
data.button1 = 1;
data.button2 = 1;
data.button3 = 1;
data.button4 = 1;
}Code language: Arduino (arduino)
Na ontvangst van de data van de zender converteren we de waarden van 0-255 naar 0-180 graden voor de servo's met de write()-functie. Op vergelijkbare wijze converteren we de data voor de ESC naar waarden van 1000-2000. In dit voorbeeld besturen we de ESC vanaf het middenpunt van Joystick 1 (waarde 127) tot de bovenste positie (255), dus we mappen 127-255 naar 1000-2000. Met de writeMicroseconds()-functie van de Servo-bibliotheek sturen we het PWM-signaal naar de ESC en kunnen we de snelheid van de brushless-motor van minimum tot maximum regelen.
Zie ook: Arduino RC-vliegtuig | 100% DIY
Zo kunnen we RC-vliegtuigen, auto's, boten, enz. besturen, aangezien ze meestal dit type motoren, servo's en brushless-motoren gebruiken.
Voorbeeld 3 – RC-auto Model Besturing
De RC-auto werd geleverd met een eigen controller die de voorwielen links/rechts kon sturen en de auto vooruit/achteruit kon laten rijden.

Omdat het een goedkope RC-auto is, zijn de bedieningen digitaal: ofwel aan, ofwel uit, naar maximale positie links/rechts en maximale snelondanks dat, demonteerde ik de auto om te zien wat erin zit en hoe ik de Arduino RC-ontvanger kan implementeren voor de besturing.

Na het blootleggen van de elektronica zag ik dat de twee motoren gewone DC-motoren zijn die op 5V werken. Zelfs de voorste motor die de beperkte stuurbewegingen regelt, is een gewone DC-motor met continue rotatie.
Dus, we weten al hoe we DC-motoren besturen, dus het vervangen van deze printplaat door onze DIY Arduino-ontvanger is vrij eenvoudig. Naast onze ontvanger hebben we alleen een motordriver nodig die twee motoren tegelijk kan aansturen. Er zijn genoeg opties, zoals de L298N-driver die we in het eerste voorbeeld gebruikten.

Die is echter te groot voor deze toepassing, dus ik koos voor de MX1508 motordriver. Dit is een simpele dual DC-motordriver met H-brug en PWM-besturing. Hij heeft 4 besturingsingangspinnen, 4 motorpinnen en 2 voedingspinnen.

Ik desoldeerde de motorverbindingen van de RC-auto printplaat en soldeerde ze aan de driver. Aan de achterkant soldeerde ik de voedingspinnen en wat overblijft is het verbinden van deze driver met de ontvanger. De voeding voor deze RC-auto komt van een 4.8V Ni-Cd accu onderin de auto.

Met draadbrugjes verbond ik deze pinnen met de VCC-pin van de Arduino, en ook de 4 besturingsingangspinnen van de driver met 4 digitale kanalen. Zoals gezegd, ondersteunt deze driver PWM-besturing, dus voor motor B (de achtermotor) gebruikte ik de PWM-kanalen 2 en 3.

Je kunt de benodigde componenten voor dit voorbeeld via de onderstaande links verkrijgen:
- MGRC RC Auto
- MX1508 DC Motordriver
- Breadboard en Jump Wires
De code voor deze RC-auto is erg podob aan het eerste voorbeeld.
/* Arduino RC Receiver - RC Model control by Dejan , www.HowToMechatronics.com Library: TMRh20/RF24, https://github.com/tmrh20/RF24/ */
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#define in3 5 // D5 - CH2 - PWM output
#define in4 6 // D6 - CH3 - PWM output
#define in1 7 // D7 - CH4
#define in2 8 // D8 - CH5
RF24 radio(3, 2); // nRF24L01 (CE, CSN)
const byte address[6] = "00001";
unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;
// Max size of this struct is 32 bytes
struct Data_Package {
byte j1PotX;
byte j1PotY;
byte j1Button;
byte j2PotX;
byte j2PotY;
byte j2Button;
byte pot1;
byte pot2;
byte tSwitch1;
byte tSwitch2;
byte button1;
byte button2;
byte button3;
byte button4;
};
Data_Package data; // Create a variable with the above structure
int steering, throttle;
int motorSpeedA = 0;
int motorSpeedB = 0;
void setup() {
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
Serial.begin(9600);
radio.begin();
radio.openReadingPipe(0, address);
radio.setAutoAck(false);
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_LOW);
radio.startListening(); // Set the module as receiver
resetData();
}
void loop() {
// Check whether we keep receiving data, or we have a connection between the two modules
currentTime = millis();
if ( currentTime - lastReceiveTime > 1000 ) {
// If current time is more then 1 second since we have received the last data, that means we have lost connection
resetData(); // If connection is lost, reset the data. It prevents unwanted behavior, for example if a drone has a throttle up, if we lose connection it can keep flying away if we dont reset the function
}
// Check whether there is data to be received
if (radio.available()) {
radio.read(&data, sizeof(Data_Package)); // Read the whole data and store it into the 'data' structure
lastReceiveTime = millis(); // At this moment we have received the data
}
// Parse the data from the Joystick 1 to the steering and throttle variables
steering = data.j2PotX;
throttle = data.j1PotY;
// Throttle used for forward and backward control
if (throttle < 110) {
// Convert the declining throttle readings for going backward from 110 to 0 into 0 to 255 value for the PWM signal for increasing the motor speed
motorSpeedB = map(throttle, 110, 0, 0, 255);
// Set Motor B backward
analogWrite(in3, motorSpeedB);
digitalWrite(in4, LOW);
} else if (throttle > 140) {
// Convert the increasing throttle readings for going forward from 140 to 255 into 0 to 255 value for the PWM signal for increasing the motor speed
motorSpeedB = map(throttle, 140, 255, 0, 255);
// Set Motor B forward
digitalWrite(in3, LOW);
analogWrite(in4, motorSpeedB);
}
// If joystick stays in middle the motors are not moving
else {
digitalWrite(in3, HIGH);
digitalWrite(in4, HIGH);
}
// steering used for left and right control
if (steering < 110) {
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
}
if (steering > 140) {
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
}
// If joystick stays in middle the motors are not moving
else {
digitalWrite(in1, HIGH);
digitalWrite(in2, HIGH);
}
}
void resetData() {
// Reset the values when there is no radio connection - Set initial default values
data.j1PotX = 127;
data.j1PotY = 127;
data.j2PotX = 127;
data.j2PotY = 127;
data.j1Button = 1;
data.j2Button = 1;
data.pot1 = 1;
data.pot2 = 1;
data.tSwitch1 = 1;
data.tSwitch2 = 1;
data.button1 = 1;
data.button2 = 1;
data.button3 = 1;
data.button4 = 1;
}Code language: Arduino (arduino)
We gebruiken de data van de joysticks om de gaspedal en sturing van de RC-auto te besturen. Voor achteruit rijden gebruiken we analogWrite() om een PWM-signaal naar de driver te sturen op Input3, terwijl we Input4 LOW houden. Voor vooruit rijden doen we het omgekeerde. Als de joystick in het midden blijft, geven we de opdracht aan de driver om de motoren te remmen of te stoppen. Hetzelfde principe geldt voor de stuurmotor, hoewel we hier geen analogWrite() hoeven te gebruiken omdat we de snelheid van deze motor niet hoeven te regelen.
Na het uploaden van deze sketch naar de Arduino, moest ik de RC-auto weer in elkaar zetten. Ik plaatste de kleine driver in de interne behuizing en bevestigde de rest van de onderdelen met schroeven. Ik verbond de ontvanger weer met de driver en plaatste hem onder de buitenste behuizing van de auto, waar genoeg ruimte was voor de ontvanger.

Dus niet alleen hebben we deze RC-auto aangepast om te worden bestuurd met onze DIY RC-zender, maar we hebben hem ook verbeterd door PWM-besturing toe te voegen, zodat we nu ook de snelheid van de auto kunnen regelen. Mocht het RC-model dat je wilt aanpassen servo's en brushless-motoren hebben in plaats van DC-motoren, dan kun je de methode uit het tweede voorbeeld volgen.
Ik hoop dat je van deze tutorial hebt genoten en iets nieuws hebt geleerd. Stel gerust vragen in de reacties hieronder en vergeet niet mijn verzameling Arduino-projecten te bekijken.
Productieproces
- DIY thuisbrouw temperatuurcontrole: Monitoren & regelen met Arduino
- Precieze thermocouple-metingen en logging voor lab- en wetenschappelijke experimenten
- Bouw Boeiende LCD Animaties & Games met Arduino UNO
- Een slimme voltmeter bouwen met Arduino en smartphone – Eenvoudig DIY-project
- Bouw een DIY Voltmeter met Arduino en Nokia 5110 Display – Stap-voor-Stap Handleiding
- Python 3 naar Arduino UNO: Eenvoudige Commando Besturing en LED Demo
- Bouw een compacte FM-radio met Arduino Nano en RDA5807M
- Hoe CAD-modellen Succes Drijven in Metaalbewerkingsprojecten
- Arduino MKR1000 Pinout: IoT Bord Handleiding
- CNC-frezenmachine vs. CNC Lasersnijder: Wat Is Best Voor Uw DIY Projecten
- Twister Snelheidsdraaibanken: Geavanceerde Polijsten & Ontgraten met 50% Meer Vermogen & Regeneratieve Controle