Radiocomando con Arduino

Radiocomando con Arduino

Introduzione

Qualora si voglia realizzare in autonomia un veicolo, velivolo o a qualsiasi altra macchina con Arduino può essere bello realizzarlo a controllo remoto con un proprio radiocomando.
Il vantaggio di realizzare un radiocomando con Arduino è principalmente quello di poterselo personalizzare.
Arduino per quanto semplice è anche molto personalizzabile e può essere stimolante progettare un radio comando specifico per le proprie applicazioni.

In questo caso verrà realizzato un radiocomando utile per più scopi

Cosa serve?

*Qui elencherò le componenti da utilizzare, a seconda di come andrete a personalizzare il vostro radiocomando togliere e aggiungerete parti.

Componenti

  • Arduino Nano 
  • 2 potenziometri
  • 2 joystick
  • Cavetti vari (sono più pratici quelli con pin maschio e/o femmina per applicazioni come le schede Arduino)
  • 4 tasti
  • Antenna NRF24L01 + PA +LNA
  • Interruttore
  • Batteria (facoltativo, il radiocomando potrebbe essere comandato anche via cavo con la corrente domestica con appositi alimentatori)

Strumenti

  • 1 cavetto per collegare la scheda Arduino al computer (in questo caso da USB-B a Mini USB-B)
  • Computer per programmare la scheda con Arduino IDE installato
  • Saldatrice per stagno (non indispensabile se si usano componenti con dei pin appositi)
  • Stampante 3D per il case (sostituibile ad esempio con del legno o del plexiglass, basta un po’ di inventiva, vedi sotto)

Design del radiocomando

Oltre che all’ergonomia per l’impugnatura bisogna pensare agli spazi occupati dalle componenti e dalla cavetteria. Il consiglio è quello di realizzarsi uno schema con i vari componenti così da rendersi conto dell’ingombro generale.

Ovviamente la disposizione delle componenti dipende dai vostri gusti.

Per mantenere le dimensioni compatte ho scelto un Arduino Nano. Per comodità personale ho rivolto il connettore mini USB-B verso sinistra, ma in generale sarebbe più pratico averlo prossimo alla superficie esterna.
L’antenna conviene sempre metterla quanto più esterna possibile, la batteria con l’interruttore di accensione dovranno essere di facile accesso.

Il radiocomando finito sarà pressappoco così:

Ovviamente nelle parti cave saranno presenti i joystick, l’interruttore, ecc…

Se si volesse usare più semplicemente del legno o del plexiglass basta sagomare due strati distanziati con in mezzo le componenti.

Programmazione radiocomando

Prima di tutto è necessario avere le librerie dei vari componenti, in questo caso è importante avere la libreria dell’antenna usata.

Clicca il bottone qui sotto per scaricare quella usata qui.

//Prima di tutto si devono inserire nello sketch le libreria che si
andranno ad usare

#include <SPI.h>

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>

#include <Wire.h>

//Si definiscono le variabili per i segnali digitali, nel nostro caso
i bottoni o eventuali interruttori

int b1 = 12;
int b2 = 10;
int b3 = 5;
int b4 = 6;

//Ora bisogna impostare i canali radio per l'antenna, si assegnano a D6 e D7
i pin CE e CSN dell'antenna (come da sketch) e si imposta il canale (in questo caso 01998)

RF24 radio (8, 9); 
const byte address[9] = "01998";

unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;


//Si crea una struttura di dati. Qui si è indicato con Pot i potenziometri,
con button i pulsanti e con j i joystick, ognuno con 2 potenziometri

struct Pacchetto_Dati {
  byte Pot1;
  byte Pot2;
  byte button1;
  byte button2;
  byte button3;
  byte button4;
  byte j1PotV;
  byte j2PotV;
  byte j1PotL;
  byte j2PotL;
  
};

Pacchetto_Dati data;

void setup() {
//Si inizializza il seriale

  Serial.begin(9600);

//I seguenti comandi attivano l'antenna in base alla libreria inserita

  radio.begin();
  radio.openWritingPipe(address);
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);

//Si inizializzano i pulsanti (e eventuali interruttori)

  pinMode(b1, INPUT_PULLUP);
  pinMode(b2, INPUT_PULLUP);
  pinMode(b3, INPUT_PULLUP);
  pinMode(b4, INPUT_PULLUP);

//Qui si impostano i valori iniziali ai vari potenziometri/pulsanti.
Quando il potenziometro sarà in posizione neutra avrà valore 127, i pulsanti
avranno valore 1 (si spiega al prossimo passaggio perché)

  data.j1PotV = 127;
  data.j2PotV = 127;
  data.j1PotL = 127;
  data.j1PotL = 127;
  data.Pot1 = 127;
  data.Pot2 = 127;
  data.button1 = 1;
  data.button2 = 1;
  data.button3 = 1;

  data.button4 = 1;

}

void loop() {

//I valori letti da Arduino per i potenziometri vanno da 0 a 1023,
ossia 1024 bit, l'antenna però non è in grado di supportare una struttura
superiore a 32 byte, ossia 256 bit. Per questo bisogna "rimappare" i
valori da 0 a 255.

 data.j1PotV =map(analogRead(A0), 0,1023, 0,255);
 data.j2PotV =map(analogRead(A2), 0,1023, 0,255);
 data.j1PotL =map(analogRead(A1), 0,1023, 0,255);
 data.j1PotL =map(analogRead(A3), 0,1023, 0,255);
 data.Pot1 =map(analogRead(A4), 0,1023, 0,255);
 data.Pot2 =map(analogRead(A5), 0,1023, 0,255);

//Si leggono i valori dei vari bottoni che normalmente sono a valore alto (=1)
mentre quando vengono premuti vengono letti a valore basso (=0)

 data.button1 = digitalRead(b1);
 data.button2 = digitalRead(b2);
 data.button3 = digitalRead(b3);
 data.button4 = digitalRead(b4);


}

Come fatto notare prima bisogna rispettare una dimensione massima per la struttura di dati di 32 byte supportati dall’antenna.

Chi comunica con il radiocomando?

Per ricevere questo segnale la cosa più semplice da fare è mettere sulla macchina una scheda Arduino con la stessa antenna. Questa prenderà il segnale, analizzerà la struttura dati, e in base ai comandi imposti al radiocomando potrà eseguire determinate azioni.

La prima parte del codice sarà abbastanza simile in quanto si andrà a inizializzare i vari input e l’antenna. La seconda metà invece dovrà prendere i dati e usarli. Successivamente questi dati verranno resettati e si ripartirà con i dati successivi.

Si riporta un esempio esemplificato. In futuro verrà riportato un esempio pratico.

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(10, 9);   // nRF24L01 (CE, CSN)
const byte address[6] = "01998";

//l'indirizzo dovrà essere lo stesso

unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;

struct Data_Package {
  byte j1PotV;
  byte j1PotL;
  byte j2PotV;
  byte j2PotL;
  byte Pot1;
  byte Pot2;
  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();
}

void loop() {
  // controlla la presenza di un emettitore
  //Nel nostro caso il radiocomando

  if (radio.available()) {
    radio.read(&data, sizeof(Data_Package));
// Legge i dati in "data"

    lastReceiveTime = millis();
// Ora si hanno effettivamente i dati
  }

  currentTime = millis();
  if ( currentTime - lastReceiveTime > 1000 ) { 
//Si esegue un controllo dei tempi di ricezione
// Se "currenttime" è più di 1 secondo dal segnale precedente
allora non si è più connessi

    resetData();
//Quindi si resettano i dati per evitare problemi

  }
  // Print the data in the Serial Monitor
  Serial.print("j1PotV: ");
  Serial.print(data.j1PotV);
  Serial.print("; j1PotL: ");
  Serial.print(data.j1PotL);
  Serial.print("; button1: ");
  Serial.print(data.button1);
  Serial.print("; j2PotV: ");
  Serial.println(data.j2PotL); 
}
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;
}

*Makers ITIS Forlì non si assumono alcuna responsabilità per danni a cose, persone o animali derivanti dall’utilizzo delle informazioni contenute in questa pagina. Tutto il materiale contenuto in questa pagina ha fini esclusivamente informativi.

Makers ITIS Forlì: https://www.makers-itis-forli.it