ROV 控制系统 Arduino 代码分析及优化
ROV 控制系统 Arduino 代码分析及优化
本代码展示了基于 Arduino 的 ROV 控制系统,包括电机控制、LED 点阵显示、串口通信等功能。
硬件连接:
- 左前推进器: 引脚 3
- 左上推进器: 引脚 5
- 右前推进器: 引脚 9
- 右上推进器: 引脚 6
- 机械臂: 引脚 10
- LED 点阵: DIN 引脚 2,CLK 引脚 7,CS 引脚 4
代码分析:
- 声明舵机对象和引脚定义:
Servo Left_Front_Thruster;//左前推进器对象
Servo Left_Upper_Thruster;//左上推进器对象
Servo Right_Front_Thruster;//右前推进器对象
Servo Right_Upper_Thruster;//右上推进器对象
Servo Arm;//机械臂对象
#define LEFT_FRONT_PIN 3//左前推进器引脚
#define LEFT_UPPER_PIN 5//左上推进器引脚
#define RIGHT_FRONT_PIN 9//右前推进器引脚
#define RIGHT_UPPER_PIN 6//右上推进器引脚
#define ARM_PIN 10//机械臂引脚
- 定义控制结构体:
struct
{
uint8_t Act_Value[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; //动作幅值 前进后退左转右转上浮下潜左翻右翻 0-110 舵机 0-140
long int Ctl_Value[5] = {1500, 1500, 1500, 1500, 0}; //控制量 左前右前左上右上 机械臂
long int Ctl_ValueLast[5]; //上一次控制量
long int count;//超时关机计数器
} ROV_Ctl;
- LED 点阵初始化:
/*LED点阵变量定义区*/
#define DIN 2
#define CS 4
#define CLK 7
LedControl lc = LedControl(DIN, CLK, CS, 4);
byte Zero[8] = {0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C};
- 串口通信变量定义:
/*串口通信变量定义区*/
#define Buffer_Lenth 9 //接收数据数组个数
long int Receive_Data_Ture = 0; //数据正确标志位
unsigned char Serial_Receive_Data[Buffer_Lenth]; //串口接收数据缓存区
char Communicate_state = 0; //通信状态标志位
- 初始化函数
setup():
void setup()
{
Serial.begin(9600);
pinMode(A0, OUTPUT);
Left_Front_Thruster.attach(LEFT_FRONT_PIN);
Left_Upper_Thruster.attach(LEFT_UPPER_PIN);
Right_Front_Thruster.attach(RIGHT_FRONT_PIN);
Right_Upper_Thruster.attach(RIGHT_UPPER_PIN);
Arm.attach(ARM_PIN);
Left_Front_Thruster.writeMicroseconds(1000);
Left_Upper_Thruster.writeMicroseconds(1000);
Right_Front_Thruster.writeMicroseconds(1000);
Right_Upper_Thruster.writeMicroseconds(1000);
delay(10);
Left_Front_Thruster.writeMicroseconds(1500);
Left_Upper_Thruster.writeMicroseconds(1500);
Right_Front_Thruster.writeMicroseconds(1500);
Right_Upper_Thruster.writeMicroseconds(1500);
led();
MsTimer2::set(500, shut);
MsTimer2::start();
}
- 主循环函数
loop():
void loop()
{
}
- 超时关机函数
shut():
void shut()
{
Receive_Data_Ture--;
if (Receive_Data_Ture > 0)
{
ROV_Ctl.count = 0;
}
if (Receive_Data_Ture <= 0)
{
ROV_Ctl.count++;
}
Serial.println(ROV_Ctl.count);
if (ROV_Ctl.count > 100)
{
analogWrite(A0, 255);
}
}
- 串口事件处理函数
serialEvent():
uint8_t Num_len;
#define USART1_REC_LEN 24 //定义最大接收字节数 200 实际69
unsigned char USART1_RX_BUF[USART1_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
void serialEvent()
{
/*接收定长数据*/
/*EB 90 00 01 02 03 04 05 06 07*/
/*获取缓存区缓存数据个数*/
uint8_t Para;
int Rx_Length = Serial.available();
if (Rx_Length > 0)
{
Para = Serial.read();
if (Para == 0xEB)
{
Num_len = 0;
}
USART1_RX_BUF[Num_len++] = Para; //将接受到的数据存入RX_BUFF
if (Num_len == 9 && USART1_RX_BUF[0] == 0xEB && USART1_RX_BUF[1] == 0x90 && USART1_RX_BUF[2] == 0xA5)
{
memcpy(Serial_Receive_Data, USART1_RX_BUF, Num_len); //保存数据
Num_len = 0;
memset(USART1_RX_BUF, 0, USART1_REC_LEN); //清空BUF
Receive_Data_Ture = 2;
handle();
mapping();
execute();
}
}
}
- 数据处理函数
handle()、mapping()、execute():
void handle()
{
}
void mapping()
{
}
void execute()
{
}
- LED 点阵显示函数
led():
void led()
{
lc.shutdown(0, false); //启动时,MAX72XX处于省电模式
lc.setIntensity(0, 8); //将亮度设置为最大值
lc.clearDisplay(0);
for (int i = 0; i < 8; i++)
{
lc.setRow(0, i, Zero[i]);
}
}
优化后的通信协议:
改变通信协议为
Serial.write(0xEB);
Serial.write(0x90);
Serial.write(R1int);
Serial.write(R2int);
Serial.write(L1int);
Serial.write(L2int);
Serial.write(keyint);
Serial.write(SUM);
解释:
这是因为在原来的代码中,接收定长数据的方式是通过判断接收数据的长度来确定数据是否完整,如果数据格式不正确或者有数据丢失,就会出现接收数据不完整或者数据错位的情况。而将通信协议改为8位的Serial.write()方式,可以保证每次发送的数据都是完整的,避免了数据丢失或错位的情况,提高了通信的稳定性和可靠性。同时,由于每一位数据都是独立发送的,也方便了接收端进行数据的解析和处理。
总结:
本代码提供了一个基于 Arduino 的 ROV 控制系统,代码结构清晰,易于理解和扩展。通过优化通信协议,提高了系统的稳定性和可靠性。您可以根据自己的需求,对代码进行修改和扩展,实现更加丰富和复杂的功能。
原文地址: https://www.cveoy.top/t/topic/n7Og 著作权归作者所有。请勿转载和采集!