è possibile convertire una stringa in array ?

Salve,sto facendo alcuni esperimenti con delle trasmissioni di dati utilizzando degli impulsi di luce.
Converto tutte le lettere in binario e poi le trasmetto attraverso delle pulsazionia d un altro arduino che dovrebbe leggere.
Io ho sempre programmato in java,quindi per me la divisione di una stringa in array è cosa comune,ma a quanto sembra su Arduino non è così semplice.
Ho questo file “dizionario.txt” che contiene una lista di caratteri da comparare per decodificare (lo so,è rudimentale,ma ci sto lavorando da ieri,è ancora molto acerbo come progetto,per ora però il trasmettitore funziona bene).
il suo contenuto è:

space,!,",#,$,%,&,’,(,),*,+,–,–,-,.,/,0,1,2,3,4,5,6,7,8,9,:,;,<,=,>,?,@,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,[,],^,,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,},|,{,~_
00100000,00100010,00100011,00100100,00100101,00100110,00100111,00101000,00101001,00101010,00101011,00101100,00101101,00101110,00101111,00110000,00110000,00110001,00110010,00110011,00110100,00110101,00110110,00110111,00111000,00111001,00111010,00111011,00111100,00111101,00111110,00111111,01000000,01000001,01000010,01000011,01000100,01000101,01000110,01000111,01001000,01001001,01001010,01001011,01001100,01001101,01001110,01001111,01010000,01010001,01010010,01010011,01010100,01010101,01010110,01010111,01011000,01011001,01011010,01011011,01011100,01011101,01011110,01011111,01100001,01100010,01100011,01100100,01100101,01100110,01100111,01101000,01101001,01101010,01101011,01101100,01101101,01101110,01101111,01110000,01110001,01110010,01110011,01110100,01110101,01110110,01110111,01111000,01111001,01111010,01111011,01111100,01111101,01111110,01111111

Praticamente,i due macro insiemi,sono divisi da “_”,quindi arduino inizialmente,dovrebbe crearmi due stringhe grosse,per poi,successivamente,dividere queste due stringhe in altri due array nei punti dove si trova “,” (dovrei fare l’escape di questo carattere nell’elenco mediante i due “–” che circondano la virgola nella lista ASCII).
Ho provato ad utilzzare il comando split,preso dal sito di processing,ma non funziona. Come posso fare,sempre se è possibile? Stavo pensando anche creare degli array e dichiararli come costanti,ma volevo usare il lettore SD perchè l’ho comprato mesi fa e praticamente non ho mai avuto modo di utilizzarlo…

Questo è il codice che ho scritto per ora.

#include <SPI.h>
#include <SD.h>
File myFile;
void setup() {
Serial.begin(9600);
// put your setup code here, to run once:
if (!SD.begin(4)) {
Serial.println(“inizializzazione fallita!”);
return;
}
Serial.println(“inizializzazione riuscita”);
myFile = SD.open(“dizionario.txt”);
String dizionarioRAW = myFile.readString();
String dizionarioSemiRaw = split(dizionarioRAW,"_");
String dizionariocompiledASCI = split(dizionarioSemiRaw[0],",");
String dizionariocompiledBIN = split(dizionarioSemiRaw[1],",");

}

void loop() {
// put your main code here, to run repeatedly:

}

Scusate per la domanda stupida,da sviluppatore quasi mi vergogno a chiedere una cosa del genere… :confused: :confused: :confused:

Ciao, da quello che so arduino si basa sul linguaggio C-C++, il tuo modo di dichiarare un array di string non mi sembra corretto, String array[10] stile c++, accantona processing e java :slight_smile:

La memoria ram disponibile su una scheda arduino è limitata, non discuto il fatto di usare array di string, ma bisognerebbe tenere presente che non si sta programmando su un PC, ma su un dispositivo con risorse molto limitate.

Adesso non è disponibile la funzione split, ma l'oggetto string, dispone dei metodi indexOf() e substring(), tramite questi due metodi e cicli for dovresti riuscire a separare la stringa :slight_smile:

Non é cosí semplice perché Arduino viene programmato in C e non in Java e il C non gestisce tanto le stringhe come altri linguaggi di programmazione.

Perché metti i dati ricevuto prima in una stringa e poi in un array?
Perché non li metti subito in un array?

Attenzione Genuino UNO ha 2kByte di RAM. Nel fare quello che vuoi fare riempi velocemente la RAM.

Ciao Uwe

Oltre agli appunti che ti hanno già fatto non riesco a capire per quale assurdo motivo ti devi creare un dizionario quando i caratteri sono già codificati in ASCII.
Potevo capire se volevi realizzare una codifica con pochi bit, per ridurre i tempi di trasmissioni, come si faceva tanto tempo fa con le codifiche a solo 6 bit con un limitato set di caratteri, ma la tua codifica è sempre ad 8 bit come quella ASCII.
Forse non ti è chiaro che qualunque valore introduci nel codice, non importa se numero, lettera, carattere speciale, è già in binario dal punto di vista del processore visto che lui capisce solo questo linguaggio.

Effettivamente,non ci avevo proprio pensato. Allora,come potrei fare? (in ogni caso,ho provato anche con gli array di costanti,ma vado oltre il limite consentito dalla memoria dinamica...)
Mettiamo ad esempio che ho una lettera, ad esempio "A",in binario è 01000001. Come faccio a decodificarlo in asci e metterlo in una stringa?

XSparter:
Mettiamo ad esempio che ho una lettera, ad esempio "A",in binario è 01000001. Come faccio a decodificarlo in asci e metterlo in una stringa?

Non devi fare nulla, nel momento stesso in cui inserisci 'a' nella stringa questa viene codificata nel suo valore ASCII, esempio pratico se devi creare un array di char che contiene la parola "hello" basta che scrivi:

char MyArray[] = "hello";

Il contenuto dell'array sarà:

MyArray[0] ---> 0x68
MyArray[1] ---> 0x65
MyArray[2] ---> 0x6c
MyArray[3] ---> 0x6c
MyArray[4] ---> 0x6f

Ovvero la codifica ASCII delle singole lettere.

Fin qui ci sono arrivato,il punto è che il tutto,avviene attraverso un sistema creato da me.
Sul primo arduino mando una stringa tramite seriale,quindi viene convertito in binario,ed inviato tramite impulsi laser ad un secondo arduino che memorizza gli stessi identici "bit" di quello che li trasmette,ora questo messaggio,devo convertirlo in lingua umana.
Cioè,io sulla seriale ricevo un messaggio composto di 0 ed 1,che se lo vado a decodificare con qualche tool online,corrisponde alla stringa che ho effettivamente scritto,ma come faccio a far fare quest'operazione all'arduino?

XSparter:
Sul primo arduino mando una stringa tramite seriale,quindi viene convertito in binario

Non devi convertire nulla, i singoli byte della stringa che ricevi sono già codificati in ASCII, devi solo inviarli tramite laser leggendoli bit per bit col metodo che preferisci.
Dal lato ricevente fai l'opposto, ricevi i singoli bit e li ricomponi su un byte che automaticamente conterrà il valore ASCII del carattere inviato.
Se non sei capace di scomporre/ricomporre un byte in bit questo è un altro paio di maniche, se il problema è questo vediamo di risolverlo.
Adesso vado a prepararmi per l'ultimo, ci si sente l'anno prossimo :smiley:

Pensavo fosse chiaro, sono riuscito solo a scomporre,ma non riesco proprio a fare il processo inverso...

Perche non usi la seriale normale (Hardware u D0 e D1 oppure una emulata via software) con cui piloti il Laser e a cui dai i valori del ricevittore.

Cosí con un sempliche Serial.print("A"); mandi i dati e con un semplice variabile = Serial.read() le ricevi e non devi preoccuparti di scomporre o ricomporre.

È comunque da considerare un modo da minimizzare i disturbo di luce sul ricevitore.

Nelle fotocelle fai a te moduli il segnale e usi come ricevitore un ricevitore per infrarosso tipo telecomando a infrarossi.

Ma questo abbassa tanto il Baudrate della trasmissione.

Ciao Uwe

Si lo avevo notato... Comunque è un esperimento,voglio realizzarlo così per puro spirito d'avventura :P. Oramai mi manca solo la decodifica,la comunicazione funziona bene,ache se comunque è abbastanza lento nella trasmissione.

Ciao, io avrei pensato di salvare i bit in un array di char, e poi fare la somma del valore di tutti i bit per ottenere il codice ascii, posto un esempio in C che poi è lo stesso linguaggio di arduino …

#include <stdio.h>

char Decodifica(char *x);
int main()
{
    char Binario[]="01000001";//byte di 8 bit valore ascii 65 'A'
    char carattere;
    carattere=Decodifica(Binario);
    printf("Il carattere e' %c \n",carattere);
    getchar();

    return 0;
}

char Decodifica(char *x){
    
   int i=7;
   int esponente=1;
   char carattere=0;
   for(i=7;i>=0;i--){
       
      carattere+= (x[i]-'0')*esponente;
      esponente*=2; //passo al valore decimale del bit sucessivo
   }
   
   return carattere;
   }

XSparter:
Pensavo fosse chiaro, sono riuscito solo a scomporre,ma non riesco proprio a fare il processo inverso...

Ecco il modo più semplice, ed anche uno dei più efficaci, per scomporre/ricomporre un byte in bit.
La soluzione è usare una union composta da una variabile "char" e una struttura, sempre di tipo char, bit fields.
Nel codice di esempio allegato la variabile "RTX_data.RTByte" contiene il byte da trasmettere, o ricevuto, mentre le variabili da RTX_data.Bits.Bit1 a RTX_data.Bits.Bit8 i singoli bit che compongono il byte.
Se poni un carattere in "RTX_data.RTByte" dentro "RTX_data.Bits.Bitn" trovi i bit che lo compongono e che dovrai inviare tramite laser, viceversa se dentro i vari "RTX_data.Bits.Bitn" poni i bit ricevuti, nel giusto ordine, all'interno di RTX_data.RTByte trovi il carattere ricevuto.
Nell'esempio di codice prima carico "@" in "RTX_data.RTByte" e visualizzo i singoli bit che lo compongono, poi inserisco in "RTX_data.Bits.Bitn" i bit corrispondenti a 'D' e tramite "RTX_data.RTByte" prima li visualizzo come singoli bit, poi come valore esadecimale.

union RTX_b
{
  char RTByte;
  struct PinStato
  {
    unsigned char Bit1: 1;
    unsigned char Bit2: 1;
    unsigned char Bit3: 1;
    unsigned char Bit4: 1;
    unsigned char Bit5: 1;
    unsigned char Bit6: 1;
    unsigned char Bit7: 1;
    unsigned char Bit8: 1;
  } Bits;
} RTX_data;

void setup() {
  Serial.begin(115200);
  RTX_data.Bits.Bit1 = 0;
  RTX_data.Bits.Bit2 = 0;
  RTX_data.Bits.Bit3 = 0;
  RTX_data.Bits.Bit4 = 0;
  RTX_data.Bits.Bit5 = 0;
  RTX_data.Bits.Bit6 = 0;
  RTX_data.Bits.Bit7 = 1;
  RTX_data.Bits.Bit8 = 0;

  Serial.println(RTX_data.RTByte);
  Serial.println();
  
  RTX_data.RTByte = 'D';

  Serial.println(RTX_data.Bits.Bit1);
  Serial.println(RTX_data.Bits.Bit2);
  Serial.println(RTX_data.Bits.Bit3);
  Serial.println(RTX_data.Bits.Bit4);
  Serial.println(RTX_data.Bits.Bit5);
  Serial.println(RTX_data.Bits.Bit6);
  Serial.println(RTX_data.Bits.Bit7);
  Serial.println(RTX_data.Bits.Bit8);
  Serial.println();
  Serial.println(RTX_data.RTByte,HEX);
}

void loop() {

}