Raspberry Pi Lärmampel

Dieser Beitrag wurde 63460 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.

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:

Panel:

  • 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

4 Comments

Add a Comment

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.