Python2 /Python 3; Adafruit 16-Kanal PCA9685 und rpi-rf

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
mollyman
User
Beiträge: 27
Registriert: Samstag 24. Februar 2018, 12:10

Hallo zusammen

Ich habe in problem und komme damit nicht wirklich weiter.
Vermutlich ist es ein dumme Anfängerfrage.

Ich habe ein Programm geschrieben, wo ich mit dem Adafruit Board ein Servo Steuere (Adafruit 16-Kanal PCA9685 / https://pypi.python.org/pypi/Adafruit-PCA9685/1.0.1).
Das Programm ist mit Python 2 geschrieben und funktioniert recht gut.
Das ganze sollte über eine IR Remote gesteuert werdenn, das geht aber nicht weil sich die DTO von LIRC und dem Display beißen.
Daher habe ich umgeswitcht auf eine 433 mhz Remote (rpi-rf / https://github.com/milaq/rpi-rf/blob/master/README.rst).
Dummerweise scheint rpi-rf das einzige zu sein, wo ich nicht nur 1 oder 0 sondern wirklich den kompletten Code den die Remote sendet (16408), den ich dann vergleichhen kann, damit das Programm auch nur auf das Signal reagiert.
Jetzt funktioniert rpi-rf sehr gut, ist aber python3.
Die Frage ist jetzt, wie bekomme ich das gelöst. Kann ich das adafruit auf Python3 heben ? Mit google habe ich dazu ichts gefunden.
Kann ich rpi-rf auf Python2 runter bekommen ?
Hat hier einer eine Idee ?

Dake im voraus
Martin
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Der Adafruit Code sollte auch für Python3 funktionieren. Einfach mal mit pip3 bzw Python3 -m ‘pip’ probieren.
mollyman
User
Beiträge: 27
Registriert: Samstag 24. Februar 2018, 12:10

Super Danke

das hat mir geholfen.

Grundsätzlich laufen jetzt alleElemente, aber irgendwie habe ich noch ein problem mit den Threads.

Vielleicht kannst du mir da auch noch kurz helfen.

Grundsätzlich möchte ich mit 3 Threads arbeiten
Thread 1 (Main) -> die GUI
Thread 2 die Überwachung des 433 MHz empfängers
Thread 3 die eigentliche Ausführung des Programms
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mir fehlt da jetzt etwas die Frage :K machen kann man das, ob’s sinnvoll ist kommt auf die Aufgabe an.
mollyman
User
Beiträge: 27
Registriert: Samstag 24. Februar 2018, 12:10

Sorry

ich bin dabei aufgehalten worden.

hier der Rest des Posts

Nach aufruf des rpi-rf scriptes läuft das Script aber die GUI startet nicht
eigentlich sollte der rpi-rf als seperater Thread wie ein Interrup arbeiten:

Code: Alles auswählen

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import tkinter as tk
import Adafruit_PCA9685
import time
import RPi.GPIO as GPIO
import os
import pygame
import _thread
import alsaaudio
import argparse
import signal
import sys
import logging

from rpi_rf import RFDevice
from tkinter import *
..

# I2C Board für Servo
pwm = Adafruit_PCA9685.PCA9685(address=0x40) # I2C Board-Adresse
pwm.set_pwm_freq(50) # Festlegung der Frequenz

...

def exithandler(signal, frame): # Teil des 433 Mhz Prozess Skriptes
    rfdevice.cleanup()
    sys.exit(0)

def receive():
    logging.basicConfig(level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S',
                    format='%(asctime)-15s - [%(levelname)s] %(module)s: %(message)s', )
 
    parser = argparse.ArgumentParser(description='Receives a decimal code via a 433/315MHz GPIO device')
    parser.add_argument('-g', dest='gpio', type=int, default=27,
                    help="GPIO pin (Default: 27)")
    args = parser.parse_args()
 
    signal.signal(signal.SIGINT, exithandler)
    rfdevice = RFDevice(args.gpio)
    rfdevice.enable_rx()
    timestamp = None
    #logging.info("Listening for codes on GPIO " + str(args.gpio))
    while True:
        if rfdevice.rx_code_timestamp != timestamp:
            timestamp = rfdevice.rx_code_timestamp
            #print (str(rfdevice.rx_code))
            rec_num = (str(rfdevice.rx_code))
            compare(rec_num)
            #logging.info(str(rfdevice.rx_code)) # + " [pulselength " + str(rfdevice.rx_pulselength) +", protocol " + str(rfdevice.rx_proto) + "]")
        time.sleep(0.01)
    rfdevice.cleanup()

def compare(recive_number):
    if recive_number == "16404":
        print ("ok")
        start()
    return
    
...

def start():
    print (" start training prozess")
    _thread.start_new_thread(Training,(99,))
    return

def rf_modul():
    print (" start rf modul")
    _thread.start_new_thread(receive())
    return

...

def Training(a):
    if Modus == 1:
        ...
    return
   
def herunterfahren():
    GPIO.cleanup()
    os.system("sudo shutdown -h now")

     
def GUI():

...

    root.mainloop() # GUI wird upgedated. Danach keine Elemente setzen

    

buttonFrame = Frame(root, background="#58FA58")
buttonFrame.grid(row=0, column=0, padx=5, pady=5)        
...
rf_modul()
GUI()
derElch
User
Beiträge: 33
Registriert: Sonntag 25. Februar 2018, 13:14

mollyman hat geschrieben:Super Danke
...
Grundsätzlich möchte ich mit 3 Threads arbeiten
Thread 1 (Main) -> die GUI
Thread 2 die Überwachung des 433 MHz empfängers
Thread 3 die eigentliche Ausführung des Programms
Meine Frage: wäre es hier nicht sinnvoller mit Queues zu arbeiten anstatt mit Threads?
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

@mollyman: `_thread` ist nicht zur Benutzung gedacht, das sieht man am Unterstrich. `receive` enthält eine Endlosschleife, und keinen Rückgabewert. Signale sind noch schwieriger als Threads zu kontrollieren. Da Du sowieso nur Polls bist Du statt eines Threads, sowieso mit `after` besser bedient. `return` ohne Argument am Ende einer Funktion ist unnötig. Logging Initalisiert man am Anfang, genauso parst man Argumente gleich am Anfang des Programms. Sternchenimporte vermeiden. Die ganzen Auslassungspunkte machen das Verstehen auch nicht gerade einfach.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

derElch hat geschrieben:Meinte Frage: wäre es hier nicht sinnvoller mit Queues zu arbeiten anstatt mit Threads?
Das ist nicht statt, sondern nur MIT Threads sinnvoll. Wer befüllt die Queue, wenn nicht ein anderer Thread?
mollyman
User
Beiträge: 27
Registriert: Samstag 24. Februar 2018, 12:10

Sirius3 hat geschrieben:@mollyman: `_thread` ist nicht zur Benutzung gedacht, das sieht man am Unterstrich. `receive` enthält eine Endlosschleife, und keinen Rückgabewert. Signale sind noch schwieriger als Threads zu kontrollieren. Da Du sowieso nur Polls bist Du statt eines Threads, sowieso mit `after` besser bedient. `return` ohne Argument am Ende einer Funktion ist unnötig. Logging Initalisiert man am Anfang, genauso parst man Argumente gleich am Anfang des Programms. Sternchenimporte vermeiden. Die ganzen Auslassungspunkte machen das Verstehen auch nicht gerade einfach.
Danke für dein Feedback
das Programm hatte ich ursprünglich in python 2 geschrieben, musste jetzt in python3 wechseln. in 2 hatte da mitdem Threads an sich gut funktioniert, daher hatte ich es hier weiter genommen.

Receive soll iin einer Endlosschleife laufen und auch keine Rückgabe liefern, aber dieses parallel zur GUI.
Ich habe mir das After angesehen und verstehe nicht, wie es mir hier helfen kann, denn After kommt soweit ich es verstanden habe nach einem Event eines GUI Elements.
Das würde mir hier nicht helfen.
Die GU dient nur zur Konfig. Die Logik wird durch betätigendes Sender gestartet.
Wenn nicht von der Stanndard-Konfig abgewichen wird,würde ich nach meinem Verständnis von "after" die Logik nicht mit dem Sender starten können.

Die Receive Funktion ist mit Ausnahme der Ausgabe, die übernahme des receive-scriptes vom Modul rpi-rf. Ehrlich gesagt reicht mein Python nicht aus um es wirklich zu verstehen, was es genau macht.

das mit den Returns nehme ich raus. Wobei es beim Receive sinn macht, dass wenn der Punkt ok kommt der Logik Thread gestartet wird und der Receive Thread endet und am ende der Logik wieder startet, so vermeide ich chaos durch versehentliches doppelt drücken oder prellen des Senders.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

After ist ein timer Mechanismus. Damit kannst du periodisch Dinge tun, ohne dabei auf Threads zurückgreifen zu müssen. Und gleichzeitig die GUI lauffähig zu halten. Das ist also schon geeignet für dein Problem.

Wenn man sich das so anschaut, dann sieht das doch eher nach Frankenstein-Programmierung aus: Versatzstücke aus dem Netz geklaubt und mit grober Nadel aneinander genäht. Das wird bestenfalls wackelig funktionieren.

Was soll das denn mal können? Mir ist das immer noch unklar.
mollyman
User
Beiträge: 27
Registriert: Samstag 24. Februar 2018, 12:10

Hi

Ja ich bin sicher alles andere wie ein Programmierer und sicherlich nicht der, der richtig gut programmieren kann.
Dennoch verwahre ich mich, dass es ein zusammengeklaubter Code ist. einzig das recive Script ist übernommen, alles andere entstammt meiner mehr oder meist wohl weniger guten Feder.

Das ganze wird ein Trainingssystem für Schnellfeuer-Pistolen-Disziplinen.
Es geht darum, dass meine Tochter auch zuhause ohne Waffe trainieren kann. Die Scheibe und LED sind so, dass sie in 2 m Entfernung so groß sind, dass sie genauso-groß erscheinen, wie bei 25 m.
Dabei wird geschossen auf Klapp-scheiben bzw bei neuen elektronischen Anlagen auf feste Scheiben mit Lichtanzeigen, Dazu werden über einen Lautsprecher die Kommandos der Schießleitung ausgegeben.

Dieser Trainer kann beides, zum einen eine feststehende Scheibe mit LED Lampen bzw. über ein Servo wird die sich wegdrehende Scheibe realisiert
das ganze hat ein kleines Display wo eingestellt wird, ob es sich um Klapp oder Drehmodus, ob mit reduzierter Zeit oder welche Schnellfeuerdisziplin gerade trainiert werden soll. Meine Tochter stellt sich dann in 2 m Entfernung hin und hat eine Pistolen-Trainingsattrappe in der Hand und in der anderen Hand einen kleinen Handsender. mit dem startet sie dann in der Gui eingestellten Zyklus.
Normalerweise war das alles ohne den 433 MHz sender geplant und hatte auch mit einem Filediskriptor recht gut mit einer IR-Fernbediendung am Monitor funktioniert. Allerdings verträgt sich LIRC und das Display nicht daher musste ich dann wieder rückwärts gehen. ich hatte dann es versucht mit einer IR ohne Decode Funktion(LIRC) einfach nur als Flanke auf dem GPIO probiert, aber dann hat das Gerät auf alles mögliche reagiert.

Als Grundwerte sind in der Gui die Einstellungen hinterlegt, die am meisten relevant sind.
das bedeutet, dass es nicht immer Eingaben an der GUI gibt, bevor der Receive teil aktiv wird, bzw ich stelle auf der GUI ein und starte denn immer wieder den Trainingszyklus.

Ich habe das After so verstanden, dass nach dem etwas passiert ist wird etwas gestartet. also 100 ms nach dem ein Button gedrückt wurde wird ein Prozess über einen Callback gestartet.
Jetzt startet meine Tochter das gerät, die GUI zeigt die richtige Einstellung,somit wird nichts an der Gui gemacht, die den receive Prozess mit einem starten kann. Selbst wenn sie einen Button drückt muss sie ohne wieder zum Gerät zu müssen einen 2,3,4,5 usw Zyklus nur über den Handsender starten können. die Receive Schleife muss immer laufen sobald das gerät an ist, unabhängig davon, was auf der GUI passiert. einzige Ausnahme wäre die Zeit, während die Trainingsfunktion läuft, da sollte der Prozess nicht laufen.

hier der aktuelle komplette Code:

Code: Alles auswählen

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import tkinter as tk
import Adafruit_PCA9685
import time
import RPi.GPIO as GPIO
import os
import pygame
import _thread
import alsaaudio
import argparse
import signal
import sys
import logging

from rpi_rf import RFDevice
from tkinter import *

#GPIO für LED festlegen
GPIO.setwarnings(False) # Warnungen ausschalten
GPIO.setmode(GPIO.BCM) # Pin Nummern verwenden
GPIO.setup(6, GPIO.OUT) # Pin 31 als Output gruen
GPIO.setup(16, GPIO.OUT) # Pin 36 als Output rot
GPIO.setup(26, GPIO.OUT) # Pin 37 als Output gelb

# Variabelen festlegen
global Kom50, Wiederholungen, SchussZeit, AbzugZeit, Modus, Schieber

# Variabelen Werte zuweisen
SchussZeit = 3 # Dauer der Sichtbarkeit der Scheibe
AbzugZeit = 0 # Zeit um die die Sichtbarkeit der Scheibe reduziert wird
Kom50= 10 # Kommando 50 Reduziert die Zeit für das Laden der Waffe auf 10 Sekunden
Modus = 2 # 1 = Lichtmodus, 2 = Klappenmodus
Wiederholungen = 5 # Duell 5 Wiederholungen ( 1 Schuß pro aufklappen) alle anderen 1

# I2C Board für Servo
pwm = Adafruit_PCA9685.PCA9685(address=0x40) # I2C Board-Adresse
pwm.set_pwm_freq(50) # Festlegung der Frequenz

# Gui Grundlagen definieren
root = Tk() # Fenster erstellen
root.wm_title("Pistol Shoot Trainer") # Fenster Titel
#root.wm_attributes ('-fullscreen', 'true') # Vollbildmodus
root.wm_geometry('480x320+0+0')
root.config(background = "#FFFFFF") # Hintergrundfarbe des Fensters

def exithandler(signal, frame): # Teil des 433 Mhz Prozess Skriptes
    rfdevice.cleanup()
    sys.exit(0)

def receive():
    logging.basicConfig(level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S',
                    format='%(asctime)-15s - [%(levelname)s] %(module)s: %(message)s', )
 
    parser = argparse.ArgumentParser(description='Receives a decimal code via a 433/315MHz GPIO device')
    parser.add_argument('-g', dest='gpio', type=int, default=27,
                    help="GPIO pin (Default: 27)")
    args = parser.parse_args()
 
    signal.signal(signal.SIGINT, exithandler)
    rfdevice = RFDevice(args.gpio)
    rfdevice.enable_rx()
    timestamp = None
    while True:
        if rfdevice.rx_code_timestamp != timestamp:
            timestamp = rfdevice.rx_code_timestamp
            rec_num = (str(rfdevice.rx_code))
            if rec_num == "16404":
                start()
                return
        time.sleep(0.01)
    rfdevice.cleanup()

#Variabelen setzen für die Schusszeit und die Anzahl der Wiederholungen pro Magazin
def AchtSekunden():
    SchussZeit = 8
    Wiederholungen = 1 
     
def SechsSekunden():
    SchussZeit = 6
    Wiederholungen = 1 

def VierSekunden():
    SchussZeit = 4
    Wiederholungen = 1 

def ZehnSekunden():
    SchussZeit = 10
    Wiederholungen = 1 
     
def Duell():
    SchussZeit = 3
    Wiederholungen = 5

#Variabelen setzen für die Reduzierung der Schusszeit 
def AbzugOhne():
    AbzugZeit = 0
     
def Abzug01():
    AbzugZeit = 0.1

def Abzug02():
    AbzugZeit = 0.2
    
def Abzug03():
    AbzugZeit = 0.3

#Variabelen setzen für Kommando 50. Reduzierung der Ladezeit auf 10 Sek.
def Kommando50Aus():
    global Kom50
    Kom50= 60
    return()

def Kommando50An():
    global Kom50
    Kom50 = 10
    return()

#Variabelen setzen für Modus ( Licht oder Klapp )
def Modus1():
    global Modus
    Modus= 1

def Modus2():
    global Modus
    Modus= 2

def start():
    print (" start training prozess")
    _thread.start_new_thread(Training,(99,))

def rf_modul():
    print (" start rf modul")
    _thread.start_new_thread(receive())

def change_vol(l):
    m = alsaaudio.Mixer('PCM')
    int_l = int(l)
    m.setvolume(int_l)
    current_volume = m.getvolume()

def Training(a):
    if Modus == 1:
        os.system("sudo xscreensaver-command -activate")
        GPIO.output(26, True)
        GPIO.output(6, False)
        GPIO.output(16, False)
        pygame.init()
        if Kom50 == 60:
            pygame.mixer.music.load("/home/pi/Documents/shoot/WaffeLaden.wav")#Ansage "Laden"
        elif Kom50 == 10:
            pygame.mixer.music.load("/home/pi/Documents/shoot/50.wav")#Ansage "Laden"
        pygame.mixer.music.play()
        time.sleep(Kom50)
        pygame.mixer.music.load("/home/pi/Documents/shoot/Achtung.wav")#Ansage "Achtung"
        pygame.mixer.music.play()
        time.sleep(1)
        for g in range(Wiederholungen):
            GPIO.output(26, False)
            GPIO.output(16, False)
            GPIO.output(6, True)
            time.sleep(7)
            GPIO.output(16, True)
            GPIO.output(6, False)
            time.sleep(SchussZeit)
        GPIO.output(16, False)
        GPIO.output(6, True)
        for g in range(4):
            GPIO.output(6, False)
            time.sleep(0.4)
            GPIO.output(6, True)
            time.sleep(0.4)
        GPIO.output(6, True)
        GPIO.output(26, True)
        GPIO.output(16, True)
        os.system("sudo xscreensaver-command -deactivate")
    elif Modus == 2:       
        os.system("sudo xscreensaver-command -activate")
        GPIO.output(16, False)
        GPIO.output(6, False)       
        GPIO.output(26, True)
        pygame.init()
        if Kom50 == 60:
            pygame.mixer.music.load("/home/pi/Documents/shoot/WaffeLaden.wav")#Ansage "Laden"
        elif Kom50 == 10:
            pygame.mixer.music.load("/home/pi/Documents/shoot/50.wav")#Ansage "Laden"
        pygame.mixer.music.play()
        pwm.set_pwm(0, 0, 130)
        pwm.set_pwm(1, 0, 130)
        pwm.set_pwm(2, 0, 130)
        pwm.set_pwm(3, 0, 130)
        pwm.set_pwm(4, 0, 130)            
        time.sleep(Kom50)
        GPIO.output(26, False)
        pygame.mixer.music.load("/home/pi/Documents/shoot/Achtung.wav")#Ansage "Achtung"
        pygame.mixer.music.play()
        time.sleep(1)
        for g in range(Wiederholungen):
            pwm.set_pwm(0, 0, 300)
            pwm.set_pwm(1, 0, 300)
            pwm.set_pwm(2, 0, 300)
            pwm.set_pwm(3, 0, 300)
            pwm.set_pwm(4, 0, 300)
            time.sleep(7)
            pwm.set_pwm(0, 0, 130)
            pwm.set_pwm(1, 0, 130)
            pwm.set_pwm(2, 0, 130)
            pwm.set_pwm(3, 0, 130)
            pwm.set_pwm(4, 0, 130)
            time.sleep(SchussZeit)
        pwm.set_pwm(0, 0, 300)
        time.sleep(1)
        pwm.set_pwm(0, 0, 130)
        GPIO.output(26, True)
        GPIO.output(16, True)
        GPIO.output(6, True)
        os.system("sudo xscreensaver-command -deactivate")
    return
   
def herunterfahren():
    GPIO.cleanup()
    os.system("sudo shutdown -h now")
     
def GUI():
    rightLabel1 = Label(buttonFrame, text="Pistol Shoot Trainer", font = "Verdana 27 bold", background="#58FA58")
    rightLabel1.grid(row=0, column=0, padx=1, pady=1, columnspan=6)
    
    rightLabel4 = Label(buttonFrame, text="Schießzeit", font = "Verdana 10 bold", background="#58FA58")
    rightLabel4.grid(row=1, column=0, padx=0, pady=3)
    
    RB11 = Radiobutton(buttonFrame, indicatoron=0, text="Duell", height=1, width=5, font = "Verdana 12 bold", variable=SchussZeit, value=3, command=Duell)
    RB11.grid(row=1, column=1, padx=5, pady=8)
    RB11.select()
 
    RB12 = Radiobutton(buttonFrame, indicatoron=0,  text="8 Sek", height=1, width=5, font = "Verdana 12 bold" , variable=SchussZeit, value=8, command=AchtSekunden)
    RB12.grid(row=1, column=3, padx=5, pady=8)

    RB13 = Radiobutton(buttonFrame, indicatoron=0,  text="6 Sek", height=1, width=5,font = "Verdana 12 bold", variable=SchussZeit, value=6, command=SechsSekunden)
    RB13.grid(row=1, column=4, padx=5, pady=8)

    RB14 = Radiobutton(buttonFrame, indicatoron=0,  text="4 Sek", height=1, width=5,font = "Verdana 12 bold" , variable=SchussZeit, value=4, command=VierSekunden)
    RB14.grid(row=1, column=5, padx=5, pady=8)

    RB15 = Radiobutton(buttonFrame, indicatoron=0,  text="10 Sek", height=1, width=6,font = "Verdana 12 bold" , variable=SchussZeit, value=10, command=ZehnSekunden)
    RB15.grid(row=1, column=2, padx=5, pady=8)

    rightLabel5 = Label(buttonFrame, text="Zeitabzug", font = "Verdana 10 bold", background="#58FA58")
    rightLabel5.grid(row=2, column=0, padx=0, pady=3)
 
    RB21 = Radiobutton(buttonFrame, indicatoron=0,  text="Ohne", height=1, width=5, font = "Verdana 12 bold" , variable=AbzugZeit, value=1, command=AbzugOhne)
    RB21.grid(row=2, column=1, pady=8, padx=5)
    RB21.select()
    
    RB22 = Radiobutton(buttonFrame, indicatoron=0,  text="0,1", height=1, width=5, font = "Verdana 12 bold" , variable=AbzugZeit, value=2, command=Abzug01)
    RB22.grid(row=2, column=2, pady=8, padx=5)

    RB23 = Radiobutton(buttonFrame, indicatoron=0,  text="0,2", height=1, width=5, font = "Verdana 12 bold", variable=AbzugZeit, value=3, command=Abzug02)
    RB23.grid(row=2, column=3, pady=8, padx=5) 

    RB24 = Radiobutton(buttonFrame, indicatoron=0,  text="0.3", height=1, width=5, font = "Verdana 12 bold" , variable=AbzugZeit, value=4, command=Abzug03)
    RB24.grid(row=2, column=4, pady=8, padx=5)
                  
    rightLabel6 = Label(buttonFrame, text="Kommando \n50", font = "Verdana 10 bold", background="#58FA58")
    rightLabel6.grid(row=3, column=0, padx=0, pady=3)

    RB31 = Radiobutton(buttonFrame, indicatoron=0,  text="Ohne", height=1, width=7, font = "Verdana 15 bold" , variable=Kom50, value=1, command=Kommando50Aus)
    RB31.grid(row=3, column=1, pady=8,columnspan=2)
    
    RB32 = Radiobutton(buttonFrame, indicatoron=0,  text="Mit", height=1, width=7, font = "Verdana 15 bold" , variable=Kom50, value=2, command=Kommando50An)
    RB32.grid(row=3, column=3, pady=8,columnspan=2)
    RB32.select()
    
    rightLabel6 = Label(buttonFrame, text="Modus", font = "Verdana 10 bold", background="#58FA58")
    rightLabel6.grid(row=4, column=0, padx=0, pady=3)
    
    RB41 = Radiobutton(buttonFrame, indicatoron=0,  text="Licht", height=1, width=7, font = "Verdana 15 bold" , variable=Modus, value=1, command=Modus1)
    RB41.grid(row=4, column=1, pady=8,columnspan=2)
       
    RB42 = Radiobutton(buttonFrame, indicatoron=0,  text="Dreh", height=1, width=7, font = "Verdana 15 bold" , variable=Modus, value=2, command=Modus2)
    RB42.grid(row=4, column=3, pady=8,columnspan=2)
    RB42.select()

    BT42 = Button(buttonFrame, text="Beenden",  height=1, width=10, font = "Verdana 10 bold", command=herunterfahren)
    BT42.grid(row=5, column=4, padx=5, pady=5,columnspan=2)
    
    rightLabel7 = Label(buttonFrame, text="Lautstärke", font = "Verdana 10 bold", background="#58FA58")
    rightLabel7.grid(row=5, column=0, padx=0, pady=3)
    
    Schieber = Scale(buttonFrame, from_ = 0, to = 100, length = 200, orient =HORIZONTAL,tickinterval = 20,resolution =  5, command=change_vol) # tickinterval = 1,
    Schieber.grid(row=5, column=1, padx=5, pady=5,columnspan=3)
    Schieber.set(10)

    #rf_modul()
    
    root.mainloop() # GUI wird upgedated. Danach keine Elemente setzen

buttonFrame = Frame(root, background="#58FA58")
buttonFrame.grid(row=0, column=0, padx=5, pady=5)        
GPIO.output(26, True)
GPIO.output(6, True)
GPIO.output(16, True)
#rf_modul()
GUI()

mollyman
User
Beiträge: 27
Registriert: Samstag 24. Februar 2018, 12:10

Habe es mit

Code: Alles auswählen

Schieber.set(10)
 
    #rf_modul()
    root.after(0, receive)
    root.mainloop() # GUI wird upgedated. Danach keine Elemente setzen
probiert.

zur Kontrolle habe ich folgenden Schritt implementiert:

Code: Alles auswählen

     while True:
        if rfdevice.rx_code_timestamp != timestamp:
            timestamp = rfdevice.rx_code_timestamp
            rec_num = (str(rfdevice.rx_code))
            print (rec_num)
            if rec_num == "16404":
                start()
                return
            else:
               print("test")
        time.sleep(0.01)
nach 45 "test" zeigt es einen Code "16384" an und das war es.
Die Gui startet erst nach der angezeigten Nummer.
Das Programm reagiert nicht auf den Sender

Beim zweiten versuch , 7 x test dann die "512" dann ist die GUI gestartet und keine Rreaktion auf den Sender.
Für mich heißt es, dass dass die Funktion receive abbricht, sobald sie einen Code entschlüsselt hat.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du wirst noch eine ganze Reihe Fehler beseitigen müssen, und ich würde das alles auch anders angehen - aber im sinne des Pragmatismus hier ein paar anmerkungen:

- du benutzt den threading call für das receive falsch. Schau mal genau hin, und Vergleiche mit dem anderen: da hast du ein paar Klammern zu viel. Du darfst nur receive reingeben, und es NICHT gleich aufrufen.
- deine diversen XSekunden Funktionen sind falsch - du denkst du setzt globale Variablen, da du die aber nicht in der Funktion global erklärst, sondern auf Modul-Ebene - wo das wirkungslos ist, und eigentlich sollte Python eine Fehler werfen, warum man das nicht eingebaut hat, ist mir ein Rätsel. Wie dem auch sei, auf der Ebenen wo es jetzt ist muss es weg, und in die Funktionen.
- gleiches gilt für andere stellen.
- du arbeitest viel mit sehr kurzen Wartezeiten. Gerade auf dem PI unser einem Standard Kernel mit nur einer hundertstel Sekunde Scheduler Auflösung kann das Abweichungen bis 30% nach sich ziehen (mir schon passiert). Wenn es kleine Zeiträume sind, und die Präzision wichtig ist, solltets du überlegen, einen busy-loop zum warten zu verwenden. Das ist zwar großes IhBäh(tm), aber ggf besser. Richtig gut und ohne Threads wäre das ganz mit pigpio (solltest du eh verwenden) und dessen waveforms. Dann geht es mit hochpräzisem timing und quasi automatisch. Wird allerdings mit der ganzen anderen Logik wie den audio files auch nicht weniger anspruchsvoll.
mollyman
User
Beiträge: 27
Registriert: Samstag 24. Februar 2018, 12:10

__deets__ hat geschrieben:Du wirst noch eine ganze Reihe Fehler beseitigen müssen, und ich würde das alles auch anders angehen - aber im sinne des Pragmatismus hier ein paar anmerkungen:

- du benutzt den threading call für das receive falsch. Schau mal genau hin, und Vergleiche mit dem anderen: da hast du ein paar Klammern zu viel. Du darfst nur receive reingeben, und es NICHT gleich aufrufen.
ich habe nochmal den Prozess genutzt, eigentlich hatte ich das ja bereits über das after aufgerufen. ( siehe mein vorheriger Post)
alt:

Code: Alles auswählen

  _thread.start_new_thread(receive())
Neu

Code: Alles auswählen

  _thread.start_new_thread(receive)
Jetzt bekomme ich einen Type error:
_thread.start_new_thread(receive)
TypeError: start_new_thread expected at least 2 arguments, got 1

aber auch mit dem after laeuft nicht die GUI und das receive zeitgleich, sondern immer nur das eine oder das andere .

Das ist auch das grosse Problem, alles andere mag gruselig programmiert sein, funktioniert. Aber dIe GUI und recieve laeuft nicht zusammen.
__deets__ hat geschrieben: - deine diversen XSekunden Funktionen sind falsch

- du denkst du setzt globale Variablen, da du die aber nicht in der Funktion global erklärst, sondern auf Modul-Ebene - wo das wirkungslos ist, und eigentlich sollte Python eine Fehler werfen, warum man das nicht eingebaut hat, ist mir ein Rätsel. Wie dem auch sei, auf der Ebenen wo es jetzt ist muss es weg, und in die Funktionen.

- gleiches gilt für andere stellen.
hmm das verstehe ich nicht. mit "def" definiere ich doch eine Funktion ? (https://www.tutorialspoint.com/python/p ... ctions.htm)
Bisher hatte ich verstanden, dass ein Modul in einer anderen Datei ausgelagert ist.
__deets__ hat geschrieben: - du arbeitest viel mit sehr kurzen Wartezeiten. Gerade auf dem PI unser einem Standard Kernel mit nur einer hundertstel Sekunde Scheduler Auflösung kann das Abweichungen bis 30% nach sich ziehen (mir schon passiert). Wenn es kleine Zeiträume sind, und die Präzision wichtig ist, solltets du überlegen, einen busy-loop zum warten zu verwenden. Das ist zwar großes IhBäh(tm), aber ggf besser. Richtig gut und ohne Threads wäre das ganz mit pigpio (solltest du eh verwenden) und dessen waveforms. Dann geht es mit hochpräzisem timing und quasi automatisch. Wird allerdings mit der ganzen anderen Logik wie den audio files auch nicht weniger anspruchsvoll.
Was meinst du mit kleinen Abständen ? die kleinen Abstände im Receive sind nach dem was ich verstanden habe für das Protokoll wichtig. ansonsten sind die Abstände mehrere Sekunden. ist das auch zu kurz ?
ich scheue mir mal das pigpio an.
Die ms Zeiten zum stellen des Servos werden per i2c zu einem Hardware PWM weitergegeben
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du benutzt halt eine veraltete Thread api und machst dir das Leben damit schwerer. Aber das hast du ja so gewollt. Die will halt IMMER zwei Argumente. Du gibst ihr nur eines. Es muss ein zweites dahinter, MIT KOMMA GETRENNT, ein leeres Tupel - () - oder nicht-leer wie bei Start, aber da ist das ja dann in Training selbst ignoriert. Also

start_new_thread(receive, ())

Und das def keine Funktionen wären habe ich nicht behauptet.ich rede davon, was DARIN passiert. Da weist du irgendwelchen Variablen werdet zu. Du GLAUBST das würde dauerhaft sein, isses aber nicht. Teste das mal mit einem simplen Skript.

Und dein Skript ist auch ein Modul. Es hat den speziellen Namen __main__, aber die Semantik ist gleich. Insofern gelten meine Ausführungen eben auch da. Global-Deklarationen auf Modulebene sind sinnlos, weil da alles (Modul-)global IST. Unterschieden wird das nur IN Funktionen, denn da gibt es lokale Variablen, und die will man von globalen unterscheiden.
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Zu den Abständen: du wartest doch diverse mal zB 0.4 Sekunden. Das ist relativ kurz. Wenn das präzise muss, sollte es ggf anders gemacht werden. Das 0.01 im receive ist eher ein freundlicher Hinweis an den Kernel, mal kurz wen anderes dran zu lassen, aber bitte gleich wieder weiter zu machen. Das wird nie eingehalten, wenn wie gesagt der scheduler schon mit der Auflösung arbeitet - da kommt garantiert immer eine, wenn nicht mehrere zeitscheiben dazwischen, und du wartest implizit immer mehrere 100stel. Schlimm ist das eher nicht, außer du machst Zuviel im anderen Thread. Was wiederum mit dem busywait doof ist... hm.

Schau erstmal das alles prinzipiell klappt, timer-tuning ist Sternchenaufgabe :)
mollyman
User
Beiträge: 27
Registriert: Samstag 24. Februar 2018, 12:10

__deets__ hat geschrieben:Du benutzt halt eine veraltete Thread api und machst dir das Leben damit schwerer. Aber das hast du ja so gewollt. Die will halt IMMER zwei Argumente. Du gibst ihr nur eines. Es muss ein zweites dahinter, MIT KOMMA GETRENNT, ein leeres Tupel - () - oder nicht-leer wie bei Start, aber da ist das ja dann in Training selbst ignoriert. Also

start_new_thread(receive, ())

Und das def keine Funktionen wären habe ich nicht behauptet.ich rede davon, was DARIN passiert. Da weist du irgendwelchen Variablen werdet zu. Du GLAUBST das würde dauerhaft sein, isses aber nicht. Teste das mal mit einem simplen Skript.

Und dein Skript ist auch ein Modul. Es hat den speziellen Namen __main__, aber die Semantik ist gleich. Insofern gelten meine Ausführungen eben auch da. Global-Deklarationen auf Modulebene sind sinnlos, weil da alles (Modul-)global IST. Unterschieden wird das nur IN Funktionen, denn da gibt es lokale Variablen, und die will man von globalen unterscheiden.
Sie schreibweise ruft die Funktion nicht so auf, dass sie funktioniert

Code: Alles auswählen

def receive(a):
und 
start_new_thread(receive, (99,))
funktioniert

Code: Alles auswählen

def receive(a):
und 
start_new_thread(receive, ())
gibt den Fehler, dass ein Argument fehlt

Code: Alles auswählen

def receive():
und 
start_new_thread(receive, ())
receive wird nicht ausgeführt, es gibt aber auch keinen Fehler
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

Im letzten Fall machst Du irgendetwas anderes falsch, was Du aber nicht zeigst.
mollyman
User
Beiträge: 27
Registriert: Samstag 24. Februar 2018, 12:10

Sirius3 hat geschrieben:Im letzten Fall machst Du irgendetwas anderes falsch, was Du aber nicht zeigst.
der komplette Code

Code: Alles auswählen

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import tkinter as tk
import Adafruit_PCA9685
import time
import RPi.GPIO as GPIO
import os
import pygame
import _thread
import alsaaudio
import argparse
import signal
import sys
import logging

from rpi_rf import RFDevice
from tkinter import *

#GPIO für LED festlegen
GPIO.setwarnings(False) # Warnungen ausschalten
GPIO.setmode(GPIO.BCM) # Pin Nummern verwenden
GPIO.setup(6, GPIO.OUT) # Pin 31 als Output gruen
GPIO.setup(16, GPIO.OUT) # Pin 36 als Output rot
GPIO.setup(26, GPIO.OUT) # Pin 37 als Output gelb

# Variabelen festlegen
global Kom50, Wiederholungen, SchussZeit, AbzugZeit, Modus, Schieber

# Variabelen Werte zuweisen
SchussZeit = 3 # Dauer der Sichtbarkeit der Scheibe
AbzugZeit = 0 # Zeit um die die Sichtbarkeit der Scheibe reduziert wird
Kom50= 10 # Kommando 50 Reduziert die Zeit für das Laden der Waffe auf 10 Sekunden
Modus = 2 # 1 = Lichtmodus, 2 = Klappenmodus
Wiederholungen = 5 # Duell 5 Wiederholungen ( 1 Schuß pro aufklappen) alle anderen 1

# I2C Board für Servo
pwm = Adafruit_PCA9685.PCA9685(address=0x40) # I2C Board-Adresse
pwm.set_pwm_freq(50) # Festlegung der Frequenz

# Gui Grundlagen definieren
root = Tk() # Fenster erstellen
root.wm_title("Pistol Shoot Trainer") # Fenster Titel
#root.wm_attributes ('-fullscreen', 'true') # Vollbildmodus
root.wm_geometry('480x320+0+0')
root.config(background = "#FFFFFF") # Hintergrundfarbe des Fensters

def exithandler(signal, frame): # Teil des 433 Mhz Prozess Skriptes
    #rfdevice.cleanup()
    sys.exit(0)

def receive():
    print ("receive start")
    logging.basicConfig(level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S',
                    format='%(asctime)-15s - [%(levelname)s] %(module)s: %(message)s', )
 
    parser = argparse.ArgumentParser(description='Receives a decimal code via a 433/315MHz GPIO device')
    parser.add_argument('-g', dest='gpio', type=int, default=27,
                    help="GPIO pin (Default: 27)")
    args = parser.parse_args()
 
    signal.signal(signal.SIGINT, exithandler)
    rfdevice = RFDevice(args.gpio)
    rfdevice.enable_rx()
    timestamp = None
    while True:
        if rfdevice.rx_code_timestamp != timestamp:
            timestamp = rfdevice.rx_code_timestamp
            rec_num = (str(rfdevice.rx_code))
            print (rec_num)
            if rec_num == "16404":
                start()
            return()
        else:
            print ("test")
        time.sleep(0.01)
    #rfdevice.cleanup()

#Variabelen setzen für die Schusszeit und die Anzahl der Wiederholungen pro Magazin
def AchtSekunden():
    SchussZeit = 8
    Wiederholungen = 1 
     
def SechsSekunden():
    SchussZeit = 6
    Wiederholungen = 1 

def VierSekunden():
    SchussZeit = 4
    Wiederholungen = 1 

def ZehnSekunden():
    SchussZeit = 10
    Wiederholungen = 1 
     
def Duell():
    SchussZeit = 3
    Wiederholungen = 5

#Variabelen setzen für die Reduzierung der Schusszeit 
def AbzugOhne():
    AbzugZeit = 0
     
def Abzug01():
    AbzugZeit = 0.1

def Abzug02():
    AbzugZeit = 0.2
    
def Abzug03():
    AbzugZeit = 0.3

#Variabelen setzen für Kommando 50. Reduzierung der Ladezeit auf 10 Sek.
def Kommando50Aus():
    global Kom50
    Kom50= 60
    return()

def Kommando50An():
    global Kom50
    Kom50 = 10
    return()

#Variabelen setzen für Modus ( Licht oder Klapp )
def Modus1():
    global Modus
    Modus= 1

def Modus2():
    global Modus
    Modus= 2

def start():
    print (" start training prozess")
    _thread.start_new_thread(Training,())

def rf_modul():
    print (" start rf modul")
    _thread.start_new_thread(receive, ())
    receive()

def change_vol(l):
    m = alsaaudio.Mixer('PCM')
    int_l = int(l)
    m.setvolume(int_l)
    current_volume = m.getvolume()

def Training(a):
    if Modus == 1:
        os.system("sudo xscreensaver-command -activate")
        GPIO.output(26, True)
        GPIO.output(6, False)
        GPIO.output(16, False)
        pygame.init()
        if Kom50 == 60:
            pygame.mixer.music.load("/home/pi/Documents/shoot/WaffeLaden.wav")#Ansage "Laden"
        elif Kom50 == 10:
            pygame.mixer.music.load("/home/pi/Documents/shoot/50.wav")#Ansage "Laden"
        pygame.mixer.music.play()
        time.sleep(Kom50)
        pygame.mixer.music.load("/home/pi/Documents/shoot/Achtung.wav")#Ansage "Achtung"
        pygame.mixer.music.play()
        time.sleep(1)
        for g in range(Wiederholungen):
            GPIO.output(26, False)
            GPIO.output(16, False)
            GPIO.output(6, True)
            time.sleep(7)
            GPIO.output(16, True)
            GPIO.output(6, False)
            time.sleep(SchussZeit)
        GPIO.output(16, False)
        GPIO.output(6, True)
        for g in range(4):
            GPIO.output(6, False)
            time.sleep(0.4)
            GPIO.output(6, True)
            time.sleep(0.4)
        GPIO.output(6, True)
        GPIO.output(26, True)
        GPIO.output(16, True)
        os.system("sudo xscreensaver-command -deactivate")
    elif Modus == 2:       
        os.system("sudo xscreensaver-command -activate")
        GPIO.output(16, False)
        GPIO.output(6, False)       
        GPIO.output(26, True)
        pygame.init()
        if Kom50 == 60:
            pygame.mixer.music.load("/home/pi/Documents/shoot/WaffeLaden.wav")#Ansage "Laden"
        elif Kom50 == 10:
            pygame.mixer.music.load("/home/pi/Documents/shoot/50.wav")#Ansage "Laden"
        pygame.mixer.music.play()
        pwm.set_pwm(0, 0, 130)
        pwm.set_pwm(1, 0, 130)
        pwm.set_pwm(2, 0, 130)
        pwm.set_pwm(3, 0, 130)
        pwm.set_pwm(4, 0, 130)            
        time.sleep(Kom50)
        GPIO.output(26, False)
        pygame.mixer.music.load("/home/pi/Documents/shoot/Achtung.wav")#Ansage "Achtung"
        pygame.mixer.music.play()
        time.sleep(1)
        for g in range(Wiederholungen):
            pwm.set_pwm(0, 0, 300)
            pwm.set_pwm(1, 0, 300)
            pwm.set_pwm(2, 0, 300)
            pwm.set_pwm(3, 0, 300)
            pwm.set_pwm(4, 0, 300)
            time.sleep(7)
            pwm.set_pwm(0, 0, 130)
            pwm.set_pwm(1, 0, 130)
            pwm.set_pwm(2, 0, 130)
            pwm.set_pwm(3, 0, 130)
            pwm.set_pwm(4, 0, 130)
            time.sleep(SchussZeit)
        pwm.set_pwm(0, 0, 300)
        time.sleep(1)
        pwm.set_pwm(0, 0, 130)
        GPIO.output(26, True)
        GPIO.output(16, True)
        GPIO.output(6, True)
        os.system("sudo xscreensaver-command -deactivate")
    return
   
def herunterfahren():
    GPIO.cleanup()
    os.system("sudo shutdown -h now")
     
def GUI():
    rightLabel1 = Label(buttonFrame, text="Pistol Shoot Trainer", font = "Verdana 27 bold", background="#58FA58")
    rightLabel1.grid(row=0, column=0, padx=1, pady=1, columnspan=6)
    
    rightLabel4 = Label(buttonFrame, text="Schießzeit", font = "Verdana 10 bold", background="#58FA58")
    rightLabel4.grid(row=1, column=0, padx=0, pady=3)
    
    RB11 = Radiobutton(buttonFrame, indicatoron=0, text="Duell", height=1, width=5, font = "Verdana 12 bold", variable=SchussZeit, value=3, command=Duell)
    RB11.grid(row=1, column=1, padx=5, pady=8)
    RB11.select()
 
    RB12 = Radiobutton(buttonFrame, indicatoron=0,  text="8 Sek", height=1, width=5, font = "Verdana 12 bold" , variable=SchussZeit, value=8, command=AchtSekunden)
    RB12.grid(row=1, column=3, padx=5, pady=8)

    RB13 = Radiobutton(buttonFrame, indicatoron=0,  text="6 Sek", height=1, width=5,font = "Verdana 12 bold", variable=SchussZeit, value=6, command=SechsSekunden)
    RB13.grid(row=1, column=4, padx=5, pady=8)

    RB14 = Radiobutton(buttonFrame, indicatoron=0,  text="4 Sek", height=1, width=5,font = "Verdana 12 bold" , variable=SchussZeit, value=4, command=VierSekunden)
    RB14.grid(row=1, column=5, padx=5, pady=8)

    RB15 = Radiobutton(buttonFrame, indicatoron=0,  text="10 Sek", height=1, width=6,font = "Verdana 12 bold" , variable=SchussZeit, value=10, command=ZehnSekunden)
    RB15.grid(row=1, column=2, padx=5, pady=8)

    rightLabel5 = Label(buttonFrame, text="Zeitabzug", font = "Verdana 10 bold", background="#58FA58")
    rightLabel5.grid(row=2, column=0, padx=0, pady=3)
 
    RB21 = Radiobutton(buttonFrame, indicatoron=0,  text="Ohne", height=1, width=5, font = "Verdana 12 bold" , variable=AbzugZeit, value=1, command=AbzugOhne)
    RB21.grid(row=2, column=1, pady=8, padx=5)
    RB21.select()
    
    RB22 = Radiobutton(buttonFrame, indicatoron=0,  text="0,1", height=1, width=5, font = "Verdana 12 bold" , variable=AbzugZeit, value=2, command=Abzug01)
    RB22.grid(row=2, column=2, pady=8, padx=5)

    RB23 = Radiobutton(buttonFrame, indicatoron=0,  text="0,2", height=1, width=5, font = "Verdana 12 bold", variable=AbzugZeit, value=3, command=Abzug02)
    RB23.grid(row=2, column=3, pady=8, padx=5) 

    RB24 = Radiobutton(buttonFrame, indicatoron=0,  text="0.3", height=1, width=5, font = "Verdana 12 bold" , variable=AbzugZeit, value=4, command=Abzug03)
    RB24.grid(row=2, column=4, pady=8, padx=5)
                  
    rightLabel6 = Label(buttonFrame, text="Kommando \n50", font = "Verdana 10 bold", background="#58FA58")
    rightLabel6.grid(row=3, column=0, padx=0, pady=3)

    RB31 = Radiobutton(buttonFrame, indicatoron=0,  text="Ohne", height=1, width=7, font = "Verdana 15 bold" , variable=Kom50, value=1, command=Kommando50Aus)
    RB31.grid(row=3, column=1, pady=8,columnspan=2)
    
    RB32 = Radiobutton(buttonFrame, indicatoron=0,  text="Mit", height=1, width=7, font = "Verdana 15 bold" , variable=Kom50, value=2, command=Kommando50An)
    RB32.grid(row=3, column=3, pady=8,columnspan=2)
    RB32.select()
    
    rightLabel6 = Label(buttonFrame, text="Modus", font = "Verdana 10 bold", background="#58FA58")
    rightLabel6.grid(row=4, column=0, padx=0, pady=3)
    
    RB41 = Radiobutton(buttonFrame, indicatoron=0,  text="Licht", height=1, width=7, font = "Verdana 15 bold" , variable=Modus, value=1, command=Modus1)
    RB41.grid(row=4, column=1, pady=8,columnspan=2)
       
    RB42 = Radiobutton(buttonFrame, indicatoron=0,  text="Dreh", height=1, width=7, font = "Verdana 15 bold" , variable=Modus, value=2, command=Modus2)
    RB42.grid(row=4, column=3, pady=8,columnspan=2)
    RB42.select()

    BT42 = Button(buttonFrame, text="Beenden",  height=1, width=10, font = "Verdana 10 bold", command=herunterfahren)
    BT42.grid(row=5, column=4, padx=5, pady=5,columnspan=2)
    
    rightLabel7 = Label(buttonFrame, text="Lautstärke", font = "Verdana 10 bold", background="#58FA58")
    rightLabel7.grid(row=5, column=0, padx=0, pady=3)
    
    Schieber = Scale(buttonFrame, from_ = 0, to = 100, length = 200, orient =HORIZONTAL,tickinterval = 20,resolution =  5, command=change_vol) # tickinterval = 1,
    Schieber.grid(row=5, column=1, padx=5, pady=5,columnspan=3)
    Schieber.set(10)

    #root.after (0, receive)
    root.mainloop() # GUI wird upgedated. Danach keine Elemente setzen

buttonFrame = Frame(root, background="#58FA58")
buttonFrame.grid(row=0, column=0, padx=5, pady=5)        
GPIO.output(26, True)
GPIO.output(6, True)
GPIO.output(16, True)
GUI()
rf_modul()
    
mollyman
User
Beiträge: 27
Registriert: Samstag 24. Februar 2018, 12:10

__deets__ hat geschrieben:Zu den Abständen: du wartest doch diverse mal zB 0.4 Sekunden. Das ist relativ kurz. Wenn das präzise muss, sollte es ggf anders gemacht werden. Das 0.01 im receive ist eher ein freundlicher Hinweis an den Kernel, mal kurz wen anderes dran zu lassen, aber bitte gleich wieder weiter zu machen. Das wird nie eingehalten, wenn wie gesagt der scheduler schon mit der Auflösung arbeitet - da kommt garantiert immer eine, wenn nicht mehrere zeitscheiben dazwischen, und du wartest implizit immer mehrere 100stel. Schlimm ist das eher nicht, außer du machst Zuviel im anderen Thread. Was wiederum mit dem busywait doof ist... hm.

Schau erstmal das alles prinzipiell klappt, timer-tuning ist Sternchenaufgabe :)
die 0,4 SSekunden sollen nur ein Blinken der LED erzeugen, die anzeigen, dass der Zyklus durch ist. Ob das 0,4 ,02 oder 0,8 sind ist dabei voellig legal
Antworten