Jump to content

Allumage programmable sur base Bosch TSZ-H


Recommended Posts

Je ne connaissait pas non plus, j'ai trouvé ça en tapant "acquisition de données Arduino" sur Google.

Voici un lien qui explique le fonctionnement

https://www.instructables.com/Système-DAcquisition-De-Données-DAQ-Avec-Arduino-E/

Sinon j'ai fait un 2eme graphique, avec un nuage de points, pas mal pour avoir une vue d'ensemble:

112618118_Nuageacquisitiondedonnes.thumb.png.7d637cff48529917200eb76f60547718.png

En abscisse le régime moteur, en ordonnée la dépression, et la couleur des points représente la richesse.

J'en ai fait un deuxième avec plus de nuances de couleur et des points plus petits (une par point d'AFR soit 10 au total), à voir à l'usage lequel des deux sera le plus parlant.

Là c'est simple: on roule et à la fin on obtient un beau nuage. En fonction des couleurs on identifie rapidement les zones à corriger.

Bon, rien de nouveau ça existe déjà (genre MegaLogViewer de EFI Analytics), mais là c'est gratuit 😀

Link to comment
Share on other sites

  • 1 year later...

Bonjour,

 

Le code sur les pages précédentes fonctionne parfaitement pour la partie allumage (fin de la page 3), pour la partie log je n'ai pas testé aucun intérêt.

Une fois l'avance modifiée et adaptée à ta mécanique tout est ok.

J'ai plusieurs montages avec ce code et des nanos et tout est parfait, que ce soit sur 4 à plat ou 4 en ligne.

Quel est le soucis ?

Link to comment
Share on other sites

Bonsoir à tous !

En effet je passe très peu sur ce forum, mais heureusement j'ai activé l'alerte sur ma boite mail quand un message est posté sur ce sujet 🙂

Comme dit pierre 1302S, le code que j'ai publié en page 3 est fonctionnel et éprouvé.

Si tu es intéressé par les fonctions de log malheureusement c'est plus compliqué:

Lors des essais j'ai rencontrés quelques soucis assez fâcheux: la macro que j'utilise est très bien en soi si ce n'est que passé un certain régime moteur elle a tendance à planter ce qui a pour effet de couper l'Arduino et donc le moteur. Plutôt gênant, dangereux même !

Peut-être qu'elle ne suit pas la réception trop fréquente des données, ou est ce que ça vient de la "source", je ne sais pas et je n'ai pas pris le temps de creuser vraiment.

Pareil pour la sortie que j'ai ajouté pour exploiter Powerdyn, le fonctionnement est très aléatoire en passant par l'entrée micro. Ce logiciel offre aussi la possibilité d'utiliser des fichiers log. Cette solution est beaucoup plus pertinente.

Du coup, je m'oriente plus vers la création d'un logger, toujours à base d'Arduino, mais indépendant de l'allumage.

J'ai déjà une ébauche: il servirait à Powerdyn et à extraire les données que l'on veut (régime, AFR etc). Le code est quasi abouti, il me reste à faire le boitier pour pouvoir attaquer des essais.

Avec cette solution pas de problème: ça peut planter, on met pas la voiture en panne 😅 et une fois qu'on a fini nos réglages, on peut le retirer de la voiture.

Il ne faut pas être trop pressé, j'ai pas mal de choses sur le feu et ma voiture est plus ou moins immobilisée pour le moment (une fuite d'huile un peu chiante).

Je vous tiendrai au courant !

 

PS: Pierre, je te recontacte prochainement par mail 😉

Link to comment
Share on other sites

il y a 40 minutes, Toine5013 a dit :

Bonsoir à tous !

En effet je passe très peu sur ce forum, mais heureusement j'ai activé l'alerte sur ma boite mail quand un message est posté sur ce sujet 🙂

Comme dit pierre 1302S, le code que j'ai publié en page 3 est fonctionnel et éprouvé.

Si tu es intéressé par les fonctions de log malheureusement c'est plus compliqué:

Lors des essais j'ai rencontrés quelques soucis assez fâcheux: la macro que j'utilise est très bien en soi si ce n'est que passé un certain régime moteur elle a tendance à planter ce qui a pour effet de couper l'Arduino et donc le moteur. Plutôt gênant, dangereux même !

 

Bonsoir Antoine,

Moi aussi j'ai activé l'alerte pour ce post vu que j'aime bien l'électronique.

Pour ton problème arduino c'est peut être l'alimentation qui n'aime pas...Est ce qu'il y a des condensateurs de filtrage sur la partie alimentation? le 7805 chauffe? est ce qu'il y a un radiateur dessus?  tu n'alimente pas la carte par un petit module usb type allume cigare par hasard?

Je n'ai toujours pas rebosser sur cet allumeur qui est dans un carton. A l'époque je n'arrivais pas à le caler, je viens de relire ton post sur le 1er démarrage. Comme toi je vais mettre pour l'instant une avance fixe à 10° pour tout les régimes moteur pour essayer. Le miens c'est toujours la version de Philippe sans capteur de dépression et avec l'IGBT qui pilote directement la bobine d'allumage.

 

Link to comment
Share on other sites

Il y a 7 heures, Toine5013 a dit :

PS: Pierre, je te recontacte prochainement par mail 😉

Pas de soucis, j'ai bien avancé sur un autre projet commun et c'est 100% fonctionnel.

 

Pour l'allumage, comme j'ai dit j'ai fait plusieurs montages pour moi et les copains (surtout polo 6n et golfs pour passer en carbus) et j'ai vraiment mis le nez dessus cet été sur mon T3.

Il y a quelques bugs sur la partie allumage, la partie dépression qui m'a fait arracher les cheveux, mais j'ai une dépression sur pipe pas sur carbu, du coup au démarrage, je n'ai pas l'impression que le seuil de déclenchement soit pris en compte par le code, j'ai parfois un excès d'avance au démarreur, mais j'ai aussi beaucoup de dépression dans la pipe donc....Même si j'ai fais le relevé des dépression avec un mano, converti les valeurs il se peut que j'ai loupé un truc.

Il faut prendre le temps de faire sa courbe ! 

N'oubliez pas, l'avance statique du code est ajoutée à votre avance statique d'allumeur.

L'actualisation du ralentit en mettant un valeur d'avance plus haute sous le régime de ralentit semble parfois me poser problème pour le démarrage aussi (testé sur golf 1) mais le carbu a déjà une pull-down pour le ralentit à froid donc pas important.

 

Dans l'ensemble, hormis le log où je n'ai pas eu le temps de m'attarder, le reste, si c'est bien monté ça tient la route autant qu'un allumage stock, j'ai fait en tout un peu plus de dix-mille bornes sur diverses autos avec ce code et ça marche.

 

Concernant les soucis arduino, il est clairement évident que le nano ne supporte pas plusieurs chose complexe à la fois côté log, je l'ai vu pour un autre projet, ou j'ai simplement voulu récupérer deux infos et les afficher sur lcd : grosse erreur ! le mieux comme tu dis Antoine c'est d'avoir un logger qui s'occupe de ça ;) 

 

@Pod, sur les montages que j'ai effectué, prenons l'exemple de mon popo, le boitier (impression 3d en pla 3D850 sakata recuit) se trouve dans le compartiment moteur à gauche, le 7805 n'a jamais été ne serais-ce que tiède ;) J'ai juste mis un bout de radiateur maison sur l'igbt. 

Pour démarrer, c'est simple tu mets la courbe à 0 partout et tu mets 10° sur la ligne statique.

Sur la version de Philippe, as-tu activer le multi-étincelles ? et as tu testé le log et la gestion de courbe avec un potar ou un smartphone ? Je voulais le tester sur des moteurs qui n'ont pas besoin de depression (double carbu par exemple)

L'avantage de la version d'Antoine c'est qu'on conserve le module branché (je parle pour ceux qui comme toi et moi ont un tzh d'origine), du coup la seule fois un mon nano chinois est parti rejoindre les étoiles (paix à mes 2€... 😁), l'allumeur stock est vite retombé à sa place, comme j'ai des raccords aviation sur le boiter, j'ai fait un pont avec les bonnes fiches en ca de panne pour reprendre les connections stock : pas besoin de changer le faisceau, on vis le pont sur les broches, et on pose l'allumeur avec sa bride pour avoir l'avance déjà réglée, en cas de gros soucis c'est faisable assez vite sur le bord de la route. C'est la seule panne que j'ai eu : un nano pourri, depuis avec un nano de marque et un deuxième dans la boite à gant déjà programmé je n'ai eu AUCUN problème.

 

montage sur T3 (photos prises lors du montage) :

image.thumb.jpeg.b21dcf24a6702756ef9d53223ddec10d.jpeg

 

image.thumb.jpeg.37569026455ee8bec17d465b7e08d22d.jpeg

 

image.thumb.jpeg.7cfe02f0894935da97446ab9d1df3f2e.jpeg

Link to comment
Share on other sites

Il y a 10 heures, pierre1302S a dit :

 

@Pod, sur les montages que j'ai effectué, prenons l'exemple de mon popo, le boitier (impression 3d en pla 3D850 sakata recuit) se trouve dans le compartiment moteur à gauche, le 7805 n'a jamais été ne serais-ce que tiède ;) J'ai juste mis un bout de radiateur maison sur l'igbt. 

Pour démarrer, c'est simple tu mets la courbe à 0 partout et tu mets 10° sur la ligne statique.

Sur la version de Philippe, as-tu activer le multi-étincelles ? et as tu testé le log et la gestion de courbe avec un potar ou un smartphone ? Je voulais le tester sur des moteurs qui n'ont pas besoin de dépression (double carbu par exemple)

L'avantage de la version d'Antoine c'est qu'on conserve le module branché (je parle pour ceux qui comme toi et moi ont un tzh d'origine), du coup la seule fois un mon nano chinois est parti rejoindre les étoiles (paix à mes 2€... 😁), l'allumeur stock est vite retombé à sa place, comme j'ai des raccords aviation sur le boiter, j'ai fait un pont avec les bonnes fiches en ca de panne pour reprendre les connections stock : pas besoin de changer le faisceau, on vis le pont sur les broches, et on pose l'allumeur avec sa bride pour avoir l'avance déjà réglée, en cas de gros soucis c'est faisable assez vite sur le bord de la route. C'est la seule panne que j'ai eu : un nano pourri, depuis avec un nano de marque et un deuxième dans la boite à gant déjà programmé je n'ai eu AUCUN problème.

 

Bravo pour le montage sur le T3 et pour le rangement de l'atelier aussi 😉.

J'ai fait une version toute simple de cet allumeur, il n'y a pas le module bluetooth non plus.

Je n'avais pas pu essayer le multi étincelles puisque je n'avais pas réussi à faire tourner le moteur. Il démarrait, s'emballait un peu et calait ensuite....

Je pense que j'avais des problèmes avec la valeur d'angle position capteur (dans le code) par rapport au calage que je faisait réellement sur le T3 du capteur Hall. .Il y a peut être aussi le soucis capton ou !capton dans le code ou je n'étais pas bon.....

Aussi dans le code d'origine de Philippe Loutrel il me semble que le ligne de code avance initiale n'existe pas....

Je veux bien que tu me donnes les valeurs d'angle que tu as choisi pour le capteur Hall et comment tu fais pour prérégler l'allumeur avant le premier démarrage car je vais sans doute essayer à nouveau bientôt. 

Si je suis satisfait je le modifierais comme la version d'Antoine.

 

Mon circuit électronique est aussi dans une boite plastique mais vu qu'Antoine a des problèmes de redémarrage intempestif je pense qu'il faudrait utiliser une boitier métal avec la carcasse métallique reliée à la masse pour blinder toute l'électronique qui est dedans.

 

Certaines phrases échangées entre toi et Antoine dans ces derniers messages me font supposer qu'un système injection se prépare......😊 et qu'apparemment ça fonctionne déjà !!!

 

Link to comment
Share on other sites

Alors, par où commencer? 😁

Concernant les problèmes de log, j'ai écarté d'office un problème de "harware" car hors de l'utilisation de la fonction log, tout fonctionne parfaitement. C'est assez surprenant: au vu de sa simplicité il y aurait tellement de raisons pour que ça ne marche pas correctement mais le retour d'expérience des différents utilisateurs prouve le contraire.

J'ai il y a quelques temps déjà échangé avec une personne qui a fait mon montage et l'a testé de façon un peu plus drastique que moi, il a épluché tous les signaux aux scope: aucun parasite malgré l'absence de blindages, les avances parfaitement respectées etc etc. Il a même réussi à démontrer que le NPN utilisé pour piloter le module est facultatif. On peut directement attaquer le module avec la sortie de l'Arduino, en inversant les états dans le programme.

Quand je disais que je n'ai pas vraiment creusé le problème j'ai peut-être un peu exagéré car j'ai tout de même quelques pistes logicielles à ce sujet:

En fait, quand on communique via le port série, l'établissement et la coupure de la liaison a pour conséquence de rebooter l'Arduino, ce qui explique la coupure du moteur.

Pour l'instant, tous mes essais ont été effectués avec une vitesse de transmission de 9600bauds, ce qui est clairement trop lent et la grosse faiblesse du code tel qu'il est construit est que si la loop n'a pas fini son exécution au moment du passage de la cible, elle n'est pas vue par le programme.

Du coup on saute une période et ça met la pagaille dans tous les calculs de régime, d'avance etc.

Il est effectivement assez compliqué de faire du multitâche avec un Arduino mais c'est tout de même possible: Les gestions Speeduino avec un seul Arduino Uno gèrent allumage, injection, log, pression turbo etc etc. La clé étant de jouer avec les interruptions.

C'est possible dans notre cas à condition de repenser l'architecture du programme. J'y ai réfléchi et j'ai normalement la solution: actuellement, la loop démarre au passage de la cible, elle s'éxecute et se met en attente du prochain passage.

Là, on laisse tourner la loop et on déclenche une interruption lors du passage de la cible qui calcule le régime et lance un timer pour déclencher l'étincelle au moment voulu. Ainsi, le programme principal est libre pour exécuter d'autres fonctions et les temps de calcul n'ont plus d'importance. Ainsi on peut faire des logs et dans le cadre de mon futur projet, je pense même pouvoir gérer l'allumage et l'injection avec un seul Nano !

J'ai adapté le programme aujourd'hui, il me restera à l'essayer en réel.

C'est une mise à jour assez importante car il y a pas mal d'évolutions par rapport au programme actuel, notamment l'utilisation d'une table pour les avances et une régulation du régime de ralenti par l'adaptation de l'avance.

Je l'essaye dans la semaine et vous tiens au courant.

 

Bonne soirée !

 

Link to comment
Share on other sites

Il y a 8 heures, Toine5013 a dit :

J'ai adapté le programme aujourd'hui, il me restera à l'essayer en réel.

Et bien Antoine, si t'as besoin de testeurs.... ;)

 

@Pod j'ai bien pris connaissance de ton message plus haut, je te recontacte par mp dès que j'ai un moment et que je suis à la maison pour te donner le code que j'ai pour l'allumage d'Antoine et la procédure.

Link to comment
Share on other sites

Salut à vous ! J'ai quelques nouvelles.

Tout d'abord, Pod, je te laisse entre les mains de Pierre pour la résolution de ton problème. Si besoin, je suis tout de même disponible 🙂

J'ai testé mon programme basé sur les interruptions et... Ca ne marche pas lol.

Enfin disons que le moteur tourne mais assez mal. En fouillant un peu je me suis aperçu que la détection de la cible par une interruption génère des instabilités au niveau du calcul du régime (des variations de 100tr/min entre deux cycles, ce qui met la pagaille dans les calculs). Je ne sais pas vraiment pourquoi, mais en attendant je suis revenu à l'ancienne méthode de détection. Néanmoins, j'ai gardé l'application du délai D par un Timer et de ce fait gagné un temps précieux:

Ancienne méthode:

1569881381_LogigrammeAEPLdlai.thumb.png.43bb1450b6c40dbf7b092bb5df8fc2fd.png

Nouvelle méthode:

1460437393_LogigrammeAEPLTimer.thumb.png.2a0e7d0d4646730fedac4bfc6421a43b.png

Ca ne parait pas comme ça, mais en 800µs un Arduino a le temps de faire pas mal de choses.

J'ai également fait des essais de mesure de temps d'éxecution, et il est clair que la vitesse de transmission a un effet très important:

A 9600 bauds l'envoi d'une ligne de données prends environ 4,5ms contre 0,9ms à 115200 bauds.

Au régime de 7000tr/min, une période dure 4,2ms. Trop court pour laisser le temps au programme de finir son exécution avant le passage suivant de la cible.

 

Voici ma dernière version de programme:

 

/*
***************************AEPL module TZH*******************************

Pour moteur 4 cylindres 4 temps
Bobine allumage pilotée par module TSZ-H
Table allumage pression / régime
Possibilité d'utiliser presque n'importe quel capteur (pression absolue ou relative)
Gestion de l'avance spécifique au ralenti pour régulation du régime (option désactivable)


La gestion de l'avance au ralenti fonctionne sur le principe suivant:
L'avance au ralenti est indépendante de la table d'allumage
Elle est fixée à 10° dans le setup comme base de départ.
On fixe une consigne de régime, avec une tolérance (exemple 800+-30tr/min)
Si le régime est proche de cette consigne (exemple +-200tr/min), on applique l'avance ralenti.
Tous les Ncycles (paramètre ajustable), on vérifie si le régime est dans la consigne
Si il est dans la consigne, on ne change rien. Si il est hors consigne,
on corrige l'avance d'un point et on conserve cette avance pour les Ncycles suivant.
Le but d'espacer les corrections est de laisser le temps au régime de se stabiliser après une correction.


Il est possible d'augmenter la vitesse d'éxecution de analogRead() en augmentant sa fréquence d'horloge(au détriment de la précision de la mesure)
Elle est égale à: fréquence d'horloge CPU / facteur de division
La configuration de la fréquence en fonction de ces variables est la suivante :
 ADPS2 | ADPS1 | ADPS0 | Facteur de division | Temps d'exécution analogRead()
   1       1       1          128                      110µs
   1       1       0          64                       60µs
   1       0       1          32                       30µs
   1       0       0          16                       16µs
   0       1       1          8                        8µs
   0       1       0          4                        4µs
   0       0       1          2                        2µs

Les lignes suivantes sont à mettre en tête du programme
  #ifndef cbi
  #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
  #endif
  #ifndef sbi
  #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
  #endif
 
Celles-çi dans void Setup()      
  sbi(ADCSRA, ADPS2);    
  cbi(ADCSRA, ADPS1);
  cbi(ADCSRA, ADPS0);
sbi vaut 1, cbi vaut 0. L'exemple ci dessus configure un facteur de division de 16
*/

#include"TimerOne.h"      // Timer pour gestion Module
#ifndef cbi                                         //
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) //
#endif                                              // Pour configuration ADC
#ifndef sbi                                         //
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))  //
#endif                                              //


// Attribution des entrées/sorties //
#define Capteur         2   // Entrée digitale capteur hall
#define Module          3   // Sortie module allumage
#define Cap_MAP         A0  // Entrée analogique capteur MAP
#define Cap_AFR         A1  // Entrée analogique capteur AFR

// Configuration capteurs //
#define AngleCapteur 60     // Les temps de calcul sont de 380us, soit 13° à 8000tr/min. Il faut placer le capteur à l'avance maxi + 13° avant PMH minimum
bool Capteur_ON = LOW;      // HIGH si Pin passe à 5V devant la cible (front montant), LOW si front descendant
#define Umin 500            //(millivolts) Tension capteur MAP minimale
#define Umax 4500           //(millivolts) Tension capteur MAP maximale
#define MAP_min 0           //(KpA) Pression mini capteur MAP
#define MAP_max 100         //(KpA) Pression maxi capteur MAP

// Paramètres ajustables //
#define Nmax  7000              // Régime de coupure moteur en tr/min
#define Ndem  170               // Régime estimé au démarreur (pour premier cycle)
#define Ncycles_Send_data 10
bool Send_data_active = true;

bool Regulation_active = true;  // Pour utiliser ou non la stratégie ralenti
#define Consigne_ralenti 800     // Régime de consigne ralenti en tr/min
#define Ncycles_ajustement 10    // Nombre de cycles avant nouvelle correction avance ralenti
#define AAral_min 5              // AA mini au ralenti en °vilo
#define AAral_max 18             // AA maxi au ralenti en °vilo
#define Fourchette_ral 300       // Fourchette de régime pour application avance ralenti


//***************** Table d'allumage en °vilebrequin ************************//

// ************** Table 205 GTI 1,6 115cv origine************* //
byte  TabAA [11][13] = { // La première accolade représente le nombre de lignes, la deuxième les colonnes
  //7  11  15  21  27  35  39  45  51  56  60  70  80  tr/mn *100
  {10, 10, 14, 22, 27, 27, 27, 27, 27, 32, 32, 31, 5},  //0 Kpa
  {10, 10, 14, 22, 27, 34, 33, 33, 32, 32, 32, 31, 5},  //10
  {10, 10, 14, 22, 27, 34, 33, 33, 32, 32, 32, 31, 5},  //20
  {10, 10, 15, 23, 28, 35, 34, 34, 33, 33, 33, 32, 5},  //30
  {10, 10, 19, 27, 32, 39, 38, 38, 37, 37, 37, 36, 5},  //40
  {10, 10, 23, 31, 36, 43, 42, 42, 41, 41, 41, 40, 5},  //50
  {10, 10, 26, 34, 39, 46, 45, 45, 44, 44, 44, 43, 5},  //60
  {10, 10, 26, 34, 39, 46, 45, 45, 44, 44, 44, 43, 5},  //70
  {10, 10, 26, 34, 39, 46, 45, 45, 44, 44, 44, 43, 5},  //80
  {10, 10, 26, 34, 39, 46, 45, 45, 44, 44, 44, 43, 5},  //90
  {10, 10, 26, 34, 39, 46, 45, 45, 44, 44, 44, 43, 5}   //100
};

// Pressions correspondantes aux lignes de la table d'allumage //
#define T0  0  // Kpa
#define T1  10  
#define T2  20
#define T3  30
#define T4  40
#define T5  50
#define T6  60
#define T7  70
#define T8  80
#define T9  90
#define T10 100

// Régimes moteur correspondant aux colonnes de la table d'allumage //
#define N0  700 // Tr/min
#define N1  1100
#define N2  1500
#define N3  2100
#define N4  2700
#define N5  3500
#define N6  3900
#define N7  4500
#define N8  5100
#define N9  5600
#define N10 6000
#define N11 7000
#define N12 8000


//***************************** VARIABLES *********************************//

// calcul Tcor //
int unsigned long Temps_correction = 0;
int unsigned long Debut_execution = 0;

//*************** void Calc_N() *********************//
int unsigned long H_prec = 0;      // Heure précedente
int unsigned long T_prec = 0;      // Période précedente       //(µs) Période en cours (360°vilebrequin)
int unsigned long T = 0;      // Période suivante
int unsigned long Davant_rech = 0; // Délai a appliquer avant debut de charge bobine (pour respect du Dwell)
int unsigned long N = 0;           // Régime moteur en tr/min
bool prem = false;                 // Flag pour premier calcul

//*************** void Lec_CAP() *******************//
int bit_Umin = 0;            // Conversion tension capteur en Bit                            
int bit_Umax = 0;            // Idem
int bit_MAP = 0;             // Valeur analogique capteur MAP
int somme_bit_MAP = 0;       //
int moy_bit_MAP = 0;         //
byte compteur_bit_MAP = 0;   //
int MAP = 0;                 // Pression absolue capteur MAP
int bit_AFR = 0;             // Valeur analogique sonde AFR
int somme_bit_AFR = 0;       //
int moy_bit_AFR = 0;         //
byte compteur_bit_AFR = 0;   //
float AFR = 0;               // Valeur AFR
bool Flag_Map = false;       //

//*************** void Calc_D() ********************//
byte  Map = 0;         // Papillon (ligne)pour entrer dans TabAA, de 0 à PapMax
byte  Reg = 0;         // Regime (colonne) pour entrer dans TabAA, de 0 à RegMax
float CT = 0;          // Coefficient des Kpa pour interpollation
float CN = 0;          // Coefficient des Nt/mn pour interpollation
float AA = 0;          // (°vilo) Avance à l'allumage
float D  = 0;          // Délai pour commande étincelle (en fonction de l'avance à l'allumage)
#define Tcor 330
//Régulation ralenti//
byte AAral = 0;                 // Avance à l'allumage au ralenti
int Compteur_reg_ralenti = 0;   // Compteur utilisé pour espacer les correction

// void ISR_Gestion_bobine() //
volatile bool Etincelle = false;

// void Send_data() //
byte Compteur_Send_data = 0;


//******************************** FONCTIONS ************************************//

void setup(){
  Serial.begin(115200);
  pinMode(Capteur, INPUT_PULLUP);
  pinMode(Module, OUTPUT);
 
  sbi(ADCSRA, ADPS2);
  sbi(ADCSRA, ADPS1);
  cbi(ADCSRA, ADPS0);
  Timer1.attachInterrupt(ISR_Gestion_bobine);
  AAral = 10;  // Fixe l'avance au ralenti à 10° comme base de départ, sera ajustée dans la stratégie ralenti selon le régime moteur
  Compteur_reg_ralenti = Ncycles_ajustement;
  bit_Umin = Umin / 4.9; // Convertit la tension min capteur MAP en Bit
  bit_Umax = Umax / 4.9; // Convertit la tension max capteur MAP en Bit
  prem = true;
 
}

void loop(){  
  while (digitalRead(Capteur) == !Capteur_ON);   // Attente de la détection de la cible
  //Debut_execution = micros();                  // Pour calcul Temps d'éxecution (pour essais)
  Calc_N();                                      // Calcul de T,N et Davant_rech
  Calc_D();                                      // Calcul de D pour prochain cycle
  Temps_correction = (micros()-Debut_execution); // Pour calcul Temps d'éxecution (pour essais)
  Lec_CAP();                                     // Lecture des capteurs
  Send_data();                                   // Log des données
 
  //Serial.println(MAP);
  //Serial.println(D);
  //Serial.println(Temps_correction);
  //Serial.println(N);
  //Serial.println(Compteur_reg_ralenti);
  //Serial.println(AA);
  while (digitalRead(Capteur) == Capteur_ON); // Attente si la cible est encore détectée
}

void Calc_N(){
  T = micros() - H_prec;
  H_prec = micros();
  Davant_rech = T * 3 / 10;
  N = 30000000 / T;
  if(prem==true) N = Ndem;
  prem = false;
}

void Calc_D(){  // Calcule le délai pour point d'allumage
 
  CalcMAP();    // Calcul de la ligne de TabAA suivant la pression MAP
  CalcReg();    // Calcul de la colonne de TabAA suivant le régime N

  //*************** Routine régulation ralenti *****************//
  if (Regulation_active == true && (N > (Consigne_ralenti-Fourchette_ral)) && (N < (Consigne_ralenti+Fourchette_ral))){  // Régulation configurée, régime dans la fourchette consigne +-200: on est au ralenti, on applique la stratégie
  AA = AAral;  // AAral est fixée à 10° dans setup() comme base de départ, puis ajustée pour maintenir le régime au régime de consigne +-30trs/min
  Compteur_reg_ralenti --; // Le compteur sert à ne pas corriger l'avance à chaque cycle, pour laisser le temps au régime de se stabiliser
  if (N < (Consigne_ralenti - 30) && Compteur_reg_ralenti <= 0){ // Si le régime est sous le régime de consigne, on augmente l'avance d'un degré et remet le compteur à zéro pour voir si ça suffit
    AAral ++;
    if(AAral > AAral_max) AAral = AAral_max;
    Compteur_reg_ralenti = Ncycles_ajustement;
  }
  if (N > (Consigne_ralenti + 30) && Compteur_reg_ralenti <= 0){ // Si le régime est au dessus de la consigne, on diminue l'avance d'un degré
    AAral --;
    if(AAral < AAral_min) AAral = AAral_min;
    Compteur_reg_ralenti = Ncycles_ajustement;  
  }
  }
  //*************************************************************//
  else {
  AA = TabAA[Map][Reg] ;
  AA = (TabAA[Map][Reg] * (1 - CT) * (1 - CN)   +  TabAA[Map + 1][Reg] * CT * (1 - CN) + TabAA[Map + 1][Reg + 1] * CT * CN + TabAA[Map][Reg + 1] * (1 - CT) * CN);
  }
  D = T / 180 * (AngleCapteur - AA)-Tcor;
  if(N < Nmax) Timer1.initialize(D);             // Lancement du Timer pour déclenchament étincelle
  Etincelle = true;                              // Flag pour donner l'instruction à ISR
}

void Lec_CAP(){
  if(Flag_Map == true){
  somme_bit_MAP += analogRead(Cap_MAP);// Lecture de la valeur analogique capteur MAP
  compteur_bit_MAP ++;
  if(compteur_bit_MAP >= 10){
    moy_bit_MAP = somme_bit_MAP / compteur_bit_MAP;
    MAP = map(moy_bit_MAP, bit_Umin, bit_Umax, MAP_min, MAP_max);  // Conversion de cette valeur en Kpa
    MAP = constrain(MAP, MAP_min, MAP_max);
    somme_bit_MAP = 0;
    compteur_bit_MAP = 0;
  }
  Flag_Map = false;
  }
 
  else {
  somme_bit_AFR += analogRead(Cap_AFR);  // Lecture de la valeur analogique capteur AFR
  compteur_bit_AFR++;
  if(compteur_bit_AFR >=10){
    moy_bit_AFR = somme_bit_AFR / compteur_bit_AFR;
    AFR = map(moy_bit_AFR, 0, 1023, 100, 200);
    AFR = AFR / 10;
    somme_bit_AFR = 0;
    compteur_bit_AFR = 0;
  }
  Flag_Map = true;
}
}

void Send_data(){
  if (Send_data_active == true) {
  if(Compteur_Send_data <= 0){ // Compte à rebours terminé
  String Message = (("N") + String(N) + (",AA") + String(AA,0) + (",") + String(MAP) + ("MAP,AFR") + String(AFR,1)); // Préparation de la ligne de log
  //String Message = (("DATA,TIME,") + String(N) + (F(","))+String(AA) + (F(",")) + String(MAP) + (F(",")) + String(AFR));
  Serial.println(Message); // Envoi des log vers port série
  Compteur_Send_data = Ncycles_Send_data; // Réinitialisation du compte à rebours
  }
  else {
  Compteur_Send_data--;
  }
}
}

void ISR_Gestion_bobine(){
  Timer1.stop(); // Arrêt du Timer
  if(Etincelle == true){
    digitalWrite(Module, HIGH); // Coupure de la bobine pour déclenchement étincelle
    Etincelle = false;
    Timer1.initialize(Davant_rech); // Lancement du Timer pour mise en charge bobine
  }
  else{
    digitalWrite(Module, LOW); // Mise en charge bobine
  }
}

void CalcReg(){
// Calcul le numero de colonne en fonction du régime N
// ainsi que le coefficient CN pour interpoller AA dans la table
// N12 limite supérieure, on commence à comparer à N11
  if (N > N11){
    Reg = 11;
    CN = (N - N11) / (N12 - N11);
    return;
  }
  if (N > N10){
    Reg = 10;
    CN = (N - N10) / (N11 - N10);
    return;
  }  
  if (N > N9){
    Reg = 9;
    CN = (N - N9) / (N10 - N9);
  return;
  }
  if (N > N8){
    Reg = 8;
    CN = (N - N8) / (N9 - N8);
  return;
  }
  if (N > N7){
    Reg = 7;
    CN = (N - N7) / (N8 - N7);
  return;
  }
  if (N > N6){
    Reg = 6;
    CN = (N - N6) / (N7 - N6);
  return;
  }
  if (N > N5){
    Reg = 5;
    CN = (N - N5) / (N6 - N5);
  return;
  }
  if (N > N4){
    Reg = 4;
    CN = (N - N4) / (N5 - N4);
  return;
  }
  if (N > N3){
    Reg = 3;
    CN = (N - N3) / (N4 - N3);
  return;
  }
  if (N > N2){
    Reg = 2;
    CN = (N - N2) / (N3 - N2);
  return;
  }
  if (N > N1){
    Reg = 1;
    CN = (N - N1) / (N2 - N1);
  return;
  }
    Reg = 0;
    CN = (N - N0) / (N1 - N0);
}

void CalcMAP(){
// Calcul le numero de ligne en fonction du MAP
// ainsi que le coefficient CT pour interpoller
// T10 limite supérieure, on commence à comparer à T9
  if (MAP > T9) {
    Map = 9;
    CT = (MAP - T9) / (T10 - T9);  // Pour interpollation
    return;
  }
  if (MAP > T8) {
    Map = 8;
    CT = (MAP - T8) / (T9 - T8);
    return;
  }
  if (MAP > T7) {
    Map = 7;
    CT = (MAP - T7) / (T8 - T7);
    return;
  }
  if (MAP > T6) {
    Map = 6;
    CT = (MAP - T6) / (T7 - T6);
    return;
  }
  if (MAP > T5) {
    Map = 5;
    CT = (MAP - T5) / (T6 - T5);
    return;
  }
  if (MAP > T4) {
    Map = 4;
    CT = (MAP - T4) / (T5 - T4);
    return;
  }
  if (MAP > T3) {
    Map = 3;
    CT = (MAP - T3) / (T4 - T3);
    return;
  }
  if (MAP > T2) {
    Map = 2;
    CT = (MAP - T2) / (T3 - T2);
    return;
  }
  if (MAP > T1) {
    Map = 1;
    CT = (MAP - T1) / (T2 - T1);
    return;
  }
    Map = 0;
    CT = (MAP - T0) / (T1 - T0);
}

 

Comme vous pouvez le remarquer, cette version n'a plus grand chose à voir avec la précedente.

-La saisie des avances se fait désormais avec une table et le calcul de D n'a plus rien à voir. En fait c'est une reprise de la méthode de calcul de l'injection de Philippe Loutrel.

-L'avance au ralenti est indépendante et est ajustée en permanence pour maintenir un régime de consigne. C'est efficace: lorsque que l'on allume les phares par exemple, on voit bien l'avance augmenter et le régime est maintenu, là où il s'écroulait auparavent.

-La mesure du capteur de pression est désormais faite sur plusieurs cycles pour moyenner cette valeur. Ce qui a pour effet de la rendre bien plus stable, là ou elle avait tendance à yoyoter, avec forcément un effet sur l'avance.

-Grâce à l'utilisation du Timer pour le délai D, le programme a gagné en disponibilité et peut donc supporter plus de tâches.

Je précise tout de même: cette version n'a pas encore été essayée sur la route, mais tous les essais que j'ai fait en statique démontre que les avances appliquées sont fidèles et stables, même à haut régime. Je pense donc qu'elle est essayable si le coeur vous en dit 😁

 

Bonne journée !

Link to comment
Share on other sites

Salut,

De mon coté j'ai des problèmes plus simple apparemment la fiche plastique de mon connecteur pour le capteur posait des problèmes car elle était fissurée, cassée sur le dessous.

Je viens de remonter un capteur Hall neuf car l'ancien était grillé. Voici le modèle que j'ai commandé

Transmetteur de hall avec pièces de fixation pour allumeur éléctronique 5/1979-7/1992

Le problème c'est que le connecteur d'origine du 1600 CT est différent mais je le savais, par contre je ne trouve le connecteur de ce module qui est celui des golf1 et je crois qu'il a été utilisé sur certaines Peugeot.

Est ce que vous connaissez une astuce, ou un shop qui vends ces connecteurs?

Link to comment
Share on other sites

Il y a 8 heures, Toine5013 a dit :

Salut à vous ! J'ai quelques nouvelles.

Tout d'abord, Pod, je te laisse entre les mains de Pierre pour la résolution de ton problème. Si besoin, je suis tout de même disponible 🙂

J'ai testé mon programme basé sur les interruptions et... Ca ne marche pas lol.

Enfin disons que le moteur tourne mais assez mal. En fouillant un peu je me suis aperçu que la détection de la cible par une interruption génère des instabilités au niveau du calcul du régime (des variations de 100tr/min entre deux cycles, ce qui met la pagaille dans les calculs). Je ne sais pas vraiment pourquoi, mais en attendant je suis revenu à l'ancienne méthode de détection. Néanmoins, j'ai gardé l'application du délai D par un Timer et de ce fait gagné un temps précieux:

Ancienne méthode:

1569881381_LogigrammeAEPLdlai.thumb.png.43bb1450b6c40dbf7b092bb5df8fc2fd.png

Nouvelle méthode:

1460437393_LogigrammeAEPLTimer.thumb.png.2a0e7d0d4646730fedac4bfc6421a43b.png

 

Bonjour Antoine,

Pour ton code parfois j'essaye de l'étudier un peu mais ce n'est pas si simple pour moi car je n'ai pas ton niveau en programmation pour vraiment pouvoir t'aider.

Je sais que lors de communication série en modifiant le firmware ça évite les reboots dont tu parles dans la transmission par le port série, c'est d'ailleurs ce qui est fait sur speeduino.

Il y a aussi la mémoire tampon qui est utilisé pour la transmission par le port série, c'est bien de l'effacer après avoir envoyé les données à chaque fois. (La commande c'est serial flush() je crois)

Ensuite je suppose que la fonction calc_D c'est le calcul du temps d'avance et que Davant_Rech c'est le temps qui est laissé à la bobine pour qu'elle puisse produire son étincelle avant de se recharger pour l'étincelle suivante.

J'ai pas trop compris à quoi te sert le Tcor qui est rajouté dans le calcul d'avance et aussi comment tu le détermine

Dans tes 2 graphiques "ancienne méthode" et "nouvelle méthode", la différence entre les 2 si j'ai bien compris c'est que tu utilises un timer mais je vois pas trop comment il est lancé. (En fait j'ai un peu de mal à comprendre la méthode de calcul, en plus le système de régulation de ralenti (variable AA??) rend la fonction calc_D un peu plus complexe). 

Pour tes essais avec interruptions tu as utilisé INT0 avec déclenchement sur front ou alors sur état stable de l'entrée 2?

C'est bien tes chronogrammes je visualise mieux la démarche de Philippe Loutrel puis de ce que tu fait pour améliorer le programme.

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share


×
×
  • Create New...