Interfacciare Arduino nano, ad un programma su pc di rilevamento peso.

Progetto ,sostituire un ripetitore di peso interfacciato ad un programma pc ,con Arduino mini o nano
Ho acquistato , arduino mini e nano, hx 711 e cella di peso.
Ricercando nei forum e negli streck ,sono riuscito ad avere le letture del peso su serial monitor,ma non riesco ad interfacciarlo al programma già esistente.
Ho letto decine di esperimenti,prove e forum, ci sono moltissimi documenti,test e video , ma non ho trovato nulla che mi aiuti a completare il mio progetto.
La stringa di comunicazione dell'oggetto che voglio sostituire è cosi :
Stringa trasmissione continua
STX [S/N][]PPPPPP ETX
STX =(CHRS$(2))inizio trasmissione
[S/N/E] = 1 car. S=peso stabile N=peso in movimento E= errore
[] =1 carattere blank
PPPPPP =6 caratteri peso selezionato
ETX =(CHR$(3)) fine trasmissione.
Ho fatto decine di prove ma sempre con esiti negativi .
-Allego l'ultimo test, che apparentemente su hiper terminal scrive le stesse ,cose , ad eccezione dello spazio, e su serial monitor quasi...
Quel "quasi "fa si che il programma di lettura non funzioni.Allego qua sotto il printscreen del'iper terminal se potete darmi consigli, Vi ringrazio moltissimo.
La parte tutta appiccicata è il mio progresso con arduino,
La parte in ordine è quella fatta dal lettore di peso originale.
-allego il mio sketch caricato su arduino.
Cortesemente non offendetevi se vedete scritte delle corbellerie, mi sento come un bambino che dice le sue prime parole...
Grazie dell'attenzione

rs232_pesa-170613a.zip (13.4 KB)

Scusate sono stato troppo generico.
Questa e' la stringa che devo simulare.

Stringa trasmissione continua
STX [S/N][]PPPPPP ETX
STX =(CHRS$(2)) inizio trasmissione
[S/N/E] = 1 car. S=peso stabile N=peso in movimento E= errore
[] =1 carattere blank
PPPPPP =6 caratteri peso selezionato 
ETX =(CHR$(3)) fine trasmissione.
#/

Questa ] la parte di programma che ho scritto , ma non funziona

define i (hx711.read()/3030-2619)  // valore di lettura da hx711 tarato /3030-2619
Serial.flush();
Serial.print(i);
Serial.write(0);
Serial.write(0x03);
Serial.write(0x02);
Serial.write(83);
#/

.
Grazie dell'aiuto in anticipo

  1. Sistema i tag CODE che .. hai fatto un po' di confusione

  2. NON mi sembra che stai trasmettendo quanto richiesto ...
    ... trasmetti un NULL, poi trasmetti il ETX, poi lo STX ... :o :o :o

Perché non trasmetti esattamente quello che hai scritto nelle specifiche seguendo l'ordine ?

Guglielmo

Ci ho provato ,ma quando visualizzavo in hiper terminal la sequenza era sfalzata, mentre ora è apparentemente simile, allego immagine.
Comunque ci riprovo ed allego i risultati.
Come faccio a dire che lo spazio per la lettura del sensore è di 6 caratteri?
Grazie del consiglio.

Ricorda che puoi visualizzare i dati su un terminale seriale SOLO in HEX dato che alcuni di quei codici possono esere interpretati come comandi da parte dell'emulatore.

Dopo di che ti crei un array di 6 char dove metti i 6 char che devi trasmettere e, con una serie di Serial.write() trasmetti in sequenza il tutto ...

0x02
S | N | E
0x20
XXXXXX
0x03

... piuttosto semplice direi.

Guglielmo

ho provato

#define i (hx711.read()/3030-2619) //  definisco i =valore di lettura da hx711 tarato /3030-2619
Serial.write (0x02);
Serial.write(83);
Serial.write(0);
Serial.print(i);
Serial.write(0x03);
/#

La stringa viene compilata bene ma non viene letto dal programma ,credo perche' manca la quantità di caratteri da aspettare pppppp,
poi cercando in vari blog ed ho provato anche con questa stringa

char String[11] = {0x02 ,0,(hx711.read()/3030-2619),0x03}; //descrivo la stringa
Serial.write ('String');                                             //scrivo la stringa descritta

/#
Purtroppo scrive solo
gggggggg

Sento che ci sono vicino ma non riesco ,per caso ha altri suggerimenti?

Grazie in anticipo,
Francesco

NO, così non va bene perché NON è detto che la Serial.print() trasmetta esattamente 6 caratteri ... se la formula restituisce un numero di 4 cifre la Serial.print() ti trasmetterà solo 4 cifre ...

... per questo ti ho detto che DEVI mettere quel valore in un array di char lungo esattamente 6 caratteri con gli zero davanti se ci sono meno di 6 cifre.

Guglielmo

/#[code/]
char byte[11] = {0x02 ,'s',(hx711.read()/3030-2619),0x03}; //descrivo la stringa

/#
Non so come si fa.
Continuo a leggere parti di programma nei forum,
Ma nessun risultato,può consigliarmi una guida che mi illumini?
Purtroppo non ho esperienza.

  1. byte è una parola riservata, NON puoi usarla per nominarci una variabile !!!

  2. prova a studiarti la sprintf ... non è esattamente banale, dato che è estremamente potente, ma ben usata, risolve svariate complicazioni ...

  3. definisci una stringa C di 11 caratteri (... occore 1 carattere in più per lo 0x00 che viene messo a fine stringa):

char miaStringa[11] = "";
  1. usa la seguente sprintf (fai molta attenzione ai doppi apici, agli spazi ed ai singoli apici che ci trovi!) ...
sprintf(miaStringa, "%c%c %06u%c", 0x02, 's', (hx711.read()/3030-2619), 0x03);
  1. stampala con la seguente Serial.write() ...
Serial.write(&miaStringa[0], 10);

... vedi quello che ti esce in hex :wink:

Guglielmo

Ci siamo quasi ,
ho fatto le letture in ascii come consigliato,

il trasmettitore da emulare scrive cosi

02 53 20 20 20 20 20 31 30 03 .S 10.

Arduino invece scrive cosi'
02 53 20 20 20 20 20 38 36 00 .S 86.
sembra che manchi l' stx finale
ma nel codice mi sembra di averlo messo.
aalego il codice corretto fino a questo punto
/#

char miaStringa[10] = "";
sprintf(miaStringa, "%c%c %6u%c%c",0x02,83,(hx711.read()/3030-2619),0x03);
Serial.write(&miaStringa[0],10); 

[code/]#/

... prova un po' a confrontare cosa ho scritto IO e cosa hai copiato TU nel codice. :smiling_imp:

Non uno, ma ben DUE errori !!!

Guglielmo

Le modifiche rispetto al codice originale ,sono dei tentativi per cercare di capire cosa cambia,
1-Il 10 invece dell'undici, non ha portato modifiche anche se è corretto l'11,e l'ho rimesso a posto.
#/

....
char miaStringa[10] = ""; //   lettura 02 53 20 20 20 20 20 31 30 00
char miaStringa[11] = ""; //   lettura 02 53 20 20 20 20 20 31 30 00
char miaStringa[12] = ""; //   lettura 02 53 20 20 20 20 20 31 30 00
....
/#

2-Ho tolto lo 0 da %06u perchè mette gli 0 prima del numero, e risponde con codice 30 anzichè 20.
#/

char miaStringa[11] = "";
//sprintf(miaStringa, "%c%c %06u%c", 0x02, 'S', (hx711.read()/3030-2619), 0x03);
//lettura02 53 20 30 30 30 30 31 30 00 
sprintf(miaStringa, "%c%c %6u%c", 0x02, 'S', (hx711.read()/3030-2619), 0x03);
//   lettura 02 53 20 20 20 20 20 31 30 00 
..
..
/#

3-ho provato ad aggiungere un carttere %c, ma non cambia nulla e giustamente come suo consiglio lo ho ritolto.
4. ho provato a mettere 9 nela scrittura ed ho capito qualcosa in piu'
#/

char miaStringa[11] = "";
sprintf(miaStringa, "%c%c %6u%c", 0x02, 'S', (hx711.read()/3030-2619), 0x03);
//Serial.write(&miaStringa[0], 10);                               //   lettura 02 53 20 20 20 20 20 31 30 00 
Serial.write(&miaStringa[0], 9);                                  //    lettura 02 53 20 20 20 20 20 31 30
//Serial.write(&miaStringa[0], 11);                               //   lettura 02 53 20 20 20 20 20 31 30 00 00 


/#

Arduino scrive null invece di stx 00 invece di 03 oppure sbaglio a scriverlo io.[/code]

Guarda, basta che prendi questo codice, così come è (... copia e incolla), e lo provi sul tuo Arduno :

void setup() {
  char miaStringa[11] = "";
  //
  delay(500);
  Serial.begin(9600);
  //
  sprintf(miaStringa, "%c%c %6u%c", 0x02, 'S', 31, 0x03);
  Serial.write(&miaStringa[0], 10);
}

void loop() {

}

... ovviamnete ho messo a caso il valore fisso 31 al posto di (hx711.read()/3030-2619), NON avendo io il hx711.

Il risultato è:

02 53 20 20 20 20 20 33 31 03

... prova e vedi.

Guglielmo

Effettivamente,con un numero fisso scrive bene,il problema si pone quando va a leggere da hx711.la libreria che sto usando è <Q2HX711.h>,ma non ci sono riferimenti a me comprensibili.
Ho provato a leggere in asci , senza la stringa , per vedere se sia il comando libreria a richiedere il null,ma emette solo 32 35 0d 0a
Farò delle prove con altre librerie .C'e' ancora qualcosa che sfugge.
Perchè con un numero fisso viene letto stx , e con la lettura da sensori, qualunque cosa scrivi dopo ,e' sempre null?
Ho provato anche a scrivere 'pippo', ma dopo la lettura da hx 711 risponde 00.

Cerca di capire che valore realmente restituisce quella funzione hx711.read() anche con una semplice Serial.print(), perché ... se restituisce cose strane allora è ovvio che poi crea problemi ... ::slight_smile:

Guglielmo

P.S.: La libreria che usi è QUESTA ? ? ?

Si la libreria era quella ,scusate se non la ho postata prima, ne ho usate cosi tante che non ero più sicuro neanche io.
Dopo un giorno intero di librerie ,forum,e compilazioni ho avuto il colpo di "genio",
perchè non scomporre la stringa? e cosi facendo ho finalmente visto la luce.
Il codice non è molto bello, ma funziona . hex 02 53 20 20 20 20 20 36 36 03

/#

char miaStringa[11] = "";
sprintf(miaStringa, "%c%c %6u%c", 0x02, 83, (hx711.read()/4030-2060), 0x03);
Serial.write(&miaStringa[0],9); //con il 9 ometto sia STX  che mi aspettavo , che il NULL di risposta
Serial.write(0x03);                 // aggiungo manualmente l' STX mancante.
delay(10);// attendi per 10 ms
// lettura in hex  02 53 20 20 20 20 20 36 36 03

#/
Davvero tante grazie per i consigli,senza la sua illuminazione non ce l'avrei mai fatta.
Speriamo che il tempo impiegato per portare a termine l'obbiettivo possa facilitare ed aiutare altri apprendisti.
Appena riesco a stabilizzare i valori di taratura posto il progetto completo.
Francesco

Questo è il codice con cui sono riuscito a riprodurre il rilevamento peso su pc ,ho aggiunto dei cicli if (da migliorare ) per fare lo 0 della lettura:
Premo il pulsante e verifico sia con il led che dalla seriale la status del programma,es.: 3_ programma normal)4_ pulsante permuto per fare lo "0"; 2_stato valori negativi diventati positivi.
Sto lavorando sulla possibilita' di leggere il valore all' accensione ed usarlo come punto "0" e da li salire con letture positive,ma stranamente non ho trovato nulla di specifico su google,e ci sto provando riadattando dei pezzi di codice di altri sensori,ancora senza risultato.

#include <Q2HX711.h>
//  accendi il led  e fai lo" 0"appena è premuto il pulsante    
#define LED 13                // LED collegato al pin digitale 13  
#define BUTTON 7              // pin di input dove è collegato il pulsante  
int  val = 0;                 // si userà val per conservare lo stato del pin di input  
#define miaStringa String //stringa personalizzata  
const byte hx711_data_pin = A3;
byte hx711_clock_pin = A2;
Q2HX711 hx711(hx711_data_pin, hx711_clock_pin); 
void setup() {  
 pinMode(LED, OUTPUT);       // imposta il pin digitale come output  
 pinMode(BUTTON, INPUT);     // imposta il pin digitale come input  
Serial.begin(2400);
#define i (hx711.read()/4030-2053) //  definisco i =valore di lettura da hx711 tarato /3030-2619 
}  
 
void loop() {  
//Serial.write(i);
//delay(2000);

#define set_offset ((hx711.read()/3050-2720)+(hx711.read()/3050-2720))
if ((hx711.read()/3050-2720) == 65535){
 Serial.write ('82');                                                          //codice 2 se (hx711.read()/3050-2720) == 65535
char miaStringa[11] = "";
sprintf(miaStringa, "%c%c %6u%c", 0x02, 83,(hx711.read()/hx711.read()-1), 0x03);//il codice 83 è fisso per peso stabile,inquanto non so come si fa a far capire ad arduino se il valore è stabile o mobile
Serial.write(&miaStringa[0],9);
Serial.write(0x03); // aggiungo manualmente l' STX mancante.

delay(5000);
  /// ((hx711.read()/3050-2720)+(hx711.read()/3050-2720));
   }
else  
    val = digitalRead(BUTTON);  // legge il valore dell'input e lo conserva  
    // controlla che l'input sia HIGH (pulsante premuto)  
   if (val == HIGH) {  
   digitalWrite(LED, HIGH);  //accende il led 
   Serial.write ('83');                                                  //codice 3 se ( pulsante premuto e led acceso
      char miaStringa[11] = "";
sprintf(miaStringa, "%c%c %6u%c", 0x02, 83,(hx711.read()/hx711.read()-1), 0x03);//il codice 83 è fisso per peso stabile,inquanto non so come si fa a far capire ad arduino se il valore è stabile o mobile
Serial.write(&miaStringa[0],9);
Serial.write(0x03); // aggiungo manualmente l' STX mancante.
delay(2000);
 }  
 else {  
   digitalWrite(LED, LOW);   //spegne il led  
   Serial.write ('84');                                                  //codice 4 se pulsante off e led spento
  #define ETX 0x03 
  char miaStringa[11] = "";
sprintf(miaStringa, "%c%c %6u%c", 0x02, 83, abs(hx711.read()/3050-2720), 0x03);//il codice 83 è fisso per peso stabile,inquanto non so come si fa a far capire ad arduino se il valore è stabile o mobile
Serial.write(&miaStringa[0],9);
Serial.write(0x03); // aggiungo manualmente l' STX mancante.
//delay(10);// attendi per 10 ms 
} 

}

[code/]

Guarda che:

sprintf(miaStringa, "%c%c %6u%c", 0x02, 83,(hx711.read()/hx711.read()-1), 0x03);//il codice 83 è fisso per peso stabile,inquanto non so come si fa a far capire ad arduino se il valore è stabile o mobile
Serial.write(&miaStringa[0],9);
Serial.write(0x03); // aggiungo manualmente l' STX mancante.

... aggiungi il STX mancante perché SBAGLI la write ... i caratteri da trasmettere sono 10 NON 9 ... 0x02, 83, lo spazio, 6 numeri e lo 0x03 ... totale, 10 caratteri. Se ne trasmetti solo 9 ovviamnete l'ultimo 0x03 non viene trasmesso ::slight_smile:

Guglielmo

Mi spieghi poi a che servono queste #define che non usi ? ? ? :o :o :o

#define miaStringa String //stringa personalizzata

#define i (hx711.read()/4030-2053) //  definisco i =valore di lettura da hx711 tarato /3030-2619

#define set_offset ((hx711.read()/3050-2720)+(hx711.read()/3050-2720))

#define ETX 0x03

... oltretutto, nella prima, usi una parola riservata "String" che è il nome di una classe !

Guglielmo

Molte cose le ho aggiunte nelle varie release e probabilmente qualcuna mi è scappata nella pulizia finale.Questo è il codice base del primo progetto senza if, effettivamente funziona anche senza definire mia stringa .e i,
l'artifizio dei 9 +1 è stato un trucco perchè se lascio 10 caratteri l'ultimoè sempre null e non ho capito perchè

#include <Q2HX711.h>

const byte hx711_data_pin = A3;
const byte hx711_clock_pin = A2;
Q2HX711 hx711(hx711_data_pin, hx711_clock_pin);
void setup(){
Serial.begin(2400);

}
void loop()
{
#define ETX 0x03
char miaStringa[11] = "";
sprintf(miaStringa, "%c%c %6u%c", 0x02, 83, abs(hx711.read()/3050-2720), 0x03);//il codice 83 è fisso per peso stabile,inquanto non so come si fa a far capire ad arduino se il valore è stabile o mobile
Serial.write(&miaStringa[0],9);
Serial.write(0x03); // aggiungo manualmente l' STX mancante.
delay(10);// attendi per 10 ms 
}*/