Résolus modifications d'un code

Bonjours à tous, alors voila, pour commander le moteur d'un positionneur rotatif, j'ai besoin d'un "inverter" 3 phases. J'ai donc fabriqué un interface de commane avec drivers, alim, ponts de puissance, etc, et j'ai connecté le tout à ma uno. En cherchant des pistes pour programmerle firmware, j'ai trouvé un prog tout fait, qui s'adapte parfaitement à mon interface de puissance. Impec, je vais pas re-inventer la roue, surtout que je n'ai pas beaucoup de temps, ce moteur étant un outil dont j'ai besoin rapidement. J'ai corrigé de nombreux petits trucs qui n'allaient pas, ou qui empéchait de compiler. Tout marche seulement voila, il y à un petit problême :la fréquence du pwm est de 31 khz et dans mon cas il me faut une fréquence comprise entre 4 et 12 khz max. Le moteur n'a aucune force. J'ai donc regardé comment changer ça mais c'est du langage avr, pas arduino. Sur ce dernier, je me débrouille à peu prés, sa va. Mais la ... J'ai regardé la datasheet du 328 mais je dois bien avouer que je pige rien. J'ai aussi tenter de retrouver le site ou je l'ai telechargé ou le nom de l'auteur pour le contacter mais j'ai échoué. C'est pourquoi je me tourne vers vous. Y aurait il ici une bonne âme pour me faire les modifications ? Ca me ferait gagner beaucoup de temps. Je n'ai pas pour habitude de chiner des codes tout fait surtout que d'habitude j'ai des besoins assez spécifiques. J'ai réalisé beaucoup de montages et de programmes tout seul, je m'en sort toujours mais là j'ai besoin d'aide.

Merci beaucoup d'avance.

/******************************************************************
 * DDS-sinewave - 3phase
 *
 ******************************************************************/
#include "avr/pgmspace.h"
#include "avr/io.h"
// table of 256 sine values / one sine period / stored in flash memory

PROGMEM prog_uchar sine256[] =
{
  127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,176,178,181,184,187,190,192,195,198,200,203,205,208,
  210,212,215,217,219,221,223,225,227,229,231,233,234,236,238,239,240,242,243,244,245,247,248,249,249,250,251,252,252,
  253,253,253,254,254,254,254,254,254,254,253,253,253,252,252,251,250,249,249,248,247,245,244,243,242,240,239,238,236,
  234,233,231,229,227,225,223,221,219,217,215,212,210,208,205,203,200,198,195,192,190,187,184,181,178,176,173,170,167,
  164,161,158,155,152,149,146,143,139,136,133,130,127,124,121,118,115,111,108,105,102,99,96,93,90,87,84,81,78,76,73,70,
  67,64,62,59,56,54,51,49,46,44,42,39,37,35,33,31,29,27,25,23,21,20,18,16,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0,
  0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,16,18,20,21,23,25,27,29,31,33,35,37,39,42,44,46,49,51,54,56,59,62,64,
  67,70,73,76,78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124
};

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
int PWM_OUT_1 = 11; // PWM output on pin 11
int PWM_OUT_2 = 10; // PWM output on pin 10
int PWM_OUT_3 = 9; // PWM output on pin 9
int LED_PIN = 13; // LED status on pin 13
int TEST_PIN = 7; // Scope trigger on pin 7
int POTEN_IN = A0; // Potentiometer on pin 0
int OFFSET_1 = 85; // Offset for second-phase
int OFFSET_2 = 170; // Offset for third-phase
double dfreq;
const double refclk = 31376.6; // measured
const uint64_t twoTo32 = pow(2, 32); // compute value at startup and use as constant
// variables used inside interrupt service declared as volatile
volatile uint8_t icnt; // var inside interrupt
volatile uint8_t icnt1; // var inside interrupt
volatile uint8_t c4ms; // counter incremented every 4ms
volatile uint32_t phase_accum; // pahse accumulator
volatile uint32_t tword_m; // dds tuning word m
//******************************************************************
void setup()
{
  Serial.begin(115200); // connect to the serial port
  Serial.println("DDS Test");  
  pinMode(LED_PIN, OUTPUT); // sets the digital pin as output
  pinMode(TEST_PIN, OUTPUT); // sets the digital pin as output
  pinMode(PWM_OUT_1, OUTPUT); // PWM output / frequency output
  pinMode(PWM_OUT_2, OUTPUT); // PWM output / frequency output
  pinMode(PWM_OUT_3, OUTPUT); // PWM output / frequency output
  // Setup the timers
  setup_timer1();
  setup_timer2();
  // disable interrupts to avoid timing distortion
  cbi (TIMSK0, TOIE0); // disable Timer0 !!! delay() is now not available
  sbi (TIMSK2, TOIE2); // enable Timer2 Interrupt
  dfreq = 1000.0; // initial output frequency = 1000.0 Hz
  tword_m = twoTo32 * dfreq / refclk; // calulate DDS new tuning word
}
//******************************************************************
void loop()
{
  if (c4ms > 250) // timer / wait for a full second
  {
    c4ms = 0;
    dfreq = analogRead(POTEN_IN); // read Poti on analog pin 0 to adjust output frequency from 0..1023 Hz
    dfreq = map(dfreq,0,1023,1,1023);//freq 1-1023 hz
    cbi (TIMSK2, TOIE2); // disble Timer2 Interrupt
    tword_m = twoTo32 * dfreq / refclk; // calulate DDS new tuning word
    sbi (TIMSK2, TOIE2); // enable Timer2 Interrupt
    Serial.print(dfreq);
//    Serial.print(" ");
//    Serial.println(tword_m);
  }
}
//******************************************************************
// timer1 setup
// set prscaler to 1, PWM mode to phase correct PWM, 16000000/512 = 31.25kHz clock
void setup_timer1()
{
  // Timer1 Clock Prescaler to : 1
  sbi (TCCR1B, CS10);
  cbi (TCCR1B, CS11);
  cbi (TCCR1B, CS12);
  // Timer0 PWM Mode set to Phase Correct PWM
  cbi (TCCR1A, COM1A0); // clear Compare Match
  sbi (TCCR1A, COM1A1);
  cbi (TCCR1A, COM1B0); // clear Compare Match
  sbi (TCCR1A, COM1B1);
  sbi (TCCR1A, WGM10); // Mode 1 / Phase Correct PWM
  cbi (TCCR1A, WGM11);
  cbi (TCCR1B, WGM12);
  cbi (TCCR1B, WGM13);
}
//******************************************************************
// timer2 setup
// set prscaler to 1, PWM mode to phase correct PWM, 16000000/512 = 31.25kHz clock
void setup_timer2()
{
  // Timer2 Clock Prescaler to : 1
  sbi (TCCR2B, CS20);
  cbi (TCCR2B, CS21);
  cbi (TCCR2B, CS22);
  // Timer2 PWM Mode set to Phase Correct PWM
  cbi (TCCR2A, COM2A0); // clear Compare Match
  sbi (TCCR2A, COM2A1);
  sbi (TCCR2A, WGM20); // Mode 1 / Phase Correct PWM
  cbi (TCCR2A, WGM21);
  cbi (TCCR2B, WGM22);
}
//******************************************************************
// Timer2 Interrupt Service at 31.25kHz = 32us
// this is the timebase REFCLOCK for the DDS generator
// FOUT = (M (REFCLK)) / (2 exp 32)
// runtime : 8 microseconds ( inclusive push and pop)
ISR(TIMER2_OVF_vect)
{
  sbi(PORTD, TEST_PIN); // Test / set PORTD,TEST_PIN high to observe timing with a oscope
  phase_accum += tword_m; // soft DDS, phase accu with 32 bits
  icnt = phase_accum >> 24; // use upper 8 bits for phase accu as frequency information
  OCR2A = pgm_read_byte_near(sine256 + icnt); // read value fron ROM sine table and send to PWM DAC
  OCR1A = pgm_read_byte_near(sine256 + (uint8_t)(icnt + OFFSET_1));
  OCR1B = pgm_read_byte_near(sine256 + (uint8_t)(icnt + OFFSET_2));
  if (icnt1++ == 125) // increment variable c4ms every 4 milliseconds
  {
    c4ms++;
    icnt1 = 0;
  }
  cbi(PORTD, TEST_PIN); // reset PORTD,TEST_PIN
}

Et ceci ?

http://playground.arduino.cc/Code/PwmFrequency

Tout marche seulement voila, il y à un petit problême :la fréquence du pwm est de 31 khz et dans mon cas il me faut une fréquence comprise entre 4 et 12 khz max.

Pourrais-tu éclarcir un point, tu parles de la fréquence du PWM ou de celle du sinus synthétisé? Parce qu'au final toi ce qu'il te faut c'est bien un sinus (ou j'ai mal compris ton besoin). Plus le PWM sera élevé plus le filtrage sera simple (composants moins volumineux, fréquence de coupure moins critique ...) et plus le sinus sera "propre".

Bonjours Poogahzi et fdufnews, merci de vous interresser à mon cas. Poogahzi merci pour le lien, je vais le mettre de coté et tâcher d'apprendre quelque chose. Mais je me demande si je peux adapter ce code directement sans influencer le reste (interuptions, etc)? fdufnews en fait le code genére 3 sinus entre 1 et 1023 hz (en fonction de la tension sur A0) decalés de 120 degrés avec un pwm fixé à 31250 hz.(sur les broches 9,10 et 11). Sa ne fonctionne pas parce que mon positionneur contient les filtres sur les phases ainsi que les capteurs de positions, ces filtres sont centrés sur 6 à 8 khz apparement, donc à 31250 hz il y a trop de perte et le moteur "sonne" mais décolle dificilement. Voila si il manque des données, n'hésitez pas. Encore merci.

C’est normal que le 31kHz soit rejeté. La fréquence qui “intéresse” tes moteurs c’est celle du sinus qui ne dépasse pas 1KHz. Il faudrait d’ailleurs que tu filtres en sortie de ta Uno pour éviter que les harmoniques crées par la synthèse de fréquence (et les PWM) ne perturbent toute ta chaîne.

Oui c'est pour ça que je dois faire baisser la fréquence du pwm, c'est mon seul problême actuellement. En fait, en sortie de la uno, j'attaque un filtre et des comparateurs pour "splitter" le signal en 2 demi phases avant d'entrer dans les drivers de mosfet. Les grilles des mosfet ne reçoivent que les crénaux dont ils ont besoin, plus un temps morts pour éviter la cross-conduction. Tout fonctionne à merveille, mais j'ai juste besoin de rammener la fréquence du pwm dans la plage voulue. Je pense qu'il doit avoir moyen de faire ça simplement mais c'est en dehors de mes compétences. Je suis éléctronicien de formation, je me suis mis à arduino pour avancer plus loin en electronique, le language arduino me permet de réaliser mes ambitions dans la plupart des cas, mais la je dois dire que ça coince. Peut tu m'indiquer ce que je dois changer dans le code pour arriver à mes fins ?

Merci beaucoup en tous cas.

hello, peux tu tester

/******************************************************************
 * DDS-sinewave - 3phase
 *
 ******************************************************************/
#include "avr/pgmspace.h"
#include "avr/io.h"
// table of 256 sine values / one sine period / stored in flash memory

PROGMEM  const char sine256[] =
{
  127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,176,178,181,184,187,190,192,195,198,200,203,205,208,
  210,212,215,217,219,221,223,225,227,229,231,233,234,236,238,239,240,242,243,244,245,247,248,249,249,250,251,252,252,
  253,253,253,254,254,254,254,254,254,254,253,253,253,252,252,251,250,249,249,248,247,245,244,243,242,240,239,238,236,
  234,233,231,229,227,225,223,221,219,217,215,212,210,208,205,203,200,198,195,192,190,187,184,181,178,176,173,170,167,
  164,161,158,155,152,149,146,143,139,136,133,130,127,124,121,118,115,111,108,105,102,99,96,93,90,87,84,81,78,76,73,70,
  67,64,62,59,56,54,51,49,46,44,42,39,37,35,33,31,29,27,25,23,21,20,18,16,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0,
  0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,16,18,20,21,23,25,27,29,31,33,35,37,39,42,44,46,49,51,54,56,59,62,64,
  67,70,73,76,78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124
};

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
int PWM_OUT_1 = 11; // PWM output on pin 11
int PWM_OUT_2 = 10; // PWM output on pin 10
int PWM_OUT_3 = 9; // PWM output on pin 9
int LED_PIN = 13; // LED status on pin 13
int TEST_PIN = 7; // Scope trigger on pin 7
int POTEN_IN = A0; // Potentiometer on pin 0
int OFFSET_1 = 85; // Offset for second-phase
int OFFSET_2 = 170; // Offset for third-phase
double dfreq;
const double refclk = 31376.6; // measured
const uint64_t twoTo32 = pow(2, 32); // compute value at startup and use as constant
// variables used inside interrupt service declared as volatile
volatile uint8_t icnt; // var inside interrupt
volatile uint8_t icnt1; // var inside interrupt
volatile uint8_t c4ms; // counter incremented every 4ms
volatile uint32_t phase_accum; // phase accumulator
volatile uint32_t tword_m; // dds tuning word m
//******************************************************************
void setup()
{
  Serial.begin(57600); // connect to the serial port
  Serial.println("DDS Test");  
  pinMode(LED_PIN, OUTPUT); // sets the digital pin as output
  pinMode(TEST_PIN, OUTPUT); // sets the digital pin as output
  pinMode(PWM_OUT_1, OUTPUT); // PWM output / frequency output
  pinMode(PWM_OUT_2, OUTPUT); // PWM output / frequency output
  pinMode(PWM_OUT_3, OUTPUT); // PWM output / frequency output
  // Setup the timers
  setup_timer1();
  setup_timer2();
  // disable interrupts to avoid timing distortion
  cbi (TIMSK0, TOIE0); // disable Timer0 !!! delay() is now not available
  sbi (TIMSK2, TOIE2); // enable Timer2 Interrupt
  dfreq = 1000.0; // initial output frequency = 1000.0 Hz
  tword_m = twoTo32 * dfreq / refclk; // calulate DDS new tuning word
}
//******************************************************************
void loop()
{
  if (c4ms > 250) // timer / wait for a full second
  {
    c4ms = 0;
    //dfreq = analogRead(POTEN_IN); // read Poti on analog pin 0 to adjust output frequency from 0..1023 Hz
    dfreq = 1000.0;
    dfreq = map(dfreq,0,1023,1,14000);//freq 1-1023 hz
    cbi (TIMSK2, TOIE2); // disble Timer2 Interrupt
    tword_m = twoTo32 * dfreq / refclk; // calulate DDS new tuning word
    sbi (TIMSK2, TOIE2); // enable Timer2 Interrupt
    Serial.println(dfreq);
    Serial.print(" ");
    Serial.println(tword_m);
  }
}
//******************************************************************
// timer1 setup
// set prscaler to 1, PWM mode to phase correct PWM, 16000000/512 = 31.25kHz clock
void setup_timer1()
{
  // Timer1 Clock Prescaler to : 1
  cbi (TCCR1B, CS10);
  cbi (TCCR1B, CS11);
  sbi (TCCR1B, CS12);
  // Timer0 PWM Mode set to Phase Correct PWM
  cbi (TCCR1A, COM1A0); // clear Compare Match
  sbi (TCCR1A, COM1A1);
  cbi (TCCR1A, COM1B0); // clear Compare Match
  sbi (TCCR1A, COM1B1);
  sbi (TCCR1A, WGM10); // Mode 1 / Phase Correct PWM
  cbi (TCCR1A, WGM11);
  cbi (TCCR1B, WGM12);
  cbi (TCCR1B, WGM13);
}
//******************************************************************
// timer2 setup
// set prscaler to 1, PWM mode to phase correct PWM, 16000000/512 = 31.25kHz clock
void setup_timer2()
{
  // Timer2 Clock Prescaler to : 1
  cbi (TCCR2B, CS20);
  cbi (TCCR2B, CS21);
  sbi (TCCR2B, CS22);
  // Timer2 PWM Mode set to Phase Correct PWM
  cbi (TCCR2A, COM2A0); // clear Compare Match
  sbi (TCCR2A, COM2A1);
  sbi (TCCR2A, WGM20); // Mode 1 / Phase Correct PWM
  cbi (TCCR2A, WGM21);
  cbi (TCCR2B, WGM22);
}
//******************************************************************
// Timer2 Interrupt Service at 31.25kHz = 32us ______________________________ok, confirmé à l'oscillo
// this is the timebase REFCLOCK for the DDS generator
// FOUT = (M (REFCLK)) / (2 exp 32)
// runtime : 8 microseconds ( inclusive push and pop)
ISR(TIMER2_OVF_vect)
{
  sbi(PORTD, TEST_PIN); // Test / set PORTD,TEST_PIN high to observe timing with a oscope_________
  phase_accum += tword_m; // soft DDS, phase accu with 32 bits
  icnt = phase_accum >> 24; // use upper 8 bits for phase accu as frequency information
  OCR2A = pgm_read_byte_near(sine256 + (uint8_t)icnt); // read value fron ROM sine table and send to PWM DAC
  OCR1A = pgm_read_byte_near(sine256 + (uint8_t)(icnt + OFFSET_1));
  OCR1B = pgm_read_byte_near(sine256 + (uint8_t)(icnt + OFFSET_2));
  if (icnt1++ == 125) // increment variable c4ms every 4 milliseconds
  {
    c4ms++;
    icnt1 = 0;
  }
  cbi(PORTD, TEST_PIN); // reset PORTD,TEST_PIN
}

Merci dfgh je vais tester ça et je reviens bientôt.

Bon ba sa marche po …
La fréquence de sortie à chuté à 500 hz environ mais j’ai du mal à mesurer parce qu’en plus le signal est instable, un peu comme si il était interrompu périodiquement a basse fréquence.

une autre tite idée ? humm ?

Merci encore.

veux tu essayer d'autres fréquences j'ai commenté les valeurs à mettre dans ton code( dans les "set up" des timers (nota: je ne voie pas ou est utilisé le timer 1...?) nota le tableau dea valeurs est en page 158 et la suite est en haut de la 159

/******************************************************************
 * DDS-sinewave - 3phase
 *
 ******************************************************************/
#include "avr/pgmspace.h"
#include "avr/io.h"
// table of 256 sine values / one sine period / stored in flash memory

PROGMEM  const char sine256[] =
{
  127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,176,178,181,184,187,190,192,195,198,200,203,205,208, //29
  210,212,215,217,219,221,223,225,227,229,231,233,234,236,238,239,240,242,243,244,245,247,248,249,249,250,251,252,252, //29
  253,253,253,254,254,254,254,254,254,254,253,253,253,252,252,251,250,249,249,248,247,245,244,243,242,240,239,238,236, //29
  234,233,231,229,227,225,223,221,219,217,215,212,210,208,205,203,200,198,195,192,190,187,184,181,178,176,173,170,167, //29
  
  164,161,158,155,152,149,146,143,139,136,133,130,127,124,121,118,115,111,108,105,102,99,96,93,90,87,84,81,78,76,73,70, //32
  67,64,62,59,56,54,51,49,46,44,42,39,37,35,33,31,29,27,25,23,21,20,18,16,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0, //44
  0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,16,18,20,21,23,25,27,29,31,33,35,37,39,42,44,46,49,51,54,56,59,62,64,  //44
  67,70,73,76,78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124                                                   //20
};                                                                                                                   //  256


#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
int PWM_OUT_1 = 11; // PWM output on pin 11
int PWM_OUT_2 = 10; // PWM output on pin 10
int PWM_OUT_3 = 9; // PWM output on pin 9
int LED_PIN = 13; // LED status on pin 13
int TEST_PIN = 7; // Scope trigger on pin 7
int POTEN_IN = A0; // Potentiometer on pin 0
int OFFSET_1 = 85; // Offset for second-phase
int OFFSET_2 = 170; // Offset for third-phase
double dfreq;
const double refclk = 31376.6; // measured
const uint64_t twoTo32 = pow(2, 32); // compute value at startup and use as constant
// variables used inside interrupt service declared as volatile
volatile uint8_t icnt; // var inside interrupt
volatile uint8_t icnt1; // var inside interrupt
volatile uint8_t c4ms; // counter incremented every 4ms
volatile uint32_t phase_accum; // phase accumulator
volatile uint32_t tword_m; // dds tuning word m
//******************************************************************
void setup()
{
  Serial.begin(57600); // connect to the serial port
  Serial.println("DDS Test");  
  pinMode(LED_PIN, OUTPUT); // sets the digital pin as output
  pinMode(TEST_PIN, OUTPUT); // sets the digital pin as output
  pinMode(PWM_OUT_1, OUTPUT); // PWM output / frequency output
  pinMode(PWM_OUT_2, OUTPUT); // PWM output / frequency output
  pinMode(PWM_OUT_3, OUTPUT); // PWM output / frequency output
  // Setup the timers
  setup_timer1();
  setup_timer2();
  // disable interrupts to avoid timing distortion
  cbi (TIMSK0, TOIE0); // disable Timer0 !!! delay() is now not available
  sbi (TIMSK2, TOIE2); // enable Timer2 Interrupt
  dfreq = 1000.0; // initial output frequency = 1000.0 Hz
  tword_m = twoTo32 * dfreq / refclk; // calulate DDS new tuning word
}
//******************************************************************
void loop()
{
  if (c4ms > 250) // timer / wait for a full second
  {
    c4ms = 0;
    //dfreq = analogRead(POTEN_IN); // read Poti on analog pin 0 to adjust output frequency from 0..1023 Hz
    dfreq = 1000.0;
    dfreq = map(dfreq,0,1023,1,14000);//freq 1-1023 hz
    cbi (TIMSK2, TOIE2); // disble Timer2 Interrupt
    tword_m = twoTo32 * dfreq / refclk; // calulate DDS new tuning word
    sbi (TIMSK2, TOIE2); // enable Timer2 Interrupt
    Serial.println(dfreq);
    Serial.print(" ");
    Serial.println(tword_m);
  }
}
//******************************************************************
// timer1 setup
// set prscaler to 1, PWM mode to phase correct PWM, 16000000/512 = 31.25kHz clock
//                                                   1/31250=0.000032
void setup_timer1()
 {                             //                                  CS22  CS11  CS10
  // Timer1 Clock Prescaler to : pas de division de la fréquence     0     0     1
  cbi (TCCR1B, CS10);          //  pour div par 8                    0     1     0
  cbi (TCCR1B, CS11);          //  pour div par 32                   0     1     1
  sbi (TCCR1B, CS12);          //  pour div par 64                   1     0     0
                               //  pour div par 128                  1     0     1
                               //  pour div par 256                  1     1     0
                               //  pour div par 1024                 1     1     1
                               // exemple:  si div par 64:   32µs*64 = 2048µs ==> 1/0.002048= 488Hz
  
  // Timer0 PWM Mode set to Phase Correct PWM
  cbi (TCCR1A, COM1A0); // clear Compare Match
  sbi (TCCR1A, COM1A1);
  cbi (TCCR1A, COM1B0); // clear Compare Match
  sbi (TCCR1A, COM1B1);
  sbi (TCCR1A, WGM10); // Mode 1 / Phase Correct PWM
  cbi (TCCR1A, WGM11);
  cbi (TCCR1B, WGM12);
  cbi (TCCR1B, WGM13);
}
//******************************************************************
// timer2 setup
// set prscaler to 1, PWM mode to phase correct PWM, 16000000/512 = 31.25kHz clock
//                                                   1/31250=0.000032
void setup_timer2()
{                              //                                  CS22  CS21  CS20
  // Timer2 Clock Prescaler to : pas de division de la fréquence     0     0     1
  cbi (TCCR2B, CS20);          //  pour div par 8                    0     1     0
  cbi (TCCR2B, CS21);          //  pour div par 32                   0     1     1
  sbi (TCCR2B, CS22);          //  pour div par 64                   1     0     0
                               //  pour div par 128                  1     0     1
                               //  pour div par 256                  1     1     0
                               //  pour div par 1024                 1     1     1
                               // exemple:  si div par 64:   32µs*64 = 2048µs ==> 1/0.002048= 488Hz
  
  // Timer2 PWM Mode set to Phase Correct PWM
  cbi (TCCR2A, COM2A0); // clear Compare Match
  sbi (TCCR2A, COM2A1);
  sbi (TCCR2A, WGM20); // Mode 1 / Phase Correct PWM
  cbi (TCCR2A, WGM21);
  cbi (TCCR2B, WGM22);
}
//******************************************************************
// Timer2 Interrupt Service at 31.25kHz = 32us ______________________________ok, confirmé à l'oscillo
// this is the timebase REFCLOCK for the DDS generator
// FOUT = (M (REFCLK)) / (2 exp 32)
// runtime : 8 microseconds ( inclusive push and pop)
// temps d'excécution de cette routine d'interruption du timer 2 est de 8 µs
// y compris l'empilage et le dépilage des regitres
// donc l etimer compte pendant 32 µs et sa routine d'interruption dure 8µs
// d'ou le temps entre deux points de la sinusoide est de 32 + 8 = 40µs
ISR(TIMER2_OVF_vect)
{
  sbi(PORTD, TEST_PIN); // Test / set PORTD,TEST_PIN high to observe timing with a oscope_________
  phase_accum += tword_m; // soft DDS, phase accu with 32 bits
  icnt = phase_accum >> 24; // use upper 8 bits for phase accu as frequency information
  OCR2A = pgm_read_byte_near(sine256 + (uint8_t)icnt); // read value fron ROM sine table and send to PWM DAC
  OCR1A = pgm_read_byte_near(sine256 + (uint8_t)(icnt + OFFSET_1));
  OCR1B = pgm_read_byte_near(sine256 + (uint8_t)(icnt + OFFSET_2));
  if (icnt1++ == 125) // increment variable c4ms every 4 milliseconds
  {
    c4ms++;
    icnt1 = 0;
  }
  cbi(PORTD, TEST_PIN); // reset PORTD,TEST_PIN
}

Super, merci. Je vais etudier sa avec attention, je pense que je devrais m'en sortir. Je pense que le timer 1 sers a synthetiser le sinus (en lisant la table)et les 2 autres font le pwm sur les 3 broches de sorties. Enfin, c'est comme sa que je l'ai compris...

Encore un grand merci.

sbi pour mettre 1 cbi pour mettre 0

bin voila la réponse à la question que j'allais te poser, cool Mais dans :

define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))

define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

cbi et sbi sont bien des tableaux,non? mais quelles sont les valeurs affectées ? d'ou sort ce sfr ? Desolé si mes questions semblent connes mais j'aime pas recopier bêtement alors j'essaye de comprendre.

Merci de ta patience.

mais je viens de me rendre compte d'une chôse aprés calcul : la plage est de 3906.25 hz (division par 8 ) à 30.51 hz (division par 1024). c'est juste ?

attention: n'ayant pas le montage, je n'avais pas le potar pour tester. j'ai donc modifié ton code

il faut remettre la lecture du potar et supprimer la valeur par défaut (dfreq = 1000.0;) désolé pour cet oubli. voici la partie en question

void loop()
{
  if (c4ms > 250) // timer / wait for a full second
  {
    c4ms = 0;
   [b] dfreq = analogRead(POTEN_IN); // read Poti on analog pin 0 to adjust output frequency from 0..1023 Hz
    //dfreq = 1000.0;
[/b]    dfreq = map(dfreq,0,1023,1,14000);//freq 1-1023 hz

J'ai l'impression qu'il y a une grosse incompréhension. Ce programme réalise une synthèse de fréquence. Il génère 3 sinus. Les 3 sorties PWM codent l'amplitude des sinus (c'est une forme de conversion numérique-analogique). Après filtrage, tu as 3 sinus dont la fréquence est comprise entre 1Hz et 1023Hz. Tu ne dois pas retrouver la fréquence des PWM. Si tu as des résidus de PWM dans ton montage c'est que ton filtrage n'est pas bon. Maintenant, si tu n'as besoin que de signaux tout ou rien en sortie en non pas de sinus, le plus simple serait de modifier la forme d'onde dans la table à la place du sinus.

cbi = clear bit sbi = set bit sfr = special function register (accès aux registres du processeur) ce sont des macros qui permettent de faire basculer un bit sur un port de sortie en manipulant directement les registres du processeur. Dans le programme ces 2 "macros" sont utiliser pour faire un marqueur qui permet de vérifier la durée de la routine d'interruption. timer1 et timer2 génèrent les PWM. 2 PWM avec le timer1, un PWM avec le timer 2. On utilise l'interruption du timer2 pour rythmer le synthétiseur de fréquence.

oui j'avais vus et je viens de tester : SA MARCHE !!! en tous cas à l'oscillo, j'ai réglé le prescaler à 8 et j'obtiens bien un pwm à 3906 hz et de belles sinusoides de 1 à 1023 hz comme voulu. Sa devrait marcher, je testerais le montage complet demain. Encore un grand merci à toi pour ta patience et ton savoir. Et en plus j'ai appris des choses en passant...

non, ce ne sont pas des tableaux

en assembleur, CBI signifie Clear Bit in I/O Register

c'est écrit sous cette forme CBI A,b ex: CBI $12,7 =>mettre à 0 le bit 7 de l'adresse $12 ( port D du µ)

dans ton code on a une sorte de définition de fonction

define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))

puis un appel à la fonction cbi (TCCR1B, CS10);

je ne connais pas, mais j'ai tendance à penser que c'est l'équivalent de l'assembleur.

pour la plage, oui il semble bien que ce soit ça

Merci fdufnews pour tes explications, c'est beaucoup plus clair pour moi maintenent. Le moteur que je dois commander c'est un positionneur rotatif qui me sert de diviseur pour ma fraiseuse et dont le contrôleur a cramé. Ce moteur a ses propres filtres internes qui sont calculés avec la reluctance interne des bobinages du moteur,et c'est pourquoi sa passait pas.(en tous cas c'est ce que m'a dit le meccano qui me l'a vendu). De plus, des données transitent par ces phases pour remonter jusqu'au controleur. Donc je pense que sa doit jouer aussi.

Voila ce qu je sais. Encore Merci.

Bin je vais mettre tout ça de coté et etudier, c'est une vraie mine d'or.

Merci, Merci