aiuto con le stringhe

Ciao a tutti,
ho una domanda riguardo all'uso delle stringhe con la seriale.
in questo momento sto lavorando con un 74hc595 per pilotare 8 uscite, ho letto che posso comandare singolarmente i vari output inserendo al posto di un valore, "B" seguito da "0" per gli output che voglio spegnere, o "1" per quelli che voglio accendere.
il programma su pc, invia un codice in seriale, che è composto dai soli "-1" e "1", c'è un modo, con le stringhe, per dividere ogni singolo "-1" e "1" in modo che posso confrontarli con quelli della lettura precedente e ottenere lo spegnimento/accendimento singolo di ogni pin?
grazie per l'aiuto, se non mi sono spiegato bene, provo a scrivere qualche sketch

In fase di lettura da seriale, Arduino legge un solo carattere alla volta, quindi basta che durante il ciclo di lettura li inserisci in un vettore e li hai già divisi.

ma che tipo di variabile devo usare, byte? long? word?

Usi il char ... ad esempio per memorizzare 12 caratteri PIU' il terminatore di fine stringa (0x00) dichiarerai :

char miaStringa[13];

ricordando che il primo elemento è l'elemento 0 e l'ultimo, è l'elemento 12 :wink:

Guarda QUI.

Guglielmo

quindi una cosa del genere, nel caso in cui da seriale, io ricevo 01001101, arduino inserisce il primo 0, nel primo valore della stringa (index = 0), '1' con index = 1, 0 con index = 2...

int latchPin = 8;
int clockPin = 12;
int dataPin = 11;
char input[8] = {'0', '0', '0', '0', '0', '0', '0', '0'};
char output[13];

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  Serial.begin(38400);
}

void loop() {
  if (Serial.available() > 0) {
      for (int index = 0; index = 8; index++){
        input[index] = Serial.read();
      }
  }
  output = 'b' + input;
  shiftOut(dataPin, clockPin, LSBFIRST, output); 
}

comunque ricevo un errore durante l'assegnazione del valore alla stringa output, che non riesco a capire. grazie per l'attenzionie

Due cose ...
... la prima .. non sono stringhe della classe String, sono stringhe pure del C quindi ... NON è ammessa la somma :

output = 'b' + input;

ma devi andare ad inserire nella giusta posizione carattere per carattere.

Secondo ...
... ti consiglio di NON usare il ciclo for, ma un indice che incrementi SOLO quando c'è veramente un carattere disponibile.

Tu testi la Serial.available() una sola volta e poi leggi a raffica. Chi ti dice che i caratteri possano essere già disponibili ?

Per OGNI carattere devi verificare che sia disponibile con la Serial.available() quindi ... devi gestire un loop che verifica la disponibilità, se disponibile mette il carattere al posto giusto, incrementa un indice per sapere la posizione successiva e ripete ... fino a quando non sono finiti i caratteri (la cosa migliore è inviare un carattere speciale che indica la fine della trasmissione ... così sei sicuro e non sei legato ad una numero fisso di caratteri)

Guglielmo

Guglielmo, lui ha parlato di programma su PC quindi non credo che possa cambiare i parametri di trasmissione e il protocollo.

PaoloP:
Guglielmo, lui ha parlato di programma su PC quindi non credo che possa cambiare i parametri di trasmissione e il protocollo.

Non ho detto che DEVE cambiare la logica di trasmissione ...
... ho detto che se riuscisse, alla fine dei vari caratteri che trasmette, a trasmetterne UNO in più (es. ETX) ... avrebbe un programma più flessibile che potrebbe usare anche se un domani cambiano le cose ... se invece non può ... dovrà limitarsi a contare gli 8 caratteri per sapere se li ha ricevuti tutti :slight_smile:

Guglielmo

P.S. : E comunque, se su PC il programma l'ha fatto lui ... credo possa anche cambiare qualche minima cosa ... :wink:

io posso modificare il programma che invia da pc a seriale, e ho sistemato il codice arduino, per fermare la registrazione quando riceve da seriale i caratteri 'END', ma non riesco a capire perchè non posso lavorare sulle stringhe input e output

int latchPin = 8;
int clockPin = 12;
int dataPin = 11;
char input[8] = {'0', '0', '0', '0', '0', '0', '0', '0'};
char output[13];
int index = 0;

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  if (Serial.available() > 0) {
    Serial.println(Serial.available());
    while (Serial.available() < 0) {
        index++;
        input[index] = Serial.read();
        if (input[index] = 'END') {
          break;
        }
      }
  shiftOut(dataPin, clockPin, LSBFIRST, output); 
}

Perché quella che tu chiami stringa è un vettore e segue regole diverse dalle "Stringhe".

scusate, ma non ho mai avuto occasione di lavorare sulle stringhe, ho guardato su reference, ma non capisco come posso fare.
adesso ho fatto una funzione per fare in modo che vengano esclusi tutti i valore diversi da 0 e da 1, e per "sommare" ogni bit dell'ultima stringa, adesso come posso "sommare" tutti i valori int in una stringa, inserendo prima la 'b'?
in qualsiasi caso, cosa significa vettore?

int latchPin = 8;
int clockPin = 12;
int dataPin = 11;
char input[13];
char output[13];
char last[13];
int index = 0;
int nReadings;

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  if (Serial.available() > 0) {
    Serial.println(Serial.available());
    while (Serial.available() < 0) {
        index++;
        input[index] = Serial.read();
        if (input[index] = 'END') {
          break;
          nReadings = index;
        }
      }
    char(output);
    char(input);
    calc();
    shiftOut(dataPin, clockPin, LSBFIRST, input); 
}
}

void calc() {
  int n1 = input[1];
  int n2 = input[2];
  int n3 = input[3];
  int n4 = input[4];
  int n5 = input[5];
  int n6 = input[6];
  int n7 = input[7];
  int n8 = input[8];
  int l1 = last[1];
  int l2 = last[2];
  int l3 = last[3];
  int l4 = last[4];
  int l5 = last[5];
  int l6 = last[6];
  int l7 = last[7];
  int l8 = last[8];
  output[1] = n1 + l1;
    if (output[1] < 0) {
      output[1] = 0;
    }
    else if (output[1] > 1) {
      output[1] = 1;
    }
  output[2] = n2 + l2;
    if (output[2] < 0) {
      output[2] = 0;
    }
    else if (output[2] > 1) {
      output[2] = 1;
    }
  output[3] = n3 + l3;
    if (output[3] < 0) {
      output[3] = 0;
    }
    else if (output[3] > 1) {
      output[3] = 1;
    }
  output[4] = n4 + l4;
    if (output[4] < 0) {
      output[4] = 0;
    }
    else if (output[4] > 1) {
      output[4] = 1;
    }
  output[5] = n5 + l5;
    if (output[5] < 0) {
      output[5] = 0;
    }
    else if (output[5] > 1) {
      output[5] = 1;
    }
  output[6] = n6 + l6;
    if (output[6] < 0) {
      output[6] = 0;
    }
    else if (output[6] > 1) {
      output[6] = 1;
    }
  output[7] = n7 + l7;
    if (output[7] < 0) {
      output[7] = 0;
    }
    else if (output[7] > 1) {
      output[7] = 1;
    }
  output[8] = n8 + l8;
    if (output[8] < 0) {
      output[8] = 0;
    }
    else if (output[8] > 1) {
      output[8] = 1;
    }
}

Vettore o Array --> Programmazione in C: vettori

ho capito, quindi se converto tutti i char con char(nome), poi posso usarli come stringhe e posso fare stringa1 = 'b' + stringa2, giusto?

NO ... devi proprio DIMENTICARTI delle String ... immagina che NON esistono ...
... oltretutto, per come sono gestite (allocazione dimanica della memoria), su una MCU piccola come quella che stai usando, sono veramente fonte di innumerevoli problemi !

Guglielmo

Z171:
scusate, ma non ho mai avuto occasione di lavorare sulle stringhe, ho guardato su reference, ma non capisco come posso fare.
....

Allora occorre che ti sudi bene il C e ti guardi BENE il reference ...

La funzione Serial.read() legge UNO ed UN SOLO carattere alla volta, quindi ... non potrà MAI leggere 'END' (... sono 3 caratteri) ok ?

Devi imparare a lavorare con i SINGOLI caratteri ... mettendoli tutti assieme in un "contenitore" che si chiama vettore o array.

Un array altro non è che una serie affiancata di elementi a cui tu accedi sia nel loro insieme (tramite il puntatore all'array) sia elemento per elemento tramite un indice.

Quando dicevo di aggiungere un "fine trasmissione" ed indicavo come esempio ETX ... intendevo il singolo "carattere" ASCII 0x03 :slight_smile:

Tu dovrai all'inizio mettere l'indice a 0 dopo di che dovrai leggere un carattere alla volta, metterlo nel tuo array alla posizione dell'indice, incrementare di uno l'indice e continuare così fino a quando o hai raggiunto il massimo numero di caratteri che puoi ricevere (dipende da quanto fai grande l'array) o hai ricevuto il carattere che, ad esempio, abbiamo definito essere la fine, ovvero ETX, ovvero 0x03 :slight_smile:

Guglielmo

Vedi se così va bene e cerca di capire le modifiche

const int latchPin = 8;
const int clockPin = 12;
const int dataPin = 11;

char input[13];
char output[13];
char last[13];

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  Serial.begin(9600);
  for (int i = 0; i < 13; i++) {
    // inizializza a ZERO tutti i vettori
    input[i] = 0;
    output[i] = 0;
    last[i] = 0;
  }
}

void loop() {
  if (Serial.available() > 0) {
    Serial.println(Serial.available()); // stampa il numero di caratteri in attesa nel buffer della seriale
    int index = 0;
    while (Serial.available() < 0) {
      index++;
      input[index] = Serial.read();
      if (input[index] = '#') break; // non puoi mettere più caratteri perchè Serial.read ne legge solo uno. Ad esempio #
    }
    int nReadings = index - 1; // esclude il carattere #
    calc();
    for (int x = 0; x < nReadings; x++) {
      shiftOut(dataPin, clockPin, LSBFIRST, input[x]);
    }
    for (int i = 0; i < 13; i++) last[i] = input[i];
  }
}

void calc() {
  for (int i = 0; i < 13; i++) {
    output[i] = input[i] + last[i];
    if (output[i] < 0)
      output[i] = 0;
    else if (output[i] > 1)
      output[i] = 1;
  }
}

Grazie mille!!!!! adesso sono riuscito a capire! grazie! ma la 'b' prima del numero binario devo metterla? ora ho capito anche quello, se non mi sbaglio, invia bit dopo bit, giusto?