Aller au contenu


Photo
- - - - -

Créer un signal carré 30Khz arduino


12 réponses à ce sujet

#1 nathan62

nathan62

    Nouveau membre

  • Membres
  • 5 messages

Posté 27 avril 2019 - 08:53

Bonjour,

 

je cherche à créer un signal carré de 30Khz en sortie avec un arduino, étant novice dans le domaine de l'électronique mais non dans l'informatique, pouvez vous me donner le schéma à suivre et des conseils ?

 

est-il possible également de rajouter un variateur pour augmenter et diminuer la fréquence de sortie ?

 

Merci d'avance.



#2 Path

Path

    Made By Humans

  • Modérateur
  • PipPipPipPipPip
  • 2 504 messages
  • Gender:Male
  • Location:Paris

Posté 27 avril 2019 - 10:29

Salut,

Tu as déjà allumé une led avec un arduino ?

Si non, commence par ça.

Si oui, https://www.arduino....aymicroseconds/avec 33 à la place de 50.

 

Si c'est pour un projet perso, je veux tout savoir de ce projet.

Sinon, je veux le nom et l'adresse de ton prof. 



#3 nathan62

nathan62

    Nouveau membre

  • Membres
  • 5 messages

Posté 27 avril 2019 - 02:50

Bonjour Path,

 

Oui j'ai déjà allumé une led avec un arduino et même fait d'autres petites choses similaires un peu plus poussées.

 

C'est un projet perso, et je cherche dans un premier temps à réaliser un générateur de fréquence de 30 Khz comme dans les études de la Dre Clark.

 

Peux-tu me dire comment as-tu déduis le fait de remplacer 33 par 50 ou le calcul pour en arriver là.

 

Es-tu sûr qu'il y'aura bien une onde carré en sortie ? La fonction tone() pourra t-elle m'aider sur ce projet ?

 

Est-ce que l'arduino mini suffit pour faire un générateur de fréquence ?

 

Je cherche également à faire une onde carrée offset positive toujours sur la même fréquence, cela est-il possible avec l’Arduino ?

 

Bien à toi.



#4 Path

Path

    Made By Humans

  • Modérateur
  • PipPipPipPipPip
  • 2 504 messages
  • Gender:Male
  • Location:Paris

Posté 27 avril 2019 - 03:17

Tu veux une fréquence de 30kHz. La période (la durée d'un cycle) est de 1 sur la fréquence. Soit 33 microsec. En l'écrivant, je me rend compte que j'ai dit une bêtise, c'est 15 qu'il faut mettre. 15 micro secondes à l'état haut + 15 à l'état bas ça te fait une période de 30 micro secondes ou environ 30 kHz.

 

Pour la fonction tone(), je crois pas que m'en sois servi un jour. Il faut essayer.



#5 Mike118

Mike118

    Staff Robot Maker

  • Administrateur
  • PipPipPipPipPip
  • 9 965 messages
  • Gender:Male
  • Location:Anglet

Posté 27 avril 2019 - 04:00

Tone peut éventuellement t'aider à condition que ses contraintes te conviennent : 
Plus d'info sur tone 


Si mon commentaire vous a plus laissez nous un avis  !  :thank_you:

Nouveau sur Robot Maker ? 

Jetez un oeil aux blogs, aux tutoriels, aux ouvrages, au robotscope  aux articles,  à la boutique  et aux différents services disponible !
En attendant qu'une bibliothèque de fichiers 3D soit mise en place n'hésitez pas à demander si vous avez besoin du fichier 3D d'un des produits de la boutique... On l'a peut être ! 
Si vous souhaitez un robot pilotable par internet n'hésitez pas à visiter www.vigibot.com et à lire le sous forum dédié à vigibot!

 

Les réalisations de Mike118  

 

 

 


#6 N1oN4o

N1oN4o

    Membre

  • Membres
  • 45 messages
  • Gender:Male

Posté 27 avril 2019 - 05:58

Les temps de montée/descente d'une sortie digitale sont de quel ordre ? 

 

Ca peut jouer un peu sur la forme et la fréquence de ton signal j'imagine .



#7 Sandro

Sandro

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 261 messages
  • Gender:Male

Posté 08 mai 2019 - 12:49

Tu cherches à obtenir quelle précisons sur la fréquence?

Est-ce que ton Arduino est sensé faire autre chose en même temps?

 

Si tu veux obtenir le maximum de précision (et garder la puissance de calcul disponible pour d'autres tâches), alors tu peux directement paramétrer un timer pour être directement connecté à une pin : avec ça tu peux obtenir n'importe quelle fréquence (enfin une fréquence de la forme 16MHz/N/M où N est un entier 16 bits (ou 8 bits selon le timer que tu utilise) et M=1 ou 8 ou 64 ou 256 ou 1024). Par contre ça implique d'aller directement écrire dans des registres (en gros, tu n'as plus les jolies fonctions arduino, tu fais le sale boulot toi même).

Si cette solution t'intéresse, je peux regarder plus en détail comment on fait.

 

Cette solution, tout comme celle d'utiliser delayMicroseconds() permettent de changer la fréquence. Il suffit de changer la durée d'attente (en changeant la valeur de reset du timer  ou la durée du delay).

 

En revanche, sauf erreur de ma part, il n'est pas possible de rajouter un offset à ton créneau en pur software.

Par contre, si tu veux un offset constant (et que tu ne tire que très peu de courant), alors 2 résistances suffisent : tu crée un pont diviseur de tension entre ta sortie et le +5V (par contre tu perds en amplitude : en gros, tu ne change que la valeur basse du créneau, mais pas la valeur haute).

 

Si tu veux quelque chose de plus poussé (garder l'amplitude, offset commandé , ...), alors dis moi ce que tu veux exactement et je pourrais essayer de te faire un montage adapté.


Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...

Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.


#8 nathan62

nathan62

    Nouveau membre

  • Membres
  • 5 messages

Posté 08 mai 2019 - 03:31

Salut Sandro,

 

Alors, je souhaite avoir la fréquence la plus précise possible.

 

Dans un premier temps, l'arduino sera juste un générateur de fréquence de 30Khz, plus tard j'aimerai y ajouter d'autres fréquences, et si cela ne se complique pas trop j'aimerai y ajouter également un écran LCD.

 

Une fréquence de la forme 16MHz/N/M ça permet de générer une fréquence sur quelle plage ?

 

Etant donné que je veux avoir le maximum de précision et que dans un premier temps l'arduino ne fera que ça, est-ce nécessaire d'allez écrire dans la base de registre quand même ?

 

Les caractéristiques du signal qui devra être généré :

  • voltage 9V avec un offset positif à 0.25V
  • fréquence 30 KHz
  • onde carrée

Est-ce possible d'avoir un voltage en oscillation entre 0.25V et 9V ?

 

Est-ce possible de faire ça avec un arduino uno voir mini ?

 

Je souhaite également mettre ce montage dans un boitier et celui-ci pourra être mis dans une poche et donc subir quelques secousses, comment je peux faire un pont diviseur de tension avec l'arduino qui puisse tenir tenir les "chocs" ?

 

Merci de ta réponse,

Nathan



#9 Sandro

Sandro

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 261 messages
  • Gender:Male

Posté 08 mai 2019 - 04:22

Si  une précision maximale est ton objectif, alors il vaut probablement mieux utiliser les timers hardware (ce qui implique d'écrire dans les registres) que de le faire avec des fonctions Arduino qui seront moins précises. Si en revanche il y a une certaine précision qui est suffisante pour ton application, alors on peut peut-être faire sans.

 

 

En termes de fréquence, tu peux aller de N=M=1, c'est à dire 16MHz (ou alors 8MHz, bien possible que ce soit que un changement de valeur à 16MHz) jusqu'à M=1024 et N=2^16-1, soit f=16MHz/M/N=0.2Hz. Tu as donc toute la gamme 0.2 Hz à 8 ou 16 MHz de disponible.

 

Par contre, ta précision dépendra de la fréquence : si tu es proche des 8MHz, ça deviendra moins précis. En gros tu as une demi période T/2 de 1/16MHz = 62.5 ns pour N=M=1 (ie T=125 ns, ie f=8MHz). La valeur suivante est pour N= et M=, on a donc T=2*125ns = 250 ns, soit f=4MHz. Puis vient N=3, M=1, qui donne T=3*125ns = 375 ns, soit f=2.66MHz. Et ainsi de suite : tant que tu gardes M=1, tu as T=M*125 ns, soit f=8MHz/N.

En gros, dès que tu es à moins de 800kHz (N=10, M=1), tu peux approximer n'importe quel fréquence avec moins de 5% d'erreur. Si tu es à moins de 80kHz (N=100, M=1), tu peux approximer avec moins de 0.5% d'erreur.

A noter néanmoins que je ne connais pas la précision intrinsèque de l'horloge, donc il y aura un certain seuil de précision que tu ne pourra pas dépasser.

 

 

Les caractéristiques du signal qui devra être généré :

  • voltage supérieur à 0.25V et 100 % OFFSET POSITIF
  • fréquence 30 KHz
  • onde carrée

je suis pas sur de comprendre ta première ligne : "voltage supérieur à 0.25V et 100 % OFFSET POSITIF". Est ce que tu entends par là l’oscillation entre 0.25 et 9V dont tu parle ensuite?

Pour la fréquence de 30 kHz, ce sera toujours 30kHz ou programmable? Si oui, tu veux pouvoir couvrir quelle plage de fréquences?

Par onde carrée, tu entends que le temps passé à l'état haut est le même qu'à l'état bas?

 

Pour la tension entre 0.25V et 9V, ces deux valeurs sont fixes ou programmables?

Tu as quoi comme sources de tensions de disponibles? Est-ce que tu alimente l’Arduino avec du 9V ou autre chose? A noter que si tu utilise une pile 9V, elle n'est pas exactement à 9V (un peu plus quand elle est pleine, un peu moins quand elle est vide) : est-ce que cette variation est acceptable en sortie?

 

A noter que les sorties d'un arduino ne peuvent pas directement délivrer du 9V, mais il suffit de rajouter un transistor et le tour est joué. Mais sinon, un Arduino Uno ou Mini fait très bien l'affaire (je te conseillerais plutôt un mini ou un micro si le but est d'avoir quelque chose de petit qui rentre dans la poche).

 

Pour ce qui est du pont diviseur et des chocs, tu as deux options principales : soit tu prend un arduino qui n'a pas de pins soudés (par exemple certains mini ou nano sont livrés avec les pins non soudés) et tu soude directement sur l'arduino ; soit tu fait un petit circuit (sur un PCB pré-perforé par exemple) où tu place des pins (mâles si tu utilise l'arduino uno qui a des pins femelle, ou femelles si tu utilise un Mini ou Nano qui ont des pins mâles) : tu peux ensuite y enficher l'arduino. Juste mettre des fils ou des pâtes de résistances dans les pins de l'Arduino Uno, ça vas bien pour faire des tests, mais ça ne restera pas en place si tu promène ton montage dans ta poche.


Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...

Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.


#10 Sandro

Sandro

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 261 messages
  • Gender:Male

Posté 08 mai 2019 - 09:21

Du coup, j'ai adapté le programme disponible ici (https://forum.arduin...opic=240200.0) pour fonctionner de 490Hz à 8MHz. A noter que je n'ai pas encore pu le tester (j'ai pas d'oscilloscope sous la main, et celui du boulot est sur le terrain et ne revient pas avant lundi). Le seul test que j'ai fait c'est de vérifier que le duty cycle est bien de 50% (en mettant un filtre RC puis en vérifiant que j'ai bien 2.5V).

 

Voici le code (si quelqu'un a un oscilo sous la main, n'hésitez pas à testerpour me dire si ça marche :

//adapted from https://forum.arduino.cc/index.php?topic=240200.0

//
//
// Use of timer1 to generate 8 Mhz clock on pin 9
//
//

const int freqOutputPin = 9;   // OC1A output pin for ATmega32u4 (Arduino Micro)

// Constants are computed at compile time

// If you change the prescale value, it affects CS22, CS21, and CS20
// For a given prescale value, the eight-bit number that you
// load into OCR1A determines the frequency according to the
// following formulas:
//
// With no prescaling, an ocr1val of 0 causes the output pin to
// toggle the value every  CPU clock cycle. That is, the
// period is equal to two clock cycles.
//
// With F_CPU = 16 MHz, the result is 8 MHz.
//
 
// To change the timer prescale division, use different bits for CS22:0 below


void initializePin9Freq(long int freq_hz)
{
  pinMode(freqOutputPin, OUTPUT);

  // f=1/T  =>  T=1/f=125ns*prescaler*(TOP+1) 

  if(freq_hz>=490)  //we can do it without prescaler
  {
    //1/f=125ns*(TOP+1)
    //8MHz/f=TOP+1
    //TOP=8000000/f-1
    unsigned int top=(8000000UL+freq_hz/2)/freq_hz-1; //nb le +freq_hz/2 permet de faire un arrondi plutôt qu'une troncature
    
    // Set Timer 1 CTC mode with no prescaling.  OC1A toggles on compare match
    //
    // WGM12:0 = 010: CTC Mode, toggle OC
    // WGM2 bits 1 and 0 are in TCCR1A,
    // WGM2 bit 2 and 3 are in TCCR1B

    TCCR1A = ( (1 << COM1A0)); // COM1A0 sets OC1A (arduino pin 9 on Arduino Micro) to toggle on compare match

    // Set Timer 1  No prescaling  (i.e. prescale division = 1)
    //
   
    TCCR1B = ((1 << WGM12) | (1 << CS10));  //WGM12 means CTC mode

    // Make sure Compare-match register A interrupt for timer1 is disabled
    TIMSK1 = 0;
    
    // This value determines the output frequency
    int ocr1aval  = top;
    OCR1A = ocr1aval;
  }
  else
  {
    //todo if we want to be able to use frequencies bellow 490Hz
  }
}

void setup()
{
  long unsigned int freq_hz=30000UL;  //the UL suffix tells that it is an unsigned long (if you don't put it, you will have problems with frequencies above 2^15 or 2^16)
  initializePin9Freq(freq_hz);
  Serial.begin(9600);
}


void loop()
{
    //Serial.println(analogRead(A0));
}

A noter que le créneau est sur la pin 9 et que ce n'est pas modifiable (enfin je crois qu'il y a une autre pin qui peut être utilisée avec le Timer1 à la place, et on pourrait faire la même chose mais avec les timers 0 ou 2 mais dans ce cas on n'a que 8 bits de résolution au lieu de 16).

 

A noter que pour l'instant la fréquence minimale est 490 car je n'utilise pas les prescaler. Si besoin, je peux regarder pour adapter à des fréquences plus basses.

 

 

Pour ce qui est de la partie électronique, j'attends d'avoir plus d'infos avant de me lancer dans les schémas


Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...

Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.


#11 nathan62

nathan62

    Nouveau membre

  • Membres
  • 5 messages

Posté 08 mai 2019 - 11:47

Tout d'abord Sandro merci pour ton aide, je ne pensais pas en avoir un aussi grand dévouement sur un forum.

 

Pour la fréquence la plage que je souhaite couvrir dans l'idéal est de 1 à 1.000.000 Hz, pour la précision c'est acceptable pour les 5% en dessous de 800kHz et 0.5% en dessous de 80KHz

 


je suis pas sur de comprendre ta première ligne : "voltage supérieur à 0.25V et 100 % OFFSET POSITIF". Est ce que tu entends par là l’oscillation entre 0.25 et 9V dont tu parle ensuite?

Oui je faisais bien allusion d'une oscillation entre 0.25V et 9V mais je me suis rétracté par la suite, et je pense que cela ne sera pas nécessaire.

 

Pour l'onde carré c'est de cette forme : https://www.noelshac...4-hcnolad00.jpgest-ce plus clair pour toi ?

 

Pour la tension c'est une pile plate 9V, et la variation est acceptable en sortie (la première solution).

 

Je partirai vers le plus stable c'est à dire une soudure sur l'arduino pour le pont diviseur.

 

Le duty cycle à 50% ça correspond à quoi ?

 

Je souhaite acheter cet oscilloscope pour visualiser la fréquence : https://www.amazon.f...d/dp/B07FPDY3DKest-il suffisant pour ce besoin ?



#12 Sandro

Sandro

    Pilier du forum

  • Modérateur
  • PipPipPipPipPip
  • 1 261 messages
  • Gender:Male

Posté 09 mai 2019 - 07:22

Bonjour,

Donc du coup, au final, tu veux des oscillations entre quelles tensions? 0.25 et 9V? ou 0.25 et 5V? ou 0 et 5V?

 

Le duty cycle d'un créneau correspond à la proportion de temps passé à l'état haut (ie 5V ou 9V dans ton cas). Duty_cycle=T_haut/T où T est la période et T_haut la durée passé à l'état haut au sein d'une période. Un duty cycle de 50% correspond au fait de passer autant de temps à l'état bas (0V ou 0.25V) qu'à l'état haut (5V ou 9V).

 

Pour l'oscilloscope, ton model ne fait malheureusement l'affaire que pour les basses fréquences : il coupe les fréquences supérieures à 200kHz. Attention, ça veut dire que pour un SINUS, tu peux monter jusqu'à 200kHz. Par contre un créneau, c'est une somme de sinus (série de fourrier), et si tu veux que le créneau s'affiche à peu près comme un créneau, il faut compter au moins 10 harmoniques (ie un sinus de fréquence 10 fois plus élevée doit passer). En gros, si tu veux voir un créneau sur cet oscilloscope, il ne doit pas dépasser les 20kHz (et même comme ça, le créneau n'est pas très beau : cf https://fr.wikipedia...omène_de_Gibbs (premier graphe)). Après, si tu veux juste vérifier la fréquence, avec cet oscillo tu peux probablement monter jusqu'à 200kHz, mais tu verra un sinus un peu difforme au lieu d'un créneau.

Attention aussi au fait qu'ils ne disent rien sur la fréquence d’échantillonnage : si celle-ci n'est pas au moins 10 fois la fréquence de coupure analogique (ie 10*200kHz), tu aura un affichage horrible.

Donc à toi de voir : si tu veux juste vérifier pour les basses fréquences, c'est bon. Si tu veux pouvoir vérifier sur toute la gamme, et vérifier la netteté du signal au passage, alors il t'en faut un qui soit bien plus puissant (mais le prix monte aussi).


Aidez-nous à vous aider : partagez toutes les informations pertinentes : description précise du problème, contexte, schéma de câblage, liens vers la documentation des composants, votre code (ou encore mieux un code minimal reproduisant le bug), ...

Vous recevrez ainsi plus de réponses, et elles seront plus pertinentes.


#13 nathan62

nathan62

    Nouveau membre

  • Membres
  • 5 messages

Posté 09 mai 2019 - 10:14

Bonjour Sandro,

 

Non pas d'oscillation dans un premier temps.

 

D'accord pour la précision pour le duty cycle, je comprends mieux.

 

Pour bien que je comprenne aussi, un offset positif c'est lorsque la tension est toujours positif c'est ça ?

 

Et sinus = onde sinusoidale et créneau = onde carré ?

 

Pour la fréquence 200Khz me suffit par contre j'aurai bien aimé voir le signal carré, et ça m'embête un peu que je ne peux pas voir ça au-dessus des 20Khz. Existe-il un autre moyen de vérifier si le signal est carré avec un autre appareil qu'un oscilloscope ? existe des oscilloscopes qui permet juste de mesurer ce que je recherche et donc seraient moins chère ?





Répondre à ce sujet



  


0 utilisateur(s) li(sen)t ce sujet

0 members, 0 guests, 0 anonymous users