P4 IOT 2018

De Wiki d'activités IMA

Présentation du sujet

Contexte

Prenons le cas d'une soutenance de quatrième année, strictement limitée en temps. On ne voudrait surtout pas rater cette dernière et ne pas avoir l'occasion de passer en revue l'ensemble de ses slides ! Le jury ne souhaite cependant pas faire office d'arbitre ou d'interrompre la personne soutenant. Ainsi, un timer connecté permettant d'indiquer le temps restant aux deux parties est placé sur la table. Ce timer fait également office de point d'accès et permet de se connecter à une page web ou les enseignants peuvent noter des commentaires que l'étudiant peut observer en temps réel.

Description du projet

Le projet consiste donc à réaliser un timer connecté, disposant de 4 afficheurs 7 segments, dont deux feront face à l'étudiant et les deux autres au jury. Nous utilisons une raspberry pi 3, et nous basons ainsi notre timer sur le timer ARM de cette dernière. La raspberry fait également office de point d'accès permettant de délivrer une page web qui permet de configurer le timer. Le code controllant les afficheurs 7 segments sera réalisé en C. Le serveur web sera basé sur le framework express de node js. Le PCB sera réalisé sous Eagle.

Réalisation

Matériel utilisé

  • 1 Raspberry pi 3
  • 4 afficheurs 7 segments SA23-11SRWA
  • 16 transistors PNP 2N2894
  • 2 multiplexeurs 74HCT595
  • 16 résistances 56 Ohms
  • 16 résistances 1,2kOhms
  • 2 capacités 100nF
  • 1 capacité 10uF

Séance 1

Recherche d'un sujet et clarification du cahier des charges

Après avoir passé du temps à rechercher un sujet, nous nous sommes orienté vers le sujet proposé par les encadrants, le timer connecté. Nous avons alors passé le reste de la séance à effectuer des recherches sur le matériel à utiliser ainsi qu'à définir les fonctionnalités que présentera notre timer. Les fonctionnalités retenues sont les suivantes :

- Une application mobile permettra de contrôler le timer

- Si l'utilisateur est un membre du jury, il pourra modifier le timer

- Si l'utilisateur est une personne qui soutient, il ne pourra que consulter le timer

- Un système de vote sera disponible à partir de l'application

- Lorsqu'il restera 2 minutes sur le timer, le téléphone de l'utilisateur vibrera

- Le timer sera double face afin qu'il soit visible par le jury et l'étudiant


Finalement, nous avons été amené à revoir les fonctionnalités proposées au cours du projet par manque de temps. L'application a été remplacé par un site web. Le système de vote n'a pas été mis en place mais le membre du jury peut écrire des commentaires à la personne qui soutient à travers le site web. La fonctionnalité de vibration à été remplacée par un système de modification de la coloration du timer présent sur le site web à partir d'un certain temps restant.

Pendant cette séance, nous avons également établit une liste du matériel que nous utiliserons : une Raspberry pi pour faire tourner le serveur accessible en wifi, un transformateur 230VAC vers 5VDC pour alimenter la Raspberry, des afficheurs 7-segments, et un driver de leds pour utiliser le moins de sortie possible.

Séance 2

Structuration du projet

Lors de cette séance, des afficheurs 7-segments nous ont été fournis. Cependant, ils présentent la particularité d'être alimenté avec 12V. Les alimenter directement par la Raspberry qui elle peut fournir 5V n'est donc pas possible.

Nous anons essayé de trouver une solution pour le contrôle des LED. Nous en avons retenu deux :

- Utiliser des pilotes de LED TLC5947

- Utiliser des transistors

Nous avons alors décidé de partir sur les pilotes de LED pour plus de simplicité, ces derniers gérant eux mêmes le courant fournis aux LED. Après avoir pris cette décision, nous avons débuté la conception de la carte sous Eagle. Nous avons choisi ce logiciel car les toutes les footprint des composants utilisés sont disponibles sur le net.

Nous avons également pu trouver des bibliothèques python pour utiliser le pilote de leds, et commencer le programme. Nous utiliserons deux pilotes de leds en cascade que nous contrôlerons avec 3 GPIO de la Raspberry. Nous avons également prévu de rajouter un ATMega328p qui pourra lui aussi contrôler les pilotes si on modifie la position de trois jumper. L'ATMega sera relié à la Raspberry en série pour qu'il puissent être programmé à travers elle.

Pour alimenter le device, nous avons ajouté à notre liste de matériel un transformateur 230VAC vers 12VDC pour alimenter les leds ainsi qu'un régulateur 12VDC vers 5VDC pour alimenter la Raspberry (2A). Ensuite la Raspberry se chargera d'alimenter les pilote de leds et l'ATMega328p.

Séance 3

Carte électronique

Durant cette séance nous avons finalisé le routage de la carte électronique suivant le circuit précédemment définit, et nous avons installé les librairies nécessaire à la programmation des pilotes de leds.

Nous avons également testé les 7-segments qui nous ont été fournit, et nous nous sommes rendus compte qu'ils étaient à cathode commune et donc fonctionnaient différemment de ce qui était indiqué sur la datasheet. Cela pose un problème puisque les pilotes de LED dont nous disposons ne sont pas compatibles avec cette configuration. Nous avons donc du nous tourner vers l'autre solution pour le contrôle des leds, celle avec les transistors. Disposant de 4 afficheurs à 7segments (+ le point), les GPIO de la Raspberry ne sont pas assez nombreux, nous avons donc du utiliser des registre à décalage pour contrôler toutes les sorties.

Nous avons alors passé cette séance à étudier les datasheet des différents composants et à établir un nouveau schéma pour la carte.

Les afficheurs 7-segments de devant ayant à afficher la même chose que ceux de derrière, nous les connecterons entre eux afin réduire de moitié la quantité de composants à utiliser.

programme Raspberry

Durant cette séance, nous avons également pensé au soft qui sera embarqué dans la Raspberry. Nous avions décidé de configurer la Raspberry en accesspoint WiFi et de faire tourner un serveur web qui sera accessible lorsque l'utilisateur se connectera au WiFi de la Raspberry. En parallèle, un autre programme tournera sur la Raspberry et s'occupera du calcul du Timer et du contrôle des leds. Pour que le programme puisse communiquer avec le serveur nous avons plusieurs solutions à étudier : IPC, socket, écriture/lecture dans des fichiers.

Serveur web

Selon la définition Wikipédia, Express est un framework nodejs permettant de mettre en place des applications web. Il s'agit du framework le plus utilisé dans ce but sous l'environnement NodeJS. N'ayant jamais utilisé Express, nous avons dû nous renseigner sur son fonctionnement et nous documenter sur les possibilités du framework. Express est basé sur une architecture typique MVC (Model-View-Controller). Nous pouvons définir des middlewares permettant de capturer les requêtes, de réaliser un traitement préalable, puis de renvoyer la page. Pour cela, il suffit de définir des routes, qui définirons les différentes requêtes HTTP possibles.

Route Méthode Description
/ GET Permet de réaliser un choix entre l'interface enseignant et étudiant
/prof GET Permet de parametrer le timer, en informant le nom du créateur du timer,

la durée de celui-ci en minutes, et l'étudiant en question.

/prof/timer GET Si un timer est configuré, affiche ce dernier, ainsi qu'un formulaire permettant

d'envoyer un commentaire.

/prof/timer POST Permet de traiter soit un nouveau commentaire, soit de lancer le timer
/etudiant GET Permet d'afficher les commentaires et un timer approximatif, qui vire au rouge lorsque

le temps devient critique (<2 minutes)

Les routes étant fixés et définies, nous pouvons passer à la réalisation.

Séance 4

Carte électronique

Lors de cette séance, nous avons pu terminer la carte. Le schematic final est le suivant :


SchematicP4IOT.png


Le PCB est le suivant :

RoutageP4IOT.png


Serveur web

Afin de pouvoir communiquer avec le programme principal manipulant le véritable timer, il est nécessaire d'implémenter une sorte de communication inter-processus. Le choix est porté sur la mise en place d'une liaison sockets UDP, qui sont plus pratique dans notre cas que des sockets basés sur TCP. Ainsi, le module 'dgram' (pour datagram, de UDP datagram socket), permet d'écouter pour un 'datagram' sur un port particulier, ou simplement de broadcaster un message. Le serveur web permettra ainsi d'envoyer la valeur du timer en secondes, tandis que le programme principal en C écoutera sur un port spécifié, et lancera le timer dès la réception de la valeur. Le code permettant l'envoi d'un message par socket UDP est simple à réaliser :

Dgramtimer.png

Nous avons décidés que le timer affiché sur les pages web est simplement à titre indicatif, soit, il ne représente pas réellement le véritable timer, dont la valeur est affiché sur les afficheurs 7 segments. Ce choix à été fait en raison du fait que nodejs et express ne tournent uniquement que sur un thread et ne permettent pas d'écouter sur un port et de rafraichir la page dès une réception. Ainsi, dès le choix de la valeur du timer, nous sauvegardons la timestamp de fin de celui-ci et lançons le timer pour un compte à rebours vers cette valeur.

Les commentaires quant à eux sont enregistrés dans un fichier sous format JSON, et dans le cas d'une requête GET, une lecture de ce fichier est réalisée et les commentaires affichés, tandis que dans le cas d'une requête POST, le fichier est réécris en mémoire avec le nouveau commentaire. L'identifiant d'un professeur commentant est défini sur le formulaire de choix du timer en ne spécifiant que le champ identifiant. La valeur de ce dernier est enregistré dans un cookie de navigateur. Les informations relatives au timer, au nom de l'étudiant et au créateur du timer sont enregistrés dans un autre fichier JSON et récupérés au besoin.

Entreeiot.png CHOIXIOT.png TimerProf.png

Séance 5

Gravure de la carte électronique

Après avoir récupéré la carte gravée, nous nous sommes rendu compte qu'il y avait eu un problème de perçage. En effet, certains trous non présents sur le schéma de routage se trouvaient la carte, d'autres n'étaient pas du tout présent ou alors pas à la bonne place. Pourtant, nous n’apercevions aucun problème lors de la vérification des fichiers gerber avec http://www.gerber-viewer.com/. Nous avons alors passé pas mal de temps à rechercher la cause du problème avec Monsieur Flamen. Finalement, le problème provenait de la génération des fichiers gerber. Après avoir corrigé le problème, la carte a pu être regravée correctement.

Configuration de la raspberry pi

Nous configurons la raspberry afin d'agir en tant que point d'accès afin de pouvoir accéder à l'interface web :

Nous installons tout d'abord les paquets dnsmasq et hostapd, permettant de configurer le point d'accès et fournir le service DNS :

   $ sudo apt-get install dnsmasq hostapd

Nous modifions le fichier de configuration de dhcpcd en ajoutant :

   interface wlan0
       static ip_address=192.168.4.1/24
       nohook wpa_supplicant

Nous relançons ensuite le service dhcpcd.

Nous modifions ensuite le fichier de configuration de dnsmasq, qui va définir la plage d'IPs à attribuer :

   interface=wlan0
     dhcp-range=192.168.4.2,192.168.4.20,255.255.255.0,24h

Enfin, nous écrivons la configuration de notre point d'accès dans un fichier de configuration de hostapd :

   interface=wlan0
   driver=nl80211
   ssid=TimerIOT
   hw_mode=g
   channel=7
   wmm_enabled=0
   macaddr_acl=0
   auth_algs=1
   ignore_broadcast_ssid=0
   wpa=2
   wpa_passphrase=timeriot
   wpa_key_mgmt=WPA-PSK
   wpa_pairwise=TKIP
   rsn_pairwise=CCMP

Enfin, nous lançons les processus hostapd et dnsmasq :

$ sudo systemctl start hostapd
$ sudo systemctl start dnsmasq

Nous rebootons enfin la raspberry. La page web est ainsi accessible en se connectant au point d'accès et en tapant http://192.168.4.1:3000 dans le navigateur.

Programme Raspberry

Pendant cette séance nous avons également finalisé le programme de la Raspberry et installé les librairies permettant d'utiliser le registre à décalage et les GPIO WiringPi.

Dans ce programme, après les initialisations, une socket UDP est créée pour recevoir la valeur initiale du Timer depuis le serveur web. La socket est par la suite fermée et le message reçu converti en entier. Puis deux threads sont lancés : Le premier qui permet le calcul du Timer en se basant sur la valeur initiale et en utilisant l'horloge physique de la Raspberry (fonction : clock_gettime(CLOCK_REALTIME, &<timespec>);), le deuxième thread contrôle les 7-segements après l'avoir parsé en unités et dizaines. Les deux threads communiquent entre eux avec un pipe et un système de verrou pour synchroniser l'envoi et la réception. Finalement les threads et le pipe sont fermés proprement.

Ce programme affiche les valeurs supérieures à 99 secondes en minutes et celle inférieures à 99 secondes en seconde. Le programme et disponible sur le git : https://github.com/ael-mess/raspberry-pi-timer/blob/master/pi.c

Séance 6

Durant cette séance nous avons combiné les deux programmes, et automatisé leur lancement. Nous avons créé un script shell qui lance le serveur web, puis dans une boucle infinie lance le Timer puis supprime les fichiers .json du controller du serveur web à la fin de chaque timer. Ce script a été mis dans /etc/.rclocal de la Raspberry en tache de fond, pour qu'il puissent être lancé à chaque allumage de la Raspberry même avant le loging.

Test

Pendant cette dernière séance nous avons également soudé une partie de nos composants pour faire des tests. Le test de la partie électronique à révélé un comportement anormal du circuit : des segments de leds restent allumés sans qu'aucune tension sur la base des transistors ne soit appliquée. Nous nous sommes assurés de corriger toutes les erreurs de soudure/contact mais nous n'avons pas pu trouver la source du problème. L’hypothèse qui a été émise est que la carte n'aillant pas été nettoyé avant la soudure, le contact n'était pas pareil pour tous les composants, et que donc le potentiel entre deux points reliés n'était pas identique (M.Thierry Flamen).

La partie logiciel elle, marche très bien sans aucun comportement anormal.

Amélioration si plus temps

- prendre plus de temps pour réaliser et tester la partie hardware.

- utiliser la socket pour l'envoie de chaque valeur du timer et non que pour la valeur initial. (parce que le timer calculé par le serveur web utilise la date de la Raspberry et n'est pas précis)

Flyer

Flyer timer iot.jpeg

Documents rendus