Affichage des articles dont le libellé est informatique. Afficher tous les articles
Affichage des articles dont le libellé est informatique. Afficher tous les articles

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.