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文字のデータを受信する正しい方法は何ですか?どんな助けでも大歓迎です。
私は同じ問題を抱えていて、しばらく頭を骨折していました、これを試してください
実行
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/ ゲッティをダイアブルする方法を理解するのに役立ちました
Raspberry Piでgpsデータを読み取るときに、これに苦労しなければなりませんでした。出力は約10秒後に停止し、レポートします
device reports readiness to read but returned no data (device disconnected?)
ほとんどすべてのフォーラムで提供されているソリューションは、wheezyを使用したRaspberry Pi2用です。私はついに、次のことを行うことで、ジェシーと一緒にRaspberryPi3で継続的なgpsストリーミングを取得することができました。
enable_uart=1
を設定し、/ boot /config.txtにdtoverlay=pi3-disable-bt
を追加します。その後、再起動します/boot/cmdline.txtを次のように変更する必要がありました
dwc_otg.lpm_enable=0 console=tty1 console=serial0,9600 root=/dev/mmcblk0p7 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
その後、再起動します
ゲッティを止める:Sudo systemctl stop [email protected]
無効にするには:Sudo systemctl stop [email protected]
/boot/cmdline.txtに注意する必要があります。ファイルに誤りがあると、RaspberryPiが起動しなくなる可能性があります。編集する前にファイルのバックアップを保持することをお勧めします。また、ボーレートを適切に設定してください。私の場合は9600でした。これがお役に立てば幸いです。
私はこれをたくさん手に入れていましたが、友人から、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
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()