Siebensegmentanzeige im Multiplexbetrieb flackert

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

Hi noch eine Frage zu der Digit Darstellung

1. Zeitanzeige.
Z.b 10.12 , es soll aber 10:12 angezeigt werden. Ich habe deshalb das 3 te Ledmodull gedreht, also ist für Punkt oben links.

2. Temperaturangabe
Z.b. 8.13, es soll aber 8:13 angezeigt werden. Mit dem alten Programm habe ich so eine Anzeige zusammen gebracht.

Meine Frage, wie kann ich den Code so anpassen, das ich diese LED ModulAnzeige hinbekomme?
Sirius3
User
Beiträge: 18051
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn ich das richtig sehe, mußt Du ja nur meine `print_digits` so anpassen, dass man mehr als einen point_pin übergeben kann.
Warum willst Du bei Temperaturen einen Doppelpunkt?
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

Hi nein, nur bei der Uhrzeit, habe es aber leicht anpassen können.
Es funktioniert. Allerdings wenn ich das über mehrere Stunden laufen lass, fängt die ANzeige wieder an zu flackern... wenn ich nur im Programm registrieren könnte wenn keine Anzeige auf den Ledmodiulen erfolgt, dann müsste ich das Programm wieder von neuem starten, aber wie kann ich das realisieren?
Benutzeravatar
sparrow
User
Beiträge: 4361
Registriert: Freitag 17. April 2009, 10:28

Was genau heißt denn flackern?
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

Wenn ich ein Video anhängen könnte wäre es einfach zu erklären. Ich weiß zwar das im Multiplexbetrieb bin, aBer die Frequenz reicht zumindest die ersten Stunden aus, das die ledanzeige gut dargestellt wird.
Sporadisch fängt die Anzeige dann zu blinken an. Irgendwann geht diese ganz aus. Kommt dann wieder , das läuft solange bis es ganz dunkel bleibt. Auch die Shell Anzeige bleibt dann irgendwann aus.
Komisch ist, das das Programm nicht auf Temperature = 0 oder if NOT Temperature reagiert..
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

Von der Hardware verwende ich ein ULN2803 um die einzelnen Segmente über Widerstände anzusteuern,
Die 4 Ledmodule fahre ich über einen UND2981 an. Mit einem Raspberry pi 4b , steuere ich beide Bausteine.
Benutzeravatar
__blackjack__
User
Beiträge: 13533
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Kann es eventuell sein, dass das aktivieren eines Digit-Pins auch eine kleine Verzögerung braucht, bis garantiert ist, dass die Segment-Pins benutzt werden können?

Edit: Und läuft das wenn man nur die Urzeit ausgibt, also den Teil mit der Logo weg lässt? (Also auch die Abfrage der Daten von dort.)

Code: Alles auswählen

- (void)countSheep {
    unsigned int sheep = 0;
    while ( ! [self isAsleep]) { ++sheep; }
}
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du kannst ein Video woanders hochladen und einen Link darauf posten.
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

Hi, also ich habe jetzt die Logoabfrage weggelassen, jetzt bleibt die Schleife scheinbar im Takt, es kommt ni.cht zum blinken oder flimmern der Anzeige... Jetzt wäre die Frage wie kann ich in meinem Programm damit umgehen wenn scheinbar die Temperatur Abfrage der Logo zu dem Problem führt.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das gpio cleanup ist so quatsch. Und verursacht denke ich das flackern. Das muss aus der while-Schleife raus. Denn jetzt wird nach jedem durchlaufen des do_loop cleanup gemacht, und damit der Pin-Zustand veraendert, wenn es zu einem Fehler kommt. Das ist ja aber nicht, was man will. Sondern man will, dass. die Abfrage einfach wieder anfaengt. Und nur beim echten Verlassen des Progamms das aufraeumen kommt.

Code: Alles auswählen

def main():
    try:
        initialize()
        while True:
            try:
                do_loop()
            except KeyboardInterrupt:
                break
            except Exception as error:
                print(error)
    finally:
        GPIO.cleanup()
do_loop ist auch ein seltsamer Name, es wird ja kein loop ausgefuehrt. show_value() oder sowas wuerde ich waehlen.
Benutzeravatar
__blackjack__
User
Beiträge: 13533
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Ich würde auch noch die Behandlung vom `KeyboardInterrupt` da raus holen, sonst hat man immer einen kleines Zeitfenster in dem das dann doch eine Ausnahme mit Stacktrace verursacht:

Code: Alles auswählen

def main():
    try:
        initialize()
        while True:
            try:
                do_loop()
            except Exception as error:
                print(error)
    except KeyboardInterrupt:
        pass
    finally:
        GPIO.cleanup()
Und eventuell auch noch die andere, allgemeine Ausnahmebehandlung auch und stattdessen mit `catch()`-Decorator vom `logururu`-Package die `do_loop()` dekorieren, damit Ausnahmen die von dort kommen, protokolliert werden, das Programm aber nicht abbrechen.

Code: Alles auswählen

- (void)countSheep {
    unsigned int sheep = 0;
    while ( ! [self isAsleep]) { ++sheep; }
}
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

Ok, ich habe die Abtastung der Temperatur auf 30sekunden erhöht, jetzt habe aktuell eine stabile Anzeige.
Kann ich eigentlich das program auf täglich von 8 bis 20 Uhr laufen lassen? Wie programmiere ich so ein timing?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Indem du es dauerhaft laufen lässt, und in deinem Programm einfach abfragst, ob der aktuelle Zeitpunkt im definierten Bereich liegt. Wenn nicht, LEDs aus & ein paar Sekunden warten.
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

Code: Alles auswählen

[code]
[/code]ok, vielen Dank fuer den Tipp, hier mal ein Ansatz, allerdings funktioniert das leider nicht so wie gedacht.
Mein Ziel, ist ja, das ich in einem Zeitraum z.b. 8:00 bis 20:00 die Leds einschalten moechte.

Code: Alles auswählen

#!/usr/bin/env python3
import time
from datetime import datetime
import datetime

ANFANG="08:00"
ENDE="20:00"

def zeitraum(START,END):
    now = datetime.datetime.now()
    if now.strftime("%H:%M") >= START and now.strftime("%H:%M") <= END:
       print("True")
       return True
    else:
       print("False")
       return False
    time.sleep(10)
    print("time:", now.strftime("%H:%M"))


while zeitraum(ANFANG,ENDE):
    print("Programm ist aktiv")
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Statt mit strings zu vergleichen benutzt man auch dafür datetime Objekte. Mit zwei datetime.time Objekten für deine Zeitspanne, und mit der combine-Methode von datetime.datetime erzeugt man sich tagesaktuelle Zeitstempel zum vergleich.
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

Hi irgendwie finde ich keinen Ansatz zum Programmieren.

target1 = datetime.time(00,23)
now = datetime.time()

if now <= target1:

Kannst du mir ein Beispiel Code zeigen. Wie kann ich eine Variable i(Zeitbereich z.b. 8-20) in die Abfrage mit einbauen, und dabei noch das Datum zu berücksichtigen..
Benutzeravatar
ThomasL
User
Beiträge: 1372
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Den Ansatz habe ich mit der Methode combine doch erwähnt. Ich sehen nicht, dass du dem folgst.
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

[/code]Ok, ich habe es jetzt hinbekommen, gibt es noch eine Möglichkeit das ich die Uhrzeit als konstante zu Programm Anfang hinterlegen kann? Das wäre komfortabler falls ich die Uhrzeit anpassen möchte

Hier meine Programmteilen

Code: Alles auswählen

#!/usr/bin/env python3
import time
from datetime import datetime
import datetime

#ANFANG="07:00"
#ENDE=19,35

def zeitraum():
    if now >= target1 and now <= target2:
        print("True")
        return True
    else:
       print("False")
       return False

while True:
  now = datetime.datetime.now()
  target1 = datetime.datetime.now()
  target2 = datetime.datetime.now()
  target1 = datetime.datetime.combine(target1,datetime.time(6,35))
  target2 = datetime.datetime.combine(target2,datetime.time(6,48))
  time.sleep(1)
  zeitraum ()
  print("now", now.strftime("%H:%M"))
  print("target1", target1.strftime("%H:%M"))
  print("target2", target2.strftime("%H:%M"))
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Schön, dass es geklappt hat. Und

Code: Alles auswählen

START = datetime.time(6,35)
ist die Konstante.
Antworten