Robomaster电机控制和serialplot串口绘图(通用)
M3508电机的控制
DJ M3508电机搭配C620电调,只需按照官方手册设定相应的ID,即可完成通信
通过查看闪烁次数,可以判断此时电调ID
对于发送报文和接收报文,采用的模式是不一样的(这样才能区分开来)
发送报文
原理讲解
发送报文采用1控多的策略,id为1-4的电机都可以用0x200来控制
如何区分我发送的是给这四个电机中的哪个电机呢?
发送的Data一共有8个字节,每一个字都对应一个id,也就是我可以单独设置某些字节位达到单独发送的功能,当然也可以填满所有字节同时发送,注意看手册上的对应关系。
程序示范
CAN1_0x200_Tx_Data[0] = torque >> 8;
CAN1_0x200_Tx_Data[1] = torque;
CAN_Send_Data(&hcan1, 0x200, CAN1_0x200_Tx_Data, 8);
接收报文
原理讲解
接收报文与发送报文区别比较大,id是一对一的,每个电机都设置单独的id,同样是8个字节的DATA,不同的是,这8个字节发送的是对应电机的各个参数。注意及时解析相对应的变量
程序示范
void CAN_Motor_Call_Back(Struct_CAN_Rx_Buffer *Rx_Buffer)
{uint8_t *Rx_Data = Rx_Buffer->Data;switch (Rx_Buffer->Header.StdId){case (0x201):{Rx_Encoder = (Rx_Data[0] << 8) | Rx_Data[1];Rx_Omega = (Rx_Data[2] << 8) | Rx_Data[3];Rx_Torque = (Rx_Data[4] << 8) | Rx_Data[5];Rx_Temperature = Rx_Data[6];}break;}
}
serialplot串口绘图
原理讲解
可以使用serialplot上位机来查看单片机传回的数据,绘制可视化图像来清晰查看。主要通过uart串口通信来完成,使用到了ch340接口。
程序演示
Tx_Encoder = Rx_Encoder;
Tx_Omega = Rx_Omega;
Tx_Torque = Rx_Torque;
Tx_Temperature = Rx_Temperature;
serialplot.Set_Data(4, &Tx_Encoder, &Tx_Omega, &Tx_Torque, &Tx_Temperature);
serialplot.TIM_Add_PeriodElapsedCallback(); //发送到缓冲区
TIM_UART_PeriodElapsedCallback(); //把缓冲区的数据发送出去
void TIM_UART_PeriodElapsedCallback()
{// UART2串口绘图UART_Send_Data(&huart2, UART2_Tx_Data, 1 + 12 * sizeof(float));
}
void Class_Serialplot::TIM_Add_PeriodElapsedCallback()
{Output();
}
void Class_Serialplot::Output()
{for (int i = 0; i < 256; i++){UART_Tx_Data[i] = 0;}UART_Tx_Data[0] = Frame_Header;if (UART_Tx_Data_Type == Serialplot_Data_Type_UINT8 || UART_Tx_Data_Type == Serialplot_Data_Type_INT8){for (int i = 0; i < Data_Number; i++){UART_Tx_Data[1 + i + 0] = *((char *)((int)Data[i] + 0));}}else if (UART_Tx_Data_Type == Serialplot_Data_Type_UINT16 || UART_Tx_Data_Type == Serialplot_Data_Type_INT16){for (int i = 0; i < Data_Number; i++){UART_Tx_Data[1 + 2 * i + 0] = *((char *)(int)Data[i] + 0);UART_Tx_Data[1 + 2 * i + 1] = *((char *)(int)Data[i] + 1);}}else if (UART_Tx_Data_Type == Serialplot_Data_Type_UINT32 || UART_Tx_Data_Type == Serialplot_Data_Type_INT32 || UART_Tx_Data_Type == Serialplot_Data_Type_FLOAT){for (int i = 0; i < Data_Number; i++){UART_Tx_Data[1 + 4 * i + 0] = *((char *)(int)Data[i] + 0);UART_Tx_Data[1 + 4 * i + 1] = *((char *)(int)Data[i] + 1);UART_Tx_Data[1 + 4 * i + 2] = *((char *)(int)Data[i] + 2);UART_Tx_Data[1 + 4 * i + 3] = *((char *)(int)Data[i] + 3);}}else if (UART_Tx_Data_Type == Serialplot_Data_Type_DOUBLE){for (int i = 0; i < Data_Number; i++){UART_Tx_Data[1 + 8 * i + 0] = *((char *)(int)Data[i] + 0);UART_Tx_Data[1 + 8 * i + 1] = *((char *)(int)Data[i] + 1);UART_Tx_Data[1 + 8 * i + 2] = *((char *)(int)Data[i] + 2);UART_Tx_Data[1 + 8 * i + 3] = *((char *)(int)Data[i] + 3);UART_Tx_Data[1 + 8 * i + 4] = *((char *)(int)Data[i] + 4);UART_Tx_Data[1 + 8 * i + 5] = *((char *)(int)Data[i] + 5);UART_Tx_Data[1 + 8 * i + 6] = *((char *)(int)Data[i] + 6);UART_Tx_Data[1 + 8 * i + 7] = *((char *)(int)Data[i] + 7);}}
}