Générer une basse fréquence avec un Mega 2560

Bonjour à toutes et à tous,

J'aurais besoin, à l'aide d'un Mega 2560, de générer une onde carrée d'une cinquantaine de Hertz (± 20Hz) de rapport cyclique quelconque, le tout se faisant dans le setup.

Le but est de me générer un signal d'interruption que j'utiliserai par ailleurs dans une application avec ce même Mega 2560.

Je suppose que cela se fait à l'aide des différents timers que je maitrise très mal :slightly_frowning_face:

Merci de votre aide.

Pierre.

utilisez la fonction tone()

const byte freqPin = 3;

void setup() {
  tone(freqPin, 50); // 50Hz sur la pin 3 indéfiniment 
}

void loop() {}

(le rapport cyclique est de 50%)

mais si l'idée c'est de connecter cela à une pin sur ce même méga, c'est un peu dommage...

50Hz à ± 20Hz c'est sans doute gérable dans la loop() avec millis()

const unsigned long periode = 20; // 20ms periode pour 50hz
unsigned long chrono = 0;
void setup() {}
void loop() {
  if (millis() - chrono >= periode) {
      chrono += periode;
      ... // faire ici ce que vous voulez faire toutes les 20ms
  }

  // ici vous pouvez faire autre chose du moment que ça prend moins de 20ms

}

Bonjour

la fonction tone() suffira peut être

https://www.carnetdumaker.net/articles/jouer-des-notes-de-musiques-avec-une-carte-arduino-genuino/

copieur :wink:

La précision est faible. 50Hz à +/- 20Hz près.
Tu es sûr ?

Je vous remercie pour vos propositions qui, dans mon cas, ne fonctionnent pas. Pourquoi ?

J'ai une application que j'ai créée à partir de ma bibliothèque de composants. Elle anime deux servos pour orienter une cellule photovoltaïque face au soleil toutes les 4 minutes.

Le principe de ma bibliothèque est que dans la loop() je scrute si mes composants (des boutons, des afficheurs, ...) ont quelques chose à dire. Entre autre un composant Tempo, qui lui, vient mettre en route mes servos toutes les quatre minutes.

Tout cela fonctionne bien.

Mais voilà, je me suis dit que, si au lieu de scruter mes composants dans la loop(), je les scrutais toutes les 20 ms (le 50 Hz en question, dont je me fiche de la précision) par une interruption, ce serait une autre façon de faire.

Ça fonctionne bien jusqu'à ce que le composant Tempo vienne activer les servos. A ce moment, le signal de commande d'interruption, généré par tone(), disparait ainsi que les signaux de commande de mes servos..

Je me suis alors servi d'une source de fréquence extérieure.

Le problème est le même : mes signaux de commande des servos disparaissent.

Je me demande si mon système ne vient pas ficher la pagaille dans les timers. J'utilise l'interruption sur la broche 18.

Je vais en essayer une autre ...

Cordialement.

Pierre.

tone() utilise un timer qui est aussi utilisé pour générer un PWM sur certaines pins.

( c'est timer2 et donc les pins 3 et 11 sur UNO ou 9 et 10 sur Mega perdent leur PWM - ou si vous mettez le PWM, ça met le bazar pour tone)


je ne vois toujours pas pourquoi la scrutation avec millis() ne fonctionnerait pas

Pourquoi faire en logiciel ce qui est prévu en électronique numérique ?
Un timer en mode CTC.

La bible :

Une fois lancé, le timer est indépendant.
De plus les timers sont dotés d'interruptions.

Si tu regardes le tableau des fréquences obtenables 50 Hz y figure.

Avec 6 timers dans la Mega 2560 il devrait être possible de faire le travail.

il faut écrire du code (logiciel) pour configurer le timer... c'est ce que fait la fonction tone() avec timer2


dans le cas présent je ne vois pas l'utilité cela dit

On ne doit pas faire grand chose dans une ISR, donc ce n'est certainement pas l'endroit pour écouter des composants et déclencher (dans le contexte de l'interruption) des moteurs et autres trucs compliqués et longs. Donc en pratique l'interruption se résume souvent à prendre note que c'est le moment de faire quelque chose (on met un bool à vrai) puis dans la loop on regarde ce booléen et on fait tout ce qu'il faut.

Dans cette approche, on n'a pas de gain réel par rapport à simplement tester le temps écoulé depuis le dernier traitement, c'est équivalent à regarder le bool de l'ISR et il n'y a rien à cabler ni à se soucier de section critique etc...

Du fait que j'ai essayé avec une source extérieure et que cela ne fonctionne pas mieux, le problème ne vient donc pas de la génération d'un signal à 50 Hz.

Le problème, je suppose, est que mon interruption matérielle vient perturber le fonctionnement de la bibliothèque "servo".

J'ai essayé avec les entrées d'interruption possibles : 18, 19, 20, 21 : pas mieux. Les bornes 2 et 3 étant utilisées par l'afficheur, je ne les ai pas essayées.

Peut-être y a-t-il d'autres bibliothèques pour commander des servos moteurs, je n'en ai pas trouvé.

Cordialement.

Pierre.

Non,
C'est un choix personnel : certains sont plus à l'aise avec le matériel, d'autres sont plus à l'aise avec le logiciel.

Si les concepteurs des vrais microcontrôleurs prennent la peine de développer des fonctions matérielles dans un produit logiciel c'est qu'il y a des bonnes raisons.

Pourquoi la liaison série logicielle est limitée en vitesse par rapport à la liaison série matérielle ?

Ce que je trouve être une démonstration à mes propos est que, sur les performances de rapidité, un ESP32 qui tourne à 320 MHz fait à peine mieux qu'un avr à 16 MHz.
Parce que l'ESP32 est basé sur un tensilica de Cadence et que Cadence fait tout payer.
Par choix économique, Espressif à choisi de faire en logiciel ce qu'un avr fait en matériel.

expliquez moi comment vous configurez le timer2 sans code et on sera d'accord... (je ne vois pas comment vous allez écrire dans les registres de configuration sans programmer)

Ce que je dis : la fonction tone() va mettre ce qu'il faut dans les registres qui configurent timer2 pour générer la bonne fréquence lors de l'interruption sur la pin de sortie ➜ le code de tone (la programmation) sert à utiliser la fonction matérielle.

Je n'ai jamais dis que l'on pouvait configurer un timer sans écrire de code.

J'ai seulement dit qu'une fois configuré le timer tourne seul sans prendre de temps au programme sauf éventuellement pour les interuptions et s'il y a un traitement spécial appelé.

Je dis que certains pensent immédiatement à digitalWrite et millis() et d'autres pensent à utiliser ces trucs incongrus qu'on appelle des modules d'électroniques à l'intérieur des micros.

Je dis que les premiers sont plus nombreux que les seconds.
J'ai bien conscience de faire partie des minoritaires.

Mais j'ai toujours dit : il faut présenter toutes les solutions à un demandeur, pas seulement celles que l'on préfère.
C'est le demandeur qui choisi.

Tu noteras que les premiers ne sont pas forcément que des électroniciens et peuvent parfois être des softeux :slight_smile:

Au départ, je suis un électricien devenu électronicien de part mon travail. Puis, pendant un moment, on m'a fait virer softeux (langage Pascal) pour finalement faire des automatismes combinant électronique, mécanique, optique et informatique.

J’apprécie donc les différentes approches.

Pour autant, par fainéantise, je trouve plus facile d’aligner des lignes de code plutôt que de commander des composants et sortir le fer à souder.

Mais au final, je me débrouille entre toutes ces techniques et je remercierai toujours les intervenants pour leurs apports..

Cordialement.

Pierre.

J’ai juste dit que c’est ce que faisait la fonction tone() en réponse à

Le code de tone() c’est le code de configuration du timer en fonction de la fréquence souhaitée, donc on faisait du logiciel pour utiliser le hardware.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.