Comment traiter données issues d'un capteur

Python est le langage de prédilection du Raspberry Pi

Modérateurs : Francois, Manfraid

redscreen
Messages : 15
Enregistré le : ven. 28 févr. 2020 17:05

Re: Comment traiter données issues d'un capteur

Message par redscreen » mar. 24 mars 2020 19:39

excellent :) heureux d'apprendre que tout va rouler, heuuuu voler :mrgreen:
pour le PWM je vais tester avec des servos de modélisme que j'ai sous la main (alimentés en 5V externe au pi), car les vérins, je ne les ai pas sous la main :(

pour le moment je teste le port série, je viens d'essayer vite fait, mais petit blocage bête, ça râle : le module "serialport" n'est pas installé
je vais donc relire tes tutos pour voir si il y a l'info quant à ce qu'on doit mettre dans le fichier "package.json" (jusqu'à présent je recopiais toujours les "package.json" et "package-lock.json"de la leçon4)
j'ai bien eu l'envie d'ajouter la ligne "serialport" au "package.json", oui mais il faut préciser une version...

j’exécute alors un: "npm install serialport" -> renvoi plein d'erreurs car il ne trouve pas visual studio..
(je fais les tests sous windows pour l'instant)

edit: notice npm et package.json trouvé dans le tuto page4
reste serialport qui ne veut pas s'installer, j'essayerai demain sur la pi, mais ça paraissait tellement cool un truc portable indépendant de l'os..

Bud Spencer
Raspinaute
Messages : 786
Enregistré le : lun. 15 août 2016 21:38

Re: Comment traiter données issues d'un capteur

Message par Bud Spencer » mer. 25 mars 2020 11:27

Je n’avais pas fait l’essais d’installer le npm serialport sous Windows, mais je viens de le faire et chez moi sans soucis (Windows 10 pro 1909). Bon j’ai bien visual studio 2019 d’installé, mais je ne vois pas trop l’incidence puisque le package est normalement fournis précompilé pour windows. De toutes façon, tu vas vite etre limité sous windows puisque tu ne pourras installer rpio que sur le pi.

Pour les pwm, j’ai fait le test et les 2 canaux sont bien indépendants donc 2 signaux pwm bien distinct possible.

Sinon, j’ai regardé un peu le code arduino que tu as mis en début de topic et c’est tout à fait faisable de le convertir en code nodejs pour un mcp3208. Je ne dois pas avoir le type de capteur que tu utilises pour essayer, mais il me semble qu’il me reste des accéléromètres 3 axes d’un projet pour lequel j’avais déjà codé un filtre de type kalman en c# pour une carte Cerb40 de chez GHI. Je vais voir si je retrouve tout ça.
Pour le fichier package.json, je n’en avais pas trop parlé au début du tuto, mais il faut considérer que c’est la première chose à faire. Il est ensuite automatiquement mis à jour par les commandes npm.
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

redscreen
Messages : 15
Enregistré le : ven. 28 févr. 2020 17:05

Re: Comment traiter données issues d'un capteur

Message par redscreen » mer. 25 mars 2020 14:18

pour info si jamais cela intéresse quelqu'un d'installer le module "serialport" sous windows : (précompilé pour windows tu dis, mais justement il veut me le compiler à tout pris, et sans VS il n'y arrive pas) -> une piste :
npm install --global --production windows-build-tools (run as administrator powershell) (et python doit être installé...)
mais effectivement, pourquoi insister, puisque mon pc Windows n'aura de tout façon pas de GPIO

donc j'ai rebranché la pi3b -> et après un "npm install serialport" (en tant que root) -> YES !! :D tout va bien, je récupère maintenant les données du port série !!
j'attaque la partie GPIO PWM

redscreen
Messages : 15
Enregistré le : ven. 28 févr. 2020 17:05

Re: Comment traiter données issues d'un capteur

Message par redscreen » ven. 27 mars 2020 20:24

J'ai fais mon petit branchement de servo (un Futaba S3003), juste pour voir que j'accède bien au GPIO PWM.

Je me suis basé sur ce tuto: https://raspberrypi.pagesperso-orange.f ... /26-03.htm
[accu 4.8V externe, masse commune servo/rpi, fil PWM sur rpi GPIO13]
jusque là tout va bien, j'installe rpio -> OK, et j'adapte l'exemple que tu as mis dans ton tuto page21:

// servo Futaba S3003 :
var x = 0;
var rpio = require("rpio");
rpio.init({ gpiomem: false, mapping: "gpio" });

rpio.pwmSetClockDivider(375); // défaut : 19.2Mhz -> 19200000/1024/375 = 50Hz

rpio.open(13, rpio.PWM);

rpio.pwmSetRange(13, 1024);

setInterval(function () { // servo S3003 : rapport cyclique entre 19 (0°), et 119 (180°)
x = x < 119 ? x+= 10 : 19; // ici je comprend pas trop la syntaxe, si jamais tu as le temps de m'expliquer...
rpio.pwmSetData(13, x);
}, 500);


Il est indiqué de définir le "ClockDivider" à 375, et c'est la que ça pose problème pour lancer programme.js -> "Clock divider must be zero or power of two"

Quand je lis la doc https://www.npmjs.com/package/rpio au 3/4 de la page, partie PWM, j'en conclu qu'il est impossible de définir la fréquence à 50Hz ?...

edit (je fais les questions et les réponses :lol: ): ah ben si, en changeant le range :
pwmSetClockDivider(256);
rpio.pwmSetRange(13, 1500); // 19200000/1500/256=50Hz, la plage (0°-180°) sera juste décalée à (28-174)

cool ! :D
avec un servo (donc en boucle fermée) ce n'est pas l'idée finale, dommage que je n'ai pas le reste du matos à dispo.

Bud Spencer
Raspinaute
Messages : 786
Enregistré le : lun. 15 août 2016 21:38

Re: Comment traiter données issues d'un capteur

Message par Bud Spencer » ven. 27 mars 2020 23:41

redscreen a écrit :
ven. 27 mars 2020 20:24
x = x < 119 ? x+= 10 : 19; // ici je comprend pas trop la syntaxe, si jamais tu as le temps de m'expliquer...
C'est ce que l'on appel un operateur ternaire (ou operateur conditionnel). Cela permet d'attribuer une valeur a une variable en fonction d'une condition. J'en avais déjà un peut parlé la et en fait c'est juste un if else simplifié :

x = x < 119 ? x+= 10 : 19

équivaut à

if x < 119
{
x = x + 10
}

else
{
x= 19
}



redscreen a écrit :
ven. 27 mars 2020 20:24
Quand je lis la doc https://www.npmjs.com/package/rpio au 3/4 de la page, partie PWM, j'en conclu qu'il est impossible de définir la fréquence à 50Hz ?...
Ici on utilise directement les canaux pwm hardware du processeur et on ne peux que définir un diviseur pour leur fréquence. la fréquence de base est de 19.2MHz et le diviseur maxi est de 4096 (et doit etre une puissance de 2 : 0,2,4,8,16,32 ... 1024,2048,4096), donc une fréquence mini de de 19200000Hz / 4096. Perso, je n'ai jamais essayé ca avec des servos rc.
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

redscreen
Messages : 15
Enregistré le : ven. 28 févr. 2020 17:05

Re: Comment traiter données issues d'un capteur

Message par redscreen » sam. 28 mars 2020 14:21

merci pour l'explication, et pour le lien, ça ne me fera pas de mal de lire ça.

j'essaye d'associer les mouvements "axe roulis udp" aux mouvements du servo,
j'ai donc essayé un truc du genre : (mais la syntaxe de mon test ne fonctionne pas)

x = x < 33 ? x = 33 : x = UDPData[13][1]+97; // pour définir une fin de course minimum et décaler le neutre à 97
x = x > 162 ? x = 162 : x = UDPData[13][1]+97; // pour définir une fin de course maximum
rpio.pwmSetData(13, x);

UDPData[13][1] = valeur en degrés de l'inclinaison
33 = rapport cyclique minimum (valeur minimum pour ne pas forcer sur le servo)
97 = à plat = servo au neutre
162 = rapport cyclique maximum (à ne pas dépasser pour ne pas forcer sur le servo)

j'ai d'abord pensé à une fonction map() que j'utilise sur arduino, je voudrais renvoyer (-90 +90) vers (33, 162) avec neutre à (97), mais je ne trouve pas d’équivalent

Bud Spencer
Raspinaute
Messages : 786
Enregistré le : lun. 15 août 2016 21:38

Re: Comment traiter données issues d'un capteur

Message par Bud Spencer » sam. 28 mars 2020 19:01

Tu es étudiant mais visiblement tu ne fais pas math sup :lol: (bha quoi un peu d'humour les gars … ).
Pas la peine de faire de map vue que la relation x<=>degré est parfaitement linéaire. une map devient utile uniquement quand la relation devient trop complexe (voir impossible) à calculer mathématiquement.

Voila 2 petites fonctions qui te font la conversion x en degré et degré en x (comme je savait pas laquelle tu avais besoin …). Je ne l'ais volontairement pas fait pour que ce soit explicite, mais tu peux simplifier les opérations (et tu as tout intérêt à le faire). Je te laisse admirer les ternaires de i sur 2 conditions ;)

Code : Tout sélectionner


var xToDegre = (value)=> {
    let i = parseInt((((90 - -90) / (162 - 33)) * (value - 33)) + -90);
    i = i < -90 ? -90 : i > 90 ? 90 : i;
    return i;
}

var degreToX = (value)=> {
    let i = parseInt((((162 - 33) / (90 - -90)) * (value - -90)) + 33);
    i = i < 33 ? 33 : i > 162 ? 162 : i;
    return i;
}

console.log("x=>degre");
console.log("si x = 33 alors degré = " + xToDegre(33));
console.log("si x = millieu (97) alors degré = " + xToDegre(97));
console.log("si x = 162 alors degré = " + xToDegre(162));
console.log("degre=>x");
console.log("si degré = -90 alors x = " + degreToX(-90));
console.log("si degré = millieu (0) alors x = " + degreToX(0));
console.log("si degré = 90 alors x = " + degreToX(90));


Modifié en dernier par Bud Spencer le sam. 28 mars 2020 21:07, modifié 1 fois.
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

Bud Spencer
Raspinaute
Messages : 786
Enregistré le : lun. 15 août 2016 21:38

Re: Comment traiter données issues d'un capteur

Message par Bud Spencer » sam. 28 mars 2020 19:20

j'avais oublié la preuve en image :
xdegx.png
xdegx.png (3.96 Kio) Vu 71 fois
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

redscreen
Messages : 15
Enregistré le : ven. 28 févr. 2020 17:05

Re: Comment traiter données issues d'un capteur

Message par redscreen » dim. 29 mars 2020 18:25

yes, ça marche nickel merci
j'ai tendance à toujours vouloir laisser l'ordinateur calculer à ma place :lol:
et effectivement je ne fais pas math sup :lol: ;)

tout fonctionne maintenant,
en attendant de pouvoir tester avec les vérins...

par contre si le "jeu" (client udp) n'est pas lancé avant, le programme refuse de se lancer car les variables ne sont pas définies,
j'ai donc essayé de les définir avant avec :

Code : Tout sélectionner

if (typeof UDPData[28] == 'undefined') {
        UDPData = new Array(29);
        for (let i=0; i<29; i++) {
        UDPData[i] = new Array(2);
        UDPData[i][0] = "Veuillez lancer le jeu";
        UDPData[i][1] = 0;
        }
}
mais si je fais ça, bien même quand je lance le client, ça reste toujours à 0 :roll:
Modifié en dernier par redscreen le dim. 29 mars 2020 19:24, modifié 1 fois.

Bud Spencer
Raspinaute
Messages : 786
Enregistré le : lun. 15 août 2016 21:38

Re: Comment traiter données issues d'un capteur

Message par Bud Spencer » dim. 29 mars 2020 19:06

Quand on parle de variable, il y 2 notions :
Definir et Initialiser.

Pour définir ta variable Data en Javascript il te suffit (il faut …) de le faire au début du programme :
var Data = [] ;

Ok, Data est définie comme étant un tableau, mais pour l’instant, pas encore initialiser, donc vide. Donc si tu appelles Data[0], ça n’existe pas, donc forcément le truc se plante lamentablement (en fait ton programme se lance sans doute, mais il plante des qu’il y a un appel de ce type).

Pour remédier à ça, c’est très simple. Dans la procédure qui utilise Data[0] (ou Data[cequetuveux]) il suffit de placer (avant le traitement) une instruction de controle genre

Code : Tout sélectionner

If (Data.length < x){return ;}
…reste de la procedure de traitement
Ou x est la taille du tableau quand il a été initialisé par la réception de données. De fait tant que Data n’a pas de donnée, on sort de la procédure et le traitement n’est pas effectué.

Tu peux meme aller plus loin avec un truc du genre :

Code : Tout sélectionner

If (Data.length < x){
console.log("en attente de données du jeu") ;
return ;
}
…reste de la procedure de traitement
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

Répondre

Retourner vers « Python »