Hallo
Ich habe mit pygame ein Programm entworfen mit dem man über die Pfeiltasten das nächste oder das vorherige Bild aufrufen kann. Nun möchte ich die Pfeiltasten durch einen Fußtaster ersetzen, der ein Eigenbau ist. Er wird über die Serielle Schnitstelle angeschlossen. Der Taster für nächstes Bild ist mit Pin 6 und 7, der für vorheriges Bild mit Pin 4 und 8 belegt (Jeweils ein Plus 5V und ein DSR/CTS Pin). Wie kann ich das Signal abfangen/ auslesen welches durch die Verbindung der beiden Pins jeweils entsteht? Habe schon viele Foren durchforstet aber keine Antwort gefunden :K
VIelen Dank schonmal für eure Mühen
MFG
Henkman
Einzelnen Pin von COM Anschluss abfragen
@Henkman: Was genau funktioniert denn nicht? Die Pins die man lesen kann existieren als Attribute auf dem `Serial`-Objekt. Einfacher geht's ja kaum.
@ BlackJack: Ich weiß einfach nicht wie ich die Pins auslese also mit welchem Code. hast du vllt mal ein Beispiel für mich?
Bisher hab ich nur das:
Würde mich sehr freuen wenn du mir da den passenden Befehl sagen kannst.
Bisher hab ich nur das:
Code: Alles auswählen
import serial
ser = serial.Serial(port='COM1', baudrate=9600, timeout=1)
ser.setDTR(True)
try:
ser.isOpen()
print("ok")
except:
print("closed")
if(ser.isOpen()):
while(1):
try:
print(ser.read())
except Exception:
print("geht nicht")
else:
print("geschlossen")
Zuletzt geändert von Anonymous am Dienstag 4. April 2017, 20:43, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
@Henkman: Der Code ist ziemlich unsinnig. Lass diese Ausnahmebehandlung weg. Und das `ser.isOpen()` macht auch keinen Sinn weil das auf *jeden Fall* offen ist so wie Du das `Serial`-Objekt erstellst. Sollte das öffnen nicht klappen hätte Zeile 3 schon eine Ausnahme ausgelöst die Du nicht behandelt hättest.
Die Klammern um die Bedingungen von ``if`` und ``while`` gehören da nicht hin, und `read()` willst Du doch gar nicht, warum machst Du das dann?
Du kannst die DTR-Leitung setzen, andere aber nicht lesen? Das ist eigenartig.
Wobei man die Methoden nicht mehr verwenden sollte, die Leitungen haben Attribute/Properties bekommen.
Die Klammern um die Bedingungen von ``if`` und ``while`` gehören da nicht hin, und `read()` willst Du doch gar nicht, warum machst Du das dann?
Du kannst die DTR-Leitung setzen, andere aber nicht lesen? Das ist eigenartig.
Wobei man die Methoden nicht mehr verwenden sollte, die Leitungen haben Attribute/Properties bekommen.
@Henkman: `Serial`-Objekte haben die lesbaren Leitungen unter ihren Namen als Attribute die man einfach abfragen kann. Schau Dir in der Dokumentation einfach mal die Attribute von `Serial` an.
Habs geschafft
Hab aber leider noch ein Problem, dass dem fertigen Programm im weg steht ...
Ich frage True am Pin ab aber er führt die Definitionen Bild_vor und Bild_zurueck nicht aus sieht jemand meinen Fehler?
Ich weiß der Code ist nicht sehr ordentlich und es kann sein, dass dort noch Befehle drin sind die unsinnig sind, weil ich vorher etwas anderes probiert hatte.
Hier der Code:
Hab aber leider noch ein Problem, dass dem fertigen Programm im weg steht ...
Ich frage True am Pin ab aber er führt die Definitionen Bild_vor und Bild_zurueck nicht aus sieht jemand meinen Fehler?
Ich weiß der Code ist nicht sehr ordentlich und es kann sein, dass dort noch Befehle drin sind die unsinnig sind, weil ich vorher etwas anderes probiert hatte.
Hier der Code:
Code: Alles auswählen
import pygame
from win32api import GetSystemMetrics
from pygame.locals import *
import os
import sys
import time
import serial
ser = serial.Serial(port='COM1', baudrate=9600, timeout=1)
valueh = GetSystemMetrics(0)
valuew = GetSystemMetrics(1)
pygame.init()
screen = pygame.display.set_mode((valueh,valuew), pygame.FULLSCREEN)
pygame.display.set_caption("Empfänger")
clock = pygame.time.Clock()
pygame.mouse.set_visible(0)
try:
NummerLan = open("C:/Tanzmusik/Nummer.txt","r")
N = NummerLan.read()
NummerLan.close()
Z = 1
Y = 1
Nummer = N
Liste ="C:/Tanzmusik/" + str(Nummer)
Inhalt = os.listdir(Liste)
Y = len(Inhalt)
print (Y)
S = 1
while Z <= Y:
if Z == 1:
image = pygame.image.load("C:/Tanzmusik/" + str(Nummer) + "/" + str(Z) + ".jpg")
image = pygame.transform.scale(image, (valueh, valuew))
image1 = image
elif Z == 2:
image = pygame.image.load("C:/Tanzmusik/" + str(Nummer) + "/" + str(Z) + ".jpg")
image = pygame.transform.scale(image, (valueh, valuew))
image2 = image
elif Z == 3:
image = pygame.image.load("C:/Tanzmusik/" + str(Nummer) + "/" + str(Z) + ".jpg")
image = pygame.transform.scale(image, (valueh, valuew))
image3 = image
elif Z == 4:
image = pygame.image.load("C:/Tanzmusik/" + str(Nummer) + "/" + str(Z) + ".jpg")
image = pygame.transform.scale(image, (valueh, valuew))
image4 = image
Z = Z + 1
Z = 1
if image1.get_alpha() is None:
image1 = image1.convert()
else:
image1 = image1.convert_alpha()
screen.blit(image1, (0, 0))
pygame.display.flip()
except:
print("Nix")
def input(events):
global S
for event in events:
if event.type == QUIT:
pygame.quit()
sys.exit()
else:
print(event)
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
Run = False
QUIT
def Bild_vor():
if S < Y:
S = S + 1
print (S)
if S == 1:
image = image1
if image.get_alpha() is None:
image = image.convert()
else:
image = image.convert_alpha()
screen.blit(image, (0, 0))
elif S == 2:
image = image2
if image.get_alpha() is None:
image = image.convert()
else:
image = image.convert_alpha()
screen.blit(image, (0, 0))
elif S == 3:
image = image3
if image.get_alpha() is None:
image = image.convert()
else:
image = image.convert_alpha()
screen.blit(image, (0, 0))
elif S == 4:
image = image4
if image.get_alpha() is None:
image = image.convert()
else:
image = image.convert_alpha()
screen.blit(image, (0, 0))
def Bild_zurueck():
if S >= 1:
S = S - 1
print (S)
if S == 1:
image = image1
if image.get_alpha() is None:
image = image.convert()
else:
image = image.convert_alpha()
screen.blit(image, (0, 0))
elif S == 2:
image = image2
if image.get_alpha() is None:
image = image.convert()
else:
image = image.convert_alpha()
screen.blit(image, (0, 0))
elif S == 3:
image = image3
if image.get_alpha() is None:
image = image.convert()
else:
image = image.convert_alpha()
screen.blit(image, (0, 0))
elif S == 4:
image = image4
if image.get_alpha() is None:
image = image.convert()
else:
image = image.convert_alpha()
screen.blit(image, (0, 0))
pygame.display.flip()
Run = True
while Run:
clock.tick(20)
input(pygame.event.get())
try:
Vor = ser.getCTS()
Zurueck = ser.getDSR()
if Vor == True:
Bild_vor
print(Vor)
time.sleep(0.5)
if Zurueck == True:
Bild_zurueck
print(Zurueck)
time.sleep(0.5)
NummerLan = open("C:/Tanzmusik/Nummer.txt","r")
N = NummerLan.read()
if N != Nummer:
Nummer = N
Liste ="C:/Tanzmusik/" + str(Nummer)
Inhalt = os.listdir(Liste)
Y = len(Inhalt)
while Z <= Y:
if Z == 1:
image = pygame.image.load("C:/Tanzmusik/" + str(Nummer) + "/" + str(Z) + ".jpg")
image = pygame.transform.scale(image, (valueh, valuew))
image1 = image
elif Z == 2:
image = pygame.image.load("C:/Tanzmusik/" + str(Nummer) + "/" + str(Z) + ".jpg")
image = pygame.transform.scale(image, (valueh, valuew))
image2 = image
elif Z == 3:
image = pygame.image.load("C:/Tanzmusik/" + str(Nummer) + "/" + str(Z) + ".jpg")
image = pygame.transform.scale(image, (valueh, valuew))
image3 = image
elif Z == 4:
image = pygame.image.load("C:/Tanzmusik/" + str(Nummer) + "/" + str(Z) + ".jpg")
image = pygame.transform.scale(image, (valueh, valuew))
image4 = image
Z = Z + 1
Z = 1
S = 1
if image1.get_alpha() is None:
image1 = image1.convert()
else:
image1 = image1.convert_alpha()
screen.blit(image1, (0, 0))
pygame.display.flip()
except:
print("Nix")
Zuletzt geändert von Anonymous am Mittwoch 5. April 2017, 09:20, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
@Henkman: Das ist viel zu unübersichtlich als das man sich da durchlesen möchte.
Die ``try``/``except``\s gehören ersatzlos gestrichen oder durch *sinnvolle* Behandlung von *konkreten* Ausnahmen ersetzt. So wie es da jetzt steht erschwert es nur die Fehlersuche.
Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Keine Variablen! Und schon gar nicht Variablen, Hauptprogramm, und Funktionsdefinitionen gemischt. Funktionen sollten keine Werte, ausser Konstanten, verwenden die nicht als Argumente übergeben wurden, und ``global`` geht gar nicht. Wenn eine Funktion ein Ergebnis hat, dann gibt man das als Rückgabewert an den Aufrufer zurück. Das durcheinander was da jetzt steht ist nicht leicht nachvollziehbar.
Es gibt auch viel zu viele Code-Wiederholungen. Code und Daten sollte man nicht wiederholen und auch nicht geringfügig geänderte Kopien verwenden. Dafür gibt es Schleifen und Funktionen.
`N`, `Z`, `Y`, `S` sind alles schlechte Namen, weil der Leser nicht sieht was die Werte bedeuten sollen. Auch generische Namen wie `Liste` oder `Nummer` helfen nicht wirklich beim Verständnis. Noch schlimmer wenn `Liste` dann an eine Zeichenkette gebunden wird und nicht an eine Liste.
`input()` ist bereits der Name einer eingebauten Funktion, die sollte man nicht verdecken.
Nummerierte Namen sind ein „code smell“. Da will man sich entweder bessere Namen ausdenken oder gar keine einzelnen Namen verwenden sondern eine Datenstruktur. Oft eine Liste. Wie zum Beispiel hier mit den Bildern.
Das mit den Zahlen `S` und `Y` ist alles andere als robust gelöst. Einerseits berücksichtigt der Code nur vier Bilder, andererseits ist die Obergrenze im Code die Anzahl der Dateien und Verzeichnisse in dem Verzeichnis. Da würde man eher entweder die tatsächliche Anzahl der *Bilder* ermitteln deren Dateiname eine Nummer ist und sich daran orientieren, oder fest von einer Anzahl von solchen Dateien ausgehen.
Und was den unnötigen Code angeht: der gesamte erste ``try``/``except``-Code, immerhin 48 Zeilen, scheint unnötig zu sein. Oder halt auch nicht, aber warum sollen *wir* das lesen und herausfinden müssen?
Die ``try``/``except``\s gehören ersatzlos gestrichen oder durch *sinnvolle* Behandlung von *konkreten* Ausnahmen ersetzt. So wie es da jetzt steht erschwert es nur die Fehlersuche.
Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Keine Variablen! Und schon gar nicht Variablen, Hauptprogramm, und Funktionsdefinitionen gemischt. Funktionen sollten keine Werte, ausser Konstanten, verwenden die nicht als Argumente übergeben wurden, und ``global`` geht gar nicht. Wenn eine Funktion ein Ergebnis hat, dann gibt man das als Rückgabewert an den Aufrufer zurück. Das durcheinander was da jetzt steht ist nicht leicht nachvollziehbar.
Es gibt auch viel zu viele Code-Wiederholungen. Code und Daten sollte man nicht wiederholen und auch nicht geringfügig geänderte Kopien verwenden. Dafür gibt es Schleifen und Funktionen.
`N`, `Z`, `Y`, `S` sind alles schlechte Namen, weil der Leser nicht sieht was die Werte bedeuten sollen. Auch generische Namen wie `Liste` oder `Nummer` helfen nicht wirklich beim Verständnis. Noch schlimmer wenn `Liste` dann an eine Zeichenkette gebunden wird und nicht an eine Liste.
`input()` ist bereits der Name einer eingebauten Funktion, die sollte man nicht verdecken.
Nummerierte Namen sind ein „code smell“. Da will man sich entweder bessere Namen ausdenken oder gar keine einzelnen Namen verwenden sondern eine Datenstruktur. Oft eine Liste. Wie zum Beispiel hier mit den Bildern.
Das mit den Zahlen `S` und `Y` ist alles andere als robust gelöst. Einerseits berücksichtigt der Code nur vier Bilder, andererseits ist die Obergrenze im Code die Anzahl der Dateien und Verzeichnisse in dem Verzeichnis. Da würde man eher entweder die tatsächliche Anzahl der *Bilder* ermitteln deren Dateiname eine Nummer ist und sich daran orientieren, oder fest von einer Anzahl von solchen Dateien ausgehen.
Und was den unnötigen Code angeht: der gesamte erste ``try``/``except``-Code, immerhin 48 Zeilen, scheint unnötig zu sein. Oder halt auch nicht, aber warum sollen *wir* das lesen und herausfinden müssen?
`valueh` und `valuew` sind falsch benannt. Davon abgesehen das man hier raten muss das `h` für `height` und `w` für `width` stehen soll, sind die Werte vertauscht!
Vergleiche mit literalen `True` oder `False` macht man nicht. Da kommt nur wieder ein Wahrheitswert bei heraus. Je nach Vergleichsoperation entweder der Wahrheitswert den man eh schon hatte, oder die Negation davon, also sollte man gleich den Wert nehmen, oder die Negation davon.
Dateien die man öffnet sollte man auch wieder schliessen. Die ``with``-Anweisung ist dabei hilfreich.
Pfade setzt man mit `os.path.join()` zusammen und nicht mit Zeichenkettenoperationen.
Hier das ganze mal ohne die ganzen Codewiederholungen und in einer sinnvolleren Reihenfolge (ungetestet):
`main_loop()` ist eigentlich zu lang, aber um das auf Funktionen aufteilen zu können muss man anfangen Variablen zu Objekten zusammen zu fassen, weil der Zustand aus zu vielen Werten besteht als das man die einzeln alle in der Gegend herum reichen möchte. Also `collections.namedtupel()` oder eigene Klassen.
Vergleiche mit literalen `True` oder `False` macht man nicht. Da kommt nur wieder ein Wahrheitswert bei heraus. Je nach Vergleichsoperation entweder der Wahrheitswert den man eh schon hatte, oder die Negation davon, also sollte man gleich den Wert nehmen, oder die Negation davon.
Dateien die man öffnet sollte man auch wieder schliessen. Die ``with``-Anweisung ist dabei hilfreich.
Pfade setzt man mit `os.path.join()` zusammen und nicht mit Zeichenkettenoperationen.
Hier das ganze mal ohne die ganzen Codewiederholungen und in einer sinnvolleren Reihenfolge (ungetestet):
Code: Alles auswählen
import os
import time
import pygame
from pygame.locals import *
from serial import Serial
from win32api import GetSystemMetrics
BASE_PATH = 'C:Tanzmusik'
IMAGE_SET_FILENAME = os.path.join(BASE_PATH, 'Nummer.txt')
IMAGME_NAME_TEMPLATE = os.path.join(BASE_PATH, '{}', '{}.jpg')
def main_loop():
with Serial('COM1') as serial:
size = (GetSystemMetrics(0), GetSystemMetrics(1))
screen = pygame.display.set_mode(size, pygame.FULLSCREEN)
pygame.display.set_caption('Empfänger')
pygame.mouse.set_visible(0)
clock = pygame.time.Clock()
image_set_name = None
images = None
current_image_index = None
display_new_image = False
while True:
with open(IMAGE_SET_FILENAME, 'r') as image_set_file:
new_image_set_name = next(image_set_file).strip()
if new_image_set_name != image_set_name:
image_set_name = new_image_set_name
images = list()
for i in range(1, 5):
try:
image = pygame.image.load(
IMAGME_NAME_TEMPLATE.format(image_set_name, i)
)
except pygame.error:
break
image = pygame.transform.scale(image, size)
if image.get_alpha() is None:
image = image.convert()
else:
image = image.convert_alpha()
images.append(image)
current_image_index = 0
display_new_image = True
for event in pygame.event.get():
if (
event.type == QUIT
or event.type == KEYDOWN and event.key == K_ESCAPE
):
return
next_image_flag = serial.cts
previous_image_flag = serial.dsr
if next_image_flag:
current_image_index += 1
if previous_image_flag:
current_image_index -= 1
if next_image_flag or previous_image_flag:
display_new_image = True
time.sleep(0.5)
current_image_index = current_image_index % len(images)
if display_new_image:
display_new_image = False
screen.blit(images[current_image_index], (0, 0))
pygame.display.flip()
clock.tick(20)
def main():
pygame.init()
main_loop()
pygame.quit()
if __name__ == '__main__':
main()
Eigener Datentyp für ein `ImageSet` und auf Funktionen aufgeteilt:
Code: Alles auswählen
import os
import time
from collections import namedtuple
import pygame
from pygame.locals import *
from serial import Serial
from win32api import GetSystemMetrics
BASE_PATH = 'C:/Tanzmusik'
IMAGE_SET_FILENAME = os.path.join(BASE_PATH, 'Nummer.txt')
IMAGE_NAME_TEMPLATE = os.path.join(BASE_PATH, '{}', '{}.jpg')
ImageSet = namedtuple('ImageSet', 'name images current_index size')
def get_current_image(image_set):
return image_set.images[image_set.current_index]
def change_current_image(image_set, offset):
return image_set._replace(
current_index=(
(image_set.current_index + offset) % len(image_set.images)
)
)
def load_image(filename, size):
image = pygame.transform.scale(pygame.image.load(filename), size)
if image.get_alpha() is None:
image = image.convert()
else:
image = image.convert_alpha()
return image
def load_image_set(name, size):
images = list()
try:
for i in range(1, 5):
images.append(load_image(IMAGE_NAME_TEMPLATE.format(name, i), size))
except pygame.error:
pass # Stop at first image that could not be loaded.
return ImageSet(name, images, 0, size)
def update_image_set(image_set, display_new_image):
with open(IMAGE_SET_FILENAME, 'r') as image_set_file:
new_image_set_name = next(image_set_file).strip()
if new_image_set_name != image_set.name:
image_set = load_image_set(image_set.name, image_set.size)
display_new_image = True
return image_set, display_new_image
def get_pedal(serial):
result = 0
if serial.cts:
result += 1
if serial.dsr:
result -= 1
return result
def process_pedal(serial, image_set, display_new_image):
adjustment = get_pedal(serial)
if adjustment != 0:
image_set = change_current_image(image_set, adjustment)
display_new_image = True
time.sleep(0.5)
return image_set, display_new_image
def main_loop():
with Serial('COM1') as serial:
size = (GetSystemMetrics(0), GetSystemMetrics(1))
screen = pygame.display.set_mode(size, pygame.FULLSCREEN)
pygame.display.set_caption('Empfänger')
pygame.mouse.set_visible(0)
clock = pygame.time.Clock()
image_set = ImageSet(None, None, None, size)
display_new_image = False
while True:
for event in pygame.event.get():
if (
event.type == QUIT
or event.type == KEYDOWN and event.key == K_ESCAPE
):
return
image_set, display_new_image = update_image_set(
image_set, display_new_image
)
image_set, display_new_image = process_pedal(
serial, image_set, display_new_image
)
if display_new_image:
display_new_image = False
screen.blit(get_current_image(image_set), (0, 0))
pygame.display.flip()
clock.tick(20)
def main():
pygame.init()
main_loop()
pygame.quit()
if __name__ == '__main__':
main()