[AIDE] Compte tour - résultats non stable

Bonjour à tous :)

Je me suis mis il y a peu à l'arduino, je suis donc débutant; sauf en langage C que je connais depuis un bail.

J'ai souci, concernant un compte tour que je dois réaliser dans le cadre d'un projet.

J'utilise pour developper 2 arduino: un premier qui simule un train d'impulsions censé venir du capteur de la machine d'origine (impulsions négatives sur celle-ci), et un deuxième qui est donc le compte tour.

Voici le code du premier arduino:

int outPin = 8;
int pinDecreaseImpulsion = 7;
int pinSendSerial = 6;

long config1 = 1600;
long config2 = 1800;

unsigned long chooseSpeed = config1;

void setup()
{
   Serial.begin(9600);
  pinMode(outPin, OUTPUT);
  pinMode(pinDecreaseImpulsion, INPUT_PULLUP);
  pinMode(pinSendSerial, INPUT_PULLUP);
  
}

void loop()
{
  if (digitalRead(pinDecreaseImpulsion) == LOW) {chooseSpeed+=20; }
  if (digitalRead(pinSendSerial) == LOW) {Serial.print("Valeur="); Serial.println(chooseSpeed);     while (digitalRead(pinSendSerial) == LOW) {delay(10);}     }
  digitalWrite(outPin, HIGH);  
  unsigned long tmpTime = chooseSpeed;
  while (tmpTime>16383) {  delayMicroseconds(16383); tmpTime -= 16383;}      // delayMicroseconds valeur max 16383
  delayMicroseconds(tmpTime);
  digitalWrite(outPin, LOW);   
  while (tmpTime>16383) {  delayMicroseconds(16383); tmpTime -= 16383;}      
  delayMicroseconds(tmpTime);
      
}

Le code du second arduino:

int pin = 3;
volatile unsigned long duration = 0;
volatile unsigned long lastPulse;

void setup() {
    Serial.begin(9600);
        attachInterrupt(0, gestionINT0, FALLING);
        pinMode(pin, INPUT_PULLUP);
        lastPulse = micros();
}

void loop() {
  

if (duration > 0) {
  Serial.print("Duree="); Serial.println(duration);
} else {
  Serial.println("Duree NULLE");
}
delay(1000);
}

void gestionINT0() {
  //duration = pulseIn(pin, HIGH, );
  duration = micros() - lastPulse;
  lastPulse = micros();
}

Mes problèmes : - La sortie du second arduino est anarchique à certains moment... Il y a des fluctuations allant jusqu'à 19 millisecondes, inacceptable pour le compte tour... - Je croyais que l'utilisation d'une interruption était précise, je me suis trompé quelque part ?

Merci si vous pouvez m'aider ;)

Edit: Voici la sortie moniteur: Duree=2920 Duree=9740 Duree=10020 Duree=12988 Duree=12980 Duree=2916 Duree=9876 Duree=3248 Duree=6492 Duree=8076 Duree=6492 Duree=6492 Duree=1880

Pfffffffffffffffffff..... :'(

Bonjour,

Le problème vient sans doute de la génération de l'impulsion. Tu l'as régardée à l'oscillo ? Quoiqu'il en soit, utilise plutôt la fonction "tone" pour être plus sûr d'avoir quelque chose de propre.

Salut!

Tiens, hier soir, j'ai répondu à une question très... semblable, ou du moins, c'est la même erreur.

Premier arduino : dans loop(), tu déclares chooseSpeed dans la fonction, du coup, à chaque boucle, c'est une nouvelle variable, il faut la déclarer en global.

  if (digitalRead(pinSendSerial) == LOW) {Serial.print("Valeur="); Serial.println(chooseSpeed);     while (digitalRead(pinSendSerial) == LOW) {delay(10);}     }

n'hésite pas à passer à la ligne, c'est plus facile à lire... ensuite, ton while qui gère le delaimicroseconde, je ne comprends pasl'interrêt, c'est zarbi...

Hello. ChooseSpeed est déjà en global ;) Et le coup des boucles, c'est à cause du fait que la fonction de delaymicro ne prend pas au dessus d'un entier 16383.

Et à l'oscillo oui, la fréquence est celle voulue, que je peux faire varier (comme vous voyez sur le programme 1 ). Si ce n'est qu'elle est "bizarre", je n'ai ni un carré, ni une sinusoide ... ca ressemble à .... des pulsions cardiaque un peu ^^

Ninnin: Et à l'oscillo oui, la fréquence est celle voulue, que je peux faire varier (comme vous voyez sur le programme 1 ). Si ce n'est qu'elle est "bizarre", je n'ai ni un carré, ni une sinusoide ... ca ressemble à .... des pulsions cardiaque un peu ^^

Et cette fréquence, elle devrait ressembler à quoi en fait ? Un carré ou non ? En tout cas, ce que tu fais pour la générer n'est pas propre du tout. Pour générer un train d'impulsion, il ne faut pas faire bagoter les sorties digitales mais utiliser les ressources dédiées du micro (genre PWM ou autre), basées sur des timers. Ce n'est pas toi qui doit simuler un timer avec du delayMicro.

Ce que je veux dire, c'est qu'il me semble que la première étape serait d'être sûr d'avoir un bon signal carré, à fréquence fixe (même si au final tu la veux variable). Ca te permet ainsi d'éliminer une source de problème: si ta lecture fonctionne avec un signal carré nickel, ensuite tu passes à une fréquence variable (avec tone(), j'ai un exemple de code si tu veux), etc... Si ta lecture ne fonctionne pas avec un signal carré nickel, c'est que la lecture est foireuse et du coup on peut debugger la lecture.

Je veux bien ton bout de code avec tone, histoire de voir si je peux faire une fréquence variable avec 2 entrée (une pour fréqu++ et une pour fréqu-- ) :)

C'est issu d'un programme qui donne une consigne de vitesse variable pour un moteur pas-à-pas. Ici, la fréquence variable dépend du temps, mais tu peux très bien la faire varier par un autre moyen. La fréquence est mise à jour toutes les 100 ms (environ, j'ai utilisé ici un delay parce que je n'avais pas besoin d'un truc trrès précis). Attention: ne pas confondre la fréquence du signal (entre 200 et 400 Hz dans cet exemple) et la cadence de mise à jour de cette fréquence (10 Hz).

// Définitions et déclarations pour le moteur pas à pas
#define stepMoteur  8

// Cadence d'échantillonnage en ms
#define CADENCE_MS 100
volatile double dt = CADENCE_MS/1000.;
volatile double temps = -CADENCE_MS/1000.;

// Déclaration des variables concernant la commande la la mesure de vitesse du moteur
static double freq = 0.;
static int rapport_step ;

// Initialisations
void setup(void) {
  
  pinMode(stepMoteur, OUTPUT);
  pinMode(13, OUTPUT);

  // Liaison série
  Serial.begin(9600);
  Serial.flush();

  rapport_step = 16 ; // Quand on est en full step

}

// Boucle principale
void loop() {

  // On passe de 400 Hz (2 tr/s) à 200 Hz (1 tr/s) en 5 secondes,
  // puis on reste à 2 Hz
  if (temps>5) {
    digitalWrite(13,HIGH);
  }
  else {
    temps = temps + dt;
  }
  freq = -40*temps + 400;
  tone(stepMoteur,(int)(freq)*rapport_step);
  
  delay(CADENCE_MS);
  
  
}

Merci beaucoup pour ce bout de code, que j'ai adapté à ma sauce.

Après avoir chargé cela dans l'arduino, ben.... c'était encore pire à l'oscillo .....

Du coup, prit d'un doute, j'ai pris un autre arduino ...... Et là, nickel :astonished:

Du coup je me demande si j'ai pas un souci avec mon UNO ....

Je fonctionne donc pour le moment avec deux nano .....

Mais ça marche :)

Thanks :)

Bonjour !

Je reviens car ça m'embete un peu cette histoire...

vous auriez une idée du pourquoi ça ne fonctionne pas sur un arduino ?

J'ai pensé à un composant defectueux, mais lequel ?

Essaie sur une autre broche peut-être ?

Sortie toujours aussi anarchique :roll_eyes:

J'ai retiré le ATMEGA de son support, placé celui-ci sur l'autre circuit imprimé (le board fonctionnel) et ça fonctionne. Donc je peux déjà exclure le micro.