Matrice de led et applications

( La suite du projet avec photo disponible plus bas :slight_smile: )

Bonjour !

J’ai récemment entrepris un projet de matrice led assez sympathique et quelques idées me sont venus.

J’ai fait le plus gros du hardware dont voici quelques photos :


Je ne vous cache pas que les soudures des 60 leds étaient assez pénible à la fin :wink:

Grâce à cette librairie : ( https://learn.adafruit.com/neopixels-on-raspberry-pi/software ), je peu contrôler les leds et faire quelques animations sympathiques, j’ai aussi ajouter un peu de code pour afficher la météo ( seulement la température pour l’instant ) grâce à l’API de weather map. Les possibilités sont assez vastes.

Je viens donc vers vous pour un peu d’aide. J’ai trouvé des animations plutôt cool ici : https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/
Cependant c’est pour arduino et donc pas en python, y’a-t-il un moyen simple de les lancer depuis le raspberry ?

Ensuite j’ai quelques idées pour améliorer mon projets :

  • Lancer mon code python qui affiche la météo, puis une animation, puis la température…Etc sans avoir besoin de la lancer manuellement, c’est adire lancer le code dès la mise sous tension du raspberry (Je crois avoir vu des posts à ce sujet sur le forum, ça ne devrai pas être trop compliqué )
  • Piloter grâce à mon téléphone ma matrice de led. Par exemples augmenter la luminosité, ou choisir qu’elles animations se lancent …Etc Là par contre je n’ai aucune idée de comment interagir avec mon code depuis le téléphone. Le plus simple serait en ssh je pense, mais c’est un peu rudimentaire… Je ne suis pas contre quelques pistes

Voilà, si certain d’entre vous on quelques pistes pour les animations et les idées d’amélioration je suis preneur.

Un grand merci à vous et a ce forum qui ma été très utile pour ce projet et d’autre.

Hello,

Très sympa ton « écran », j’adore :+1:

Le plus propre pour contrôler ton pi c’est de faire un petit serveur http (en python regarde du côté de Flask par exemple). Et du côté smartphone je te conseille Automate pour envoyer tes requêtes

Bonjour,

Joli projet et bravo pour avoir eu la patience de souder les 60 leds :sweat_smile:

A titre personnel, j’ai un Rpi 3B+ équipé d’un module Sense Hat qui affiche les infos des capteurs, le tout écrit en Python. Le module comprend une matrice 64 leds est des capteurs de température, humidité, pression atmosphérique, humidité, accéléromètre, gyroscope.
Le code affiche un message de bienvenu au démarrage, les infos des capteurs et une animation « arc en ciel ». Le programme tourne en boucle infinie.
Vous pouvez paramétrer la couleur des leds en fonction de la température.

Une vidéo de démonstration : sensehat - YouTube

Le code à adapter selon votre application :

# On importe les librairies nécessaires.

from sense_hat import SenseHat
from random import randint
import time
import psutil
from time import localtime, strftime

#sense.set_rotation(180) #pour changer l’angle d’affichage
sense = SenseHat()

#On définit des couleurs
green = (89, 166, 89)
red = (255, 0, 0)
blue = (179, 217, 255)
blue1 = (0, 115, 230)
blue2 = (38, 38, 115)
yellow = (255, 255, 0)
white = (255, 255, 255)
none = (0, 0, 0)
orange = (255, 255, 153)
orange1 = (255,69,0)
#On affiche un message de démarrage
sense.show_message(« Bonjour », text_colour=blue, back_colour=none, scroll_speed=0.08)
sense.show_message(« :) », text_colour=blue, back_colour=none, scroll_speed=0.08)
sense.show_message(« Bienvenue sur… », text_colour=blue, back_colour=none, scroll_speed=0.08)
sense.show_message(« Sense Hat ! », text_colour=blue, back_colour=none, scroll_speed=0.08)

#On lance une boucle infinie pour faire notre script
while True :

# On réalise une animation random
for i in range (0,400) :
    x = randint(0, 7)
    y = randint(0, 7)
    r = randint(0, 255)
    g = randint(0, 255)
    b = randint(0, 255)
    sense.set_pixel(x, y, r, g, b)
    time.sleep(0.02)

for i in range (0, 1):
    #On lit les valeurs différents capteurs
    humidity = sense.get_humidity()
    #print("Humidity: %s %%H" % humidity)
    sense_pressure = sense.get_pressure()
    #print("Pressure: %s Millibars" % sense_pressure)
    temp1 = sense.get_temperature_from_humidity()
    #print("Temperature1: %sC" % temp1)
    temp2 = sense.get_temperature_from_pressure()
    #print("Temperature2: %sC" % temp2)
    temp3 = (((temp1 + temp2)/2)-11)
    #print("Temperature3: %sC" % temp3)
    cpu_pc = psutil.cpu_percent()
    #print cpu_pc
    cpu_temp = round(int(open('/sys/class/thermal/thermal_zone0/temp').read()) / 1e3,1)
    #print cpu_temp

    #En fonction de la température lue, on change la couleur d'écriture    
    if temp3 < 10 :
           #print "cas 1"
           color = white
    elif temp3 >= 10 and temp3 < 16 :
           #print "cas 2"
           color = blue
    elif temp3 >= 16 and temp3 < 28 :
           #print "cas 3"
           color = yellow
    elif temp3 >= 28 and temp3 < 30 :
           #print "cas 4"
           color = orange
    elif temp3 >= 30 and temp3 < 35 :
           #print "cas 5"
            color = orange1
    elif temp3 >= 35 :
           #print "cas 5"
           color = red

    #On affiche les valeurs des capteurs sur la matrice        
    sense.show_message("T:%dC" % temp3, text_colour=color, scroll_speed=0.1)
    sense.show_message("P:%dMbars" % sense_pressure, text_colour=color, scroll_speed=0.1)
    sense.show_message("H:%d%%" % humidity, text_colour=color, scroll_speed=0.1)
    sense.show_message("CPU Temp %sC" % cpu_temp, text_colour=color, scroll_speed=0.1)
    #sense.show_message("CPU Load %s" % cpu_pc, text_colour=color, scroll_speed=0.08)
    #sense.show_message("CPU Temp %sC" % cpu_temp, text_colour=color, scroll_speed=0.08)
    #sense.show_message("Free Ram %s" % mem_avail_mb, text_colour=color, scroll_speed=0.08)
    time.sleep(1)

#On réalise une animation arc-en-ciel pour finir 
pixels = [
    [255, 0, 0], [255, 0, 0], [255, 87, 0], [255, 196, 0], [205, 255, 0], [95, 255, 0], [0, 255, 13], [0, 255, 122],
    [255, 0, 0], [255, 96, 0], [255, 205, 0], [196, 255, 0], [87, 255, 0], [0, 255, 22], [0, 255, 131], [0, 255, 240],
    [255, 105, 0], [255, 214, 0], [187, 255, 0], [78, 255, 0], [0, 255, 30], [0, 255, 140], [0, 255, 248], [0, 152, 255],
    [255, 223, 0], [178, 255, 0], [70, 255, 0], [0, 255, 40], [0, 255, 148], [0, 253, 255], [0, 144, 255], [0, 34, 255],
    [170, 255, 0], [61, 255, 0], [0, 255, 48], [0, 255, 157], [0, 243, 255], [0, 134, 255], [0, 26, 255], [83, 0, 255],
    [52, 255, 0], [0, 255, 57], [0, 255, 166], [0, 235, 255], [0, 126, 255], [0, 17, 255], [92, 0, 255], [201, 0, 255],
    [0, 255, 66], [0, 255, 174], [0, 226, 255], [0, 117, 255], [0, 8, 255], [100, 0, 255], [210, 0, 255], [255, 0, 192],
    [0, 255, 183], [0, 217, 255], [0, 109, 255], [0, 0, 255], [110, 0, 255], [218, 0, 255], [255, 0, 183], [255, 0, 74]
    ]
msleep = lambda x: time.sleep(x / 1000.0)


def next_colour(pix): 
    r = pix[0]
    g = pix[1]
    b = pix[2]

    if (r == 255 and g < 255 and b == 0):
        g += 1

    if (g == 255 and r > 0 and b == 0):
        r -= 1

    if (g == 255 and b < 255 and r == 0):
        b += 1

    if (b == 255 and g > 0 and r == 0):
        g -= 1

    if (b == 255 and r < 255 and g == 0):
        r += 1

    if (r == 255 and b > 0 and g == 0):
        b -= 1

    pix[0] = r
    pix[1] = g
    pix[2] = b

for i in range (0,2500):    
    for pix in pixels:
        next_colour(pix)

    sense.set_pixels(pixels)
    msleep(1)

Merci pour vos retours !
Je vais regarder ton code il y a des idées sympathiques merci !

Concernant flask Gpapig, j’ai créé un serveur je peu avoir accès a ma page html, changer son apparence …etc, mais est-il possible de faire un page avec un bouton pour lancer mon code python qui est dans ‹ /home/pi ›, un autre bouton qui lance une autre animation …etc ?

Par contre je ne comprend pas bien ton idée d’envoyer mes requêtes avec automate. Une requête c’est un accès à un url, par exemple IpDuRaspberry/index/page1 ?
Peux-tu m’éclairer ?

Merci encore pour vos retours ! :slight_smile:

Hello, chaque route peut te servir pour lancer tes programmes oui (ou tu peux aussi mettre des boutons sur ta page et lier les actions). Regarde du côté des mots clefs POST et FORM. En gros a rajouter un formulaire dans ta page puis dans flask regarder si c’est une requête POST, si oui faire ceci ou cela selon tes désirs

Du côté des requêtes l’avantage avec Automate c’est que tu peux formater tes requêtes comme tu veux (y inclure un header avec username password par exemple) mais l’accès par URL fonctionne bien aussi si tu veux y garder simple

Je regrade ce soir ou demain pour te mettre un exemple

Ah oui d’accord je vois, prend ton temps c’est pas pressé.
Je viens de me rendre compte qu’avec Flask ( je crois que ça vient de ça ) le css est « figé ». J’ai un fichier index.html, qui a un fichier style.css de lié. le css a juste un body { background et color }. Tout ça fonctionne très bien, mais si je modifie le css rien de change. J’ai du créer un nouveau fichier styles.css ( avec un « s » cette fois) et la j’ai pu le modifier. si je modifie ce styles.css ( avec un s) les modification ne sont pas prises en compte :joy: . très étrange ahah.
J’ai supprimé les deux fichier css, et meme s’il nexiste plus je peu toujours lier le html à tel ou tel fichier css et ça marche toujours, très perturbant ahah !

Enfin bon c’était juste une remarque étrange, ou bien une fausse manip de ma part peut etre…

Bonne soirée

L’actualisation est bizarre sous flask, il faut tuer le processus puis le relancer (doit y avoir moyen de faire autrement mais jamais cherché comment). Par contre le CSS est parfaitement pris en compte.

Voila un tout petit exemple (je n’ai pas fait d’HTML ici), sinon il faut utilser des templates et la fonction render_templates

# -*- coding: utf-8 -*-

from flask import Flask, request

def mafonction()
    print "coucou"

app = Flask(__name__)

@app.route('/ceque/jeveux')  #, methods=['GET'])
def balbla():
        mafonction()
        return "function exécutée"

if __name__ == '__main__':
    app.run(host ="0.0.0.0")

Bonsoir,

J’ai donc bien réussi grâce a ton aide à lancer mon programme python pour allumer mes led, je peu donc grâce a des boutons choisir d’allumer une lumiere, d’afficher la météo …Etc

Cependant je n’arrive pas à couper le programme, je m’explique :

        @app.route('/ceque/jeveux')  
        def balbla()
                while True:
                       try :
                              pluie(strip)
                              fct2(strip)
                       except KeyboardInterrupt:
                              remetLEDa0(strip)
                              break

                return "function exécutée"

les fonction se lance et ma page html reste à charger et je ne peu pas interrompre pour éteindre les led. En ssh dans la console il me suffisait de faire un « ctrl -c » pour éteindre les led et interrompre la fonction, ici je ne vois pas comment faire. Des idées ?

Il te faut dissocier la fonction de la route.

La des que tu charge ta page tu rentres dans une boucle infinie.

Je regarde demain si j’ai un peu de temps

Après plusieurs tentative je n’y arrive pas… Si tu as le temps de voir ça je suis preneur, sinon je changerai peut être complétement d’approche :slight_smile:

Hello, désolé j’ai été occupé, je regarde ça demain je pense

C’est moche mais ça fonctionne.

En gros j’ai fais une variable en dehors de la fonction (son nom est « continue »)
Je l’initialise a True

Puis dans la route appelant ta matrice, je boucle tant que continue est True.
Dans l’autre route (« arrete »), je change la valeur de la bariable global continue à False, du coup la 1ère fonction s’arrête quand tu accèdes à tonip/arrete

Désolé d’avoir mis autant de temps à faire ces quelques lignes

global continue
continue = True  

 @app.route('/ceque/jeveux')  
        def balbla()
                while continue :
                              pluie(strip)
                              fct2(strip)

                remetLEDa0(strip)
                return "function exécutée"

 @app.route('/arrete')  
        def arrete()
             global continue
             continue = False
             return "function stoppée"

Merci d’avoir pris le temps d’écrire ce code. Cependant ça ne fonctionne pas chez moi…
Le problème étant, quand mes animations tournent après avoir accéder à ‹ monIp/ceque/jeveux ›, je ne peu plus envoyer de requête jusqu’à ce que la boucle soit finit. Si je tape 'MonIp/arrete, il ne se passe rien juste une barre de chargement dans le vide. Je crois que Flask n’écoute plus ce que ce passe tant qu’il est occupé à faire autre chose.
Peut être est-ce impossible d’arrêter l’animation de cette façon ?

Merci en tout cas

Je t’en prie, tu as bien copié le code correctement ?

Oui à part l’indentation de def blabla() et def arrete() qui doivent être au meme niveau que @app.route et « continue » modifié en « continu » car « continue » avec un « e » est une méthode python donc erreur

Le soucis d’indentation vient du forum

Pour continue c’est une variable, l’important c’est que se soit le même nom partout vérifie bien ça. Au pire change y en mavariable

Oui j’ai mis un nom de variable lambda, mais du coup ça ne marche pas, impossible d’envoyer une requête pendant qu’un programme est lancé.

Quand je lance mon serveur je fais : sudo python app.py
Cela changerai-t-il quelque chose de faire : sudo python3 app.py

Toi tu es sous python2 ou 3 ?

Montre moi ce qu’il y a dans tes fonctions pluie et fct2