Tester/Controller Iniettori Benzina

Salve a tutti, premetto che ho provato a cercare tra molti forum oltre a quello ufficiale e con diverse soluzioni, ma niente che si adatti "velocemente" al mio obiettivo.

Millis, multiblink...ect

Venendo al punto, molto tempo fa avevo costruito un semplice tester o driver per iniettori benzina, unica pecca era che si basava, e tutt'ora si basa sulla funzione "delay" per impostare il tempo di apertura e chiusura dell'iniettore/i, regolabili tramite due potenziometri separatamente; questo però influenza tutto il sistema arduino, generando ritardi quando i tempi impostati sono molto lunghi, specialmente nella visualizzazione dell'LCD.

Quello che volevo realizzare ora, era un sistema che mantenga le stesse caratteristiche ma senza l'uso della funzione "delay" per impostare i tempi dell'iniettore, in modo magari anche di aggiungere qualche altra funzione, per esempio rilevare se l'iniettore è difettoso (tipico corto circuito),
inoltre mi piacerebbe riuscire a pilotarne quattro in sequenza, come accade nelle auto in normale funzionamento.
Avevo altresì pensato di pilotare gli iniettori da un circuito basato su NE555 e lasciare ad arduino solo il compito di lettura della frequenza o qualcosa di simile, ma se potessi eviterei.

Allego il codice:

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);
int inj1 = 3;
int TjON, TjOFF = 0;

void setup() {
  pinMode(inj1, OUTPUT);
  lcd.begin(16, 2);
}

void loop() {

  int TjON = analogRead(0);
  int TjOFF = analogRead(1);
  TjON = map(TjON, 0, 1023, 1, 30);
  TjOFF = map(TjOFF, 0, 1023, 20, 140);

  lcd.setCursor(0, 0);
  lcd.print("TjON =");
  lcd.print(TjON);
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print("TjOFF=");
  lcd.print(TjOFF);
  lcd.print(" ");

  digitalWrite(inj1, HIGH);
  delay(TjON);
  digitalWrite(inj1, LOW);
  delay(TjOFF);
  
}

Grazie a tutti.

Qualcosa del genere:

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);
int inj1 = 3;
int TjON, TjOFF = 0;

unsigned long Timer1 = 0;
unsigned long Timer2 = 0;

void setup() {
  pinMode(inj1, OUTPUT);
  lcd.begin(16, 2);
}

void loop() {

  int TjON = analogRead(0);
  int TjOFF = analogRead(1);
  TjON = map(TjON, 0, 1023, 1, 30);
  TjOFF = map(TjOFF, 0, 1023, 20, 140);

  lcd.setCursor(0, 0);
  lcd.print("TjON =");
  lcd.print(TjON);
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print("TjOFF=");
  lcd.print(TjOFF);
  lcd.print(" ");

  if (Timer1 == 0) Timer1 = millis();
   
  if (millis() - Timer1 < TjON) {
    digitalWrite(inj1, HIGH);
  }
  else {
    digitalWrite(inj1, LOW);
    if (Timer2 == 0) Timer2 = millis();
    if (millis() - Timer2 < TjOFF) {
      digitalWrite(inj1, HIGH);
    }
    else {
      digitalWrite(inj1, LOW);
      Timer1 = 0;
      Timer2 = 0;
    }
  }

}

Grazie mille Cyberhs per il consiglio, era più o meno quello che volevo provare con millis, ma senza successi, purtroppo il risultato è appena sufficiente, cioè l'iniettore "ronza", e non credo sia un bene, inoltre osservando i due sketch all'oscilloscopio noto che con il tuo sketch ho l'uscita del pin 3 con un duty cycle strano...

Cerco di spiegarmi con un esempio:

Mio Sketch forma d'onda: ­|­¯||­¯||­¯| variabile sia su on che su off

Tuo Sketch forma d'onda: ­¯­|­¯­­¯|­¯­¯­||­¯­¯|­¯­¯|­¯­¯||­¯ quasi sempre con uscita alta e picchi di off che credo s siano la causa del ronzio, dato che sotto una certa
frequenza l'iniettore "vibra" senza aprire

Da cosa credi sia dovuto?

Ciao e grazie

Dal mio sketch errato, prova così:

#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);
int inj1 = 3;
int TjON, TjOFF = 0;

unsigned long Timer1 = 0;
unsigned long Timer2 = 0;

void setup() {
  pinMode(inj1, OUTPUT);
  lcd.begin(16, 2);
}

void loop() {

  int TjON = analogRead(0);
  int TjOFF = analogRead(1);
  TjON = map(TjON, 0, 1023, 1, 30);
  TjOFF = map(TjOFF, 0, 1023, 20, 140);

  lcd.setCursor(0, 0);
  lcd.print("TjON =");
  lcd.print(TjON);
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print("TjOFF=");
  lcd.print(TjOFF);
  lcd.print(" ");

  if (Timer1 == 0) Timer1 = millis();
   
  if (millis() - Timer1 < TjON) {
    digitalWrite(inj1, HIGH);
  }
  else {
    digitalWrite(inj1, LOW);
    if (Timer2 == 0) Timer2 = millis();
    if (millis() - Timer2 > TjOFF) {
      Timer1 = 0;
      Timer2 = 0;
    }
  }

}

Ciao Cyberhs, e grazie per la pronta risposta.
Ho provato il tuo ultimo sketch, e l'iniettore non vibra più...
Ora non riesco più a modificare a piacimento e in modo flessibile i tempi di apertura, mi consente solo quattro parametri di lavoro: 7,5;15;27,5;32,5 ms approssimativi.
Sinceramente per lo scopo lavorativo è perfetto e più che ottimale, tanto che credo adotterò il tuo codice come aggiornamento del mio precedente sketch grezzo :slight_smile:

Ora ho due domande:
millis da quanto so è il tempo che arduino registra dall'inizio del programma... è quindi un valore sempre crescente per tutta la durata di lavoro di arduino? è resettabile o associabile ad una variabile?

Cercando tra i vari siti mi imbattei in un codice un pò avanzato per me, mi ci vorrebbe un po' per tradurlo nel complesso, ma per la gestione degli iniettori recitava così:

void pulseINJ1(void)
{
    if (( injqty > 0) && (mcs1 - mcs1Last > (inj1State ? INJ1_ON : INJ1_OFF))) {
        digitalWrite(INJ1_PIN, inj1State = !inj1State);
        mcs1Last = mcs1;
    }
}

Può essere una buona alternativa?

Riporto la fonte del progetto:

Ciao e grazie ancora :slight_smile:

Ora non riesco più a modificare a piacimento e in modo flessibile i tempi di apertura, mi consente solo quattro parametri di lavoro: 7,5;15;27,5;32,5 ms approssimativi.

Non capisco bene cosa vuoi dire: come fai ad esprimere, ad esempio, il ritardo di 7.5 ms quando il millis ti restituisce solo interi?

Devi usare la funzione micros(), come è stato fatto nello sketc che hai indicato.

A proposito di questo, sembra una versione iniziale e non definitiva e si può fare di meglio a livello di codice.

Sia la millis che la micros hanno dei limiti dovuti al fatto che sono espressi con un unsigned long, quindi il conteggio al massimo arriva a 4.294.967.295 dopo il quale ripartono da 0.

Per la millis questo comporta che dopo circa 49 giorni di funzionamento (4.294.967,295 secondi) il contatore si azzera, mentre per la micros questo avviene dopo circa 1 ora (4.294,9 secondi).

Se il tuo test non dura più di un ora, puoi usare tranquillamente micros, ovviamente considerando i microsendi al posto dei millisecondi.

Scusa forse non sono stato chiaro, volevo dire che, osservando all'oscilloscopio l'uscita del pin 3 ho quei quattro valori fissi di apertura dell'iniettore, TjON assume solo quei quattro valori tramite il potenziometro.

Poco importa, quello che cercavo in realtà era un "là" iniziale diverso dalle mie idee per sbloccarmi;
userò questo tuo ultimo sketch come nuovo driver, ma quello che mi incuriosiva era riuscirne a pilotarne quattro in sequenza, ma dal tuo punto di partenza credo che proverò aggiungere qualche timer in più ed aggiungere altre tre sequenze di "if".

Grazie mille Cyberhs

Tempo fa il forum ha aiutato un utente a realizzare una centralina per il controllo di un motore marino.
Forse trovi qualche spunto per il tester degli iniettori.
--> centralina accensione motore - Software - Arduino Forum

Il codice è sparso nelle varie pagine.

Maechen:
Salve a tutti, premetto che ho provato a cercare tra molti forum oltre a quello ufficiale e con diverse soluzioni, ma niente che si adatti "velocemente" al mio obiettivo.

Millis, multiblink...ect

Venendo al punto, molto tempo fa avevo costruito un semplice tester o driver per iniettori benzina, unica pecca era che si basava, e tutt'ora si basa sulla funzione "delay" per impostare il tempo di apertura e chiusura dell'iniettore/i, regolabili tramite due potenziometri separatamente; questo però influenza tutto il sistema arduino, generando ritardi quando i tempi impostati sono molto lunghi, specialmente nella visualizzazione dell'LCD.

Quello che volevo realizzare ora, era un sistema che mantenga le stesse caratteristiche ma senza l'uso della funzione "delay" per impostare i tempi dell'iniettore, in modo magari anche di aggiungere qualche altra funzione, per esempio rilevare se l'iniettore è difettoso (tipico corto circuito),
inoltre mi piacerebbe riuscire a pilotarne quattro in sequenza, come accade nelle auto in normale funzionamento.
Avevo altresì pensato di pilotare gli iniettori da un circuito basato su NE555 e lasciare ad arduino solo il compito di lettura della frequenza o qualcosa di simile, ma se potessi eviterei.

Allego il codice:

#include <LiquidCrystal.h>

LiquidCrystal lcd(8, 9, 10, 11, 12, 13);
int inj1 = 3;
int TjON, TjOFF = 0;

void setup() {
  pinMode(inj1, OUTPUT);
  lcd.begin(16, 2);
}

void loop() {

int TjON = analogRead(0);
  int TjOFF = analogRead(1);
  TjON = map(TjON, 0, 1023, 1, 30);
  TjOFF = map(TjOFF, 0, 1023, 20, 140);

lcd.setCursor(0, 0);
  lcd.print("TjON =");
  lcd.print(TjON);
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print("TjOFF=");
  lcd.print(TjOFF);
  lcd.print(" ");

digitalWrite(inj1, HIGH);
  delay(TjON);
  digitalWrite(inj1, LOW);
  delay(TjOFF);
 
}




Grazie a tutti.

Maechen:
Salve a tutti, premetto che ho provato a cercare tra molti forum oltre a quello ufficiale e con diverse soluzioni, ma niente che si adatti "velocemente" al mio obiettivo.

Millis, multiblink...ect

Venendo al punto, molto tempo fa avevo costruito un semplice tester o driver per iniettori benzina, unica pecca era che si basava, e tutt'ora si basa sulla funzione "delay" per impostare il tempo di apertura e chiusura dell'iniettore/i, regolabili tramite due potenziometri separatamente; questo però influenza tutto il sistema arduino, generando ritardi quando i tempi impostati sono molto lunghi, specialmente nella visualizzazione dell'LCD.

Quello che volevo realizzare ora, era un sistema che mantenga le stesse caratteristiche ma senza l'uso della funzione "delay" per impostare i tempi dell'iniettore, in modo magari anche di aggiungere qualche altra funzione, per esempio rilevare se l'iniettore è difettoso (tipico corto circuito),
inoltre mi piacerebbe riuscire a pilotarne quattro in sequenza, come accade nelle auto in normale funzionamento.
Avevo altresì pensato di pilotare gli iniettori da un circuito basato su NE555 e lasciare ad arduino solo il compito di lettura della frequenza o qualcosa di simile, ma se potessi eviterei.

Allego il codice:

#include <LiquidCrystal.h>

LiquidCrystal lcd(8, 9, 10, 11, 12, 13);
int inj1 = 3;
int TjON, TjOFF = 0;

void setup() {
  pinMode(inj1, OUTPUT);
  lcd.begin(16, 2);
}

void loop() {

int TjON = analogRead(0);
  int TjOFF = analogRead(1);
  TjON = map(TjON, 0, 1023, 1, 30);
  TjOFF = map(TjOFF, 0, 1023, 20, 140);

lcd.setCursor(0, 0);
  lcd.print("TjON =");
  lcd.print(TjON);
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print("TjOFF=");
  lcd.print(TjOFF);
  lcd.print(" ");

digitalWrite(inj1, HIGH);
  delay(TjON);
  digitalWrite(inj1, LOW);
  delay(TjOFF);
 
}




Grazie a tutti.

l'elettronica delle auto non e troppo semplice come la vuoi far tu :smiling_imp:

tempi di iniezione ed anticipo sono in continua variazione modificati da i sensori principali dell'auto,

temperatura aria (debimetro) temperatura motore, sonda lambda etc....