L'ultimo codice ha qualcosa che non va.
Devo un'attimo ricontrollare la scala dell'egt poi,perché ne ho rimediata un'altra e segna comunque 100°
L'ultimo codice ha qualcosa che non va.
Prova questo per vedere come appare.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the Serial address to 0x27 for a 16 chars and 2 line display
#define misurazioni 5
int k1, k2, k3, k4;
char buffer[6];
void setup() {
Serial.begin (9600);
pinMode (A0, INPUT_PULLUP);
pinMode (A1, INPUT_PULLUP);
pinMode (A2, INPUT_PULLUP);
pinMode (A3, INPUT_PULLUP);
lcd.init(); // initialize the Serial
lcd.backlight();
}
void loop() {
k1 = K(A0);
lcd.setCursor(0, 0);
sprintf(buffer, "1=%dC", k1);
lcd.print(buffer);
k2 = K(A1);
lcd.setCursor(8, 0);
sprintf(buffer, "2=%dC", k2);
lcd.print(buffer);
k3 = K(A2);
lcd.setCursor(0, 1);
sprintf(buffer, "3=%dC", k3);
lcd.print(buffer);
k4 = K(A3);
lcd.setCursor(8, 1);
sprintf(buffer, "4=%dC", k4);
lcd.print(buffer);
//delay (500); // regolare per un corretto aggiornamento Serial
}
int K (int pin) {
int misura = 0;
for (int x = 0; x < misurazioni; x ++) {
misura += analogRead (pin);
}
misura = misura / misurazioni;
misura = map(misura, 0, 1024, 0, 1250);
return misura;
}
L'ho provato,non è male,mi pare che refreshino solo i numeri che variano,però hanno uno strano effetto tremolante mentre lo fanno
Questo è invece il progetto che feci nel 2016
Lo schermo non pulsa,pare funzionare in modo più costante.
Ma vieniamo poi all'altro problema,quello della temperatura non reale(e che magari incide anche sulla lettura un po' tremolante).
Se io collego il modulo EGT da solo (12v e GND) collego una sonda Egt e legge in volta circa 0.10v(quindi intorno ai 20° C°)stabile e perfetto.
Ma appena gli collego un Analog di Arduino(che misurandolo a vuoto ha 5V) il valore va a sbattere a 0.34v(che sono circa 85° anche se Arduino ne segna 100).
Ora non ho capito bene che problema è.
Ottimo, ma viene meglio se nel loop gli fai stampare solo quello che può variare nel tempo.
Ad esempio crea una funzione di nome lcdPrintMaschera che chiami
da dentro la funzione setup().
Ovviamente rimuovi dalla sprintf il numero e = così risparmi per ogni stampa 1 millesimo di secondo.
Viene ancora meglio se eviti di stampare il valore attuale quando questo è
uguale al valore precedente.
Riguardo a 1024 io penso che debba essere 1023 poiché 2^10-bit fa appunto 1024, ma il massimo valore che puoi leggere con analogRead() è appunto 1024-1.
Ciao.
Ho capito solo il 3% di quello hai hai detto :-D.
Però nel primo video(che è quello del codice attuale) non si capisce na minchia con i numeri che variano,oscillano in modo anomalo.
Mentre sul secondo video (quel "famoso" mio progetto di tanti anni fa) i numeri sono stabili
Tutto quello che dici @Maurotec è vero, ma visto il risultato che @tonyevo vuole, penso che risparmiare così tanto tempo non sia necessario e opto anche per utilizzare un ritardo finale.
Un nuovo codice con alcune piccole modifiche:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the Serial address to 0x27 for a 16 chars and 2 line display
#define misurazioni 5
int k1, k2, k3, k4;
char buffer[6];
void setup() {
Serial.begin (9600);
pinMode (A0, INPUT_PULLUP);
pinMode (A1, INPUT_PULLUP);
pinMode (A2, INPUT_PULLUP);
pinMode (A3, INPUT_PULLUP);
lcd.init(); // initialize the Serial
lcd.backlight();
}
void loop() {
k1 = K(A0);
lcd.setCursor(0, 0);
sprintf(buffer, "1=%4uC", k1);
lcd.print(buffer);
k2 = K(A1);
lcd.setCursor(8, 0);
sprintf(buffer, "2=%4uC", k2);
lcd.print(buffer);
k3 = K(A2);
lcd.setCursor(0, 1);
sprintf(buffer, "3=%4uC", k3);
lcd.print(buffer);
k4 = K(A3);
lcd.setCursor(8, 1);
sprintf(buffer, "4=%4uC", k4);
lcd.print(buffer);
delay (750); // regolare per un corretto aggiornamento Serial
}
int K (int pin) {
int misura = 0;
for (int x = 0; x < misurazioni; x ++) {
misura += analogRead (pin);
}
misura = misura / misurazioni;
misura = map(misura, 0, 1023, 0, 1250);
return misura;
}
Per quanto riguarda le letture anomale, se tutto è ben collegato non ho spiegazioni, una piccola deviazione di un certo grado sarebbe spiegabile dalla risoluzione dell'ADC dell'arduino o dalla funzione map, ma non tanto.
Nel codice di @gonpezzi cambia la sprintf così:
sprintf(buffer, "4=%4uC", k4);
Cioè al posto della d ci metti 4u in ogni sprintf.
Ciao.
Non lo sapevo, è la prima volta che uso sprintf e non ho visto dove l'ho studiato.
Corretto il codice del post#26 in base a questo nuovo contributo di @Maurotec .
Fai il conto giusto e ridimensiona il buffer.
Cioè secondo questa stringa di formattazione:
4=%4uC
Ci sono 3 caratteri fissi più un campo di 4 caratteri (4u), dove u sta per unsigned.
4=XXXXC
Quindi io conto 7 caratteri, il buffer deve essere grande 7 + 1.
Nota che se il buffer lo dimensioni poco più grande funziona pure, ma sprechi qualche byte.
Ciao.
Intanto grazie ragazzi per l'impegno che ci state mettendo,domani testo il codice e vediamo che dice,
nel frattempo forse ho ritrovato il codice con il quale avevo fatto quel progetto anni fa,forse è quasi inutile allo scopo,perchè in quel codice si usava la libreria del MAX6675(altro componente che converte il segnale della sonda K in un segnale 0-5v.)
lo metto tanto per
// Librerie:
#include <LiquidCrystal.h>
#include <max6675.h>
// Pin librerie:
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int sensorPin = A0; // definisce il pin al quale applicare il segnale dal modulo AFR
int sensorValue1 = 0; // variable to store the value coming from AFR module
int sensorValue0 = 0; // variable to store the value coming from AFR module
int sensorValue2 = 0; // variable to store the value coming from AFR module
float lagFactor = 40.00; // definizione del fattore di smorzamento della lettura
float AFR = 0; // variable to store the real AFR value
float AFR1 = 0; // variable to store the real AFR value
int ktcSO = 8;
int ktcCS = 9;
int ktcCLK = 10;
MAX6675 ktc(ktcCLK, ktcCS, ktcSO);
void setup() {
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// MESSAGGIO INIZIALE
// imposta la posizione del cursore e scrive un messaggio iniziale sul LCD.
lcd.setCursor(2, 0);
lcd.print("BENVENUTO");
lcd.setCursor(4, 1);
lcd.print("A BORDO");
// APPLICA UN RITARDO DI 5 SECONDI
delay(5000);
// pulisce lo schermo
lcd.clear();
}
void loop() {
// memorizza la letture precedente in una nuova variabile
sensorValue0 = sensorValue2 ;
// legge l'ingresso sul pin 0
sensorValue1 = analogRead(sensorPin);
//calcolo il valore letto in Volt
float voltage0= sensorValue0 * (5.0 / 1023.0);
float voltage1= sensorValue1 * (5.0 / 1023.0);
//CALCOLO DEL VALORE AFR
// applico un filtro al valore letto per evitare i disturbi
sensorValue2 = sensorValue0 + (sensorValue1 - sensorValue0)*(0.40);
// trasforma la lettura nel valore AFR
AFR = map ( sensorValue2 ,0 , 1023 ,1000 ,2000 );
AFR1=AFR/100 ;
//STAMPA SUL DISPLAY DEL VALORE AFR
// posiziono il cursore sulla terza colonna ovvero la n°2, prima riga ovvero la n°0
lcd.setCursor(3, 1);
// stampo il valore AFR sul display:
lcd.print("AFR = ");
lcd.print(AFR1);
//Mi posiziono sulla 3° colonna, seconda riga.
lcd.setCursor(3, 0);
//Stampo il valore EGT sul display:
lcd.print("EGT = ");
lcd.print(ktc.readCelsius());
}
Per quello che riguarda invece il segnale che ha un voltaggio maggiore una volta collegato all'adc di arduino,non può essere invece il pull up che gli crea questo problema?
No il max lavora su protocollo SPI e ricordo abbia una risoluzione di 12-bit.
Ma dimmi una cosa, io ho partecipato alla 24 ore di pergusa nel 2004, a parte il freddo che avevo ai piedi (4*C) non avevo il tempo di guardare il contachilometri figuriamoci guardare la temperatura.
Comunque al poso di visualizzare 1= ecc potresti scrivercelo nella cornice del display, ad esempio con i trasferibili. Così il riferimento 1 2 3 4 sarebbe ben visibile. Sul display ci saranno solo le temperature ben distanziate.
Curiosità: a che serve sapere la temperatura di ogni cilindro e che differenze ci possono essere tra loro.
Ciao.
Allora,diciamo che attualmente utilizzerei lo schermo solo in fase di mappatura dell'auto,l'idea iniziale era di mandare i segnali in ECU tramite CAN,ma ho avuto dei problemini in merito e quindi alla fine mi ero stufato e visto che le sonde erano gia passate,ho pensato intanto di fare uno schermo solo per visualizzare e poi cambiera centralina alla macchina e utilizzero una versione piu evoluta che ha gia 4 ADC in entrata e posso visualizzarle direttamente nel programma di mappatura.
Riguardo l'utilità invece,mi serve per sapere le temperature dei gas di scarico di ogni cilindro singolo,cosi da capire quale è piu magro(quindi EGT piu alto)o piu grasso(EGT piu bassi) e trimmerarli(regolare la carburazione singola di ogni cilindro) per avere un valore quasi identico in ogni cilindro,sopratutto in full gas.
Con le EGT è piu pratico,visto che è difficile e costoso montare 4 sonde lambda wideband
Toglieteli, ormai è chiaro che la stabilità non era nelle letture ma nella stampa sull'LCD.
Avete collegato il GND dell'ETG e il GND di arduino?
Grazie alle informazioni fornite da @Maurotec, ho ottenuto un altro codice, (questo testato sull'LCD), e i risultati sono gli stessi del vostro progetto iniziale.
#define misurazioni 5
int k1, k2, k3, k4;
char buffer[16];
void setup() {
lcd.init(); // initialize the Serial
lcd.backlight();
}
void loop() {
k1 = K(A0);
k2 = K(A1);
lcd.setCursor(0, 0);
sprintf(buffer, "1=%4uC 2=%4uC ", k1, k2);
lcd.print(buffer);
k3 = K(A2);
k4 = K(A3);
lcd.setCursor(0, 1);
sprintf(buffer, "3=%4uC 3=%4uC ", k3, k4);
lcd.print(buffer);
delay (750); // regolare per un corretto aggiornamento Serial
}
int K (int pin) {
int misura = 0;
for (int x = 0; x < misurazioni; x ++) {
misura += analogRead (pin);
}
misura = misura / misurazioni;
misura = map(misura, 0, 1023, 0, 1250);
return misura;
}
Ottimo, ma il buffer deve essere grande n caratteri + 1. Il +1 perché ogni
c string per essere valida deve terminare con '\0'.
"1=%4uC 2=%4uC "
3+4+1+3+4+1 = 16
e non resta spazio per '\0', quindi la stringa di formattazione seguente:
"1=%4uC 2=%4uC"
è di 15 caratteri e quindi il buffer di 15 + 1 è ok.
Ciao.
Si,confermo che a livello elettrico è tutto collegato in modo corretto.
Ho una fonte a 12v. questa fonte alimenta la scheda con i 4 AD,questi 12v vanno anche ad un LM che converte la corrente in 5v che alimenta arduino.
Si sono stabili perché il valore è stabile e non pulisci il campo o il display.
Tutto il problema nasce quando il numero di caratteri di cui è composto il valore si riduce. Quindi ad esempio stampo: 1250
Poi la temperatura scende a 999 e lo stampo. Ciò che vedo però sul display è 9990 lo zero è rimasto li da prima. La sprintf come è stata usata da @gonpezzi risolve il problema.
Ciao.
P.s. se al codice vecchio togli il pull up,la lettura della temperatura è reale
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the Serial address to 0x27 for a 16 chars and 2 line display
prova a metterci tutto
``
È vero, nell'ultimo codice che ho caricato, ho lasciato quella parte dietro con il taglia e incolla.
L'inizio completo prima dell'setup deve essere il seguente:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the Serial address to 0x27 for a 16 chars and 2 line display
#define misurazioni 5
int k1, k2, k3, k4;
char buffer[17];
eccomi,non sono morto,ma fra lavoro e e dopo aver bruciato il quadrimodulo dell'egt ora sono tornato in carreggiata.
Allora testato il codice,diciamo che in linea di massima ci stiamo,cioe siamo arrivati a quello che desideravo,ma se si potesse migliorare la visualizzazione dei numeri staremo al top,perchè anche qui(lo so che rompo la minchia) mi pare che nel cambiare, i numeri(ora i numeri che rimangono fissi non pulsano piu),hanno uno strano effetto dissolvenza ,come se lasciassero un piccolo ghost(non riesco a spiegarmi).
Guardate quello in alto a destra,che è l'unico effettivamente collegato ad una sonda