Lettura frequenza comando pompa bruciatore diesel

Buongiorno a tutti.
Sono nuovo del forum e quasi completamente a digiuno di programmazione.
A livello elettrico/elettronico però ho un po' di dimestichezza.

Vorrei realizzare un mio primo progetto per l'automatizzazione del pilotaggio di un riscaldatore diesel da camper.
Il riscaldatore funziona in maniera completamente autonoma con un suo display che funge anche da cronotermostato e la sua pompa a induzione che pesca dal serbatoio alimentata in PWM a 12V con impulsi che vanno da 1.2Hz a 5Hz.
Il display comunica con la centralina di pilotaggio bruciatore tramite bus proprietario a 3 fili.
Sul display ci sono 5 tasti per il comando ed è dotato di una ricevente 433 a codice fisso per poter essere comandato da un telecomando a 4 canali (On/off/temp up/ e temp down).
Non voglio apportare modifiche invasive al cablaggio ed al bruciatore.

Il mio scopo è innanzitutto è quello di mostrare su di un display il consumo il LT/h ed un contatore che indichi il totale dei litri consumati (magari resettabile).Mi limiterei quindi a leggere gli impulsi che arrivano alla pompa.

Secondo scopo è quello di usare un sensore di temperatura e di gestirmi in maniera autonoma il pilotaggio del bruciatore (che ha il limite di lavorare ON/OFF spegnendosi una volta arrivato in temperatura piuttosto che modulare la portata della pompa).
Questo non sarebbe un problema se il ciclo di accensione e spegnimento non avesse un consumo esagerato di corrente (10A/h x 4/5 minuti per il riscaldamento della candeletta di accensione) che nell'economia di un camper alimentato da una batteria servizi da 100Ah è un grande consumo.
La gestione del pilotaggio la farei tramite il telecomando 433MHz cablando i tastini ad Arduino piuttosto che clonando il segnale ed utilizzando un modulo 433TX).

Per ora con arduino leggere un sensore di temperatura , visualizzarlo nel serial monitor , mettere dei limiti ed accendere un leD se superate certe soglie ci sono riuscito.

Quello che non riesco a fare (o non del tutto) è leggere la frequenza di un impulso.
Non capisco se il comando PulseIn non funzioni per via della "lentezza" del segnale simulato da un tastino.
Ho provato anche contare gli impulsi leggendo direttamente il tastino come Analog IN e ci riesco (ho recuperato uno sketch da qualche parte).Mi chiedo se questo sketch è in grado di leggere un numero non intero nel periodo.
Probabilmente dovrei campionare gli impulsi in un periodo più lungo di 1 secondo (magari 10) per poter avere un range di 12-50 impulsi nei 10scondi.Voi cosa dite?

L'impulso a 12V della pompa lo prenderei con un partitore di tensione.
Una volta estratta la frequenza (o numeri di impulsi per secondo) riesco a tirarmi fuori il consumo orario moltiplicando per il dosaggio di ogni impulso che è fisso (0,02ml).

per ora ho "scritto" questo :

int button = A1;
int buttonState;
int oldButtonState;
int counter;
unsigned long startTime;
unsigned long ritardo = 1000;
bool firstClick;

void setup() 
{                
 Serial.begin(9600);
 pinMode(button, INPUT);     

 firstClick = true;

 oldButtonState = LOW;
 counter = 0;
}

void loop() 
{
 buttonState = digitalRead(button);
 
 if (buttonState == HIGH)
 {
   // ho premuto il pulsante
   
   if (oldButtonState == LOW)
   {
     oldButtonState = HIGH;

     if (firstClick)
     {
       startTime = millis();
       firstClick = false;
     }
     
     counter++;
   }
 }
 else oldButtonState = buttonState;
 
 unsigned long elapsedTime =  millis() - startTime;
 if (elapsedTime > ritardo)
 {
   firstClick = true;
   Serial.print("Impulsi contati: ");
   Serial.println(counter, DEC);
   counter = 0;
 }
}

qualcuno può darmi un aiuto.

Ciao grazie

Ciao, ti chiedo cortesemente di editare il tuo post e racchiudere il codice tra i tag CODE come previsto dal regolamento (il primo pulsante in alto a sinistra della toolbar < / >). Per editare il post non usare il quick edit ma usa l'opzione edit presente nel menù che appare premendo l'opzione More... in basso a destra.
Grazie

la sua pompa a induzione che pesca dal serbatoio alimentata in PWM a 12V con impulsi che vanno da 1.2Hz a 5Hz.

Questa descrizione non ha senso. I PWM non cambiano frequenza.

Se fai prove con un pulsante, devi mettere in parallelo al pulsante un condensatore da 100~470nF, altrimenti i falsi contatti del pulsante (detti rimbalzi) producono letture multiple.
Con pulseIn leggi il periodo positivo e il periodo negativo del segnale in microsecondi, poi fai i dovuti calcoli.
pulseIn

Grazie Datman per il sugerimento.
Effettivamente avevo notato errori saltuari nella lettura.

Un segnale PWM (Pulse Width Modulation) può avere frequenza variabile, se si varia solo la larghezza della parte (semiperiodo) a livello alto o solo quella della parte a livello basso.

Buonasera a tutti,
sono andato un pelo avanti col progettino.
Il conteggio sembra funzionare correttamente soprattutto se allungo il tempo di lettura a 10 secondi invece che a 1.
Ho collegato anche un display 2x16 che riesco ad accendere e visualizzare le scritte.

Non riesco però a visualizzare il dato del consumo che mi ricavo moltiplicando il conteggio impulsi * 0,02(dosaggio/impulso) * 6 (volte x10 secondi di campionamento)* 60 (per ottenere il consumo orario).

Sul display mi visualizza sempre 720 (che ad occhio ha a che fare con 60x6x0,02).
Se invece del consumo provo a far visualizzare solo in conteggio visualizza un numero corretto.

Non capisco se sbaglio la sintassi della moltiplica o è una questione di definizione tipologia variabili INT o FLOAT (che non mi è ancora ben chiaro..sopratutto se si possono fare oprazioni tra variabili diverse).

Ecco lo sketch

[/#include <LiquidCrystal.h>

const int rs=12, en=11, d4=5, d5=4, d6=3, d7=2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
int button = A1;
int buttonState;
int oldButtonState;
int counter;
float consumo;
unsigned long startTime;
unsigned long ritardo = 10000;
bool firstClick;

void setup() 
{ 
  lcd.begin(16, 2);
  lcd.print(" Diesel Heater");  
  lcd.setCursor(0,1);
  //lcd.print("   Controller");        
  Serial.begin(9600);
  pinMode(button, INPUT);     

  firstClick = true;

  oldButtonState = LOW;
  counter = 0;
}

void loop() 
{
  buttonState = digitalRead(button);
  
  if (buttonState == HIGH)
  {
    // ho premuto il pulsante
    
    if (oldButtonState == LOW)
    {
      oldButtonState = HIGH;

      if (firstClick)
      {
        startTime = millis();
        firstClick = false;
      }
      
      counter++;
    }
  }
  else oldButtonState = buttonState;
  
  unsigned long elapsedTime =  millis() - startTime;
  if (elapsedTime > ritardo)
  {
    firstClick = true;
    //Serial.print("Impulsi contati: ");
    //Serial.println(counter, DEC);
    consumo = (counter*0,02*6*60);
    //Serial.println(consumo);
    lcd.setCursor(0,1);
    lcd.print("Cons. Lt/h:");
    lcd.setCursor(13,1);
    lcd.print(consumo);
    counter = 0;
  }
}code]

Qualcuno può illuminarmi per favore?
ciao e grazie

Roberto

Robypolo16v:

    consumo = (counter*0,02*6*60);

Ah, il maledetto comma operator :slight_smile:
I numeri float vanno scritti con il punto.
Poi siccome 0.02660 è un valore costante, tanto vale moltiplicare counter per 7.2

Comunque se invece di misurare la frequenza, che costringe a lunghi tempi di attesa con un errore abbastanza grande (circa il 10%) si misurasse il periodo, si avrebbero diverse letture al secondo con una precisione maggiore (circa 0.2%)