Go Down

Topic: RS485 testing (Read 1 time) previous topic - next topic

Standardoil

il progrmma che usi è il primo che hai postato?
se sì devo chiederti di nuovo perché usi contggi così strani nei byte
sono loro la causa degli zeri che hai
Prima legge di Nelson (che sono io):
A parità di risultato
maggiore è il pensiero,
minore il lavoro.
Quindi prima di fare pensa!

bk013

In realtà no, ho fatto la modifica secondo la quale ho un vettore di 8 elementi quanti sono quelli che mi restituisce ogni volta come stringa la bilancia

Standardoil

alla riga 18 assegni una variabile boolean ad un oggetto stream, non va bene
dimensiona una variabile Stream e usala al posto di quella che hai
naturalmente i test li devi fare per Stream !=Null, non per "false"
Prima legge di Nelson (che sono io):
A parità di risultato
maggiore è il pensiero,
minore il lavoro.
Quindi prima di fare pensa!

bk013

Perdonami standardoil ma non mi è chiara questa cosa che mi hai detto.
In pratica quello che ho capito dalle prove fatte è che quando provo a mettere i valori forniti dalla read in un vettore per memorizzarmi il dato non vado in sincrono perchè differente velocità tra lettura e scrittura, quindi prendo un pò a cavolo e mi esce solo spazzatura.
Potreste dirmi per bene come si fa questa cosa? credo sia una stupidaggine, ma mi sta bloccando sul serio.
Grazie

ORSO2001

ciao...allora il protocollo dice:

6 bytes di caratteri ASCII (48..57 valore decimale)
1 byte CR (13 valore decimale)
1 byte LF (10 valore decimale)

questi dati vengono inviai in continuazione...quindi a te basterebbe verificare di ricevere  CR ed LF leggere i 6 bytes successivi e verificare che in chiusura ci siano ancora CR ed LF.

bk013

Grazie per la risposta Orso, ho già provato questa strada, ma il vettore si riempie sempre di zeri oltre i valori utili. E' proprio dalla read al salvataggio il problema. Se faccio la eco come mi è stata consigliata in precedenza stampo tutto come si deve.

ORSO2001

posta il codice dove verifichi CR ed LF che vediamo...e anche quello dove fai l'eco

bk013

Il codice per la eco è esattamente quello che mi è stato postato qualche risposta fa,
quello invece che ho scritto io per la funzione completa è il seguente:



Code: [Select]


float leggi_bilancia() {
  String dati_peso = "";
  bool letto_LF = false;
  bool letto_peso = false;
 
  while(!letto_peso) {
    while(Serial3.available() > 0) {
      char c = Serial3.read();

      if (c == 10 && !letto_LF) {
        letto_LF = true;
        continue;
      }

      if (c == 10 && letto_LF) {
        letto_peso = true;
        break;
      }

      if (letto_LF) {
        dati_peso += c; 
      }
    } 
  }
 

  float peso = dati_peso.toFloat() / 100;

  send_peso(peso);

  return peso;
}


Silente

Scusate se intervengo solo adesso nella discussione.
Da quello che ho capito si sta cercando di leggere il valore restituito da una bilancia.
Essa (verificato?) restituisce il numero in questo modo: invia ogni tot tempo via seriale in codifica ascii sette cifre e due fine messaggio, costituiti da due caratteri sempre uguali.
Quello che si vuole fare è ottenere e salvare il valore da essa restituito, in modo da poterlo usare da un'altra parte del codice.
Corretto?
Se si ho un'idea per continuare che dovrebbe andare, ma ora non la dico per non creare confusione ulteriore.

Standardoil

Ok, èprova questa, scritta al volo, non provata e non compilata, ma dovrebbe andare

Code: [Select]

float leggibilancia(void)
{
   float cifra=0;
   while(1) // bloccante, ma anche la tua lo e'
   {
    if (Serial3.available())
       {
        // un carattere presente
        char cx=Serial3.read();
        if (cx=='\n')
          {
              // uno dei due terminatori, lo ignoro
              continue;
          }
        if (cx==' ')
          {
              //spazio, possibile solo se la stampante sostituisce gli zeri superflui, lo ignoro
              continue;
          }
        if (cx=='\r')
          {
              //l'altro terminatore, fine del lavoro
              return cifra;
              
          }

          // nessuno dei casi precedenti
          cifra=cifra*10+((float)cx-'0')/100;


       }
   }


}


vedi se va, devo uscir di casa, a dopo
Prima legge di Nelson (che sono io):
A parità di risultato
maggiore è il pensiero,
minore il lavoro.
Quindi prima di fare pensa!

ORSO2001

secondo me non va bene...e ti spiego....
imposti una boolean a false
entri in un while perchè questa boolena è false
leggi la seriale e se trovi il LF ....
nella prima if imposti una seconda boolean a true
questa ti fa accedere al secondo if dove imposti la prima boolean (quella del while) a true
aggiungi alla String LF
esci da while e non c'entri più....
devi semore fare attenzione alla sequenza in cui imposti e verifichi le variabili.
prova questo:
Code: [Select]
String numero = "";
boolean LF = false;

void setup() {
  Serial.begin(9600);

}

void loop() {
  char c;
  if (Serial.available()) {
    c = Serial.read();
    if (LF) {
      if (c != 10 && c != 13) {
        numero += c;
      }
    }
    if (c == 10) {
      LF = true;
    }
    if (c == 13 && LF) {
      LF = false;
      float peso = numero.toFloat() / 100;
      Serial.println(peso);
      numero = "";
    }
  }
}

ORSO2001

mi sono dimenticato di scrivere che...come le variabili hanno una loro visibilità (scope) anche le istruzioni come break e continue hanno un loro contesto (tra le graffe in cui sono inseriti) e non si propagano in tutto il programma...quindi quelle due che hai iserito tu hanno poco senso.

Standardoil

Non proprio,
Continue si riferisce esplicitamente al for, while, o do...while appena esterno ad essa
Break in in più anche allo switch appena esterno
Non seguono i blocchi (parentesi graffe) ma proprio i cicli
Prima legge di Nelson (che sono io):
A parità di risultato
maggiore è il pensiero,
minore il lavoro.
Quindi prima di fare pensa!

Standardoil

#43
Apr 17, 2018, 07:02 pm Last Edit: Apr 17, 2018, 07:11 pm by Standardoil
Gli errori nella funzione scritta da bk013 sono differenti
Confonde il carattere 10 col 13
Quindi lavora un LF sì  e uno no
Dopo il primo LF passa per un oggetto stringa, al quale aggiunge di tutto, in particolare i CR
Al secondo LF tenta una conversione da oggetto stringa a float
Non so bene come si comporti la conversione con stringhe sporche, ma sembra che si comporti male
Restituisce il convertito diviso 100
comunque NON è il programma del quale parla nel post 31

La logica della mia invece è  questa:
In un while che non termina mai
Se c'è un carattere
Lo legge
Ignora gli spazi (eventuali zeri soppressi )
Ignora uno dei due terminatori (tanto sono usati in coppia, me ne basta uno)
L'altro terminatore restituisce il risultato del calcolo
Sottinteso: se nessuno dei tre casi precedenti
Deve essere per forza una cifra
Esegui il calcolo parziale (con una routine 'rubata' al K&R)
Il trucco è calcolare in float e dividere subito per 100

Che poi è  vero che come trucco vale poco, lavorare in int e eseguire una sola divisione farei prima
Lasciamo anche allo OP qualcosa
Prima legge di Nelson (che sono io):
A parità di risultato
maggiore è il pensiero,
minore il lavoro.
Quindi prima di fare pensa!

Standardoil

A occhio ho usato più  bit a scriverlo in italiano che in C
Mi sa che oltre a pensare direttamente in algebra complessa mi conviene parlare in C invece che in italiano
Mai che trovi le faccine quando mi servono. ...
Prima legge di Nelson (che sono io):
A parità di risultato
maggiore è il pensiero,
minore il lavoro.
Quindi prima di fare pensa!

Go Up