Python et Ethernet/UDP

Python est le langage de prédilection du Raspberry Pi

Modérateurs : Francois, Manfraid

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

Re: Python et Ethernet/UDP

Message par Pinhapple » jeu. 22 juin 2017 10:48

romaxx a écrit :ah oui le CESI... l'important c'est d' être passionné ;)
Ha ha, oui, faut savoir bosser de sa propre initiative ! ;)
romaxx a écrit :Temps réel = traitements synchrones, c'est par exemple la différence entre un UART et un USART. Si ton périphérique n'a pas répondu au bout d'un temps bien précis, c'est considéré au niveau hardware comme un évènement que tu peux exploiter dans ton programme.
Ok, merci pour les explications ! :)
romaxx a écrit :L'arduino est basé sur le W5500 pour l'Ethernet c'est bien ça ?
W5100 ! C'est un shield no-name chinois qu'on m'a fourni. J'ai également un "vrai" shield Ethernet Arduino, équipé lui d'un W5500, mais à code égal, il ne fonctionne pas... :?
romaxx a écrit :Arduino t'es imposé ?
Arduino ou RPi ; comme j'ai vu que c'était grillé pour tout faire juste en RPI (OS non-temps réel) ou juste en Arduino (pas assez de mémoire), je tente un outil avec les deux : acquisition et traitement par l'Arduino, stockage et exploitation des résultats sur RPi. Après plusieurs discussions en ligne, on m'a suggéré d'utiliser une Arduino Due, plus puissante et plus rapide, mais ici on m'a imposé une Uno pour réduire les coûts.
  • RPi 3 + LibreELEC / RPi 3 + RetroPie / RPi B+ + Sense HAT ou Framboisedorf ou module caméra
  • Arduino Mega, Uno, Nano
  • Freescale FRDM KL25Z

destroyedlolo
Raspinaute
Messages : 1634
Enregistré le : dim. 10 mai 2015 18:44
Localisation : Dans la campagne à côté d'Annecy
Contact :

Re: Python et Ethernet/UDP

Message par destroyedlolo » jeu. 22 juin 2017 11:36

Salut,
Pinhapple a écrit :Arduino ou RPi ; comme j'ai vu que c'était grillé pour tout faire juste en RPI (OS non-temps réel) ou juste en Arduino (pas assez de mémoire), je tente un outil avec les deux
J'ai suivi en diagonal vos échanges : il aurait peut-être été possible de tout faire sur le PI soit en créant un démon en C, soit si ca ne passait pas en créant un module kernel pour prendre en charge le côté acquisition temps réel. Mais si la création d'un module n'a rien de transcendant, "taper" directement dans le hard pour gérer les timers nécessaires et les IRQ GPIO tout en respectant le système est une autre affaire ... surtout avec tes contraintes de temps pour finaliser ton projet (trouver les docs sur les API kernel correspondante, expérimenter, ... et s'ajoute peut etre aussi pour toi le fait de maitriser la compilation et la philosophie d'un kernel)
Bref, utiliser un Arduino + PI me semble un bon compromis.

La communication entre les 2 est qq chose de classique dans le monde IoT ; si ce n'est pas fait, tu devrait peut etre faire une recherche dans ce domaine car il existe peut etre déjà des librairies toutes faites pour l'Arduino qui le font.

A+
  • BananaPI : Gentoo, disque SATA de 2 To
  • Domotique : 1-wire, TéléInfo, Tablette passée sous Gentoo, ESP8266
  • Multimedia par DNLA
  • Et pleins d'idées ... et bien sûr, pas assez de temps.
Un descriptif de ma domotique 100% fait maison.

romaxx
Messages : 78
Enregistré le : lun. 24 oct. 2016 10:59

Re: Python et Ethernet/UDP

Message par romaxx » jeu. 22 juin 2017 11:55

destroyedlolo a écrit :Bref, utiliser un Arduino + PI me semble un bon compromis.
La communication entre les 2 est qq chose de classique dans le monde IoT ; si ce n'est pas fait, tu devrait peut etre faire une recherche dans ce domaine car il existe peut etre déjà des librairies toutes faites pour l'Arduino qui le font.
Oui, utiliser un PI + uC est une bonne chose, que ce soit Arduino, pic ou autre (de nombreux HAT pilotant des servos / actionneurs utilisent ce principe).
C'est courant dans le monde de l'IoT, oui, mais l'IoT ne nécessite pas vraiment de déterminisme, juste de la fiabilité.

Sur arduino due il y a des libs DMA pour l'UART (https://github.com/rblilja/DmaSerial), peut être qu'une liaison UART en DMA entre pi et arduino ferait l'affaire.

ps: @destroyedlolo, je peux pas répondre aux MP.. :cry:
--
Adhérent à l'A.F.S.T.L

destroyedlolo
Raspinaute
Messages : 1634
Enregistré le : dim. 10 mai 2015 18:44
Localisation : Dans la campagne à côté d'Annecy
Contact :

Re: Python et Ethernet/UDP

Message par destroyedlolo » jeu. 22 juin 2017 14:13

Salut,
romaxx a écrit :C'est courant dans le monde de l'IoT, oui, mais l'IoT ne nécessite pas vraiment de déterminisme, juste de la fiabilité.
Ben, les timings étaient serrés pour l’acquisition des signaux, ce n'est peut-être plus le cas entre l'arduino et le PI ( @Pinhapple, tu nous à pas indiqué si le flux était continue et si oui avec quels volumétrie, ou si c'est pas batch, donc on a "un peu de temps" entre chaque trames).
Si on a plus de marge de manœuvre, ca peut être (conditionnel) plus interessant/scalable/évolutif de passer par des solutions MQTT que de faire des transfère de bas niveau. Sans compter que dans le cadre d'un projet de fin d'étude, ca fait gagner du temps car les impondérables sont déjà pris en compte donc moins de temps à passé sur du débugging.
romaxx a écrit :ps: @destroyedlolo, je peux pas répondre aux MP.. :cry:
Pas grave, c'était pour ST :)

A+
  • BananaPI : Gentoo, disque SATA de 2 To
  • Domotique : 1-wire, TéléInfo, Tablette passée sous Gentoo, ESP8266
  • Multimedia par DNLA
  • Et pleins d'idées ... et bien sûr, pas assez de temps.
Un descriptif de ma domotique 100% fait maison.

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

Re: Python et Ethernet/UDP

Message par Pinhapple » jeu. 22 juin 2017 15:56

destroyedlolo a écrit :@Pinhapple, tu nous à pas indiqué si le flux était continue et si oui avec quels volumétrie, ou si c'est pas batch, donc on a "un peu de temps" entre chaque trames).
Si on a plus de marge de manœuvre, ca peut être (conditionnel) plus interessant/scalable/évolutif de passer par des solutions MQTT que de faire des transfère de bas niveau. Sans compter que dans le cadre d'un projet de fin d'étude, ca fait gagner du temps car les impondérables sont déjà pris en compte donc moins de temps à passé sur du débugging.
L'idée est, pour chaque tour, de compter le nombre d'impulsions du signal, de mesurer la durée entre deux fronts montants consécutifs, et de mesurer la durée d'un niveau haut. En espérant comprendre le sens de ta question : le flux est continu (pas de pause, je lance et arrête l'enregistrement pendant que le radar tourne déjà) ; par contre, qu'entends-tu par "volumétrie" ? Si c'est le nombre d'impulsions du signal, on est à 4 kHz, donc 4 000 impulsions par seconde, et 16 384 impulsions par tour, donc on a 1 tour = 4,096 secondes = 16 384 impulsions (à la louche, et c'est là que mon projet serait utile pour détecter d'éventuels écarts).

J'ai fait quelques calculs et tests cet après-midi : j'ai théoriquement 16 384 impulsions par tour (5 caractères), 125 µs de durée d'impulsion (3 caractères), et 250 µs entre deux fronts montants (3 caractères) : si je fais le calcul de ce que je vais avoir à balancer en UDP, j'arrive à 5 + 16 384 * 3 + 16 384 * 3 = 98 309 caractères dans une chaîne, sans même inclure les séparateurs, ce qui ferait monter le total à 98 309 + 32 768 = 131 077 caractères. Je n'y connais pas grand chose en UDP avec Python et Arduino, mais ça ne représente pas une immense quantité de données à envoyer/recevoir ? Sachant que l'Arduino est censé envoyer cette chaîne entre deux impulsions, donc en moins de 125 µs... :shock:
  • RPi 3 + LibreELEC / RPi 3 + RetroPie / RPi B+ + Sense HAT ou Framboisedorf ou module caméra
  • Arduino Mega, Uno, Nano
  • Freescale FRDM KL25Z

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

Re: Python et Ethernet/UDP

Message par Pinhapple » jeu. 22 juin 2017 16:00

destroyedlolo a écrit :@Pinhapple, tu nous à pas indiqué si le flux était continue et si oui avec quels volumétrie, ou si c'est pas batch, donc on a "un peu de temps" entre chaque trames).
Si on a plus de marge de manœuvre, ca peut être (conditionnel) plus interessant/scalable/évolutif de passer par des solutions MQTT que de faire des transfère de bas niveau. Sans compter que dans le cadre d'un projet de fin d'étude, ca fait gagner du temps car les impondérables sont déjà pris en compte donc moins de temps à passé sur du débugging.
L'idée est, pour chaque tour, de compter le nombre d'impulsions du signal, de mesurer la durée entre deux fronts montants consécutifs, et de mesurer la durée d'un niveau haut. En espérant comprendre le sens de ta question : le flux est continu (pas de pause, je lance et arrête l'enregistrement pendant que le radar tourne déjà) ; par contre, qu'entends-tu par "volumétrie" ? Si c'est le nombre d'impulsions du signal, on est à 4 kHz, donc 4 000 impulsions par seconde, et 16 384 impulsions par tour, donc on a 1 tour = 4,096 secondes = 16 384 impulsions (à la louche, et c'est là que mon projet serait utile pour détecter d'éventuels écarts).

J'ai fait quelques calculs et tests cet après-midi : j'ai théoriquement 16 384 impulsions par tour (5 caractères), 125 µs de durée d'impulsion (3 caractères), et 250 µs entre deux fronts montants (3 caractères) : si je fais le calcul de ce que je vais avoir à balancer en UDP, j'arrive à 5 + 16 384 * 3 + 16 384 * 3 = 98 309 caractères dans une chaîne, sans même inclure les séparateurs, ce qui ferait monter le total à 98 309 + 32 768 = 131 077 caractères. Je n'y connais pas grand chose en UDP avec Python et Arduino, mais ça ne représente pas une immense quantité de données à envoyer/recevoir ? Sachant que l'Arduino est censé envoyer cette chaîne entre deux impulsions, donc en moins de 125 µs... :shock:
  • RPi 3 + LibreELEC / RPi 3 + RetroPie / RPi B+ + Sense HAT ou Framboisedorf ou module caméra
  • Arduino Mega, Uno, Nano
  • Freescale FRDM KL25Z

destroyedlolo
Raspinaute
Messages : 1634
Enregistré le : dim. 10 mai 2015 18:44
Localisation : Dans la campagne à côté d'Annecy
Contact :

Re: Python et Ethernet/UDP

Message par destroyedlolo » jeu. 22 juin 2017 17:01

Ok, ca se clarifie (enfin j'espère :) )

1t = 4,096 secondes ce qui correspond à 16384 impulsions et tu dois envoyé tes informations pour chaque tour, donc toutes les 4,096s : tu confirmes ?

Si je reprend ta formule 5 + 16 384 * 3 + 16 384 * 3 = 98 309 ok mais t'où vienne les 32768 supplémentaires ? C'est pour l'enveloppe de tes données ?

Quoi qu'il en soit, 131 077 octets sur 5s, c'est vraiment pinuts en ethernet.
Meme si tu envois les données des que tu les revoie, ca te fait du 3*2 = 6c + 2c de séparation toutes les 4,096 / 16 384 = 0.25s + toutes les 4,096s 5 ou 6 caractères pour le nbre d’impulsion par tour.

Donc grosso modo, 8 * 4 = 32 c/s ce n'est franchement pas énorme.
  • BananaPI : Gentoo, disque SATA de 2 To
  • Domotique : 1-wire, TéléInfo, Tablette passée sous Gentoo, ESP8266
  • Multimedia par DNLA
  • Et pleins d'idées ... et bien sûr, pas assez de temps.
Un descriptif de ma domotique 100% fait maison.

Bud Spencer
Modérateur
Messages : 1094
Enregistré le : lun. 15 août 2016 21:38

Re: Python et Ethernet/UDP

Message par Bud Spencer » jeu. 22 juin 2017 18:08

Pinhapple a écrit :J'ai fait quelques calculs et tests cet après-midi : j'ai théoriquement 16 384 impulsions par tour (5 caractères), 125 µs de durée d'impulsion (3 caractères), et 250 µs entre deux fronts montants (3 caractères) : si je fais le calcul de ce que je vais avoir à balancer en UDP, j'arrive à 5 + 16 384 * 3 + 16 384 * 3 = 98 309 caractères dans une chaîne, sans même inclure les séparateurs, ce qui ferait monter le total à 98 309 + 32 768 = 131 077 caractères. Je n'y connais pas grand chose en UDP avec Python et Arduino, mais ça ne représente pas une immense quantité de données à envoyer/recevoir ? Sachant que l'Arduino est censé envoyer cette chaîne entre deux impulsions, donc en moins de 125 µs... :shock:

T’es pas prêt de t’en sortir comme ça.
Primo :
Convertir tes entiers en string, c’est du n’importe quoi. Ça te fais (16384 * 2) + 1 conversion par tour. Je ne parle même pas de l’explosion relative de la quantité mémoire utilisé (faut-il encore qu’il y en ait assez sur l’arduino) pour tout buffériser. Tout ça pour qu’a l’envoi tout soit forcement re-encoder en octets avec en prime une multiplication par 4 la volumétrie nécessaire.

Un truc qu’il faut savoir, c’est que tu ne transmets ni des chaines de caractères et encore moins des entiers. Tu ne transmets que des octets et la quantité dépend des types de départ et de l’encodage utilisé.

Secondo : 131077 octet par tours.
Un datagram UDP unicast c’est maxi 65535 octet. Là-dessus, il faut en enlever 20 pour le header IP et 8 pour le header UDP donc la taille maxi du payload c’est 65535 – (20 + 8) = 65507 octet. Ce qui veut dire qu’avec ta méthode tu vas devoir envoyer les résultats d’un tour en au moins 3 séquences. Il faut aussi savoir que les gros datagramme UDP, c’est bien, mais forcement ça fragmente (de mémoire MTU Ethernet 1500 octet) et qui dit fragmentation dit conso mémoire (si l'en reste ...) , conso uc (si il a encore du temps) et dégradation des performance (et pas qu’un peu sur des petits systèmes comme le pi ou l’arduino)

Pour résumer, ton arduino est déjà sur les rotules à force de traitement d’interrupt. et de conversion, il n’a plus de mémoire et sa couche réseaux est totalement saturée.
Pour te répondre clairement, Non, ca ne marchera pas avec ces méthodes.

Ton problème de volumétrie par tour peut tout simplement se résoudre en 32770 octets en raisonnant de la sorte :
1 word (2 octets) pour stocker la valeur d’impulsion + 16384 bytes (1 octet) pour stocker 16384 durée d’impulsion + 16384 bytes (1 octet) pour stocker 16384 durée de signaux.
De là à les envoyer en 125 µS, ce n’est pas gagné …
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

romaxx
Messages : 78
Enregistré le : lun. 24 oct. 2016 10:59

Re: Python et Ethernet/UDP

Message par romaxx » jeu. 22 juin 2017 19:02

Bud Spencer a écrit : Secondo : 131077 octet par tours.
Un datagram UDP unicast c’est maxi 65535 octet. Là-dessus, il faut en enlever 20 pour le header IP et 8 pour le header UDP donc la taille maxi du payload c’est 65535 – (20 + 8) = 65507 octet. Ce qui veut dire qu’avec ta méthode tu vas devoir envoyer les résultats d’un tour en au moins 3 séquences. Il faut aussi savoir que les gros datagramme UDP, c’est bien, mais forcement ça fragmente (de mémoire MTU Ethernet 1500 octet) et qui dit fragmentation dit conso mémoire (si l'en reste ...) , conso uc (si il a encore du temps) et dégradation des performance (et pas qu’un peu sur des petits systèmes comme le pi ou l’arduino)

Ton problème de volumétrie par tour peut tout simplement se résoudre en 32770 octets en raisonnant de la sorte :
1 word (2 octets) pour stocker la valeur d’impulsion + 16384 bytes (1 octet) pour stocker 16384 durée d’impulsion + 16384 bytes (1 octet) pour stocker 16384 durée de signaux.
De là à les envoyer en 125 µS, ce n’est pas gagné …
Datasheet du W5100: Not support IP Fragmentation, ça c'est fait.

La seule solution que je vois c'est de faire de l'UART DMA, comme ça ton uC n'est pas bouffé par les interruptions de com, il se concentre sur ton acquisition de données, et ton pi vient chercher les données sur ton arduino en DMA.
--
Adhérent à l'A.F.S.T.L

Bud Spencer
Modérateur
Messages : 1094
Enregistré le : lun. 15 août 2016 21:38

Re: Python et Ethernet/UDP

Message par Bud Spencer » jeu. 22 juin 2017 20:40

romaxx a écrit :Datasheet du W5100: Not support IP Fragmentation, ça c'est fait.
Ca tu t'en fous puisque de toutes façon, dans ce cas d'utilisation, tu ne peut pas vraiment te permettre d'avoir des datagrammes fragmentés.
romaxx a écrit : La seule solution que je vois c'est de faire de l'UART DMA, comme ça ton uC n'est pas bouffé par les interruptions de com, il se concentre sur ton acquisition de données, et ton pi vient chercher les données sur ton arduino en DMA.
Tu peux nous écrire un petit bout de code d'exemple coté pi et coté arduino pour être plus explicite ?
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 »