Pages: [1]   Go Down
Author Topic: Ancora problemi con stringhe e la porta seriale di Arduino  (Read 1466 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 87
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ciao a tutti ragazzi, qualche giorno fa ho creato un topic nel quale cercavo di salvare dei dati su EEPROM. Adesso mi sono accordo che per poter andare a salvare più dati (ricevuti da porta seriale) devo cercare di leggere delle stringhe per poi manipolarle ed estrarre i dati da queste.

Cercando e ricercando sul forum ho trovato qualche codice, e alla fine sono riuscito a scrivere questo
Code:
int led=13;
String stringa;                                        // stringa ricevuta

void setup() {
  pinMode(led, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  stringa = "";                                     // azzera stringa

  while (Serial.available() > 0) {              // ricezione da Serial Monitor
    stringa += char(Serial.read());               // aggiungi carattere alla stringa
  }

  stringa.trim();                                   // elimina spazi iniziali e finali
  stringa.toLowerCase();                            // converti in minuscolo

  if (stringa == "accendi") digitalWrite(led, HIGH);
  else if (stringa == "spegni") digitalWrite(led, LOW);
}
perchè non funziona??non riesco proprio a capirlo
Logged

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Stampa il contenuto di stringa sulla seriale prima del confronto.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 87
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

niente...ho provato a inserire
Code:
Serial.print(stringa);
subito dopo il ciclo while ma non mi scrive niente...
Logged

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Appunto.

Ecco perché il test successivo fallisce.

Devi battezzare un carattere come "fine delle trasmissioni" a riempier la stringa fino a che non vedi quel byte.
A quel punto puoi fare il confronto per capire che comando hai ricevuto.
Logged

Genova
Offline Offline
Faraday Member
**
Karma: 38
Posts: 3280
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

se non hai un carattere di chiusura potresti usare

Code:
while (Serial.available() > 0) {              // ricezione da Serial Monitor
    stringa += char(Serial.read());               // aggiungi carattere alla stringa
 if string.indexof di stringa == accendi >>>  esegui ....
  }

Logged

no comment

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sì, ma in quel caso dovrebbe anche preoccuparsi di togliere il comando identificato dalla stringa di accumulo, altrimenti quella cresce fino a far resettare il micro.
Nel caso "classico" del carattere di terminazione la cosa è più semplice perché basta "svuotare" la stringa di accumulo ogni volta che lo si riceve.

Comunque sarebbe meglio usare un char[], non String.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 87
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Allora ragazzi ho messo un carattere di fine stringa che io ho indicato con il punto. Quindi ogni qual volta che dovrebbe trovare questo benedetto punto la lettura dovrebbe interrompersi.
Ad esempio se io mando tramite seriale la parola "accendi." appena vede il punto dovrebbe interrompere l'acquisizione. Il codice che ho scritto è questo:
Code:
int led=13;
String stringa;                                        // stringa ricevuta

void setup() {
  pinMode(led, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  stringa = "";                                     // azzera stringa

  while (Serial.available() > 0 && (Serial.read() != '.')) {    // ricezione da Serial Monitor
    stringa += char(Serial.read());               // aggiungi carattere alla stringa
  }
  //delay(4000);
  //Serial.print(stringa);

  stringa.trim();                                   // elimina spazi iniziali e finali
  stringa.toLowerCase();                            // converti in minuscolo

  if (stringa == "accendi") digitalWrite(led, HIGH);
  else if (stringa == "spegni") digitalWrite(led, LOW);
}
ma ancora non funzionaaaa smiley-sad

cmqe ritornando alla questione char[] o string ho preferito scegliere la soluzione delle string perchè innazi tutto gli operatori di stringa sono molto più semplici, cioè per catenare ho visto che basta utilzzare la sintassi
stringa1 + stringa 2...ecc...

poi per quanto riguarda i char[] ho visto che questi devono essere dichiarati e dimensionati a priori e il bello è che non so quanto sarà lunga questa stringa...

almeno queste sono nozioni che ho imparato nel giro di una settimana avendo arduino davanti...se ci sono scappatoie fatemi sapere!sono qui per imparare smiley-grin
Logged

Genova
Offline Offline
Faraday Member
**
Karma: 38
Posts: 3280
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sì, ma in quel caso dovrebbe anche preoccuparsi di togliere il comando identificato dalla stringa di accumulo, altrimenti quella cresce fino a far resettare il micro.
Nel caso "classico" del carattere di terminazione la cosa è più semplice perché basta "svuotare" la stringa di accumulo ogni volta che lo si riceve.

Comunque sarebbe meglio usare un char[], non String.

ok  allora
Code:
while (Serial.available() > 0) {              // ricezione da Serial Monitor
    stringa += char(Serial.read());               // aggiungi carattere alla stringa
    if string.indexof di stringa == accendi >>> 
     {
       string="";
       esegui ....
     }
  }
Logged

no comment

Offline Offline
Jr. Member
**
Karma: 0
Posts: 87
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ma la mia soluzione con il punto nel ciclo while non va bene??
Logged

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ma la mia soluzione con il punto nel ciclo while non va bene??

No, perché chiami Serial.available() ad un ritmo rapidissimo, mentre i caratteri impiegano un tempo molto più lungo per arrivare.
Devi uscire dal ciclo di ricezione quando hai ricevuto il carattere di fine riga (il punto va benissimo) oppure dopo un certo timeout, oppure quando hai ricevuto un certo numero massimo di caratteri ma il punto ancora non l'hai visto.

Poi devi mettere un tetto alla lunghezza del buffer di accumulo (cioè la String) altrimenti rischi di saturare la RAM.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 87
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ragazzi non ci crederete ma ho risolto. Ma adesso voi dovete risolvermi questo dubbio fra questi due codici. Il primo non funziona, mentre il secondo si. Ma in sostanza sono identici!!Come mai???
Code:
void loop() {

  stringa = "";                                     // azzera stringa

  while (Serial.available() > 0) {    // ricezione da Serial Monitor  
    delay(10);
    if (char(Serial.read()) ==  '.'){
      break;
    }
    stringa += char(Serial.read());               // aggiungi carattere alla stringa
  }

  stringa.trim();                                   // elimina spazi iniziali e finali
  stringa.toLowerCase();                            // converti in minuscolo

  if (stringa == "accendi") digitalWrite(led, HIGH);
  else if (stringa == "spegni") digitalWrite(led, LOW);
}

mentre il secondo che funziona è questo
Code:
void loop() {

  stringa = "";                                     // azzera stringa

  while (Serial.available() > 0) {    // ricezione da Serial Monitor  
    delay(10);
    char c = Serial.read();
    if (c == '.'){
      break;
    }
    stringa += c;               // aggiungi carattere alla stringa
  }

  stringa.trim();                                   // elimina spazi iniziali e finali
  stringa.toLowerCase();                            // converti in minuscolo

  if (stringa == "accendi") digitalWrite(led, HIGH);
  else if (stringa == "spegni") digitalWrite(led, LOW);
}

?????????
Logged

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Che cosa vuol dire

Code:
(char(Serial.read()) ==  '.')

Esiste forse una funzione char() ? Non capisco come possa compilare una roba del genere... ?
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 87
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok...capito.quindi era un problema di compilazione. Pensavo esistesse una funzione di quel tipo.
Comunque tuxduino volevo chiederti se a questo punto come hai suggerito conviene meglio utilizzare un char[].
Per poterlo riempire sicuramente devo utilizzare un ciclo, ma poi per poterci smanettare sopra?quali funzioni posso utilizzare?
Ad esempio per concatenare, cercare dei caratteri, sostituirli valgono esattamente le stesse funzioni del C?
Devo importare le librerie string.h??
Logged

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Stiamo parlando di C-string, cioè char[] con la convenzione che la stringa è termianta da un byte nullo.
Tutte le funzioni della famiglia str* funzionano su questa convenzione.
Per aggiungere caratteri tieni un contatore e accedi direttamente a stringa[cnt], per il confronto usa strcmp().
Logged

Pages: [1]   Go Up
Jump to: