Générateur de signal carré ATMEGA 2560

Bonjour,
J'ai pour projet de réaliser un générateur de fréquence à l'aide d'un Arduino Mega 2560. Le but est de simuler la fréquence délivrée par un capteur et de tester l'entrée de l'automate chargé d'exploiter cette fréquence. Il faudrait donc émettre les fréquences suivantes : 10^(-3), 10^(-2), 10^(-1), 1, 10, 10^(2), 10^(3), 10^(4), 10^(5) Hz. (signal carré d'amplitude 5V)
Idéalement on écrirait la valeur souhaité sur un clavier numérique qui renverrai l'information sur un écran LCD, avant de venir raccorder un oscilloscope ou l'automate à la sortie PMW.
Je débute totalement sur Arduino, donc tout conseils est bon à prendre.
Merci d'avance.

Edit: Passer d'une fréquence à une autre serait peut-être plus simple avec une simple pression de bouton poussoir ?

1 Like

Soyons clairs, est-ce du PWM ou du carré?

Signal carré...désolé pour l'abus de langage...

Bonjour,

De mémoire, c'est un sujet +/- déja traité ici à propos d'un simulateur de débitmétre.

EDIT:
J'ai retrouvé

post36

Générateur signaux carrés.

A voir si ça convient, je ne me rappelle plus dans les détails.

Il faudrait sûrement "blinder" la sortie des signaux carré suivant sur quoi devrait être connecter le générateur de signaux carré.

1 Like

Merci, je vais regarder à ça :+1:

Je crois que ça n'ira pas assez haut en fréquence...

Avec un micro 8 bits il n'est pas possible de choisir exactement une fréquence, seule la chance peut le permettre.
Il n'est possible d'obtenir que des fréquences voisines, ou très voisines.

Deux pistes :

  1. lecture de la datasheet du microcontroleur
    ou :
  2. Lecture du (très bon) site de Mike Gammon :
    Gammon Forum : Electronics : Microprocessors : Timers and counters.
    Explications et applications pratiques.
    Il y a une liste très utile de toutes les valeurs de fréquences qu'il est possible d'obtenir avec un microcontrôleur avr 8 bits.

Mike Gammon se base sur un UNO avec son atmega328p, pour un MEGA et son atmega 2560 il y aura peut-être une adaptation du nom des timers : je ne suis pas certain que cela soit nécessaire, je n'ai jamais utilisé de carte MEGA, je préviens.

1 Like

Je viens de survoler le topic et effectivement c'est pas vraiment les mêmes attendus. J'ai vraiment du mal à trouver des contenus sur de la génération de fréquence inférieures à 1Hz.

Merci du conseil...Je m'en vais lire tout ça. :+1:

Bonjour brian08600
Un truc qui va bien pour ça, c'est l'exemple de l'IDE BlinkWithoutDelay, en changeant la variable interval et où en travaillant en microsecondes à la place des millisecondes.

Si tu veux un exemple...

Cordialement
jpbbricole

1 Like

La difficulté, c'est d'obtenir des fréquences élevées, on est limité par la fréquence horloge du micro.
Pour les fréquences basses une fonction basée sur "blink without delay" fonctionnera.

1 Like

J'aurais cru l'inverse (plus difficile dans les hautes fréquences).

1 Like

Je vais me renseigner pour le Blink Without Delay...Merci à tous pour la piste. Je débute vraiment sur Arduino (comme en programmation d'ailleurs), c'est pas évident...

Oui, car il n'est pas possible d'obtenir une fréquence supérieure à la moitié de la fréquence horloge.

Si j'ai bien compris ce que j'ai lu (probablement que non), la fréquence horloge de la Mega est de 16MHz. La moitié représenterait 8Mhz et la fréquence maximum que je souhaite délivré est de 100kHz. Donc à priori ce serait possible. Ou je suis à côté de la plaque?

Bonjour

Le fil de discussion suivant pourrait t'intéresser :

Cordialement.

1 Like

Il y a une différence de fonctionnement entre utiliser les compteurs des timers et "clignote sans utiliser la fonction delay()" :grinning:.

Les deux méthodes ne sont pas bloquantes, c'est-à-dire que le micro peut continuer à faire d'autre tâche .
Nb => ce n'est plus vrai avec la méthode "blink without delay" si tu veux obtenir des fréquences élevées.

La différence est ailleurs :

  • "clignote sans utiliser la fonction delay()" c'est de la programmation.
  • Les Timers ce n'est pas de la programmation : c'est de l'électronique numérique.

Les timers, tu ne fais juste que les configurer, une fois lancés, ils vivent leur vie indépendante tant que tu ne leur changes pas leur configuration.
C'est parce que c'est de la pure électronique, que seuls, ils peuvent atteindre les fréquences élevées.

Une fonction digitalWrite sur avr prend environ 60/65 cycles horloge.
Avec une horloge à 16 MHz un cycle = 1/16MHz = 62,5 ns.
Un digitalWrite(x, HIGH) immédiatement suivi d'un digitalWrite(x, LOW) mobilise toutes les ressources du micro. Un cycle prend 120 cycles horloge soit une fréquence théorique maximale de 130 kHz au lieu de 8000 kHz par les timers.

NB : il existe une fonction digitalWriteFast qui est plus optimisée mais ne compte pas dépasser 500 kHz toujours en mobilisant les ressources du micro.

Ne compte pas lever l'obstacle avec un micro comme un ESP32 qui tourne 10 fois plus vite : 160 MHz d'horloge.
En fait l'horloge est une première fois divisée par 2 (80 MHz) et une deuxième fois pour les circuits qui gèrent les sorties : 40 MHz contre 16 MHz (sans division) l'amélioration est insuffisante, seul avantage avoir des registres 32 bits au lieu de 8 bits qui apporteront de la souplesse.

Je pose la pertinence de réaliser, avec précision, les fréquences que tu recherches avec un microcontrôleur.

Je pense (en électronicien :grinning:) que déléguer cette fonction délicate à un circuit spécialisé purement électronique serait préférable.

Je pense au DDS AD9833 que l'on peut approvisionner sur Aliexpress sous forme de module (5 à 6 €).
Il existe deux modules différents, celui que je te conseille est :
image
Il a l'avantage d'avoir un atténuateur et un amplificateur qui isole l'AD9833 de la charge.
L'AD9833 est assez chatouilleux vis à vis de sa charge, c'est plus sage de l'isoler de sa charge.

Tu fuis ce modèle :
image

Les performances de l'AD9833 est avec le quartz 25 MHz tel que vendu par Ali :

The frequency registers are 28 bits wide,
with a 25 MHz clock rate, resolution of 0.1 Hz can be achieved
with a 1 MHz clock rate, the AD9833 can be tuned to 0.004 Hz resolution.

La datasheet de l'AD9833 se trouve ici :

Je n'ai pas essayé d'obtenir des fréquences basses, à la lecture de la datasheet je pense qu'il descend jusqu'à 0,1 Hz, il serait sage de le vérifier ou d'interroger Analog Devices

Merci à vous pour cette réponse. Je vais voir avec mon tuteur de stage si on se tourne vers cette option ou si on réduit la plage des fréquences (potentiellement 10^(-3) à 10^(3) Hz). Et je reviens vous partager mes avancées (ou obstacles...) dès que j'en ai. Je vais essayer aujourd'hui de générer les fréquences les plus basses pour commencer.

Oui, enfin il faudra justifier ce changement d'architecture.
Quelles sont les limites théoriques en fréquence avec un timer? Quel est l'erreur sur les fréquences demandées?
Quelles sont les limites théoriques en fréquence avec une génération par logiciel? Quel est l'erreur sur les fréquences demandées?
Quelles sont les limites théoriques en fréquence avec un AD9833? Quel est l'erreur sur les fréquences demandées?
Si les solutions ne couvrent pas toute la gamme de fréquence ne pourrais-tu pas fair un système hybride, génération avec un timer sur une gamme de fréquences, génération par logiciel sur une autre partie, par exemple.
D'ailleurs, dans ta description du besoin dans le post #1, tu donnes des fréquences à générer mais tu ne donnes pas la tolérance acceptable sur celles-ci.

Je n’avais pas percuté que c’etait pour un stage. Évidement @fdufnews a raison il te faut tout justifier.

Il manque une information : quelles autres taches le micro aura t-il a exécuter ?

J’imagine que tu dispose d’un oscilloscope.
Tu peux immédiatement faire un test pour determiner la frequence max obtenable avec la solution logicielle :
Une loop comme :

Void loop()
{
  digitalWrite( x, HIGH) ;
  digitalWrite(x, LOW) ;
 }

Te donnera une première limite haute, un test avec la fonction digitalWriteFast te donnre une autre limite haute.
Un test à l’oscillo , a défaut à l’analyseur logique, est a faire pour vérifier que le rapport cyclique est suffisament proche de 50/50 (temps du 1 par rapport au temps du 0) pour ton application.

La fonction loop devant probablement faire autre chose, a toi de verifier si c’est possible.