Abfrage der Laufzeit entfernen und weiteres

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Frank R.
User
Beiträge: 38
Registriert: Montag 23. September 2019, 10:10

Sieht gut aus, habe "led" in "len" geändert. Besten Dank Sirius3.

Jetzt bleibt nur noch der Teil, dass die zuletzt aktivierte LED für einige Sekunden eingeschaltet bleibt. Ich schaue mal, ob ich dazu was finde.
Frank R.
User
Beiträge: 38
Registriert: Montag 23. September 2019, 10:10

Hallo,

nach dem ich jetzt tagelang nach Antworten gesucht habe, bin ich leider immer noch nicht schlauer geworden. Ist es überhaupt möglich, die Zufallswiedergabe so zu ändern, dass die zuletzt aktivierte LED noch für einige Sekunden eingeschaltet bleibt? Mir ist zwar bekannt, dass es neben der sleep noch eine delay Funktion gibt, aber wie ich den Code schreiben muss... Also, geht das überhaupt, oder kann ich das Suchen auch aufgeben?
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

Wo willst Du denn nach Antworten suchen? Als Programmierer mußt Du die Antwort selbst entwickeln, und zwar aus Bausteinen, die Du schon kennst, also Zufalls-LED auswählen, für ein paar Sekunden warten, LED ausschalten.
Frank R.
User
Beiträge: 38
Registriert: Montag 23. September 2019, 10:10

Ich habe nach Beispielen gesucht, bei https://py-tutorial-de.readthedocs.io/de/python-3.3/# z.B. Habe aber nichts gefunden, bzw. weiß nicht wie ich das realisieren soll. Ich habe zwar eine vage Vermutung, wie das funktionieren könnte, aber das war's dann auch.
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

Dann mußt Du nur noch die vage Idee, die ich meiner Meinung nach recht konkret beschrieben habe, umsetzen.
Frank R.
User
Beiträge: 38
Registriert: Montag 23. September 2019, 10:10

Wieder mal später als geplant, aber mittlerweile weiß ich wirklich nicht mehr weiter. Das einzige Code Beispiel, was ungefähr mit meinem Problem zu tun hat, ist der elektronische Würfel mit 6 Zahlen. Der wird natürlich noch mittels Port Expander betrieben, und der Code ist entsprechend anders. Das Prinzip ist aber genau das, was ich brauche: Zufällige, SCHNELLE Wiedergabe der einzelnen LEDs zur Darstellung von "Zahlen", und die zuletzt angezeigte Zahl bleibt aktiviert. Analog zu meinem Projekt wäre das eben die zufällige LED Schaltung (z.B. mit einem time.sleep (on_time) von 0.02) und nach Erreichen des Wertes bei "repetition_count" bleibt die zuletzte aktivierte LED aktiv (entweder für eine festgelegte Zeit, oder bis der Taster erneut gedrückt wird.) Ich habe schon versucht, den Code anzupassen, aber ohne Erfolg.

Der aktuelle Code (siehe unten) funktioniert, aber wenn ich einfach nur die on_time erhöhe, bleiben ja ALLE LEDs entsprechend lange angeschaltet, aber das sollen sie ja nicht. NUR die letzte LED soll z.B. für 10 Sekunden, oder bis per Tasterdruck der Ablauf neu gestartet wird aktiviert sein. Und da hakt's.

Code: Alles auswählen

import gpiozero
import time
import random

def play_leds(leds):
    repetition_count = 20  # Muster wird repetition_count mal wiederholt
    on_time = 0.02  # Leuchtdauer der LED
    for _ in range(repetition_count * len(leds)):
        led = random.choice(leds)
        led.on()
        time.sleep(on_time)
        led.off()

def main():
    leds = gpiozero.LEDBoard(17, 18, 27, 22, 23, 24, 25, 4, 12)
    button = gpiozero.Button(16)
    while True:
        button.wait_for_press()
        play_leds(leds)

if __name__ == '__main__':
    main()
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

Dafür mußt Du Code schreiben, der mit der zuletzt gewählten LED etwas macht.
Frank R.
User
Beiträge: 38
Registriert: Montag 23. September 2019, 10:10

So, nachdem ich mich mit jemandem kurzgeschlossen habe der "etwas" mehr Ahnung hat als ich, ist derzeit folgender Code aktuell. Aber immer noch fehlerhaft:

Code: Alles auswählen

import gpiozero
import time
import random

def play_leds(leds):
    repetition_count = 20  # Muster wird repetition_count mal wiederholt
    on_time = 0.02  # Leuchtdauer der LED
    
    for i in range(repetition_count):
        led = random.choice(leds)
        led.on()
        time.sleep(on_time)
        if i < repetition_count-1:
            led.off()

def main():
    leds = gpiozero.LEDBoard(17, 18, 27, 22, 23, 24, 25, 4, 12)
    button = gpiozero.Button(16)
    while True:
        button.wait_for_press()
        play_leds(leds)

if __name__ == '__main__':
    main()
Wenn ich jetzt den Taster drücke, läuft die Zufallswiedergabe und die zuletzt aktivierte LED bleibt an, bis ich den Taster wieder drücke. ABER: Manchmal bleiben ZWEI LED an, nicht nur ein. Also irgendwo stimmt noch was nicht :?:
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

Wo schaltest Du denn die letzte LED wieder aus?
Frank R.
User
Beiträge: 38
Registriert: Montag 23. September 2019, 10:10

nochmal überarbeitet, und ja, wo schalte ich die aus? Fehlt offensichtlich

Code: Alles auswählen

import gpiozero
import time
import random

def play_leds(leds):
    repetition_count = 20 * len(leds)  # Muster wird repetition_count mal wiederholt
    on_time = 0.1  # Leuchtdauer der LED
    
    for i in range(repetition_count):
        led = random.choice(leds)
        led.on()
        time.sleep(on_time)
        if i < repetition_count-1:
            led.off()

def main():
    leds = gpiozero.LEDBoard(17, 18, 27, 22, 23, 24, 25, 4, 12)
    button = gpiozero.Button(16)
    while True:
        button.wait_for_press()
        play_leds(leds)

if __name__ == '__main__':
    main()
Frank R.
User
Beiträge: 38
Registriert: Montag 23. September 2019, 10:10

und nochmal angepasst

Code: Alles auswählen

import gpiozero
import time
import random

def play_leds(leds):
    repetition_count = 20 * len(leds)  # Muster wird repetition_count mal wiederholt
    on_time = 0.1  # Leuchtdauer der LED
    
    for i in range(repetition_count):
        led = random.choice(leds)
        led.on()
        time.sleep(on_time)
        if i < repetition_count-1:
            led.off()
        else:
            time.sleep(5)
            led.off()

def main():
    leds = gpiozero.LEDBoard(17, 18, 27, 22, 23, 24, 25, 4, 12)
    button = gpiozero.Button(16)
    while True:
        button.wait_for_press()
        play_leds(leds)

if __name__ == '__main__':
    main()
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

Du hast Code mehrfach kopiert. Dabei geht es nur darum, eine Schleife zu programmieren, die 179mal kurz und einmal lang pausiert.

Code: Alles auswählen

import gpiozero
import time
import random
from itertools import repeat, chain

def play_leds(leds):
    on_time = 0.1  # Leuchtdauer der LED
    delays = chain(repeat(on_time, 20 * len(leds) - 1), [5])
    for delay in delays:
        led = random.choice(leds)
        led.on()
        time.sleep(delay)
        led.off()

def main():
    leds = gpiozero.LEDBoard(17, 18, 27, 22, 23, 24, 25, 4, 12)
    button = gpiozero.Button(16)
    while True:
        button.wait_for_press()
        play_leds(leds)

if __name__ == '__main__':
    main()
Frank R.
User
Beiträge: 38
Registriert: Montag 23. September 2019, 10:10

Oh jeh.. da hab ich mich wohl in den Schleifen verrannt. Habe deinen Code eben mal getestet, sieht ja schon anders aus. Vielen lieben Dank erstmal, Sirius3.
Ich versuche mal, den Code nachzuvollziehen:

Aus den itertools werden, vereinfacht gesagt, repeat für die Wiederholungen und chain für den Ablauf der Iterationen importiert. delays definiert eine chain, also Kette von Abläufen, welche 20 mal die Anzahl der LEDs durchläuft, wobei jede LED für 0.1 Sekunden leuchtet, ausgeschaltet wird, und die letzte LED (- 1) für [5] Sekunden aktiviert bleibt. delay wird durch [5] bestimmt, wenn ich dort eine andere Zahl eintrage bleibt die LED länger an.

Hoffe ich habe das halbwegs verständlich erklärt, wie ich den Code verstehe?
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

Es gibt verschiedene Arten, solche Probleme zu lösen. Einen Index zu nehmen, um zu wissen, ob man am letzten Durchgang angekommen ist, ist indirekter, als mit einer Schleife über die Pausen direkt. Index versucht man deshalb in Python zu vermeiden, weil man Don schön einfach andere Reihen binden kann, als nur aufsteigende Zahlen.
Frank R.
User
Beiträge: 38
Registriert: Montag 23. September 2019, 10:10

Kann ich denn, basierend auf diesem Code, einen Sound abspielen? Also bei jedem Aufleuchten einer LED einen Sound (immer der selbe) mit der entsprechenden on_time? Für das Abspielen dachte ich an pygame, scheint wohl die einfachste Möglichkeit zu sein. Wie man einen Sound an sich abspielt ist ja gut dokumentiert. Wäre hier ein eigener Abschnitt (wie z.B. def main():) notwendig bzw. sinnvoll, oder kann das in den vorhandenen (def play.....) integriert werden?
__deets__
User
Beiträge: 14542
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das muss schon mit der bestehenden Logik verbaut werden. Und es kann sein, dass du den Pygame Event Loop treiben musst. Also gelegentlich mal aufrufen.
Frank R.
User
Beiträge: 38
Registriert: Montag 23. September 2019, 10:10

Hallo,

bin jetzt etwas weiter mit dem Sound, allerdings funktioniert es noch nicht so richtig. Momentan sieht der Code folgendermaßen aus:

Code: Alles auswählen

import gpiozero
import time
import random
import pygame
from itertools import repeat, chain
pygame.init()
sound = pygame.mixer.Sound('/home/pi/Documents/test.wav')

def play_leds(leds):
    on_time = 0.1  # Leuchtdauer der LED
    delays = chain(repeat(on_time, 20 * len(leds) - 1), [5])
    for delay in delays:
        led = random.choice(leds)
        led.on()
        sound.play()
        time.sleep(delay)
        led.off()

def main():
    leds = gpiozero.LEDBoard(17, 18, 27, 22, 23, 24, 25, 4, 12)
    button = gpiozero.Button(16)
    while True:
        button.wait_for_press()
        play_leds(leds)

if __name__ == '__main__':
    main()
Ich vermute mal, dass das nicht optimal ist :?: Ich habe das Problem, dass der Sound, wenn er nicht genau so lang bzw. kurz ist wie das Aufblinken, völlig falsch abgespielt wird. d.h. wenn ich den Sound nicht auf 0.1 Sekunden kürze, funktioniert die Wiedergabe nicht richtig. Und am Ende soll ein ANDERER Sound entsprechend des delays, also hier 5 Sekunden lang abgespielt werden.
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn Du in 18 sekunde 180 mal einen Sound abspielen willst, dann rate mal, wie lange ein Ton sein kann ...
Was soll man sonst noch sagen? Du mußt das was Du willst programmieren. Das passiert nicht von alleine.
Frank R.
User
Beiträge: 38
Registriert: Montag 23. September 2019, 10:10

Natürlich nur 0.1 Sekunden, wie oben geschrieben. Mich interessiert eher, ob denn der Code an sich so ok ist, oder ob der Einbau des sound.play() anders gelöst werden sollte.
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

Man könnte natürlich auch parallel dazu einen Sound abspielen, der halt so lang ist, wie die ganze Würfelei.
Antworten