Rientro in forum dopo anni scusate sto facendo delle prove per ambientarmi di nuovo

come applicazione dal telefono sto usando Bluethoot Electronics.

Le serial print chiamate ad ogni ciclo di programma intasano il buffer di trasmissione e diventano bloccanti. Questo le trasforma in piccoli delay di qualche millisecondo. E questo del tutto incidentalmente (cioè non progettato) lascia il tempo ai pochi byte in arrivo dal bluetooth di depositarsi nel buffer di ricezione, per cui il while available riesce (sempre per pura fortuna) a ricomporre le stringhe.

Il problema è non avere previsto alcun tipo di sincronizzazione sui byte in arrivo e attenzione sul loro tempo di arrivo, per cui le stringhe si ricompongono solo per caso (una certa percentuale risulterà comunque malformata e non riconosciuta).

Non funziona più o non compila più?
Perchè se gli hai anteposto un asterisco vedo più probabile la seconda. Se vuoi escludere delle linee di codice dalla compilazione le devi commentare usando o // all'inizio della riga oppure la sequenza /* */, che può anche comprendere più righe.
La sintassi di altre parti del programma mi lascia molto perplesso, tipo qui:

if(Direzione==1){digitalWrite(R_dx_Av,HIGH),digitalWrite(R_dx_In,LOW),digitalWrite(R_sx_Av,HIGH),digitalWrite(R_sx_In,LOW);} /*AVANTI*/

Le varie istruzioni vanno separate normalmente con il ; non con la virgola, possibilmente su più righe e ben indentate, es.:

if(Direzione==1){  /*AVANTI*/
  digitalWrite(R_dx_Av,HIGH);
  digitalWrite(R_dx_In,LOW);
  digitalWrite(R_sx_Av,HIGH);
  digitalWrite(R_sx_In,LOW);
} 

Ciao, Ale.

Ciao Claudio
infatti le vorrei togliere le serial print, ma se le tolgo non funziona.

Ciao Guargua
il problema è con le Serial print...che come mi conferma Claudio FF mi a lungo andare si trasformano come delay, ma se le tolgo non funziona.

Il "lungo andare" sono circa 60 millisecondi, poi il buffer di trasmissione è pieno (perché i byte a 9600 bit/s escono circa uno al millisecondo). Il vero problema non sono le serial print , ma la logica di ricezione, se ne parla in questo thread: https://forum.arduino.cc/t/comunicazione-seriale-tra-arduino-uno-e-arduino-mega/866064

Scusa, già te l'hanno chiesto ma non hai risposto: cosa intendi esattamente con "non funziona"? che lo accendi e non risponde mai ai comandi? O risponde ma dopo "x" comandi non fa più niente? O apparentemente dopo "y" secondi? Che dai un comando e ne fa un altro? COSA?
Poi in genere è sempre bene precisare di quale scheda si parla, nel tuo caso sembra che sia una Mega, ma devi confermarcelo tu, non lasciare a noi il compito di "indovinare".

In ogni caso devi evitare come la peste le variabili "String", usa le stringhe classiche del C. Anche perché qui la usi solo come buffer dei caratteri ricevuti quindi è abbastanza facile (se vuoi qualche "imbeccata" su come fare, dillo e ti spieghiamo).

E, per finire, tu hai questo buffer RX_2 nel quale accumuli i caratteri ricevuti, e ok (tralasciamo il discorso "String", e che per convenzione si indicano con tutte maiuscole solo le costanti ed i simboli e non le variabili) e quindi nella funzione USA_BLUETOOTH controlli se hai ricevuto uno dei comandi. Ma poi questo benedetto buffer quand'è che lo svuoti? Se mando i comandi "AvV1" lui all'inizio prenderà "Av" ma poi la stringa "AvV1" non sarà mai uguale a nessuna di quelle delle if()...

Ciao docdoc
uso una mega che compila in entrambi i casi, nella funzione USA_BLUETOOTH nell'ultima riga riporto RX_2="";

succede che quando uso le serialprint per verificare sul serialmonitor vedo tutto correttamente ed anche la funzione DIREZIONE_VELOCITA_RUOTE risponde ai comandi, ma quando le tolgo perchè non mi serve più ovviamente vederle sul serial monitor ricompilo, DIREZIONE_VELOCITA_RUOTE non risponde più.

Al momento mi sto leggendo il thead consigliato da Claudio FF....senza capirci molto in realtà.
Voglio anche provare ad utilizzare il buon caro millis().

Ho notato che mettendo delay() al posto dei 2 serial.print......funziona tutto, credo di essere sulla strada giusta.
Provo a sostituire il delay con millis().
Che dite sono sulla strada giusta??

Col delay, così come con millis, puoi introdurre un minimo di ritardo che con molta fortuna può funzionare, ma sarebbe solo una pezza.... fatta pure male.
Il problema è quello evidenziato da @Claudio_FF. Devi verificare che siano arrivati 2 caratteri nel corretto ordine prima di controllare il comando.
Il link che ti ha messo, come gli altri link di quella discussione, possono aiutare, ma devi cercare almeno di capire quale è la logica corretta.

I caratteri arrivano corretti e mi basta un delay(5); perche tutto funzioni correttamente......è qui che non riesco a sbloccarmi.

Il problema è che non voglio utilizzare ne delay() ne serial.print(li uso solo in fase di progammazione), perchè a lungo andare sono bloccanti.

Ho provato anche con una semplice funzione boleana, ma mi serve sempre quella frazione di tempo che non voglio ripetere all'infinito nel LOOP.

Il problema è proprio quello...
Verifichi i comandi troppo velocemente e ti perdi dei pezzi.
Quindi puoi "rallentare" in 2 modi:

  • con un delay (ammesso che funzioni anche su utilizzi prolungati)
  • cambi logica seguendo i suggerimenti di @Claudio_FF
    Scegli tu quello che preferisci.

domani provo a rileggere e capire i suggerimenti di ClaudioFF....oggi li ho letti ma non li ho capiti sinceramente tipo Handshake logico e lo schema alla fine.....anzi credo di averlo capito, ma non credo sia il mio caso.

Claudio in quella discussione ha fatto praticamente un trattato sui protocolli di comunicazione...
Te la puoi cavare anche in modo più semplice.
Prima però devi capire quale è il problema:
Come l'hai scritto tu non sei mai sicuro di quale sia il primo carattere del comando e quale il secondo.
Se ne perdi uno, la sequenza "Av V1 Dx Av" diventa "vV 1D xA v" e quindi nessuno sarà interpretato correttamente.
Devi inventarti un modo per "sicronizzare" invio e ricezione.

SINCRONIZZARE
mi sta venendo qualke idea....
ci devo pensare.
per il momento crazie a tutti.

Come no? I tuoi comandi V0 V1 ecc li fai (ad esempio) precedere da un '#' e seguire da un '*' che rappresentano inizio e fine. In ricezione ti trovi l'array con dentro esattamente le tue stringhe, e in formato standard C, quindi testabili con la funzione strcmp:

if (strcmp(buffer, "V0") == 0) { ...... }

che funzione è???.......lo fai per confondermi ancora di più??? :thinking: :thinking: :grinning: :grinning: :grinning:

Si ma tu dovresti svuotare la stringa solo dopo aver riconosciuto un comando (quindi dentro a tutte le if) oppure quantomeno se il buffer, dopo le if, contiene esattamente 2 caratteri.

Se invece lo fai in quel punto, indipendentemente da cosa ricevi, potresti svuotare il buffer quando hai ricevuto ancora solo uno dei due caratteri (ed ecco perché coi delay sembri risolvere, semplicemente dai tempo di ricevere i due caratteri -comunque metodo non sicuro al 100%-).

Quando si devono fare comunicazioni di questo tipo, sempre meglio implementare un minimo di "protocollino" come suggerito. Quantomeno un carattere inziale come "*" (il terminatore non serve se i comandi sono sempre composti da 2 caratteri).

Ma inizia a studiare un poco le stringhe del C (al posto di "String") perché ti sarà utilissimo per imparare a programmare in modo più efficiente, e per evitare che in futuro i programmi possano darti seri malfunzionamenti o bloccarsi (questi sono gli "effetti" dell'uso di String purtroppo).

Ad esempio confrontare due stringhe si fa con la funzione strcmp() che già ti hanno indicato, invece di "==", ma una volta iniziato a comprendere come funzionano le stringhe C e come si gesticono, è tutto abbastanza facile.

Grazie a tutti ragazzi per i consigli.

void USA_BLUETOOTH()
{
 if(Serial2.available())        /*Se la seriale è attiva Bluetooth HC-08 Trasmette o Riceve*/
   { 
         
    while(Serial2.available()) /*Finchè è attiva*/
         { 
                    
          rx_2=Serial2.read();  /*"rx_2" assume il CARATTERE che riceve*/
          RX_2.concat(rx_2);    /*"RX_2" assume tutti i CARATTERI da "rx_2" in un unica STRINGA*/
          if(RX_2=="V0"){Velocita=0, RX_2="";} /*FERMO*/  
          if(RX_2=="V1"){Velocita=1, RX_2="";} /*LENTO*/    
          if(RX_2=="V2"){Velocita=2, RX_2="";} /*VELOCE*/  
          if(RX_2=="Av"){Direzione=1, RX_2="";}/*AVANTI*/
          if(RX_2=="In"){Direzione=2, RX_2="";}/*INDIETRO*/ 
          if(RX_2=="Dx"){Direzione=3, RX_2="";}/*DESTRA*/ 
          if(RX_2=="Sx"){Direzione=4, RX_2="";}/*SINISTRA*/
         } 
    }                            
} 
Grazie a tutti i consigli per il momento l'ho risolta cosi, secondo voi può andare??

Comunque non tornando al discorso Stringhe, effettivamente sono alle prime armi, ho fatto qualke prova documentandomi ma sono ancora indietro.