使用串行通信在python和arduino之间进行同步
我有一个应用程序,我需要:使用串行通信在python和arduino之间进行同步,python,arduino,serial-port,synchronization,Python,Arduino,Serial Port,Synchronization,我有一个应用程序,我需要: 使用arduino将伺服电机移动到某个位置,并在该位置停止 让python控制的摄像头在该位置获取图像 获取图像时,伺服应移动到对称位置 该序列重复N次 所以我尝试使用串行通信来同步arduino和python代码。在arduino端,当伺服到达某个位置时,它使用串行通信向python代码发送一个字符串。根据到达的位置,字符串为“交叉”或“Co”。arduino应等待python代码通过串行通信发送字符串“Ok”(图像采集后)。收到该字符串后,arduino应启动伺服
因此,我想知道同步这两个代码的最佳方法是什么,并确保我的图像的正确名称将对应于伺服的正确位置 提前感谢您提供的任何链接或想法 格雷格 阿杜伊诺代码 `
#包括
//伺服
伺服myservo;//创建伺服对象以控制伺服
//大多数电路板上可以创建12个伺服对象
int pos=0;//变量来存储伺服位置
//摄像机
常数int CameraPin=53;//摄像机触发的次数
int CameraState=低;//用于设置LED的LED状态
常数int ledPin=13;//LED引脚的编号
字符串Str=“c”;
无效设置(){
myservo.attach(9);//将针脚9上的伺服连接到伺服对象
//将数字LED引脚设置为输出:
pinMode(CameraPin,输出);
//将数码相机引脚设置为输出:
引脚模式(LED引脚,输出);
//串行通信
Serial.begin(9600);
Serial.println(“就绪”);
}
void循环(){
Serial.flush();
//转到同一位置并等待
ServoCo(15);//转到Co位置
Serial.println(“Co”);//将信号Co发送到python
而(!Serial.available()){}//等待python发送获取的数据
当((Serial.available()在loop()
函数中时,您已经实现了您的软件,因为该函数将作为控制台软件中的main()
执行一次
由于Arduino(C语言)必须通过串行链路与计算机(Python语言)通信,因此一个有效的解决方案是使用状态机原则
步骤1-定义所需状态列表以及要达到的位置数
一个简单的enum e_State
允许定义列表
对于要到达的两个位置,使用枚举e_Pos
:
步骤2-定义启动参数
要在loop()
调用之间存储持久数据,static
变量
使用的是:
要临时存储下一个状态,请添加eState NextState
在loop()
函数的输入处,NextState=LoopState;
to
默认情况下保持相同的状态
步骤3-定义状态机算法
void loop() {
static eState LoopState = STATE_START; // to store the current state
static ePos ServoPos = FIRST_POS; // to store the selected position
eState NextState = LoopState;
switch (LoopState) {
case STATE_START:
ServoPos = FIRST_POS;
NextState = STATE_MOVE_POS;
break;
case STATE_MOVE_POS:
NextState = STATE_SEND_CMD;
break;
case STATE_SEND_CMD:
NextState = STATE_WAIT_ACK;
break;
case STATE_WAIT_ACK:
// NextState = STATE_MOVE_POS;
break;
default:
// when undefined state, restart
NextState = STATE_START;
}
// define the state for the next loop
LoopState = NextState;
}
步骤4-使用所选的ServoPos
管理状态移动位置的操作
switch (ServoPos) {
case FIRST_POS:
ServoCo(15); // go to 'Co' position
break;
case SECOND_POS:
ServoCross(15); // go to 'Cross' position
break;
};
NextState = STATE_SEND_CMD; // when reached, send serial message
Serial.flush(); // clear the serial buffer
if (ServoPos == FIRST_POS) {
Serial.println("Co"); //send signal 'Co' to python
}
else {
Serial.println("Cross"); //send signal 'Cross' to python
}
NextState = STATE_WAIT_ACK;
步骤5-根据到达的伺服位置
管理状态_SEND_CMD
的操作
switch (ServoPos) {
case FIRST_POS:
ServoCo(15); // go to 'Co' position
break;
case SECOND_POS:
ServoCross(15); // go to 'Cross' position
break;
};
NextState = STATE_SEND_CMD; // when reached, send serial message
Serial.flush(); // clear the serial buffer
if (ServoPos == FIRST_POS) {
Serial.println("Co"); //send signal 'Co' to python
}
else {
Serial.println("Cross"); //send signal 'Cross' to python
}
NextState = STATE_WAIT_ACK;
步骤6-通过查找确认“OK”来管理状态等待确认的操作
(可选)添加比较if(Str==“OK”)
以确保
电脑答对了
Arduino是否将接收到的Ok
发送回?Serial.available()是的,我希望代码在while循环中等待,而只有2个字节,当有3个字节时就会返回(如“Ok\n”)。当你说清除缓冲区时,你的意思是刷新它吗?Arduino循环的体系结构()
函数不符合该函数的定期调用。注意:该函数中的开括号数似乎不等于闭括号数。Arduino源代码是否编译无误?如果没有,则在ServoCo()中缺少最后一个闭括号。
void loop() {
static eState LoopState = STATE_START; // to store the current state
static ePos ServoPos = FIRST_POS; // to store the selected position
eState NextState = LoopState;
switch (LoopState) {
case STATE_START:
ServoPos = FIRST_POS;
NextState = STATE_MOVE_POS;
break;
case STATE_MOVE_POS:
NextState = STATE_SEND_CMD;
break;
case STATE_SEND_CMD:
NextState = STATE_WAIT_ACK;
break;
case STATE_WAIT_ACK:
// NextState = STATE_MOVE_POS;
break;
default:
// when undefined state, restart
NextState = STATE_START;
}
// define the state for the next loop
LoopState = NextState;
}
switch (ServoPos) {
case FIRST_POS:
ServoCo(15); // go to 'Co' position
break;
case SECOND_POS:
ServoCross(15); // go to 'Cross' position
break;
};
NextState = STATE_SEND_CMD; // when reached, send serial message
Serial.flush(); // clear the serial buffer
if (ServoPos == FIRST_POS) {
Serial.println("Co"); //send signal 'Co' to python
}
else {
Serial.println("Cross"); //send signal 'Cross' to python
}
NextState = STATE_WAIT_ACK;
if (Serial.available()) { // no state change while no acknowledge
String Str = Serial.readStringUntil('\n');
Serial.println(Str);
if (Str == "OK") {
// ack is OK, select the next position and continue
ServoPos = (ServoPos == FIRST_POS)?(SECOND_POS):(FIRST_POS);
NextState = STATE_MOVE_POS;
}
else {
// ack is KO, restart from first position
NextState = STATE_START;
}
}