Perturbations alimentation arduino sur moto 50cc

Salut a tous!

alors voila j'ai un montage d'un compteur de vitesse avec quelques fonctions suppplémentaires qui fonctionne très bien sur ma moto de 500CC, j'ai voulu le répliquer sur une 50cc et la ca pose problème...

le montage est composé d'une promini, d'un ecran oled spi, et l'alim est un convertisseur 12V => usb issu d'un adaptateur auto pour allume cigare.

tout fonctionne, y compris moteur démarré, mais les hauts régimes de la 50... le montage aime pas ca... la 50 doit prendre 10-12000 tours/minutes et ma 500 dans les 8000 tr/min, je pense que le problème vient de la.

j'ai essayé de recouvrir l'interieur de mon boitier avec de l'aluminium + isolation pour faire une cage de faraday, c'est un peu mieux mais ca bug toujours, j'ai aussi mis une diode sur l'alim 12V pour éviter des retours de tension négative et un condo de 100uf 35V sur la partie 5V entre l'alim et l'arduino.

Je précise que c'est moi qui ai réalisé les 2 montages,HW et code, la 500 a un capteur a lamelles+ aimant (je sais plus le nom, capsule en verre avec des lamelles métalliques) la 50 avait deja un capteur a effet hall d'origine, mais je pense pas que ce soit le soucis, car tout fonctionne, je penche vraiment pour des perturbations HT.

Je vois pas trop quoi faire de +... une idée?

bonsoir
certainement ampoule "Reed" pour le 500

Je n'ai pas bien compris comment se manifeste le problème sur le 50 ?

comment sont acquises les impulsions ?

programme ?

oui, c'est ca un capteur reed pour la 500,

sur la 50, et bien lorsqu'on fait monter le moteur a haut régime, l'arduino redémarre ou se fige, au choix, parfois il faut meme la reprogrammer pour qu'elle reparte.
coté code je me suis basé sur le code du playground arduino qui utilise une interruption afin de relever l'état d'une entrée de la carte (code identique a peu de choses près sur les 2 motos)

void setup(void) {
   //Serial.begin(115200);
  reedCounter = maxReedCounter;
//  reedCounter_rpm = maxReedCounter;
  //circumference = 2*3.14*radius; 
  circumference = 75.96 ; //12.66; // divisé par 6, car 6 impultions par tour. 
  //pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  
  // TIMER SETUP- the timer interrupt allows precise timed measurements of the reed switch
  //for more info about configuration of arduino timers see http://arduino.cc/playground/Code/Timer1
  cli();//stop interrupts

  //set timer1 interrupt at 1kHz
  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;
  // set timer count for 1khz increments
  OCR1A = 1999;// = (1/1000) / ((1/(16*10^6))*8) - 1
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS11 bit for 8 prescaler
  TCCR1B |= (1 << CS11);
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);

  sei();//allow interrupts
  //END TIMER SETUP

  EEPROM.get(0, vt5);
  //vt5.total= 5963; //initialisation kms
 // pinMode(A6, INPUT);
 pinMode(16, OUTPUT);  //(a2)temoin clignos
   pinMode(6, INPUT); //tr
  pinMode(7, INPUT); //tl
  pinMode(14, INPUT_PULLUP);   // bouton compteur
  
  u8g2.begin();
  splash();
  t.every(100, drawScreen);
  t.every(150, check_lights);
  t.every(300, check_btn);
 
 clignos.begin(); // This initializes the NeoPixel library.
 
//Serial.print("tot. kms : "); Serial.println(vt5.total);
}

//calculations
//tire radius ~ 12.01 inches
//circumference = pi*2*r =~75.99 inches
//max speed of 35mph =~ 616inches/second
//max rps =~7.25
ISR(TIMER1_COMPA_vect) {//Interrupt at freq of 1kHz to measure reed switch
  reedVal = digitalRead(4);//get val of A0
  turn_r = digitalRead(7);//get val of D6
  turn_l = digitalRead(6);//get val of D7
  if (!reedVal) { //if reed switch is closed
    if (reedCounter == 0) { //min time between pulses has passed
      mph = (56.8 * float(circumference)) / float(timer); //calculate miles per hour
      session_dist += 0.322f;
      //Serial.println(session_dist);
      if (session_dist > 100) {
        int m = (long)(session_dist * 100) / 100.0;
        vt5.total += m / 1000.00f;
        vt5.trip1 += m / 1000.00f;
        vt5.trip2 += m / 1000.00f;
        session_dist -= m;
        save_count++;
      }
      if (save_count == 10) {
        save_count = 0;
        EEPROM.put(0, vt5);
      }

      timer = 0;//reset timer
      reedCounter = maxReedCounter;//reset reedCounter
      kph = mph * 1.609344;
    }
    else {
      if (reedCounter > 0) { //don't let reedCounter go negative
        //reedCounter -= 1;//decrement reedCounter
      }
    }
  }
  else { //if reed switch is open
    if (reedCounter > 0) { //don't let reedCounter go negative
      reedCounter -= 1;//decrement reedCounter
    }
  }
  
  if (timer > 2000) {
    mph = 0;
    kph = 0;//if no new pulses from reed switch- tire is still, set mph, rpm and kph to 0
    //rpm=0;
  }
  else {
    timer += 1;//increment timer
  }
  clignos.show();
}

void loop(void) {
  t.update();

}

(c'est le setup et loop du code de la 50, il y a une fonction pour gérer les clignotants aussi sur celle la.)
mais vraiment je pense qu'il s'agit d'un problème hardware...

Je trouve que tu fais beaucoup de chose dans la routine de traitement des interruptions. En particulier, des calculs sur des flottants.
A 12000 tr/min il y a une interruption toutes les 5ms. Dans les ISR il faut faire le strict minimum. Tout ce qui prend du temps peut être fait en tâche de fond dans loop().
Typiquement, dans l'ISR, lorsque la condition if (reedCounter == 0) est satisfaite la seule chose importante à faire c'est sauvegarder le contenu de timer. Il suffit ensuite de positionner un drapeau qui sera testé dans loop() pour indiquer qu'il y a un calcul à réaliser.

EDIT: Pendant le développement, le drapeau pourrait être un compteur plutôt qu'un simple booléen. Ce qui permettrait à la tâche de fond de savoir que le calcul est trop long et que des infos sont perdues. Typiquement, est-il indispensable de faire les calculs en mph et en kmh?

C'est pas comme cela que j'ai compris. Je comprends qu'il y a une interruption toute les ms et qu'on en profite pour tester le capteur. A basse vitesse ou à haute vitesse, il y a quasiment toujours la même charge.

Mais le programme n'est pas complet.

Exactement, l'ISR est a fréquence fixe, il n'y a pas de fonction compte-tours et la charge sur l'arduino est toujours la meme...

non, ce n'est pas indispensable..

de mon expérience avec l'arduino, moins il y en a dans le loop mieux c'est, mais je crois qu'on est un peu hors sujet :wink:

C'est une règle à ne pas ignorer en matière de développement informatique. N'importe quel professionnel sera du même avis.

Pas d'accord, donc.

L'arche de Noé a été faite par un amateur, et le Titanic par des professionnels. Et un plombier professionnel voulait faire l'évacuation de l'évier de ma cuisine dans les tubes d'aération du vide sanitaire... Je ne fais pas forcément confiance aux professionnels.

Maintenant surcharger loop quand il y a des fonctions de type t.update, c'est pas terrible. Je pense que c'est à cela qu'il est fait allusion.

Pour moi, et tant que l'on ne m'a pas démontré le contraire, je pense que le calcul doit être fait d'un côté ou d l'autre, et cela revient presque au même. Si on a un calcul long à faire, que l'on bloque d'un côté ou de l'autre bloquera tout au final. Il faut gérer correctement l'ensemble.
L'essentiel (si les fonctions d'interruptions ne sont pas réentrantes) est que l'on ait fini le calcul de l'interruption avant un nouveau déclenchement.

Maintenant pour le programme en cours, il peut fonctionner en basse vitesse du moteur, et les conditions actives peuvent êtres plus nombreuse et donc rallonger le temps du programme et le faire bloquer. Mais dans ce cas on risque plus d'avoir une mesure fausse.

A basse vitesse, quelques ISR déborderont, mais à haute voit cela ne se voit pas, et quand on va vite, les ISR déborderont systématiquement et plus aucun temps n'est accordé à loop().
Pour le savoir, il suffit de mettre une sortie à HIGH en débit d'ISR, et à LOW en fin d'ISR. Avec un analyseur logique, on voit tout de suite si les ISR débordent. Sans analyseur à 10€ (petite pub pour placer ce produit fort utile dans ce type de situation), on peut utiliser LED_BUILTIN ou une autre led. Tant qu'elle ne brille pas fort, on a du temps dans loop. On arrive à la moitié du temps dans l'ISR si la led brille autant si on inverse son HIGH et son LOW.

En basse vitesse ce qu'il y a derrière

if (!reedVal) { //if reed switch is closed
est négligeable. Et ce doit être la majorité du temps. Si ce qu'il y a derrière est important et prend 10ms, tant qu'elle est faiblement appelée, cela ne se voit pas. Elle va manger 10 interruptions. Mais quand on tourne plus vite on ne peut plus manger ces 10 intervalles.

Il y a des choses quand même bizarres:

if (!reedVal) { //if reed switch is closed
On dirait que l'incrémentation se fait quand le relais est fermé. A priori, on devrait avoir une incrémentation sur un front et pas sur un niveau. Non?

Ca sert à quelque chose?

Si il ne faut pas que reedCounter soit négatif, c'est raté! Il manque une partie du programme. A priori pour un compteur d'impulsions, j'aurais pris un entier non signé.

Pas si on n'a pas fait avant la mesure du temps libre.

Pour voir si cela vient ou non de la fréquence, on peu faire un test. Il suffit de remplacer le relais Reed par un signal carré de fréquence variable et voir sur table si le problème persiste. Un GBF fait aussi l'affaire, mais c'est moins courant.

Brillante démonstration.
Et la tour Eiffel ? Par des pros je crois.

oui.

pas bête ca, le digitalWrite en lui meme étant quand meme lourd...

en fait ca vient du code d'exemple que j'ai utilisé, et je pense que le commentaire justifie l'utilisation de > plutot que >=, car ce compteur est initialisé a 10 et est ensuite décrémenté jusqu'a 0..

bon, je veux pas entrer dans des débats du type pain au chocolat ou chocolatine svp, tout n'est pas blanc ou noir et y a des pros qui font bien leur boulot tout comme l'inverse et aussi des amateurs qui font mieux que les pros, ou pas...

en tout cas vos remarques m'on fait me questionner sur des parties de ce code que je considérait comme fonctionnel car utilisés avec succès sur ma 500, quelques tests aujourd'hui m'on permis de voir que j'étais un peu trop optimiste, et détecter le signal de mes clignotants dans l'ISR était en effet un peu trop, du coup j'en ai profité aussi pour calculer la vitesse directement en km/h plutot que d'utiliser la conversion de fainéant que j'avais mise.

je finis tout ca et je vous tiendrai au courant demain :wink:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.