Projet arduino, mesure de fréquence

Bonjour à tous,

Je réalise en ce moment un projet sous arduino et LabView.

Je dois contrôler si des Leds s'allume sur un panneau de commande d'un appareils. J'ai utilisé des capteurs de courant avec des résistance de shunt relié a mon panneau de commande pour récupérer une valeur de tension pour chaque LED, mon problème est que j'ai une de mes Leds qui clignote à 4.630Hz, j'aimerais savoir si il y a possibilité de mesurer cette fréquence?

Merci

Ben

Vu le prix d'achat de LabView les réponses vont avoir du mal à se bousculer.

avec un oscilloscope ?

En fait c'est quoi ta question ?

  • interfaçage LabView avec arduino --> déjà répondu
  • mesurer une fréquence avec une carte arduino : oui c'est possible mais dans ce cas tu créé de la confusion en faisant référence à LabView.
    C'est juste une utilisation d'un micro-controleur avr.

Bonjour, oui en effet je n'aurais pas du afficher Labview dans le titre.

Je souhaite juste mesurés la fréquence de clignotement d'une LED. Mon montage électronique est constitué d'un capteur de courant. Lorsque une de mes Leds est allumés, j'obtiens une tension de 200mV sur ma résistance de shunt, avec un montage constitué d'un LM324, j'obtiens une valeur environnant la moitié de la valeur pleine échelle de l'arduino soit 2,5V, La fréquence de clignotement se fera sur une tension de 2,5V lorsqu'elle est allumée, et environ 0V éteintes, je souhaite donc dans mon programme mesuré la fréquence de clignotement de cette derniere LED, je sais grâce à un oscillo qu'elle clignote à 4,640HZ, je souhaite avoir cette valeur sans passer par un oscillo,(projet d'un banc de test automatique), j'ai essayé avec la fonction pulseIN() , mais j'obtiens une valeur incohérente. Je ne pense pas que je puisse utiliser cette fonction sur une PIN analogique. Et je ne peux pas changée de PIN sur l'arduino car je récupère toutes mes valeurs(7 capteurs de courant) sur la même PIN grâce à un multiplexeur. Il me faut donc ma valeur en tension de ma LED (qui clignote(et qui fonctionne)) ainsi que sa fréquence de clignotement.

Merci, si d'autres précision je peux vous fournir mon programme.

menu_acqui_test.ino (13.2 KB)

Pour le schéma : un bon dessin vaut mieux qu'un long discours :grin:

Quelques pistes :
Toutes les fonctions arduino basées sur le temps sont le résultats d'une optimisation non pas sur la performance mais sur la simplicité d'usage.

Quand tu es dans un cas particulier il est recommandé de mettre les mains dans le cambouis pour ton optimisation.
Les limitations de la fonction pulsIn() sont AMHA ici :

Fichier wiring_pulses.c / fonction pulseIn()

uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
et :
while ((*portInputRegister(port) & bit) == stateMask)

  • if (numloops++ == maxloops)*
    return 0;
    Les fonctions digitalPinToBitMask(pin);,**digitalPinToPort(pin);,*portInputRegister(port) & bit) font appel à des variables stockées en flash par PROGMEN et par conséquent elles sont trop lentes.

Ces fonctions servent à accéder "simplement" au E/S référencées arduino (0,1,..,A0,..A5) d'une manière "un peu moins lente" que ne le fait digitalRead() mais guère moins.
L'idéal serait de tout remplacer par la lecture directe des registres (ce sera moins simple mais plus efficace).
Il y a un rapport 60 entre le temps mis par digitalRead et la lecture des registres et un rapport 30 entre la solution utilisée dans pulseIn et la lecture des registres.

exemple (attention il faut adapter à la bonne entrée c'est un exemple tiré de la gestion d'un DHT22)
while((PIND&(1<<PORTD3)) >> PORTD3 )
{if (numloops++ == maxloops)
return 0;}
Dans un micro avr les E/S sont groupée par port de 8 E/S --> Lecture de la datasheet obligatoire, un peu de café n'est pas inutile :grin:

Titre : STP édite le titre du premier message et choisis en un plus représentatif, les titres servent aux recherches.

Voila je viens de refaire mes schémas rapidement.(je ne peux pas ajouter d'autre composant annexe vu que mon PCB est en cours de création.)

Je n'est pas réellement compris ta réponse, je pense qu'elle est à un niveau supérieur à ma compréhension, si tu le souhaite tu peux me l'expliquer et je ferais un effort pour essayer de comprendre mais je ne te garantie rien. Des bouts que j'ai peu prés compris tu me dis c'est que le temps de réaction des demandes est différents suivant les commande demandé à l'Uc, mais l'optimisation de ma mesures(le temps qu'elle prend) je m'en fou un peux, tant que j'ai ma valeur de fréquences ça me suffit.

Merci en tout cas de m'aider.

Titre : j'ai modifié le titre, je pense qu'il conviendra mieux.

Nouveau_document_1Page_1[1].pdf (582 KB)

Je viens de relire le sujet depuis le début.
Je m'étais auto-vérouillé sur pulseIn() qui donne des valeurs incohérentes sans voir que la fréquence est seulement de 4 Hz et le niveau max égal à 2,5 V

Remarque : évite l'écriture au km, fais un paragraphe par idée et fais des retours à la ligne car ton texte est difficile à comprendre.

Question :
Est-ce que tu veux absolument faire des mesures analogiques et des mesures de temps sans changer de pin ?
Ce n'est pas optimisé mais c'est faisable car les broches des entrées "dites" analogiques peuvent être renvoyées à l'intérieur du micro soit sur un port numérique soit sur une entrée du multiplexeur analogique.
Mais cela donnera dans l'usine à gaz.

Commentaires:
4 Hz c'est bien en dessous de la limite de pulseIn() donc cela doit fonctionner.
Par contre le niveau de commutation des entrées numériques du micro est justement autour de 2,5V donc il est possible qu'un coup cela commute et qu'un coup cela ne commute pas..
Il faut que tu modifie le schéma pour avoir un niveau bas inférieur à 1V et un niveau haut au moins égal à 3,5 V.

Si c'est impossible pour des considérations extérieures, interface les sorties des ampli-op avec des comparateurs.
Avec un comparateur tu peux fixer où tu veux le point de commutation.
Mais il faudra ajouter un inverseur suplémentaire.

Comme d'habitude il faut tirer les vers du nez : tu ne nous à pas dit qu'elle carte tu utilises, si c'est une UNO il serait préférable de passer à une Méga pour avoir plus I/O.
Cela éviterait des solutions tordues.

Désoler pour les paragraphes aux Km, c'est un de mes gros défauts.

Pour te répondre,

  • Est-ce que tu veux absolument faire des mesures analogiques et des mesures de temps sans changer de pin ?
    Oui je suis obligé de garder la même Pin, car elle est commune à toute mes mesures de courant et je ne peux pas en rajouter une non plus par soucis que mon PCB est déjà réalisé et que je dois rendre présenté mon projet le 22 juin.

J'utilise un arduino Mega 2560

Et je ne peux pas modifier le schéma pour la même raison précédente.

Mon formateur ma dit que je pourrais m'orienter vers la librairie Mstimer2. Je regarde se que je peux en faire. Si tu as d'autre idée je suis preneur.

Bonne journée et merci de ton aide

4 Hz c'est bien en dessous de la limite de pulseIn() donc cela doit fonctionner.

Peut être mais pulseIn() ne mesure pas une fréquence mais une période. Soit la période de l'état haut, soit la période de l'état bas suivant l'argument passé à la fonction.

  • Est-ce que tu veux absolument faire des mesures analogiques et des mesures de temps sans changer de pin ?
    Oui je suis obligé de garder la même Pin, car elle est commune à toute mes mesures de courant et je ne peux pas en rajouter une non plus par soucis que mon PCB est déjà réalisé et que je dois rendre présenté mon projet le 22 juin.

Ouai enfin bon....
Si la seule solution c'est de changer de pin on coupe une piste et on met un fil sur le PCB. Faut pas non plus se tirer une balle dans le pied en bloquant sur ce genre d'argument.

Une librairie pour mesurer les basses fréquences: http://interface.khm.de/index.php/lab/interfaces-advanced/frequency-measurement-library/

Ouai enfin bon....
Si la seule solution c'est de changer de pin on coupe une piste et on met un fil sur le PCB. Faut pas non plus se tirer une balle dans le pied en bloquant sur ce genre d'argument.

Ce n'est pas question de se tirer une balle dans le pied, c'est que j'ai fournis il y a un mois de ça un cahier des charges avec un schéma, et un diagramme de procédure, je ne peux pas me permettre de le modifier plus qu'il l'ai déjà, et je dois garder cette Pin car il me faut absolument la tension qui correspond au courant consommé par ma LED, garder la Pin est donc primordiale, mais cette partie je pense que vous ne la voyez pas comme moi, vu que sa correspond plus à la partie Labview que arduino, mais je ne pense pas que grand monde comprendra ce logiciel vu son prix et sa complexité. je peux fournir le diagramme si vous le souhaitez mais sa ne changera rien à l'avancement du problème.

j’éclaire un peu plus ma question, j'aimerais savoir si je peux :
Récupérer mes données analogiques avec un while(analog.available) ou truc du genre , pour récupérer ma valeur et la stocké dans un tableau, dés que je la récupère je lance un timer à part juste qu'a la prochaine valeur à environ 2,5V , pour effectué une mesure de temps, et la convertir en fréquence.

Merci de votre aide, je sais que j'ai du mal à m'expliquer, donc si vous avez d'autres questions.

Une librairie pour mesurer les basses fréquences: http://interface.khm.de/index.php/lab/interfaces-advanced/frequency-measurement-library/

je regarde cette librairie, merci

Edit : je viens de me rendre compte d'une erreur au sujet de mon while analog. available , il y aura toujours une valeur au moins égale à 0...

dés que je la récupère je lance un timer à part juste qu'a la prochaine valeur à environ 2,5V

Etant donné la fréquence à mesurer au lieu de bricoler un timer, il suffit de lire la valeur de millis() ou micros() au moment d'une transistion et de refaire la même chose à la transition suivante. Tu auras ainsi ta période avec la précision de ton système d'échantillonnage.

C'est bien là mon problème je ne vois pas comment le déclencher lorsque j'ai une valeur ..

Il faut comparer la valeur courante de l'échantillon avec la (ou des) valeur(s) précédente(s) afin de déterminer si tu as bien le franchissement d'un seuil et son sens de variation. Une fois cette transition confirmée, tu stockes la valeur de micros() dans une variable temporaire. A la transition suivante tu fais la même chose et tu calcules la différence pour avoir le temps écoulé.