Ho il seguente problema con un progetto che legge da una cella di carico dei pesi e discerne dal valore del peso per identificare cosa è buono e cosa no. Il problema risiede nel fatto che quando metto o tolgo il "pezzo" sul piatto della cella di carico molte volte anche se lo stato dovrebbe essere ok passa allo stato ko per un istante probabilmente per il tempo di lettura , ho provato con vari delay ma non risolvo il problema . Spero qualcuno possa aiutarmi.
#include <Q2HX711.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include <SD.h>
#include <DS3232RTC.h>
#include <pitches.h>
File Log;
DS3232RTC myRTC;
LiquidCrystal_I2C lcd(0x27, 16, 2);
#define RELAY_RED 3
#define RELAY_GREEN 4
#define THRESHOLD_HIGH 0.2
#define THRESHOLD_LOW 0.1
#define THRESHOLD_LETTURA 3
float peso_target = 5;
const byte hx711_data_pin = 6;
const byte hx711_clock_pin = 7;
float y1 = 98.5; // peso noto
long x1 = 0L;
long x0 = 0L;
float avg_size = 20.0; // amount of averages for each mass measurement
float ratio_1 ;
float ratio_2 ;
float ratio ;
float mass ;
Q2HX711 hx711(hx711_data_pin, hx711_clock_pin);
// buzzer
int melody[] = {
NOTE_C5,
};
int duration = 500;
void setup() {
myRTC.begin();
setSyncProvider(myRTC.get);
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println("Inizializzazione SD card...");
if (!SD.begin(10)) {
Serial.println("Inizializzazione Fallita!");
while (1);
}
Serial.println("Inizializzazione terminata.");
delay(1000);
//configurazione luce output
pinMode(RELAY_RED, OUTPUT);
pinMode(RELAY_GREEN, OUTPUT);
//suono inizializzazione
for (int thisNote = 0; thisNote < 3; thisNote++) {
tone(8, melody[thisNote], duration);
delay(1000);
}
//lcd init
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("COMEST SRL");
lcd.setCursor(0, 1);
lcd.print("fir. ver. 1.5");
delay(3000);
lcd.clear();
calibratura();
}
void calibratura () {
// tare procedure
for (int ii = 0; ii < int(avg_size); ii++) {
delay(10);
x0 += hx711.read();
}
x0 /= long(avg_size);
lcd.print("Caricare il peso noto");
// calibration procedure (mass should be added equal to y1)
int ii = 1;
while (true) {
if (hx711.read() < x0 + 10000) {
} else {
ii++;
delay(2000);
for (int jj = 0; jj < int(avg_size); jj++) {
x1 += hx711.read();
}
x1 /= long(avg_size);
break;
}
}
lcd.clear();
lcd.print("Calibration Complete");
delay (1000);
}
void loop () {
long reading = 0;
for (int jj = 0; jj < int(avg_size); jj++) {
reading += hx711.read();
}
reading /= long(avg_size);
// calculating mass based on calibration and linear fit
ratio_1 = (float) (reading - x0);
ratio_2 = (float) (x1 - x0);
ratio = ratio_1 / ratio_2;
mass = y1 * ratio;
if (mass > 20.0) {
digitalWrite(RELAY_GREEN, HIGH);
digitalWrite(RELAY_RED, LOW);
delay (100);
digitalWrite(RELAY_GREEN, LOW);
digitalWrite(RELAY_RED, LOW);
lcd.clear ();
lcd.print("togliere peso");
} else {
if (mass < 4.0 ) {
digitalWrite(RELAY_GREEN, LOW);
digitalWrite(RELAY_RED, LOW);
lcd.clear ();
lcd.print("INSERIRE PEZZO...");
lcd.print("Raw: ");
lcd.print(reading);
lcd.print(", ");
lcd.println(mass);
} else {
lettura ();
}
}
}
void lettura () {
if (mass >= peso_target - THRESHOLD_LOW && mass <= peso_target + THRESHOLD_HIGH) {
//LETTURA CORRETTA
digitalWrite(RELAY_GREEN, HIGH);
digitalWrite(RELAY_RED, LOW);
lcd.clear ();
lcd.print("OK");
lcd.println(mass);
Log = SD.open("Log.txt", FILE_WRITE);
Log.println("");
Log.print("OK");
Log.print("--");
Log.print(hour());
Log.print(":");
Log.print(minute());
Log.print(":");
Log.print(second());
Log.print("--");
Log.print(day());
Log.print("/");
Log.print(month());
Log.print("/");
Log.print(year());
Log.println("");
Log.close();
} else {
//LETTURA ERRATA, FUORI SOGLIA
lcd.clear ();
lcd.print("KO");
lcd.println(mass);
Log = SD.open("Log.txt", FILE_WRITE);
Log.println("");
Log.print("NG");
Log.print("--");
Log.print(hour());
Log.print(":");
Log.print(minute());
Log.print(":");
Log.print(second());
Log.print("--");
Log.print(day());
Log.print("/");
Log.print(month());
Log.print("/");
Log.print(year());
Log.println("");
digitalWrite(RELAY_GREEN, LOW);
digitalWrite(RELAY_RED, HIGH);
Log.close();
}
}
Per cortesia, come da regolamento, per prima cosa presentati nell'apposita discussione spiegando bene quali esperienze hai in elettronica e programmazione, affinché possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.
Poi leggi attentamente tutto il regolamento, in particolare leggi bene i punti 15.3 e 17.1, e impegnati a rispettarlo.
Ti ricordo che, purtroppo, fino a quando non avrai fatto la presentazione, nessuno ti potrà rispondere, quindi ti consiglio di farla al più presto.
Inoltre, per cortesia, indenta il codice (puoi farlo dall'IDE con CTRL+T) e controlla come hai immesso il codice, perchè c'è qualcosa che non va nel modo "CODE".
Quello credo che significhi semplicemente che il peso è al di fuori dei limiti, per eccesso o per difetto.
Dicci anche da dove hai preso il programma
Sì, ci sono un po' di cose strane come "float avg_size = 20.0;" che, essendo un numero di letture, non può che essere intero e, d'altra parte, poi viene fatto in int()..., ma, si sa, in rete può scrivere chiunque...
Ti è già stato detto, ti chiarisco meglio la cosa ... in conformità al REGOLAMENTO , punto 7, cortesemente edita il tuo post qui sopra (quindi NON scrivendo un nuovo post, ma utilizzando il bottone a forma di piccola matita che si trova in basso del tuo post), seleziona TUTTA la parte di codice e premi l'icona </> nella barra degli strumenti per contrassegnarla come codice.
Inoltre, così com'è, non è molto leggibile ... assicurati di averlo correttamente indentato nell'IDE prima di inserirlo (questo lo si fa
premendo ctrlT su un PC o cmdT su un Mac all'intero del IDE). Per maggiori informazioni ... punto 17.2 del succitato regolamento.
Grazie.
Guglielmo
P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposito thread e sistemato il codice come da regolamento, nel rispetto del citato regolamento nessuno ti risponderà (eventuali risposte verrebbero temporaneamente nascoste), quindi ti consiglio di fare il tutto al più presto.
salve, ho preso parte del codice per comunicare con il modulo hx711 su Github (procedura di taratura e reading dei valori), il resto a tentativi ho scritto quasi tutto io.
si esatto , quando il pezzo è ko sul display compare la scritta NG (no good) seguito dal valore letto del peso e si accende il led rosso del lampeggiatore. Il tutto funziona bene solo che non riesco a risolvere il problema di eliminare letture fantasma (esempio quando si toglie il pezzo o lo si mette magari esercitando una leggera pressione sul piatto) il progetto andrà ulteriormente sviluppato con automazione sempre con Arduino con un manipolatore automatico che preleverà e posizionerà i pezzi in maniera autonoma.
su questo PC non ho lo IDE, ma ho visto alcune cose che potresti mettere a posto nel programma
cominciamo col dire che se il ciclo di lavoro dipende e comanda un manipolatore non hai bisogno del riconoscimento del pezzo presente, il manipolatore quando posa un pezzo sul piatto di lettura avvia anche la lettura con un segnale specifico
a lettura eseguita la bilancia ri-avvia il manipolatore, con un segnale specifico
quindi puoi togliere quella gestione strana delle letture sopra e sotto le soglie per sapere quando il peso c'é
semplicemente il peso c'é quando premi un pulsante specifico (lo stesso pin che verrà comandato dal manipolatore)
poi metti a int il conteggio delle letture, dai che non si può vedere un for comandato da un float
anche la storia di castare un float a double, toglila, che per arduino float e double sono uguali, ma comunque anche fosse la "promozione" di queste cose è automatica
metti a posto le note del cicalino, tu suoni 3 note, ma ne hai dichiarata solo una, le successive due non so da dove possano venire
a parte che se fai il primo punto dovresti uscire dalle canne, ma devi definire meglio i limiti
sotto il tre presumi pezzo assente
oltre il 20 eccesso di peso
pezzo buono 4 entro una certa banda...
ma tra 4 e 20 cosa succede?
Ti hanno gia suggerito quasi tutto, vorrei solo aggiungere un suggerimento per controllare anche condizioni anomale (a grandi linee, non sono un programmatore)
Potresti ad esempio avere condizioni anomale se il manipolatore non portasse l'oggetto sulla bilancia, se nel toglierlo dalla bilancia gli sfuggisse e ci ricadesse sopra, e cosi via, se vuoi fare un'automazione devi considerare anche queste possibilita'.
Sempre come esempio ... nessun pezzo sulla bilancia, azzeri (non so se sia il caso di posizionare anche qualche sensore ottico per controllare che effettivamente non ci sia nulla sulla bilancia, sta a te decidere su questo), poi il manipolatore posiziona il pezzo, primo controllo da fare dopo che il manipolatore ha lasciato andare il pezzo e si e' ritirato, vedere che il peso non rimanga a zero (vorrebbe dire che il manipolatore ha sbagliato e non ha posizionato alcun pezzo sulla bilancia, se pero' ci metti i sensori ottici questo controllo lo possono fare loro), se ok si procede, se no allarme ... da qui si pesa (letture, media, acquisizione valore, controllo se ok o ko), a questo punto esci dalla routine di lettura (non ti serve continuare a leggere il peso quando il pezzo e' in movimento, per cui le letture "fantasma" non sarebbero piu un problema) e segnali se ko o fai le azioni richieste se ok, poi suppongo il manipolatore debba rimuovere il pezzo, dopo la rimozione fai un'ulteriore misura (o piu) per controllare che il peso sia tornato zero, se non e' cosi potrebbe voler dire che il manipolatore non ha tolto il pezzo dalla bilancia per qualche motivo o problema, e segnali l'errore, altrimenti continui (ovviamente se ci fossero sensori ottici, la presenza o meno del pezzo la potrebbero rilevare loro, senza la necessita' delle pesate di controllo presenza/assenza pezzo)
l'implementazione sul manipolatore verrà a breve in un secondo step, per ora ho risolto inviando un segnale da pulsante comandato manualmente, sembra essere tutto ok. E' stato prezioso il vostro contributo soprattutto facendomi pensare al comando proveniente da fonte esterna.