web-dev-qa-db-ja.com

PySerialを使用したArduinoからRaspberryPiへのシリアル受信はしばらくすると停止します

Raspberry Piで処理するために、一度に約25文字のデータを受信する必要があるプロジェクトに取り組んでいます。 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);
  }
}

'llllddddllldddd ...'のような行を送信します。この行の長さは25文字です。さて、これをRaspberryPiで受け取りたいです。これが私が動かそうとしているコードです:

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を介してarduinoからラズベリーに25文字のデータを受信する正しい方法は何ですか?どんな助けでも大歓迎です。

10
mozcelikors

私は同じ問題を抱えていて、しばらく頭を骨折していました、これを試してください

実行

ps -ef | grep tty

出力が次のようになっている場合

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

次に、gettyがそのポートにデータを送信しようとするのを無効にする必要があります

Raspberry Piのシリアルポートを使用するには、ファイル/ etc/inittabでこの行を見つけて、getty(ログイン画面を表示するプログラム)を無効にする必要があります。

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

そして、その前に#を追加してコメントアウトします

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

Raspberry Piが起動時にシリアルポートにデータを送信しないようにするには、ファイル/boot/cmdline.txtに移動し、その行を見つけて削除します。

console=ttyAMA0,115200 kgdboc=ttyAMA0,115200

RaspberryPiを再起動します

クレジットが必要なクレジット: http://blog.oscarliang.net/raspberry-pi-and-arduino-connected-serial-gpio/ ゲッティをダイアブルする方法を理解するのに役立ちました

12
user2387729

Raspberry Piでgpsデータを読み取るときに、これに苦労しなければなりませんでした。出力は約10秒後に停止し、レポートします

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

ほとんどすべてのフォーラムで提供されているソリューションは、wheezyを使用したRaspberry Pi2用です。私はついに、次のことを行うことで、ジェシーと一緒にRaspberryPi3で継続的な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 [email protected]

    無効にするには:Sudo systemctl stop [email protected]

/boot/cmdline.txtに注意する必要があります。ファイルに誤りがあると、RaspberryPiが起動しなくなる可能性があります。編集する前にファイルのバックアップを保持することをお勧めします。また、ボーレートを適切に設定してください。私の場合は9600でした。これがお役に立てば幸いです。

2
Chandan Purohit

私はこれをたくさん手に入れていましたが、友人から、Pythonからのデータをarduinoに要求するように言われました。

以下の説明


pythonプログラムによってプロンプトが表示された場合にのみ、arduinoにデータを送信させることを検討してください。

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);
     }
   }    
}

また、python-arduino通信の例をいくつか含むgithubリポジトリを作成しました。

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

1
gskielian

loopコードのArduino関数の間、改行文字\nを終了することはありません。これは、\n文字まで読み取るため、ser.readline()でのみ問題になります。

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()
0
Farmer Joe