Générateur de fréquence au 100ème

Bonjour,

Est ce que quelqu'un pourrait m'éclairer... Je voudrais savoir s'il serait possible de générer à partir d'arduino un signa de fréquence précis au 100ème.
Je voudrais générer les fréquence 7.38, 15.66, 31.32, 62.64, 125.28, 250.56, 501.12, 1002.24
J'ai déjà utilisé les PWM pour contrôler la vitesse d'un moteur mais je ne pense pas pouvoir les utiliser pour cette application ? Sinon comment je peux solutionner mon problème ? derrière je veux piloter un vibreur linéaire comme ceux installés dans les phones. Ces fréquences sont des fréquences de Diapason. Je voudrais voir s'il est possible d'obtenir une vibration similaire à un diapason mais constante.
Vous remerciant...

Patrice

Bonjour,
avec le timer 1, à partir du quartz de 16 MHz, tu disposes :

  1. d'un diviseur "prescaler" qui peut prendre les valeurs suivantes :
    CS12 CS11 CS10 Description
    0 0 0 Stop timer0
    0 0 1 CK
    0 1 0 CK/8
    0 1 1 CK/64
    1 0 0 CK/256
    1 0 1 CK/1024
  2. du compteur proprement dit, dont les régistres auto reload permettent de diviser d'une valeur comprise entre 1 et 65536

exemple de calcul empirique, en prenant le cas le + défavorable qui serait 1002.24 :
16 000 000 / 1 / 15964 = 1002.255 ; 16 000 000 / 1 / 15965 = 1002.192
-> si ce n'est pas assez précis pour toi, il faudra un mcu plus rapide
-> voici pour la précision, pour la justesse, cela dépendra aussi de celle du quartz

La meilleure solution n'est pas d'utiliser un timer, mais de positionner une sortie à l'état haut ou bas en suivant un écart en us dépendant de la fréquence voulue, dans la loop().

Je ne pense pas.
Les fonctions digitalWrite et digitalRead ne répondent pas à la même vitesse selon la pin concernée. Question précision et stabilité on fait mieux.
Dès que tu modifie le code de loop la fréquence changera, pas terrible.
De plus le temps dont tu parles est obtenu avec un timer............autant utiliser directement un timer en mode CTC.

Voir le site de Mike Gamon pour des exemples détaillés dont certains permettent d'obtenir la fréquence exacte en utilisant des modes CTC indirects.---> voir l'exemple pour obtenir 38 kHz.

les gigues imprévisibles et inquantifiables ne devraient cependant pas fausser la fréquence sur + d'une période, car la correction se fait automatiquement à la comparaison suivante ...

donc je serais plutôt d'accord avec ard_newbie
(mon réflexe d'utiliser le CTC provient d'une exigence d'avoir des signaux propres, ce qui n'est pas nécessaire ici)

Bonjour

Je voudrais générer les fréquence 7.38, 15.66, 31.32, 62.64, 125.28, 250.56, 501.12, 1002.24

Vu l'utilisation présumée de des fréquences 'diapason' faut-il se prendre collectivement la tête sur la précision, la gigue....

L'effet thérapeutique supposé sera-t-il moindre en cas d'écart......? :wink:

La première de ces fréquence serait d'ailleurs 7,83 Hz et non 7,38 Hz

+1 pour les timers
voici un test et ses résultats effectués avec un compteur d’événements

const byte LED = 13;   //ici, on branche le compteur d'évenements

ISR(TIMER1_COMPA_vect)
{
  static boolean state = false;
  state = !state;  // toggle
  digitalWrite (LED, state ? HIGH : LOW);
}

void setup() {
  pinMode (LED, OUTPUT);
  
  // set up Timer 1
  TCCR1A = 0;          // normal operation
  //TCCR1B = bit(WGM12) | bit(CS10) | bit (CS12);   // CTC, scale to clock / 1024
  //TCCR1B = bit(WGM12)  | bit (CS12);              // CTC, scale to clock / 256
  //TCCR1B = bit(WGM12) | bit(CS10) | bit (CS11);   // CTC, scale to clock / 64
  //TCCR1B = bit(WGM12) | bit (CS11);               // CTC, scale to clock / 8
  TCCR1B = bit(WGM12)| bit (CS11);                  // CTC, scale to clock / 1
  
  OCR1A =  990;       // compare A register value (1000 * clock speed / 1024)
  TIMSK1 = bit (OCIE1A);             // interrupt on Compare A Match
} // end of setup


/*
 * relevés effectués avec un compteur d'évenements
 * 
 * 7.83 Hz et de ces octaves, 31.32 Hz - 62.64 Hz - 125.28 Hz - 250.56 Hz - 501.12 Hz, 1002.24 Hz, 2004.48 Hz, 4008.96 Hz, etc.
 * 
 * OCR1A =  990; =    7.83306 Hz  TCCR1B = bit(WGM12) | bit(CS10) | bit (CS12);   // CTC, scale to clock / 1024
 *                   16                                                                                     500
 * OCR1A =  990; =   31.3323 Hz   TCCR1B = bit(WGM12) | bit (CS12);               // CTC, scale to clock /  256
 *                   64                                                                                     128
 * OCR1A =  990; =  125.3291 Hz   TCCR1B = bit(WGM12) | bit(CS10) | bit (CS11);   // CTC, scale to clock /   64
 *                  250                                                                                      32
 *                  500                                                                                      16
 * OCR1A =  990; = 1000.2631 Hz   TCCR1B = bit(WGM12) | bit (CS11);               // CTC, scale to clock /    8
 * OCR1A =  991; = 1001.6220 Hz   TCCR1B = bit(WGM12) | bit (CS11);               // CTC, scale to clock /    8
 *                 2000                                                                                       4
 *                 4000                                                                                       2
 * OCR1A =  990; = 8021.0600 Hz   TCCR1B = bit(WGM12) | bit (CS11);               // CTC, scale to clock /    1
 * OCR1A =  991; = 8012.9700 Hz   TCCR1B = bit(WGM12) | bit (CS11);               // CTC, scale to clock /    1
 */
void loop() { }

Bonjour,
As-tu regardé du côté des générateurs DDS ?