Hallo alle miteinander,
ich habe mein Problem in einem anderen Threat kurz geschildert und die Empfehlung bekommen, einen neuen zu öffnen...
Ausgangspunkt:
Ein Freund hat mich auf die Jukebox4Kids (hier) hingewiesen, welche auch hier im Forum veröffentlicht wurde.
Ich fand's sofort geil, weil das mit den CD's bei kleinen Kindern echt so ne Sache ist.
Aber ich hab das Programm nicht gecheckt und wollte auch einfach selber mal was programmieren.
Ich hab mal ein Foto von der (fast) fertigen Musikbox angehängt.
Aufbau:
Ich habe auf Playlists verzichtet. Es werden einfach die Lieder von 1.mp3 durchnummeriert. Im Verzeichnis liegt eine .txt-Datei, welche angibt, wieviele Lieder in dem Ordner sind. Somit werden alle lieder Nach-und-nach abgespielt, bis das letzte fertig ist.
Mittels RFID können die "CD's" gewechselt werden. Auf den RFID-Karten ist auch nur eine Zahl gespeichert. Diese ist der Name des Ordners. Die Ordner sind auch einfach von 1 bis ... durchnummeriert.
Am Gehäuse ist ein USB-Anschluss angebracht. Darauf befinden sich die Lider, dann können diese relativ einfach ausgetauscht bzw. neue hinzugefügt werden.
Ich hab ein 2-Zeiliges Display mit je 16 Zeichen verbaut, welches mittels I2C angesteuert wird. Das zeigt so Zeugs an wie Liednummer und Name der "CD" und zählt die Liedzeit mit.
Problem1:
Ich habe lange rumprobiert, bis das mit dem Autostart funktioniert hat. Es lag wohl daran, dass ALLE Dateien ausführbar sein müssen. Leider bekomme ich die Lieder auf dem Stick nicht ausführbar gemacht. Sowohl über die Shell, als auch über den Desktop gehts nicht.
Frage1:
Weiß mir jemand eine Lösung, wie die Dateien auf dem USB-Stick aufrufen kann? Also im Autostart.
Problem2:
Das Display funktioniert im Autostart nicht so richtig. Starte ich das Programm über den Desktop oder die Shell, dann läuft es. Im Autostart zeigt es entweder nur Hieroglyphen an oder nur die erste Zeile mit einem extrem schlechten Kontrast.
Frage2:
Muss ich da irgendwas beachten, umstellen oder sonst so, damit es gescheit läuft??
Nochmal ne kurze Erläuterung:
Ich hab mal den Code und zwei Screenshots vom Desktop des Pi angehängt.
Auf dem einen findet man die (geöffneten) .txt-Dateien vom Ordner /home/pi/ und auf dem Anderen die .txt-Dateien aus dem Ordner 1. Nur zur Veranschaulichung des Codes.
Mittels Maxvol.txt kann die maximal mögliche Lautstärke gedrosselt werden. Das habe ich aber bisher nur mal so eingebaut, aber noch nicht benutzt. Man könnte es auch mit RFID-Karten im normalen Betrieb verwenden und die Lautstärke auf 75% oder 50% drosseln (oder wie auch immer).
Nach jedem Liedwechsel wird die Datei songid.txt aktualisiert, dann kann er nach dem Start wieder beim letzten Lied weitermachen.
Wenn der Ordner mit einer RFID-Karte gewechselt wird, dann wird der Ordner auch in der txt-Datei gespeichert.
Mit den Knöpfen kann man Start/Pause, Stopp, Vor, Rück, lauter und leiser machen. Wenn man die Stopptaste über 2,5 Sekunden lange gedrückt hält, dann beendet sich das Programm und der Raspberry fährt runter.
In Zeile 28 befindet sich die Variable mit welcher ich den Pfad von der SD-Karte auf den USB-Stick ändern könnte.
Reicht das an Input? Oder habe ich was elementares vergessen?
Schonmal Danke im Voraus.
Grüße
Alex
Hier mal der komplette Code (ist aber auch extra angehängt)
#!/usr/bin/python
## Jukebox 4 Franziska
# 4 Leerzeichen pro Einrueckung
import pygame.mixer
import RPi.GPIO as GPIO
import time
import MFRC522
import lcddriver
MIFAREReader = MFRC522.MFRC522()
# Pins fuer die Buttons
P_play = 29
P_vor = 31
P_rueck = 33
P_lauter = 35
P_leiser = 37
P_stop = 36
# GPIO's mit integriertem Pull-Down-Widerstand aktivieren
GPIO.setmode(GPIO.BOARD) # BOARD, da die Bibliothek des Mifare-Readers auch BOARD voreingestellt hat und es sonst zu einer Fehlermeldung kommt.
GPIO.setwarnings(False) # sonst kommt jedes mal beim Starten eine Warnung
GPIO.setup(P_play, GPIO.IN, GPIO.PUD_DOWN)
GPIO.setup(P_vor, GPIO.IN, GPIO.PUD_DOWN)
GPIO.setup(P_rueck, GPIO.IN, GPIO.PUD_DOWN)
GPIO.setup(P_lauter, GPIO.IN, GPIO.PUD_DOWN)
GPIO.setup(P_leiser, GPIO.IN, GPIO.PUD_DOWN)
GPIO.setup(P_stop, GPIO.IN, GPIO.PUD_DOWN)
pfad = "/home/pi/" # Pfad zu den Dateien
lcd = lcddriver.lcd()
lcd.lcd_clear()
lcd.lcd_backlight("on")
pygame.mixer.init()
null = 0 # Die Null als Variable. Wird waehrend dem Programm nicht veraendert
# Variablen zur Angabe von CD, Lied, Startlautstaerke, Maximallautstaerke und Anzahl der Lieder auf der CD
ordner = open (pfad + "ordner.txt").read()
ordner = int(ordner) # Diese Variable bestimmt den Ordner, also die CD, welche gespielt wird. Somit wird hier die zuletzt gespielte CD geladen.
anzahl = open (pfad + str(ordner) + "/anzahl.txt").read()
anzahl = int(anzahl) # Diese Variable bestimmt die Anzahl der Lieder auf der CD.
songID = open (pfad + "songid.txt").read()
songID = int(songID) # Diese Variable bestimmt das aktuell oder zuletzt gespielte Lied auf der CD
lautstaerke = 0.2 # Startlautstaerke
maxvol = open (pfad + "maxvol.txt").read()
maxvol = float(maxvol) # Maximal moegliche Lautstaerke.
cd = open (pfad + str(ordner) + "/cd.txt").read()
if maxvol < lautstaerke:
lautstaerke = maxvol
# Ab hier kommen die Zeitvariablen
stopStart = 0 # Zeitstempel beim Druecken (Halten) der Stopptaste
stopStop = 0 # Zeitstempel mit welchem die gedrueckte Zeit der Stopptaste berechnet wird
liedZeitAn = 0 # Startzeit zu Beginn eines jeden Liedes
jetztZeit = 0 # Aktuelle Zeit zum Errechnen der Spieldauer des Liedes
liedZeit = 0 # Gesamtzeit des Liedes bis jetzt
minute = 0 # Minutenzahl in der Zeitanzeige
sekunde = 0 # Sekundenzahl in der Zeitanzeige
# Variablen fuers Display
lcdLied = "0"
lcdZeit = "0"
lcdLaut = lautstaerke * 10
lcdPauseZeit = 5
state = "PLAYING"
lcd.lcd_backlight("on")
lcd.lcd_display_string(" Franziska's ", 1)
lcd.lcd_display_string(" Musikbox ", 2)
pygame.mixer.music.load(pfad + "start.mp3") # Startsound (diese, die vorherigen drei und die naechsten zwei Zeilen wieder einkommentieren)
pygame.mixer.music.play()
time.sleep(7)
pygame.mixer.music.set_volume(lautstaerke)
pygame.mixer.music.load(pfad + str(ordner) + "/" + str(songID) + ".mp3")
pygame.mixer.music.play()
liedZeitAn = time.time()
while True:
# Durch die While-Schleife direkt nach dem if wird dafuer gesorgt, dass die Auswahl erst nach Loslassen des Buttons aktiv wird. Ansonsten koennte die Schleife waehrend des Drueckens oefters durchlaufen werden.
playTaste = GPIO.input(P_play)
vorTaste = GPIO.input(P_vor)
rueckTaste = GPIO.input(P_rueck)
lauterTaste = GPIO.input(P_lauter)
leiserTaste = GPIO.input(P_leiser)
stopTaste = GPIO.input(P_stop)
an = pygame.mixer.music.get_busy()
(status,TagType) = MIFAREReader.MFRC522_Request(MIFAREReader.PICC_REQIDL)
jetztZeit = time.time()
if stopStop - stopStart > 2.5:
break
if jetztZeit - lcdPauseZeit > 2.5:
lcd.lcd_display_string("Lied %s %s " % (lcdLied, lcdZeit), 1)
lcd.lcd_display_string(cd, 2)
if playTaste == 1 and state == "STOPED":
while playTaste == 1:
playTaste = GPIO.input(P_play)
state = "PLAYING"
print("los gehts mit Song No. ", songID)
pygame.mixer.music.play()
liedZeitAn = time.time()
time.sleep(0.1)
elif playTaste == 1 and state == "PAUSED":
while playTaste == 1:
playTaste = GPIO.input(P_play)
state = "PLAYING"
print("paused->playing Song No. ", str(songID))
pygame.mixer.music.unpause()
liedZeitAn = time.time() - liedZeit
time.sleep(0.1)
elif playTaste == 1 and state == "PLAYING":
while playTaste == 1:
playTaste = GPIO.input(P_play)
state = "PAUSED"
print("playing->paused")
pygame.mixer.music.pause()
elif stopTaste == 1:
stopStart = time.time()
while stopTaste == 1:
stopTaste = GPIO.input(P_stop)
stopStop = time.time()
if stopStop - stopStart > 0.5 and stopStop - stopStart < 1:
lcd.lcd_display_string("********", 1)
elif stopStop - stopStart > 1 and stopStop - stopStart < 1.5:
lcd.lcd_display_string("****************", 1)
elif stopStop - stopStart > 1.5 and stopStop - stopStart < 2:
lcd.lcd_display_string("********", 2)
elif stopStop - stopStart > 2 and stopStop - stopStart < 2.5:
lcd.lcd_display_string("****************", 2)
elif stopStop - stopStart > 2.5:
break
if state == "PLAYING" or state == "PAUSED":
state = "STOPED"
pygame.mixer.music.stop()
elif vorTaste == 1:
while vorTaste == 1:
vorTaste = GPIO.input(P_vor)
if songID == anzahl:
songID = 1
print("Uuuund schon wieder von Vorne!!")
else:
songID += 1
print("Neeeeext Song is No. ", songID)
lcdLaut = lautstaerke * 100
pygame.mixer.music.load(pfad + str(ordner) + "/" + str(songID) + ".mp3")
songid_out = open(pfad + "songid.txt", "w")
songid_out.write(str(songID))
songid_out.close()
time.sleep(0.1)
if state == "PLAYING":
pygame.mixer.music.play()
liedZeitAn = time.time()
else:
state = "STOPED"
elif rueckTaste == 1:
while rueckTaste == 1:
rueckTaste = GPIO.input(P_rueck)
if songID > 1:
songID -= 1
print("Zurueck, jetzt kommt Lied Nr. ", songID)
else:
songID = anzahl
print("Jetzt sind wir beim letzten Lied!")
lcdLaut = lautstaerke * 100
stopZahl = 0
songid_out = open(pfad + "songid.txt", "w")
songid_out.write(str(songID))
songid_out.close()
time.sleep(0.1)
pygame.mixer.music.load(pfad + str(ordner) + "/" + str(songID) + ".mp3")
if state == "PLAYING":
pygame.mixer.music.play()
liedZeitAn = time.time()
elif lauterTaste == 1:
while lauterTaste == 1:
lauterTaste = GPIO.input(P_lauter)
lautstaerke += 0.05
if lautstaerke > maxvol:
lautstaerke = maxvol
print("Lautstaerke", lautstaerke * 10)
lcdLaut = lautstaerke * 100
lcd.lcd_display_string("Lautstaerke %s " % int(lcdLaut), 1)
pygame.mixer.music.set_volume(lautstaerke)
lcdPauseZeit = time.time()
elif leiserTaste == 1:
while leiserTaste == 1:
leiserTaste = GPIO.input(P_leiser)
lautstaerke = lautstaerke - 0.05
if lautstaerke < 0.05:
lautstaerke = 0.05
print("Lautstaerke", lautstaerke * 10)
lcdLaut = lautstaerke * 100
lcd.lcd_display_string("Lautstaerke %s " % int(lcdLaut), 1)
lcdPauseZeit = time.time()
pygame.mixer.music.set_volume(lautstaerke)
elif an == 0 and state == "PLAYING":
if songID < anzahl:
songID += 1
pygame.mixer.music.load(pfad + str(ordner) + "/" + str(songID) + ".mp3")
time.sleep(1)
songid_out = open(pfad + "songid.txt", "w")
songid_out.write(str(songID))
songid_out.close()
pygame.mixer.music.play()
liedZeitAn = time.time()
time.sleep(0.2)
state = "PLAYING"
print("naechstes Lied")
lcdLaut = lautstaerke * 100
lcd.lcd_display_string("Lied %s VOL %s" % (songID, int(lcdLaut)), 1)
# Nach jedem Lied kommt - nach einer Pause - automatisch nas naechste Lied.
else:
songID = 1
songid_out = open(pfad + "songid.txt", "w")
songid_out.write(str(songID))
songid_out.close()
state = "STOPED"
print("CD fertig")
lcd.lcd_display_string("CD beendet ", 1)
pygame.mixer.music.load(pfad + str(ordner) + "/" + str(songID) + ".mp3")
# Wenn dasletzte Lied beendet ist, dann stoppt die Jukebox, stellt aber auf Lied 1 Zurueck. Somit kann mit der Play-Taste wieder von vorne begonnen werden.
elif status == MIFAREReader.MI_OK:
# Get the UID of the card
(status,uid) = MIFAREReader.MFRC522_Anticoll()
# This is the default key for authentication
key = [0xFF,0xFF,0xFF,0xFF,0xFF,0xFF]
# Select the scanned tag
MIFAREReader.MFRC522_SelectTag(uid)
# Authenticate
status = MIFAREReader.MFRC522_Auth(MIFAREReader.PICC_AUTHENT1A, 8, key, uid)
# Check if authenticated
if status == MIFAREReader.MI_OK:
karte = MIFAREReader.MFRC522_Read(8)
print("Karte erkannt")
print(karte)
if karte[0] > null and karte[2] == null:
if ordner == karte[0]:
print "Gleiche Karte wie vorher"
lcd.lcd_display_string("Die laeuft schon", 1)
time.sleep(2)
MIFAREReader = MFRC522.MFRC522()
continue
else:
ordner = karte[0]
print(ordner)
print("neue CD")
songID = 1
pygame.mixer.music.load(pfad + str(ordner) + "/" + str(songID) + ".mp3")
songid_out = open(pfad + "songid.txt", "w")
songid_out.write(str(songID))
songid_out.close()
ordner_out = open(pfad + "ordner.txt", "w")
ordner_out.write(str(ordner))
ordner_out.close()
anzahl = open (pfad + str(ordner) + "/anzahl.txt").read()
anzahl = int(anzahl)
cd = open (pfad + str(ordner) + "/cd.txt").read()
time.sleep(0.1)
pygame.mixer.music.play()
liedZeitAn = time.time()
state = "PLAYING"
lcd.lcd_display_string(" Karte erkannt ", 1)
lcd.lcd_display_string(cd, 2)
time.sleep(2)
print("Karte weg vom Scanner")
elif karte[1] > 0 and karte[2] == 0: # maximallautstaerke begrenzen. Aktuell noch nicht benutzt.
maxvol = karte[1] / 100
maxvol_out = open(pfad + "maxvol.txt", "w")
maxvol_out.write(str(maxvol))
maxvol_out.close()
print("Maximallautstaerke geaendert")
if maxvol < lautstaerke:
lautstaerke = maxvol
print("Lautstaerke auf neuen Maximalwert reduziert")
pygame.mixer.music.set_volume(lautstaerke)
MIFAREReader = MFRC522.MFRC522()
if state == "PLAYING":
# Spieldauer des Liedes berechnen
liedZeit = jetztZeit - liedZeitAn
minute = liedZeit / 60
sekunde = (minute - int(minute)) * 60
if sekunde < 10 or minute < 10: # fuegt vorher eine Null hinzu, wenn die Sekunden- oder Minutenzahl einstellig ist
if sekunde < 10 and minute < 10:
lcdZeit = ("0%s:0%s" % (int(minute), int(sekunde)))
elif sekunde < 10:
lcdZeit = ("%s:0%s" % (int(minute), int(sekunde)))
elif minute < 10:
lcdZeit = ("0%s:%s" % (int(minute), int(sekunde)))
else:
lcdZeit = ("%s:%s" % (int(minute), int(sekunde)))
if songID < 10:
lcdLied = (" %s" % songID)
else:
lcdLied = songID
time.sleep(0.1)
# Das Ende des Programms beginnt hier! Die letzten beiden Zeilen fahren den Raspberry Pi herunter, koennen aber auskommentiert werden
print("Jukebox wird ausgeschaltet")
lcd.lcd_clear()
lcd.lcd_display_string(" Musikbox wird ", 1)
lcd.lcd_display_string(" ausgeschaltet ", 2)
pygame.mixer.music.load(pfad + "ende.mp3")
pygame.mixer.music.play()
time.sleep(5)
lcd.lcd_clear()
lcd.lcd_backlight("off")
GPIO.cleanup()
from subprocess import call
call("sudo shutdown -h now", shell=True)
Alles anzeigen