samedi 30 août 2014

Point projet, questions, et choix !

Dès le début de la phase de prototypage, le but était de m'assurer que j'allais être capable de contrôler des relais avec un Raspberry Pi.
Cela s'est avéré plutôt simple. La communauté a beaucoup travaillé, les libraires sont nombreuses et les cartes électroniques sont peu onéreuses.

Maintenant il temps de prendre un peu de recul et repenser le projet dans son ensemble : choix du Raspberry Pi pour le tir, montage des relais pour les multiplier, mise au point d'un système de vérification de la continuité des lignes, commande de l'ensemble.

Prenons les points un par un...

Choix du Raspberry Pi

La framboise est-elle un bon choix pour ce montage ?
Après ces quelques tests et jours de réflexion ... je ne crois pas.
Les raisons en sont les suivantes :
  1. C'est un OS complet. Donc il peut planter (même si c'est Linux), il peut y avoir des comportements étranges (les relais qui se connectent au boot) et puis ... 
  2. ... il est trop complet pour ce que je veux faire ! Lan, HDMI, USB, Stockage ... j'ai juste besoin d'une boîte qui commande des PINs !
  3. Il n'a pas d'entrée analogique (voir plus loin sur le test des lignes, cela va poser problème). Certes on peut lui adjoindre une carte pour faire de l'analogique, mais on en revient au point 2, c'est compliqué tout ça !
  4. Le temps de boot est long. Certes je pourrais le réduire avec une autre distribution, mais on voit bien que le projet n'est pas fait pour ça.
Bref, je remets en cause le choix du Raspberry comme moteur de tir, même si je ne l'exclue pas du projet, j'y reviens plus tard.

Multiplication des relais

Ah, les relais. J'ai fait mes tests avec 8 relais, c'est cool. Mais je vais en avoir besoin d'au moins 30 !
Donc de 30 GPIOs. 

C'est faisable, mais au prix d'une carte d'extension de GPIO en port I2C. Soit, mais il y a plus simple : je vais utiliser des multiplexeurs, donc faire des série de 74HC595.
De même, je vais avoir besoin pour mes tests de ligne d'entrées analogiques (peut-être pas autant c'est un point à creuser), donc il faut envisager des dé-multiplexeurs analogiques.

Bref, en tout cas le choix est fait parmi les divers solutions et je vais partir sur des multiplexeurs au moins en sortie.

Vérification de la continuité des lignes

C'est un point que je n'ai pas encore étudié en détail, mais le principe sera le suivant : faire passer un courant très faible dans chacune des sorties pour récupérer un voltage qui me permettra :
  1. de tester si la ligne est continue (et donc si les inflammateurs sont bien branchés)
  2. d'en déduire une résistance qui me permettra d'évaluer la qualité de la ligne. Si je détecte une résistance trop élevée cela peut signifier un inflammateur défaillant ou un branchement de mauvaise qualité (chose qu'on ne peut pas déterminer avec une simple LED qui indique ON/OFF)

Commande du système

Ma décision est prise, je vais transformer mon boitier en esclave et communiquer avec une "télécommande" par ondes radio. Cela me parait pas le plus simple, mais le plus logique par rapport aux conditions de tir qu'on rencontre sur un feu.
Donc le principe sera le suivant :
  • la télécommande aura une batterie à elle, un écran de bonne qualité (probablement tactile) et une interface sans fil pour communiquer avec le boitier de tir
  • le boitier aura quant à lui juste un écran minimaliste pour afficher deux ou trois informations, une interface sans fil, et tous les relais à commander ...

Les choix de conception


Tout cela me donne une vision plus précise de mon montage final, et des choix qui s'y rapportent.
Donc afin d'éviter les problèmes liés au Raspberry Pi cités plus haut, je vais m'orienter vers une conception du boitier de tir sur base d'Arduino (probablement un Uno). Cette machine me semble plus adaptée à une utilisation comme commande de tir.

Voici donc vers quoi je m'oriente pour le système de tir :

Le système de tir en version schématique
Quant à la "télécommande", elle aura les composants suivants :

"télécommande" en version schématique

Et là par contre le Raspberry PI prend tout son sens car j'aurais besoin d'un stockage, de pouvoir facilement charger des fichiers via une clé USB, peut-être un jour de jouer du son pour accompagner mon feu ?

Bref tout cela me semble cohérent et va donc me servir de ligne de vie pour la suite du projet.

jeudi 28 août 2014

Contrôle de la carte 8 Relais avec les GPIO

Les branchements ont été un peu limites, je ne savais pas trop où brancher mes leds, comment alimenter la carte ... bref, il s'en est fallut de quelques tests !

Mais ça marche.

Rapidement, le montage :

Schéma du montage relais (en sachant que les bornes des relais sont mappés par la carte)


Les LEDs sont montées comme auparavant, à l'exception du fait que maintenant elles sont alimentées par l'alimentation de la BreadBoard, et que le tout est branché aux bornes des relais.

Montage de test complet

Petit zoom sur le branchement des relais : j'ai connecté la seconde prise, celle qui est active quand le relais est activé.

Les branchements sur les relais


Et enfin un zoom sur le branchement de la carte relais, c'est tout simple :

Branchement de la carte relais


En bas, la masse (issu du Raspberry), ensuite les 8 GPIOs, et enfin l'alimentation 5V du Raspberry.

J'ensuite lancé le même programme Python que dans le précédent post, et cela fonctionne. Magique !

Note : j'ai effectué différents tests, en éteignant le Raspberry Pi, en l'allumant, en le faisant planter ... et parfois, les relais s'activent ! Ce n'est pas une bonne nouvelle : il faudra systématiquement couper l'accès à la batterie de tir avant que le programme soit chargé et opérationnel ! 

Maintenant j'ai la base de mon projet de table de tir : la capacité à activer des relais sur lesquels seront branchés les artifices à partir d'un Raspberry.
Maintenant la suite : vérifier la continuité des lignes, et surtout multiplier les relais !

mercredi 27 août 2014

Premiers tests de contrôle de leds à partir du Raspberry Pi

Maintenant que tous les composants sont arrivés, je peux commencer à m'amuser avec une BreadBoard, des leds et une carte 8 relais.

Commençons simple : brancher une led sur la BreadBoard avec son alimentation externe.

Parlons un peu de l'alimentation de BreadBorad que j'ai acheté ici :
http://www.amazon.fr/gp/product/B00CO1Y14Y/

JMT Power Supply Module Compatible 3.3V 5V 
Elle est tout à fait pratique ! Elle se fixe sur la Breadboard et si vous en avez une à peu prêt standard elle alimentera vos deux lignes de courant. En plus chaque ligne est commutable en 5V ou 3.3V, et il existe une troisième alimentation en haut. Enfin vous l'alimentez en mini usb ou avec un chargeur ... chez moi mini usb parce que j'en ai des cartons.
Bref pour faire des tests, c'est l'idéal.


J'ai configuré les jumpers de l'alimentation pour sortir du 3.3V. Reste à déterminer la valeur de la résistance...
D'après ce site : http://users.telenet.be/h-consult/elec/led.htm c'est du 65 Ohms qu'il me faut.
Les premières qui me tombent sous la main sont du 150 Ohms, et ça s'allume (pas vif, mais je m'en moque) donc ça ira, des 150 Ohms, cela sera.

Le module est branché, je branche en série : "+" -> LED + (la grande patte) / LED - -> Résistance -> "-"

Test alimentation


Tada ! Ca marche. Cool.

Maintenant plus compliqué, passons à l'allumage d'une led par les GPIO du Raspberry Pi. Je commence par désactiver l'alimentation de Breadboard. Ensuite, il faut savoir à quoi correspondent chaque pin. Pour Raspberry Pi B+, voici le schéma :

GPIO du Raspberry Pi B+
En gros, pour aller vite on va utiliser les ports en vert (les ports "libres", sans rôle particulier du tout) et une masse.

Et pour faire notre test, refaisons un peu de Python ...

import RPi.GPIO as GPIO
import time
# mon GPIO
gpio = 26

# on utilise BCM car il y a un bug sur les GPIO eleves du B+ en mode "board"
GPIO.setmode(GPIO.BCM)

# on configure le GPIO en "Out"
GPIO.setup(gpio, GPIO.OUT)

# on le passe a HIGH, on attend une seconde, on le passe a LOW
GPIO.output(gpio,GPIO.HIGH) 
time.sleep(1)
GPIO.output(pin,GPIO.LOW)

# clean up des GPIOs
GPIO.cleanup()
Côté montage on fait très simple :
Le Pin 37 est relié au "+" de la LED, on met notre résistance en série, et ensuite on branche l'autre patte sur une masse du Raspberry ...
Et hop cela fonctionne.

Bon, cela n'a pas fonctionné tout de suite, j'avoue. Tout cela parce qu'il existe un bug dans le Rpi.GPIO qui empêche les GPIO de valeur "élevés" (les nouveaux du Raspberry B+) de fonctionner en mode "Board". Donc il faut les adresser en mode "BCM", d'où la ligne :

GPIO.setmode(GPIO.BCM)

Une fois que cela a été testé et monté, j'ai branché 8 Leds, et modifié mon programme pour qu'elles s'allument à tour de rôle.

import RPi.GPIO as GPIO
import time

def blink(pin):  
        GPIO.output(pin,GPIO.HIGH)  
        time.sleep(1)  
        GPIO.output(pin,GPIO.LOW)  
        time.sleep(1)  
        return  

# on utilise BCM car il y a un bug sur les GPIO eleves du B+ en mode "board"
GPIO.setmode(GPIO.BCM)    
  
# liste des leds de droite a gauche
allGPIOs = [26,19,13,06,05,21,20,16]

# setup de tous les GPIOs
for i in allGPIOs:
 GPIO.setup(i, GPIO.OUT)

# allumage en serie
for i in allGPIOs:  
        blink(i)  

# clean up des GPIOs  
GPIO.cleanup()   

Schéma :

Premier montage, à partir de maintenant je ne ferai plus les multiples lignes !


Montage :
Test 8 Leds

Tout cela fonctionne bien.
Prochaine étape complexifier le montage pour intégrer ma carte de relais.

vendredi 22 août 2014

Début de la programmation : test d'URWID

Je n'ai toujours pas tout mon matériel et mon Raspberry se sent bien seul.
Mais que cela n'empêche pas de commencer à travailler.

Pour pouvoir faire mes tests, je vais avoir besoin d'un ensemble de fonctions Python. Comme je n'ai pas envie de les lancer à la main, je vais faire un launcher, utilisable en ligne de commande.
J'ai tourné mon attention vers urwid, une librairie Python permettant de créer des interfaces graphiques en mode console.
Je m'en vais donc tester ça.

La chance, c'est que cette librairie existe en package ! Donc aptitude, mon ami, j'ai besoin d'urwid ...
sudo aptitude install python-urwid
... et quelques tests plus tard, la version sur aptitude est trop ancienne pour faire marcher ne serait-ce que les tutoriaux. Bref, je repars et me voici à installer la dernière version. Récupération de l'archive ici, décompression et ensuite :
sudo python setup.py install
Cette fois cela fonctionne correctement et je peux lancer les tutoriaux.

Quelques tutoriaux plus tard ... cela commence à ressemble à quelque chose !
Cette librairie est vraiment sympa.
Voici le résultat :




Le programme commence à s'organiser.
En gros deux classes : une classe menu qui gère que ce que vous voyez, une classe "PiFire" qui s'occupera du tir.
De cette façon si j'ai besoin de changer le menu pour un autre système je n'aurais pas tout à réécrire ...

Un peu de code :

import urwid
import os

class PiFire:
 'Classe de gestion du tir'
 seqFile = '' # Fichier de sequence charge
 seqFolder = '/home/pi/tir_sequences' # Dossier ou chercher les fichiers de sequence
 
 
 def __init__(self):
  self.reboot_relays() # On ferme tous les relais au lancement
 
 # Getter dossiers des fichiers de sequence
 def get_seqFolder(self):
 
 # Setter du fichier de sequence
 def set_seqFile(self,file=''):
  
 # Getter du fichier de sequence
 def get_seqFile(self):
 
 # Methode de parsing du fichier de sequence
 def parse_seqFile(self,file):
  
 # Methodes de base pour controler les relais
 def on_relay(self,relayNum):

 def off_relay(self,relayNum):
 
 # Methode pour passer tous les relais a OFF
 def reboot_relays(self):
  
 # Methode pour charger un fichier de sequence
 def load_seq(self):
  
 # Methode pour lancer le fichier de sequence
 def launch_seq(self):

class Menus:
 'Classe de gestion de la navigation dans les menus'
 
 TitleLvl1 = 'PiFire' # Nom de l'application

 # Initialisation du menu principal et de l'overlay
 def __init__(self,firesys):
 
 # renvoie l'overlay pour la premiere execution
 def initialize(self):
 
 # Creation d'un bouton
 def create_button(self,text,function):
  button = urwid.Button(text)
  urwid.connect_signal(button, 'click', eval('self.'+function), text)
  return urwid.AttrMap(button, None, focus_map='reversed')
   
 # Construit le menu de premier niveau (lance fois au debut et a chaque changement de fichier de sequence)
 def menu(self):
  body = [urwid.Text(Menus.TitleLvl1), urwid.Divider()]
  body.append(urwid.Text(('banner', u"Maintenance"), align='center'))
  body.append(self.create_button('Reset Relais','item_chosen'))
  body.append(self.create_button('Test de ligne','item_chosen'))
  body.append(self.create_button('Choix Fichier Sequence','file_choose'))
  body.append(urwid.Text(self.fireSystem.get_seqFile()))
  body.append(urwid.Divider())
  body.append(urwid.Text(('banner', u"Tir"), align='center'))
  body.append(self.create_button('Lancement de ligne','item_chosen'))
  body.append(self.create_button('Lancement pas a pas','item_chosen'))
  body.append(self.create_button('Lancement Sequence','item_chosen'))
  body.append(urwid.Divider())
  body.append(self.create_button('Sortie','exit_program'))
  self.menuLvl1 = urwid.ListBox(urwid.SimpleFocusListWalker(body))
 
 # Methode pour selectionner un fichier de tir
 def file_choose(self,button,choice):
 
 # Methode utilisee pour positionner le fichier de tir
 def file_set(self,button,choice):
  
 # Methode standard (do nothing) appelee par un choix sur un menu de premier niveau
 def item_chosen(self,button, choice):
 
 # Renvoi au menu de premier niveau
 def re_build_menu(self,button,choice=1):
 
 # Sors du programme
 def exit_program(self,button,choice):

firesystem = PiFire()
menu = Menus(firesystem)
urwid.MainLoop(menu.initialize(), palette=[('reversed', 'standout', '')]).run()

J'ai enlevé toutes les lignes, sauf la création du menu principal et le squelette.
Quelques commentaires sur le squelette. J'ai essayé de bien diviser la partie affichage de la partie "mécanique". Par exemple quand on sélectionne le fichier qui contient les ordres de tir, toute l'intelligence (parsing du fichier, vérification de son format, sauvegarde des variables) se fait dans l'objet PiFire avec des getters / setters. Naturellement le contrôle des relais se fera là bas aussi.

Ensuite pour la partie menu, le bout de code que j'ai laissé illustre bien la facilité de mise en oeuvre : on créé un "cadre" et on ajoute des éléments dedans. La méthode "button" gérant comme une grande la navigation avec les flèches du clavier et la mise en place de listeners.

Il me reste à faire le parsing des fichiers de tir et ensuite il me faudra attendre la réception du matériel électronique, j'ai hâte !

Si vous voulez la source complète voici le lien vers le commit sur Google Code :
https://code.google.com/p/pifire/source/browse/main.py?r=8d425676c597b3d32168a2ef163ce2d0dd24b315

PS : pour les développeurs qui regarderaient ce code, ce n'est forcément très propre, en particulier le "eval" dont j'aurais pu me passer, mais comme ça c'est simple de rajouter un élément au menu !

mercredi 20 août 2014

Installation du Raspberry PI

J'ai donc reçu mon magnfique Raspberry PI B+ avec sa carte mémoire "NOOB".
Pour rappel j'ai acheté ça : Raspberry Pi Model B+ Starter Kit, Black Case by New IT

Je me suis pris une soirée pour l'installer ... et j'ai été un peu déçu. En fait c'est très simple. De bout en bout du déballage à un système opérationnel, il s'est écoulé 2h en comptant les mises à jour système.

Petite note sur le boitier : Il est en plastique rigide, des picots tiennent bien le Raspberry et des fentes permettent d'accéder aux différents connecteurs. C'est pas mal du tout, mais incompatible avec les Shields du Raspberry, ce dont je me doutais. Mais en attendant, il protège le PI de la poussière, c'est bien.

Bref, je comptais faire un poste complet sur la mise en route, cela va se résumer à quelques lignes ...
  1. Brancher le PI sur un clavier USB, reliez le au réseau et à un écran en HDMI
  2. Branchez le, il va booter. Une interface "NOOB" apparaît pour vous demander quel OS installer
  3. J'ai choisi Raspbian parce c'est un système très complet et que vu que je ne sais encore de quoi j'aurais besoin, il m'a paru le plus adapté
  4. Cela s'installe...
  5. On vous pose deux-trois questions sur la langue, le clavier etc. J'ai tout passé en Français, ce sont des menus, pas de risque de se tromper (et au pire vous êtes en QWERTY...) et j'ai demandé à booter sur la ligne de commande et pas sous "X" (l'interface graphique) vu le type de projet que je veux mener
Terminé. Le PI reboot, il est opérationnel, il est configuré en DHCP, un serveur SSH tourne, Python est de la partie. J'ai ensuite débranché la prise, j'ai enlevé le clavier et le HDMI, tout bien calé dans un coin de mon bureau avec juste la prise réseau, rebooté à nouveau. Et j'ai pris le contrôle du PI en SSH.

J'ai enfin lancé une mise à jour système :
sudo aptitude update
sudo aptitude upgrade
sudo reboot
Ça a pris du temps, mais j'avais quitté le PC donc je ne sais pas combien de temps.

Vu que je n'ai pas encore reçu mes autres composants (BreadBoard et autre), je ne peux pas commencer mes bricolages. Triste.

J'ai quand même fait deux petites choses après l'installation :

Je suis passé en IP fixe histoire de ne pas dépendre du service DHCP de ma box.
Voici le fichier /etc/network/interface initial :

auto lo

iface lo inet loopback
iface eth0 inet dhcp

allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp


Voici le nouveau :

auto lo

iface lo inet loopback


auto eth0

iface eth0 inet static
address 192.168.1.43
network 192.168.1.0
netmask 255.255.255.0
gateway 192.168.1.1

Et enfin pour clore ce sujet, j'avais une erreur au boot :

FAT-fs (mmcblk0p5): Volume was not properly unmounted. Some data may be corrupt. Please run fsck.

Petit tour sur les forums et ce post a tout résolu :
http://www.raspberrypi.org/forums/viewtopic.php?p=495156

Juste une histoire de dirty bit sur le volume FAT. On récupère les dosfstools et deux commandes plus loin, c'est réglé.

Remarques sur le temps de boot

Le projet PiFire nécessite de lancer le RaspbarryPi une fois sur le terrain, dans le stress d'avant feu, et globalement quand on a jamais le temps.

Le temps de démarrage est important.
Or, avec un système tout proprement installé, le boot prend environ 35s entre le branchement du PI et la fin du processus.

Boot en 35s, un peu long pour ce que je veux en faire.

Sous Linux il existe un analyseur de boot qui permet de bien savoir ce qui prend du temps au démarrage : bootchart.

Vous trouverez ici un mini-tutoriel qui explique comment faire : Tutoriel Bootchart sur PI

Et ... voici le résultat chez moi :

Bootchart après installation

Bon je ne pense pas qu'on puisse beaucoup améliorer ça. peut-être une meilleure carte SD. Les gars qui s'occupent de la distribution bossent bien !
Il faudra quand même ajouter à la todo list le test de ArchLinux qui est censé booter en 7-8s.

lundi 18 août 2014

Le prototypage, partie coeur

Pour commencer la phase de prototypage du cœur, je vais avoir besoin de mes premiers composants.
Rappel des objectifs :

  1. Avoir un Raspberry Pi qui commande une carte relais avec ses GPIO
  2. Ces relais ont une alimentation séparée en sortie (pour les tests ils vont alimenter des LEDs)
Voila pour une première étape. Dans un second temps nous nous intéresserons à la multiplication des GPIO pour pouvoir gérer assez de relais (minimum 30) en plus du reste ...

Pour réaliser cette première partie de prototypage, voici ma liste de courses réalisée chez Amazon :
  • Un Raspberry Pi B+ avec sa carte SD pour l'installation de l'OS (ici)
  • Un module relais 8 canaux (ici)
  • Une alimentation pour Breadboard (ici)
  • Et puis des câbles, des résistances, des leds et une breadboard un peu grande
Objectif : 
  • 8 Leds sont alimentées par l'alimentation du Bread Board 
  • Le Raspberry Pi contrôle l'allumage de ces Leds par un programme
Voici les tâches à réaliser :

Tâches du cœur du projet
Beaucoup d'informatique, donc, l'électronique restant très simple.
Cette phase est importante à deux titres. Tout d'abord elle va valider le contrôle d'un relais avec le RPI. C'est la base du projet, si je n'y arrive pas c'est fichu. Ensuite elle va poser les bases de ce qui deviendra avec le temps le programme de tir. Les tâches individuelles décrites ci-dessus seront autant de fonctions et d'objets qui par la suite serviront à créer une interface de tir complète.

La suite c'est donc l'installation du Raspberry PI.

samedi 16 août 2014

Présentation du projet

Maintenant que nous avons fait l'introduction, passons à la phase "organisation du projet".

Je vous propose un petit schémas très synthétique de ce que va être le déroulé des opérations.

Schéma fonctionnel du projet PiFire
Ce n'est pas un document électronique, loin de là, mais un schémas logique.
Le projet se divise en briques.

Les carrés sont des éléments "package", je ne sais pas trop ce que j'y mettrai. Les losanges sont des éléments électroniques, deux alimentations séparées sont des cylindres, les borniers sont représentés par un anneau.

Puis les couleurs :

  • Vert : le cœur du projet, sans lesquels le projet est un échec
  • Jaune : les éléments optionnels mais qui apporteraient une plus-value
  • Gris : l'affichage / contrôle distant. Je ne sais pas quoi faire encore pour cette partie, je la laisse en suspens en attendant.
Voici l'explication du cœur :
  • Un contrôleur (pour l'instant un Raspberry Pi) est au centre
  • Il est alimenté par une batterie (que l'on va appeler BPI)
  • Il contrôle via une carte d'extension GPIO plus ou moins 30 relais
  • Ces relais sont reliés à une batterie de tir (BTIR)
  • L'ensemble est relié aux borniers qui eux-même sont reliés aux artifices via des inflammateurs.
Voila pour le cœur. C'est très simple et direct (même si ça va représenter du boulot).

Ensuite les options :
  • Un convertisseur analogique / numérique est relié au contrôleur et aux borniers. Il servira à mesurer la résistance des lignes, ceci afin d'effectuer un test de continuité. Cette fonction est alimentée par la batterie BPI
  • Le contrôleur de batterie, je ne sais pas quelle forme il prendra. Mais il devrait être relié à BPI et BTIR afin de mesurer la charge de ces deux éléments. Rien de plus stressant sur un tir que de s'interroger sur la bonne tenue des batteries !
  • Enfin l'interface vers l'humain. Est-ce que ce sera un écran intégré au boitier ? une prise de contrôle à distance ? aujourd'hui je ne peux pas répondre, j'avance en marchant ...
En tout cas, voici le gros parti pris de conception : deux alimentation séparées et aucun moyen de communication entre les deux. C'est le B.A BA d'une table de tir. En aucun cas un bug logiciel ou un dysfonctionnement d'un composant seul ne devra pouvoir déclencher un tir. Naturellement le système de test de continuité va de facto devoir relier les deux, mais il y aura des coupe-circuit et des résistances pour contrôler l'envoi d'électricité dans les bornes et limiter l'ampérage reçu. Nous y reviendrons quand le moment sera venu.

Comme je ne sais pas trop où je vais, là où je rencontrerai des problèmes, je vais commencer par une phase de prototypage. C'est l'objet du prochain billet.