Domande bluetooth HC-05, e ponte H l293d

Ciao, parto subito:

mi è arrivato ieri il modulo bluetooth HC-05.

Ora riesco a comandare il mio primo grezzo mezzo terrestre, senza usare la seriale usb :D. Ho 1 domanda:

per comandare il mezzo, mi sono scritto un app che funziona in questo modo:

tengo premuto il pulsante, e invio una stringa via seriale ad Arduino, che può essere "W" "S" "A" "D", e in base a queste azionerà i motori per muoversi nella direzione desiderata;
al rilascio del pulsante, invierò la stringa "X", che fermerà tutti i motori. Ora il problema è, che se mente sto tenendo premuto "avanti", stacco manualmente il collegamento del piedino TX del modulo bluetooth, al rilascio del pulsante, il BT non riceverà la stringa "X" che serve a fermare i motori, e quindi si "bloccherà" sull ultimo comando inviato.

Ho provato a fare così: alla pressione del pulsante lato app, parte un timer che invia ogni tot millisecondi la stringa della direzione desiderata, e lato arduino, controllo quando !BT.available(), e nel caso appunto non lo è, quindi smettte di ricevere input, ferma i motori. Ma niente, non va, i motorini ricevono HIG e LOW in modo velocissimo che si sentono ticchettare tipo "trrrr".

Ora la domanda reale è: in che modo si puo fare il controllo di emergenza nel caso ci sia un guasto sul pin TX?

Potrei anche farlo manualmente, cioe che quando mi accordo che non risponde piu ai comandi mi disconnetto, ma non mi sembra una soluzione accettabile..

PONTE H:

per fare delle prove sto alimentando il ponte H che dà potenza i motorini con un trasformatore da modellismo, che in OUT ha: 0 -14 V DC 700mA. E ha la rotella per regolarne (la tensione o la corrente???)

I pin per il controllo dei motori tramite ponte H sono PWM perchè voglio regolarne la velocità.

La situazione è:

col traformatore al minimo della potenza (domanda di prima: tensione o corrente?), se setto la velocità dei motorini fino al 15%, vanno come devono, ma se aumento la potenza dei motorini (traformatore sempre al minimo), questi accellerano per 2 secondi, poi si fermano, poi riprendono.. se alzo la potenza (V o I?) del trasformatore, riesco a far girare i motorini senza problemi senza che si fermano, cioe tutto è rapportato. Perchè succede questo?

Ho ipotizzato che il circuito richiede piu corrente di quanta gli viene fornita, ma non saprei..

scusate per la lunghezza del post.

E sono un nabbo riguardo l'elettronica, quindi se qualcuno risponderà, fatelo con parole molto povere :cry: :cry: :cry: :grinning:

Grazie :slight_smile:

Leggiti le specifiche del L293D. http://www.ti.com/lit/ds/symlink/l293.pdf paragrafo 6.3.
Non puoi scendere con la tensione motori sotto la tensione di alimentazione della logica (i 5V).

Ciao Uwe

mattoide:
Ho provato a fare così: alla pressione del pulsante lato app, parte un timer che invia ogni tot millisecondi la stringa della direzione desiderata, e lato arduino, controllo quando !BT.available(), e nel caso appunto non lo è, quindi smettte di ricevere input, ferma i motori. Ma niente, non va, i motorini ricevono HIG e LOW in modo velocissimo che si sentono ticchettare tipo "trrrr".

non sei lontano dal risultato che cerchi, credo

io faccio l'ipotesi che la cadenza di trasmissione della app sia inferiore alla cadenza di ricezione di arduino
che non è facile da definire, posto che la app trasmetta ogni per fare un esempio 1 secondo
arduino riceve, decodifica ed esegue in per fare esempio mezzo secondo
dopo mezzo secondo quindi sta aspettando che la app trasmetta, ma la app non trasmetterà ancora per un po', arduino quindi spegne tutto

il problema è di facile soluzione, ma devi evitare alcune trappole che adesso ti indico

  1. non cercare di tenere sincrone trasmissione e ricezione, le velocità dipendono da troppe variabili, anche usare dei timer non risolve il problema, a loro volta i timer e/o i delay e/o i millis soffrono di tolleranze ampie

  2. non cercare di trasmettere a velocità maggiore di quanto arduino possa trattare, primo arduino è molto veloce, certamente più di quanto ci si aspetta quando si è ancora novizi, e secondo se per caso tu ci riuscissi riempiresti il buffer della seriale di arduino, che poi a buffer pieno prima di eseguire un comando passa un certo tempo

  3. per la stessa ragione non devi rallentare arduino, altrimenti, facendo ipotesi semplificativa che arduino sia rallentato ad accettare un comando ogni 0,1 secondi (sempre per fare esempio), ti troveresti che dopo poco arduino risponde con oltre sei secondi di ritardo ai comandi, non bella cosa ne convieni?

E io aggiungo
4) non serve, e all'inizio sarebbe solo un fardello in più, tentare di realizzare un protocollo con trasmissione full duplex
Un protocollo full duplex con ack e conferma di esecuzione sarebbe certamente una bella cosa, anzi ti consiglio di farlo, ma dopo
Per cominciare quello che vuoi fare lo ottieni anche con una trasmissione unidirezionale

Mi ricorda quando con papà e io portavamo la williams formula uno (il modellino) in campi aperti (posteggi) per farla correre, puntualmente l'interruttore del ricevitore si spegneva a causa di un pietruzza e la poveretta era già destinata a schiantarsi sul marciapiede, e noi corse per raggiungerla e riattivare l'interruttore e fare cessare il motore di girare alla massima velocità. Da tragico disasro si trasforma in risate isteriche perché dopo l'urto violento l'auto rimbalzava quanche metro indietro e appena poggiate le gomme posteriori do un breve sgommata la vettura si dirigeva pietosamente verso il marciapiede, questo andava avanti fini a quando raggiunta l'auto la sollevavo e accendevo il ricevitore.

Ciao.

Ho provato a fare così: alla pressione del pulsante lato app, parte un timer che invia ogni tot millisecondi la stringa della direzione desiderata, e lato arduino, controllo quando !BT.available(), e nel caso appunto non lo è, quindi smettte di ricevere input, ferma i motori. Ma niente, non va, i motorini ricevono HIG e LOW in modo velocissimo che si sentono ticchettare tipo "trrrr".

In ricezione non si deve controllare solo se è available, ma anche se non è più available da tot millisecondi. Un radiocomando RC standard trasmette continuamente circa 40..50 volte al secondo (almeno così era sui vecchi PPM analogici di quindici anni fa), quindi se non si riscontra più un available per 50ms si può considerare perso il segnale, e anche in assenza di comandi andrebbe trasmesso un codice "no command" (ma non ho idea se via BT si possa o meno mantenere una trasmissione costante e se ci sono latenze).

Ecco, non voglio fare la fine del modellino :stuck_out_tongue_closed_eyes:

Riguardo il ponte H non sono riuscito a trovare risposta alle mie domande :roll_eyes: :roll_eyes: aiutatemi a capire :slightly_frowning_face: :slightly_frowning_face:

Riguardo la comunicazione:

  • se dopo ogni comando ricevuto svuotassi il buffer? potrebbe essere una soluzione?

  • se faccio partire un millis() dopo ogni comando ricevuto, e a ogni giro di loop controllo anche se non ricevo comandi da N millis allora mi femo? potrebbe essere un'altra soluzione?

Vi posto il codice che c'e su arduino ora (senza controllo sulla NON-ricezione), così se avete voglia potreste dirmi se posso migliorare qualcosa

#include <SoftwareSerial.h>

#define bluetoothSerial_TX_PIN 3
#define bluetoothSerial_RX_PIN 2

#define MOTORE1_1 10
#define MOTORE1_2 11
#define MOTORE2_1 5
#define MOTORE2_2 6
#define STOP 0
#define MAX 255

String incomingData;
int motor_speed = 0;
int motor_L_speed = 0;
int motor_R_speed = 0;

SoftwareSerial bluetoothSerial =  SoftwareSerial(bluetoothSerial_RX_PIN, bluetoothSerial_TX_PIN);

void setup() {

  Serial.begin(9600);
  bluetoothSerial.begin(9600);


  pinMode(MOTORE1_1, OUTPUT);
  pinMode(MOTORE1_2, OUTPUT);

  pinMode(MOTORE2_1, OUTPUT);
  pinMode(MOTORE2_2, OUTPUT);

  pinMode(bluetoothSerial_RX_PIN, INPUT);
  pinMode(bluetoothSerial_TX_PIN, OUTPUT);


  analogWrite(MOTORE1_1, STOP);
  analogWrite(MOTORE1_2, STOP);
  analogWrite(MOTORE2_1, STOP);
  analogWrite(MOTORE2_2, STOP);

  Serial.println("Pronto!");
  bluetoothSerial.println("Pronto!");

}

void loop() {

  while (bluetoothSerial.available() > 0) {
    
    incomingData = bluetoothSerial.readStringUntil('\n');
    incomingData.trim();

    if (incomingData == "W") {
      forward();
    } else if (incomingData == "S") {
      backward();
    } else if (incomingData == "A") {
      left();
    } else if (incomingData == "D") {
      right();
    } else if (incomingData == "X") {
      stop_motor();
    }  else if (incomingData.substring(0, 5) == "SPEED") {
      motor_speed = incomingData.substring(5, incomingData.length()).toInt();
      if (motor_speed > 255)
        motor_speed = 255;
    } else if (incomingData.substring(0, 1) == "L") {
      motor_L_speed = incomingData.substring(1, incomingData.length()).toInt();
      forwardL();
    } else if (incomingData.substring(0, 1) == "R") {
      motor_R_speed = incomingData.substring(1, incomingData.length()).toInt();
      forwardR();
    }
  }

  delay(10);
}

void forwardR() {
  analogWrite(MOTORE1_1, STOP);
  analogWrite(MOTORE1_2, motor_R_speed);
}

void forwardL() {
  analogWrite(MOTORE2_1, motor_L_speed);
  analogWrite(MOTORE2_2, STOP);
}

void stop_motor() {
  analogWrite(MOTORE1_1, STOP);
  analogWrite(MOTORE1_2, STOP);

  analogWrite(MOTORE2_1, STOP);
  analogWrite(MOTORE2_2, STOP);
}

void forward() {
  analogWrite(MOTORE1_1, STOP);
  analogWrite(MOTORE1_2, motor_speed);

  analogWrite(MOTORE2_1, motor_speed);
  analogWrite(MOTORE2_2, STOP);
}


void backward() {
  analogWrite(MOTORE1_1, motor_speed);
  analogWrite(MOTORE1_2, STOP);

  analogWrite(MOTORE2_1, STOP);
  analogWrite(MOTORE2_2, motor_speed);
}


void right() {
  analogWrite(MOTORE1_1, STOP);
  analogWrite(MOTORE1_2, motor_speed);

  analogWrite(MOTORE2_1, STOP);
  analogWrite(MOTORE2_2, motor_speed);
}

void left() {
  analogWrite(MOTORE1_1, motor_speed);
  analogWrite(MOTORE1_2, STOP);

  analogWrite(MOTORE2_1, motor_speed);
  analogWrite(MOTORE2_2, STOP);
}

Aggiungo che ho notato che se stacco il cavo che dal pin 2 va sulla breadboard al pin TX del BT, e lo stacco lato BT, le stringhe che legge arduini sono tutti caratteri e simboli strani, quindi ho provato a inserire la condizione che se una stringa è diversa da quelle ammesse allora deve fermarsi, ma a volte alcuni caratteri strani è come se non avessero il fine stringa "\n", che leggo con readStringUntil("\n"), quindi ci mette tempo e rimane incantato per un po.

Ho provato anche a digitalRead(2) per vedere se c'e 0 o 1 sul pin. Effettivamente se il cavo è staccato c'e 0, ma cmunque ci mette un po a fermarsi..

se stacco il cavo prorpio dal pin invece, sembra tutto piu veloce.. Non riesco a trovare soluzioni migliori.

EDIT: invece penso di averla trovata!!! A breve il codice modificato e mi dite cosa ne pensate..

mattoide:
Vi posto il codice che c'e su arduino ora (senza controllo sulla NON-ricezione), così se avete voglia potreste dirmi se posso migliorare qualcosa

Alcuni consigli, poi decidi tu :wink:

Non vorrei smontare il tuo entusiasmo, ma prima che qualcuno ti bastoni (virtualmente :slight_smile: ), fermati un attimo ed impara ad usare le stringhe C (array di char) e non le Stringhe (oggetto String), che solitamente creano solo casini (prova a cercare nel forum).

Per quanto riguarda la trasmissione seriale (comandi), visto che è sempre M2M, non è necessario usare delle stringhe parlanti, ti basta usare dei byte (0-255) che per comodità puoi definire tramite delle define o degli enum, cioè delle costanti, cosi eviti di dover ricordare numeri. Lato app, fai la stessa cosa.

enum COMMAND {
  CMD_NONE    = 0,
  CMD_STOP    = 1,
  CMD_FORWARD = 2,
  CMD_LEFT    = 3,
  CMD_RIGHT   = 4,
  //...
};

//oppure

#define CMD_STOP    1
#define CMD_FORWARD 2
#define CMD_LEFT    3
#define CMD_RIGHT   4

e quindi dove ti serve usi CMD_LEFT invece di 3

byte cmd = bt.read();

switch (cmd) {
  case CMD_LEFT:
    //vai a sinistra
    break;
  case CMD_RIGHT:
    //vai a destra
    break;
  //...
}

Naturalmente dovresti definire un protocollo di trasmissione.

Ad esempio protesti inviare sempre 2 byte più uno di fine trasmissione, dove il primo rappresenta il comando principale (cambia velocità) e il secondo un eventuale parametro (valore velocità).
E' solo un esempio, decidi tu sulla base di cosa hai intenzione di trasmettere.

Non preoccuparti se devi inviare qualcosa (es. metri percorsi) che potrebbe superare il limite del byte, questo lo si può sempre "dividere" su più byte in partenza per poi "ricostruire" alla ricezione.

Per il momento direi che hai abbastanza materiale su cui lavorare, visto che dovresti rivedere tutta la gestione dei comandi, ma meglio farlo subito che dopo :wink:

Federico

Federico66:
Alcuni consigli, poi decidi tu :wink:

Non vorrei smontare il tuo entusiasmo, ma prima che qualcuno ti bastoni (virtualmente :slight_smile: ), fermati un attimo ed impara ad usare le stringhe C (array di char) e non le Stringhe (oggetto String), che solitamente creano solo casini (prova a cercare nel forum).

Per quanto riguarda la trasmissione seriale (comandi), visto che è sempre M2M, non è necessario usare delle stringhe parlanti, ti basta usare dei byte (0-255) che per comodità puoi definire tramite delle define o degli enum, cioè delle costanti, cosi eviti di dover ricordare numeri. Lato app, fai la stessa cosa.

Si, è una modifica che avevo gia in canna, all'inizio ho scelto le stringhe perchè mi risultava più facile debuggare :slight_smile:

mattoide:
Si, è una modifica che avevo gia in canna, all'inizio ho scelto le stringhe perchè mi risultava più facile debuggare

Bene, meglio cosi :slight_smile:

Per il debug dell'enum si potrebbe fare cosi:

#define DEBUG 1
#if DEBUG
  const char enumToString[][20] = {"CMD_NONE","CMD_STOP","CMD_FORWARD","CMD_LEFT","CMD_RIGHT"};
  #define PRINT_ENUM(value) { Serial.print(enumToString[value]); Serial.print(":"); Serial.println(value);}
#endif

// devi usare numeri in sequenza per essere allineato con l'array
enum COMMAND {
  CMD_NONE    = 0,
  CMD_STOP    = 1,
  CMD_FORWARD = 2,
  CMD_LEFT    = 3,
  CMD_RIGHT   = 4,
  //...
};

void setup() {
  Serial.begin(9600);
  byte cmd = 2
  #if DEBUG
    PRINT_ENUM(cmd)
  #endif
}

purtroppo devi mantenere allineati enum e array, ma non so se esiste metodo migliore, anzi se qualcuno ha idee, mi interessa :slight_smile:

Federico

Sto facendo alcuni esperimenti con i byte, ma non ne vengo fuori.

Per l'invio di un solo byte per la direzione va anche bene. Ma se poi mi devo prendere un byte per la direzione e uno per la velocità mi sta risultando difficile. Ho provato sia con Serial.read() con cilo while personalizzato, sia readBytes(), sia readBytesUntil(). Riesci a farmi un esempio di come lo faresti? Grazie :slight_smile:

Per il ponte h invece ? Riuscite a illuminarmi?

mattoide:
Per l'invio di un solo byte per la direzione va anche bene. Ma se poi mi devo prendere un byte per la direzione e uno per la velocità mi sta risultando difficile.

Ma stai trasmettendo più comandi con un solo invio? A me non piace, non so gli altri, ma io la trovo una gestione ostica, anche perchè nella trasmittente dovresti prevedere il "cumulo dei comandi"

Io preferisco inviare un comando alla volta.
Esempio, facciamo finta, che non ci sia un protocollo, quindi devo inviare/ricevere almeno un byte (comando principale).

trasmissione:

  • avanti -> invio un byte
  • velocità,x -> invio due byte

quindi in ricezione, ad ogni ciclo del loop:

  • ricevo qualcosa, leggo il primo byte
  • se "avanti", avvio motori
  • se "velocità", leggo il secondo byte, imposto la velocità

ho usato questo sistema in un paio di progetti e mi trovo bene, poi naturalmente qualcun altro potrebbe consigliarti diversamente.

Federico

mattoide:
Riguardo il ponte H non sono riuscito a trovare risposta alle mie domande :roll_eyes: :roll_eyes: aiutatemi a capire :slightly_frowning_face: :slightly_frowning_face:

No. Ti ho risposto nella prima risposta.
Ciao Uwe

Federico66:
Ma stai trasmettendo più comandi con un solo invio? A me non piace, non so gli altri, ma io la trovo una gestione ostica, anche perchè nella trasmittente dovresti prevedere il "cumulo dei comandi"

Io preferisco inviare un comando alla volta.
Esempio, facciamo finta, che non ci sia un protocollo, quindi devo inviare/ricevere almeno un byte (comando principale).

trasmissione:

  • avanti -> invio un byte
  • velocità,x -> invio due byte

quindi in ricezione, ad ogni ciclo del loop:

  • ricevo qualcosa, leggo il primo byte
  • se "avanti", avvio motori
  • se "velocità", leggo il secondo byte, imposto la velocità

ho usato questo sistema in un paio di progetti e mi trovo bene, poi naturalmente qualcun altro potrebbe consigliarti diversamente.

Federico

Ho cambiato il codice così, ma non so, sento che non è vicino al tuo consiglio! Che ne dici?

#include <SoftwareSerial.h>

#define bluetoothSerial_TX_PIN 3
#define bluetoothSerial_RX_PIN 2

#define MOTORE1_1 10
#define MOTORE1_2 11
#define MOTORE2_1 5
#define MOTORE2_2 6
#define MOTOR_STOP 0
#define MAX 255

#define MAX_BYTES 5
#define STOP 88
#define FORWARD 87
#define BACKWARD 83
#define LEFT 65
#define RIGHT 68
#define L_FORWARD 81
#define R_FORWARD 69
#define RIGHT 68
#define SPEED 70

char bt_bytes[MAX_BYTES];
String toSpeed;
 
int motor_speed = 0;
int motor_L_speed = 0;
int motor_R_speed = 0;

SoftwareSerial bluetoothSerial =  SoftwareSerial(bluetoothSerial_RX_PIN, bluetoothSerial_TX_PIN);

void setup() {

  Serial.begin(9600);
  bluetoothSerial.begin(9600);


  pinMode(MOTORE1_1, OUTPUT);
  pinMode(MOTORE1_2, OUTPUT);

  pinMode(MOTORE2_1, OUTPUT);
  pinMode(MOTORE2_2, OUTPUT);

  pinMode(bluetoothSerial_RX_PIN, INPUT);
  pinMode(bluetoothSerial_TX_PIN, OUTPUT);


  analogWrite(MOTORE1_1, MOTOR_STOP);
  analogWrite(MOTORE1_2, MOTOR_STOP);
  analogWrite(MOTORE2_1, MOTOR_STOP);
  analogWrite(MOTORE2_2, MOTOR_STOP);

  Serial.println("Pronto!");
  bluetoothSerial.println("Pronto!");

}

void loop() {

  if (bluetoothSerial.available() > 0) {

    bluetoothSerial.readBytesUntil('\n', bt_bytes, MAX_BYTES);


    switch (bt_bytes[0]) {

      case FORWARD:
        forward();
        break;

      case BACKWARD:
        backward();
        break;

      case LEFT:
        left();
        break;

      case RIGHT:
        right();
        break;

      case STOP:
        stop_motor();
        break;

      case SPEED:
       
        motor_speed = (String(bt_bytes[1]) + String(bt_bytes[2]) + String(bt_bytes[3])).toInt();
        if (motor_speed > 255)
          motor_speed = 255;
        break;

      case L_FORWARD:
        motor_L_speed = (String(bt_bytes[1]) + String(bt_bytes[2]) + String(bt_bytes[3])).toInt();
        forwardL();
        break;

      case R_FORWARD:
        motor_R_speed = (String(bt_bytes[1]) + String(bt_bytes[2]) + String(bt_bytes[3])).toInt();
        forwardR();
        break;

        default:
                stop_motor();

    }
  }



}

void forwardR() {
  analogWrite(MOTORE1_1, MOTOR_STOP);
  analogWrite(MOTORE1_2, motor_R_speed);
}

void forwardL() {
  analogWrite(MOTORE2_1, motor_L_speed);
  analogWrite(MOTORE2_2, MOTOR_STOP);
}

void stop_motor() {
  analogWrite(MOTORE1_1, MOTOR_STOP);
  analogWrite(MOTORE1_2, MOTOR_STOP);

  analogWrite(MOTORE2_1, MOTOR_STOP);
  analogWrite(MOTORE2_2, MOTOR_STOP);
}

void forward() {
  analogWrite(MOTORE1_1, MOTOR_STOP);
  analogWrite(MOTORE1_2, motor_speed);

  analogWrite(MOTORE2_1, motor_speed);
  analogWrite(MOTORE2_2, MOTOR_STOP);
}


void backward() {
  analogWrite(MOTORE1_1, motor_speed);
  analogWrite(MOTORE1_2, MOTOR_STOP);

  analogWrite(MOTORE2_1, MOTOR_STOP);
  analogWrite(MOTORE2_2, motor_speed);
}


void right() {
  analogWrite(MOTORE1_1, MOTOR_STOP);
  analogWrite(MOTORE1_2, motor_speed);

  analogWrite(MOTORE2_1, MOTOR_STOP);
  analogWrite(MOTORE2_2, motor_speed);
}

void left() {
  analogWrite(MOTORE1_1, motor_speed);
  analogWrite(MOTORE1_2, MOTOR_STOP);

  analogWrite(MOTORE2_1, motor_speed);
  analogWrite(MOTORE2_2, MOTOR_STOP);
}

Per il ponte H:

"Non puoi scendere con la tensione motori sotto la tensione di alimentazione della logica (i 5V)."

Ho ragionato meglio su questa frase, penso di aver capito!! Domani prendo un multimetro, che mi sa che è arrivato il tempo di usarlo, così posso assicurarmi se ho capito bene o no. Grazie :slight_smile:

EDIT:

riguardo il ponte H, se il trasformatore è alla sua massima potenza, e come velocità dei motorini metto 255 (massimo) comunque dopo qualche secondo si ferma.. se sto invece intorno al 70% della velocità, regge.. quindi credo di aver capito solo a metà.

mattoide:
Ho cambiato il codice così, ma non so, sento che non è vicino al tuo consiglio! Che ne dici?

Non ho mai usato readBytesUntil, ed è preferibile evitarlo in quanto è bloccante.
Se cerchi nel forum trovi vari esempi su come cumulare i bytes in arrivo fino al terminatore, questo è un esempio:

const byte EOT = 0x04; //End of transmission
byte idx = 0;
byte bt_bytes_count = 0;

//accumulo e poi leggo, serve un terminatore
while (bluetoothSerial.available() > 0) {
  byte rb = bluetoothSerial.read();
  if (rb == EOT) {
    //fine ricezione, esco
    bt_bytes_count = idx;
    break;
  } else if (idx >= MAX_BYTES) {
    //ricevo più bytes!!
    bt_bytes_count = idx;
    break;
  } else {
    bt_bytes[idx] = rb;
    idx++;
  }
}
if (bt_bytes_count > 0) {
  //controllo i comandi ricevuti ed eseguo
}

Ho usato 0x04 (4) come terminatore, usa quello che vuoi.

Però io solitamente, quando sviluppo anche la trasmittente e invio pochi bytes, non uso il terminatore.
Anche perchè in pratica invii un solo byte significativo, che decide per gli eventuali successivi :slight_smile:
In pratica, fai un controllo sul primo byte che deve essere necessariamente uno di quelli che ti aspetti, altrimenti non fai nulla; se è buono e prevede alcuni byte successivi, continui a leggere.

//controllo byte per byte, non serve un terminatore
if (bluetoothSerial.available() > 0) {
  //leggo il primo byte
  byte rb = bluetoothSerial.read();
  delay(2);
  switch (rb) {
    case FORWARD:
      //vado avanti
      break;
    //...
    case SPEED: // se speed devo leggere ancora
      //leggo il secondo byte
      byte speed = bluetoothSerial.read();
      //imposto velocità
      break;
    default:
      //non ho ricevuto comando conosciuto, esco
      break;
  }

  //per sicurezza si può aggiungere questo per svuotare il buffer
  while(bluetoothSerial.available()) {
    bluetoothSerial.read();
    delay(2);
  }
}

Quindi, fai qualche prova, per capire la differenza e verificare i pro e i contro dei due metodi :wink:

Veniamo a questo!

motor_speed = (String(bt_bytes[1]) + String(bt_bytes[2]) + String(bt_bytes[3])).toInt();

Se devi trasmettere un intero, puoi fare cosi:
(spero di aver conferma da qualcun altro :slight_smile: )

//Trasmittente
int iT = 32767;

//scomponi in due byte e invii
byte iHigh= (byte)(iT / 256);
byte iLow= (byte)(iT % 256);

//Ricevente
//ricomponi int
int iR = (iHigh * 256) + iLow;

quindi nel tuo caso, sarà

  case SPEED: // se speed devo leggere ancora due byte
    //leggo il secondo byte -> HighByte
    byte speedHigh = bluetoothSerial.read();
    delay(2);

    //leggo il terzo byte -> LowByte
    byte speedLow = bluetoothSerial.read();
    delay(2);

    motor_speed = (speedHigh * 256) + speedLow;

Spero di non aver detto castronate :slight_smile:

Federico

EDIT