Accensione CDI con arduino uno: HELPPPP!

Ciao a tutti,
ho bisogno di un consiglio da veri esperti.
Ho realizzato una centralina cdi per accensione motore 2 tempi: sono due circuiti di cui uno analogico e uno digitale.
Quello analogico è un boost converter che eleva la tensione di alimentazione (12v) a 380v e serve per generare la scintilla alla bobina di accensione (cdi).
Quello digitale è arduino uno che prende il segnale dal sensore pm-l24 ottico a forcella (alimentato coi 5v dell'arduino) sull'ingresso digitale e su un altra uscita digitale manda il segnale ritardato in funzione dei giri motore.
Provando il tutto a banco, col generatore di funzioni che simula il sensore ho la scintilla alla candela fino ad alti regimi (15000 rpm).

Allora attacco il sensore e ci faccio passare in mezzo qualcosa e vedo che la scintilla viene generata: bene.
Monto tutto sul motore e accendo: al minimo il motore gira bene, appena salgo di giri inizia a borbottare e non funziona regolarmente.
Allora nel codice inserisco un lampeggio di un led in modo che quando sto generando la scintilla il led stia 500ms acceso e 500ms spento, così so che il codice sta girando bene: da qui infatti noto che quando il motore inizia ad andare male il lampeggio non è più costante e addirittura il led a volte è rimasto sempre acceso o sempre spento.

Premetto che arduino è ultra filtrato sia sulla alimentazione che sui pin digitali ad esempio dei dip switch che utilizzo, inoltre è schermato ed è tutto contenuto dentro un contenitore in alluminio: infatti a banco funziona molto bene senza problemi, ma sul motore sembra che dia i numeri..

Aspetto risposte sagge :slight_smile:

Grazie

Se vuoi aiuti devi postare schema e codice.... così è impossibile aver idea di ciò che succede!!

void setup()
{//Serial.begin(9600);
   // initialize Timer1
    cli();          // disable global interrupts
    TCCR1A = 0;     // set entire TCCR1A register to 0
    TCCR1B = 0;     // same for TCCR1B
 
    // set compare match register to desired timer count:
    // turn on CTC mode:
    TCCR1B |= (1 << WGM12);
    TCCR1B &= ~(1 << WGM10);
    TCCR1B &= ~(1 << WGM11);
    // Set for prescaler 8:
    TCCR1B |= (1 << CS11);
    TCCR1B  &= ~(1 << CS12);
    TCCR1B  &= ~(1 << CS10);
    // enable timer compare interrupt:
    TIMSK1 |= (1 << OCIE1A);
    // enable global interrupts:
    sei();

  attachInterrupt(counterInterrupt, counterISR, RISING);
  
  pinMode(PUIN,INPUT); // ingresso segnale pick-up
  pinMode(PUOUT,OUTPUT); // uscita segnale pick-up ritardato

  pinMode(ledRun,OUTPUT); // led indicazione modalità configurazione (lampeggio) e modalità run (fisso)

  pinMode(SWITCH1,INPUT);
  pinMode(SWITCH2,INPUT);
  pinMode(SWITCH3,INPUT);
  pinMode(SWITCH4,INPUT);
  digitalWrite(ledRun, LOW); 
  digitalWrite(SWITCH1, HIGH);
  digitalWrite(SWITCH2, HIGH);
  digitalWrite(SWITCH3, HIGH);
  digitalWrite(SWITCH4, HIGH);
  
  digitalWrite(PUIN, LOW);
  digitalWrite(PUOUT, LOW);
 
  s[0]=digitalRead(SWITCH1); // 10
  s[1]=digitalRead(SWITCH2); // 11
  s[2]=digitalRead(SWITCH3); // 12
  s[3]=digitalRead(SWITCH4); // 13

 void loop()
{
////////////////////////////////////////////////////////////////////////////////// 

    // Modalità RUN
    
      // controllo se durante la fase run è stata cambiata la configurazione e se si allora riavvio per poterla caricare
      if(i==0) {if(digitalRead(SWITCH1)!=s[0]) Riavvia();
                  else i++;}
      if(i==1) {if(digitalRead(SWITCH2)!=s[1]) Riavvia();
                  else i++;}
      if(i==2) {if(digitalRead(SWITCH3)!=s[2]) Riavvia();
                  else i=0;}              
                  
       // se nessuna configurazione è selezionata non fa partire il motore e il led run lampeggia lentamente
      if(s[0]==HIGH && s[1]==HIGH && s[2]==HIGH )
      {
        NotRun=HIGH; digitalWrite(ledRun, HIGH); delay(500); digitalWrite(ledRun, LOW); delay(500); digitalWrite(PUOUT, 0);
      }  
      
      // Se la configurazione non è presente, il motore parte comunque (senza applicare ritardi) e il led run lampeggia velocemente.
      if(freq_max[5]==0)  
      {
        if((millis()-last>=250) && RUN)
        {
          digitalWrite(ledRun, 1);
          last=millis(); 
          RUN=0;
        }
        if((millis()-last>=250) && !RUN)
        {
          digitalWrite(ledRun, 0);
          last=millis();
          RUN=1;  
        }  
      }
      
      if(counter.ready()) // leggo i valori dall'array delta_t_tab
      {
        if(counter.hertz()<0 || counter.hertz()>250) freq=50;
        else freq=counter.hertz();
        dt=(int)(delta_t_tab[freq]/tick);
        
        switch (var) 
            {
              case 1:
                var=2;
                last=millis();
                break;
              case 2:
                digitalWrite(ledRun, HIGH); 
                if(millis()-last>=500) {var=3; last=millis();}
                break;
              case 3: 
                digitalWrite(ledRun, LOW); 
                if(millis()-last>=500) {var=2; last=millis();}
                break;
            }
      }
      //if(freq_max[5]!=0) {digitalWrite(ledRun, 1);}
         
//////////////////////////////////////////////////////////////////////////////// 
      
//////////////////////////////////////////////////////////// Regolazione durata impulso PUOUT
  if(flag)
  {
    if(micros()-width>=pulse_width) {digitalWrite(PUOUT, LOW); flag=LOW; val=HIGH;}
  } 
////////////////////////////////////////////////////////////  
	
}

void counterISR()
{ 
  if(NotRun==HIGH) val=LOW;

  if(val&&!flag)
  {
    counter.poll();
    if(dt>24) 
    {
      OCR1A = dt-24;
      TCCR1B |= (1 << WGM12);
      TCCR1B &= ~(1 << WGM10);
      TCCR1B &= ~(1 << WGM11);
      TCCR1B |= (1 << CS11);
      TCCR1B &= ~(1 << CS12);
      TCCR1B &= ~(1 << CS10); 
    }
    else {digitalWrite(PUOUT, HIGH); flag=HIGH; width=micros();}
  }
  
}

ISR(TIMER1_COMPA_vect)
{
  TCCR1A = 0;     // set entire TCCR1A register to 0
  TCCR1B = 0;
  
  if(NotRun==HIGH) val=LOW;
  digitalWrite(PUOUT, val); 
  flag=HIGH; 
  width=micros();

}

ho tralasciato la definizione delle variabili e qualche calcolo, comunque funziona e l'ho già testato diverse volte.
Appena posso metto lo schema

Ti consiglio di armarti di notebook, mettere qualche Serial.write nel codice, e controllare cos'è che non va....

Le prove effettuate le ho fatte con strumentazione da laboratorio.
Se metto delle serial print il codice mi si rallenta molto e perdo il sincronismo tra il segnale che mi arriva e quello che genero.

Dal punto di vista hardware alimentavo arduino con la tensione 12v della batteria, che è soggetta a fluttuazioni costanti in base al numero di rpm.
Lo facevo perchè pensavo che avendo il proprio regolatore da 5v, fluttuazioni dell'ordine di 3v non gli facessero paura. Per scrupolo ho messo un regolatore 7809 tra batteria e lui e in uscita ad esso un filtro di modo comune più due condensatori che non fanno mai male.
Devo ancora provarlo così; ho provato però attaccato al sensore, facendo passare un disco forato in mezzo alla fotocellula il sensore funziona bene e la scintilla generata va molto bene.

Ci saranno i fantasmi di mezzo....boh.

Le prove al banco le hai fatte con la candela attaccata o hai solo verificato che partisse l'impulso tramite un led?
Monitorare via seriale un'applicazione di questo tipo è una pessima idea.
Se non sono problemi indotti dai disturbi (anche le vibrazioni indotte al sensore sono da valutare) è probabile veramente che si tratti di fantasmi :grin:

Le ho fatte ovviamente a candela collegata che sparava EMI ovunque e tutto era liscio come l'olio.
Rimane solo da valutare le vibrazioni del sensore...come fare?

Se hai l'oscilloscopio puoi provare a vedere quanto è pulito il segnale.
Quante acquisizioni fai per ogni rivoluzione?
O fai solo acquisizione sul pms?