Pilotare servo motori a distanza con Arduino

In questo articolo ti mostro come è possibile pilotare a distanza dei servo motori con Arduino.
DigitSpace
Prima di passare al contenuto è doveroso ringraziare il sito DigitSpace per avermi fornito parte del materiale di questo progetto.
Qualche settimana fa avevo scritto un articolo su come è possibile pilotare a distanza dei motori passo passo con Arduino e i moduli radio nRF24L01.
L’esigenza era di Marco, che vorrebbe realizzare una torretta da soft-air gestita appunto da remoto.
In fase di realizzazione si è voluto cambiare tipo di motori, passando dagli stepper motor a dei servo a rotazione continua.
Da qui la necessità di modificare il codice ed i collegamenti e visto che la cosa potrebbe tornare utile a qualcuno mi è sembrato giusto condividerla.
Codice Trasmittente
/*
Pilotare servo motori a distanza con Arduino
Autore : Andrea Lombardo
Web : http://www.lombardoandrea.com
Post : https://wp.me/p27dYH-Q5
*/
//Inclusione delle librerie
#include <Bounce2.h>
#include <nRF24L01.h>
#include <RF24_config.h>
#include <RF24.h>
//Costanti e PIN
//Pin pulsante incorporato nel modulo joystick che abilita o disabilita il controllo dei motori
const unsigned int pinSwEnable = 2;
//Pin pulsante esterno che controllerà il servo del grilletto
const unsigned int pinSwTrigger = 3;
//Chip Select e Chip Enable della Radio
const unsigned int radioCE = 4;
const unsigned int radioCS = 5;
//Pin per il LED di stato
const unsigned int ledEnable = 7;
//Pin analogici per il joystick
const unsigned int jX = A0;
const unsigned int jY = A1;
//Definizione indirizzo sul quale stabilire la comunicazione radio
const byte indirizzo[5] = {0, 0, 0, 0, 0};
/*
Variabili utilizzate per definire min e max speed ed eseguire il mapping sui valori del joystick.
*/
const unsigned int maxSpeedForward = 180;
const unsigned int stopSpeed = 90;
const unsigned int maxSpeedBackward = 0;
/*
La lettura dei potenziometri non è mai affidabile al 100%.
Questo valore aiuta a determinare il punto da considerare come "Sta al centro" nei movimenti.
*/
const unsigned int treshold = 8;
//Millisecondi per il debonuce del bottone
const unsigned long debounceDelay = 10;
//Definisco struttura pacchetto da inviare
struct Packet {
unsigned int speedX;
unsigned int speedY;
boolean enable;
boolean trigger;
};
//Variabili di appoggio
long valX, mapX, valY, mapY, tresholdUp, tresholdDown;
//Creo istanze dei bottoni
Bounce btnEnable = Bounce(); //istanzia un bottone dalla libreria Bounce
Bounce btnTrigger = Bounce(); //istanzia un bottone dalla libreria Bounce
//Creo istanza della "radio" passandogli il numero dei pin collegati a CE e CSN del modulo
RF24 radio(radioCE, radioCS);
//Creo ed inizializzo istanza pacchetto da inviare
Packet pkt = {
stopSpeed,//speedX
stopSpeed,//speedY
false,//enable
false //trigger
};
void setup() {
Serial.begin(115200);
//Definizione delle modalità dei pin
//LED Enable
pinMode(ledEnable, OUTPUT);
//Tasto enable
pinMode(pinSwEnable, INPUT_PULLUP);
//Tasto grilletto
pinMode(pinSwTrigger, INPUT_PULLUP);
//Inizializzo la radio
radio.begin();
/*
Setto la potenza della radio, nel mio caso a LOW
La radio può lavorare a diverse potenze: RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH e RF24_PA_MAX
Che corrispondono a: -18dBm, -12dBm,-6dBM, e 0dBm
*/
radio.setPALevel(RF24_PA_LOW);
//Apro un canale di comunicazione sull'indirizzo specificato (sarà lo stesso per il ricevitore)
radio.openWritingPipe(indirizzo);
//Richiamando questo metodo sto impostando la radio come trasmettitore
radio.stopListening();
//Configuro istanze dei pulsanti
btnEnable.attach(pinSwEnable);
btnEnable.interval(debounceDelay);
btnTrigger.attach(pinSwTrigger);
btnTrigger.interval(debounceDelay);
//Calcolo range valori entro i quali considerare la posizione del joystick come "Sta al centro"
tresholdDown = (maxSpeedForward / 2) - treshold;
tresholdUp = (maxSpeedForward / 2) + treshold;
//Invio stato di enable al LED
digitalWrite(ledEnable, pkt.enable);
}
void loop() {
//gestisci stato dei pulsanti
handlePulsanti();
//gestisci valori dei potenziometri
handleJoystick();
//Invia dati tramite la radio
if (pkt.enable) {
radio.write(&pkt, sizeof(pkt));
}
}
/*
Si occupa di leggere i valori del joystick, mapparli ed aggiornare le variabili nel Packet
*/
void handleJoystick() {
//esegui lettura analogica dei valori provenienti dai potenziometri del joystick
valX = analogRead(jX);
valY = analogRead(jY);
//mappa i valori letti in funzione della velocità minima e massima
mapX = map(valX, 0, 1023, 0, maxSpeedForward);
mapY = map(valY, 0, 1023, 0, maxSpeedForward);
if (mapX <= tresholdDown) {
//x va indietro
pkt.speedX = map(mapX, maxSpeedBackward, tresholdDown, maxSpeedBackward, tresholdDown);
} else if (mapX >= tresholdUp) {
//x va avanti
pkt.speedX = map(mapX, tresholdUp, maxSpeedForward, tresholdUp, maxSpeedForward);
} else {
//x sta fermo
pkt.speedX = stopSpeed;
}
if (mapY <= tresholdDown) {
//y va indietro
pkt.speedY = map(mapY, maxSpeedBackward, tresholdDown, maxSpeedBackward, tresholdDown);
} else if (mapY >= tresholdUp) {
//y va avanti
pkt.speedY = map(mapY, tresholdUp, maxSpeedForward, tresholdUp, maxSpeedForward);
} else {
//y sta fermo
pkt.speedY = stopSpeed;
}
}
/*
Si occupa di leggere lo stato dei pulsanti ed aggiornare le variabili nel Packet
*/
void handlePulsanti() {
btnEnable.update();
if (btnEnable.fell()) {
pkt.enable = !pkt.enable;
}
//Mostra lo stato di enable con il LED
digitalWrite(ledEnable, pkt.enable);
//Aggiorna stato di pressione del "grilletto"
btnTrigger.update();
pkt.trigger = !btnTrigger.read();
}
Codice Ricevente
/*
Pilotare servo motori a distanza con Arduino
Autore : Andrea Lombardo
Web : http://www.lombardoandrea.com
Post : https://wp.me/p27dYH-Q5
*/
//Inclusione delle librerie
#include <Servo.h>
#include <nRF24L01.h>
#include <RF24_config.h>
#include <RF24.h>
//Costanti e PIN
//Chip Select e Chip Enable della Radio
const unsigned int radioCS = 2;
const unsigned int radioCE = 3;
//Pin servo X
const unsigned int pinServoX = 5;
//Pin servo Y
const unsigned int pinServoY = 6;
//Pin servo Trigger
const unsigned int pinServoTg = 9;
//definizione indirizzo sul quale stabilire la comunicazione radio
const byte indirizzo[5] = {0, 0, 0, 0, 0};
//definisco struttura pacchetto che riceverò
struct Packet {
unsigned int speedX;
unsigned int speedY;
boolean enable;
boolean trigger;
};
const unsigned int stopSpeed = 90;
//Creo istanza della "radio" passandogli il numero dei pin collegati a CE e CSN del modulo
RF24 radio(radioCE, radioCS);
//Creo istanze servo
Servo servoX;
Servo servoY;
Servo servoTg;
//Creo ed inizializzo istanza pacchetto che userò per i dati ricevuti
Packet pkt = {
stopSpeed,
stopSpeed,
false,
false
};
void setup() {
//Definizione delle modalità dei pin
Serial.begin(115200);
//Associa pin ai servo
servoX.attach(pinServoX);
servoY.attach(pinServoY);
servoTg.attach(pinServoTg);
//Inizializzo la radio
radio.begin();
/*
Setto la potenza della radio, nel mio caso a LOW
La radio può lavorare a diverse potenze: RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH e RF24_PA_MAX
Che corrispondono a: -18dBm, -12dBm,-6dBM, e 0dBm
*/
radio.setPALevel(RF24_PA_LOW);
//Apro un canale in lettura sull'indirizzo specificato
radio.openReadingPipe(1, indirizzo);
//Metto la radio in ascolto
radio.startListening();
servoX.write(stopSpeed);
servoY.write(stopSpeed);
servoTg.write(0);
}
void loop() {
//Se ci sono dati in ricezione sulla radio
if (radio.available()) {
//Leggo i dati sul buffer e li scrivo nell'istanza Packet precedentemente creata
radio.read(&pkt, sizeof(pkt));
} else {
//Se non ricevo dati per un qualsiasi motivo, azzero tutto nell'istanza Packet.
pkt = {
stopSpeed,
stopSpeed,
false,
false
};
}
//Se nel pkt il valore del trigger è 1 ruoto di 90° il servo motor
if (pkt.trigger) {
servoTg.write(90);
} else {
//Altrimenti lo rimetto a 0
servoTg.write(0);
}
//Interpreta i valori ricevuti ed aziona i motori di conseguenza
pilotaServiMovimento(pkt);
Serial.print("enable: ");
Serial.print(pkt.enable);
Serial.print(" speedX: ");
Serial.print(pkt.speedX);
Serial.print(" speedY: ");
Serial.print(pkt.speedY);
Serial.print(" trigger: ");
Serial.println(pkt.trigger);
delay(15);
}
/*
Interpreta i valori contenuti nella struttura Packet
ed aziona i servo di conseguenza
*/
void pilotaServiMovimento(Packet pkt) {
if (pkt.enable) {
servoX.write(pkt.speedX);
servoY.write(pkt.speedY);
} else {
servoX.write(stopSpeed);
servoY.write(stopSpeed);
}
}
Schemi
Anche in questa occasione ho utilizzato dei moduli radio nRF24L01 per la comunicazione a distanza. La parte trasmittente è rimasta più o meno uguale a quella della precedente versione, mentre la ricevente adesso gestisce in totale tre servo motori. Due per rotazione ed elevazione (quelli a rotazione continua) ed uno per azionare il grilletto della replica (0° – 180°).
Per comodità ti riporto il pinout del modulo nRF24L01:
| GND | Ground |
| Vcc | 1.9V – 3.3V |
| CE | Chip Enable |
| CSN | Chip Select |
| SCK | Serial Clock |
| MOSI | Master Output Slave Input |
| MISO | Master Input Slave Output |
| IRQ | Interrupt (generalmente non ci serve) |
Circuito Trasmittente
Come ti ho già anticipato lo schema del trasmettitore è pressoché identico a quello della precedente versione, cambiano solo i pin CS e CE della radio che prima erano disposti diversamente visto che utilizzavo un Arduino Nano.

Circuito Ricevente
Dato che i servo a disposizione esprimono le migliori prestazioni ad un voltaggio diverso da quello che potrebbe fornire Arduino, ho inserito nel circuito un trasformatore DC DC (detto anche Buck Converter) per portare l’alimentazione da 12V (che sarebbero troppi per i servo) a 7V cosi da alimentare sia loro sia l’Arduino.
Nello specifico i servo che ho utilizzato sono due MG996R e un SG90 offerti dal sito DigitSpace che ringrazio.

Sono fiducioso nella riuscita del progetto e non vedo l’ora di vedere foto e video del lavoro ultimato da Marco.
Per adesso accontentiamoci di una demo da banco:
A fine pagina trovi il link per scaricare il pacchetto con codici e schemi di collegamento. Come sempre ti ricordo che acquistando prodotti Amazon passando attraverso i link del mio sito, io percepisco una piccola commissione (parliamo di centesimi) in buoni regalo. Questi buoni sommati alle eventuali donazioni PayPal, servono a mantenere attivo il sito web e ad acquistare nuovi componenti.
Arduino UNO R4 WiFi [ABX00087] - Scheda di sviluppo con microcontrollore ARM Cortex-M4 e WiFi integrato, ideale per progetti IoT, automazione e applicazioni connesse con Arduino IDE.
AZDelivery Scheda Microcontrollore con Cavo USB e con eBook
13,99 €ELEGOO UNO R3 Advanced Starter Kit per progetti per Principianti con Kit di apprendimento Italiano Compatibile con i progetti IDE di Arduino
ELEGOO UNO R3 Project Basic Starter Kit per Principianti, Incluso Kit di Apprendimento Tutorial in Italiano, Compatibile con Arduino IDE
29,99 €Arduino UNO R4 Minima [ABX00080] - Scheda di sviluppo con microcontrollore ARM Cortex-M4, ideale per progetti IoT, automazione e applicazioni con IDE Arduino.
Auto Amazon Links: Nessun prodotto trovato.
Auto Amazon Links: Nessun prodotto trovato.
Auto Amazon Links: Nessun prodotto trovato.
Auto Amazon Links: Nessun prodotto trovato.


![Arduino UNO R4 WiFi [ABX00087] - Scheda di sviluppo con microcontrollore ARM Cortex-M4 e WiFi integrato, ideale per progetti IoT, automazione e applicazioni connesse con Arduino IDE. #1](https://m.media-amazon.com/images/I/51z3unD0rSL._SL120_.jpg)
![Arduino UNO R4 WiFi [ABX00087] - Scheda di sviluppo con microcontrollore ARM Cortex-M4 e WiFi integrato, ideale per progetti IoT, automazione e applicazioni connesse con Arduino IDE. #2](https://m.media-amazon.com/images/I/51qwMwhIEpL._SL120_.jpg)
![Arduino UNO R4 WiFi [ABX00087] - Scheda di sviluppo con microcontrollore ARM Cortex-M4 e WiFi integrato, ideale per progetti IoT, automazione e applicazioni connesse con Arduino IDE. #3](https://m.media-amazon.com/images/I/41xRusra-PL._SL120_.jpg)
![Arduino UNO R4 WiFi [ABX00087] - Scheda di sviluppo con microcontrollore ARM Cortex-M4 e WiFi integrato, ideale per progetti IoT, automazione e applicazioni connesse con Arduino IDE. #4](https://m.media-amazon.com/images/I/51Pj4AYoI2L._SL120_.jpg)
![Arduino UNO R4 WiFi [ABX00087] - Scheda di sviluppo con microcontrollore ARM Cortex-M4 e WiFi integrato, ideale per progetti IoT, automazione e applicazioni connesse con Arduino IDE. #5](https://m.media-amazon.com/images/I/51aGD+zFqLL._SL120_.jpg)
![Arduino UNO R4 WiFi [ABX00087] - Scheda di sviluppo con microcontrollore ARM Cortex-M4 e WiFi integrato, ideale per progetti IoT, automazione e applicazioni connesse con Arduino IDE. #6](https://m.media-amazon.com/images/I/51qB0r6PqYL._SL120_.jpg)
![Arduino UNO R4 WiFi [ABX00087] - Scheda di sviluppo con microcontrollore ARM Cortex-M4 e WiFi integrato, ideale per progetti IoT, automazione e applicazioni connesse con Arduino IDE. #7](https://m.media-amazon.com/images/I/518XcmBXXAL._SL120_.jpg)
![Arduino UNO R4 WiFi [ABX00087] - Scheda di sviluppo con microcontrollore ARM Cortex-M4 e WiFi integrato, ideale per progetti IoT, automazione e applicazioni connesse con Arduino IDE. #8](https://m.media-amazon.com/images/I/41mGAFfpn9L._SL120_.jpg)

















![Arduino UNO R4 Minima [ABX00080] - Scheda di sviluppo con microcontrollore ARM Cortex-M4, ideale per progetti IoT, automazione e applicazioni con IDE Arduino. #1](https://m.media-amazon.com/images/I/51L0AYnxlBL._SL120_.jpg)
![Arduino UNO R4 Minima [ABX00080] - Scheda di sviluppo con microcontrollore ARM Cortex-M4, ideale per progetti IoT, automazione e applicazioni con IDE Arduino. #2](https://m.media-amazon.com/images/I/5111WEC6vgL._SL120_.jpg)
![Arduino UNO R4 Minima [ABX00080] - Scheda di sviluppo con microcontrollore ARM Cortex-M4, ideale per progetti IoT, automazione e applicazioni con IDE Arduino. #3](https://m.media-amazon.com/images/I/41752hu+9BL._SL120_.jpg)
![Arduino UNO R4 Minima [ABX00080] - Scheda di sviluppo con microcontrollore ARM Cortex-M4, ideale per progetti IoT, automazione e applicazioni con IDE Arduino. #4](https://m.media-amazon.com/images/I/51gDXfwE4qL._SL120_.jpg)
![Arduino UNO R4 Minima [ABX00080] - Scheda di sviluppo con microcontrollore ARM Cortex-M4, ideale per progetti IoT, automazione e applicazioni con IDE Arduino. #5](https://m.media-amazon.com/images/I/519n0CHiF5L._SL120_.jpg)
![Arduino UNO R4 Minima [ABX00080] - Scheda di sviluppo con microcontrollore ARM Cortex-M4, ideale per progetti IoT, automazione e applicazioni con IDE Arduino. #6](https://m.media-amazon.com/images/I/515PpgJcSfL._SL120_.jpg)
![Arduino UNO R4 Minima [ABX00080] - Scheda di sviluppo con microcontrollore ARM Cortex-M4, ideale per progetti IoT, automazione e applicazioni con IDE Arduino. #7](https://m.media-amazon.com/images/I/519E0KPfiHL._SL120_.jpg)
RSS - Articoli
Commentati Recentemente