Interruption et capteur effet hall.

Bonsoir,
Je suis en train de construire un led globe(POV) compose de 48 led(6 registre a decallage).
je l ai teste avec un code simpliste sans prendre en compte mon capteur effet hall
qui me permet de determiner le temps que dure un tour et j arrive a obtenir mon image non stabilise.
Bref, depuis j essaie d ajoute ce fameux capteur a mon code en utilisant les interruption mais je n arrive pas.
Je sais pas si je procede correctement.
je vous donne mon code :

unsigned char data[516];

int larg = 86;

byte dataPin = 5;
byte clockPin = 6;
byte lockPin = 7;

volatile bool reload = 0;

unsigned long tmpActuel = 0;
unsigned long tmpPreced = 0;
unsigned long tmpPause = 0;

void setup()
{
  pinMode(dataPin,OUTPUT);
  pinMode(clockPin,OUTPUT);
  pinMode(lockPin,OUTPUT);
  
  attachInterrupt(1,interrupt,FALLING);
}

void interrupt()
{
  reload = 1;
}

void reloadPauseTime()
{
  tmpActuel = micros();
  tmpPause =  (tmpActuel - tmpPreced) / larg;
  tmpPreced = tmpActuel;
  reload = 0;
}


void loop()
{
  if(reload)
  {
    reloadPauseTime();
  }
  int c = 0;
  for(int i = 0;i<larg;i++)
  {
    //digitalWrite(lockPin,LOW);
    PORTD = B01000000;   //Met lockPin a 0 et laisse clockPin a 1
    for(int j = 0;j<6;j++)
    {
      for(int i = 0;i<8;i++)
      {
        PORTD = B00000000;          //Met clockPin(10) a 0.
        if(!(data[c] & (1u << i)))        //Si i bit de c = 1.
        {
          PORTD = B00100000;        //Met dataPin(8) a 1.
        }
        PORTD = B01000000;          //Remet clockPin(10) a 1.
      } 
      c++;
    }
    //digitalWrite(lockPin,HIGH);
    PORTD = B11000000; //Remet lockPin a 1 et laisse clockPin a 1
    delayMicroseconds(tmpPause);
  }
  
}

Merci d avance.

Bonjour,

Travaille intégralement en interruption (fonction loop() vide).

Dans ton interruption :

  1. prend le temps actuel avec micros()
  2. compare ce temps au temps de l'interruption précédente -> durée de la rotation
  3. stocke le nouveau temps pour l'interruption suivante
  4. lance l'affichage de tes leds avec un délai entre chaque rangée de leds calculé par rapport au temps de la rotation (temps_t / nb_leds)

Comme ça quand ton capteur hall est déclenché l'affichage se lancera de manière synchrone et s'ajustera à la vitesse de rotation.

OK merci je vais tenter ca.J y avais deja vaguement songe mais j ai lu que l on ne pouvais pas utiliser la fonction micros() dans la fonction d interruption???

micros() s'arrête pendant les interruptions (comme delay() ou millis()), mais rien n'empêche de stocker sa valeur :wink:

C'est aussi pour à ça qu'on effectue le moins de choses possibles dans les interruptions

J ai tenter ca :(Mais ca marche pas du tout lol)

unsigned char data[];
int larg;

char dataPin = 5;
char clockPin = 6;
char lockPin = 7;

unsigned long tmpActuel = 0;
unsigned long tmpPreced = 0;
unsigned long tmpPause = 0;

void setup()
{
  //DDRD = B11100000;
  pinMode(dataPin,OUTPUT);
  pinMode(clockPin,OUTPUT);
  pinMode(lockPin,OUTPUT);
  EIMSK = B00000010;
  EICRA = B00001000;
  sei();
}

void affichage()
{
  int c = 0;
  for(int i = 0;i<larg;i++)
  {
    //digitalWrite(lockPin,LOW);
    PORTD = B01000000;   //Met lockPin a 0 et laisse clockPin a 1
    for(int j = 0;j<6;j++)
    {
      for(int i = 0;i<8;i++)
      {
        PORTD = B00000000;          //Met clockPin(10) a 0.
        if(!(data[c] & (1u << i)))        //Si i bit de c = 1.
        {
          PORTD = B00100000;        //Met dataPin(8) a 1.
        }
        PORTD = B01000000;          //Remet clockPin(10) a 1.
      } 
      c++;
    }
    //digitalWrite(lockPin,HIGH);
    PORTD = B11000000; //Remet lockPin a 1 et laisse clockPin a 1
    delayMicroseconds(tmpPause);
  }
}

ISR(INT1_vect)
{
  tmpActuel = micros();
  tmpPause = (tmpActuel-tmpPreced) / larg;
  tmpPreced = tmpActuel;
  affichage();
}

void loop()
{
}

J avais bien compris qu il fallait faire le minimum de chose dans l interruption
J ai pas compris comment tous faire dans la fonction d interruption sans utiliser micro ou delay.

Puisque tu as un delay() il faut passer par la loop() :

unsigned char data[];
int larg;

boolean MAJ=0;
boolean Flag=0;

char dataPin = 5;
char clockPin = 6;
char lockPin = 7;

unsigned long tmpActuel = 0;
unsigned long tmpPreced = 0;
unsigned long tmpPause = 0;

void setup()
{
  //DDRD = B11100000;
  pinMode(dataPin,OUTPUT);
  pinMode(clockPin,OUTPUT);
  pinMode(lockPin,OUTPUT);
  EIMSK = B00000010;
  EICRA = B00001000;
  sei();
}

void affichage()
{
  int c = 0;
  for(int i = 0;i<larg;i++)
  {
    //digitalWrite(lockPin,LOW);
    PORTD = B01000000;   //Met lockPin a 0 et laisse clockPin a 1
    for(int j = 0;j<6;j++)
    {
      for(int i = 0;i<8;i++)
      {
        PORTD = B00000000;          //Met clockPin(10) a 0.
        if(!(data[c] & (1u << i)))        //Si i bit de c = 1.
        {
          PORTD = B00100000;        //Met dataPin(8) a 1.
        }
        PORTD = B01000000;          //Remet clockPin(10) a 1.
      } 
      c++;
    }
    //digitalWrite(lockPin,HIGH);
    PORTD = B11000000; //Remet lockPin a 1 et laisse clockPin a 1
    delayMicroseconds(tmpPause);
  }
}

ISR(INT1_vect)
{
  tmpActuel = micros();
if(Flag==1) {
  tmpPause = (tmpActuel-tmpPreced) / larg;
  tmpPreced = tmpActuel;
  MAJ=1;
}
Flag=1;
 }

void loop(){

if(MAJ==1){

   MAJ=0;
   affichage();

}

}

Ok Merci B@tto je vais essaye ca!!!!
Mais j arrive pas a saisir le role de la variable Flag??Vu qu on la remet jamais a 0??

Flag c'est le ptit bonus pour la toute première mesure qui n'a pas de précédent :wink:

tu peux le virer si ça te perturbe !

Ok c est bien ce que je m etais dit.
Bon j arrive enfin a avoir quelque chose mais l affichage est trop rapide, l image a l air stable meme si j essaye de ralentir la rotation l image de change pas ca prouve que le capteur remplit son role, le probleme doit se situer dans le calcul.
Je vois pas d ou ca peut venir, je divise le temps d un tour par le nombre de colonne normalement ca devrait fonctionne =(

Edit: J ai inclus une petite marge d erreur a mon calcul et j ai enfin reussi a stabiliser mon image!!!
Un GRAND merci a vous!!!!