Salve a tutti sono nuovo sia del forum sia del mondo di Arduino, comunque sono in grado di eseguire alcuni programmi basilari.
Ho un quesito da porvi... Vorrei costruire un robot radiocomandato ma non so come scrivere il programma per "interfacciare" Arduino alla ricevente (PPM).
Sono in possesso di Arduino UNO, microricevente e scheda motore della DFRobot (quella che da 2A x canale) questa --> 2x2A DC Motor Shield For Arduino - DFRobot
Non sono a richiedervi l'intero codice, anche perchè sarebbe troppo semplice, ma semplicemente lo spunto per partire in particolare la parte di lettura del segnale.
Scusate.... ma ho trovato un codice scritto da lesto per utilizzare gli interrupt
//se pin2 è stato modificato
if (_changed&MASKPCINT0){
//se pin2 ora è in stato alto
if (_newbit&MASKPCINT0) {
//INTERRUPT STATO ALTO SUL PIN 2
}else{
//INTERRUPT STATO BASSO SUL PIN 2
}
}
volevo sapere se all'interno di questo ciclo if/else devo inserire il codice che Arduino deve eseguire nel caso in cui si attivasse questo pin. :%
So che può sembrare una domanda banale ma non so dove battere la testa, ormai è una sfida e la devo vincere.
Scusa, ma a quanto pare non riesco a spiegarmi, io devo collegare un radiocomando RC su arduino x comandare dei motori a 6 Vdc. Vorrei una mano per poter leggere tali valori.
Grazie e scusa ancora se non riesco a spiegarmi bene ma ho appena iniziato a lavorare con Arduino
Vediamo se ho capito io....
devi prendere il segnale PPM di una Rx e mandarlo ad arduino che a sua volta dovra decodificarlo e comandare per verso di ricazione e velocità dei motori tramite un adeguato pont H ...
Giusto ?
Se non ho capito male, devi fare la cosa più banale del mondo, cioè comandare il robot tramite un radiocomando.
In questo caso, ti passo questo codice che avevo scritto un po' di tempo fa, praticamente legge i valori dalla ricevente che ovviamente cambiano in base ai movimenti degli stick del radiocomando e poi li scrive in un display seriale.
Basta che ti tiri fuori le poche righe di codice che ti servono.
Ciao.
#include <Servo.h>
#include <SoftwareSerial.h>
#define throttle 2
#define gear 4
#define elev 5
#define rudder 6
#define aile 7
#define rxPin 8
#define txPin 9
double throttleVal = 0; // Variabile motore sinistro
double gearVal = 0; // Variabile motore sinistro
double elevVal = 0; // Variabile motore sinistro
double rudderVal = 0; // Variabile motore sinistro
double aileVal = 0; // Variabile motore sinistro
// Servo left;
// Servo right;
SoftwareSerial SerialDisplay = SoftwareSerial(rxPin, txPin);
void setup()
{
pinMode(throttle, INPUT);
pinMode(gear, INPUT);
pinMode(elev, INPUT);
pinMode(rudder, INPUT);
pinMode(aile, INPUT);
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
// Serial.begin(9600);
SerialDisplay.begin(9600);
// SerialDisplay.print(char(21);
SerialDisplay.print(char(14));
SerialDisplay.print(char(12));
SerialDisplay.print(char(12));
SerialDisplay.print(char(20));
SerialDisplay.print(char(255));
SerialDisplay.print(char(19));
SerialDisplay.print(char(64));
// Serial.print("^N");
// Serial.print("^T");
// Serial.print(0xFF);
// right.attach(9);
// left.attach(10);
}
void loop()
{
for (int i = 0;i < 6; i++)
{
throttleVal = throttleVal + pulseIn(throttle, HIGH); // lettura ricevente canale motore sx
gearVal = gearVal + pulseIn(gear, HIGH); //lettura ricevente motore dx
elevVal = elevVal + pulseIn(elev, HIGH); //lettura ricevente motore dx
rudderVal = rudderVal + pulseIn(rudder, HIGH); //lettura ricevente motore dx
aileVal = aileVal + pulseIn(aile, HIGH); //lettura ricevente motore dx
if (i == 5)
{
throttleVal = throttleVal / 5;
gearVal = gearVal / 5;
elevVal = elevVal / 5;
rudderVal = rudderVal / 5;
aileVal = aileVal / 5;
// Serial.print("Elev -> ");
// Serial.print(elevVal);
// Serial.print(" throttle -> ");
// Serial.print(throttleVal);
// Serial.print(" Gear -> ");
// Serial.print(gearVal);
// Serial.print(" Aile -> ");
// Serial.print(aileVal);
// Serial.print(" Rudder -> ");
// Serial.println(rudderVal);
/* SerialDisplay.print("Elev -> ");
delay(2000);
SerialDisplay.print(int(elevVal));
SerialDisplay.print(" throttle -> ");
SerialDisplay.print(int(throttleVal));
SerialDisplay.print(" Gear -> ");
SerialDisplay.print(int(gearVal));
SerialDisplay.print(" Aile -> ");
SerialDisplay.print(int(aileVal));
SerialDisplay.print(" Rudder -> ");
SerialDisplay.print(int(rudderVal));*/
break; //faccio una media dei valori perchè sono leggermente oscillanti
}
}
// Prima riga
SerialDisplay.print(char(17));
SerialDisplay.print(char(0));
SerialDisplay.print(char(0));
SerialDisplay.print("TH=");
SerialDisplay.print(int(throttleVal));
SerialDisplay.print(" EL=");
SerialDisplay.print(int(elevVal));
// Seconda riga
SerialDisplay.print(char(17));
SerialDisplay.print(char(1));
SerialDisplay.print(char(0));
// SerialDisplay.print(int(gearVal));
SerialDisplay.print("AL=");
SerialDisplay.print(int(aileVal));
SerialDisplay.print(" RU=");
SerialDisplay.print(int(rudderVal));
SerialDisplay.print(char(17));
SerialDisplay.print(char(0));
SerialDisplay.print(char(15));
if (gearVal > 2000) SerialDisplay.print("G");
else SerialDisplay.print("g");
// SerialDisplay.print(int(gearVal));
// SerialDisplay.print("Ciao ");
// delay(2000);
/*
// *** comando servo sinistro
// stick in avanti
if (leftVal > 2200) left.write(180); // gira in senso orario
//stick in indietro
if (leftVal < 1800) left.write(0); // gira in senso antiorario
// stick al centro
if (leftVal > 1800 && leftVal < 2500) left.write(90); //stai fermo
// *** comando servo destro
//stick avanti
if (rightVal > 2200) right.write(0); // gira in senso orario
//stick indietro
if (rightVal < 1800) right.write(180); // gira in senso antiorario
//stick al centro
if (rightVal > 1800 && rightVal < 2500) right.write(90); //fermo
*/
}
anche il codice di stefanoxjx è corretto, e molto più semplice da leggere. Ovvio ha certi svantaggi, ma se il loop è abbastanza veloce non dovresti avere problemi. noterai che il PPM è un'oda quadra, dove la durata del segnale alto rappresenta il valore inviato.
il codice che uso io non è altro che una pulseIn che lavora completamente ad interrupt, non bloccando il tuo codice nel caso la ricevente sia staccata, il tuo loop si blocchi a fare altro... sta a ste scegliere la semplicità o la complessità in base al tuo progetto.
visto che non sono un esperto di elettronica, chiedo gentilmente una delucidazione su questo tutorial riguardante proprio la decodifica di una scheda ricevente RC:
guardando nel programma viene utilizzata l'istruzione "digitalread", esempio: si manda un segnale con il telecomando (es. leva in posizione FORWARD) e si legge sulla scheda Arduino il corrispondente piedino della scheda ricevente in stato HIGH.
i segnali della scheda ricevente vengono letti da Arduino in maniera digitale o sbaglio?
nel programma di Stefano invece viene utilizzata invece l'istruzione "pulsein" e si fa una media dei valori PWM.
Mi potete chiarire quando bisogna utilizzare "pulsein" e quando "digitalread" per decodificare i segnali sulla scheda ricevente?
lui usa una digital read perchè la stopria del pulseIn la fa attraverso la scheda collegata. La storia della media la puoi evitare, però sarebbe utile per ammortizzare eventuali interferenze
@elvis94: Ciao, essendo il tuo primo post, ti chiederei di presentartiQUI (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con attenzione il REGOLAMENTO ...
... poi, il forum Italiano è suddiviso in 4 sezioni : Generale, Hardware, Software e Megatopics; quest'ultima (Megatopics) è riservata e NON devi aprici nuovi topics, ma puoi partecipare alle discussioni.
A secondo della domanda, come hai fatto ora, apri un nuovo topics (uno ed uno solo per argomento, il cross-posting è proibito).