Go Down

Topic: faire fonctionner 2 attach interrupt à la fois (Read 2517 times) previous topic - next topic

inryjo

Sans parler de refaire une conception adaptée à la situation, tu pourrais déjà tenter de corriger le fonctionnement actuel en modifiant le code du début de loop() comme suit :
Avec cette modif, j'obtiens toujours des résultats bizarres, c'est à dire que si je donne des impulsions à un rythme constant, ma vitesse va afficher un truc du genre 23 /43/64/97 kmh successivement.
(même chose pour le compte-tours)
Est-ce le reste du code qui interfère ?

kamill

Tu es sur de la fréquence de test impulsions? Tu les génère avec quoi?

inryjo

Tu es sur de la fréquence de test impulsions? Tu les génère avec quoi?
bouton poussoir et je mets un métronome pour être sûr, je ne devrais pas avoir autant de variations !

rjnc38

bouton poussoir et je mets un métronome pour être sûr, je ne devrais pas avoir autant de variations !
avec un bouton poussoir il faut au minimum un circuit anti-rebond entre l'inter et l'arduino
une autre solution si tu as un autre arduino tu lui fais généré un signal carre a fréquence variable

inryjo

avec un bouton poussoir il faut au minimum un circuit anti-rebond entre l'inter et l'arduino
une autre solution si tu as un autre arduino tu lui fais généré un signal carre a fréquence variable
Bonne idée, j'utilise maintenant la sortie pwm d'un raspberry pour tester les rpm sauf qu'en programmant 470Hz, j'obtiens 25600 RPM (avec des fluctuations) alors qu'en théorie je devrais avoir 28200 RPM, à quoi est-ce dû ?

Et comme tu as indiqué 16 Hz pour la fréquence maximale du capteur de roue, je crains qu'il ne renvoie qu'une seule impulsion par tour de roue. Ce n'est donc pas une mesure de fréquence instantanée qu'il convient de faire (comptage du nombre d'impulsions sur une période déterminée), mais une mesure de période (mesure du temps écoulé entre deux impulsions).
Merci beaucoup pour ces explications, je comprends bien mieux maintenant. Je vais donc voir comment modifier mon code. Pour toi, ça reste possible de compter le delta T entre chaque impulsion de roue et en même temps calculer la fréquence moteur ?

inryjo

#20
Feb 20, 2016, 05:01 pm Last Edit: Feb 20, 2016, 06:50 pm by inryjo
Tout-à-fait. Comme je l'ai indiqué, il s'agit de processus très lents comparés à la vitesse du microcontrôleur.

En revanche, il faut s'assurer qu'aucun traitement ne bloque le programme durablement. Il faut notamment veiller à traiter correctement les éventuels rebonds sur les entrées.

J'ai ajouté quelques lignes pour un anti rebond et changé la méthode de calcul des km/h. Ca m'a l'air de fonctionner.
Ou alors tu parlais d'un anti rebond physique, genre avec un condensateur ?
Par contre avec ces modifs, les fonctions noInterrupts/Interrupts dans mon loop ne risquent-elles pas d'affecter le interrupts des km/h ?
Autre chose, le compteur affiche la derniere vitesse enregistrée, comment faire en sorte qu'il se remette à 0 quand il n'a plus d'impulsions ?
Et aussi j'ai toujours le problème que ma vitesse moteur est légèrement erronnée, quand je mets mon PWM à par exemple 12000 RPM, j'ai 11400/11500.

En tout cas merci encore, j'ai pas mal avancé !

Code: [Select]

#include <Wire.h>
#include "Sodaq_DS3231.h"
#include <LiquidCrystal.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 10

volatile byte rpmcount;
unsigned int rpm;
unsigned int rpmroue;
unsigned long timeold;
volatile byte kmhcount;
unsigned int kmh;

unsigned long kmhtimeold;
const int potar = 0;
int valeurLue;
float tension;
float temp;
uint32_t old_ts;

long debouncing_time = 15; //Debouncing Time in Milliseconds
volatile unsigned long last_micros;

float start, finished;
float elapsed, time;
float circMetric=1.7; // wheel circumference relative to sensor position (in meters)
float speedk ;
 
LiquidCrystal lcd(12,11,9,8,7,6);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void heure();
void LCDPrint();
 
void setup()
{
Serial.begin(115200);
while (!Serial);
lcd.begin(16,2);
sensors.begin();
Wire.begin();
rtc.begin();
start=millis();
attachInterrupt(1, rpm_pulse, FALLING);
attachInterrupt(0, debounceInterrupt, FALLING);
start=micros();
digitalWrite(2,HIGH);/*pullup interne*/
digitalWrite(3,HIGH);/*pullup interne*/
}

void loop()
{
noInterrupts(); // interdit les interruptions / la modification des compteurs
uint32_t t_now = micros();  // lit l'heure
// lit et réinitialise les compteurs
uint32_t rpmc = rpmcount;
rpmcount = 0;
interrupts(); // autorise les interruptions / la modification des compteurs
uint32_t delta_t = t_now-timeold; // calcule la durée du comptage effectué
timeold = t_now; // mémorise l'heure de départ du nouveau comptage
  // calcule et affiche les résultats
  Serial.print("Compte-tours:");
  Serial.println(rpmc*6.0e7/delta_t);
  rpm = rpmc*6.0e7/delta_t;
  delay(400); 
 
Serial.print("Vitesse");
Serial.println(int(speedk)); 

valeurLue = analogRead(potar);
tension = valeurLue * 5.0 / 1023;
Serial.print("Tension = ");
Serial.println(tension,2);

sensors.requestTemperatures();
float temp = sensors.getTempCByIndex(0);
Serial.print("Temperature de la sonde: ");
Serial.println(temp);


DateTime now = rtc.now(); //get the current date-time   
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.println();

LCDPrint();
}

void debounceInterrupt() {
   if((long)(micros() - last_micros) >= debouncing_time * 1000) {
     kmh_pulse();
     last_micros = micros();
   }
 }

void rpm_pulse()
{
  rpmcount++;
}

void kmh_pulse()
{
  elapsed=millis()-start;
  start=millis();
  speedk=(3600*circMetric)/elapsed; // km/h
}

void LCDPrint()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print(speedk,1);
lcd.setCursor(2,0);
lcd.print("kmh");
lcd.setCursor(0,1);
lcd.print(rpm);
lcd.setCursor(5,1);
lcd.print("RPM");
lcd.setCursor(11,0);
lcd.print(tension);
lcd.setCursor(15,0);
lcd.print("V");
lcd.setCursor(15,1);
lcd.print((char)223);
lcd.setCursor(5,0);
lcd.print("16");
lcd.setCursor(7,0);
lcd.print(":");
lcd.setCursor(8,0);
lcd.print("23");
lcd.setCursor(13,1);
float temp = sensors.getTempCByIndex(0);
lcd.print(temp,0);
return;
}


Go Up