Python PySerial程序无法正确读取数据

2024-09-28 01:25:18 发布

您现在位置:Python中文网/ 问答频道 /正文

在我深入了解正在发生的事情、问题以及我为解决问题所采取的步骤之前,下面是我在项目中使用的设备的简要概述

我使用的设备:

红外编码器:https://www.amazon.ca/dp/B07B3PLZZ2/ref=cm_sw_r_oth_api_glt_i_NCFT5KHJBARTBC76XG7Y?_encoding=UTF8&psc=1

Arduino Mega 2560 w/9V 1A电源适配器:https://www.amazon.ca/gp/product/B01H4ZDYCE/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1

电脑:MacBookPro 2020,M1芯片,8GB内存

IDE:Pycahrm社区版

Python解释器:Python 3.8

背景:

我有一个风扇,它以恒定的速度旋转。拦截风扇叶片是我连接到Arduino的红外编码器。当刀片通过红外编码器旋转时,我编写的Arduino脚本应该在传感器被触发时打印“1”,否则打印“0”

这个很好用

现在,我希望能够在Python中使用这个“1”和“0”数据,因为我有一个视频游戏的想法,我想用Pygame制作一个原型

在Pycharm上,我安装了pyserial,以便能够访问所有数据。为了捕获Pycharm中的1和0,我编写了以下代码:

变数

serialInst = serial.Serial()
serialInst.port = '/dev/cu.usbmodem11301'
serialInst.baudrate = 9600
serialInst.timeout = 0.5
serialInst.open()

读取数据功能

def readData(self):

    if serialInst.inWaiting():

        packet = serialInst.readline()

        if int(packet.decode('utf').rstrip('\n')) == 1:
            
            print('1')

        elif int(packet.decode('utf').rstrip('\n')) == 0:

            print('0')

它的工作方式相当简单。如前所述,如果风扇触发传感器,Arduino将输出一个“1”,然后Python读取数据并用if语句确认

未触发传感器时的相同操作

问题

此函数是python代码的主while循环中调用的第一个函数。在循环到readData函数之前,还有其他函数在后面被调用,但是当调用这些函数时,几乎就像Arduino数据停止检查是否有任何更改一样

问题是什么样子的

No matter if the fan's blades go through the sensor, the output is always 0

如果我注释掉主while循环中使用的任何函数,那么一切都可以100%正常工作。只有当我开始在主while循环中引入其他函数时,问题才会发生

我试过的

我目前打开了9个其他标签页,上面有人们在StackOverflow上报告的类似Pyserial问题,下面是我读过并尝试过的一些事情:

  • 正在添加serialInst.timeout值。我玩过从0.01到0.5的各种数字,但都没有成功

  • 在各种不同的位置使用serialInst.reset\u output\u buffer()、serialInst.flushOutput()、serialInst.reset\u input\u buffer()或serialInst.flushInput()

  • 我尝试了很多可能的解决方案,但是,这是我的问题更严重的时候。。。以前,我在另一个类中使用readData函数作为类的一部分,但是,每次我尝试从主while循环运行它时,它都会跳过数据,不提供任何数据,显示非常奇怪的字符。。。那只是一场噩梦

现在我在主游戏类中有了readData函数,只需要解决最后一个问题,一切都会正常工作

总结

我有一个名为readData的python函数,它读取来自Arduino的数据,Arduino是“1”或“0”。当readData是我程序的main while循环中唯一被调用的函数时,一切正常;应该存在时有“1”,应该存在时有“0”

当我取消注释while循环中必须使用的其他函数时,问题就出现了

程序肯定会在整个while循环中循环,但是,当它到达readData函数时,它只会在读取“0”时“卡住”。。。即使应该有一个“1”

我需要什么

readData函数if语句应正确打印“1”或“0”,无论主while循环中的其他函数是否被注释掉

我需要“解冻”阻碍这部分计划的任何东西

如果你需要更多的信息,请告诉我。我真的很感谢你抽出时间

更新

似乎在调用其他函数时,一切都正常。但是,当我可以使用pygame.display.update()时,arduino数据开始“冻结”

我不确定为什么更新游戏屏幕会导致程序停止工作

我还在Arduino代码中添加了一个Serial.flush()。。。如果这有帮助的话


Tags: the数据函数代码程序ifpacket传感器
1条回答
网友
1楼 · 发布于 2024-09-28 01:25:18

解决了这个问题

我错误地认为是我在while循环中调用的其他函数导致了问题

事实证明,当我取消注释其他函数时,我的代码按预期运行:

风扇触发传感器时为1,没有传感器活动时为0

那么到底是什么问题呢

有几件事:

一,。pygame.display.update()

当我取消对pygame.display.update()的注释时,我的realData()函数(输出1和0的函数)将“冻结”

看起来是这样的:

0
0
0
0
0
0
0

即使风扇明显撞击了传感器,它也不会检测到“1”

为什么,我还是不知道。。。但我找到了一条过去的路

为了解决这个问题,我添加了以下内容:

serialInst.reset_input_buffer()

到realData()函数的末尾

在此之后,我遇到了一个新问题:

数据输出了1、0和一堆我不想要的空格。它看起来是这样的:

1
0
0
0
0

0

0


0

1

0

1

我不想要这些空格,因为我的realData()函数是用某些if语句编程的,如果有1或0,这些if语句将执行某些任务。。。不是换行符/空格

发生这种情况的原因是因为Arduino

以下是导致问题的Arduino端的代码:

void loop() {
  // read the state of the pushbutton value:
  x = digitalRead(sensor);

  // check if the fan hit the sensor. If it is, the sensor is HIGH:
  if (sensor == HIGH) {
     
    Serial.print(1);

  } else {
    
    Serial.print(0);

  }

}

问题是,我在使用:

Serial.println(1)

// and

Serial.println(0)

这会告诉Pycharm我想发送1、0和新行。因此,我将该代码更改为:

Serial.print(1)

// and

Serial.print(0)

这消除了Pycharm接收随机新行的可能性

之后,Pycharm方面还有两个问题需要解决,这很容易:

而不是通过以下方式在Pycharm中捕获数据:

packet = serialInst.readline()

我用过:

packet = serialInst.read()

最后一部分是简单地解码消息,因为它将输出如下内容:

b'0'
b'0'
b'0'
b'1'
b'0'
b'0'

所以我简单地用了:

x = int(packet.decode('utf'))

最终产品如下所示:

0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
1
0
0

等等

现在,我可以使用if语句进一步推进我的游戏,具体取决于输出中是“1”还是“0”

现在很完美了。我真的希望这能帮助那些遇到与我相同问题的人

相关问题 更多 >

    热门问题