Go Down

Topic: Lettura seriale dati su arduino Aiuto (Read 2093 times) previous topic - next topic

SukkoPera

Non riesci a capire cosa, di preciso? Una stringa è un vettore di char in C, e si copia con strcpy() o strncpy(). Si possono saltare i primi N caratteri semplicemnte sommando N al puntatore alla stringa.
"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

nid69ita

#16
Apr 11, 2016, 04:20 pm Last Edit: Apr 11, 2016, 04:23 pm by nid69ita
Occhio però che anche la strcpy() si aspetta di trovare il fine stringa NULL  '\0'   (terminatore)
Tanto vale usare direttamente la strtol() per convertire dal char+1 come dicevo prima.  
Ma come detto do @astro,  DEVI avere la stringa memorizzata in un array di char e terminata da carattere di fine stringa.

@dany perdona ma quell'esempio VB   non è ammissibile!   In vb ragioni su una stringa completa mentre in Arduino con la serial.read() ricevi 1 char alla volta. Quindi, nel tuo codice, dove hai messo i dati ricevuto ? Posta un benedetto pezzo di codice ARDUINO, del vb chissefrega.  la strcpy fa tipo la mid() ma scimiottare il VB in C è un non sense.
my name is IGOR, not AIGOR

astrobeed

Ma come detto do @astro,  DEVI avere la stringa memorizzata in un array di char e terminata da carattere di fine stringa.
Esatto, il primo problema da risolvere è avere un array di char terminato con 0x00, in alternativa conoscere l'esatta lunghezza, perché dalla seriale, non importa se hardware o software, ottieni solo una sequenza di byte, tipicamente uno per volta, nell'ordine di ricezione.
Come ho già spiegato i modi più semplici per procedere sono inserire un carattere univoco, durante la trasmissione, che identifica la fine del pacchetto dati, oppure usare un time out, le alternative sono decisamente più complesse da gestire, sopratutto con wiring in mezzo alle scatole che lascia zero controllo sulla seriale.
Scientia potentia est

SukkoPera

In verità mi pare di capire che lui abbia sempre stringhe di un numero fisso di caratteri. Per cui basta leggerne altrettanti dalla seriale, quindi processare. Per quello ho usato strncpy() nel mio suggerimento, senza preoccuparmi troppo della terminazione della stringa.
"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

danyevo

Mi dispiace ma non ci capisco più niente esiste un esempio completo per farmi capire come funziona?
lasciamo perdere i miei esempi e cominciamo da capo.
allora mettiamo che io ho un arduino con collegato 10 sensori di temperatura e via seriale devo inviare i dati  ad un altro arduino, come faccio a leggerli e inviarli ad un display che mi scrive tutte e 10 le temperature separate?
Vi avverto che non sono un veterano vi ringrazio per la pazienza

SukkoPera

#20
Apr 11, 2016, 04:57 pm Last Edit: Apr 11, 2016, 04:59 pm by SukkoPera
Quello che stavi facendo secondo me va bene. Puoi inviare sequenze fisse di 5 caratteri, dove il primo è una lettera che identifica il sensore e i restanti sono la temperatura in centesimi di grado, tipo:

A1234 -> Sensore A 12.34 °C
D5678 -> Sensore D 56.78 °C

Il "problema" è che sulla seriale hai uno stream continuo di caratteri, senza inizio né fine. Ma se manteniamo la lunghezza delle stringhe fissa la gestione è semplice: tieni un buffer di 5 caratteri, lo riempi e quindi lo processi con il codice che ti ho detto prima, o usando strtol() o atoi() come suggerito da nid. In questo caso però il buffer deve essere di 6 caratteri e l'ultimo deve essere sempre '\0'.

Se non ti è chiaro qualcosa sulla gestione delle stringhe, cerca un tutorial e dagli un'occhiata. Poi chiedi per quel che ancora resta ancora oscuro, eventualmente.

Prova ad abbozzare uno sketch che fa questo e postalo.
"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

danyevo

Allora ritorniamo al tuo esempio:


io ricevo dalla seriale a111 b222 c333 d444

salvo in una variabile che si chiama: dr
poi ò str1 la variabile che memorizza la lettera e str2 la variabile che memorizza la cifra

mi puoi sviluppare il tuo esempio con il nome di queste variabili

char str2[MAX_STR];

if (str1[0] == 'a') {
  strncpy (str2, str1 + 1, 5);
}

SukkoPera

Tutto dipende dal tipo di dr. Assumo che sia una stringa stile C, quindi:

Code: [Select]
#define MAX_STR 4

char dr[MAX_STR];


Abbiamo quindi array di dimensione fissa di 4 caratteri, che dovrai riempire con quel che arriva dalla seriale. Una volta riempiti:

Code: [Select]
char str1, str2[MAX_STR] = {0};

str1 = dr[0];
strncpy (str2, dr + 1, MAX_STR - 1);


Nota che str1 è un singolo carattere, non una stringa. str2 è invece una stringa, e sarà anche terminata col classico '\0';
"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

danyevo

#23
Apr 11, 2016, 05:57 pm Last Edit: Apr 11, 2016, 06:00 pm by danyevo
Sarebbe così:


Code: [Select]

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
#define MAX_STR 4
char dr[MAX_STR];

int str2 ;
int vr;
void setup() {
 
Serial.begin(9600);
}

void loop() {
 
 vr = Serial.read();
 

char str1, str2[MAX_STR] = {0};
str1 = dr[0];

if (str1 == "a") {
strncpy (str2, dr + 1, MAX_STR - 1);

 
  lcd.setCursor(0, 0);
  lcd.print("T1:");
  lcd.setCursor(3, 0);
  lcd.print(str2);
}
 
 

char str1, str2[MAX_STR] = {0};

str1 = dr[0];

if (str1 == "b") {


strncpy (str2, dr + 1, MAX_STR - 1);

  lcd.setCursor(0, 2);
  lcd.print("T2:");
  lcd.setCursor(3, 2 );
  lcd.print(str2);
  } 
}


SukkoPera

Ci sono un po' di errori... Hai provato a compilare?

1. La lettura della seriale è totalmente sballata. Dai un'occhiata qua.

2. str2 è dichiarata due volte con due tipi diversi.

3. Quando confronti str1 devi usare apici singoli, essendo un singolo carattere e non una stringa.

4. L'indentazione e la formattazione fanno schifo, usa la formattazione automatica dell'IDE.
"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

danyevo

corretto alcuni errori ho provato a compilare ma mi da:

Arduino:1.6.7 (Windows 7), Scheda:"Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

C:\Users\Server\AppData\Local\Temp\arduino_389944218c90a290adf55133051df5e7\sketch_apr11a.ino: In function 'void loop()':

sketch_apr11a:31: error: redeclaration of 'char str1'

   char str1, str2[MAX_STR] = {0};

        ^

sketch_apr11a:16: error: 'char str1' previously declared here

   char str1, str2[MAX_STR] = {0};

        ^

sketch_apr11a:31: error: redeclaration of 'char str2 [4]'

   char str1, str2[MAX_STR] = {0};

                          ^

sketch_apr11a:16: error: 'char str2 [4]' previously declared here

   char str1, str2[MAX_STR] = {0};

              ^

C:\Users\Server\AppData\Local\Temp\arduino_389944218c90a290adf55133051df5e7\sketch_apr11a.ino: At global scope:

sketch_apr11a:46: error: expected declaration before '}' token

 }

 ^

exit status 1
redeclaration of 'char str1'

  Questo report potrebbe essere più ricco di informazioni con
  "Mostra un output dettagliato durante la compilazione"
  abilitato in "File > Impostazioni"



Code: [Select]

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
#define MAX_STR 4
char dr[MAX_STR];
int vr;
void setup() {

  Serial.begin(9600);
}

void loop() {

  vr = Serial.read();


  char str1, str2[MAX_STR] = {0};
  str1 = dr[0];

  if (str1 == 'a') {
    strncpy (str2, dr + 1, MAX_STR - 1);


    lcd.setCursor(0, 0);
    lcd.print("T1:");
    lcd.setCursor(3, 0);
    lcd.print(str2);
  }



  char str1, str2[MAX_STR] = {0};

  str1 = dr[0];

  if (str1 == 'b') {


    strncpy (str2, dr + 1, MAX_STR - 1);

    lcd.setCursor(0, 2);
    lcd.print("T2:");
    lcd.setCursor(3, 2 );
    lcd.print(str2);
  }
}
}


SukkoPera

#26
Apr 11, 2016, 07:23 pm Last Edit: Apr 11, 2016, 07:23 pm by SukkoPera
Ascoltami: metti un attimo da parte questa cosa, e investi un po' di tempo a studiarti il C e le sue basi. Senza offesa, ma sicuramente così farai prima ad ottenere qualcosa, piuttosto che mettendo insieme cose a caso di cui capisci poco o niente.
"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

danyevo

Si sicuramente lo farò ma adesso ho urgentemente bisogno di questo progetto te ne sarei grato se mi aiuti a finirlo.. sono disperato veramente mi serve con urgenza.
Grazie

paulus1969

Una via più semplice:

Code: [Select]

int a;
int b;

if (Serial.available())
 {
    a = Serial.read();
    b = Serial.parseint();
 }

// a questo punto hai in a il codice del carattere ed
// in b il valore numerico


if (a == 'a')
  {
    faiqualcosa (b);
    a =0;
  }

if (a == 'b')
 {faiqualcosaltro (b);
   a = 0;
  }

ecc
ecc


danyevo

Ok grazie mille veramente paulus1969 sono riuscito a trovare la soluzione con il tuo esempio.
Grazie a tutti per la pazienza :)

Go Up