Ich hab mal wieder eine Anfrage von einem Zuschauer meines Youtube-Kanals bekommen:

Hallo,
Ich habe dir schon einmal bei YouTube geschrieben und nach der Möglichkeit gefragt mit einem Taster die Funktionen wechseln kann.
Ich habe nach deiner Anleitung versucht da was zubauen. Da ich aber ein totaler Neuling in Python bin habe ich es natürlich nicht geschafft.
Dann habe ich mich an das Kaminfeuer gewagt, mit copy und Paste bin ich da nicht sehr weit gekommen.würde ich gerne ein Programm haben mit der Rainbow Funktion und der Kaminfeuer, die in einer Schleife laufen und ich diese mit einem tasten Druck wechseln kann.
Würdest du mir da weiter helfen?

Marvin (http://tritrip.de/2020/12/28/geniale-wake-up-lampe/#comments)

Danke für das Feedback und die Frage!

Natürlich kann ich nicht jede Frage beantworten und jede Programmieridee umsetzen. Da ich jedoch für meine eigene Lampe bereits verschiedene Szenen habe, ist die Erweiterung um den Taster in diesem Fall aber schnell umgesetzt.

Die Lampe ist Teil eines meiner Raspberry Pi Projekte. Basis ist eine Ikea Vidja LED Lampe, mit der, durch einen Umbau mit einem LED Strip und einer Ansteuerung über einen Raspberry Pi, nun verschiedene Beleuchtungs-Szenen realisiert werden können:

Dazu gibt es bereits Zwei Videos auf meinem Youtube Kanal:

und weitere werden noch folgen. So kann die Lampe heute schon über ein Webinterface bedient werden, welches über einen auf dem Raspberry Pi laufenden Apache Webserver und Flask realisiert ist. Später soll noch eine Einbindung in das Smarthome folgen.

Das Ganze ist modular aufgebaut und diesem einzelnen Module laufen in unabhängigen Threads. Aus diesem Grund kann das Modul zur Ansteuerung des LED Strips hier unverändert übernommen werden.

Hier der vollständige Source Code für die LED-Strip Ansteuerung mit Szenen wie „Wake Up Lampe„, „Regenbogen“ und „Kaminfeuer“: MyStrip.py:

#!/usr/bin/env python3

# Inspired by rpi_ws281x library strandtest example
# Author: Tony DiCola (tony@tonydicola.com)

import threading
import time
import random
from rpi_ws281x import *

# LED strip configuration:
LED_COUNT      = 20     # Number of LED pixels.
LED_PIN        = 18      # GPIO pin connected to the pixels (18 uses PWM!).
#LED_PIN        = 10      # GPIO pin connected to the pixels (10 uses SPI /dev/spidev0.0).
LED_FREQ_HZ    = 800000  # LED signal frequency in hertz (usually 800khz)
LED_DMA        = 10      # DMA channel to use for generating signal (try 10)
LED_BRIGHTNESS = 40      # Set to 0 for darkest and 255 for brightest
LED_INVERT     = False   # True to invert the signal (when using NPN transistor level shift)
LED_CHANNEL    = 0       # set to '1' for GPIOs 13, 19, 41, 45 or 53

class MyStrip(threading.Thread):

# Define functions which animate LEDs in various ways.
       
    def rnd(self,min,max):
        return int(random.random()*(max-min) + min)

    def wheel(self, pos):
        # Generate rainbow colors across 0-255 positions
        if pos < 85:
            return Color(pos * 3, 255 - pos * 3, 0)
        elif pos < 170:
            pos -= 85
            return Color(255 - pos * 3, 0, pos * 3)
        else:
            pos -= 170
            return Color(0, pos * 3, 255 - pos * 3)

    def rainbow(self, InitRainbow = False):

        # Draw rainbow that fades across all pixels at once
        for j in range(256):
            for i in range(self.strip.numPixels()):
                self.strip.setPixelColor(i, self.wheel((i+j) & 255))
                # Bei Init langsam hochlaufen
                if InitRainbow:
                    self.strip.show()
                    time.sleep(0.01)

            InitRainbow=False
            self.strip.show()
            time.sleep(0.02)
            if (not self.RunStrip) or self.Clear: #ermoegliche Abbruch in jeder Loop
                break
                    
    def __init__(self, szene, rot, gruen, blau):
        threading.Thread.__init__(self)
        self.RunStrip = True
        self.Szene = szene
        self.SzeneNeu = szene
        self.WakeupLed = -1
        self.Clear = False
        self.Update = True
        self.UpdateFarbe = True
        self.Rot = rot
        self.RotNeu = rot
        self.Gruen = gruen
        self.GruenNeu = gruen
        self.Blau = blau
        self.BlauNeu = blau 
        
    def run(self):
        # Create NeoPixel object with appropriate configuration.
        self.strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)
        # Intialize the library (must be called once before other functions).
        self.strip.begin()
    
        while self.RunStrip:
            
            # Lichtwecker
            if (self.Szene == "LichtWecker") and (self.WakeupLed<LED_COUNT):
                self.WakeupLed=self.WakeupLed+1
                for x in range (0,50,5):
                    # Die letzte LED ist außerhalb des Ranges, deshalb kann das ewig so weiter gehen ;-)
                    self.strip.setPixelColor(self.WakeupLed, Color(5*x,3*x,0)) # Farbe RGB #F59300
                    self.strip.show()
                    time.sleep(2)
                    if (not self.RunStrip) or self.Clear: #ermoegliche Abbruch nach 2 Sekunden
                        break

            # Licht
            if (self.Szene == "Licht") and self.Update:
                self.Update = False
                for x in range (0,LED_COUNT):
                    self.strip.setPixelColor(x, Color(225,135,0)) # Farbe RGB #F59300
                    self.strip.show()
                    time.sleep(0.01)
                    
            # Farbe
            if (self.Szene == "Farbe") and (self.Update):
                self.Update = False
                for x in range (0,LED_COUNT):
                    self.strip.setPixelColor(x, Color(self.Rot,self.Gruen,self.Blau))
                    self.strip.show()
                    time.sleep(0.01)

            # Regenbugen
            if (self.Szene == "Regenbogen"):
                if self.Update:
                    self.rainbow(True)
                    self.Update = False
                else:
                    self.rainbow()

            # Kaminfeuer
            if (self.Szene == "Kaminfeuer") and (self.Update):
                self.Update = False                
                for i in range(0,20,1):
                    self.strip.setPixelColor(i, Color(255,120,0))
                    self.strip.show()
                    time.sleep(0.01)
                for i in range(20,40,1):
                    self.strip.setPixelColor(i, Color(250,50,0))
                    self.strip.show()
                    time.sleep(0.01)
                for i in range(40,60,1):
                    self.strip.setPixelColor(i, Color(150,0,0))
                    self.strip.show()
                    time.sleep(0.01)
                for i in range(60,80,1):
                    self.strip.setPixelColor(i, Color(100,0,0))
                    self.strip.show()
                    time.sleep(0.01)
            if (self.Szene == "Kaminfeuer"):
                # Random 255,120,0
                self.strip.setPixelColor(self.rnd(10,20), Color(250,50,0))
                self.strip.setPixelColor(self.rnd(10,20), Color(250,120,0))
                # Random 250,50,0
                self.strip.setPixelColor(self.rnd(20,40), Color(250,120,0))
                self.strip.setPixelColor(self.rnd(20,40), Color(250,150,0))
                self.strip.setPixelColor(self.rnd(30,40), Color(150,0,0))
                self.strip.setPixelColor(self.rnd(20,50), Color(150,0,0))
                # Random 150,0,0
                self.strip.setPixelColor(self.rnd(40,60), Color(150,50,0))
                self.strip.setPixelColor(self.rnd(40,60), Color(150,0,0))
                self.strip.setPixelColor(self.rnd(40,60), Color(150,0,0))
                # Random 100,0,0
                self.strip.setPixelColor(self.rnd(60,80), Color(50,0,0))
                self.strip.setPixelColor(self.rnd(60,80), Color(100,0,0))
                self.strip.setPixelColor(self.rnd(60,80), Color(150,0,0))
                # Random 0,0,0
                self.strip.setPixelColor(self.rnd(80,100), Color(0,0,0))
                self.strip.setPixelColor(self.rnd(80,100), Color(0,0,0))
                self.strip.setPixelColor(self.rnd(80,100), Color(50,0,0))
                time.sleep(0.05)
                self.strip.show()

            # Clear Strip
            if self.Clear:
                for x in range (LED_COUNT,-1,-1):
                    self.strip.setPixelColor(x, Color(0,0,0))
                    self.strip.show()
                    time.sleep(0.01)
                self.WakeupLed = -1
                self.Szene = self.SzeneNeu
                self.Clear = False
                self.Update = True
                
            if (self.Szene == "Farbe") and (self.UpdateFarbe):
                self.Rot = self.RotNeu
                self.Gruen = self.GruenNeu
                self.Blau = self.BlauNeu
                self.UpdateFarbe = False
                self.Update = True
        
    def close(self):
        self.RunStrip = False
        
    def setSzene(self, szene):
        if self.SzeneNeu != szene:
            self.SzeneNeu = szene
            self.Clear = True
            print("Neue Szene: "+szene)
            
    def setFarbe(self, rot, gruen, blau):
        update = False
        if self.RotNeu != rot:
            self.RotNeu = rot
            update = True
            print("Neuer Rot-Wert")
        if self.GruenNeu != gruen:
            self.GruenNeu = gruen
            update = True
            print("Neuer Gruen-Wert")
        if self.BlauNeu != blau:
            self.BlauNeu = blau
            update = True
            print("Neuer Blau-Wert")
        self.UpdateFarbe = update
        
if __name__ == '__main__':
    Strip = MyStrip()
    Strip.start()
    print("LED Strip gestartet")
    print("Press Ctrl-C to quit.")
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        pass    
    Strip.close()
    print("Stop der Klasse angefordert")
    Strip.join()
    print("Klasse gestoppt")
    print("TODO: LEDs löschen?")

LED Strip und Taster müssen dann, wie im folgenden Bild gezeichnet, angeschlossen werden. Beim Taster müssen zwei Beine an der selben Seite des Tasters verwendet werden. Die gegenüberliegenden Beine sind durchkontaktiert. (Auf dem Bild sieht das leide genau falsch aus, aber besser lies sich der Taster in Fritzing auf die Schnelle leider nicht platzieren)

Schaltung LED Strip + Taster

Das zusätzliche Netzteil ist natürlich optional, aber sinnvoll, wenn die Stromaufnahme des LED-Strips mehr als 1A beträgt. Mehr dazu in meinem Video zu LED-Strip Ansteuerung: Einsteiger Tutorial – LED Strip Ansteuerung mit dem Raspberry Pi.

Und hier der Sourcecode für die Umschaltung zwischen verschiedenen Szenen mittels eines Tasters.

Zwischen welchen Szenen Du umschaltest und in welcher Reihenfolge kannst Du in dem Feld „Szenen“ definieren. Für jede Szene „Farbe“ wir ein Eintrag in dem Feld „Farben“ benötigt, der die Farbe definiert ( RGB = [rot,grün,blau] )

Taster.py (verwendet MyStrip.py):

import MyStrip
import RPi.GPIO as GPIO
from time import sleep

Szenen = ["Licht","Farbe","Farbe","Farbe","Regenbogen","Kaminfeuer", "LichtWecker"]
Farben = [[255,0,0], # rot
         [0,255,0], # gruen
         [0,0,255]] # blau
GPIO_Port_Taster = 15


if __name__ == '__main__':
    
    print ('Press Ctrl-C to quit.')

    try:
        # Starte mit der ersten Szene / ersten Farbe
        Szene = 0
        Farbe = 0

        # Port fuer Taster initialisieren
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(GPIO_Port_Taster,GPIO.IN,pull_up_down=GPIO.PUD_UP)

        # LED Strip initialisieren
        Strip = MyStrip.MyStrip("LichtWecker", 255, 0 ,0)
        Strip.start()
        print("Strip gestartet")
            
        while True:
            # warte auf stabilen High Pegel (Pull up)
            while (GPIO.input(15)==False):
                sleep(0.1)

            # warte bis Taster gedrückt wird
            while (GPIO.input(15)==True):
                sleep(0.1)

            # naechste Szene
            Strip.setSzene(Szenen[Szene])
            if Szenen[Szene] == "Farbe":
                # ggf naechste Farbe
                Strip.setFarbe(Farben[Farbe][0],Farben[Farbe][1],Farben[Farbe][2])
                Farbe = Farbe + 1
                if Farbe >= len(Farben):
                    Farbe = 0
            Szene = Szene + 1
            if Szene >= len(Szenen):
                Szene = 0

    except KeyboardInterrupt:
        Strip.close()
        Strip.join()
        print("LED Strip gestoppt")

Amazon Links

*Werbung! Wenn Du auf einen der Amazon Links klickst und anschließend ein beliebiges Produkt auf Amazon kaufst, unterstützt Du meine Seite mit einem kleinen Anteil. Dir entstehen dadurch KEINE Mehrkosten und Du zahlst den ganz normalen Preis. Danke!

LED Strip
WS2812B LED Strip – https://amzn.to/2Y1tF0e

Raspberry Pi 3
Raspberry Pi 3 Model B – https://amzn.to/3o5kWou
Netzteil 3A mit Schalter – https://amzn.to/3pcK6D2

Alternativ: Raspberry Pi 3 Starter Kit
Raspberry Pi 3 Model B Starter Kit inkl. SD-Karte vorinstalliert mit Raspbian OS – https://amzn.to/2M9Zt0b

Raspberry Pi Zubehör
Raspberry Pi Gehäuse – https://amzn.to/399Te5P
Netzteil 3A – https://amzn.to/3iH6u4Y
Netzteil 8A – https://amzn.to/3p7ZU9R
Schraubklemmen Adapter (5 Stück) – https://amzn.to/2KH0nkA
Steckbrett (3 Stück) – https://amzn.to/3pjimN7
74HCT125 (5 Stück) – https://amzn.to/3955PHp
Steckbrett Kabel – https://amzn.to/2Y37yqk
Kabel Set (male/female/divers) – https://amzn.to/2Y89KfX
16GB microSD Karte – https://amzn.to/2KAdzaK

Ikea Vidja Standleuchte *

https://www.ikea.com/de/de/p/vidja-st…
*Unbezahlte Werbung