Progetto Carroattrezzi

Buonasera a tutti, mi sono messo a costruire un modellino di carroattrezzi per due motivi.. il primo è perchè mi piace costruire le cose, il modellismo e l'elettronica e il secondo è in ricordo di mio padre che faceva soccorso stradale e mi portava da bambino quando poteva su quel carroattrezzi.. di conseguenza il mio progetto voglio che sia il più fedele a quello vero che guidava lui.. sia come forma che come funzionalità. Detto questo volevo costruire un telecomando per poi gestire tutti i movimenti che mi serviranno e al momento essendo comunque il primo prototipo ho pensato di utilizzare un collegamento bluetooth tra telecomando e camion. In attesa che mi consegnino la seconda Mega2560 in settimana sto facendo delle prove con una Mega2560 e un Uno. L'accoppiamento tra i moduli bluetooth HC-05 l'ho fatto e due led riesco a farli accendere anche se con una latenza pazzesca di circa 2 secondi, cosa che risolverò in qualche modo più avanti. Il problema è che mi sono arenato con il comando di un servomotore che verrà collegato a una delle due schede e un joystick per comandarlo al momento collegato alla Uno. Vi anticipo che non ho conoscenze a sufficienza per creare uno sketch da solo quindi sto prendendo spunti qua e la ma proprio non so cosa non funziona.. qualcuno gentilmente saprebbe aiutarmi? Ringrazio in anticipo, Matteo

Ciao! Dovresti dire quale problema riscontri e quale comportamento vorresti avesse il programma.
Poi per vedere se il programma non può fare quello che vorresti, dovremmo appunto vedere il programma :slight_smile:
quindi posta il codice nel tag code. :slight_smile:

Eccomi qua… Beh avrei bisogno che dal radiocomando tramite un joystick collegato ad un primo arduino mega tramite bluetooth possa muovere un servomotore collegato ad un secondo arduino… che mi servirà per gestire lo sterzo del camion. Avrò bisogno di un secondo servo da comandare ma copierò e incollerò le stringhe del primo, per la ralla della gru, che dovrà funzionare allo stesso modo. Per quanto riguarda i led ho il problema della latenza di cui vi parlavo… dal momento in cui premo il tasto sul radiocomando al momento in cui si accende il led collegato alla scheda del camion passano 2 secondi circa… e avrei bisogno che fosse istantaneo… e in più che alcuni pulsanti mi comandino alla prima pressione l’on e alla seconda l’off… so che vi chiedo un aiuto enorme ma non so dove sbattere la testa… grazie in anticipo…

#include <Servo.h>

/*
 * How to configure and pair two HC-05 Bluetooth Modules
 * by Dejan Nedelkovski, www.HowToMechatronics.com
 * 
 *                 == MASTER CODE ==
 */
#define led1Pin 11
#define led2Pin 8
int state = 0;
int potValue = 0;

Servo myServoX;         // Oggetto ServoX
Servo myServoY;         // Oggetto ServoY
int servoX = 5;         // Pin Servo X
int servoY = 10;        // Pin Servo Y
int posX = 90;          // Posizione iniziale del ServoX
int posY = 90;          // Posizione iniziale del ServoY
int joyX = A0;          // Ingresso analogico del Joystick X
int joyY = A1;          // Ingresso analogico del Joystick Y
int joyValueX = 0;      // Valore letto X
int joyValueY = 0;      // Valore letto Y
int outValueX = 0;      // Valore mappato sull'out ServoX
int outValueY = 0;      // Valore mappato sull'out ServoY



void setup() {
  pinMode(led1Pin, OUTPUT);
  digitalWrite(led1Pin, LOW);
  pinMode(led2Pin, OUTPUT);
  digitalWrite(led2Pin, LOW);
  Serial1.begin(38400); // Default communication rate of the Bluetooth module

  myServoX.attach(servoX);  // ServoX collegato al Pin 9
  myServoY.attach(servoY);  // ServoY collegato al Pin 10
  myServoX.write(posX);     // Inizializzazione posizione del ServoX a 90°
  myServoY.write(posY);     // Inizializzazione posizione del ServoY a 90°
  delay(50);
  
}
void loop() {
 if(Serial1.available() > 0){ // Checks whether data is comming from the serial port
    state = Serial1.read(); // Reads the data from the serial port
 }
 // Controlling the LED
 if (state == '1') {
  digitalWrite(led1Pin, HIGH); // LED ON
  state = 0;
 }
 else if (state == '0') {
  digitalWrite(led1Pin, LOW); // LED ON
  state = 0;
 }
 if (state == '3') {
  digitalWrite(led2Pin, HIGH); // LED ON
  state = 0;
 }
 else if (state == '2') {
  digitalWrite(led2Pin, LOW); // LED ON
  state = 0;
 }
  myServoX.write(posX);
  myServoY.write(posY);
  delay(30);
}
/*
 * How to configure and pair two HC-05 Bluetooth Modules
 * by Dejan Nedelkovski, www.HowToMechatronics.com
 * 
 *                 == SLAVE CODE ==
 */
 
#include <Servo.h>
#define button1 8
#define button2 7
Servo myServo;
int state = 20;
int button1State = 0;
int button2State = 0;

Servo myServoX;         // Oggetto ServoX
Servo myServoY;         // Oggetto ServoY
int servoX = 9;         // Pin Servo X
int servoY = 10;        // Pin Servo Y
int posX = 90;          // Posizione iniziale del ServoX
int posY = 90;          // Posizione iniziale del ServoY
int joyX = A0;          // Ingresso analogico del Joystick X
int joyY = A1;          // Ingresso analogico del Joystick Y
int joyValueX = 0;      // Valore letto X
int joyValueY = 0;      // Valore letto Y
int outValueX = 0;      // Valore mappato sull'out ServoX
int outValueY = 0;      // Valore mappato sull'out ServoY

void setup() {
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  myServo.attach(9);
  Serial.begin(38400); // Default communication rate of the Bluetooth module

  myServoX.attach(servoX);  // ServoX collegato al Pin 9
  myServoY.attach(servoY);  // ServoY collegato al Pin 10
  myServoX.write(posX);     // Inizializzazione posizione del ServoX a 90°
  myServoY.write(posY);     // Inizializzazione posizione del ServoY a 90°
  delay(50);
  
}
void loop() {
 if(Serial.available() > 0){ // Checks whether data is comming from the serial port
    state = Serial.read(); // Reads the data from the serial port
 }

 
 // Reading the button1
 button1State = digitalRead(button1);
 if (button1State == HIGH) {
   Serial.write('1');// Sends '1' to the master to turn on LED
   delay(1000);
 }
 else {
   Serial.write('0');
   delay(1200);  
 }  
  // Reading the button2
 button2State = digitalRead(button2);
 if (button2State == HIGH) {
   Serial.write('3');// Sends '3' to the master to turn on LED
   delay(1000);
 }
 else {
   Serial.write('2');
   delay(1200);  
 }  


 // Lettura analogica del potenziometro
  joyValueX = analogRead(joyX);
  joyValueY = analogRead(joyY);
  // Mappatura del range, il potenziometro
  // viene letto sul piedino A0 (valore da 0 a 1023)
  // e convertito tramite l'istruzione map
  // ad un valore compreso tra 0° e 180°
  // cioè gli angoli che il Servo può coprire
  posX = map(joyValueX, 0, 1023, 0, 180);
  posY = map(joyValueY, 0, 1023, 0, 180);
    myServoX.write(posX);
  myServoY.write(posY);
  delay(30);
 Serial.write(posX = map); // Sends potValue to servo motor
 delay(10);
}

Ecco gli sketch… come vi dicevo sto “rubando” parti di sketch da altri progetti per tentare di adattarli al mio… perchè al momento di programmazione capisco ancora poco se si tratta di creare da zero… aggiungo che il joystick che controlla lo sterzo dovrà anche nell’altro asse controllarmi dei motori dc avanti indietro e velocità tramite L298N… sto chiedendo troppo vero? Un grazie enorme a chi potrà aiutarmi anche solo un pochino, Matteo

Un po confuso e da rivedere.
Se io ho un arduino con joystick , sarà il sistema di comando, quindi non dovrebbe essere questo arduino a far muovere i servo, perché per farlo deve essere collegato fisicamente ai servo.
Allora ho un arduino che legge il joystick, e trasmette al secondo arduino l'angolo, ma il programma si complica, devo trasmettere prima un carattere che indichi quale servo, e poi trasmettere l'angolo.

Mi spiace ma con colla e incolla codice pronto, non riuscirai mai a realizzare quello che vuoi.

Lo so.. purtroppo non avendo le basi faccio fatica a crearne uno da zero ma sto per iniziare a provarci.. quello che speravo era in un aiuto su come partire perchè nel linguaggio arduino non trovo alcune stringhe che ho visto in tanti sketch che ho guardato online.. perciò la cosa mi confonde un po. Ora provo a leggere altro per iniziare a farne uno da zero.
Matteo

Ho provato a scrivere questi codici… ma ovviamente non funziona…

int j1posx = A0;
int j1posy = A1;
int j1valuex = 512;
int j1valuey = 512;
int state = 0;
int posx = 90;
int posy = 90;




void setup() {
  Serial1.begin(34800);
  delay(50);
}

void loop() {
  if(Serial1.available() > 0) {
    state = Serial1.read();
  }
  j1valuex = analogRead(j1posx);
  j1valuey = analogRead(j1posy);
  posx = map(j1valuex, 0, 1023, 0, 180);
  posy = map(j1valuey, 0, 1023, 0, 180);
  Serial1.write(posx = map);
  Serial1.write(posy = map);
}
#include <Servo.h>

Servo myServox;
Servo myServoy;
int servox = 2;
int servoy = 3;
int posx = 90;
int posy = 90;
int state = 0;




void setup() {
  Serial.begin(38400);
  myServox.attach(servox);
  myServoy.attach(servoy);
  myServox.write(posx);
  myServoy.write(posy);
  delay(50);
}

void loop() {
  if(Serial.available() > 0) {
    state = Serial.read();
  }
  myServox.write(posx);
  myServoy.write(posy);
  delay(30);
}

A parte che oggi mi è arrivata la seconda scheda mega2560 ma mi da errore quando provo a caricarci sopra il codice e ancora devo capire perchè… usando una mega per il trasmettitore e la uno per il ricevitore niente non si muove niente :confused:
Dove sbaglio? :confused:

ciao.
quello che vuoi fare non è semplicissimo, soprattutto se sei agli inizi e non sei pratico col codice.
secondo me conviene fare un passo alla volta.
partiamo dal "master", ovvero lo sketch che legge i joystick e invia i dati
ho commentato il tuo codice per cercare di spiegare cosa fa. porta pazienza se per caso ho scritto cose troppo ovvie.

// MASTER

// pin a cui collego i joystick
int j1posx = A0;
int j1posy = A1;

// valore letto sul pin analogico
// in questo caso l'inizializzazione è inutile,
// questo valore non lo usi mai
int j1valuex = 512;
int j1valuey = 512;

// questa variabile non serve, 
// sotto vedi il perché
int state = 0;

// variabili per l'angolo del servo
// anche qui l'inizializzazione è inutile
int posx = 90;
int posy = 90;


void setup() {
  // inizializzi la seriale 1
  // presumo che il modulo BT sia collegato  questa seriale
  Serial1.begin(34800);
  delay(50);
}

void loop() {
  // in questo sketch tu devi trasmettere dei valori e non riceverli, 
  // quindi questo pezzo non serve
  if (Serial1.available() > 0) {
    state = Serial1.read();
  }

  // qui leggi i valori dei joystick
  // è meglio fare una lettura a vuoto sui pin analogici
  // quindi
  analogRead(j1posx);
  j1valuex = analogRead(j1posx);
  analogRead(j1posy);
  j1valuey = analogRead(j1posy);

  // qui converti il valore letto nel valore di un angolo
  posx = map(j1valuex, 0, 1023, 0, 180);
  posy = map(j1valuey, 0, 1023, 0, 180);

  // qui invii i valori sulla seriale
  // devi inviare la variabile... quello che hai scritto tra parentesi non ha senso
  // inoltre invece della write conviene usare la print
  //Serial1.write(posx = map);
  //Serial1.write(posy = map);
  Serial1.println(posx);
  Serial1.println(posy);
}

dall'altra parte cos'hai? la uno con collegato il modulo BT? come l'hai collegato?

Ciao, grazie mille per l'aiuto. Appena ritorno a casa dal lavoro nel tardo pomeriggio modifico il codice in base ai tuoi consigli. Devo solo capire come creare la variabile da inviare di cui mi hai parlato..
Si sia il mega che l'uno hanno un modulo bluetooth hc-05 master e slave che già si allineano.. entrambe le schede, alimentazione a parte, hanno TX>RX e RX>TX. La scheda Uno sarà poi sostituito da un'altra Mega, entrambi gli HC-05 saranno poi connessi alla seriale 1. Grazie ancora per i consigli.
Matteo

Le variabili per l'invio ci sono già... Le hai chiamate posx e posy.
Occhio che anche la parte di ricezione è da sistemare.

Presumo sia da sistemare perché al posto del serial.write mi hai consigliato il serial.printIn?

No, va sistemato più o meno dappertutto…

Se posso, con queste difficoltà difficilmente arriverai al progetto finito e funzionante.
Da quello che scrivi si vede chiaramente che stai sparando nel mucchio… ci può anche stare all’inizio, ma un minimo di sforzo lo devi fare.
Se non sei pratico col codice ti si può dare una mano, ma se non hai proprio chiaro cosa fare e come farlo diventa molto dura.
Prima di pensare a scrivere uno sketch, cerca di capire come funziona a livello pratico quello che vuoi fare.
Butta giù uno schemino riassuntivo con le varie operazioni da fare, scritte anche in italiano.
Quando hai chiaro il cosa e il come puoi pensare al codice.

Dopo la parte da maestrina… stasera il codice che ho messo io puoi anche fare a meno di provarlo perché sicuramente non funzionerà.
Ci sono molti aspetti ancora da vedere prima di arrivare a qualcosa di funzionante.

Io ti ringrazio tanto per il codice del trasmettitore che mi hai scritto ma ti chiedo scusa perchè devo contraddirti su due cose.. la prima è che io so benissimo di quello che mi serve, nel senso che so benissimo cosa fare a livello pratico di come dovrà funzionare il mio progetto e la seconda è di come dovrà funzionare.. ma purtroppo non a livello software come già ho scritto nei miei primi post.. è verissimo che sono alle prime armi nella programmazione di questo tipo ma sono comunque un tecnico che conosce altri tipi di programmazioni (ad esempio domotica e in parte KNX) e che impara in fretta ma purtroppo non ne ho le basi. Io del mio ce lo sto mettendo non per niente, anche se per voi può sembrare scontato, sono gia riuscito a creare modulo bluetooth master e modulo slave, a farli comunicare tra di loro anche se con una latenza come ho scritto nel primo post.. ma se mi spiegassi il codice del ricevitore come hai fatto per il trasmettitore e dal momento che ho capito quest'ultimo capire anche i prossimi passi che devo fare.. Ovviamente, da tecnico iscritto ad un forum simile a questo, non pretendo e non mi aspetto troppi aiuti, in quanto anche a me capitava con alcuni utenti di non aiutarli completamente perchè io ci ho perso tempo e fatica per imparare quello che so.
Matteo

Stavo rileggendo comunque il tuo codice.. ma ci sono dei valori che forse se non dichiaro prima potrebbe causarmi degli errori di compilazione? scusa ma, capendone già poco ma per quel poco che so mi sto confondendo.
Matteo

Ciao, ho fatto una prova, per esempio, senza queste definizioni che mi hai detto che non servivano:
int posx = 90;
int posy = 90;
int j1valuex = 512;
int j1valuey = 512;

a prescindere che i valori siano corretti o meno, la IDE non mi fa andare avanti.. sbaglio io, naturalmente qualcosa.. vorrei capire però che cosa, e capire se puoi darmi una mano a creare il codice del ricevitore per questa funzione.. per il resto riuscirò ad aggiustarmi, in un modo o nell'altro. Grazie
Matteo

Se devi trasmettere valori numerici inferiori a 255 compreso, è meglio usare write.
Se usi write trasmetti un byte un numero che non ha bisogno di essere convertito e lo puoi leggere con una sola read(), se usi println() trasmetti i caratteri che compongono il numero, esempio 180, trasmetti i caratteri '1' '8' '0'
più il newline, quindi 4 read(), salvarli in un array e convertirli in numero. ti complichi la vita di parecchio inutilmente.

Ripeto, visto che invii numeri sotto i 255, write ti semplifica la vita.

Facciamo qualche esempio con solo due servo. Se capisci il concetto puoi estendere il programma a tutti i servo che ti servono.
Ovviamente non posso provare il programma, potrebbero esserci errori di programmazione logici o di codice, che non fanno funzionare il programma. Ma la logica del programma, come dovrebbe funzionare sara valida.

/* Arduino con joystik trasmette dati */
 
int j1posx = A0;int j1posy = A1;
int j1valuex = 512;
int j1valuey = 512;
int state = 0;
int posx = 90;
int posy = 90;

void setup() {
  Serial1.begin(34800);
  delay(50);
}

void loop() {
  if(Serial1.available() > 0) {
    state = Serial1.read();
  }
  j1valuex = analogRead(j1posx);
  j1valuey = analogRead(j1posy);
  posx = map(j1valuex, 0, 1023, 0, 180);
  posy = map(j1valuey, 0, 1023, 0, 180);
    // Con write  trasmetto l'angolo sotto forma di numero o il codice ascii del carattere
  Serial1.write('x'); // Invio il carattere x il suo codice ascii, cosi il ricevente saprà che dovrà agire sul servo x
  Serial1.write(posx );
  Serial1.write('y'); // Invio il carattere y il suo codice ascii, cosi il ricevente sapra che dovrà agire sul servo y[color=#222222][/color]
  Serial1.write(posy );
}
/* Ricevente */
#include <Servo.h>

Servo myServox;
Servo myServoy;
int servox = 2;
int servoy = 3;
int posx = 90;
int posy = 90;
char servo;

void setup() {
  Serial.begin(38400);
  myServox.attach(servox);
  myServoy.attach(servoy);
  myServox.write(posx);
  myServoy.write(posy);
  delay(50);
}

void loop() {
  if(Serial.available() > 0) {
    sevo = Serial.read();
     if(servo=='x'){// ho letto il carattere x
         while(!Serial.available()>0);// Attendo che ci siano dati sulla seriale
         posx=Serial.read(); // leggo l'angolo del servo x
     }else if(servo=='y'){
          while(!Serial.available()>0);// Attendo che ci siano dati sulla seriale
          posy=Serial.read(); // leggo l'angolo del servo y
     }
  }
  myServox.write(posx);
  myServoy.write(posy);
  delay(30);
}

Su write / print quello che dice torn è ovviamente corretto.
Nella mia testa pensavo già ad un minimo di protocollo di comunicazione e per questo pensavo alla print.

Le variabili che dichiari all'inizio servono. Quello che puoi tralasciare è l'inizializzazione ad un valore che non usi mai.

Ciao ragazzi. Ho provato i codici suggeriti da torn24 ma come già da lui anticipato, non funziona. E io non capisco il motivo. Non lo capisco perché come già vi ho detto NON CONOSCO IL CODICE così approfonditamente. Per me leggendo quanto scritto da entrambi, potrebbe avere un senso e potrebbe funzionare, ma in realtà non è così. Forse non avete ben chiaro che per uno che non ha mai scritto un codice in vita sua e per lo più non conosce le possibili funzioni associabili e funzionabili per quello che cerco dj fare, non è semplice. E ve lo dice come vi ho già scritto un tecnico domotico. Quindi cj chiedo.. O mi scrivete il codice funzionante sia per tx che per rx così che posso leggerlo e capire quanto scritto oppure lasciate perdere e in qualche modo mi aggiusto, perché così mi confondete solo. E vi chiedo di essere espliciti, anche per quest'ultima cosa. Grazie

Matteo

>matt855br: ... purtroppo la risposta è nel punto 16.1 del REGOLAMENTO ... noi qui possiamo AIUTARE, ma chi chiede deve metterci un po' di impegno nello studiare (... e, al punto 16.1, sono indicate varie cose da cui partire) ... :confused:

Quindi, dedicaci un po' di tempo, cerca di scrivere tu il programma e poi chiedi per le parti che non funzionano ... :slight_smile:

Guglielmo

D'accordo va bene, nel week end ci proverò e nel caso posterò i miei codici chiedendo aiuto, chiedo scusa ma non sapevo. Nemmeno ci fosse una guida da cui iniziare.
Matteo