Raspberry Pi Lärmampel
Dieser Beitrag wurde 85691 mal angezeigt.
Hy Leute,
nachdem sich nun schon ein Jahr nichts auf meiner Seite getan hat. Wollte ich euch gerne ein kleines neues Raspberry Pi Projekt zeigen. Das Projekt ist auf der Arbeit entstanden, da eine kaufbare Lärmampel auch gut und gerne mal über 500 Euro kosten kann.
Daher hier einmal eine kostengünstigere Variante, bei der man zusätzlich auch noch etwas lernen kann.
Ideal ist das Projekt auch für Praktikanten oder Auszubildende die gerade in der Entwicklung anfangen, da man hier auch gleich sehen kann was programmiert wurde.
Die Lärmampel ist vielfältig einsetzbar. Ob im Büro, in der Schule oder aber zu hause um die kleinen bei Laune zu halten und gleichzeitig zu trimmen, etwas leiser zu spielen 😉
Materialliste
Damit wir unsere Lärmampel bauen können, benötigen wir einige Materialien. Ihr könnt natürlich schauen ob ihr einen anderen Soundsensor oder ein anderes Panel bekommt.
Beim Soundsensor würde ich dann einen nehmen der nicht durch einen Poti eingestellt werden kann, sondern einen festen dB Wert hat.
Beim LED-Panel müsst ihr darauf achten das diese WS2812 oder WS2812b sind. Diese können wir mit dem Pi direkt ansprechen.
- 1 x Raspberry Pi 3B
- Jumper Kabelbaum
- Netzteil 5V/3000mA
- 10 x Klettkabelbinder zum Bündeln Haft- und Flauschteil (optional)
- MicroSD 16GB Karte
- Raspberry Pi Case (offene Pins)
- 2 x (WS2812 WS2812b LED 5050 RGB 8×8 64 LED Matrix) oder WS2812B LED Strip Panel Kit Matrix 8×32 256 Pixel Digitales Flexible
- Stimmen-Erkennungs-Sensor
- Ggf. Debugkabel
Damit z.b.der Sensor mit dem Jumper Kabel verbunden werden kann, ist ein Lotkolben und Zinn notwendig. Dies wird ebenfalls für die beiden Panels benötigt. Damit die Pins entsprechend mit der Platine verbunden werden können. Um den Sensor ggf. einzustellen, wird noch ein kleiner Schrauberzieher oder eine Pinzette benötigt.
Bevor man die Platinen berührt sollte man sich erden, bzw. kurz den unlackierten Teil einer Heizung berühren um ggf. Spannungen im Körper abzubauen.
Infos zum Potenziometer
Der Poti ist bei diesem Model etwas eigenwillig. Dies kann sich je nach Model unterscheiden. Im Test, hat sich der Poti gerne mal von sich aus nach justiert. Des Weiteren wirken „Fremd-oder Körperspannung“ebenfalls als Störfaktor und erschweren das einrichten. Daher sollte, wenn möglichder Poti eingestellt werden, währendman Handschuhe trägt, bzw. geerdet ist.
Aufbau Steps
1. Elemente vorbereiten
Als erstes bereiten wir die Panels vor. Dafür löten wir die Pins entsprechend an die beiden Panels. Im Lieferumfang sind jeweils 3 Pins vorhanden. Diese verlöten wir entsprechend. Da die Jumper-Kabel auf einer Seite Pins haben, können wir diese entsprechend mit verlöten.
Bei dem Sensor können wir die Pins ebenfalls verlöten. Danach können wir die Jumper
Kabel mit dem Raspberry Pi verbinden. Damit das ganze nachvollziehbar ist, sind alle Jumper-Kabel Farblich unterschiedlich. So ist genau zu erkennen, wo das jeweilige Kabel angeschlossen werden muss um die initiale Funktionalität herzustellen.
Sobald alle Adern am Panel als auch am Sensor verlötet sind, schließen wir die Adern entsprechend am Raspberry Pi an.
Folgende Pin Belegung habe ich an dieser Stelle gewählt:
- 2 Pin: 5V Power(Blau) → + 5V LED Panel No.1 →+ 5V LED Panel No.2
- 6 Pin: Ground (Lila) → GND LED Panel No.1 → GND LED Panel No.2
- 12 Pin: GIPO18(Grün) → DIN LED Panel No.1 → DOUT → DIN LED Panel No.2
Sensor:
- 40 Pin: SPI1 SCLK (Braun) → D0 Sensor
- 4 Pin: 5V Power (Rot) → + Sensor
- 9 Pin: Ground(Orange) → G Sensor
Die gelbe Ader ist nicht angeschlossen, da dies der analoge Port des Sensors ist und der Raspberry Pi unterstützt keine Analogen Signale.
Nachdem nun alles soweit angeschlossen ist, können wir uns dem Betriebssystem und der Software widmen.
2. Betriebssystem installieren und Grundeinrichten
Als Betriebssystem wird Raspbian Lite(Raspbian Buster Lite) verwendet.Dies kann man auf der Seite raspberrypi.org downloaden.
Damit wir das System auf die MicroSD Karte schreiben können, benötigen wir das Programm Win32DiskImager, als auch einen Kartenleser.
Kopiert das entpackte Image mit dem Programm auf die SD Karte. Nachdem der Vorgang abgeschlossen ist, erscheint die SD Karte als „Boot“ auf eurem Arbeitsplatz.
Hier könnt ihr nun die WLAN Daten hinterlegen und den SSH Port freigeben.Erstellt dafür eine leere „ssh“ Textdatei.
Diese Datei sorgt dafür dass der Pi beim Booten über den Port 22 erreichbar ist. Dieser ist sonst Standardmäßig geschlossen.Nun müssen die WLAN Daten hinterlegt werden. Dafür erstellt eine Textdatei mit dem Namen: „wpa_supplicant.conf“ und füllt diese mit:
country=DE ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 network={ ssid="wlan-bezeichnung" psk="passwort" key_mgmt=WPA-PSK }
Diese Datei wird dann entsprechend in die WLAN Konfig des Pi verschoben und der Pi wählt sich ins WLAN ein.
Nun muss eine SSH-Verbindung zum Port 22 mit PUTTY des Pi`s hergestellt werden.
Den Pi könnt ihr im WLAN durch diverse Port-Scanner ausfindig machen oder euer Router hält die IP Adresse des Pi`s bereit.
Der Standard User ist „pi“, das Standard Passwort ist „raspberry“
Damit könnt ihr euch mit dem Pi verbinden und erst einmal eine Grundeinrichtung durchführen.
3 Updates und nötige Pakete installieren
Damit der Pi auch mit unserem Panel und Sensor interagieren kann, müssen wir erst mal einige Updates machen und nötige Pakete installieren.
Dazu meldet euch zuerst als Root an mit „sudo -i“. Dadurch müsst ihr nicht vor jedem Befehl das „sudo“ hängen.
apt-get update && apt-get upgrade -y && apt-get dist-upgrade -y
Nachdem die Updates durchgelaufen sind, können wir den raspbian konfigurieren. Dies machen wir mit dem Befehl „raspi-config“
Erweitert hier die SD Karte, damit ihr die volle Größe nutzen könnt, falls ihr dies später noch für etwas anderes nutzen möchtet.
Stellt auch das Datum und die Zeitzone ein, sowie, das Keyboard Layout.
Sollte der Pi danach ein Reboot benötigen, führt dies aus oder macht mit dem folgenden weiter:
apt-get install gcc make build-essential python-dev python-pip wget git scons swig pigpio screen
Dieser Befehl lädt uns die benötigten Module wie z.b. „python-dev“ oder „git“ runter.
Danach müssen wir unterbinden, das sein Modul geladen wird.
Dafür öffnen wir die Datei /etc/modprobe.d/snd-blacklist.conf mit dem Befehl
nano /etc/modprobe.d/snd-blacklist.conf
und fügen am Ende der File dies ein:
blacklist snd_bcm2835
Da wir an der Stelle PWM verwenden, müssen wir das Soundmodul der ARM CPU deaktivieren. Da es sonst zu Störungen kommen kann.
Zusätzlich müssen wir noch eine Konfig ändern mit :
nano /boot/config.txt
und fügen dort ein „#“ vor die Zeile mit „dtparam=audio=on“
Wir schließen und speichern unsere Änderungen und führen einen „reboot“ durch.
Nach dem Reboot können wir die nötigen Packages laden.
4. LED Software Package laden
Mit
git clone https://github.com/jgarff/rpi_ws281x
holen wir uns nun ein Test-Suit. Mit diesem können wir das ganze Testen, als auch eine Installation machen, damit wir das ganze später in unserem Script nutzen können.
Danach wechseln wir ins das neue Verzeichnis und installieren mit scons.
cd rpi_ws281x/ && sudo scons
Wenn dies durchgelaufen ist, kompilieren & installieren wir das Ganze:
cd python && sudo python setup.py build && sudo python setup.py install
Damit sollten wir nun die Panel nutzen können. Testen können wir das Ganze mit:
sudo PYTHONPATH=".:build/lib.linux-armv7l-2.7" python examples/strandtest.py
Wenn der Test erfolgreich war, können wir fortführen. Wenn nicht, sollte das Panel und die Vorherigen Steps geprüft werden.
Lärmampel Script
Da der Test erfolgreich war und unsere Panels leuchten, können wir uns ein eigenes Lärmampel Script schreiben.
Das Script muss von euch noch weiter angepasst werden. Je nachdem welchen Sensor ihr euch geholt habt.
Als Beispiel gibt es hier das Script:
#!/usr/bin/env python3 import RPi.GPIO as GPIO import time, sys, datetime from neopixel import * import random #GPIO SETUP SOUND_PIN = 21 GPIO.setmode(GPIO.BCM) GPIO.setup(SOUND_PIN, GPIO.IN) # LED PANEL configuration: LED_COUNT = 128 # 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 = 5 # 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 # Define functions which animate LEDs in various ways. def colorWipe(strip, color, wait_ms=1): """Wipe color across display a pixel at a time.""" for j in range(2): for i in range(40): strip.setPixelColor(i+(j*64) , color) #time.sleep(wait_ms/1000.0) strip.show() # Create NeoPixel object with appropriate configuration. 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). strip.begin() def colorWipeSeperator(strip, color): #Die Funktion definiert um einen Seperator auf die LED Panels zu projizieren damit besser unterschieden werden kann for j in range(2): for i in range(40,48): strip.setPixelColor(i+(j*64) , color) colorWipeSeperator(strip,Color(255,255,255)) #Der Seperator sollte zuerst Weiss sein, kann aber jederzeit hier geaendert werden def colorWipeAverage(strip, color): # Die Funktion definiert um die Durchschnittslautstaerke auf die LED Panels zu projizieren for j in range(2): for i in range(48,64): strip.setPixelColor(i+(j*64), color) strip.show() count = 0 ledcolor = "" dblevel_min = 0 #0 dblevel_mid = 16 #13 dblevel_mid2 = 23 #20 dblevel_max = 28 #25 ledcolor2="" #Fuer den Durchschnittsektor def DETECTED(SOUND_PIN): global count #nowtime = datetime.datetime.now() if GPIO.input(SOUND_PIN): count += 1 else: count -= 1 print ("Sound Module Test (CTRL+C to exit)") time.sleep(1) print ("Ready --> RUN") try: GPIO.add_event_detect(SOUND_PIN, GPIO.BOTH, callback=DETECTED) middle = [] middlevalue = 0 maxvalue = 0 minvalue = 0 secoundoutput = 1 cyclus = 0 sleeptime = 0.005 averagecyclus = 0 # Die Variablen die ich fuer die Berechnung des Durchschnittwertes benoetige averagevalue = 0 fiveminutes = 0 average = [] while 1: dB = (count+83.2073)/11.003 count = 0 position = 50+dB average.append(dB) # Die einzelnen DB Werte werden in eine Liste gepackt #print(dB) line = "" for x in range(100): if x == int(round(position)): line += "*" middle.append(dB) if dB > maxvalue: maxvalue = dB if dB < minvalue: minvalue = dB if x == 50: line += "|" line += " " #print line #print "DB: "+str(dB) cyclus += sleeptime averagecyclus += sleeptime #Die Zeit wird mitgezaehlt um nach 6 Minuten die erste wieder zu loeschen fiveminutes += sleeptime time.sleep(sleeptime) if cyclus >= secoundoutput: for x in middle: middlevalue += x #print len(middle) #print "middle is: "+str((middlevalue/len(middle))) #print "max is: "+str(maxvalue) #print "min is: "+str(minvalue) #test maxvalue = maxvalue+(-1*minvalue) # #print "min-max-sum is: "+str(maxvalue+(-1*minvalue)) #LED COLOR if (maxvalue >= dblevel_mid2 and ledcolor != "red"): ledcolor = "red" colorWipe(strip, Color(0, 255, 0)) # Red wipe elif (maxvalue < dblevel_mid2 and maxvalue >= dblevel_mid and ledcolor != "yellow"): ledcolor = "yellow" colorWipe(strip, Color(255, 255, 0)) # Yellow wipe elif (maxvalue < dblevel_mid and ledcolor != "green"): ledcolor = "green" colorWipe(strip, Color(255, 0, 0)) # Green wipe # time.sleep(1) cyclus = 0 middlevalue = 0 maxvalue = 0 minvalue = 0 middle = [] if averagecyclus >= 60: #Nach einer jeden Minute startet die Berechnung und Durchfuehrung des Durchschnittwertes if fiveminutes < 359: #Sollte es unter 6 Minuten sein wird dies ausgefuehrt for x in average: averagevalue += x averagevalue = averagevalue/(len(average)) #Berechnung des Durchschnitts if (averagevalue >= dblevel_mid2 and ledcolor2 != "red"): #Gleichen If-Anweisungen wie bei der aktuellen Lautstaerke ledcolor2="red" colorWipeAverage(strip, Color(0,255,0)) elif (averagevalue <dblevel_mid2 and averagevalue >= dblevel_mid and ledcolor2 !="yellow"): ledcolor2="yellow" colorWipeAverage(strip, Color(255,255,0)) elif (averagevalue < dblevel_mid and ledcolor2 != "green"): ledcolor2="green" colorWipeAverage(strip, Color(255,0,0)) averagecyclus = 0 else: #Sollten 6 Minuten erreicht werden wird der Zaehler der die Gesamtzeit zaehlt wieder auf 5 Minuten zurueckgesetzt um keinen Ueberlauf zu schaffen fiveminutes = 300 averagevalue = 0 averagecyclus = 0 for i in range(12000): #Die ersten 12000 Eintraege also die der ersten Minute der aktuellen 6 Minuten wird aus der Liste geloescht average.pop(0) for x in average: #Der Durchschnitt wird erneut berechnet aus den aktuellen 5 Minuten averagevalue += x averagevalue = averagevalue/(len(average)) if (averagevalue >= dblevel_mid2 and ledcolor2 != "red"): #Gleiche If-Anweisungen wie beim aktuellen Wert ledcolor2="red" colorWipeAverage(strip, Color(0,255,0)) elif (averagevalue <dblevel_mid2 and averagevalue >= dblevel_mid and ledcolor2 !="yellow"): ledcolor2="yellow" colorWipeAverage(strip, Color(255,255,0)) elif (averagevalue < dblevel_mid and ledcolor2 != "green"): ledcolor2="green" colorWipeAverage(strip, Color(255,0,0)) except KeyboardInterrupt: print (" Quit") GPIO.cleanup()
Der Quellcode ist teilweisekommentiert, damit nachvollzogen werden kann, was passiert.
Wenn ihr andere Panels oder ein LED-Streifen verwendet, müsst ihr die Anzahl der LEDs anpassen, die vorhanden sind.
Das Script könnt ihr nun speichern unter „/home/pi/lernampel.py“ und ausführen mit:
screen -dmS lernampel sudo PYTHONPATH=".:build/lib.linux-armv7l-2.7" python /home/pi/lernampel.py
Das „screen“ sorgt dafür, dass die „Ausgabe in ein neues Terminal geschrieben wird, wenn es eine Ausgabe gibt. Mit „screen –x“ kann man dort rein springen und mit „strg+a d“ verlassen ohne den screen zu beenden.
Autostart nach Reboot
Damit unser Ampelscript automatisch nach jedem Neustart, direkt mit dem System bootet, müssen wir dies entsprechend hinterlegen.
Dazu öffnen wir mit nano die Datei /etc/rc.local
sudo nano /etc/rc.local
Und fügen dort, eine neue Zeile vor dem exit 0 ein:
screen -dmS lernampel sudo PYTHONPATH=".:build/lib.linux-armv7l-2.7" python /home/pi/lernampel.py
Finetuning
Wenn der Sensor ein Poti hat, muss der Ponti nun eingestellt werden. Bzw. Finegetuned werden. Das ganze kann sich etwas hinziehen, da es keine fixen Einstellungspunkte gibt und auch keine dB Orientierungen. Hier müsst ihr dann nach eigenem Ermessen den Poti einstellen.
Ich hoffe ich konnte euch weiterhelfen und ihr seit mit dieser Anleitung gut klar gekommen.
Wenn ja, würde ich mich über keine kleine Aufmerksamkeit freuen! Z.b. ein Bier oder eine Tasse Kaffee:
PayPal Friends: https://paypal.me/spacedevil
Oder mit BTCs: 1LvETe6uTP64hK3UR3oSAdzT5ZjLnttqBm
Hallo Sven,
vielen Dank für die tolle Anleitung.
Leider klappt es nicht ganz bei mir.
Beim Stimmen-Erkennungs-Sensor (welcher der gleiche wie bei dir sein dürfte), leuchten beide LEDs. Jedoch bekomme ich ständig folgenden Wert via Print angezeigt.
max is: 7.56223757157
min is: 0
max is: 7.56223757157
min is: 0
max is: 7.56223757157
min is: 0
Die Kinder freuts, grün ist gesichert 🙂
Ne Idee woran das liegen könnte?
Danke und Grüße
Tom
Hallo Tom,
beachte einmal den Step mit dem Finetuning 🙂 Es scheint mir als ob hier die Einstellung mit dem Poti vergessen wurde.
Beste Grüße
Hallo Sven,
danke für die Antwort.
Hmm den Poti kann ich drehen wie ich will, an dem Wert ändert sich nicht. Wie wenn kein Wert übertragen wird.
Wie hast du den Poti eingestellt?
Danke und Grüße
Tom
Hi Sven,
hast du noch einen Tipp für mich?
Ich kann den Poti drehen, wie ich will. Der Wert ändert sich nicht. Kann ich den Wert auch anders irgendwie messen?
Danke und Grüße
Tom
Hallo Sven,
vielen Dank zunächst für die Anleitung, die Du hier zur Verfügung gestellt hast. Nach ein paar Schwierigkeiten und einigen Anpassungen im Installationsprozess hat am Ende das Panel – ich verwende aktuell nur eins – fein in den vorgesehenen Farben geleuchtet. Die Einstellungen des Poti funktionierten auch ganz gut nachdem ich hierzu eine Hilfestellung im Netz gefunden habe: Auf dem Sensor sind 2 LED´s: Power und Aktivierung. Man kann hier das Pati so lang drehen, bis die 2. LED nicht mehr leuchtet, nur noch glimmt und hat somit einen Startpunkt, von dem man die Einstellungen vornehmen kann.
Es wäre für viele sicher hilfreich, wenn Du die Installationsbefehle ein wenig anpassen könntest. Python klappt so nicht mehr – hier werden die Alternativen Python 3 verlangt. Die Installation der LED-Software ist leider so in der Beschreibung nicht vollständig. Hier fehlen noch „git clone https://github.com/jgarff/rpi_ws281x“ im Ordner rpi_ws281x sowie „git checkout dev“ und danach „git pull“. Erst danach leuchten bei mir die LED´s.
Für andere Mitleser: Je nach Modul sind die Anschlüsse der LED-Panele ggf. anders beschriftet und trotzdem nicht eindeutig. Ich musste ein paar Pins tauschen obwohl ich das vermeintlich gleiche Modell bestellt hatte.
Viele Grüße
Thomas