Я хочу сделать простой двухсторонний последовательный обмен между моей малиной Pi и моим Arduino. Это для проекта, в котором я заменил Arduino другим серийным устройством, которого у меня пока нет.
Я сделал одностороннюю связь (https://maker.pro/raspberry-pi/tutorial/how-to-connect-and-interface-raspberry-pi-with-arduino) от Arduino до малины Pi, но у меня есть небольшая проблема с 2-сторонним движением. Код Arduino, который я использую, приведен в этом примере: https://www.arduino.cc/en/Serial/Read:
int incomingByte = 0; // for incoming serial data
void setup() {
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}
void loop() {
// send data only when you receive data:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
// say what you got:
Serial.print("I received: ");
Serial.println(incomingByte, DEC);
}
}
И код Python, который я использую, таков:
import serial
import time
ser = serial.Serial('/dev/ttyACM1',9600)
var1 = "3"
while True:
ser.write(var1.encode())
time.sleep(0.2)
read_serial=ser.readline()
print read_serial
Просматривая сеть, я изменил значение, которое нужно отправить из только ser.write('3') в строку 'var1' и поместить '.encode()' после этого, чтобы кодировать в байты. Ошибок не возникает, но ничего не происходит/выписывается.
Целью этого является то, что малина Pi отправит "3" в Arduino и Arduino, чтобы ответить "Я получил: 3", который должен быть напечатан в окне терминала Raspberry Pi/Python. Оттуда я предполагаю, что я могу сделать это более сложным по отношению к моей цели отправки команды следующим образом: "0 30 50 100", на которое устройство, на которое у меня нет, будет отвечать.
Я ценю любую помощь. Спасибо.
В моем проекте моя цель - установить двусторонний обмен данными между Arduino и Raspberry Pi через последовательный интерфейс. Малина Pi отправляет команду Arduino для выполнения, Arduino отправляет показания датчика малины Pi (в настоящее время случайное число).
В настоящее время проект включает два сценария для малины Pi, написанные на Python, и программу для Arduino. Первый скрипт для Raspberry Pi с использованием библиотеки URWID организует графический интерфейс и ввод команды, второй скрипт используется для связи с последовательным портом. Источники приведены ниже. Результат операции вполне удовлетворительный, но, может быть, где-то я делаю что-то неправильно? Правильно ли это решение проблемы?
Программное обеспечение Arduino:
#define SERIAL_SPEED 19200 // the speed of the serial port
#define READ_SENSOR_INTERVAL 1000UL // frequency of output to the serial port
int IN1 = 7;
int IN2 = 6;
int IN3 = 5;
int IN4 = 4;
int ENA = 9;
int ENB = 3;
char command = 'S';
char prevCommand = 'A';
int velocity = (4 + 1) * 10 + 100; // the fill factor of the PWM
unsigned long timer0 = 2000;
unsigned long timer1 = 0;
long randNumber;
long myflag = 0;
void setup() {
Serial.begin(SERIAL_SPEED);
pinMode (ENA, OUTPUT);
pinMode (IN1, OUTPUT);
pinMode (IN2, OUTPUT);
pinMode (ENB, OUTPUT);
pinMode (IN4, OUTPUT);
pinMode (IN3, OUTPUT);
}
void loop()
{
static unsigned long prevSensorTime = 0;
if (millis() - prevSensorTime > READ_SENSOR_INTERVAL) {
prevSensorTime = millis();
if (myflag == 1)
{
randNumber = random(300);
Serial.print(command);
Serial.println(randNumber);
}
}
if (Serial.available() > 0) {
timer1 = millis();
prevCommand = command;
command = Serial.read();
myflag = 1;
if (command != prevCommand) {
switch (command) {
case 'W':
// Вперёд
analogWrite(ENA, 0);
analogWrite(ENB, 0);
delay(20);
digitalWrite (IN2, LOW);
digitalWrite (IN1, HIGH);
digitalWrite (IN4, LOW);
digitalWrite (IN3, HIGH);
analogWrite(ENA, velocity);
analogWrite(ENB, velocity);
break;
case 'A':
analogWrite(ENA, 0);
analogWrite(ENB, 0);
delay(20);
digitalWrite (IN2, LOW);
digitalWrite (IN1, HIGH);
digitalWrite (IN4, HIGH);
digitalWrite (IN3, LOW);
analogWrite(ENA, velocity);
analogWrite(ENB, velocity);
break;
case 'S':
analogWrite(ENA, 0);
analogWrite(ENB, 0);
delay(20);
digitalWrite (IN2, HIGH);
digitalWrite (IN1, LOW);
digitalWrite (IN4, HIGH);
digitalWrite (IN3, LOW);
analogWrite(ENA, velocity);
analogWrite(ENB, velocity);
break;
case 'D':
analogWrite(ENA, 0);
analogWrite(ENB, 0);
delay(20);
// A
digitalWrite (IN2, HIGH);
digitalWrite (IN1, LOW);
// B
digitalWrite (IN4, LOW);
digitalWrite (IN3, HIGH);
analogWrite(ENA, velocity);
analogWrite(ENB, velocity);
break;
case ' ':
//velocity = 0;
analogWrite(ENA, 0);
analogWrite(ENB, 0);
break;
default:
if ((command >= 48) && (command <= 57)) {
if (command == 48)
{
velocity = 0;
}
else
{
velocity = (command - 48 + 1) * 10 + 100;
}
}
}
}
}
else {
timer0 = millis(); // Получение текущего времени
if ((unsigned long)(timer0 - timer1) > 20000) {
analogWrite(ENA, 0);
analogWrite(ENB, 0);
prevCommand = ' ';
}
}
}
Сценарий GUI Python
from __future__ import print_function, absolute_import, division
import subprocess
import urwid
import serial
from subprocess import Popen, PIPE
from time import sleep
def exit_on_q(key):
global power
global ser
global spower
global p
global currc
if key in ('q', 'Q'):
p.stdin.write(b'Q\n')
p.stdin.flush()
sleep(1)
raise urwid.ExitMainLoop()
if key in ('w', 'W'):
# forward
currc = 'W - Forward'
p.stdin.write(b'W\n')
p.stdin.flush()
if key in ('a', 'A'):
# Left
currc = 'A - Left'
p.stdin.write(b'A\n')
p.stdin.flush()
if key in ('s', 'S'):
# Backward
currc = - Backward'
p.stdin.write(b'S\n')
p.stdin.flush()
if key in ('d', 'D'):
# Right
currc = 'D - Right'
p.stdin.write(b'D\n')
p.stdin.flush()
if key in (' '):
# Stop
currc = 'Space - Stop'
p.stdin.write(b' \n')
p.stdin.flush()
if key in ('+'):
if (power < 99):
power = power + 10
spower = spower + 1
txt_CP.set_text(('banner', str(power)))
if key in ('-'):
if (power > 0):
power = power - 10
spower = spower - 1
txt_CP.set_text(('banner', str(power)))
txt_CCV.set_text(('banner', currc))
def enter_idle():
loop.remove_watch_file(pipe.stdout)
def update_text(read_data):
txt_Q.set_text(('banner', read_data))
if __name__ == '__main__':
currc = "No command"
palette = [
('banner', 'black', 'light gray'),
('streak', 'black', 'dark blue'),
('bg', 'black', 'dark blue'),]
# spower = 0..9 (48 .. 57)
spower = 4
power = spower * 10
txt_F = urwid.Text(('banner', u"W - Forward (\u2191)"), align='center')
txt_LRS = urwid.Text(('banner', u"\u2190 A - Left | Space - Stop | D - Right \u2192"), align='center')
txt_B = urwid.Text(('banner', u"S - Backward (\u2193)"), align='center')
txt_P = urwid.Text(('banner', u"'+' Increase motor power | '-' Decrease motor power"), align='center')
txt_C = urwid.Text(('banner', u"Current power:"), align='center')
txt_CP = urwid.Text(('banner', str(power)), align='center')
# current command
txt_CC = urwid.Text(('banner', u"Current command: "), align='center')
txt_CCV = urwid.Text(('banner', u"No command"), align='center')
txt_Log = urwid.Text(('banner', u"Log: "), align='center')
txt_LogV = urwid.Text(('banner', u""), align='center')
txt_Q = urwid.Text(('banner', u"Q - Quit"), align='center')
#empty string
txt_E = urwid.Text(('banner', u""), align='center')
pile = urwid.Pile([txt_F, txt_LRS, txt_B, txt_E, txt_P, txt_C, txt_CP, txt_E, txt_CC, txt_CCV, txt_E, txt_Log, txt_LogV, txt_E, txt_Q ])
top = urwid.Filler(pile, top = 5)
loop = urwid.MainLoop(top, palette, unhandled_input=exit_on_q, handle_mouse=False)
stdout = loop.watch_pipe(update_text)
stderr = loop.watch_pipe(update_text)
p = subprocess.Popen(['python3', 'shell_edt.py'], stdin = PIPE, stdout = stdout, stderr = stdout, shell = False)
loop.run()
Пиратский скрипт связи
import sys
import threading
import serial
from time import sleep
global currcomm
readtimer = 1 #
def read():
global serialport
global currcomm
threading.Timer(readtimer, read).start()
if (currcomm != -1):
data = serialport.read(10);
print(str(data) + " : " + str(len(data)))
sys.stdout.flush();
#sleep(0.5) '''
serialport = serial.Serial("/dev/ttyACM0", 19200, timeout=0.2)
data = serialport.read(100);
currcomm = -1
threading.Timer(readtimer, read).start()
sleep(1)
while True:
currcomm = input()
if (currcomm == 'S') or (currcomm == 'D') or (currcomm == 'W') or (currcomm == 'A') or (currcomm == ' '):
serialport.write(bytes(currcomm, encoding = 'utf-8'));
if (currcomm == 'Q'):
serialport.close() # Only executes once the loop exits
ser.write
\r
или\n
), который RasPi не отправляет?