当我试图找出如何让按钮按下后使用GPIO引脚发送左或右按键时,我偶然发现了this question。
似乎所选择的链接问题的答案是我需要让我继续但是在安装xautomation之后,尝试将代码调整到我的脚本并阅读Popen的文档(我甚至尝试运行新文件随着代码逐字)我不断收到以下错误:
Traceback (most recent call last):
File "/home/zdistaging/Documents/xte test.py", line 17, in <module>
keypress(shift_a_sequence)
File "/home/zdistaging/Documents/xte test.py", line 15, in keypress
p.communicate(input=sequence)
File "/usr/lib/python3.4/subprocess.py", line 941, in communicate
self.stdin.write(input)
TypeError: 'str' does not support the buffer interface
我正在使用Pixel的Raspbian Jessie(从raspberrypi.org下载)在Pi 3模型B上运行Python3
任何想法为什么会出错?
如果它有所帮助,我所要做的就是允许用户在FEH幻灯片中左右滚动......考虑到这个看起来很简单的任务,我可能完全不合适。我不是在寻找有人为我彻底解决这个问题 - 我喜欢与编码相关的挑战 - 我只是对python的新手;在正确的方向上推动我会非常有帮助。
非常感谢任何帮助!!!
编辑:很抱歉不包含该代码!
from subprocess import Popen, PIPE
control_f4_sequence = '''keydown Control_L
key F4
keyup Control_L
'''
shift_a_sequence = '''keydown Shift_L
key A
keyup Shift_L
'''
def keypress(sequence):
p = Popen(['xte'], stdin=PIPE)
p.communicate(input=sequence)
keypress(shift_a_sequence)
keypress(control_f4_sequence)
编辑编辑:
这是我的更新代码......它实际上是为按下左右按钮打印空格。
import time
import RPi.GPIO as GPIO
from subprocess import Popen, PIPE
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
leftArrow = '''key \x1B[D''' # I've tried '''key Left'''
rightArrow = '''key \x1B[C''' # and '''key Right''' with the same results
offButton = 26 # Black wire
onButton = 19 # White wire
leftButton = 13 # Red wire
rightButton = 6 # Green wire
def keypress(sequence):
if isinstance(sequence, str):
sequence = sequence.encode('ascii')
p = Popen(['xte'], stdin=PIPE)
p.communicate(input=sequence)
GPIO.setup( offButton, GPIO.IN, GPIO.PUD_UP )
GPIO.setup( onButton, GPIO.IN, GPIO.PUD_UP )
GPIO.setup( leftButton, GPIO.IN, GPIO.PUD_UP )
GPIO.setup( rightButton, GPIO.IN, GPIO.PUD_UP )
while True:
offButton_state = GPIO.input( offButton )
onButton_state = GPIO.input( onButton )
leftButton_state = GPIO.input( leftButton )
rightButton_state = GPIO.input( rightButton )
if offButton_state == GPIO.LOW:
print( "Off button pressed" )
if onButton_state == GPIO.LOW:
print( "On button pressed" )
if leftButton_state == GPIO.LOW:
keypress(leftArrow)
print( "Left button pressed" )
if rightButton_state == GPIO.LOW:
keypress(rightArrow)
print( "Right button pressed" )
time.sleep( 1 )
我已经阅读了subprocess and Popen.communicate(),但无法确定问题是与该问题有关还是与xte is expecting as an argument有关。想法?
答案 0 :(得分:1)
错误表明您的控制序列是字符串(即unicode),但Subprocess似乎期望字节。
在函数 protected void ReaderFPMachine()
{
_readerCollection = ReaderCollection.GetReaders();
foreach (Reader Reader in _readerCollection)
{
_fPMachineID = Reader.Description.SerialNumber;
break;
}
this.CheckFingerPrint();
}
protected void CheckFingerPrint()
{
try
{
_finger = null;
_reader = _readerCollection[0];
if (!OpenReader())
{
//this.Close();
}
if (!StartCaptureAsync(this.OnCaptured))
{
//this.Close();
}
}
catch (Exception ex)
{
}
}
private void OnCaptured(CaptureResult captureResult)
{
try
{
_finger = null;
// Check capture quality and throw an error if bad.
if (!CheckCaptureResult(captureResult)) return;
//SendMessage(Action.SendMessage, "A finger was captured.");
DataResult<Fmd> resultConversion = FeatureExtraction.CreateFmdFromFid(captureResult.Data, Constants.Formats.Fmd.ANSI);
if (resultConversion.ResultCode != Constants.ResultCode.DP_SUCCESS)
{
_reset = true;
throw new Exception(resultConversion.ResultCode.ToString());
}
_finger = resultConversion.Data;
_fingerPrintID = Fmd.SerializeXml(_finger);
//MsVisitorHd _msVisitorHd = this._vMSBL.GetSingleMsVisitorHdByFingerPrintID(_fingerXML);
//List<MsVisitorHd> _listMsVisitorHd = this._vMSBL.GetListMsVisitorHd();
bool _exist = false;
//foreach (var _item in _listMsVisitorHd)
//{
// Fmd _fmd = Fmd.DeserializeXml(_fingerPrintID);
// Fmd _fmd2 = Fmd.DeserializeXml(_item.FingerPrintID);
// CompareResult compareResult = Comparison.Compare(_fmd, 0, _fmd2, 0);
// if (compareResult.ResultCode != Constants.ResultCode.DP_SUCCESS)
// {
// _reset = true;
// throw new Exception(compareResult.ResultCode.ToString());
// }
// else
// {
// if (compareResult.Score < (PROBABILITY_ONE / 100000))
// {
// //_visitorExist = new MsVisitorHd();
// //_visitorExist = _item;
// _exist = true;
// break;
// }
// else
// {
// }
// }
//}
if (!CheckCaptureResult(captureResult)) return;
// Create bitmap
foreach (Fid.Fiv fiv in captureResult.Data.Views)
{
this.FingerPictureBox.BackgroundImage = CreateBitmap(fiv.RawImage, fiv.Width, fiv.Height);
}
if (_exist)
{
_fgMember = "Y";
//MessageBox.Show("Sidik jadi terdaftar sebagai " + _visitorExist.VisitorName);
}
else
{
_fgMember = "N";
}
//SendMessage(Action.SendMessage, secondFinger.Bytes.ToString() + "Comparison resulted in a dissimilarity score of " + compareResult.Score.ToString() + (compareResult.Score < (PROBABILITY_ONE / 100000) ? " (fingerprints matched)" : " (fingerprints did not match)"));
//SendMessage(Action.SendMessage, "Place a finger on the reader.");
// count = 0;
//}
}
catch (Exception ex)
{
// Send error message, then close form
//SendMessage(Action.SendMessage, "Error: " + ex.Message);
}
}
public bool OpenReader()
{
_reset = false;
Constants.ResultCode result = Constants.ResultCode.DP_DEVICE_FAILURE;
// Open reader
result = _reader.Open(Constants.CapturePriority.DP_PRIORITY_COOPERATIVE);
if (result != Constants.ResultCode.DP_SUCCESS)
{
MessageBox.Show("Error: " + result);
_reset = true;
return false;
}
return _reset;
}
public void GetStatus()
{
Constants.ResultCode result = _reader.GetStatus();
if ((result != Constants.ResultCode.DP_SUCCESS))
{
_reset = true;
throw new Exception("" + result);
}
if ((_reader.Status.Status == Constants.ReaderStatuses.DP_STATUS_BUSY))
{
Thread.Sleep(50);
}
else if ((_reader.Status.Status == Constants.ReaderStatuses.DP_STATUS_NEED_CALIBRATION))
{
_reader.Calibrate();
}
else if ((_reader.Status.Status != Constants.ReaderStatuses.DP_STATUS_READY))
{
throw new Exception("Reader Status - " + _reader.Status.Status);
}
}
public bool CheckCaptureResult(CaptureResult captureResult)
{
if (captureResult.Data == null)
{
if (captureResult.ResultCode != Constants.ResultCode.DP_SUCCESS)
{
_reset = true;
throw new Exception(captureResult.ResultCode.ToString());
}
// Send message if quality shows fake finger
if ((captureResult.Quality != Constants.CaptureQuality.DP_QUALITY_CANCELED))
{
throw new Exception("Quality - " + captureResult.Quality);
}
return false;
}
return true;
}
public bool CaptureFingerAsync()
{
try
{
GetStatus();
Constants.ResultCode captureResult = _reader.CaptureAsync(Constants.Formats.Fid.ANSI, Constants.CaptureProcessing.DP_IMG_PROC_DEFAULT, _reader.Capabilities.Resolutions[0]);
if (captureResult != Constants.ResultCode.DP_SUCCESS)
{
_reset = true;
throw new Exception("" + captureResult);
}
return true;
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
return false;
}
}
public Bitmap CreateBitmap(byte[] bytes, int width, int height)
{
byte[] rgbBytes = new byte[bytes.Length * 3];
for (int i = 0; i <= bytes.Length - 1; i++)
{
rgbBytes[(i * 3)] = bytes[i];
rgbBytes[(i * 3) + 1] = bytes[i];
rgbBytes[(i * 3) + 2] = bytes[i];
}
Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
for (int i = 0; i <= bmp.Height - 1; i++)
{
IntPtr p = new IntPtr(data.Scan0.ToInt64() + data.Stride * i);
System.Runtime.InteropServices.Marshal.Copy(rgbBytes, i * bmp.Width * 3, p, bmp.Width * 3);
}
bmp.UnlockBits(data);
return bmp;
}
public bool StartCaptureAsync(Reader.CaptureCallback OnCaptured)
{
// Activate capture handler
_reader.On_Captured += new Reader.CaptureCallback(OnCaptured);
// Call capture
if (!CaptureFingerAsync())
{
return false;
}
return true;
}
#endregion
中,将序列转换为字节,如下所示:
keypress
有关字节,字符串和unicode的非常好的文章可以在这里找到:https://nedbatchelder.com/text/unipain.html
答案 1 :(得分:0)
我一直在查看相同的示例,这是我的6个按钮的工作示例:(它有些混乱,但我的调试行也可以帮助其他人)
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
from Xlib import X
from subprocess import Popen, PIPE
buttons = [18, 23, 24, 25, 8, 7 ]
opcodes = ['next', 'enter', 'alt tab', 'previous', 'spacebar', 'shift' ]
opcodes2 = ['key Left ', 'key Up ', 'key Down ', 'key Right ', 'key Enter ', 'key Shift_L ']
# set the gpio pins
for button in buttons:
GPIO.setup(button, GPIO.IN, GPIO.PUD_UP )
def keypress(sequence):
#if isinstance(sequence, str):
#sequence = sequence.encode('ascii')
p = Popen(['xte', '-x:0'], stdin=PIPE)
p.communicate(input=sequence)
def main():
while True:
button_state = []
for button in buttons:
button_state.append(GPIO.input(button))
for item in range(len(button_state)):
if button_state[item] == 0:
print (opcodes2[item] ) #debugging
# send X key for keystroke in (for the given iteration of the loop) opcodes[button.output(index)]
#print (repr(str(opcodes2[item]).encode('ascii')))
keypress(str(opcodes2[item]).encode('ascii'))
print (repr(button_state)) #for debugging
time.sleep(0.3)
del button_state
if __name__ == '__main__':
main()
注意每个命令的opcodes2中的尾随空格(可以是任何字符)。 ascii编码放弃了我的最后一个字符,所以这是我有点难看的解决方法。