Allumage a avance variable

Bonjour

je souhaite réalisé un allumage a avance variable pour intégré sur un solex (un solex de compétition)

j'ai fais quelque recherche et je suis tombé sur ca : AEPL-duino, allumage programmable à 3 +1 composants. Arduino Programmable electronic ignition

j'ai donc modifier le programme pour avoir une courbe pour un moteur 2t

se qui me donne se programme

(il est sur mon drive car trop long)

ce que j'aurais voulu savoir c'est si ce programme pouvait être utilisé sur un attiny85
voila a quoi le schéma devrait ressembler

l' arduino pro mini servira pour affiché le régime du moteur sur un écran
S1 représente le rupteur d'origine calé 45° avant le point mort haut
je n'ai pas besoin de l'emetteur bluetooth car porté trop court et manque de place

merci d'avance
alexis

Salut,
j'ai déjà exploité cet allumage qui est au point.
Je ne vois pas l'intérêt de le transposer sur un attiny85.
Et en lisant l'article à fond, le concepteur donne la réponse à votre question.
Pour éviter un autre problème, il est préférable d'acheter l'IGBT en France.
Tous ceux en provenance de Chine actuellement sont hors caractéristiques et j'ai été obligé de rajouter un driver d'aide à la commutation.

ba le truc c'est que je suis très limité en place, la totalité arduino (ou attiny) + IGBT +batterie + rupteur + condensateur doivent logé a la place de l'allumage d'origine et la batterie doit être capable de faire fonctionné le système 6h minimum (c'est pour faire des endurance)
donc un attiny aiderai a réduire la place du circuit

Bonjour

aujourd’hui je voulais réalisé les premiers test de l’allumage sauf que au moment de téléverser il m’indique une erreur : expected ‘}’ before numeric constant

avez vous une idée de la source de ce bug ?

merci d’avance
alexis

code partie 1 :

#include "TimerOne.h"
char ver[] = "Version du _11-11-16 ";


int Na[] = 0, 500, 800, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 11000, 12000, 13000, 14000, 15000,16000 0;//t/*mn vilo

int Anga[] = {0, 0 , 10 , 30  , 30 ,  29,  29,  28,  28,   25,   20,  15,   10,   7, 5, 4, 3, 2, 1 0};
int Ncyl = 2;           //Nombre de cylindres, moteur 4 temps.Multiplier par 2 pour moteur 2 temps
const int AngleCapteur = 45; //Position en degrès avant le PMH du capteur(Hall ou autre ).
const int CaptOn = 0;  //CapteurOn = 1 déclenchement sur front montant (par ex. capteur Hall "saturé")

const int Dwell = 3; // Dwell =3 pour simuler un allumage à vis platinées: bobine alimentée 2/3 (66%) du cycle



const int Multi = 0;//1 pour multi-étincelles
const int N_multi = 2500; //t/mn pour 4 cylindres par exemple

int Nb[] = {0,  3100, 0};   //Connecter D8 à la masse
int Angb[] = {0,   12,   0};

int Nc[] = {0,  6100,  0};    //Connecter D9 à la masse
int Angc[] = {0,  16,   0};

 
int tFlash = 100; //Durée du flash en µs 100, typique

const int Nplancher = 500; // vitesse en t/mn jusqu'a laquelle l'avance  = 0°
const int trech  = 3000;//temps de recharge bobine, 3ms= 3000µs typique, 7ms certaines motos
const int unsigned long Dsecu  = 1000000;//Securite: bobine coupee à l'arret apres Dsecu µs
int delAv = 2;//delta avance,par ex 2°. Quand Pot avance d'une position, l'avance croit de delAv

const int Bob = 4;    //Sortie D4 vers bobine.En option, on peut connecter une Led avec R=330ohms vers la masse
const int Cible = 2;  //Entrée sur D2 du capteur, R PullUp
const int Pot = A0;   //Entrée analogique sur A0 pour potard de changement de courbes. R PullUp
const int Led13 = 13; //Temoin sur tout Arduino, suit le courant de bobine
const int Flash = A3; //Sortie A3 vers module Flash Led 3w  Keyes
const int Courbe_b = 8;  //Entré D8  R PullUp.Connecter à la masse pour courbe b
const int Courbe_c = 9;  //Entré D9  R PullUp. Connecter à la masse pour courbe c

int valPot = 0;       //0 à 1023 selon la position du potentiomètre en entree
float modC1 = 0;      //Correctif pour C1[], deplace la courbe si potard connecté
int unsigned long D = 0;  //Delai en µs à attendre après la cible pour l'étincelle
int milli_delay = 0;
int micro_delay = 0;
float RDzero = 0; //pour calcul delai avance 0° < Nplancher t/mn
float  Tplancher = 0; //idem//idem
int tcor  = 140; //correction en µs  du temps de calcul pour D
int unsigned long Davant_rech = 0;  //Delai en µs avant la recharge de la  bobine.
int unsigned long prec_H  = 0;  //Heure du front precedent en µs
int unsigned long T  = 0;  //Periode en cours
int unsigned long Tprec  = 0;//Periode precedant la T en cours, pour calcul de Drech
int N1  = 0;  //Couple N,Ang de debut d'un segment
int Ang1  = 0; //Angle d'avance vilo en degrès
int N2  = 0; //Couple N,Ang de fin de segment
int Ang2  = 0;
int*  pN = &Na[0];//pointeur au tableau des régimes. Na sera la courbe par defaut
int*  pA = &Anga[0];//pointeur au tableau des avances. Anga sera la  courbe par defaut
float k = 0;//Constante pour calcul de C1 et C2
float C1[30]; //Tableaux des constantes de calcul de l'avance courante
float C2[30]; //Tableaux des constantes de calcul de l'avance courante
float Tc[30]; //Tableau des Ti correspondants au Ni

int Tlim  = 0;  //Période minimale, limite, pour la ligne rouge
int j_lim = 0;  //index maxi des N , donc aussi  Ang
int unsigned long NT  = 0;//Facteur de conversion entre N et T à Ncyl donné
int AngleCibles = 0;//Angle entre 2 cibles, 180° pour 4 cyl, 120° pour 6 cyl, par exemple
int UneEtin = 1; //=1 pour chaque étincelle, testé et remis à zero par isr_GestionIbob()
int Ndem = 60;//Vitesse estimée du vilo entrainé par le demarreur en t/mn
int unsigned long Tdem  = 0;  //Periode correspondante à Ndem,forcée pour le premier tour
int Mot_OFF = 0;//Sera 1 si moteur detecté arrété par l'isr_GestionIbob()
int unsigned long T_multi  = 0;  //Periode minimale pour multi-étincelle

void  CalcD ()//////////////////
// Noter que T1>T2>T3...
{ 
  for (int j = 1; j <= j_lim; j++)//On commence par T la plus longue et on remonte
  {
    if  (T >=  Tc[j]) {     //on a trouvé le bon segment de la courbe d'avance
      D =  float(T * ( C1[j] - modC1 )  + C2[j]) ;//D en µs, C2 incorpore le temps de calcul tcor
      if ( T > Tplancher)D = T * RDzero;//Imposer 0° d'avance de 0 à 500t/mn
      break;  //Sortir, on a D
    }
  }
}
void  Etincelle ()//////////
{ if (D < 14000) {         // Currently, the largest value that will produce an accurate delay is 16383 µs
    delayMicroseconds(D); //Attendre D }
  }
  else {
    milli_delay = ((D / 1000) - 2);//Pour ces D longs, delayMicroseconds(D)ne va plus.
    micro_delay = (D - (milli_delay * 1000));
    delay(milli_delay); //
    delayMicroseconds(micro_delay);
  }
  digitalWrite(Bob, 0);//Couper le courant, donc étincelle
  digitalWrite(Led13, 0); //Temoin
  //digitalWrite(Flash, 1); delayMicroseconds(tFlash); digitalWrite(Flash, 0);
  //Maintenant que l'étincelle est émise, il faut rétablir Ibob au bon moment

  if (Multi && (T >= T_multi))Genere_multi();
  else {
    switch (Dwell)  //Attente courant coupé selon le type de Dwell

    { case 1:       //Ibob coupe 1ms par cycle seulement, la bobine doit supporter de chauffer
        Davant_rech = 1000; //1ms off par cycle
        break;

      case  2:      //Type bobine faible resistance, dite "electronique"
        Davant_rech = 2 * T - Tprec - trech;//On doit enir compte des variations de régime moteur
        Tprec = T;    //Maj de la future periode precedente
        break;

      case  3:      //Type "vis platinées", Off 1/3, On 2/3
        Davant_rech = T / 3;
        break;
    }
    Timer1.initialize(Davant_rech);//Attendre Drech µs avant de retablire le courant dans la bobine
  }
  Tst_Pot();//Voir si un potard connecté pour deplacer la courbe ou selectionner une autre courbe
  UneEtin = 1; //Pour signaler que le moteur tourne à l'isr_GestionIbob().
}

code 2eme partie:

void  Genere_multi()//////////
{ //L'etincelle principale a juste été générée
  delay(1); //Attendre fin d'etincelle 1ms
  digitalWrite(Bob, 1);//Retablir  le courant
  delay(3); //Recharger 3ms
  digitalWrite(Bob, 0);//Première etincelle secondaire
  delay(1); //Attendre fin d'etincelle 1ms
  digitalWrite(Bob, 1);//Retablir  le courant
  delay(2); //Recharger 2 ms
  digitalWrite(Bob, 0);//Deuxième etincelle secondaire
  delay(1); //Attendre fin d'etincelle 1ms
  digitalWrite(Bob, 1);//Retablir  le courant pour étincelle principale
}
void  Init ()/////////////

{ AngleCibles = 720 / Ncyl; //Cibles sur vilo.Ex pour 4 cylindres 180°,  120° pour 6 cylindres
  NT  = 120000000 / Ncyl; //Facteur de conversion Nt/mn moteur, Tµs entre deux PMH étincelle
  //c'est à dire deux cibles sur vilo ou deux cames d'allumeur
  T_multi = NT / N_multi; //Periode minimale pour generer un train d'étincelle
  //T temps entre 2 étincelle soit 720°  1°=1/6N
  Tdem  = NT / Ndem; //Periode imposée à  la première étincelle qui n'a pas de valeur prec_H
  Tplancher = 120000000 / Nplancher / Ncyl; //T à  vitesse plancher en t/mn: en dessous, avance centrifuge = 0
  RDzero = float(AngleCapteur) / float(AngleCibles);
  Select_Courbe();  //Ajuster éventuellement les pointeurs pN et pA pour la courbe b ou c
  N1  = 0; Ang1 = 0; //Toute courbe part de  0
  int i = 0;    //locale mais valable hors du FOR
  pN++; pA++; //sauter le premier element de tableau, toujours =0
  for (i  = 1; *pN != 0; i++)//i pour les C1,C2 et Tc.Arret quand regime=0.
    //pN est une adresse (pointeur) qui pointe au tableau N.Le contenu pointé est *pN
  { N2 = *pN; Ang2 = *pA;//recopier les valeurs pointées dans N2 et Ang2
    k = float(Ang2 - Ang1) / float(N2  - N1);//pente du segment (1,2)
    C1[i] = float(AngleCapteur - Ang1 + k * N1) / float(AngleCibles);
    C2[i] = -  float(NT * k) / float(AngleCibles) - tcor; //Compense la durée de calcul de D
    Tc[i] = float(NT / N2);  //
    N1 = N2; Ang1 = Ang2; //fin de ce segment, début du suivant
    pN++; pA++;   //Pointer à l'element suivant de chaque tableau
  }
  j_lim = i - 1; //Revenir au dernier couple entré
  Tlim  = Tc[j_lim]; //Ligne rouge
  Serial.print("Ligne_"); Serial.println(__LINE__);
  Serial.print("Tc = "); for (i = 1 ; i < 15; i++)Serial.println(Tc[i]);
  Serial.print("Tlim = "); Serial.println(Tlim);
  Serial.print("C1 = "); for (i = 1 ; i < 15; i++)Serial.println(C1[i]);
  Serial.print("C2 = "); for (i = 1 ; i < 15; i++)Serial.println(C2[i]);
  
  Timer1.attachInterrupt(isr_GestionIbob);//IT d'overflow de Timer1 (16 bits)
  Timer1.initialize(Dsecu);//Le courant dans la bobine sera coupé si aucune etincelle durant Dsecu µs
  Mot_OFF = 1;// Signalera à loop() le premier front
  digitalWrite(Bob, 0); //par principe, couper la bobine
  digitalWrite(Led13, 0); //Temoin
}
void  isr_GestionIbob()//////////
{ Timer1.stop();    //Arreter le decompte du timer
  if (UneEtin == 1) {
    digitalWrite(Bob, 1);    //Le moteur tourne,retablire le courant dans bobine
    digitalWrite(Led13, 1);//Temoin
  }
  else
  { digitalWrite(Bob, 0);  digitalWrite(Led13, 0); //Temoin//Moteur arrete, preserver la bobine, couper le courant
    Mot_OFF = 1;//Permettra à loop() de detecter le premier front de capteur
  }
  UneEtin = 0;  //Remet  le detecteur d'étincelle à 0
  Timer1.initialize(Dsecu);//Au cas où le moteur s'arrete, couper la bobine apres Dsecu µs
}
void  Select_Courbe()///////////
//Par défaut, la courbe a est déja selectionnée
{ if (digitalRead(Courbe_b) == 0) {   //D8 à la masse
    pN = &Nb[0];  // pointer à la courbe b
    pA = &Angb[0];
  }
  if (digitalRead(Courbe_c) == 0) {    //D9 à la masse
    pN = &Nc[0];  // pointer à la courbe c
    pA = &Angc[0];
  }
}
void Tst_Pot()///////////
{ valPot = analogRead(Pot);
  if (valPot < 240 || valPot > 900)modC1 = 0;//0° ou pas de potard connecté (valpot =1023 en théorie)
  else {
    if (valPot < 500)modC1 = float (delAv) / float(AngleCibles);//Position 1
    else modC1 = 2 * float (delAv) / float(AngleCibles);//Position 2
  }
}
////////////////////////////////////////////////////////////////////////
void setup()///////////////
/////////////////////////////////////////////////////////////////////////
{ Serial.begin(9600);//Ligne suivante, 3 Macros du langage C
  Serial.println(__FILE__); Serial.println(__DATE__); Serial.println(__TIME__);
  Serial.println(ver);
  pinMode(Cible, INPUT_PULLUP); //Entrée front du capteur sur D2
  pinMode(Bob, OUTPUT); //Sortie sur D4 controle du courant dans la bobine
  pinMode(Pot, INPUT_PULLUP); //Entrée pour potard 100kohms, optionnel
  pinMode(Courbe_b, INPUT_PULLUP); //Entrée à la masse pour selectionner la courbe b
  pinMode(Courbe_c, INPUT_PULLUP); //Entrée à la masse pour selectionner la courbe c
  pinMode(Led13, OUTPUT);//Led d'origine sur tout Arduino, temoin du courant dans la bobine
  pinMode(Flash, OUTPUT);//Sortie vers flash, patte S
  Init();// Executée une fois au demarrage et à chaque changement de courbe
}
///////////////////////////////////////////////////////////////////////////
void loop()   ////////////////
////////////////////////////////////////////////////////////////////////////
{ while (digitalRead(Cible) == !CaptOn); //Attendre front actif de la cible
  T = micros() - prec_H;    //front actif, arrivé calculer T
  prec_H = micros(); //heure du front actuel qui deviendra le front precedent
  if ( Mot_OFF == 1 ) { //Demarrage:premier front de capteur
    T = Tdem;//Fournir  T = Tdem car prec_H n'existe par pour la première étincelle
    digitalWrite(Bob, 1);//Alimenter la bobine
    digitalWrite(Led13, 1); //Temoin
    Mot_OFF = 0; //Le moteur tourne
  }
  if (T > Tlim)     //Sous la ligne rouge?
  { CalcD(); // Top();  //Oui, generer une etincelle
    Etincelle();
  }
  while (digitalRead(Cible) == CaptOn); //Attendre si la cible encore active
}

Dans ton code numéro 1, les valeurs du tableau Na doivent être entre accolades, comme pour les autres tableaux