LOCODUINO
Parlons Arduino => Débuter => Discussion démarrée par: Rob1 le juillet 09, 2018, 08:59:33 pm
-
Bonsoir à tous
Je dit petite énigme car je suis convaincu qu'elle ne résistera pas à la pertinence de certains d'entre vous.
Contexte un ATtiny85 pilote un émetteur Infrarouge (IR) dont le faisceau est détecté par un récepteur
raccordé à la broche 2 d'un Arduino Uno.
La trame, telle que visible sur l'image ci-dessous montre un bit de Start de 100ms suivit de 6 bits de 20 ms
chacun séparé par un LOW de 20ms.
Le programme ci-dessous est volontairement simplifié pour mes test, particulièrement la fonction ISR
void DecodeIR2() {
Serial.println(millis());
}
Le tableau excel suivant liste dans
la première colonne contient le résultat du Serial.println(millis());
la seconde est le calcul de la période correspondante
Vous pouvez constater que l'instruction Serial.println(millis()); semble être exécutée deux fois consécutivement.
Merci de votre aide
Amicalement Roland
// déclaration de constantes
const int InputIR = 2;
const int ledPin12 = 12;
volatile unsigned long TimeIR2 = 0;
volatile unsigned long TimeIR2mem = 0;
volatile unsigned long CptIR2 = 0;
int IRState = 0; // variable pour la lecture IR2
void setup() {
Serial.begin(500000);
Serial.println("Prog OK");
// initialisation de la broche 2 en Input
// pinMode(InputIR, INPUT);
// initialisation de la broche 12 en Output
pinMode(ledPin12, OUTPUT);
attachInterrupt(0, DecodeIR2, RISING);
}
void loop() {
// copie de l'entrée IR dans la sortie 12
// IRState = digitalRead(InputIR);
// digitalWrite(ledPin12, IRState);
}
void DecodeIR2() {
Serial.println(millis());
}
-
Complément d'info
J'ai ajouté un compteur dans la fonction d'interruption comme suit
void DecodeIR2() {
CptIR2 ++;
Serial.println(CptIR2);
Serial.println(millis());
}
et j'obtient ceci sur la console
Prog OK
1
38
2
38
3
77
4
77
5
116
6
116
On constate que la fonction d'interruption est systématiquement visitée deux fois dans la même milliseconde !!! ???
J'hésite à solliciter Hercule Poirot il est en route pour Saint-Pétersbourg pour voir les Belges et les Anglais ;) :D ;D
-
Bonjour Rob1
En branchant l'oscilloscope sur la broche 2 du Uno, que voit on ?
-
Bonjour Jean Luc
Il est branché sur la broche 2.
J'ai pris un deuxième cliché à 50 µs voir mieux voir le front.
A noté que l'oscilloscope est un simple DS202 je ne suis pas sûr des ses perf.
Merci de me consacrer un peu de ton temps
Amicalement Roland
-
Et si tu affiches micros() au lieu de millis() ?
-
Oui j'ai déjà fait le test.
Il y a plus ou moins 600 µs d'écart entre les valeurs qui apparaissent identique en ms.
Je pourrait contourner le problème mais c'est toujours mieux de savoir pour progresser.
-
Je vais entreprendre le test suivant pour éviter l'instruction serial.print à chaque appel de fonction
Je vais faire produire à l'ATtiny un signal carré à 500Hz
Sur l' Arduino je compterai les pulses et je ne "printerai" que toutes les 500 pulses
je verrai mieux la périodicité de la fonction interruption.
-
Oui j'ai déjà fait le test.
Il y a plus ou moins 600 µs d'écart entre les valeurs qui apparaissent identique en ms.
Je pourrait contourner le problème mais c'est toujours mieux de savoir pour progresser.
Et donc à l'oscillo tu vois 2 fronts séparés de 600µs ?
-
Non je ne vois rien. Pourtant je suppose que mon étage d'entrée est peut-être en cause.
Il est constitué d'un simple module reflex infrarouge identique au Jpg ci-dessous sur lequel j'ai coupé la diode émetteur.
Suite au test, numéro 1, sous interruption avec une fréquence de signal de 100Hz, la périodicité de la tâche est proche de 5ms au lieu de 10ms attendu.
Info complémentaire
J'ai fait un nouveau test, numéro 2, en délaissant la tâche interruption au profit du Loop (voir code) .
et là j'obtient bien une périodicité de 10ms (9,8 précisément) .
// déclaration de constantes
const int InputIR = 2;
int mem = 0;
volatile unsigned long CptIR2 = 0;
int IRState = 0; // variable pour la lecture IR2
void setup() {
Serial.begin(500000);
Serial.println("Prog OK");
pinMode(InputIR, INPUT);
}
void loop() {
IRState = digitalRead(InputIR);
if (IRState==HIGH && mem==0){
mem = 1;
CptIR2 ++;
if (CptIR2>99) {
CptIR2=0;
Serial.println(micros());
}
}
if (IRState==LOW && mem==1){
mem = 0;
}
}
-
Suite et sans doute fin.
Comme il n'était pas question de douter de l'Arduino et
que mon si petit programme ne semblait pas présenter de faille
je me suis résolu à changer mon capteur pour un autre type, voir Jpg.
Et miracle cela fonctionne correctement.
Je suppose qu'avec l'autre il y a un pulse que le scope ne voit pas.
Comme toujours les bons outils font les bons ouvriers et inversement.
Merci à Jean Luc pour ton aide
Rob1 le chef de gare.........
Je vais quand même refaire un test avec un autre capteur du premier type
pour voir si c'est un problème de modèle ou d'exemplaire.
-
J'ai utilisé ce genre de module avec quelques soucis : sensibilité à la lumière parasite et parasitage ...
Comme détecteur d'occupation, il faut mettre un condensateur de 100 µF, minimum 6,3V (mais les 25V sont tout petit) en parallèle sur la diode détectrice çàd en parallèle sur le 100nF (104) pour obtenir une tempo de l'ordre de 1s. Et un petit tube sur cette diode détectrice.
Là c'est plutôt l'autre entrée qu'il faut filtrer.
-
Merci de tes conseils que je vais adapter.
Je ne peux pas filtrer autant car je veux détecter une suite d'impulsion de 1ms chacune.
Le problème de la lumière ne devrait pas se poser car le récepteur IR est à l'ombre de la motrice
qui porte l'émetteur.
-
Sur, ce n'est pas le signal qu'il faut filtrer, mais la référence. Et peut être aussi l'alimentation sur le circuit.
Attention, à toutes fins utile, la diode est sensible latéralement (et via les réflexions) ...
-
Merci
Je donnerai des nouvelles lorsque j'aurai réalisé mes test embarqués.
Pour le moment je suis en statique dans mon bureau.
Cordialement Roland