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

[pastacode lang= »python » message= »Pollution RVB » highlight= » » provider= »manual » manual= »import%20time%0Afrom%20neopixel%20import%20*%0Aimport%20urllib2%0Aimport%20re%0A%0A%23%20pour%20envoyer%20les%20infos%20de%20debug%20sur%20la%20sortie%20standard%0A%23%20Commenter%20pour%20suppression%20des%20messages%0ADEBUG%20%3D%20True%0A%0A%23%20Configuration%3A%20du%20%22ruban%22%20de%20LED%0A%23%20Dans%20le%20cas%20pr%C3%A9sent%2C%20je%20n%20utilise%20qu%20une%20LED%0A%0ALED_NB%20%20%20%20%20%20%20%20%20%3D%201%20%20%20%20%20%20%20%23%20Nombre%20de%20LED%20neopixel.%0ALED_PIN%20%20%20%20%20%20%20%20%3D%2018%20%20%20%20%20%20%23%20GPIO%20pin%20connectee%20au%20pixels%20et%20qui%20supporte%20le%20PWM%20hardware%0ALED_FREQ_HZ%20%20%20%20%3D%20800000%20%20%23%20LED%20signal%20frequency%20in%20hertz%20(800khz)%0ALED_DMA%20%20%20%20%20%20%20%20%3D%205%20%20%20%20%20%20%20%23%20Cannal%20DMA%20a%20utiliser%20pour%20generer%20le%20signal%20PWM%20%20%0ALED_LUMINOSITE%20%3D%20255%20%20%20%20%20%23%200%20-%3E%20sombre%20%20255%20forte%20luminositee%0ALED_INVERT%20%20%20%20%20%3D%20False%20%20%20%23%20True%20pour%20invertir%20le%20signal%20%0A%0A%23%20Definition%20des%20couleurs%20%0Arouge%20%20%20%3D%20%20%20%20%20%20%20%5B0%2C0%2C255%5D%0Aorange%20%20%3D%20%20%20%20%20%20%20%5B0%2C64%2C200%5D%0Ajaune%20%20%20%3D%20%20%20%20%20%20%20%5B0%2C128%2C200%5D%0Avert%20%20%20%20%3D%20%20%20%20%20%20%20%5B0%2C128%2C0%5D%0Ableue_vert%20%3D%20%20%20%20%5B255%2C128%2C0%5D%0Ableu%20%20%20%20%3D%20%20%20%20%20%20%20%5B255%2C0%2C0%5D%0Aviolet%20%20%3D%20%20%20%20%20%20%20%5B255%2C0%2C200%5D%0Arose%20%20%20%20%3D%20%20%20%20%20%20%20%5B%5D%0A%0A%23%20Definition%20d%20un%20tableau%20de%20cl%C3%A9%20et%20valeur%20(dictionnaire)%0A%23%20pour%20contenir%20les%20indices%20de%20pollution%20pour%20differentes%20periodes%20(jour%2C%20demain%2C%20…)%0Aindice_polution%20%3D%20%7B%7D%0A%0Ajour%20%3D%20None%0A%0A%0A%23%20Donne%20la%20couleur%20%22couleur%22%20(tableau%20a%203%20elements%2C%20la%20valeur%20du%20bleu%2C%20la%20valeur%20du%20vert%2C%20la%20valeur%20du%20rouge)%0A%23%20a%20la%20led%20se%20trouvant%20a%20la%20position%20%22led_num%22%20dans%20le%20ruban%20de%20leds%20%0Adef%20led_couleur(led_num%2Ccouleur)%3A%0A%20%20%20%20ruban.setPixelColorRGB(led_num%2Ccouleur%5B0%5D%2Ccouleur%5B1%5D%2Ccouleur%5B2%5D)%0A%20%20%20%20ruban.show()%0A%0A%0A%23%20fait%20clignoter%20la%20led%20se%20trouvant%20a%20la%20position%20%22led_num%22%20avec%20la%20couleur%20%22couleur%22%0Adef%20led_clignotte(led_num%2Ccouleur)%3A%0A%20%20%20%20for%20i%20in%20range(10)%3A%0A%20%20%20%20%20%20%20%20led_couleur(led_num%2Ccouleur)%0A%20%20%20%20%20%20%20%20time.sleep(0.5)%0A%20%20%20%20%20%20%20%20led_couleur(led_num%2C%5B0%2C0%2C0%5D)%0A%20%20%20%20%20%20%20%20time.sleep(0.5)%0A%0A%23%20Donne%20a%20la%20led%20se%20trouvant%20a%20la%20position%20%22led_num%22%20la%20couleur%20correspondant%20a%20%22niveau_in%22%0A%23%20%20%20%20%20%20%20%20vert%20%3C%2040%0A%23%20%2040%20%3C%20jaune%20%3C%2060%0A%23%20%2060%20%3C%20orange%20%3C%2080%0A%23%20%2080%20%3C%20rouge%20%3C%20100%0A%23%20%20100%20%3C%20rouge%20clignotant%0Adef%20led_niveau(led_num%2Cniveau_in)%3A%0A%20%20%20%20niveau%20%3D%20int(niveau_in)%0A%20%20%20%20if%20niveau%20%3C%2040%3A%0A%20%20%20%20%20%20%20%20if%20DEBUG%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(‘vert’)%0A%20%20%20%20%20%20%20%20led_couleur(led_num%2C%20vert)%0A%20%20%20%20elif%20niveau%20%3C%2060%3A%0A%20%20%20%20%20%20%20%20if%20DEBUG%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(‘jaune’)%0A%20%20%20%20%20%20%20%20led_couleur(led_num%2C%20jaune)%0A%20%20%20%20elif%20niveau%20%3C%2080%3A%0A%20%20%20%20%20%20%20%20if%20DEBUG%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(‘orange’)%0A%20%20%20%20%20%20%20%20led_couleur(led_num%2C%20orange)%0A%20%20%20%20elif%20niveau%20%3C%20100%3A%0A%20%20%20%20%20%20%20%20if%20DEBUG%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(‘rouge’)%0A%20%20%20%20%20%20%20%20led_couleur(led_num%2C%20rouge)%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20if%20DEBUG%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20print(‘clignotant’)%0A%20%20%20%20%20%20%20%20led_clignotte(led_num%2C%20rouge)%0A%0A%0A%23%20Recupere%20l’indide%20de%20polution%20a%20Paris%20sur%20http%3A%2F%2Fwww.airparif.asso.fr%0A%23%20Met%20a%20jour%20de%20la%20variable%20globale%20de%20type%20dictionnaire%20%22indice_polution%22%0Adef%20get_indice_polution()%3A%0A%20%20%20%20global%20jour%2C%20indice_polution%0A%20%20%20%20%0A%20%20%20%20try%3A%20page%20%3D%20urllib2.urlopen(%22http%3A%2F%2Fwww.airparif.asso.fr%2Findices%2Fresultats-jour-citeair%23jour%22)%0A%20%20%20%20except%20IOError%2C%20e%3A%0A%20%20%20%20%20%20%20%20print(e.reason)%0A%20%20%20%20%20%20%20%20return%0A%20%20%20%20for%20ligne%20in%20page%3A%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20if%20%22%3C!–%20jour–%3E%22%20in%20ligne%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20jour%20%3D%20%22aujourdhui%22%0A%20%20%20%20%20%20%20%20if%20%22%3C!–%20demain–%3E%22%20in%20ligne%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20jour%20%3D%20%22demain%22%0A%20%20%20%20%20%20%20%20if%20jour%20and%20%22Indice%20de%20l%22%20in%20ligne%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20result%20%3D%20re.search(%22(%3F%3C%3D%3B)%5B0-9%5D%2B%22%2Cligne)%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20DEBUG%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print%20(result)%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20result%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20indice_polution%5Bjour%5D%20%3D%20result.group(0)%0A%20%20%20%20%20%20%20%20%20%20%20%20jour%20%3D%20None%0A%20%20%20%20if%20DEBUG%3A%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20for%20j%20in%20%5B’aujourdhui’%2C%20’demain’%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20j%20in%20indice_polution.keys()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(%22indice%20de%20polution%20%22%20%2B%20j%20%2B%20%22%3A%20%22%20%2B%20indice_polution%5Bj%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(%22Pas%20d%20indice%20trouve%20pour%20%22%20%2B%20j)%0A%20%20%20%20%20%20%20%20%0A%0A%23%20Programme%20principal%20%0Aif%20__name__%20%3D%3D%20’__main__’%3A%0A%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%23%20Creation%20de%20l%20objet%20NeoPixel%0A%20%20%20%20%20%20%20%20ruban%20%3D%20Adafruit_NeoPixel(LED_NB%2C%20LED_PIN%2C%20LED_FREQ_HZ%2C%20LED_DMA%2C%20LED_INVERT%2C%20LED_LUMINOSITE)%0A%20%20%20%20%20%20%20%20%23%20Intialisation%20de%20la%20librairie%20%20%0A%20%20%20%20%20%20%20%20ruban.begin()%0A%20%20%20%20%20%20%20%20led_num%3D0%0A%20%20%20%20%20%20%20%20while%20True%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20if%20DEBUG%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20print(ruban.getPixelColor(0))%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20get_indice_polution()%0A%20%20%20%20%20%20%20%20%20%20%20%20led_niveau(0%2Cindice_polution%5B’aujourdhui’%5D)%0A%20%20%20%20%20%20%20%20%20%20%20%20time.sleep(10)%0A%20%20%20%20finally%3A%0A%20%20%20%20%20%20%20%20led_couleur(0%2C%5B0%2C0%2C0%5D)%0A%20%20%20%20%20%20%20%20%0A »/]

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 , , , , , , , , .

One Comment

  1. super : je cherchais quelque chose de clair pour faire fonctionner ma bande de led et j’ai tout compris avec votre tuto.
    Il me semble en plus qu’il faille arrêter la sortie son qui utilise PWM pour ne pas avoir d’interférences et d’arrêt de l’application.
    .
    .

Laisser un commentaire

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