Problème de lecture d'un signal 4 kHz avec un RPi 3  [RESOLU]

Un lieu pour discuter des composants et de leur utilisation. Un passage obligé si vous devez interfacer votre Raspberry Pi avec le monde extérieur. On y trouvera aussi les cartes type commande de moteur pas à pas, continu, servo...

Modérateurs : Francois, smba38

Pinhapple
Raspinaute
Messages : 125
Enregistré le : jeu. 23 févr. 2017 15:53
Localisation : Rouen

Problème de lecture d'un signal 4 kHz avec un RPi 3

Message par Pinhapple » jeu. 30 mars 2017 09:43

Bonjour à tous !

C'est encore moi avec un souci de plus ! ;)

Pour poser le contexte : je travaille toujours sur un projet lié aux radars. Celui sur lequel je dois travailler émet deux signaux : l'un carré symétrique de fréquence 4 kHz/de période 250 µs ; l'autre est juste un front haut de durée 125 µs tous les 16 384 fronts hauts du premier signal, il est en front bas le reste du temps. Le premier signal représente l'émission de "signaux radars", le deuxième représente l'impulsion de référence. Donc à chaque début de tour, on a une impulsion du deuxième signal pour indiquer un nouveau tour, pendant que le premier signal émet en continu.

Mon objectif est de lire ces signaux avec mon RPi 3. Pour simuler les signaux, j'utilise une Arduino Uno dont voici le code :

Code : Tout sélectionner

#define pinA    5     // Arduino pin emitting A signal.
#define pinB    6     // Arduino pin emitting B signal.
#define period    250   // Period in microseconds.
#define aPerLap 16384 // Number of pulse per lap.

long currentA = 0;

void setup()
{

  pinMode(pinA, OUTPUT);
  pinMode(pinB, OUTPUT);

  digitalWrite(pinA, LOW);
  digitalWrite(pinB, LOW);

}

void loop()
{

  if (currentA == aPerLap * 2 || currentA == 0)
  {

    digitalWrite(pinB, HIGH);

    currentA = 0;

  }

  digitalWrite(pinA, !digitalRead(pinA));

  delayMicroseconds(period / 2);
  
  digitalWrite(pinB, LOW);

  currentA++;

  if (currentA == 16384)
  {
  
    currentA = 0;
  
  }

}
Je doute que le code soit optimisé, l'utilisation de threads ou équivalents pourrait sûrement améliorer les choses. Si tout se passe bien, j'ai mon premier signal qui émet en continu à 4 kHz comme prévu, tandis que j'ai une impulsion de 125 µs du deuxième signal toutes les 4,096 secondes.

Côté RPi, j'utilise le code suivant pour lire les signaux, abaissés du 5 V vers 3,3 V grâce à deux ponts diviseurs de tensions (un par signal) :

Code : Tout sélectionner

#include <stdio.h>
#include <stdlib.h>
#include <wiringPi.h>

#define pinA 0 // WiringPi 0 = BCM GPIO 17 = Pin# 11
#define pinB 2 // WiringPi 2 = BCM GPIO 27 = Pin# 13

int main()
{

	wiringPiSetup();

	pinMode(pinA, INPUT);
	pinMode(pinB, INPUT);

	while (1)
	{

		printf("Signal A : %d | Signal B : %d\n", digitalRead(pinA), digitalRead(pinB));

	}

	return 0;

}
Le code est simple, merci WiringPi. Mais mes soucis commencent ici : si j'ai bien des 0 et des 1 irréguliers côté signal A, je n'ai rien du tout côté signal B. Je sais qu'afficher des données dans la console prend du temps à l'échelle d'un programme, mais j'imagine que je devrais au moins avoir un 1 du signal B de temps en temps, par pure chance. De plus, en affichant les signaux A et B émis par l'Arduino sur un oscilloscope, je retrouve bien mon A carré symétrique, mais de période 285 µs au lieu de 250, et le signal B n'affiche qu'une droite à 0 V, avec de minuscules pics réguliers, positifs quand le signal A monte, négatifs quand il redescend.

Du coup mes questions :
  • Comment afficher avec précision les vraies valeurs des signaux sur le RPi ? Avec une lecture en direct (affichage console ?) ou en différé (enregistrement dans un fichier puis exploitation du fichier), peu importe. Même si Rasbian n'est pas un RTOS, j'aimerais m'approcher au plus près des valeurs réelles.
  • A quoi peut être dû l'écart entre mon signal émis (250 µs de période) et le signal lu par l'oscilloscope (285 µs de période) ? Y a-t-il moyen de réduire cet écart ?
  • Pourquoi ces petits pics mis en évidence par l'oscilloscope sur le signal B ?
Je suis bien entendu ouvert à toute suggestion !

En pièce-jointe : l'allure des deux signaux sur l'oscilloscope.
oscillo.png
oscillo.png (1.01 Kio) Vu 6288 fois
Petit aparté : j'ai également un souci de calcul du nord magnétique sur un autre sujet, à votre bon cœur !
Modifié en dernier par Pinhapple le lun. 3 avr. 2017 14:51, modifié 2 fois.
  • RPi 3 + LibreELEC / RPi 3 + RetroPie / RPi B+ + Sense HAT ou Framboisedorf ou module caméra
  • Arduino Mega, Uno, Nano
  • Freescale FRDM KL25Z

guillaume9344
Raspinaute
Messages : 629
Enregistré le : mar. 6 janv. 2015 19:44
Localisation : finistere

Re: Problème de lecture d'un signal 4 kHz avec un RPi 3

Message par guillaume9344 » jeu. 30 mars 2017 12:15

Bonjour,
la différence de timing du signal A provient du temps de traitement des autres instruction de la boucle.
Pour la gestion d' actions cycliques , vous pouvez utiliser les ticker:
https://github.com/esp8266/Arduino/blob ... rBasic.ino
cela appel à intervalles réguliers une fonction .

Pour pouvoir mesurer le signal B, l'oscillo est dans les choux, un signal de 125µs toutes les 4s est trop rapide si vous déclenchez sur le signal A , il faut un oscillo à mémoire et déclencher sur le signal B front montant.

pour la mesure sur le pi il faudrait utiliser les interruptions (voir wiringpi).
rpi b+ ,osmc, motioneyes
rpi 2 raspbian , server minecraft 24h/24 , utilisation gpio
orange pi pc debian ,utilisation gpio, motion cam

guillaume9344
Raspinaute
Messages : 629
Enregistré le : mar. 6 janv. 2015 19:44
Localisation : finistere

Re: Problème de lecture d'un signal 4 kHz avec un RPi 3

Message par guillaume9344 » jeu. 30 mars 2017 12:24

les petits pics observés sur le signal B sont du à la "diaphonie" des signaux, en gros le signal A "bave" sure le signal B à cause de la proximité des fils, les connections,.....
si ces picsne depasses pas 0.5v ils ne sont pas trop gênant.
rpi b+ ,osmc, motioneyes
rpi 2 raspbian , server minecraft 24h/24 , utilisation gpio
orange pi pc debian ,utilisation gpio, motion cam

Pinhapple
Raspinaute
Messages : 125
Enregistré le : jeu. 23 févr. 2017 15:53
Localisation : Rouen

Re: Problème de lecture d'un signal 4 kHz avec un RPi 3

Message par Pinhapple » ven. 31 mars 2017 09:36

guillaume9344 a écrit :Pour pouvoir mesurer le signal B, l'oscillo est dans les choux, un signal de 125µs toutes les 4s est trop rapide si vous déclenchez sur le signal A , il faut un oscillo à mémoire et déclencher sur le signal B front montant.
Je vais voir si on ça en stock, merci pour l'info !
guillaume9344 a écrit :pour la mesure sur le pi il faudrait utiliser les interruptions (voir wiringpi).
C'est noté, je vais aller voir la doc et des exemples de ce pas, merci encore !
guillaume9344 a écrit :les petits pics observés sur le signal B sont du à la "diaphonie" des signaux, en gros le signal A "bave" sure le signal B à cause de la proximité des fils, les connections,.....
si ces picsne depasses pas 0.5v ils ne sont pas trop gênant.
C'est toujours intéressant de pouvoir mettre un nom sur un phénomène ! :D
De ce que j'en ai vu sur l'oscillo, les valeurs des pics sont vraiment faibles, donc ça devrait aller !
  • RPi 3 + LibreELEC / RPi 3 + RetroPie / RPi B+ + Sense HAT ou Framboisedorf ou module caméra
  • Arduino Mega, Uno, Nano
  • Freescale FRDM KL25Z

guillaume9344
Raspinaute
Messages : 629
Enregistré le : mar. 6 janv. 2015 19:44
Localisation : finistere

Re: Problème de lecture d'un signal 4 kHz avec un RPi 3

Message par guillaume9344 » ven. 31 mars 2017 09:54

Pour remplacer l'oscillo vous pouvez aussi utiliser un analyseur logique , il y en a pour une poignées d'euros chez les chinois, et c'est un appareil qui servira souvent:
https://www.amazon.fr/XCSOURCE-Disposit ... ur+logique ou équivalant.
rpi b+ ,osmc, motioneyes
rpi 2 raspbian , server minecraft 24h/24 , utilisation gpio
orange pi pc debian ,utilisation gpio, motion cam

spourre
Raspinaute
Messages : 735
Enregistré le : lun. 22 déc. 2014 16:50
Localisation : 67380 LINGOLSHEIM

Re: Problème de lecture d'un signal 4 kHz avec un RPi 3

Message par spourre » ven. 31 mars 2017 10:44

+1 avec Guillaume.
Une autre cause possible est le mauvais découplage de l'alimentation de la carte qui génère les 2 signaux.
Il st toujours recommandé de mettre, au plus près de chaque circuit intégré, une capa de découplage entre le + VDD et la masse. (un 100 nF spécifique en // avec un chimique). Le design du PCB intervient aussi mais cela, Bud l'avait déjà mentionné dans la limitation de vitesse du bus SPI.

Le signal le plus problématique à traiter est certainement le signal B, non pas à cause de sa fréquence de récurrence mais à cause de sa durée.
Je suppose que le signal A, donne lui la position angulaire de l'antenne (avec une surprenante précision, bien supérieure à l'ouverture d'une grande parabole) et que le B donne le passage à une référence (à corréler plus tard avec le Nord). L'antenne tournant toujours dans le même sens, il n'y a pas à détecter le sens de rotation. La vitesse de rotation étant constante, le signal A pourrait faire une RAZ de l'angle et lancer un watchdog pour détecter l'arrêt de la rotation. Un stockage de la position à l'arrête permettrait d'éviter d'attendre, au pire, un tour complet pour retrouver une position actualisée.
Tout cela devra se faire, comme souligné par Guillaume, avec les interruptions.
Dans un premier temps, je vous suggère de ne tester que le signal ,A, en rendant votre programme paramétrable au lancement, avec 2 arguments pour la durée de l'impulsion et pour sa fréquence..
Cela vous permettra de mettre au point la thread de traitement du signal A. Commencer par allonger sa durée car Bud avait aussi mentionné un problème de latence.
Si, la durée est trop problématique, il faudra envisager de le prolonger avec un monostable externe par exemple.

Nota: Par définition, le front désigne le changement d'état du signal (montant, descendant). il est donc illogique de parler du front bas dans votre premier post. Ceci est uen remarque à titre pédagogique uniquement.

Sylvain
Modifié en dernier par spourre le ven. 31 mars 2017 16:05, modifié 1 fois.

guillaume9344
Raspinaute
Messages : 629
Enregistré le : mar. 6 janv. 2015 19:44
Localisation : finistere

Re: Problème de lecture d'un signal 4 kHz avec un RPi 3

Message par guillaume9344 » ven. 31 mars 2017 10:57

spourre a écrit : Je suppose que le signal A, donne lui la position angulaire de l'antenne (avec une surprenante précision, bien supérieure à l'ouverture d'une grande parabole)

Sylvain
Pas tout à fait , le signal A représente une synchro pour l'émission d'un train d’impulsions radar, c'est la fréquence de récurrence du radar et intervient dans la portée, la précision et d'autre paramètres .
rpi b+ ,osmc, motioneyes
rpi 2 raspbian , server minecraft 24h/24 , utilisation gpio
orange pi pc debian ,utilisation gpio, motion cam

spourre
Raspinaute
Messages : 735
Enregistré le : lun. 22 déc. 2014 16:50
Localisation : 67380 LINGOLSHEIM

Re: Problème de lecture d'un signal 4 kHz avec un RPi 3

Message par spourre » ven. 31 mars 2017 16:35

guillaume9344 a écrit :
spourre a écrit : Je suppose que le signal A, donne lui la position angulaire de l'antenne (avec une surprenante précision, bien supérieure à l'ouverture d'une grande parabole)

Sylvain
Pas tout à fait , le signal A représente une synchro pour l'émission d'un train d’impulsions radar, c'est la fréquence de récurrence du radar et intervient dans la portée, la précision et d'autre paramètres .
Je ne l'ai pas tout à fait analysé comme vous car Pinhapple écrit:

1) Que le premier signal est symétrique. Je ne connais pas beaucoup de radars qui émettent avec un rapport cyclique de 0.5 (compromis entre puissance crête et résolution radiale et éventuel Doppler) .
2) Que le 2 ème signal marque bien le début d'un nouveau tour d'antenne:
Donc à chaque début de tour, on a une impulsion du deuxième signal pour indiquer un nouveau tour, pendant que le premier signal émet en continu.
Ces considérations, certes intéressantes, ne changent pas grand chose au problème posé.

Sylvain

guillaume9344
Raspinaute
Messages : 629
Enregistré le : mar. 6 janv. 2015 19:44
Localisation : finistere

Re: Problème de lecture d'un signal 4 kHz avec un RPi 3

Message par guillaume9344 » ven. 31 mars 2017 17:28

spourre a écrit : Je ne l'ai pas tout à fait analysé comme vous car Pinhapple écrit:

1) Que le premier signal est symétrique. Je ne connais pas beaucoup de radars qui émettent avec un rapport cyclique de 0.5 (compromis entre puissance crête et résolution radiale et éventuel Doppler) .

Ces considérations, certes intéressantes, ne changent pas grand chose au problème posé.

Sylvain
sert , c'est pour cela que j'ai écrit "synchro", derrière ce n'est pas ce qui est émit. mais c'est vrai que ca ne fait pas plus avancer le chmilbique.
rpi b+ ,osmc, motioneyes
rpi 2 raspbian , server minecraft 24h/24 , utilisation gpio
orange pi pc debian ,utilisation gpio, motion cam

Pinhapple
Raspinaute
Messages : 125
Enregistré le : jeu. 23 févr. 2017 15:53
Localisation : Rouen

Re: Problème de lecture d'un signal 4 kHz avec un RPi 3

Message par Pinhapple » lun. 3 avr. 2017 14:45

spourre a écrit :Nota: Par définition, le front désigne le changement d'état du signal (montant, descendant). il est donc illogique de parler du front bas dans votre premier post. Ceci est uen remarque à titre pédagogique uniquement.
Effectivement, je pensais plutôt à "état haut" et "état bas" (respectivement 1 V et 0 V). ;)

J'ai manipulé un peu d'interruptions avec WiringPi en suivant cet exemple issu du GitHub officiel, exemple que j'ai adapté à mes besoins : lecture d'une seule pin, puis de deux. Si je comprends bien, lire les interruptions avec INT_EDGE_RISING me permet de lire de déclencher une action dès que le signal "monte", c'est-à-dire à chaque front montant ? Si c'est bien le cas, c'est exactement ce qu'il me faut !

Pour lire une seule pin, j'ai adapté l'exemple donné plus haut en remplaçant les tableaux par des int, ce qui me permet bien de lire environ 4 096 fronts montants par seconde de mon signal A. En revanche, si je tente de lire mon signal B (pour rappel, un état haut de 250 µs toutes les 4,096 secondes, état bas le reste du temps), le programme pédale dans le vide et rien ne s'affiche dans la console, alors que je m'attendais à un front montant toutes les 4 secondes.

Auriez-vous une idée de ce qui peut coincer ? Est-ce que mon code Arduino me permet d'obtenir ce que je souhaite ?

De plus, je souhaite afficher en console l'état en direct de mes deux signaux, sous la forme "Signal A : [0 ou 1] | Signal B : [0 ou 1]" ; est-ce que c'est jouable malgré la faible durée de mes fronts et la relativement haute durée d'affichage en console ? L'idée finale étant de pouvoir récupérer l'état de mes signaux pour les afficher dans un label ou sur un graphique (segment en rotation autour d'un point).

Le code C issu de l'exemple WiringPi que j'utilise :

Code : Tout sélectionner

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wiringPi.h>

static volatile long globalCounter;

void interrupt(void)
{

    ++globalCounter;

}

int main()
{

    int gotOne, pin;
    int myCounter;

    globalCounter = myCounter = 0;

	wiringPiSetup();

	wiringPiISR(0, INT_EDGE_RISING, &interrupt); // 0 pour le signal A, 2 pour le signal B.

	for (;;)
    {

        gotOne = 0;

        fflush(stdout);

        for (;;)
        {

            if (globalCounter != myCounter)
            {

                if (globalCounter == 16384)
                {

                    globalCounter = 0;

                }

                printf("Counter : %d\n", globalCounter);

                myCounter = globalCounter;

                ++gotOne;

            }

            if (gotOne != 0)
            {

                break;

            }

        }

    }

	return 0;

}
Concernant les signaux : le A représente les 16 384 impulsions envoyées par le radar à chaque tour, tandis que le signal B représente le signal de référence qui indique qu'un nouveau tour commence. Bravo à ceux qui avaient deviné ! ;)
  • RPi 3 + LibreELEC / RPi 3 + RetroPie / RPi B+ + Sense HAT ou Framboisedorf ou module caméra
  • Arduino Mega, Uno, Nano
  • Freescale FRDM KL25Z

Répondre

Retourner vers « L'électronique et le Raspberry Pi »