dividere testo in più parti

È possibile dividere un testo ricevuto in input in più parti? Dovrei inviare tramite bluetooth un testo con 9 cifre da dividere in gruppi da 3 ovvero tre variabili che vanno da 001 a 255 che poi trasformerò in interi.
Si può fare?
Grazie.

Se per testo intendi una stringa, arduino ha un buon set di funzioni per operare su di essa:

in particolare può tornarti utile la substring:

Ciao :slight_smile:

La classe String, su Arduino, è da evitare come la peste !

NON siete su un PC dove c'è un sistema operativo ed un "garbage collector", siete su una piccola MCU con solo 2KBytes di SRAM, dove dovete fare tutto voi e dove usare la classe "String", a causa dell'allocazione e riallocazione dinamica della memoria, porta quasi sempre ... a sicuri problemi ! :smiley:

Detto questo, imparate invece ad usare le stringhe classiche del C ... ovvero semplici array di char terminati dal carattere null (0x00) e le funzioni che troverete nella libreria standard (... che, oltretutto, è automaticamente inclusa dal IDE) AVR libc. :wink:

Guglielmo

Tutto ciò premesso, se appunto hai usato una classica stringa del 'C', ovvero un array di char terminato da 0x00, la separazione in gruppi è piuttosto semplice, visto che ogni carattere è direttamente indicizzabile tramite l'indice dell'array.

Ti basta un secondo array di appoggio (char [4]) dove con un veloce FOR sposti gruppi di 3 caratteri e, volendo, li trasformi direttamente in numerici con la atoi() :slight_smile:

Guglielmo

Butto lì questo codice:

char s[10] = "123456789";
byte n[3];

for (int i = 0; i < 3; i++) {
  n[i] = (s[i * 3] - '0') * 100 + (s[i * 3 + 1] - '0') * 10 + (s[i * 3 + 2] - '0');
}

Non l'ho testato, ma vuole essere una sorta di split e conversione fatti in una volta sola. Cerca di capirne la logica! Se funziona e se lo sistemate opportunamente vi fa risparmiare tempo e flash :).

Grazie, devo ancora studiare tanto, quindi devo inviare una stringa in formato array lavorabile da arduino.
Giusto?

L'invio NON è importante, tanto la ricezione è sempre carattere a carattere ...
... è nella fase di ricezione e di memorizzazione della stringa che devi metterla in un char array :wink:

Guglielmo

questa soluzione prettamente matematica fatta esclusivamente con gli interi è fattibile?
valore =123456789
prima_parte =valore-valore/1000000 = 789
terza_parte= valore/1000000 = 123
seconda_parte=valore/1000-valore/1000000*1000 = 123456-123000 =456

Ho usato molta fantasia, mi pare di aver letto che in C con gli interi le frazioni restituiscono solo la parte intera.

Certo, l'approccio matematico è altrettanto valido, ma io lo realizzerei un po' diversamente:

long v = 123456789;
int p1 = v / 1000000;
long tmp = v % 1000000;
int p2 = tmp / 1000;
int p3 = tmp % 1000;

(% è l'operatore di modulo, che ritorna il resto della divisione)

Questo però richiede che tu abbia già convertito la stringa ricevuta in un numero (che deve essere long nel tuo caso), dovresti poter usare la funzione strtol() per questo.

PS: Sarebbe interessante stimare velocità e flash utilizzata da tutti questi metodi!

potrei adottare questa soluzione, visto che devo inviare 3 valori da compresi tra 1 e 155, li aumento tutti di 100 ovvero li faccio diventare da 100 a 355 e poi metto un -100 alla fine di ogni riga di codice che mi hai postato.
ovviamente invio tramite bluetooth un Int a questo punto ovvero dichiaro v del tuo codice come Int

Buona l'idea del +100, ma non puoi usare un int, dato che arriva fino a 65535 (se unsigned tra l'altro, altrimenti la metà). Devi per forza usare un long, sicuramente c'è modo di inviarlo via BT.

@pierfraxxxx: per me stai complicandoti inutilmente la vita ...
... dai retta, trasmetti i 9 caratteri e separali come ti ha fatto vedere SukkoPera. E' il sistema più semplice, veloce e ... indolore. :slight_smile:

Se poi ti vuoi incasinare la vita ... trasmetti pure via BT un "numerico long int" ... :smiling_imp:

Guglielmo

si, quello degli array è la soluzione più semplice, purtroppo non conosco il c++, programmo solo android con app inventor che è un sistema facilitato senza codice. Pensavo se mando tramite bluetooth direttamente un array di android fatto con appinventor chissà se arduino me lo legge già come array.
Devo provare.

SukkoPera non riesco a capire cosa dice questa linea:
for (int i = 0; i < 3; i++) {
n = (s[i * 3] - '0') * 100 + (s[i * 3 + 1] - '0') * 10 + (s[i * 3 + 2] - '0');
}

Ogni numero che viene trasmesso come un carattere lungo la linea seriale, NON viene trasmesso in binario, ma secondi una codifica internazionale che prende il nome di codice ASCII.

Quindi, la cifra 1 NON viene trasmessa sulla seriale come 0x01, ma con il codice che identifica il carattere 1 in ASCII, che è 0x31.

I numeri da 0 a 9 vengono quindi trasmessi sulla seriale con codici ASCII da 0x30 a 0x39 ...
... il codice di SukkoPera non fa altro che, con un trucchetto, eliminare quel 0x30 in più che ogni cifra ha a causa della codifica ASCII e trasformarla veramente in numerico.

Fai i conti e vedrai che viene giusto :wink:

Guglielmo

ok, grazie, devo provare, ho le idee più chiare ora :wink:

Vorrei provare una soluzione utilizzando la funzione li libreria atoi()

      char s[10] = "123456789"; //Tuo array letto da seriale, da te detto formato da 9 cifre-caratteri ;)
      char numero[4];
      int i=0,j=0, posizione=0;
      int NumeriInteri[3];


      for ( i = 0; i < 3; i++) {

          for(j=0;j<3;j++){

               numero[j]=s[posizione++];

          }
          numero[j]='\0';//terminatore stringa

         NumeriInteri[i]=atoi(numero);
 
       }

//nell'array NumeriInteri hai i tre numeri, che poi puoi assegnare se necessario ad altre tre variabili.

Ho provato su un compilatore C, sembra che funzioni...

... se la atoi() non funzionasse saremmo in mezzo ai guai :grin: :grin: :grin:

Naturalmente, in testa al codice, deve esserci: #include <stdlib.h>

Guglielmo

Occhio solo che nel mio codice non è n=, ma n[ i ]=!

Mi è anche venuto in mente, di usare la funzione strncpy() al posto di un ciclo for, non credo che cambi molto ma è una variante. :slight_smile:

      char s[10] = "123456789"; //Tuo array letto da seriale, da te detto formato da 9 cifre-caratteri ;)
      char numero[4];
      int i=0,j=0, posizione=0;
      int NumeriInteri[3];


      for ( i = 0; i < 3; i++) {

          strncpy(numero,s+posizione,3);
          numero[3]='\0';//terminatore stringa

          NumeriInteri[i]=atoi(numero);
          posizione+=3;
       }

//nell'array NumeriInteri hai i tre numeri, che poi puoi assegnare se necessario ad altre tre variabili.

forse, c'è un problema, nel titolo del thread non era specificato ma poi nella discussione lo avevo fatto presente.
Tutte le procedure che avete riportato partono con un array di char, ma io ottengo una stringa di dati via bluetooth, come faccio a trasformare un Serial.read() in un array?