【问题标题】:Serial Receiving from Arduino to Raspberry Pi with PySerial stops after a while一段时间后,使用 PySerial 从 Arduino 到 Raspberry Pi 的串行接收停止
【发布时间】:2013-11-20 21:46:27
【问题描述】:

我正在做一个项目,我必须一次接收大约 25 个字符的数据才能在 Raspberry Pi 中处理它。这是生成我想从 Arduino 接收的一些数据的示例代码:

char i =0;
char  a =0;
char b=0;


void setup(){

 Serial.begin(9600);
 for(i=0;i<25;i++){

    Serial.print('l');}
    Serial.print('\n');
    delay(2000);
}


void loop(){

 for(i=0;i<25;i++){
     for(a=0;a<i;a++){
      if((a==9)||(a==19)||(a==24))
          Serial.print('l');
      else
          Serial.print('d');   
     }
     for(b=0;b<25-i;b++){
          Serial.print('l');
     }


     delay(2000);
  }
}

它会发送这样的一行 'lllldddddllldddd...' 这行是 25 个字符的长度。现在,我想用 Raspberry Pi 接收这个。这是我正在尝试工作的代码:

ser = serial.Serial('/dev/AMA0',9600,timeout=1)
ser.open()

try:
   serial_data = ser.readline()
   print serial_data
except serial.serialutil.SerialException:
   pass

此代码非常正确地接收数据大约 5 秒钟,然后突然停止接收。

此外,当我尝试以下操作时,我没有得到任何输出或输入/输出错误。

serial_data = ser.readline()
print serial_data

EDIT1: 好的,我现在评论了异常。它给出了以下错误:

 raise SerialException('device reporst rediness to read but returned no data (device disconnected?)')
serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected?)

通过 PySerial 将 25 个字符的数据从 arduino 接收到 raspberry 的正确方法是什么?任何帮助将不胜感激。

【问题讨论】:

    标签: python serial-port arduino raspberry-pi pyserial


    【解决方案1】:

    我也遇到了同样的问题,而且头疼了好久,试试这个

    运行

    ps -ef | grep tty
    

    如果输出看起来像任何东西

    root      2522     1  0 06:08 ?        00:00:00 /sbin/getty -L ttyAMA0 115200 vt100
    

    那么你需要禁止 getty 尝试向该端口发送数据

    为了使用树莓派的串口,我们需要通过在文件/etc/inittab中找到这一行来禁用getty(显示登录屏幕的程序)

    T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
    

    并在前面加#注释掉

    #T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100)
    

    要防止树莓派在启动时向串口发送数据,请转到文件 /boot/cmdline.txt 并找到该行并将其删除

    console=ttyAMA0,115200 kgdboc=ttyAMA0,115200
    

    重启树莓派

    信用到期:http://blog.oscarliang.net/raspberry-pi-and-arduino-connected-serial-gpio/ 帮助我弄清楚如何禁用 getty

    【讨论】:

    • 如果你禁用 getty,而 getty 显示登录屏幕,那么你将如何登录 Pi?
    【解决方案2】:

    在 raspberry pi 中读取 gps 数据时,我不得不为此苦苦挣扎。输出将在大约 10 秒后停止并报告

     device reports readiness to read but returned no data (device disconnected?)
    

    几乎所有论坛中给出的解决方案都是针对 raspberry pi 2 with wheezy。通过执行以下操作,我终于设法在我的树莓派 pi3 中与 jessie 获得连续的 gps 流:

    1. 设置enable_uart=1并在/boot/config.txt中添加dtoverlay=pi3-disable-bt。然后重启
    2. 我不得不将我的 /boot/cmdline.txt 更改为

      dwc_otg.lpm_enable=0 console=tty1 console=serial0,9600 root=/dev/mmcblk0p7 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

      然后重启

    3. 停止盖蒂: sudo systemctl stop serial-getty@ttyAMA0.service

      禁用:sudo systemctl stop serial-getty@ttyAMA0.service

    您需要小心 /boot/cmdline.txt。文件中的任何错误都可能使您的树莓派无法启动。最好在编辑之前保留文件的备份。还要正确设置波特率。就我而言,它是 9600。希望这会有所帮助!

    【讨论】:

      【解决方案3】:

      我以前经常得到这个,然后一个朋友告诉我提示 arduino 从 python 中获取数据。

      以下说明


      考虑让 arduino 仅在您的 python 程序提示时发送数据:

      prompt.py

      #!/usr/bin/python
      import serial, time
      ser = serial.Serial('/dev/ttyACM0',  115200, timeout = 0.1)
      
      #if you only want to send data to arduino (i.e. a signal to move a servo)
      def send( theinput ):
        ser.write( theinput )
        while True:
          try:
            time.sleep(0.01)
            break
          except:
            pass
        time.sleep(0.1)
      
      #if you would like to tell the arduino that you would like to receive data from the arduino
      def send_and_receive( theinput ):
        ser.write( theinput )
        while True:
          try:
            time.sleep(0.01)
            state = ser.readline()
            print state
            return state
          except:
            pass
        time.sleep(0.1)
      
      f = open('dataFile.txt','a')
      
      while 1 :
          arduino_sensor = send_and_receive('1')
          f.write(arduino_sensor)
          f.close()
          f = open('dataFile.txt','a')
      

      prompt.ino

      void setup () {   pinMode(13, OUTPUT);   Serial.begin(115200); } 
          void loop() {
      
        if (Serial.available())    {
      
           ch = Serial.read();
      
           if ( ch == '1' ) { 
             Serial.println(analogRead(A0)); // if '1' is received, then send back analog read A0
           } 
           else if (ch == '2') {    
             digitalWrite(13,HIGH); // if '2' is received, turn on the led attached to 13
           } 
           else if (ch == '3') {
             digitalWrite(13,LOW); // if '3' is received then turn off the led attached 13
           } else {
             delay(10);
           }
         }    
      }
      

      另外,我创建了一个 github 存储库,其中包含一些用于 python-arduino 通信的更多示例:

      https://github.com/gskielian/Arduino-DataLogging/blob/master/PySerial/README.md

      【讨论】:

        【解决方案4】:

        Arduino 代码中的loop 函数期间,您永远不会结束换行符\n,这只是ser.readline() 的问题,因为它会一直读取到\n 字符。

        在您的 setup 函数中,您正确发送了一个 \n 字符,它可以解释正在发送的初始值,但不能解释数据。

        也许像这样修改你的 Arduino 代码:

        void loop(){
            for(i=0;i<25;i++){
                for(a=0;a<i;a++){
                    if((a==9)||(a==19)||(a==24)) {
                      Serial.print('l');
                    } else {
                        Serial.print('d');   
                    }
                } /*end for loop a*/
                for(b=0;b<25-i;b++){
                    Serial.print('l');
                } /*end for loop b*/
        
                Serial.print('\n'); // CODE EDITED HERE
                delay(2000);
            }    
        }
        

        你的 python 代码是这样的......

        ser = None
        try:
            ser = serial.Serial('/dev/AMA0',9600,timeout=3)
            ser.open()
        
            while True:
                try:
                    serial_data = ser.readline()
                    print serial_data
                except:
                    pass
        except:
            pass    
        finally:
            if ser:
                ser.close()
        

        【讨论】:

        • 其实我之前确实用过。覆盆子方面没有任何变化。奇怪的是,我在 5 秒内完全按照我的意愿接收数据。然后,即使我确保 Arduino 继续传输,数据也会突然停止接收。
        • @mozcelikors 也许您可以尝试将您的timeout 提高到大于 2 的值,因为您将 Arduino 延迟了那么久?在你的python代码中添加一个打印语句或其他东西到你的except中也是值得的(只是为了调试),也许串行最终会遇到异常。我最近做的一个 Arduino 项目遇到了这个问题。
        • @mozcelikors =( ...我很感兴趣...我回家后要拿出我的arduino。
        • 好的,我现在评论了异常。它给出了以下错误:raise SerialException('device reporst rediness to read but returned no data (device disconnected?)') serial.serialutil.SerialException: device reporst rediness to read but returned no data (device disconnected?)
        • @mozcelikors 你试过在你的Arduino代码中降低delay吗?
        【解决方案5】:

        试试sudo rasbpi-config, 选择接口选项,对第一条消息说“不”(“内核登录”),对第二条消息说“是”(“串行通信开启”)。我发现如果第一条消息在它上面会引发错误。说“不”可以解决问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-30
          • 2021-08-16
          • 2015-10-21
          • 2018-01-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多