Salve a tutti, premettendo che sono nuovo all'interno del forum e spero di non fare errori, volevo porvi un mio problema su quanto riguarda un progetto con Arduino Lylipad.
Sono alla realizzazione di una “gesture control car”, ovvero tramite vari movimenti della mano comandare una macchinina elettrica. Per mezzo di un guanto ,su cui risiederà un accelerometro, verranno inviate le varie accelerazioni registrate ad una scheda Arduino Lilypad e a sua volta mediante un modulo bluetooth hc-05 si invierà il comando alla macchinina, gestita da un arduino uno.
Il mio problema risiede sulla comunicazione bluetooth, non capisco perché il modulo bluetooth posto sull'Arduino Lilypad non invia i caratteri che serviranno a far muovere la macchina.
Metto in allegato i codici qui sotto, garzie.
master.ino :
#include <SoftwareSerial.h>
#include <math.h>
#define BT_TX_PIN 1
#define BT_RX_PIN 0
SoftwareSerial bt = SoftwareSerial(BT_RX_PIN, BT_TX_PIN);
const int x_out = A0; /* connect x_out of module to A0 of lilypad */
const int y_out = A1 ; /* connect y_out of module to A1 of lilypad */
void setup() {
Serial.begin(9600);
bt.begin(38400);
pinMode(BT_RX_PIN, INPUT);
pinMode(BT_TX_PIN, OUTPUT);
pinMode(x_out, INPUT);
pinMode(y_out, INPUT);
}
void loop() {
int x_adc_value, x_g_value;
int y_adc_value, y_g_value;
x_adc_value = analogRead(x_out);
y_adc_value = analogRead(y_out);
x_g_value = ( ( ( (double)(x_adc_value * 5)/1024) - 1.65 ) / 0.330 ); // Acceleration in x-direction in g units
y_g_value = ( ( ( (double)(y_adc_value * 5)/1024) - 1.65 ) / 0.330 ); // Acceleration in y-direction in g units
if((x_g_value ==3) and (y_g_value ==1))
bt.println('F');
if((x_g_value ==3) and (y_g_value ==3))
bt.println('B');
if((x_g_value ==4) and (y_g_value ==2 ))
bt.println('R');
if((x_g_value ==2) and (y_g_value ==2))
bt.println('L');
if((x_g_value ==3) and (y_g_value ==2))
bt.println('S');
}
Benvenuto. Essendo il tuo primo post, nel rispetto del regolamento, ti chiediamo cortesemente 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 su citato REGOLAMENTO... Grazie.
Qui una serie di link utili, non inerenti al tuo problema:
ti do un consiglio. prima di addentrarti nella comunicazione testa la portata dei moduli. io con 2 hc-05 perdo il segnale a 3 metri senza ostacoli. sono pensati per essere accoppiati ad un cellulare o qualcosa che abbia comunque più portata di loro. in alternativa passa agli hc-12.
Ah capisco, il problema è che io prima di verificare il tutto con l'arduino lilypad avevo fatto un test con un altro arduino (arduino uno) e la comunicazione tra i due dispositivi avveniva con successo, riuscendo così ad inviare il segnale e a far muovere la macchina. Premettendo che ho controllato che i collegamenti fossero corretti, invertendo la coppia tx-rx, non capisco perchè non funzioni. Sbaglio qualcosa con il codice ?
Se usi una seriale software (emulata) perchè usare i pin della seriale fisica ? E magari hai puse usb collegato ? #define BT_TX_PIN 1 #define BT_RX_PIN 0
SoftwareSerial bt = SoftwareSerial(BT_RX_PIN, BT_TX_PIN);
ciao grazie per la risposta, in pratica io collego il modulo hc-05 all' Arduino lilypad 328 main board tramite i connettori ftdi della scheda è corretta come cosa ?
#include <SoftwareSerial.h>
#define TX_BT 10 // collegato fisicamente al tx del modulo bluetooth e al pin 10 del LilyPad
#define RX_BT 11 //collegato fisicamente al rx del modulo bluetooth e al pin 11 del LilyPad
SoftwareSerial myHC(RX_BT, TX_BT); //questo definisce myHC
/*quando prendi dimistichezza puoi direttamente definire il modulo con
* i pin utilizzati, ovvero:
* oltre alla prima riga che include la libreria SoftwareSerial che emula
* le seriali su pin a tuo piacimento poi inserisci direttamente
* SoftwareSerial myHC(10, 11);
*/
void setup() {
myHC.begin(9600); //inizializza la seriale del modulo per la ricezione/invio dei dati
}
void loop() {
/*qui ci metti tutto quello che vuoi
char mioNme[] = "ANGELO";
myHC.write(mioNome); //invia tramite bluetooth l'array mioNome
delay(2000); //attendi due secondi
*/
}
Ciao miky_police grazie per la tua disponibilità, ora vorrei solo assicurarmi di una cosa, ma se io collego il tx-rx del modulo bluetooth ai connettori tx-rx ftdi è corretto o no ? grazie ancora
FTDI? e dov'è sul LilyPad l'FTDI? ci sono i pin per poter collegare un ftdi ma non il chip. Se intendi quelli allora la risposta è SI. Ma nascono una serie di "problematiche".
Devi inizializzare la Seriale di arduino per poter comunicare con il modulo, facendo anche a meno del SoftwareSerial, ovvero aggiungere solo questo di seguito nel setup:
void setup() {
Serial.begin(9600); // rx e tx collegati incrociati con il modulo bt
}
Le ragioni fondamentali che induce la maggior parte di noi ad usare il modo da me prima postato (con l'utilizzo SoftwareSerial) sono 2:
se inizializzi il modulo sulla seriale fisica dell'atmega devi scablare il modulo bt per collegare l'ftdi tutte le volte per poter caricare uno sketch;
non puoi usare il monitor seriale mentre stai provando il tuo sketch perchè hai il modulo collegato e non l'ftdi, e se per caso ti viene la felice idea di sdoppiare gli rx e tx per poterli usare contemporanemente, beh, ti risparmio la fatica, al 99% avrai problemi di comunicazione.
Poi un'altra cosa... Ho dato un'occhiata al tuo codice e anche se fai i collegamenti bene e configuri correttamente i moduli la vedo difficile che riesci a spedire qualcosa...
Fai dei calcoli matematici per capire la posizione della mano inserendo le letture in variabili di tipo double quindi come se stai usando i float (numeri con la virgola anzichè int che sono numeri senza virgola quindi interi).
Prendendo in esame questo pezzo di codice:
if((x_g_value ==3) and (y_g_value ==1))
bt.println('F');
Ben capisci che se x_g_value è uguale a 2.9999 sei fregato perché non spedirà un bel niente... Quindi arrivi anche a comprendere che devi creare dei range di valori validi che determinano la posizione del sensore e quindi della mano che si tramutano in movimento.
Sarebbe opportuno dire piuttosto:
Si Miky_police sei stato chiarissimo e disponibile, ti ringrazio molto. Si effettivamente ogni volta devo scablare il modulo bt per collegare l'ftdi per poter caricare uno sketch e si non posso neanche visualizzare il monitor seriale, ma non vorrei fare altre saldature sul Lilypad perciò ho optato per questa soluzione, quindi da quello che ho capito funziona come ragionamento anche se non è la miglior cosa da fare.
ti lascio la foto del guanto se gli vuoi dare un'occhiata
Se usi la seriale dell'atmega devi collegare fisicamente l'rx del LilyPad al tx del bt e viceversa il tx del Lilypad all rx del bt. Poi essendo gia circuitati sul LilyPad sulla seriale dell'atmega non devi dichiarare niente lato software. devi solo inizializzare la seriale nel setup ovvero
voi setup() {
Serial.begin(9600); //oppure al baud che preferisci
}
chiaro?
EDIT: guarda i pinout del LilyPad è chiarissimo che da sinistra verso destra hai RX del LilyPad che collegherai al tx del bt e a seguire il tx che collegherai al rx del bt.
Scusami miky_police, ma avrei un 'altro piccolo problema, ho seguito i tuoi consigli ed ho collegato il bt a due pin fisici, però adesso sussiste un altro tipo di problema.
Inizialmente quando ho collegato il bt e ho provato a trasmettere un carattere alla macchina, sembrava che quest'ultima non ricevesse nulla. Allora ho provato a vedere cosa effettivamente la macchina ricevesse dal bt e ho scoperto che riceveva dei caratteri strani, che non hanno nulla a che fare con il carattere inviato dal atmega. Come posso risolvere tutto ciò ?
COM4 arduino uno:
?
?
?
d
?
?
?
una cosa del genere
Grazie e scusa di nuovo, ma è la prima volta che utilizzo una software serial.
Ti lascio anche il codice sia dell'atmega sia quello della macchina (arduino uno)
master.ino
#include <SoftwareSerial.h>
#include <math.h>
#define BT_TX_PIN 10
#define BT_RX_PIN 11
SoftwareSerial bt(BT_RX_PIN,BT_TX_PIN);
const int x_out = A0; /* connect x_out of module to A1 of lilypad */
const int y_out = A1 ; /* connect y_out of module to A2 of lilypad */
void setup() {
Serial.begin(9600);
bt.begin(9600);
pinMode(x_out, INPUT);
pinMode(y_out, INPUT);
}
char ultimo = 'X';
char dato = 'F';
void loop() {
/*int x_adc_value, x_g_value;
int y_adc_value, y_g_value;
x_adc_value = analogRead(x_out);
y_adc_value = analogRead(y_out);
x_g_value = ( ( ( (double)(x_adc_value * 5)/1024) - 1.65 ) / 0.330 ); // Acceleration in x-direction in g units
y_g_value = ( ( ( (double)(y_adc_value * 5)/1024) - 1.65 ) / 0.330 ); // Acceleration in y-direction in g units */
if(dato != ultimo)
{
ultimo = dato;
Serial.print(dato);
delay (2000);
}
}
slave.ino
#include <AFMotor.h>
#include <SoftwareSerial.h>
//definisco pin RX e TX da Arduino verso modulo BT
#define BT_TX_PIN A0
#define BT_RX_PIN A1
// DC motor on M1-M2
AF_DCMotor motor1(1);
AF_DCMotor motor2(2);
//istanzio oggetto SoftwareSerial (il nostro futuro bluetooth)
SoftwareSerial bt = SoftwareSerial(BT_RX_PIN, BT_TX_PIN);
void setup() {
//definisco modalità pin
pinMode(BT_RX_PIN, INPUT);
pinMode(BT_TX_PIN, OUTPUT);
//inizializzo comunicazione Seriale
Serial.begin(9600);
//inizializzo comunicazione Bluetooth
bt.begin(9600);
// turn on motor #1-2
motor1.setSpeed(200);
motor1.run(RELEASE);
motor2.setSpeed(200);
motor2.run(RELEASE);
}
int i;
void loop() {
//se ci sono dati sul buffer della Serial
while (Serial.available() > 0)
{
//mandali al modulo bluetooth
bt.print(Serial.read());
}
//se ci sono dati sul buffer SoftwareSerial (il buffer del bluetooth)
while (bt.available() > 0) {
//mostrali nel Serial Monitor
char movimento = bt.read();
Serial.println(movimento);
switch(movimento)
{
case'F':
motor1.run(FORWARD);
motor2.run(FORWARD);
motor1.setSpeed(173);
motor2.setSpeed(200);
break;
case'B':
motor1.run(FORWARD);
motor2.run(FORWARD);
motor1.setSpeed(173);
motor2.setSpeed(200);
break;
case'R':
motor1.run(RELEASE);
motor2.run(FORWARD);
for (i=0; i<90; i++) {
motor1.setSpeed(i);
motor2.setSpeed(i);
}
break;
case'L':
motor1.run(FORWARD);
motor2.run(RELEASE);
for (i=0; i<90; i++) {
motor1.setSpeed(i);
motor2.setSpeed(i);
}
break;
case'S':
motor1.run(RELEASE);
motor2.run(RELEASE);
motor1.setSpeed(0);
motor2.setSpeed(0);
delay(3);
break;
default:
motor1.run(FORWARD);
motor2.run(FORWARD);
break;
}
}
}
(nello slave.ino avevo messo un caso di default, per assicurami che effettivamente avveniva una comunicazione tra le due parti)
if(dato != ultimo)
{
ultimo = dato;
Serial.print(dato); // questo serve per vederlo su monitor seriale
bt.print(dato); //questo lo manda al bluetooth che lo trasmetterà al destinatario se associato
delay (2000);
}
attento che guardando al volo anche lo slave c'è qualcosa che non mi torna un come fai ricevere i dati.