Table des matières

Diviseur de fréquence + affichage nombre de fronts descendants sur MAX7221

C'est cette version qui sert à évaluer si il y a des pertes d'images avec le banc stéréo Ueye.

La sortie de la caméra maître doit être connectée a l'entrée 12 de l'arduino.

Une led est connectée entre gnd et la broche 13 de l'arduino avec une résistance de limitation de courant en série.

L'afficheur module MAX7219 est connecté sur le port SPI de l'arduino:

  1. CLK= broche 11
  2. CS= broche 10
  3. DIN= broche 9

Installer la librairie arduino: https://bvdp.inetdoc.net/files/synchro_camera/LedControl.zip

diviseuranddisplay.ino
 /* created by Bertrand VANDEPORTAELE */
const int inputPin = 12; //signal d'entrée
const int ledPin = 13; //broche 13=PB5
 char val=0;
char cpt=0;
unsigned int cpt2=0;
 
 
/* We start by including the library */
#include "LedControl.h"
 
 
 
/*
 * Now we create a new LedControl.
 * We use pins 12,11 and 10 on the Arduino for the SPI interface
 * Pin 9 is connected to the DATA IN-pin of the first MAX7221
 * Pin 11 is connected to the CLK-pin of the first MAX7221
 * Pin 10 is connected to the LOAD(/CS)-pin of the first MAX7221
 * There will only be a single MAX7221 attached to the arduino
 */
LedControl lc = LedControl(9, 11, 10, 1);
 
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void displayvalue(unsigned int val)
{
   lc.setChar(0, 0, '0'+val%10, false);
   lc.setChar(0, 1, '0'+(val/10)%10, false);
   lc.setChar(0, 2, '0'+(val/100)%10, false);
   lc.setChar(0, 3, '0'+(val/1000)%10, false);
   lc.setChar(0, 4, '0'+(val/10000)%10, false);
 
}
////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
  // start serial port at 9600 bps:
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  pinMode(inputPin, INPUT);
  /* while(1)    //pour test recopie simple
 {
   val = (PINB>>4) & 1;
 PORTB =  (PORTB & 0xdf) | (val<<5);
 }*/
 
  //wake up the MAX72XX from power-saving mode
  lc.shutdown(0, false);
  //set a medium brightness for the Leds
  lc.setIntensity(0, 8);
  //  lc.setLed(0,2,7,true);
  lc.setChar(0, 0, ' ', false);
  lc.setChar(0, 1, ' ', false);
  lc.setChar(0, 2, ' ', false);
  lc.setChar(0, 3, ' ', false);
  lc.setChar(0, 4, ' ', false);
  lc.setChar(0, 5, ' ', false);
  lc.setChar(0, 6, ' ', false);
  lc.setChar(0, 7, ' ', false);
  cpt2=0;
 
 
  }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop()
{
 while(1)
 {
while( ( (PINB>>4) & 1)==1); //attente front descendant 
cpt++;
if (cpt>=5)  //facteur de division /2 
{
//  delayMicroseconds(150); 
  PORTB =  (PORTB & 0xdf) | (val<<5);
  cpt=0;
  if (val==0) val=1; else val=0; 
}
 
 
 displayvalue(cpt2);
 cpt2++;
 if (cpt2>10000)
 cpt2=0;
while( ( (PINB>>4) & 1)==0); //attente front montant
}
}

Diviseur de fréquence

diviseur.ino
 /* created by Bertrand VANDEPORTAELE */
const int inputPin = 12; //signal d'entrée
const int ledPin = 13; //broche 13=PB5
 char val=0;
char cpt=0;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
  // start serial port at 9600 bps:
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  pinMode(inputPin, INPUT);
  /* while(1)    //pour test recopie simple
 {
   val = (PINB>>4) & 1;
 PORTB =  (PORTB & 0xdf) | (val<<5);
 }*/
  }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop()
{
 while(1)
 {
while( ( (PINB>>4) & 1)==0); //attente front montant
cpt++;
if (cpt>=5)  //facteur de division /2 
{
  delayMicroseconds(15); 
  PORTB =  (PORTB & 0xdf) | (val<<5);
  cpt=0;
  if (val==0) val=1; else val=0; 
}
while( ( (PINB>>4) & 1)==1); //attente front descendant
}
}

Générateur précis avec moyennage sur la période du signal généré

timerprecis2.ino
 /* created by Bertrand VANDEPORTAELE */
#include <SPI.h>
#include <util/atomic.h>
#define XOR ^
 
const int ledPin = 13; //broche 13=PB5
 
//valeur étalonnée de l'intervale de temps entre chaque interruption Timer, mesurée à l'oscillo en moyennant
//valeur correcte pour la carte copie arduino avec oscillateur à quartz
#define INTERVALE_IT_NS 260020
//Valeur à régler de l'intervale de temps en ns entre chaque commutation de la broche
//commutation chaque 1/15 de seconde
// #define INTERVALE_COMMUT_NS 66666667
//commutation chaque 1/120 de seconde
//#define INTERVALE_COMMUT_NS   8333333
//commutation chaque 1/10 de seconde
#define INTERVALE_COMMUT_NS 100000000
//commutation chaque 4 secondes, valeur proche du max
//  #define INTERVALE_COMMUT_NS 4000000000
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned long int cpt = 0; //peut compter jusquà  4*10^ 9, soit 4 secondes entre chaque commutation
#define PRESCALER_INDEX 3
#define TIMER_PERIOD 8000
// TIMER ISR VECTOR and configuration
unsigned char isr_modulo_count, global_isr_modulo = 0 ;
ISR(TIMER2_COMPA_vect) {
  //transmit interrupt
  cpt = cpt + INTERVALE_IT_NS;
  if (cpt >= INTERVALE_COMMUT_NS)
  {
    cpt -= INTERVALE_COMMUT_NS;
    PORTB ^= 0x01 << 5 ; //bit 5 du port B
  }
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setupTimer2(unsigned char prescaler, unsigned int period) {
  TCCR2A = 0;// set entire TCCR2A register to 0
  TCCR2B = 0;// same for TCCR2B
  TCNT2  = 0;//initialize counter value to 0
  OCR2A = period;// = (16*10^6) / (8000*8) - 1 (must be <256)
  // turn on CTC mode
  TCCR2A |= (1 << WGM21);
  switch (prescaler) {
    case 0 :
      // Set CS20 bit for no prescaler
      TCCR2B |= (1 << CS20);
    case 1 :
      // Set CS21 bit for 8 prescaler
      TCCR2B |= (1 << CS21);
    case 2 :
      // Set CS21 bit for 64 prescaler
      TCCR2B |= (1 << CS21) | (1 << CS20);
      break ;
    case 3 :
      // Set CS21 bit for 128 prescaler
      TCCR2B |= (1 << CS22) ;
      break ;
    case 4 :
      // Set CS21 bit for 256 prescaler
      TCCR2B |= (1 << CS22) | (1 << CS21);
      break ;
    case 5 :
      // Set CS21 bit for 1024 prescaler
      TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20);
      break ;
    default :
      TCCR2B |= (1 << CS20);
      break ;
  }
  // enable timer compare interrupt
  TIMSK2 |= (1 << OCIE2A);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
  // start serial port at 9600 bps:
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  cli();//stop interrupts
  setupTimer2(PRESCALER_INDEX, TIMER_PERIOD); // setup interrupt with prescaler (see datasheet for prescaler value, and reload value)
  sei();//allow interrupts
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop()
{
}

Version moins précise mais avec période du signal généré constante

timerprecis1.ino
/* created by Bertrand VANDEPORTAELE */
#include <SPI.h>
#include <util/atomic.h>
const int ledPin=13; //broche 13=PB5   
#define XOR ^
 #define HEAT_BEAT_DIVIDER_MAX  129
 
 /*
periode  HEAT_BEAT_DIVIDER_MAX  
 520us     1
1042us   2
 1560us       3
 2080us   4
4160us  8
 20300us    39
 20850us    40
1045ms 2000
 1/15seconde ->  130
 */
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int heart_beat_divider = 0 ;
#define PRESCALER_INDEX 3
#define TIMER_PERIOD 8000 
// TIMER ISR VECTOR and configuration
unsigned char isr_modulo_count, global_isr_modulo = 0 ;
ISR(TIMER2_COMPA_vect){
   //transmit interrupt
     heart_beat_divider = heart_beat_divider + 1 ;
      if(heart_beat_divider >= HEAT_BEAT_DIVIDER_MAX){
         PORTB ^= 0x01 <<5 ; //bit 5 du port B
         heart_beat_divider = 0;
      }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setupTimer2(unsigned char prescaler, unsigned int period){
  TCCR2A = 0;// set entire TCCR2A register to 0
  TCCR2B = 0;// same for TCCR2B
  TCNT2  = 0;//initialize counter value to 0
  OCR2A = period;// = (16*10^6) / (8000*8) - 1 (must be <256)
  // turn on CTC mode
  TCCR2A |= (1 << WGM21);
 
  switch(prescaler){
    case 0 :
      // Set CS20 bit for no prescaler
      TCCR2B |= (1 << CS20);
    case 1 :
      // Set CS21 bit for 8 prescaler
      TCCR2B |= (1 << CS21);
    case 2 :
      // Set CS21 bit for 64 prescaler
      TCCR2B |= (1 << CS21) | (1 << CS20);
      break ;   
    case 3 :
      // Set CS21 bit for 128 prescaler
      TCCR2B |= (1 << CS22) ;
      break ; 
    case 4 :
      // Set CS21 bit for 256 prescaler
      TCCR2B |= (1 << CS22) | (1 << CS21);
      break ; 
     case 5 :
      // Set CS21 bit for 1024 prescaler
      TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20);
      break ;  
    default :
      TCCR2B |= (1 << CS20);
      break ;
 
  }
  // enable timer compare interrupt
  TIMSK2 |= (1 << OCIE2A); 
}  
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
   // start serial port at 9600 bps:
  Serial.begin(115200);      
  pinMode(ledPin, OUTPUT);   
  cli();//stop interrupts
  setupTimer2(PRESCALER_INDEX, TIMER_PERIOD); // setup interrupt with prescaler (see datasheet for prescaler value, and reload value)
  sei();//allow interrupts
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop()
{
}