générateur d'impulsions à fréquence et rapport cyclique variable [résolu]

Bonjour, je souhaite réaliser un générateur d’impulsion dont le temps de montée ( sortie 13 à 1) sera de 15ms, et dont l’intervalle entre ces 2 montées sera variable de 1 Hz à 50 Hz.
J’ai parcouru le net, ai trouvé qu’on pourrais le faire avec Timer 4 sur ATmeg250 mais je ne sais pas “gérer” les timer.

Si quelqu’un pouvait m’aider , merci…

Des hertz ce n’est pas un intervalle de temps, c’est une fréquence (l’inverse)

Il vous faudrait une sortie analogique (un CNA) si vous voulez piloter la de montée
Vu les timing dont vous parlez (en ms ou centième de seconde) c’est faisable directement dans la loop et sans timer

Sinon vous pouvez lire cela sur les timers

le code d’exemple donné cependant est faux, l’auteur s’est mélangé les pinceaux avec le ++ après varCompteur au lieu d’avant sans doute dansif (varCompteur++ > 125) {mais c’est pas le plus important

J’ai peur (au vu de son dessin) que l’auteur ne confonde un temps de montée et un temps à l’etat haut.
Une approche sans timer (mais consommant du CPU) est la suivante:
lire l’exemple blinkWitoutDelay
faire une dissymétrie des temps où la LED est allumée et où la LED est éteinte
changer millis() en micros() -ou avoir une granularité temporelle très grossière-

Ah oui Effectivement je n’avais pas vu l’image

Au fait il y a une PWM Frequency library qui permet une abstraction de tout la « complexité » des timers

hello
je viens de faire ce bout de code, si cela peux t'aider
il tourne sur UNO
change la valeur en ligne 8 pour avoir la fréquence
tu peux imaginer la lecture d'un potar pour règler cette valeur pour avoir la fréquence que tu cherches
(1 à 50 Hz)

#define toggle_pulse digitalWrite (PULS, !digitalRead(PULS))
#define PULS                         8                   // pin 8 pour les PULS
int   compteur                =     0;
int   partie_utile              =   29; //29 = 15ms
int   compt                   =  partie_utile;
bool  isr                     = true;
int   periode                 =   40; //1950 pour 1 hz et 40 pour 50hz
unsigned long deb = 0;
byte memo = 0;
void setup() {
 Serial.begin(115200);
  while (!Serial)
  {
    ;                                                   // attente pour l'ouverture du port serie
  }
   cli();
  TCCR2A = 0b00010000; //toggle OC2B sur comparaison trouvée                                 // compteur OCR2B
  TCCR2B = 0b00000011;                                  // pas de prescaler
  TIMSK2 = 0b00000001;                                  // debordements pris en compteautorise les interruptions pour OCA1 pinoche 9
  OCR2B  = 250;//
pinMode(PULS,      OUTPUT); 
sei();
Serial.println("initialisation ok.");                 // annonce de fin des initialisations
  Serial.flush();
memo=digitalRead(PULS);
}

void loop() {
  if(digitalRead(PULS)==!memo)
  {
    Serial.print(digitalRead(PULS));Serial.print("  ");
    Serial.println(micros()-deb);
    memo=digitalRead(PULS);
    deb=micros();
}
}

ISR (TIMER2_OVF_vect)
{
  if (isr)
  { //Serial.println(compt);Serial.flush();
    if (compteur++ >= compt )
    {
      toggle_pulse; compteur = 0;

      if (compt == partie_utile)
      {
        compt = periode;
      }
      else
      {
        compt = partie_utile;
      }
    }
  }
}

Quitte à « compliquer » avec les registres, le timer et ISR, autant éviter le digitalWrite combiné au digital read qui va être lent et remplacer

#define PULS                         8                   // pin 8 pour les PULS
#define toggle_pulse digitalWrite (PULS, !digitalRead(PULS))

par le code suivant (puisqu’on connaît la pin à la compilation) #define PULS (PIND = 0b00000001)  // bascule sur pin 8ça fait la bascule en 62.5 nanosecondes au lieu des (à la louche) 8 microsecondes de votre macro, soit environ 130 fois plus rapide

Merci à tous, je viens de rentrer et découvrir vos réponses j’essai demain.
Je donnerai le résultat.

Ps: oui j’ai embrouillé mon dessin avec des ms et des hertz mais vous avez compris ma demande.

:frowning: ;D ;D ;D ;D

Bonjour, j'ai téléchargé le code et j'ai de suite changé
#define PULS 8 // pin 8 pour les PULS
par;
#define PULS (PIND = 0b00000001) // bascule sur pin 8
et ca ne fonctionne pas.

et j'ai remis
#define PULS 8 // pin 8 pour les PULS et là c'est bon.

j'ai ajouté un potard et j'ai bien la variation de fréquence tout en gardant le puls de 15ms
Merci pour l'aide apportée.

#define toggle_pulse digitalWrite (PULS, !digitalRead(PULS))
//#define PULS (PIND = 0b00000001)  // bascule sur pin 8
#define PULS                 6                   // pin 6 pour les PULS
int   compteur                =     0;
int   partie_utile            =   29; //29 = 15ms
int   compt                   =  partie_utile;
bool  isr                     = true;
int   periode                 ;//  40; //1950 pour 1 hz et 40 pour 50hz
unsigned long deb = 0;
byte memo = 0;
int FreqValue;
#define FeqVarie_Pin (A2) // analog pin for wind direction sensor 



void setup() {
 Serial.begin(115200);
  while (!Serial)
  {
    ;                                                   // attente pour l'ouverture du port serie
  }
   cli();
  TCCR2A = 0b00010000; //toggle OC2B sur comparaison trouvée                                 // compteur OCR2B
  TCCR2B = 0b00000011;                                  // pas de prescaler
  TIMSK2 = 0b00000001;                                  // debordements pris en compte autorise les interruptions pour OCA1 pinoche 9
  OCR2B  = 250;//
pinMode(PULS,      OUTPUT); 
sei();
Serial.println("initialisation ok.");                 // annonce de fin des initialisations
  Serial.flush();
memo=digitalRead(PULS);
}

void loop() {
  FreqValue = analogRead(FeqVarie_Pin); 
  periode = map(FreqValue, 0, 1023, 1950, 40);  
  if(digitalRead(PULS)==!memo)
  {
    Serial.print(digitalRead(PULS));Serial.print("  ");
    Serial.println(micros()-deb);
    memo=digitalRead(PULS);
    deb=micros();
}
}

ISR (TIMER2_OVF_vect)
{
  if (isr)
  { //Serial.println(compt);Serial.flush();
    if (compteur++ >= compt )
    {
      toggle_pulse; compteur = 0;

      if (compt == partie_utile)
      {
        compt = periode;
      }
      else
      {
        compt = partie_utile;
      }
    }
  }
}

relisez post 6, je disais de remplacer en gros digitalWrite (PULS, !digitalRead(PULS));par PIND = 0b00000001;  // bascule sur pin 8 mais j'avais conservé les #define pour ne pas trop changer le code

en gros ça donnerait cela:

const byte pulsPin = 8; // la pin de pulsation, ne pas changer car dépendance dans l'ISR
int   compteur                =     0;
int   partie_utile            =   29; //29 = 15ms
int   compt                   =  partie_utile;
bool  isr                     = true;
int   periode                 =   40; //1950 pour 1 hz et 40 pour 50hz
unsigned long deb = 0;
byte memo = 0;

void setup() {
  Serial.begin(115200);
  cli();
  TCCR2A = 0b00010000; //toggle OC2B sur comparaison trouvée                                 // compteur OCR2B
  TCCR2B = 0b00000011;                                  // pas de prescaler
  TIMSK2 = 0b00000001;                                  // debordements pris en compteautorise les interruptions pour OCA1 pinoche 9
  OCR2B  = 250;//
  pinMode(PULS,      OUTPUT);
  sei();
  Serial.println("initialisation ok.");                 // annonce de fin des initialisations
  Serial.flush();
  memo = digitalRead(PULS);
}

void loop() {
  if (digitalRead(PULS) == !memo)
  {
    Serial.print(digitalRead(PULS)); Serial.print("  ");
    Serial.println(micros() - deb);
    memo = digitalRead(PULS);
    deb = micros();
  }
}

ISR (TIMER2_OVF_vect)
{
  if (isr) {
    if (compteur++ >= compt ) {
      PIND = 0b00000001;  // bascule sur pin 8 CABLE EN DUR. 
      compteur = 0;
      if (compt == partie_utile)compt = periode;
      else compt = partie_utile;
    }
  }
}

si ce code était fonctionnel