Pulizia registro

Salve,

esiste un'istruzione per pulire il registro della porta seriale?

Grazie

Quale registro ? Le UART hanno una serie di registri all'interno della MCU ... ma penso che tu stai parlando d'altro ... cosa devi fare esattamente ?

Guglielmo

Ho spiegato il problema nel post denominato "Sensore di pressione".

In buona sostanza ricevo dei valori sballati dal dispositivo "sensore" e pensavo che sulla porta seriale, dove i dati vengono depositati per essere letti dal PC, ci potessero essere, assieme ai dati corretti, anche altri che non lo sono.

Quindi, tra una lettura e l'altra, sempre che ciò abbia valenza, potrei pulire la porta seriale dal suo contenuto.

Ok, quindi la cosa che tu vuoi fare è svuotare il "buffer di ricezione della seriale".

NO, non c'è una funziona fatta apposta per questo, ma bastano poche righe di codice:

while (Serial.available()) {
   Serial.read();
   delay(5);
}

Guglielmo

P.S. Se si fa riferimento a qualche cosa scritto in un altro thread, si mette il link alla discussione e si spiega esattamente il problema.

Quindi il mio sketch potrebbe essere così :

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int pressione = 0;

void setup() {
  lcd.begin(16, 2);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  Serial.begin(9600);
  digitalWrite(8, HIGH);
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);
}

void loop() 
{
  if (Serial.available())
   Serial.read();           // svuota il buffer
        delay(5);
   {
    char ch = Serial.read();

    if (ch=='1')		// valvola di Carico
     digitalWrite(8, HIGH);
    else if (ch=='A')
     digitalWrite(8, LOW);

    else if (ch=='2')		// valvola di Scarico
     digitalWrite(9, HIGH);
    else if (ch=='B')
     digitalWrite(9, LOW);

    else if (ch=='3')		// toglie la corrente
     digitalWrite(10, HIGH);    // collegamenti relè diversi
    else if (ch=='C')
     digitalWrite(10, LOW);
 
   }
pressione = analogRead(A0); // carica il buffer
lcd.setCursor(0, 0);
lcd.print("Temperatura: ");
lcd.setCursor(0,1);
lcd.print(pressione);
Serial.println(pressione);
/// ******
}

non so se mettere un altro ritardo dove ho piazzato gli asterischi.

NO, lo svuotamento del buffer si fa normalmente alla fine di una ricezione errata per eliminare i restanti caratteri. Esempio, in una trasmissione in cui ho un buffer di 32 caratteri e mi aspetto che essi arrivino terminati da un carattere terminatore, se ricevo 32 caratteri, ma NON il terminatore, c'è chiaramente stato un errore e quindi devo smettere di ricevere e buttare tutto quello che segue sino a quando il buffer non è vuoto, per poi poter iniziare una nuova ricezione.

Se lo fai come lo hai messo tu ... butti tutto quelo che arriva, anche le cose esatte che tu stai aspettando !

Invece di fare tutti quegli IF in cascata, usa una bella switch/case e, nel caso "default:", ovvero il caso di un carattere NON tra quelli che ti aspetti, semplicemente NON fai nulla (ovvero lo scarti).

Guglielmo

Poco tempo fa, avevo scritto lo sketch con l'uso di "swict/case" qualcuno qui mi ha consigliato di usare gli "If".

Pensavo di valutare la qualità del dato in ingresso da PC, è vero, è meglio farlo qui, ci provo.

Ho riscritto lo sketch, non so se la sintassi è esatta specialmente quella inerente l’uso di “switch”, confido in un piccolo aiuto.

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int pressione = 0;
int conta = 0;

void setup() {
  lcd.begin(16, 2);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  Serial.begin(9600);
  digitalWrite(8, HIGH);
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);
}

void loop() {

  conta = conta + 1  

  if (Serial.available())

      switch (ch) {

          case 1:
          digitalWrite(8, HIGH);

          case "A":
          digitalWrite(8, LOW);
          break;

          case 2:
          digitalWrite(9, HIGH);
          break;

          case "B":
          digitalWrite(9, LOW);
          break;

          case 3:
          digitalWrite(10, HIGH);

          case "C":
          digitalWrite(10, LOW);
          break;
          }  // switch

     lcd.setCursor(0, 0);
     lcd.print("Temperatura: ");
     lcd.setCursor(0,1);

     pressione = analogRead(A0);
     pA = pressione * 1.5
     PB = pressione * 0.5

     if (conta == 1){
         p1 = pressione
     }
   
     switch (pressione) {

        case pA:
        case pB:
        Serial.println(p1);
        lcd.print(p1);
        Serial.read();
        delay(5);
        break;
   
        default:
        Serial.println(pressione);
        lcd.print(pressione);
        delay(5);
        break;

     }  // switch

  }   // if

     if (conta == 6){	// sesta rilevazione in un minuto
         conta = 0
     }
}   //void loop

Grazie.

ciao

per quel che riguarda il primo switch:

-non dichiari cosa sia quella variabile ch e nemmeno cosa contiene.

-se ch è un CHAR allora per valutarlo devi mettere apici singoli, non doppi.

-mancano almeno 3 o 4 break.

per il secondo switch: direi che non può funzionare.

In generale: prova almeno a compilare… qualche errore salta fuori.

ciao
pippo72

>Dinamo2016: Ti ricordo che il parametro dello switch DEVE essere un valore intero ...

Dal Kernighan & Ritchie (la Bibbia :smiley: ) :

The switch statement is a multi-way decision that tests whether an expression matches one of a number of constant integer values, and branches accordingly.

switch (expression) {
case const-expr: statements
case const-expr: statements
default: statements
}

Each case is labeled by one or more integer-valued constants or constant expressions. If a case matches the expression value, execution starts at that case. All case expressions must be different. The case labeled default is executed if none of the other cases are satisfied. A default is optional; if it isn't there and if none of the cases match, no action at all takes place. Cases and the default clause can occur in any order.

Guglielmo

l’ho riscritto ancora,

int pressione = 0;
char ch;

void setup() {
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  Serial.begin(9600);
  digitalWrite(8, HIGH);
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);
}

void loop() { 

  if (Serial.available())
    {
      switch (ch)
      {
          case '1':
          digitalWrite(8, HIGH);
          break;

          case 'A':
          digitalWrite(8, LOW);
          break;

          case '2':
          digitalWrite(9, HIGH);
          break;

          case 'B':
          digitalWrite(9, LOW);
          break;

          case '3':
          digitalWrite(10, HIGH);
          break;

          case 'C':
          digitalWrite(10, LOW);
          break;
      }  // switch

      pressione = analogRead(A0);
      Serial.println(pressione);
      delay(100);  // devo provare

   }   // if
   
}   //void loop

il Comando > delay(100); < presuppone il ritardo di cento ms., non so se va bene, devo provare.

Spero ora funzioni!

... ma il carattere dentro a "ch" (... ovvero ... Serial.read()) ce lo vuoi mettere prima di fare lo switch/case o no ? ? ? :smiling_imp:

Guglielmo

Mi devo ancora a leggere attentamente questo i listati di questo linguaggio :

int pressione = 0;

void setup() {
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  Serial.begin(9600);
  digitalWrite(8, HIGH);
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);
}

void loop() { 

  if (Serial.available())
    {

      char ch = Serial.read();      

      switch (ch)
      {
          case '1':
          digitalWrite(8, HIGH);
          break;

          case 'A':
          digitalWrite(8, LOW);
          break;

          case '2':
          digitalWrite(9, HIGH);
          break;

          case 'B':
          digitalWrite(9, LOW);
          break;

          case '3':
          digitalWrite(10, HIGH);
          break;

          case 'C':
          digitalWrite(10, LOW);
          break;
      }  // switch

      pressione = analogRead(A0);
      Serial.println(pressione);
      delay(100);  // devo provare

   }   // if
   
}   //void loop