我正在研究一个python脚本,该脚本监视Arduino 101板载加速度计的串行输入。它已根据为不同的Arduino硬件编写的脚本改编(可以在here中找到)。
检测到更改时,当检测到更改时,python脚本将运行display.exe
(或在Linux上为XRandR
)来旋转显示。这需要与Linux和Windows一起使用。
arduino将一个字符串写入序列为<right>
,<left>
,<normal>
和<inverted>
。这些值可以在Linux上的XRandR上正常工作,但是display.exe需要度值(0、90、180、270)。因此,当direction
== normal
时,应将其转换为0
... left
至90
,依此类推。
在我的情况下,原始代码中使用的“翻译”不起作用(在将其调整为与我的arduino的输出匹配之后),但这是一个示例供参考:
translation = {"Y_POS":"90",
"X_POS":"180",
"X_NEG":"0",
"Y_NEG":"270"}
我将每个输入值(例如,从Y_POS
更改为left
),由于此操作不起作用,目前,我正在为{{1 }}。必须有一种不太冗长的方法来实现这一目标。如何做到这一点而又不必重复不必要的事情?
direction
使用# This python3.4 script is the computer-side component of my
# auto-rotating display project, which rotates a computer display
# automatically when the physical monitor is rotated
# Terminate this script before trying to program the Arduino.
# Similarly, do not have the Arduino serial viewer open whilst this script is
# running
import serial
import string
import time
from subprocess import call # for sending the command to rotate
import traceback # for debugging
# This function tries to initialise a serial connection on dev
# If no device is connected, it will fail
# If a non-Arduino device is connected there, it may connect
def initSerial(dev):
ser = serial.Serial(dev, 9600, timeout=1,
xonxoff=False, rtscts=False, dsrdtr=False)
ser.flushInput()
ser.flushOutput()
return ser
# This function tries to initialise a serial connection
# It blindly tries to connect to anything on possibleDevices
# If if fails, it waits then tries again.
# This function does not return until it succeeds
def waitForSerialInit():
# The Arduino can appear on any of these ports on my computer
# It may appear on different ports for you.
# To figure out which ones to use,
# 1) open the Arduino IDE
# 2) Click on Tools > Serial Port
# The devices listed there are what you should type here
possibleDevices = ["COM6", "COM3"] # Windows
# possibleDevices = ["/dev/ttyACM0","/dev/ttyACM1","/dev/ttyACM2"] # Linux
while True:
for dev in possibleDevices:
try:
ser = initSerial(dev)
print("device found on " + dev)
return ser
except Exception:
print("Failed to initialise device on " + dev)
time.sleep(5)
# depending on what orientation your accelerometer is relative to your monitor,
# you may have to adjust these.
# This is for when the Y axis points to the top of the monitor,
# And the bottom of the Arduino is against the monitor back
#
# The second string on each of these lines are the arguments sent in the
# terminal command to rotate. So if you want to try this on Mac or Windows,
# this is one of the things you'll need to change
#
# Only some of the stuff the Arduino sends will be a command
# Other stuff is just diagnostics
# We only want to rotate the display when the line starts and ends with
# these substrings. These must match what's in monitor.ino
line_start = "Rotate Monitor <"
line_end = ">"
# Ok, let's go.
# Start by initialising a serial connection to the Arduino
ser = waitForSerialInit()
while True:
try:
line = ser.readline().decode("utf-8")
except Exception:
# It's probably been unplugged
#
# But this also catches other types of errors,
# Which is not ideal.
print("error: ")
traceback.print_exc()
print("probably not plugged in")
time.sleep(5)
print("trying to init serial again")
ser = waitForSerialInit()
continue
if line == "":
continue # ignore empty lines
# print line for debugging purposes
print("line: " + line)
# check if the line starts with the special command start
if line.find(line_start) == 0:
#yes this is a command
direction = line.replace(line_start,"")
direction = direction[0:direction.find(line_end)]
print("direction: " + direction)
# check the direction is valid (so not NOT_SURE)
if direction == "normal":
command = "C:\Rotaytor\display.exe /device 2 /rotate:0"
print("running: " + command)
call(command, shell=True)
elif direction == "left":
command = "C:\Rotaytor\display.exe /device 2 /rotate:90"
print("running: " + command)
call(command, shell=True)
elif direction == "inverted":
command = "C:\Rotaytor\display.exe /device 2 /rotate:180"
print("running: " + command)
call(command, shell=True)
elif direction == "right":
command = "C:\Rotaytor\display.exe /device 2 /rotate:270"
print("running: " + command)
call(command, shell=True)
else:
print("invalid direction: " + direction)
print("ignoring")
时错误输出为:
translation = {"normal":"0, ...}
答案 0 :(得分:1)
您应该可以将每个if / elif替换为:
command = "C:\Rotaytor\display.exe /device 2 /rotate:" + translation[direction]
print("running: " + command)
call(command, shell=True)
基于字典:
translation = {"normal": 0, ...}
第96行开始将是:
if line.find(line_start) == 0:
#yes this is a command
direction = line.replace(line_start,"")
direction = direction[0:direction.find(line_end)]
print("direction: " + direction)
translation = {"normal": 0, ...}
# check the direction is valid (so not NOT_SURE)
if direction in translation:
command = "C:\Rotaytor\display.exe /device 2 /rotate:" + translation[direction]
print("running: " + command)
call(command, shell=True)
else:
print("invalid direction: " + direction)
print("ignoring")