python - Arduino和Python之间的通信
问题描述
我需要使用我的笔记本电脑与 Arduino 交谈(发送命令来控制状态机以制作一个简单的自动售货机)当我尝试将命令放入串行监视器时一切看起来都很好但是当我通过 python 发送命令时不是在职的。看起来状态没有像我预期的那样改变。
这是python代码:
def query():
cmd = "0"
dev = serial.Serial("COM3", 9600,timeout=5)
time.sleep(2)
dev.write(cmd.encode("utf-8"))
print("Pyhton: Query ",dev.readline())
#time.sleep(1)
#print(dev.readline())
def up():
cmd = "1"
dev = serial.Serial("COM3", 9600)
time.sleep(2)
dev.write(cmd.encode("utf-8"))
print("Pyhton: up ",dev.readline())
#time.sleep(1)
#print(dev.readline())
def pickup():
cmd = "2"
dev = serial.Serial("COM3", 9600)
time.sleep(2)
dev.write(cmd.encode("utf-8"))
print("Pyhton: pickup ",dev.readline())
#time.sleep(1)
#print(dev.readline())
def ship():
cmd = "3"
dev = serial.Serial("COM3", 9600)
time.sleep(2)
dev.write(cmd.encode("utf-8"))
print("Pyhton: ship ",dev.readline())
#time.sleep(1)
#print(dev.readline())
def origin():
cmd = "4"
dev = serial.Serial("COM3", 9600)
time.sleep(2)
dev.write(cmd.encode("utf-8"))
print("Pyhton: origin ",dev.readline())
#time.sleep(1)
#print(dev.readline())
tokenDict = {
"001":query,
"002":up,
"003":ship,
"004":pickup,
"005":origin
}
lineList = [line.rstrip('\n') for line in open("cmd.txt")]
for line in lineList:
time.sleep(1)
functionToCall = tokenDict[line]
functionToCall()
这是Arduino代码:
int cmd = 0;
enum {IDLEx, UP, PICKUP, SHIP, ORIGIN};
uint8_t STATE = IDLEx;
void setup() {
Serial.begin(9600);
//Serial.flush();
pinMode(LED_BUILTIN, OUTPUT);
}
void readSerialData() {
if (Serial.available()>0) {
delay(300);
//cmd = Serial.readStringUntil('\n');
cmd = Serial.read();
process_serial(cmd, &STATE);
//test(cmd);
}
}
void process_serial(int data, uint8_t *state)
{
switch (*state)
{
case IDLEx: {
if (data == '0') {
*state = IDLEx;
Serial.println("Arduino: IDLE");
} else if (data == '1' ) { //go to up state
*state = UP;
//Serial.println("Arduino: Up");
} else if (data == '2') {
*state = PICKUP;
//Serial.println("Arduino: PICKUP");
} else if (data == '3') {
//Serial.println("Arduino: SHIP");
*state = SHIP;
} else if (data == '4') {
//Serial.println("Arduino: ORIGIN");
*state = ORIGIN;
}
break;
}
case UP: {
Serial.println("Arduino: UP");
delay(1000);
*state = PICKUP;
break;
}
case PICKUP: {
Serial.println("Arduino: PICKUP");
delay(1000);
*state = SHIP;
break;
}
case SHIP: {
Serial.println("Arduino: SHIP");
delay(1000);
*state = ORIGIN;
break;
}
case ORIGIN: {
Serial.println("Arduino: ORIGIN");
delay(1000);
*state = IDLEx;
}
break;
}
}
void loop() {
//Serial.println(STATE);
readSerialData();
}
我从文本文件中读取了类似的命令
001
001
002
001
001
003
001
004
001
005
这是我期望的输出:
Pyhton: Query b'Arduino: IDLE\r\n'
Pyhton: Query b'Arduino: IDLE\r\n'
Pyhton: up b'Arduino: Up\r\n'
Pyhton: Query b'Arduino: Up\r\n'
Pyhton: Query b'Arduino: Up\r\n'
Pyhton: ship b'Arduino: SHIP\r\n'
Pyhton: Query b'Arduino: SHIP\r\n'
Pyhton: pickup b'Arduino: PICKUP\r\n'
Pyhton: Query b'Arduino: PICKUP\r\n'
Pyhton: origin b'Arduino: ORIGIN\r\n'
我的问题是当我将数据发送到 Arduino 时,Arduino 似乎没有更改状态(以 Swith case 作为代码)请注意我使用的是 Arduino nano 328 和 python 3.x 有人可以向我建议吗?我该如何解决这个问题?
解决方案
在您的每个功能中,您都有这一行:
dev = serial.Serial("COM3", 9600)
该行打开重置 Arduino 板的串行端口。为避免这种情况,您应该在程序开始时打开该端口一次,然后每次都继续使用相同的串行端口实例,而不是在每个函数中重新创建它。