Raspberry Pi et diode neopixel – Une borne indicative de pollution

Borne indicative de pollution

L’idée initiale est assez simple: Récupérer l’indice de pollution sur Airparif et piloter une led RGB Neopixel afin de lui donner une couleur correspondant à l indice récupéré…

La diode RGB Neopixel:

Cette diode distribuée par Adafruit  contient en fait 3 diodes (une rouge, une verte et une bleue) ainsi qu’un petit composant électronique (ws2811) permettant de commander, en utilisant un seul fil, les niveaux de ces 3 diodes et d’obtenir ainsi n’importe quelle couleur résultant du mélange des 3 couleurs primaires.

RGB

Le brochage de la Diode est le suivant:

Neopixel

La commande de la diode se fait via la broche “Data In”. La broche “Data out” permet de chainer plusieurs diodes

Pilotage de la diode RGB Neopixel avec le Raspberry Pi:

Ce pilotage se fait en utilisant la broche 12 du Raspberry Pi (GPIO 18). D après ce que j ai pu trouver sur le Net, c’est actuellement l’unique GPIO permettant en Python de fonctionner en PWM de façon hardware (utilisation du contrôleur DMA du Raspberry Pi – le BCM2825 si j ai bien compris).

Je m’explique, il est possible de faire varier le niveau de sortie de toutes les broche GPIO de façon “logiciel”, en faisant une boucle dans un programme tournant sur le Raspberry Pi, mais étant donné la vitesse du processeur se trouvant sur le Raspberry Pi,  la fréquence du signal de sortie n’est pas assez élevée pour piloter correctement la diode. Cette diode Neopixel nécessite en effet un signal de fréquence 800 Khz

Compilation et installation de la librairie (rpi_ws281x) permettant le pilotage de la diode Neopixel

Ouvrir un terminal sur le Raspberry Pi et taper les commandes ci-dessous:

sudo apt-get update
sudo apt-get install build-essential python-dev git scons swig

git clone https://github.com/jgarff/rpi_ws281x.git
cd rpi_ws281x
scons

cd python
sudo python setup.py install

L’installation pour Python 2 s’est bien passée, par-contre, l’installation pour python 3 a planté (erreur gcc à investiguer plus tard)

Le code python

import time
from neopixel import *
import urllib2
import re

# pour envoyer les infos de debug sur la sortie standard
# Commenter pour suppression des messages
DEBUG = True

# Configuration: du "ruban" de LED
# Dans le cas présent, je n utilise qu une LED

LED_NB         = 1       # Nombre de LED neopixel.
LED_PIN        = 18      # GPIO pin connectee au pixels et qui supporte le PWM hardware
LED_FREQ_HZ    = 800000  # LED signal frequency in hertz (800khz)
LED_DMA        = 5       # Cannal DMA a utiliser pour generer le signal PWM  
LED_LUMINOSITE = 255     # 0 -> sombre  255 forte luminositee
LED_INVERT     = False   # True pour invertir le signal 

# Definition des couleurs 
rouge   =       [0,0,255]
orange  =       [0,64,200]
jaune   =       [0,128,200]
vert    =       [0,128,0]
bleue_vert =    [255,128,0]
bleu    =       [255,0,0]
violet  =       [255,0,200]
rose    =       []

# Definition d un tableau de clé et valeur (dictionnaire)
# pour contenir les indices de pollution pour differentes periodes (jour, demain, ...)
indice_polution = {}

jour = None


# Donne la couleur "couleur" (tableau a 3 elements, la valeur du bleu, la valeur du vert, la valeur du rouge)
# a la led se trouvant a la position "led_num" dans le ruban de leds 
def led_couleur(led_num,couleur):
    ruban.setPixelColorRGB(led_num,couleur[0],couleur[1],couleur[2])
    ruban.show()


# fait clignoter la led se trouvant a la position "led_num" avec la couleur "couleur"
def led_clignotte(led_num,couleur):
    for i in range(10):
        led_couleur(led_num,couleur)
        time.sleep(0.5)
        led_couleur(led_num,[0,0,0])
        time.sleep(0.5)

# Donne a la led se trouvant a la position "led_num" la couleur correspondant a "niveau_in"
#        vert < 40
#  40 < jaune < 60
#  60 < orange < 80
#  80 < rouge < 100
#  100 < rouge clignotant
def led_niveau(led_num,niveau_in):
    niveau = int(niveau_in)
    if niveau < 40:
        if DEBUG:
            print('vert')
        led_couleur(led_num, vert)
    elif niveau < 60:
        if DEBUG:
            print('jaune')
        led_couleur(led_num, jaune)
    elif niveau < 80:
        if DEBUG:
            print('orange')
        led_couleur(led_num, orange)
    elif niveau < 100:
        if DEBUG:
            print('rouge')
        led_couleur(led_num, rouge)
    else:
        if DEBUG:
            print('clignotant')
        led_clignotte(led_num, rouge)


# Recupere l'indide de polution a Paris sur http://www.airparif.asso.fr
# Met a jour de la variable globale de type dictionnaire "indice_polution"
def get_indice_polution():
    global jour, indice_polution
    
    try: page = urllib2.urlopen("http://www.airparif.asso.fr/indices/resultats-jour-citeair#jour")
    except IOError, e:
        print(e.reason)
        return
    for ligne in page:      
        if "<!-- jour-->" in ligne:
            jour = "aujourdhui"
        if "<!-- demain-->" in ligne:
            jour = "demain"
        if jour and "Indice de l" in ligne:
            result = re.search("(?<=;)[0-9]+",ligne)
            if DEBUG:
                print (result)
            if result:
                indice_polution[jour] = result.group(0)
            jour = None
    if DEBUG:          
        for j in ['aujourdhui', 'demain']:
            if j in indice_polution.keys():
                print("indice de polution " + j + ": " + indice_polution[j])
            else:
                print("Pas d indice trouve pour " + j)
        

# Programme principal 
if __name__ == '__main__':
    try:
        # Creation de l objet NeoPixel
        ruban = Adafruit_NeoPixel(LED_NB, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_LUMINOSITE)
        # Intialisation de la librairie  
        ruban.begin()
        led_num=0
        while True:
            if DEBUG:
                    print(ruban.getPixelColor(0))
                    
            get_indice_polution()
            led_niveau(0,indice_polution['aujourdhui'])
            time.sleep(10)
    finally:
        led_couleur(0,[0,0,0])
        
Pollution RVB

Impression 3D du boitier Raspberry Pi et de la borne

Le proto en photo :

raspberry pi led neopixel

 

Projets de développement:

  • “Dashboard” mutli LED
  • Récupération et monitoring d autres type de donnés sur internet ( Web Services and Co)
    • Risque de pluie ds l’heure
    • Niveaux Allergènes
    • Popularité d un Hashtag twitter

 

Posted in Fabrications, Projet en cours, Projet terminé and tagged , , , , , , , , .

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *