Estrarre numeri da Seriale

Ciao a tutti,non ho molta esperienza in questo campo,perciò chiedo a chi ne sa piu di me.
Nel mio progetto,in pratica,arrivano continuamente sulla seriale di arduino 5 numeri(cioè 5 valori di sensori),uno per ogni riga.
Cio che devo riuscire a fare è salvare ognuno di questi numeri in una variabile diversa,probabilmente per molti di voi è una cosa banale,ma io non ho mai utilizzato questi metodi.Aspetto risposte,grazie in anticipo

Avrei alcune domande:

  1. I valori sono divisi da uno stesso carattere (es "valore, 'A', valore, 'A', valore...")
  2. I valori sono trasmessi in cifre o in un unico byte ('centoventi' o "'1','2','0'")
  3. é previsto un minimo di intervalli tra due invii consecutivi dei valori, sufficiente a permettere ad Arduino di vuotare la seriale e (se necessario) operare?
    Da qui possiamo ragionare

No i valori non sono divisi da un carattere,ogni numero è inviato come un unico byte,l'unica cosa che diatingue i numeri sono i fine riga.Infine tra gli invii dei numeri non ci sono delay,posso aggiungere dei delay minimi come 100 millisecondi ma non oltre.

5 numeri(cioè 5 valori di sensori),

ogni numero è inviato come un unico byte,

Uhmm, secondo me ti stai contraddicendo.

Perchè non metti lo sketch che usi per inviare

Docsavage questo thread si riferisce proprio a quello sketch con i sensori di flessione,e per farlo funzionare bene devo riuscire a distinguere i valori dei 5 sensori

Gli sketch di invio dati:

#include <SoftwareSerial.h>

SoftwareSerial transmit(2,3);

void setup() {
  Serial.begin(9600);
  transmit.begin(9600);
  
  pinMode(A4,INPUT);
   pinMode(A3,INPUT);
    pinMode(A2,INPUT);
   pinMode(A1,INPUT);
    pinMode(A0,INPUT);
  // put your setup code here, to run once:

}

void loop() {
  int pollice=analogRead(A4);
  int indice=analogRead(A3);
  int medio=analogRead(A2);
  int anulare=analogRead(A1);
  int mignolo=analogRead(A0);
  

 

   
  transmit.write(pollice);
  
  transmit.write(indice);

  
  transmit.write(medio);

  
  transmit.write(anulare);

  transmit.write(mignolo);

   




  



  
  delay(50);

}

Quello che mi manca è la parte di ricezione che riesce a distinguere tutti e 5 i dati

Tu invii 5 interi. Ogni intero è composto da 2 byte. In ricezione devi prendere i byte e ricomporli a 2 a 2 come int.

Volevo sapere se ci fosse un altro metodo per separare i vari dati dei sensori che poi fanno muovere i servo motori,perchè nell'altra discussione i servo motori ciclicamente si bloccavano,quindi il tutto non funzionava bene.Ho anche notato che con il programma dell'altra discussione, vedendo nel monitor seriale i dati che arrivavano,a volte c'èrano numeri grandissimi e che non c'entravano niente con quello che realmente doveva arrivare.Invece altre volte riavviavo arduino e nel monitor seriale c'erano i dati giusti,anche se c'era il problema dei servo motori che si bloccavano

Se il programma di trasmissione é modificabile, allora semplificati la vita...
Leggi i cinque valori e li salvi in altrettante variabili. In trasmissione cominci con un preambolo differente per ogni variabile (ad esempio le lettere dell'alfabeto maiuscole in ordine), poi trasmetti la variabile, ed infine un terminatore non numerico fisso. Usi per tutte la Serial.print, che ti divide la variabile mandando tela cifra per cifra. Ci hai messo 10 MS circa, ma li hai, ed é MOLTO più facile la ricezione.
Prova a pensare tu alla ricezione, con due accorgimenti: dato x un numero a n cifre e y un numero ad una cifra per avere XY é x*10+y
Inoltre le cifre hanno codici aschii diversi dal loro valore, ma consecutivi ed in ordine crescente.
Se serve una mano ci sono, ma pensaci, credo ci possa arrivare

Grazie per le risposte,non so come fare ad aggiungere le lettere all'inizio e alla fine del dato del sensore.

Va bene grazie ,guardo e ti faccio sapere

Scusa, ma ho una domanda.
Se io devo scrivere "A35stop" come faccio?
A me verrebbe di scrivere 'A', di scrivere '35' e di scrivere 'stop'.
Ora, dato che 'A' si traduce 'A', 35 si traduce variabile che memorizza il valore letto dal primo sensore, e che 'stop' si traduce costante char globale che contiene un carattere non numerico che arbitrariamente identifica il messaggio stop e che non é il punto, usato nei float come virgola (meglio non mischiare, chissà se per questo pezzo passasse qualcosa di non previsto adesso). A che conclusione arrivi? Aggiungendoci, poi, che 'scrivi' si traduce Serial.print (...);... Il gioco é fatto.
Ora tocca al secondo, come fai?

Perciò per trasmettere uso questo metodo:

transmit.write('A');
transmit.write(pollice&0xFF);
  transmit.write(pollice>>8);
transmit.write('#');

Perché per trasmettere usi write? La print fa qualcosa di meglio, divide le stringhe in caratteri e le formatta. In fatica, mentre write (120) ti restituisce un byte con per valore 120 print (120) ti restituisce 3 bites con i seguenti valori: numero 1, numero 2, numero 0. I bites aumentano, ma non dovrebbe essere un problema. Il bello di una struttura inizio valore fine é che inizio mi dice dove scrivere il numero, e fino a che non becco fine scrivo. Il problema di una write é che stiano usando un numero più grande di un byte, che non é semplice riunire.

Grazie giovepluvio per la risposta,da quanto ho capito,per mandare un singolo valore del sensore(per ora inizio con uno per non complicarmi la vita),devo usare questo metodo in trasmissione:

transmit.print('A');
  transmit.print(pollice&0xFF);
  transmit.print(pollice>>8);
  transmit.print('#');

In ricezione invece come devo comportarmi?
Grazie

Per la print basta scrivere print (numero) ci pensa lei a dividere il numero.
In ricezione leggi il primo carattere. Se é un inizio valido azzeri la variabile che hai associato a quell'inizio. Da qui verifichi se ricevi una cifra (if (isDigit(RX))RX scritto minuscolo, e forse isDigit non é corretto. Comunque é equivalente a if (rx-'0'>-1 &&rx-'0'<10)) { var=var*10+(rx-'0')}
else
Se leggi terminatore return;, visto che hai finito di scrivere quel numero
Else (quindi se non é un numero o un terminatore) allora éun errore e va risolto. Puoi scegliere se azzeri e segni l'errore o ignori.
Fai tutto questo usando una variabile di appoggio, per evitare di perdere un sacco di valori.
Inoltre per semplificare il tutto puoi farlo all'interno di una funzione Leggiseriale (byte indice), che viene chiamata dal primo carattere. Indice può essere, ad esempio inizio-'A'. Ovviamente devi inserire il richiamo in un if (rx-'A'>-1 &&rx-'A'<maxarray). Poi l'indice dice alla funzione in che pezzo dell array di ricezione scrivere. Puoi farlo solo se usi per inizio caratteri contigui.
Si capisce o ho messo troppa carne al fuoco?

In effetti,per me c'è molta carne al fuoco.Vediamo,il codice di invio per un solo sensore è questo:

INVIO:

 transmit.print('A'); //inizio pollice
  transmit.print(pollice);
  transmit.print('#'); //terminatore

quello di ricezione:
RICEZIONE:

void loop() {
  if(receive.available()) {
    
    rx=receive.read();   //ricevo
    if(rx == 'A') {      //inizio la lettura
      var=0;
    }

    

    if (rx <= '9' && rx >= '0') {  // Una cifra
      var=var*10+(rx-'0')
    }

    else(rx=='#'){
      return;
    }

Docsavage,grazie per la risposta,ho ancora molto da imparare...
Cercando nei vari post che mi hai indicato ho creato questa parte di ricezione,cosa ne pensi?

#include <Servo.h>

#include <SoftwareSerial.h>


SoftwareSerial receive(2,3);

Servo pollice;
Servo indice;
Servo medio;
Servo anulare;
Servo mignolo;


char rx;
int ricevuta;
int stato;
int datopollice;

void setup() {

  pollice.attach(4);
  indice.attach(5);
  medio.attach(6);
  anulare.attach(7);
  mignolo.attach(8);

  pollice.write(0);
  indice.write(0);
  medio.write(0);
  anulare.write(0);
  mignolo.write(0);
  
  
  Serial.begin(9600);
  receive.begin(9600);
  // put your setup code here, to run once:

}

void loop() {
  if(receive.available()) {
    
    rx=receive.read();   //ricevo
    if(rx == '#') {   //inizio trovato
      
      stato=1;
      ricevuta=0;
    }
     

      if(rx=='A') {
      datopollice = ricevuta;
      stato=0;
      Serial.println(ricevuta);
        
      }


      if (rx <= '9' && rx >= '0') {
      // una cifra
      if (stato == 1) {
        // parte intera
        ricevuta = ricevuta * 10 + rx - '0';
        // shiftare di una cifra e aggiungere l'ultima


    }
  }
    

 }


}

Grazie,scusa se torno a romperti,ho tolto come mi hai suggerito la parte di gestione decimale,ho cambiato il tipo di variabile da float ad int,per far muovere i servo motori ho aggiunto map(ricevuta,0,1000,0,180) che ho messo solo al pollice per il momento;
Nonostante ciò i servo motori continuano a fare dei piccoli movimenti senza senso,forse la sensibilità da aggiustare,ma non si muovono come dovrebbero.
Scusa ancora se ti rompo,Grazie

#include <Servo.h>
#include <SoftwareSerial.h>
SoftwareSerial receive(2, 3);

int ricevuta; // per la gestione della variabile in trasmissione
char rx; // il carattere ricevuto
int stato; // lo stato della ricezione

Servo pollice;
Servo indice;
Servo medio;
Servo anulare;
Servo mignolo;


void setup()
{
    pollice.attach(8);
    indice.attach(7);
    medio.attach(6);
    anulare.attach(5);
    mignolo.attach(4);
    
    pollice.write(0);
    indice.write(0);
    medio.write(0);
    anulare.write(0);
    mignolo.write(0);
    
    Serial.begin(9600);
    receive.begin(9600);
}

void loop()
{
    if (receive.available())
    {
        rx = receive.read();          // Leggo il primo carattere

        if (rx == '#')                 // se è il cancelletto comincio la lettura
        {
            stato = 1;
            ricevuta = 0;                // Ricevuta è la variabile di appoggio dove faccio i calcoli
        }

        if (rx <= 'E' && rx >= 'A')    // Fine trasmissione
        {
            switch (rx)
            {
                case 'A':
                    ricevuta=map(ricevuta,0,1000,0,180);
                    pollice.write(ricevuta);
                    break;

                case 'B':
                    indice.write(ricevuta);
                    break;

                case 'C':
                    medio.write(ricevuta);
                    break;

                case 'D':
                    anulare.write(ricevuta);
                    break;

                case 'E':
                    mignolo.write(ricevuta);
                    break;

                default:
                    break;
            }
        }

        stato = 0;
    }

    

    if (rx <= '9' && rx >= '0')    // Una cifra
    {
        if (stato == 1)              // Parte intera
        {
            ricevuta = ricevuta * 10 + rx - '0';         // Shiftare di una cifra e aggiungere l'ultima
           
        }

       
    }
}

Va bene,grazie,solo un ultima cosa,se volessi leggere in seriale i valori di un dito ad esempio,dove dovrei inserire il serial.print?
Grazie ancora