Arduino uno - verification programme => mesure angle

J-M-L:
Si si On parle d'angle effectivement pour mesurer cela - un autre dessin explicatif

Sur un 4 cylindre (90° =360/4) F sera l'angle pendant lequel le contact est fermé et O l'angle pendant lequel il sera ouvert. Chaque moteur aura son optimal

(source)

Oui JML
j'avais bien compris le but du jeu :grin:

Mais ce cherche à faire/obtenir zoilgust , c'est simplement obtenir des "profils" simples de came

  • came primaire (entrainante/mére)
  • came secondaire (entrainée/fille)

ça ne reste que de la petite "mecanique"

une came "carrée aux angles arrondis" ça ne reste qu'un "rond inscrit déformé" 8)

Donc si vous faites une interruption sur CHANGE vous aurez votre info.

Oui pour le carré arrondi :slight_smile:

Oui mais je stocke comment ?
Une boucle ? Tant que je n'ai pas 8 CHANGE je stocke dans des variables ?

Ces 8 CHANGE = Temps total ?

Par exemple - ou alors vous lisez les interruptions pendant un certain temps connu

zoilgust:
Oui mais je stocke comment ?
Une boucle ? Tant que je n'ai pas 8 CHANGE je stocke dans des variables ?

Ces 8 CHANGE = Temps total ?

Il te faut juste stocker les durées d'etats entre les "changes" (et ensuite faire de la discrimination) et comme AMHA (par ... intuition/expérience :grin: ) il y aura plus de 8 "changes" par rotation de 360° :grin: sur ton rupteur , il faut aussi déjà penser à intégrer les notions d’anti rebonds/hysteresis 8)

Pour le filtrage, je vous conseille le montage que je vous ai donné à la réponse #12.

Pour le stockage des données :

Sur l'arbre menant: il y a une information par tour elle sert à :

  • mesurer la vitesse de l'arbre menant,
  • donner un instant de référence pour les autres mesures.

Sur l'arbre mené, il y a 4 informations par tour (dédoublées par les ouvertures/fermetures). Par le jeu des interruptions Arduino, on relève les temps auxquels ces informations apparaissent par rapport à la référence.

Il faut donc deux interruptions :

  • la première pour enregistrer le temps de référence de l'axe menant (sur front montant ou descendant)
  • la deuxième pour enregistrer les commutations de la came (sur front changeant)

et on recommence à chaque tour.

Bien évidemment, vous n'aurez pas les mêmes résultats à chaque tour à cause des incertitudes de mesures. Il faut introduire un système de filtrage. Du type de celui-ci dépend le nombre d'informations à stocker.

Pour un filtre passe-bas, il faut que chaque information soit conservée une fois. C'est-à-dire qu'à chaque tour, on aura à disposition :

  • les mesures sur le tour précédent,
  • les mesures sur le tour courant.
    Si, au lieu d'un filtrage, vous faites un lissage, alors, il vous faudra autant de paquets de mesure que l'opérateur de lissage en demandera (un dizaine en général).

Cordialement.

Pierre

pour le filtrage j'utiliserais le schéma reçu, encore merci.

après réflexion c'est bien ça ChPr, je ne peux pas utiliser 8 CHANGE, car le CHANGE ne me dit pas si je suis sur un front montant ou descendant

et vu qu'il faut que je dissocie je vais utiliser 4 attachinterrupt en FALLING ou RISING.

ça m'éclaircie un peu tout ça.

pour le lissage pas de probleme, c'est un axe qui va tourner à 400 trs/min, il va en recevoir des interruptions :wink:

je tente de traduire ça en langage arduino ce soir :o

zoilgust:
je ne peux pas utiliser 8 CHANGE, car le CHANGE ne me dit pas si je suis sur un front montant ou descendant

Bonjour,

Il suffit de tester si l'entrée est HIGH ou LOW en début d'interruption pour savoir si le front est montant ou descendant

zoilgust:
et vu qu'il faut que je dissocie je vais utiliser 4 attachinterrupt en FALLING ou RISING.

Tu ne peux utiliser qu'un attachinterrupt par entrée

kamill:
Bonjour,

Il suffit de tester si l'entrée est HIGH ou LOW en début d'interruption pour savoir si le front est montant ou descendant

Tu ne peux utiliser qu'un attachinterrupt par entrée

ah oui c'est vrai on peut faire ça !

ah bon ? on ne peut pas avoir 2 attachinterrupt ?

On peut avoir 2 attachinterrupt, mais sur 2 entrées différentes

ah ok je comprend, donc c'est mort ...

et je n'avais pas fait attention dans le lien que j'avais donné
http://www.locoduino.org/spip.php?article64

il utilise bien 4 entrées

merci !

par contre est-ce que je peux faire plusieurs interruptions avec la même pin du type :

const pinILS1 = 2

byte comptageILS1 = 0; //pour recuperer le temps du FALLING
byte comptageILS2 = 0;
byte comptageILS3 = 0;
byte comptageILS4 = 0;
etc...

attachInterrupt(pinILS1, interruptILS1, FALLING);
attachInterrupt(pinILS1, interruptILS2, FALLING);
attachInterrupt(pinILS1, interruptILS3, FALLING);
etc ...

void interruptILS1 {

comptageILS1 = 0; // recupere le temps de l'interruption 1

}

void interruptILS2{

comptageILS2 = 0; // recupere le temps de l'interruption 2

}

void interruptILS3{

comptageILS3 = 0; // recupere le temps de l'interruption 3

}

etc...
etc...

ou alors passer par le CHANGE et le digitalread, mais je bloque sur un bouclage pour stocker 4 temps d'interruption.
punaise je pars de loin ...

const pinILS1 = 2

byte comptageILS1 = 0; //pour récupérer le temps du FALLING
byte comptageILS2 = 0;
byte comptageILS3 = 0;
byte comptageILS4 = 0;
etc...

attachInterrupt(pinILS1, interruptILS1, CHANGE);


void interruptILS1 {

if(digitalread = LOW){

for (un bouclage ?)
comptageILS1 = 0; // recupere le temps de l'interruption 1
comptageILS2 = 0; // recupere le temps de l'interruption 2
comptageILS3 = 0; // recupere le temps de l'interruption 3
comptageILS4 = 0; // recupere le temps de l'interruption 4

et un calcul qui prend le temps total

}
}

ChPr:
Faites le montage décrit sur le schéma ci-joint. Une capacité de 4.7 ou 10 nF convient bien. Pour cette application, n'importe quel type de condensateur convient. Ce qu'il faut, c'est qu'il soit bien au plus près des bornes de l'Arduino.

Cordialement.

Pierre

ce condensateur c'est bon ?

resistance 220 kohm ?

resistance 4.7kohm ?

merci !

zoilgust:
par contre est-ce que je peux faire plusieurs interruptions avec la même pin du type : ...

Non (d'ailleurs je ne vois pas du tout l'intérêt)

je suis tellement nul que je ne sais pas encore totalement ce qu'il est encore possible de faire ... ou pas :wink:

merci, donc un CHANGE et un detection d'un LOW ou HIGH

zoilgust:
pour le filtrage j'utiliserais le schéma reçu, encore merci.

...

pour le lissage pas de probleme, ...

Attention de ne pas confondre le filtrage des signaux (circuit résistance/capacité) et le filtrage ou lissage des données : opérations logicielles.

Ne vous lancez-pas directement dans le langage Arduino ( langage C ), faites d'abord un codage symbolique que vous traduirez ensuite en langage C.

Cordialement.

Pierre

merci du conseil, je pense que ça aussi ça va m'aider :wink:

mouaif ... j'ai l'impression de tourner en rond ...

ça ressemble à quelque chose ?

//declaration de variables
//variable etat = low
//variable temps = 0

void setup() {
  //pin 2 en OUTPUT
  //serialbegin(9600)
  //un attachinterrupt qui prend en compte les CHANGE => tick

}

void loop() {

//recuperation de la variable dans tick
   // si variable etat  = low => il compte le temps => stockage var 1
  // si variable etat  = high => il compte le temps => stockage var 2
  // si variable etat  = low => il compte le temps => stockage var 3
  // si variable etat  = high => il compte le temps => stockage var 4
  etc ...
  etc...
  //totalise toutes les variables pour avoir le temps total (var 1 + .... + var 8)
  //converti en angle chaque temps de fermeture (high)
   //affichage de la var 2 qui sera une fermeture (high)
//affichage de la var 4 qui sera une fermeture (high)
//affichage de la var 6 qui sera une fermeture (high)
//affichage de la var 8 qui sera une fermeture (high)
//delay 500
 
}

void tick() {
  //un digitalread qui lit le signal
  //stockage de cet etat dans la variable etat
 }

l'espoir faisant vivre, j'ai fait ce petit programme, qui dans un malentendu pourrait fonctionner :confused:

qu'en pensez vous ?

const byte interruptPin = 2;
volatile byte state = LOW;
int unsigned long temps = 0;
int unsigned long periode1 = 0;
int unsigned long periode2 = 0;
int unsigned long periode3 = 0;
int unsigned long periode4 = 0;
int unsigned long periode5 = 0;
int unsigned long periode6 = 0;
int unsigned long periode7 = 0;
int unsigned long periode8 = 0;

void setup() {
  pinMode(interruptPin, OUTPUT);
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
}

void loop() {
  if(digitalRead(interruptPin) == LOW){
  static unsigned long previousMicros = 0; 
  unsigned long currentMicros = micros(); 
  

  periode1 = currentMicros - previousMicros; 
  
  
  previousMicros = currentMicros; }

  if(digitalRead(interruptPin) == HIGH){
  static unsigned long previousMicros = 0; 
  unsigned long currentMicros = micros(); 
  

  periode2 = currentMicros - previousMicros; 
  
  
  previousMicros = currentMicros; }
  if(digitalRead(interruptPin) == LOW){
  static unsigned long previousMicros = 0; 
  unsigned long currentMicros = micros(); 
  

  periode3 = currentMicros - previousMicros; 
  
  
  previousMicros = currentMicros; }
  if(digitalRead(interruptPin) == HIGH){
  static unsigned long previousMicros = 0; 
  unsigned long currentMicros = micros(); 
  

  periode4 = currentMicros - previousMicros; 
  
  
  previousMicros = currentMicros; }
  if(digitalRead(interruptPin) == LOW){
  static unsigned long previousMicros = 0; 
  unsigned long currentMicros = micros(); 
  

  periode5 = currentMicros - previousMicros; 
  
  
  previousMicros = currentMicros; }
  if(digitalRead(interruptPin) == HIGH){
  static unsigned long previousMicros = 0; 
  unsigned long currentMicros = micros(); 
  

  periode6 = currentMicros - previousMicros; 
  
  
  previousMicros = currentMicros; }
  if(digitalRead(interruptPin) == LOW){
  static unsigned long previousMicros = 0; 
  unsigned long currentMicros = micros(); 
  

  periode7 = currentMicros - previousMicros; 
  
  
  previousMicros = currentMicros; }
  if(digitalRead(interruptPin) == HIGH){
  static unsigned long previousMicros = 0; 
  unsigned long currentMicros = micros(); 
  

  periode8 = currentMicros - previousMicros; 
  
  
  previousMicros = currentMicros; }
  Serial.println(1000000 / periode1 * 60);
  Serial.println(1000000 / periode2 * 60);
  Serial.println(1000000 / periode3 * 60);
  Serial.println(1000000 / periode4 * 60);
  Serial.println(1000000 / periode5 * 60);
  Serial.println(1000000 / periode6 * 60);
  Serial.println(1000000 / periode7 * 60);
  Serial.println(1000000 / periode8 * 60);
 
  
 }

void blink() {
  state = !state;
}

Ce que vous avez écrit en langage symbolique puis traduit en C montre que vous n'avez pas vraiment assimilé la philosophie du fonctionnement des interruptions.

Je ne peux que vous inviter à revoir cela en tapant par exemple dans votre moteur de recherche :"Arduino les interruptions matérielles" et de lire et chercher à comprendre la philosophie de la chose sans pour l'instant chercher à détailler plus précisément.

Une fois que vous aurez assimilé ce principe, vous verrez que son application vous paraitra plus claire.

Pour résumer :

  • une interruption c'est une entrée matérielle de l'Arduino
  • quand il y a un changement dans cette entrée, l'Arduino effectue une tache courte (ISR) consistant principalement à noter le moment où cela s'est produit
  • Après, dans le fonction loop(), l'Arduino va scruter cycliquement les données que l'ISR a modifiées et faire les traitements appropriés.
    Dans les liens que vous trouverez sur internet, cela vous sera expliqué de différentes manières. Il y en aura certainement une qui fera "tilt" chez vous.

Cordialement.

Pierre