Bonsoir à tous
ce matin fut riche d'enseignements
D'abord suite à la vérification de l'adéquation du délai pratiqué vs le délai préalablement calculé et issu du tableau
on sait rendu compte d'une erreur grossière
En gros pour les faibles vitesses de rotation le délai réel possédait une erreur négative ( moins d'avance ),
à moyenne vitesse une erreur contenue ( proche de zéro ) alors qu'a haute vitesse l'erreur devenait positive ( plus d'avance )
Donc l'erreur était grosso modo croissante alors que les délais en µs était décroissant avec la vitesse qui augmente
Ces deux effets contraire était assez perturbateur .
J'ai donc décortiqué le code et mesurer fonction par fonction les délais de boucle ou process et trouvé le coupable,
dans la fonction ci-dessous qui parcourt le tableau de manière croissante et posait le soucis de timing rencontré ce matin.
Code:
//-------------------------------------------- Function to map the engine rpm to value for the array element --------------------------------------------//
int decode_rpm(int rpm_){
map_rpm = 1;
if(elapsedtime > RPMS[MAX_INDEX]) // On ne dépasse pas la ligne rouge, on peut émettre une étincelle
{
if(elapsedtime < RPMS[1]) // Le délai est plus petit que le premier délai du tableau, donc vitesse supérieure à "startRPM"
{
while((elapsedtime*1.1) < RPMS[map_rpm]) // Incrémentation de la vitesse
{
map_rpm++; // Saute au prochain index dans le tableaau
}
}
}
//Serial.println(map_rpm);
return map_rpm;
}
En effet à basse vitesse la routine qui commence à incrémenter la vitesse pour trouvé le délai, part de l'index [1]
si la vitesse lue est plus haute il incrémente de 1, donc pour une vitesse égale à l'index 10 soit 200 T/min allumeur,
il incrémente 9 fois et prend un certain temps mesuré à 210 µs par ma routine de vérification
hors à 800 T/min elle passe à 774 µs, car il faut incrémenter 99 fois depuis l'index [1].
J'en conclu donc qu'a basse vitesse le délai de parcour du tableau prend moins de temps qu'a haute vitesse,
ce qui est l'inverse du temps de délais avant étincelle stocké en mémoire dans le µc,
Vous me direz alors pourquoi ne pas incrémenter ou décrémenter pour ne pas parcourrir le tableau du début à chaque fois.
Si le moteur s'arrête ou que le µc perd une impulsion d'entrée et vu le moyennage de la vitesse cela rendrait
le temps de cette routine aléatoire et assez imprévisible.
J'ai donc décidé de corriger ce soucis en enlevant du délai final le temps de cette conversion,
comme on a vu que ce délai erronné ce matin tendais vers 2 ms, j'ai simplement modifié ma fonction de temporisation
pour en tenir compte.
Ca donne ceci
Code:
/// Si on capte un signal sur l'entrée on récupère le délai et on actionne la bobine.
void loop()
{
if (triggered){
start_times = micros();
triggered = false;
decode_rpm(elapsedtime);
finaldelay = (DELAYS[map_rpm]) - (cmap_pressure * (DELAYDEP[map_rpm])); // cmap_pressure correspond à la valeur de dépression en degré lue au tour précédent
stop_times = micros();
conversiontime = (stop_times - start_times) - 50; // temps moyen d'écart avec la consigne "DELAYS[map_rpm]" de 20 µs
milli_delay = ((finaldelay/1000)-2);
micro_delay = (finaldelay-(milli_delay*1000))-conversiontime; // -conversiontime pour corriger les erreurs de sommations du temps des différentes lecture et calculs
delay(milli_delay); // Currently, the largest value that will produce an accurate delay is 16383 µs
delayMicroseconds(micro_delay); // Currently, the largest value that will produce an accurate delay is 16383 µs
dwellAndFire(COIL1);
read_pressure ();
decode_pressure(map_pressure_kpa);
Serial.print("V");
Serial.print(",");
Serial.print(engine_rpm_average);
Serial.print(",");
Serial.print(cmap_pressure);
Serial.print(",");
Serial.print(DELAYS[map_rpm]);
Serial.print(",");
Serial.print(DELAYDEP[map_rpm]);
Serial.print(",");
Serial.print(conversiontime);
Serial.println(",");
}
}
Les lignes start_times et stop_times permettent de mesurer ce timing variable et ainsi de corrigé la dérive.
C'était un peu long, mais ça devrait en amuser certains :-)
ou aider d'autres et moi même pour de prochain projets
Côté IHM , j'ai complèté le décorum
Fichier(s) joint(s):
aecp_ihm.png [ 195.24 Kio | Vu 6558 fois ]
Les cercles servent à afficher les valeurs tandis que les rectangles affichent sous forme de graphique
les fenêtres attendues pour les courbes qui s'y affiche en dynamique en suivant les informations de données
venant de l'Atmega32U4
Bref Processing ets un très bon outil assez facile à utiliser car très bien documenté et surtout multi-Os
d'ailleurs je vais tester cette IHM sous Win8 sur le laptop de mon fils pour voir
Les fichiers à jour
Edit du 25/01/2015
Les dossiers concernant les fichiers sont mis à jour avec les dernières modifications Fichier(s) joint(s):
Mon_projet_aecp.tar [2.77 Mio]
Téléchargé 296 fois
Fichier(s) joint(s):
aecp_rupteur_arduino.tar.bz2 [4.7 Kio]
Téléchargé 296 fois
Fichier(s) joint(s):
aecp_processing.tar.bz2 [558.25 Kio]
Téléchargé 308 fois
Fichier(s) joint(s):
aecp_1350x690_processing.tar.bz2 [502.75 Kio]
Téléchargé 317 fois
A +