Siebensegmentanzeige im Multiplexbetrieb flackert

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

@Dusty: man benutzt keine globalen Variablen. Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht mal 4, mal 3 und mal nur 2.
Du importierst datetime aus datetime, überschreibst aber diese Namen sofort wieder durch das Modul datetime. Was soll da der erste Import?
Warum rufst Du drei mal datetime.datetime.now auf?
Mit dem Rückgabewert von zeitraum wird gar nichts gemacht!

Code: Alles auswählen

import time
import datetime

START_TIME = datetime.time(6,35)
END_TIME = datetime.time(6,48)

def is_active_time():
    now = datetime.datetime.now()
    start_date = datetime.datetime.combine(now, START_TIME)
    end_date = datetime.datetime.combine(now, END_TIME)
    print(f"now: {now:%H:%M}")
    print(f"target1: {start_date:%H:%M}")
    print(f"target2: {end_date:%H:%M}")
    return start_date <= now <= end_date

while True:
    time.sleep(1)
    print(is_active_time())
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

jetzt habe ich das in mein Programm eingebaut, leider funktioniert das Ausschalten der LEd s nicht , irgendwo habe ich noch einen Denkfehler...koennt ihr nochmal drueber schaun, vorab vielen Dank

hier meine Programmzeilen....

Code: Alles auswählen


START_TIME=datetime.time(4,35)
END_TIME=datetime.time(5,57)

.....

def zeitraum():
    now = datetime.datetime.now()
    time.sleep(1)
    start_date = datetime.datetime.combine(now, START_TIME)
    end_date = datetime.datetime.combine(now, END_TIME) 
    if now >= start_date and now <= end_date:
        return True
    else:
        return False


def main():
    try:
        initialize()
        while True:
                try:
                    if zeitraum():
                        show_value()
                    else:
                        print("off")
                except Exception as error:
                    print(error)
                #time.sleep(1)
    except KeyboardInterrupt:
        pass
    finally:
        GPIO.cleanup()


if __name__ == "__main__":
    main()
    


Benutzeravatar
Dennis89
User
Beiträge: 1156
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,
was funktioniert denn nicht? Das hier ist doch dein Code und der gibt mir 'on' und 'off' abhängig von deinem Zeitraum aus.

Code: Alles auswählen

from datetime import datetime, time
from time import sleep

START_TIME = time(6, 30)
END_TIME = time(6, 33)


def zeitraum():
    now = datetime.now()
    sleep(1)
    start_date = datetime.combine(now, START_TIME)
    end_date = datetime.combine(now, END_TIME)
    if now >= start_date and now <= end_date:
        return True
    else:
        return False


def main():
    try:
        while True:
            try:
                if zeitraum():
                    print("on")
                else:
                    print("off")
                sleep(1)
            except Exception as error:
                print(error)
    except KeyboardInterrupt:
        pass
    finally:
        print("Bye")


if __name__ == "__main__":
    main()
Grüße
Dennis

Edit: Vielleicht hast du einen Fehler in 'initialize'?
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Warum ist in dem Code denn ein sleep(1)?
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

@Dusty: wie soll man bei dem unvollständigen Code sagen können, warum Deine LEDs nicht ausgeschaltet werden?
Ganz einfach, weil im gesamten Code keine LEDs angesprochen werden.

Das sleep hat in `zeitraum` nichts zu suchen und die if-Konstruktion ist viel zu kompliziert, wenn es ein einfaches `return` der Bedingung auch tun würde.
Benutzeravatar
__blackjack__
User
Beiträge: 13111
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Dusty: sparrow meint sicher das `sleep()` in `zeitraum()`. Eine Funktion sollte nur eine Sache tun, und bei einem Test auf einen Zeitraum erwartet der Leser nicht, das die Funktion nicht einfach nur so schnell wie möglich testet, sondern auch noch künstlich länger braucht.

Statt zwei Vergleiche gegen den selben Wert mit ``and`` zu verknüpfen, ist es kürzer und leichter lesbar, wenn man die Vergleichsoperatoren verkettet.

Wenn man literale Wahrheitswerte in ``if`` und ``else`` zurück gibt (oder dem gleichen Namen zuweist), dann ist das ``if``/``else``-Konstrukt überflüssig, denn die ``if``-Bedingung ergibt ja schon einen Wahrheitswert den man entweder direkt verwenden kann, oder mit ``not`` negieren kann, falls man das Gegenteil von dem Ergebnis braucht.

Ungetestet:

Code: Alles auswählen

def zeitraum():
    now = datetime.datetime.now()
    start_date = datetime.datetime.combine(now, START_TIME)
    end_date = datetime.datetime.combine(now, END_TIME) 
    return start_date <= now <= end_date
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

[/code]Hallo, erstmal vielen Dank für die Kommentare. Alles richtig und habe verstanden, aber trotzdem wird nachdem ich die zeitgrenzen gesetzt habe, nicht die die Schleife unterbrochen, bzw led ausgeschaltet.

Hier mein gesamt Code

Code: Alles auswählen

 #!/usr/bin/env python3
import datetime
import time
import snap7
from RPi import GPIO

ADDRESS_TEMPERATURE_POOL = "VW1118"
ADDRESS_TEMPERATURE_AUSSEN = "VW1120"
DELAY_TIME = 0.003

START_TIME=datetime.time(4,35)
END_TIME=datetime.time(19,43)

# kontrolliert Programm beenden mit ctrl + c
# python /home/pi/Desktop/finale/masterpool.py
# Pinbelegung raspberry
# led segmente pi 4B
# a=4, b=27, c=22, d=5, e=6, f=26, g=23, point=24
# lede module
# digit1=12,digit2=13,digit3=20,digit4=19,

SEGMENT_PINS = (4, 27, 22, 5, 6, 26, 23, 24)
DIGIT_PINS = (12, 13, 20, 19)

DIGITS = {
    " ": [0, 0, 0, 0, 0, 0, 0],
    "0": [1, 1, 1, 1, 1, 1, 0],
    "1": [0, 1, 1, 0, 0, 0, 0],
    "2": [1, 1, 0, 1, 1, 0, 1],
    "3": [1, 1, 1, 1, 0, 0, 1],
    "4": [0, 1, 1, 0, 0, 1, 1],
    "5": [1, 0, 1, 1, 0, 1, 1],
    "6": [1, 0, 1, 1, 1, 1, 1],
    "7": [1, 1, 1, 0, 0, 0, 0],
    "8": [1, 1, 1, 1, 1, 1, 1],
    "9": [1, 1, 1, 1, 0, 1, 1],
    "o": [1, 0, 0, 0, 0, 1, 1],  # Gradsymbol
    "-": [0, 0, 0, 0, 0, 0, 1],
}


def initialize():
    GPIO.setmode(GPIO.BCM)
    for pin in SEGMENT_PINS + DIGIT_PINS:
        GPIO.setup(pin, GPIO.OUT)
        GPIO.output(pin, 0)


def print_segment(digit_pin, character, point=False):
    GPIO.output(digit_pin, 1)  # Turn on Digit
    for pin, value in zip(SEGMENT_PINS, DIGITS[character]):
        GPIO.output(pin, value)
    GPIO.output(SEGMENT_PINS[-1], point)  # Display point?
    time.sleep(DELAY_TIME)
    GPIO.output(digit_pin, 0)


def print_digits(text, point_pin=0):
    for pin, character in zip(DIGIT_PINS, text):
        print_segment(pin, character, pin == point_pin)

def print_temperature(temperature, station):
    if temperature is None:
        print("Kein Wert", temperature)
        point_pin = 0
        temperature = "----"
    else:
        #print(station, "=", temperature/10)
        temperature = f'{temperature*0.1:4.1f}o'.replace('.','')
        if len(temperature) > 4:
            point_pin = 0
            temperature = temperature[:3] + 'o'
        else:
            point_pin = DIGIT_PINS[1]
    print_digits(temperature, point_pin)


def print_zeit():
    now = datetime.datetime.now()
    #print("time:", now.strftime("%H:%M"))
    print_digits(now.strftime("%H%M"), DIGIT_PINS[1])
    print_digits(now.strftime("%H%M"), DIGIT_PINS[2])

def show_value():
    try:
        plc = snap7.logo.Logo()
        plc.connect("192.168.178.6", 1118, 1245)
        plc.get_connected()

        while True:
            start = time.monotonic()
            TEMP1=plc.read(ADDRESS_TEMPERATURE_POOL)
            TEMP2=plc.read(ADDRESS_TEMPERATURE_AUSSEN)

            while time.monotonic() - start < 10.3:
                print_zeit()
            while time.monotonic() - start < 20.6:
                #temperatur = plc.read(ADDRESS_TEMPERATURE_POOL)
                print_temperature(TEMP1, "Temp. Pool")
            while time.monotonic() - start < 30.9:
                #temperatur = plc.read(ADDRESS_TEMPERATURE_AUSSEN)
                print_temperature(TEMP2, "Temp. Außen")
    finally:
        plc.disconnect()
        plc.destroy()

def zeitraum():
    now = datetime.datetime.now()
    start_date = datetime.datetime.combine(now, START_TIME)
    end_date = datetime.datetime.combine(now, END_TIME)
    return start_date <= now <= end_date


def digit_aus():
    GPIO.output(19, 0) #Turn off Digit One
    GPIO.output(12, 0) #Turn on Digit One
    GPIO.output(13, 0) #Turn on Digit One
    GPIO.output(20, 0) #Turn on Digit One
    GPIO.output(24, 0) #Turn on Digit One

def main():
    try:
        initialize()
        while True:
                try:
                    if zeitraum():
                        show_value()
                    else:
                        print("off")
                        digit_aus()
                except Exception as error:
                    print(error)
                #time.sleep(1)
    except KeyboardInterrupt:
        pass
    finally:
        GPIO.cleanup()


if __name__ == "__main__":
    main()
    
Benutzeravatar
Dennis89
User
Beiträge: 1156
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

möglich das du in der 'while'-Schleife von 'show_value' festhängst?

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

Natürlich wird die Schleife nicht unterbrochen, weil Du dafür auch keinen Code geschrieben hast.
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

ich will ja in der schleife bleiben, da ich in dieser schleife die 3 fach LED Anzeige Zeit/Temp1 und Temp2 sequenziell anzeigen möchte, aber eben nur anzeigen wenn der definierte Zeitbereich erreicht ist, und das soll sich jeden Tag wiederholen...
Benutzeravatar
Dennis89
User
Beiträge: 1156
Registriert: Freitag 11. Dezember 2020, 15:13

Dann musst du aber zwingend in der Schleife eine Bedingung einbauen, damit du die wieder verlassen kannst. Solange die Schleife läuft passiert nichts anderes.

Du kannst auch die Schleife sein lassen und in einem Intervall immer eine Funktion aufrufen, solange du in deinem Zeitfenster bist.
https://schedule.readthedocs.io/en/stab ... ation.html



Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

jetzt habe ich es auch geschnallt, ich war in der falschen Schleife unterwegs.

Mit Anpassung in der richtigen Schleife, macht’s das Programm genau das was ich möchte, Euch vielen Dank für die Hinweise… VG Steffen

Code: Alles auswählen

 def show_value():
    try:
        plc = snap7.logo.Logo()
        plc.connect("192.168.178.6", 1118, 1245)
        plc.get_connected()

        while zeitraum():
            start = time.monotonic()
            TEMP1=plc.read(ADDRESS_TEMPERATURE_POOL)
            TEMP2=plc.read(ADDRESS_TEMPERATURE_AUSSEN)

            while time.monotonic() - start < 10.3:
                print_zeit()
            while time.monotonic() - start < 20.6:
                #temperatur = plc.read(ADDRESS_TEMPERATURE_POOL)
                print_temperature(TEMP1, "Temp. Pool")
            while time.monotonic() - start < 30.9:
                #temperatur = plc.read(ADDRESS_TEMPERATURE_AUSSEN)
                print_temperature(TEMP2, "Temp. Außen")
        digit_aus()
    finally:
        plc.disconnect()
        plc.destroy()
        
        
        
Antworten