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,

Ich habe im multiplexerbetrieb 4 siebensegmentanzeigen, gesteuert über Raspery pi laufen. Hierüber habe ich 3 Anzeigen im Wechsel von jeweils 10 Sekunden (uhrzeit, Temperatur 1 und Temperatur 2.

Die Ansteuerung erfolgt über 2 Bausteine, einmal um die sieben Segmente einzuschalten, sowie die 4 LED Module seriel in einer hohen Taktung anzusteuern.

Das ganze habe ich in Python über While schleifen realisiert, funktioniert auch soweit.
Allerdings fängt nach einiger Zeit ,ca 30 Minuten ,die Anzeige zu blinken an.
Meine Frage, wie kann ich den schleifendurchlauf dahin kontrollieren, das ein synchronisieren der schleifenzeit stattfindet. Oder wenn ich merke das ein Blinken Eintritt, das Programm von Neuem starte.
Vorab vielen Dank für einen Rat.
VG
Steffen

Ein Auszug aus meinem Programm

while 1:
t1 = datetime.datetime.now()
now = datetime.datetime.now()
while (datetime.datetime.now()-t1).seconds <= 10:
print_Zeit()
t2 = datetime.datetime.now()
now = datetime.datetime.now()
werth = str(plc.read(AdrLogo_Temp_pool))
while (datetime.datetime.now()-t2).seconds <= 10:
print_Temperatur(werth,"Temp. Pool")
t3 = datetime.datetime.now()
now = datetime.datetime.now()
werte = str(plc.read(AdrLogo_Temp_aussen))
while (datetime.datetime.now()-t3).seconds <= 10:
print_Temperatur(werte,"Temp. Außen")
digit_aus()
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

Sorry die Formatierung hat es mir zerlegt, entsprechend ist while1 die endlosscheife, die anderen 3 schleifen, laufen jeweils 10 Sekunden seriell
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

1 ist kein Ersatz für True. Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht mal 3 und mal 4.
Variablennamen und Funktionen werden komplett klein geschrieben.
Man benutzt keine Abkürzungen. Was soll ein AdrLogo_Temp_pool sein? Oder ein werth?
`datetime`-Objekte sind dann sinnvoll, wenn man wirklich ein Datum haben möchte. Für`s Sekundenzählen benutzt man time.monotonic.
print_Zeit, print_Temperatur und digit_aus sind nicht definiert. Man kann also auch nicht sagen, warum bei Dir irgendetwas blinkt.
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

Ich lese die Temperaturdaten aus der SiemensLogo, die IP dazu ist im String hinterlegt. In Die Variable werth, lese ich den Temperaturwert 1 ein. Die Funktionen Print Zeit/Temperatur lesen jeweils den Wert und steuern die siebensegmentanzeige an um den Wert darzustellen.
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

Vielen Dank noch mal, mit perf_counter() habe ich immer das gleiche Zeitraster in der Schleife laufen, so das die Anzeige nicht mehr flackert. vG Steffen
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

Hi Sirius3,

ich habe das ausprobiert, das Programm funktioniert. Jedoch fängt nach einiger Zeit die Ausgabewerte nicht anzuzeigen.
Das programm soll ja in einem 10 Sekundenraster jeweils die Systemzeit, Temperatur1 und Temperatur 2, seriel anzeigen.
Die Tempwerte lese ich über die siemens Logo aus, wie oben beschrieben und zeige im Multiplexbetrieb die Werte auf 4 LED-Module an.

Vielleicht hast du oder noch jemand anders ein Tipp für mich, wie ich den Schleifenablauf synchronisieren kann, falls die Anzeigewerte wieder ausbleiben.
Da die Systemanzeige ebenfalls nach einiger Zeit nicht dargestellt wird, glaube ich nicht das es was mit der Logoanbindung zu tun hat, aber genau weiss ich das nicht.

Schonmal vorab vielen Dank.

Hier mein kompletter Code:

[

Code: Alles auswählen

code]#!/usr/bin/env pythoimport osn3
import RPi.GPIO as GPIO
import time, datetime
import string
import snap7
import sys
import os

ADDRESS_TEMPERATURE_POOL = "VW1118"
ADDRESS_TEMPERATURE_AUSSEN = "VW1120"
delay_time = 0.005

# 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,

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)

segment8 =  (4,27,22,5,6,26,23,24)

for segment in segment8:
    GPIO.setup(segment, GPIO.OUT)
    GPIO.output(segment, 0)
    #Digit 1
    GPIO.setup(12, GPIO.OUT)
    GPIO.output(12, 0) #Off initially
    #Digit 2
    GPIO.setup(13, GPIO.OUT)
    GPIO.output(13, 0) #Off initially
    #Digit 3
    GPIO.setup(20, GPIO.OUT)
    GPIO.output(20, 0) #Off initially
    #Digit 4
    GPIO.setup(19, GPIO.OUT)
    GPIO.output(19, 0) #Off initially

null = [0,0,0,0,0,0,0]
zero = [1,1,1,1,1,1,0]
one = [0,1,1,0,0,0,0]
two = [1,1,0,1,1,0,1]
three = [1,1,1,1,0,0,1]
four = [0,1,1,0,0,1,1]
five = [1,0,1,1,0,1,1]
six = [1,0,1,1,1,1,1]
seven = [1,1,1,0,0,0,0]
eight = [1,1,1,1,1,1,1]
nine = [1,1,1,1,0,1,1]
ten = [1,0,0,0,0,1,1]
eleven = [0,0,0,0,0,0,1]



def print_segment(charector):
    if charector == "1":
        for i in range(7):
            GPIO.output(segment8[i], one[i])

    if charector == "2":
        for i in range(7):
            GPIO.output(segment8[i], two[i])

    if charector == "3":
        for i in range(7):
            GPIO.output(segment8[i], three[i])

    if charector == "4":
        for i in range(7):
            GPIO.output(segment8[i], four[i])

    if charector == "5":
        for i in range(7):
            GPIO.output(segment8[i], five[i])

    if charector == "6":
        for i in range(7):
            GPIO.output(segment8[i], six[i])

    if charector == "7":
        for i in range(7):
            GPIO.output(segment8[i], seven[i])

    if charector == "8":
        for i in range(7):
            GPIO.output(segment8[i], eight[i])

    if charector == "9":
        for i in range(7):
            GPIO.output(segment8[i], nine[i])

    if charector == "0":
        for i in range(7):
            GPIO.output(segment8[i], zero[i])

    if charector == 10:  #Gradsymbol
        for i in range(7):
            GPIO.output(segment8[i], ten[i])

    if charector == " ":  #Space
        for i in range(7):
            GPIO.output(segment8[i], null[i])

    if charector == "-":  #minus zeichen
        for i in range(7):
            GPIO.output(segment8[i],eleven[i])

    return;


def print_temperatur(temp,station):
    if not temp:
        print("Kein Wert",temp)
    else:
        print(station,"=",temp)
    #time.sleep(10)
    if temp.count("-") == 1:
    #lese Temperatur aus Logo ohne komma
        GPIO.output(12,1) #Turn on Digit One
        print_segment(str(temp[0])) #Print h1 on segment
        time.sleep(delay_time)
        GPIO.output(12,0) #Turn on Digit One

        if len(temp) == 4:
            GPIO.output(13,1) #Turn on Digit One
            print_segment(str(temp[1])) #Print h1 on segment
        #GPIO.output(24,1) #Display point On
            time.sleep(delay_time)
        #GPIO.output(24,0) #Display point Off
            GPIO.output(13,0) #Turn off Digit One

            GPIO.output(20,1) #Turn on Digit One
            print_segment(str(temp[2])) #Print h1 on segment
            time.sleep(delay_time)
            GPIO.output(20,0) #Turn on Digit One

        if len(temp) == 3:
            GPIO.output(13,1) #Turn on Digit One
            print_segment(str(temp[1])) #Print h1 on segment
            GPIO.output(24,1) #Display point On
            time.sleep(delay_time)
            GPIO.output(24,0) #Display point Off
            GPIO.output(13,0) #Turn off Digit One

            GPIO.output(20,1) #Turn on Digit One
            print_segment(str(temp[2])) #Print h1 on segment
            time.sleep(delay_time)
            GPIO.output(20,0) #Turn on Digit One

        if len(temp) == 2:
            GPIO.output(13,1) #Turn on Digit One
            print_segment(str(0)) #Print h1 on segmen
            GPIO.output(24,1) #Display point On
            time.sleep(delay_time)
            GPIO.output(24,0) #Display point Off
            GPIO.output(13,0) #Turn off Digit One

            GPIO.output(20,1) #Turn on Digit One
            print_segment(str(temp[1])) #Print h1 on segment
            time.sleep(delay_time)
            GPIO.output(20,0) #Turn on Digit One

        GPIO.output(19,1) #Turn on Digit One
        print_segment(10) #Print h1 on segment
        time.sleep(delay_time)
        GPIO.output(19,0) #Turn on Digit One
        digit_aus()

    else:
        if len(temp) == 3:
            GPIO.output(12,1) #Turn on Digit One
            print_segment(str(temp[0])) #Print h1 on segment
            time.sleep(delay_time)
            GPIO.output(12,0) #Turn on Digit One

            GPIO.output(13,1) #Turn on Digit One
            print_segment(str(temp[1])) #Print h1 on segment
            GPIO.output(24,1) #Display point On
            time.sleep(delay_time)
            GPIO.output(24,0) #Display point Off
            GPIO.output(13,0) #Turn off Digit One

            GPIO.output(20,1) #Turn on Digit One
            print_segment(str(temp[2])) #Print h1 on segment
            time.sleep(delay_time)
            GPIO.output(20,0) #Turn on Digit One

        if len(temp) == 2:
            GPIO.output(13,1) #Turn on Digit One
            print_segment(str(temp[0])) #Print h1 on segment
            GPIO.output(24,1) #Display point On
            time.sleep(delay_time)
            GPIO.output(24,0) #Display point Off
            GPIO.output(13,0) #Turn on Digit One

            GPIO.output(20,1) #Turn on Digit One
            print_segment(str(temp[1])) #Print h1 on segment
            time.sleep(delay_time)
            GPIO.output(20,0) #Turn on Digit One

        if len(temp) == 1:
            GPIO.output(13,1) #Turn on Digit One
            print_segment(str(0)) #Print h1 on segment
            GPIO.output(24,1) #Display point On
            time.sleep(delay_time)
            GPIO.output(24,0) #Display point Off
            GPIO.output(13,0) #Turn on Digit One

            GPIO.output(20,1) #Turn on Digit One
            print_segment(str(temp[0])) #Print h1 on segment
            time.sleep(delay_time)
            GPIO.output(20,0) #Turn on Digit One

        GPIO.output(19,1) #Turn on Digit One
        print_segment(10) #Print h1 on segment
        time.sleep(delay_time)
        GPIO.output(19,0) #Turn on Digit One
        digit_aus()


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) #Tur


def print_zeit():
    now = datetime.datetime.now()
    hour = now.hour
    minute = now.minute
    hour = now.strftime("%H")
    minute = now.strftime("%M")
    h1 = str(int(hour[0:1]))
    h2 = str(int(hour[1:2]))
    m1 = str(int(minute[0:1]))
    m2 = str(int(minute[1:2]))

    print ("time:", now.strftime("%H:%M"))
    #delay_time = 0.001 #delay to create virtual effect
    GPIO.output(12, 1) #Turn on Digit One
    print_segment(h1) #Print h1 on segment
    time.sleep(delay_time)
    GPIO.output(12, 0) #Turn off Digit One

    GPIO.output(13, 1) #Turn on Digit One
    print_segment(h2) #Print h1 on segment
    GPIO.output(24, 1) #Display point On
    time.sleep(delay_time)
    GPIO.output(24, 0) #Display point Off
    GPIO.output(13, 0) #Turn off Digit One

    GPIO.output(20, 1) #Turn on Digit One
    print_segment(m1) #Print h1 on segment
    GPIO.output(24, 1) #Display point On
    time.sleep(delay_time)
    GPIO.output(24, 0) #Display point Off
    GPIO.output(20, 0) #Turn off Digit One

    GPIO.output(19, 1) #Turn on Digit One
    print_segment(m2) #Print h1 on segment
    time.sleep(delay_time)
    digit_aus()

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

         while True:
             start = time.monotonic()
             while (round((time.monotonic() - start),1) < (10.3)):
                 print_zeit()
             start = time.monotonic()
             temperatur = str(plc.read(ADDRESS_TEMPERATURE_POOL))
            #print("na")
             while (round((time.monotonic() - start),1) < (10.3)):
                 if not temperatur:
                     print_temperatur("---- Temp. Pool")
                 else:
                     print_temperatur(temperatur, "Temp. Pool")
             start = time.monotonic()
             temperatur = str(plc.read(ADDRESS_TEMPERATURE_AUSSEN))
            #print("und")
             while round((time.monotonic() - start),1) < (10.3):
                 if not temperatur:
                     print_temperatur("---- Temp. Außen")
                 else:
                     print_temperatur(temperatur, "Temp. Außen")
    finally:
        digit_aus()
        plc.disconnect()
        plc.destroy()


def main():
    while True:
        try:
            do_loop()
        except KeyboardInterrupt:
            break
        except Exception as error:
            print(error)

if __name__ == "__main__":
    main()
[/code]
Benutzeravatar
sparrow
User
Beiträge: 4165
Registriert: Freitag 17. April 2009, 10:28

Ohjeh.

Ich bin mir ziemlich sicher, dass dein Fehlerhandling falsch ist.
Und auch, dass `GPIO.setwarnings(False)` falsch ist, weil du damit Warnungen unterdrückst. Du solltest lieber Abstellen, was die Warnungen auslöst.
Leider bein ich in der Pin-Geschichte nicht tief genug drin um dir zu sagen, was genau du da falsch machst, aber ich nehme an, dass du die Pins zwar initialisierst, aber nirgends mehr frei gibst, nachdem das Programm beendet wurde.

Dann hast du unglaublich viel Redundanz in deinem Programm.
Ich habe angefangen das aufzuräumen. Du ist jetzt eine `print_on_display`-Funktion. Die erwartet eine Zeichenkette mit max. 4 Zeichen zur Anzeige.
Das ist ein ungestester Zwischenstand.

Code: Alles auswählen

#!/usr/bin/env pythoimport osn3
import RPi.GPIO as GPIO
import time, datetime
import snap7

ADDRESS_TEMPERATURE_POOL = "VW1118"
ADDRESS_TEMPERATURE_AUSSEN = "VW1120"
DELAY_TIME = 0.005

# 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,

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)

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

CHARS = {
    "0": [0,0,0,0,0,0,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],
    "°": [1,0,0,0,0,1,1],
    "-": [0,0,0,0,0,0,1],
    " ": [1,1,1,1,1,1,0],
}

for segment in SEGMENT_PARTS:
    GPIO.setup(segment, GPIO.OUT)
    GPIO.output(segment, 0)
    for digit_pin in DIGIT_PINS:
        GPIO.setup(digit_pin, GPIO.OUT)
        GPIO.output(digit_pin, 0) #Off initially


def print_on_display(chars):
    if len(chars) > len(DIGIT_PINS):
        raise ValueError(f"Can only display <= {len(DIGIT_PINS)} characters")
    for char, pin in zip(chars.rjust(4, " "), DIGIT_PINS):
        GPIO.output(pin, 1)
        for segment, flag in zip(SEGMENT_PARTS[:7], CHARS[char]):
            GPIO.output(segment, flag)
        GPIO.output(24,1) #Display point On
        time.sleep(DELAY_TIME)
        GPIO.output(24,0) #Display point Off
        GPIO.output(pin, 0)


def print_temperatur(temp,station):
    if not temp:
        print("Kein Wert",temp)
    else:
        print(station,"=",temp)
    print_on_display(f"{temp}°")


def print_zeit():
    now = datetime.datetime.now()
    print("time:", now.strftime("%H:%M"))
    print_on_display(now.strftime("%H%M"))


def digit_aus():
    GPIO.output(19, 0)
    GPIO.output(12, 0)
    GPIO.output(13, 0)
    GPIO.output(20, 0)
    GPIO.output(24, 0)


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

         while True:
             start = time.monotonic()
             while (round((time.monotonic() - start),1) < (10.3)):
                 print_zeit()
             start = time.monotonic()
             temperatur = str(plc.read(ADDRESS_TEMPERATURE_POOL))
            #print("na")
             while (round((time.monotonic() - start),1) < (10.3)):
                 if not temperatur:
                     print_temperatur("---- Temp. Pool")
                 else:
                     print_temperatur(temperatur, "Temp. Pool")
             start = time.monotonic()
             temperatur = str(plc.read(ADDRESS_TEMPERATURE_AUSSEN))
            #print("und")
             while round((time.monotonic() - start),1) < (10.3):
                 if not temperatur:
                     print_temperatur("---- Temp. Außen")
                 else:
                     print_temperatur(temperatur, "Temp. Außen")
    finally:
        digit_aus()
        plc.disconnect()
        plc.destroy()


def main():
    while True:
        try:
            do_loop()
        except KeyboardInterrupt:
            break
        except Exception as error:
            print(error)

if __name__ == "__main__":
    main()
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

Hi erst mal vielen Dank, ich werde das ausprobieren.
Bzgl. Der Pins und Anzeige, es funktioniert, ich habe dazu eine Platine mit Sockel für 4 x LED Module und 2 Halbleiter Bausteine, die zum einen nacheinander die Segmente eines Modul s ansteuern und zum anderen die sequenziel die LED Module bestromen, im Multi Plexbrtrieb das klappt auch ganz gut, die Messwerte werden sauber da gestellt.

Leider eben nach ca. 30 Minuten kommt außer tritt, die zeitliche Umschaltung nach 10 Sekunden, Klappt aber weiterhin, bloß die Messwerte werden dann. Nicht mehr übertragen…
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

›as‹ bei ›import‹ ist zum umbenennen da, GPIO wird aber gar nicht umbenannt. Warum also das ›as‹?
›os‹, ›sys‹ und ›string‹ werden importiert, aber gar nicht benutzt.
Konstanten schreibt man KOMPLETT_GROSS. Für jede Pin-Nummer sollte es auch eine Konstante geben, denn DIGIT_ONE_PIN ist besser zu lesen als 12.
Warum werden die Pins 12, 13, 19 und 20 achtmal initialisiert? Das ist doch unsinn.
Statt zwölft Variablen für zwölf Digits, nimmt man eine Variable als Liste.
Man iteriert nicht über einen Index, sondern direkt über die Elemente, bei zwei Listen via ›zip‹.
Warum nennst Du das Minuszeichen ›eleven‹?
; wird nie verwendet, ein naktes ›return‹ am Ende einer Funktion ist überflüssig.
Benutze keine Abkürzungen, wenn Du ›temperature‹ meinst, dann schreib das auch.
Wenn man die selben Anweisungen immer wieder schreibt, dann ist das ein Fall für eine Funktion.
Die Kommentare sind zum Großteil falsch, weil sie nicht mit dem Code übereinstimmen, da stellt sich die Frage, was richtig ist, der Code oder der Kommentar?
Wenn Code sowohl im if-, als auch im else-Block vorkommt, kann man den auch einfach einmal danach schreiben. Wenn man prüfen will, ob das erste Zeichen ein "-" ist, dann benutzt man nicht count. In temp stehen bereits Strings, die nochmal per `str` umzuwandeln ist unsinn.
In `print_zeit` wird schließlich `hour` und `minute` zuerst mit Werten belegt, die dann gleich wieder überschrieben werden. h1, h2, m1 und m2 werden auf sehr komplizierte Art erzeugt, warum erst Zahlen in Strings umwandeln, die dann wieder in Zahlen und dann wieder in Strings? Mindestens zwei Umwandlungen sind überflüssig. Die Ausgabe läßt sich dann wieder stark vereinfachen.

`print_temperatur` erwartet zwei Argumente, bei Lesefehlern der Temperatur wird aber nur eins angegeben.

Code: Alles auswählen

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

ADDRESS_TEMPERATURE_POOL = "VW1118"
ADDRESS_TEMPERATURE_AUSSEN = "VW1120"
DELAY_TIME = 0.005

# 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, temperatur):
        print_segment(pin, character, pin==point_pin)


def print_temperature(temperature, station):
    if not temperature:
        print("Kein Wert", temperature)
        temperatur = "----"
        point_pin = 0
    else:
        print(station, "=", temperature)
        point_pin = DIGIT_PINS[2]
        if temperature.startswith("-"):
            if len(temperature) == 4:
                point_pin = 0
            temperature = temperature[1:3]
            temperature = "-00"[:-len(temperature)] + temperature + "o"
        else:
            temperature = " 00"[:-len(temperature)] + temperature + "o"
    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])


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

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


def main():
    while True:
        try:
            do_loop()
        except KeyboardInterrupt:
            break
        except Exception as error:
            print(error)

if __name__ == "__main__":
    main()
Am Programm kann ich nicht sehen, dass irgendwas nicht richtig funktioniert, außer dieses snap7, das ich nicht kenne.
Benutzeravatar
Dennis89
User
Beiträge: 1124
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

wenn man bei 'RPi' bleiben will, dann würde ich noch ein 'GPIO.cleanup' einbauen. So damit das immer vor dem Programmende aufgerufen wird. (Ich hoffe ich habs jetzt nicht übersehen)

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

@Dennis89: ja, da hab ich zum Schluß nicht mehr weiter gemacht:

Code: Alles auswählen

def main():
    while True:
        initialize()
        try:
            do_loop()
        except KeyboardInterrupt:
            break
        except Exception as error:
            print(error)
        finally:
            GPIO.cleanup()
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

Hi,

also der erste Versuch ging leider schief, siehe unten die Ausgabe in shell:
Die 10 Sekundenschleife bleibt bei der Zeitanzeige in einer Dauerschleife.
Noch ein Hinweis zur Temperatur.
Ich hatte deshalb in der Fkt Temperaturanzeige soviele ifs drinnen um die Wertanzeige richtig zu setzen, der Rohwert aus der Logo 1 -> wird 0.1 interpretiert, 0der 12 -> 1.2 , oder 234 -> 23.4
D.h. ein Rohwert von -23 -> -2.3 Wobei das 1 Digit immer - führt und das letzte Digit immer die Gradsymbolik.
SNAP7 wird von der Logo verwendet um auf die Speicherbereiche zugreifen zu können.

time: 21:15
name 'temperatur' is not defined
time: 21:15
name 'temperatur' is not defined
time: 21:15
name 'temperatur' is not defined

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

Hallo,

in Zeile 99 war ein Tippfehler, bei 'print_temperatur' fehlte eine 'e' am Schluss. In Zeile 59 gibt es kein 'temperatur', das Argument, dass die Temperatur (oder eine Zeit) in die Funktion reicht heißt 'text'. 'temperatur' aus Zeile 63 wird gar nicht benutzt.

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.005

# 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 not temperature:
        print("Kein Wert", temperature)
        point_pin = 0
    else:
        print(station, "=", temperature)
        point_pin = DIGIT_PINS[2]
        if temperature.startswith("-"):
            if len(temperature) == 4:
                point_pin = 0
            temperature = temperature[1:3]
            temperature = "-00"[: -len(temperature)] + temperature + "o"
        else:
            temperature = " 00"[: -len(temperature)] + temperature + "o"
    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])


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

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


def main():
    while True:
        initialize()
        try:
            do_loop()
        except KeyboardInterrupt:
            break
        except Exception as error:
            print(error)
        finally:
            GPIO.cleanup()


if __name__ == "__main__":
    main()
Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
sparrow
User
Beiträge: 4165
Registriert: Freitag 17. April 2009, 10:28

@Dusty: Ich werde aus deiner Erklärung nicht schlau. Bitte zeige entsprechende Beispiele, was in "print_temperature" als "temperature" eingehen kann und was du darstellen möchtest.

Ich bin mir sicher, dass man das viel kürzer und besser mit einfachen String-Operationen lösen kann als mit so einer if-Wand.
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

Ok ich versuche es zu beschreiben:
Der Temperatur rohwert von der Logo muss durch 10 geteilt werden, z.B. Logo wert von 1 , wird zu 0.1C auf LED Modul angezeigt. Dabei soll immer das 4. Ledmodul das gradsymbol sein, die 3 anderen led Module bilden den umgerechneten Temperaturwert ab. Wenn ein Komma notwendig ist, wird an dem Led Modul der Punkt noch mit angesteuert.
Wenn Minusgrad auftritt, wird das immer am 1. Ledmodul dargestellt.
Z.b -2 wird zu -0.2C. Oder -234 wird zu -23.4C

Bei der Uhrzeit werden Stunden in Ledmodule 1 u. 2 , Minuten auf Ledmodul 3 und 4 angezeigt.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Dusty: das wurde ja schon in Deinem Code klar, war nur eben ziemlich umständlich ausgedrückt. Auch jetzt noch ist die Logik in meinem `print_temperature` recht komplex.
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

Hi Dennis,

jetzt läuft es zumindest ein stück weiter, nach 10 Sekunden kommt kurz ein Temperaurwert, dann geht es weiter mit der Zeit weiter

VG
Steffen

anzeige in shell:
time: 20:32
time: 20:32
time: 20:32
Temp. Pool = 50
'int' object has no attribute 'startswith'
time: 20:32
Benutzeravatar
grubenfox
User
Beiträge: 413
Registriert: Freitag 2. Dezember 2022, 15:49

Keine Ahnung was das jetzt mit der ursprünglichen Frage zu tun hat, aber offenbar ist ` temperature` hier vom Typ 'int' und darum scheitert die Zeile mit dem ` if temperature.startswith("-"):`

Code: Alles auswählen

def print_temperature(temperature, station):
    if not temperature:
        print("Kein Wert", temperature)
        point_pin = 0
    else:
        print(station, "=", temperature)
        point_pin = DIGIT_PINS[2]
        if temperature.startswith("-"):
            if len(temperature) == 4:
                point_pin = 0
            temperature = temperature[1:3]
            temperature = "-00"[: -len(temperature)] + temperature + "o"
        else:
            temperature = " 00"[: -len(temperature)] + temperature + "o"
    print_digits(temperature, point_pin)
[/quote]
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Solangsam kommt raus, was Du eigentlich für Fehler hast. Die Temperatur ist eine Zahl und kein String. Warum das angeblich in Deinem ursprünglichen Code funktioniert hat, ist mir ein Rätsel.
Mit einer Zahl wird aber der Code deutlich lesbarer:

Code: Alles auswählen

def print_temperature(temperature, station):
    if temperature is None:
        print("Kein Wert", temperature)
        point_pin = 0
        temperature = "----"
    else:
        print(station, "=", temperature)
        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[2]
    print_digits(temperature, point_pin)
Dusty
User
Beiträge: 35
Registriert: Sonntag 19. März 2023, 08:22

Hi, jetzt schaut es gut aus, zumindest im kurztest funktioniert es ohne flackern...
vielen Dank für die tolle und kompetente Hilfe. VG Steffen
Antworten