- /******************************************************
- * FileName: LobotServoController.cpp
-
- * Description: Lobot舵机控制板二次开发库,本文件包含
- 了此库的具体实现
- *****************************************************/
-
- #include "LobotServoController.h"
-
- #define GET_LOW_BYTE(A) (uint8_t)((A))
- //宏函数 获得A的低八位
- #define GET_HIGH_BYTE(A) (uint8_t)((A) >> 8)
- //宏函数 获得A的高八位
- #define BYTE_TO_HW(A, B) ((((uint16_t)(A)) << 8) | (uint8_t)(B))
- //宏函数 以A为高八位 B为低八位 合并为16位整形
-
- LobotServoController::LobotServoController()
- {
- //初始化运行中动作组号为0xFF,运行次数为0,运行中标识为假,电池电压为0
- numOfActinGroupRunning = 0xFF;
- actionGroupRunTimes = 0;
- isRunning = false;
- batteryVoltage = 0;
- #if defined(__AVR_ATmega32U4__) //for Arduino Leonardo,Micro....
- SerialX = &Serial1;
- #else
- SerialX = &Serial;
- #endif
- }
-
- LobotServoController::LobotServoController(HardwareSerial &A)
- {
- LobotServoController();
- SerialX = &A;
- }
- LobotServoController::~LobotServoController()
- {
- }
-
- /*********************************************************************************
- * Function: moveServo
- * Description: 控制单个舵机转动
- * Parameters: sevoID:舵机ID,Position:目标位置,Time:转动时间
- 舵机ID取值:0<=舵机ID<=31,Time取值: Time > 0
- * Return: 无返回
- * Others:
- **********************************************************************************/
- void LobotServoController::moveServo(uint8_t servoID, uint16_t Position, uint16_t Time)
- {
- uint8_t buf[11];
- if (servoID > 31 || !(Time > 0)) { //舵机ID不能打于31,可根据对应控制板修改
- return;
- }
- buf[0] = FRAME_HEADER; //填充帧头
- buf[1] = FRAME_HEADER;
- buf[2] = 8; //数据长度=要控制舵机数*3+5,此处=1*3+5
- buf[3] = CMD_SERVO_MOVE; //填充舵机移动指令
- buf[4] = 1; //要控制的舵机个数
- buf[5] = GET_LOW_BYTE(Time); //填充时间的低八位
- buf[6] = GET_HIGH_BYTE(Time); //填充时间的高八位
- buf[7] = servoID; //舵机ID
- buf[8] = GET_LOW_BYTE(Position); //填充目标位置的低八位
- buf[9] = GET_HIGH_BYTE(Position); //填充目标位置的高八位
-
- SerialX->write(buf, 10);
- }
-
- /*********************************************************************************
- * Function: moveServos
- * Description: 控制多个舵机转动
- * Parameters: servos[]:舵机结体数组,Num:舵机个数,Time:转动时间
- 0 < Num <= 32,Time > 0
- * Return: 无返回
- * Others:
- **********************************************************************************/
- void LobotServoController::moveServos(LobotServo servos[], uint8_t Num, uint16_t Time)
- {
- uint8_t buf[103]; //建立缓存
- if (Num < 1 || Num > 32 || !(Time > 0)) {
- return; //舵机数不能为零和大与32,时间不能为零
- }
- buf[0] = FRAME_HEADER; //填充帧头
- buf[1] = FRAME_HEADER;
- buf[2] = Num * 3 + 5; //数据长度 = 要控制舵机数*3+5
- buf[3] = CMD_SERVO_MOVE; //填充舵机移动指令
- buf[4] = Num; //要控制的舵机个数
- buf[5] = GET_LOW_BYTE(Time); //取得时间的低八位
- buf[6] = GET_HIGH_BYTE(Time); //取得时间的高八位
- uint8_t index = 7;
- for (uint8_t i = 0; i < Num; i++) { //循环填充舵机ID和对应目标位置
- buf[index++] = servos.ID; //填充舵机ID
- buf[index++] = GET_LOW_BYTE(servos.Position); //填充目标位置低八位
- buf[index++] = GET_HIGH_BYTE(servos.Position);//填充目标位置高八位
- }
- SerialX->write(buf, buf[2] + 2); //发送帧,长度为数据长度+两个字节的帧头
- }
-
- /*********************************************************************************
- * Function: moveServos
- * Description: 控制多个舵机转动
- * Parameters: Num:舵机个数,Time:转动时间,...:舵机ID,转动角,舵机ID,转动角度 如此类推
- * Return: 无返回
- * Others:
- **********************************************************************************/
- void LobotServoController::moveServos(uint8_t Num, uint16_t Time, ...)
- {
- uint8_t buf[128];
- va_list arg_ptr = NULL;
- va_start(arg_ptr, Time); //取得可变参数首地址
- if (Num < 1 || Num > 32 || (!(Time > 0)) || arg_ptr == NULL) {
- return; //舵机数不能为零和大与32,时间不能为零,可变参数不能为空
- }
- buf[0] = FRAME_HEADER; //填充帧头
- buf[1] = FRAME_HEADER;
- buf[2] = Num * 3 + 5; //数据长度 = 要控制舵机数 * 3 + 5
- buf[3] = CMD_SERVO_MOVE; //舵机移动指令
- buf[4] = Num; //要控制舵机数
- buf[5] = GET_LOW_BYTE(Time); //取得时间的低八位
- buf[6] = GET_HIGH_BYTE(Time); //取得时间的高八位
- uint8_t index = 7;
- for (uint8_t i = 0; i < Num; i++) { //从可变参数中取得并循环填充舵机ID和对应目标位置
- uint16_t tmp = va_arg(arg_ptr, uint16_t); //可参数中取得舵机ID
- buf[index++] = GET_LOW_BYTE(tmp); //貌似avrgcc中可变参数整形都是十六位
- //再取其低八位
- uint16_t pos = va_arg(arg_ptr, uint16_t); //可变参数中取得对应目标位置
- buf[index++] = GET_LOW_BYTE(pos); //填充目标位置低八位
- buf[index++] = GET_HIGH_BYTE(pos); //填充目标位置高八位
- }
- va_end(arg_ptr); //置空arg_ptr
- SerialX->write(buf, buf[2] + 2); //发送帧
- }
-
-
- /*********************************************************************************
- * Function: runActionGroup
- * Description: 运行指定动作组
- * Parameters: NumOfAction:动作组序号, Times:执行次数
- * Return: 无返回
- * Others: Times = 0 时无限循环
- **********************************************************************************/
- void LobotServoController::runActionGroup(uint8_t numOfAction, uint16_t Times)
- {
- uint8_t buf[7];
- buf[0] = FRAME_HEADER; //填充帧头
- buf[1] = FRAME_HEADER;
- buf[2] = 5; //数据长度,数据帧除帧头部分数据字节数,此命令固定为5
- buf[3] = CMD_ACTION_GROUP_RUN; //填充运行动作组命令
- buf[4] = numOfAction; //填充要运行的动作组号
- buf[5] = GET_LOW_BYTE(Times); //取得要运行次数的低八位
- buf[6] = GET_HIGH_BYTE(Times); //取得要运行次数的高八位
- SerialX->write(buf, 7); //发送数据帧
- }
-
- /*********************************************************************************
- * Function: stopActiongGroup
- * Description: 停止动作组运行
- * Parameters: Speed: 目标速度
- * Return: 无返回
- * Others:
- **********************************************************************************/
- void LobotServoController::stopActionGroup(void)
- {
- uint8_t buf[4];
- buf[0] = FRAME_HEADER; //填充帧头
- buf[1] = FRAME_HEADER;
- buf[2] = 2; //数据长度,数据帧除帧头部分数据字节数,此命令固定为2
- buf[3] = CMD_ACTION_GROUP_STOP; //填充停止运行动作组命令
-
- SerialX->write(buf, 4); //发送数据帧
- }
-
- /*********************************************************************************
- * Function: setActionGroupSpeed
- * Description: 设定指定动作组的运行速度
- * Parameters: NumOfAction: 动作组序号 , Speed:目标速度
- * Return: 无返回
- * Others:
- **********************************************************************************/
- void LobotServoController::setActionGroupSpeed(uint8_t numOfAction, uint16_t Speed)
- {
- uint8_t buf[7];
- buf[0] = FRAME_HEADER; //填充帧头
- buf[1] = FRAME_HEADER;
- buf[2] = 5; //数据长度,数据帧除帧头部分数据字节数,此命令固定为5
- buf[3] = CMD_ACTION_GROUP_SPEED; //填充设置动作组速度命令
- buf[4] = numOfAction; //填充要设置的动作组号
- buf[5] = GET_LOW_BYTE(Speed); //获得目标速度的低八位
- buf[6] = GET_HIGH_BYTE(Speed); //获得目标熟读的高八位
-
- SerialX->write(buf, 7); //发送数据帧
- }
-
-
- /*********************************************************************************
- * Function: setAllActionGroupSpeed
- * Description: 设置所有动作组的运行速度
- * Parameters: Speed: 目标速度
- * Return: 无返回
- * Others:
- **********************************************************************************/
- void LobotServoController::setAllActionGroupSpeed(uint16_t Speed)
- {
- setActionGroupSpeed(0xFF, Speed); //调用动作组速度设定,组号为0xFF时设置所有组的速度
- }
-
- /*********************************************************************************
- * Function: getBatteryVoltage
- * Description: 发送获取电池电压命令
- * Parameters: 无输入参数
- * Return: 无返回
- * Others:
- **********************************************************************************/
- void LobotServoController::getBatteryVoltage()
- {
- uint8_t buf[4];
- buf[0] = FRAME_HEADER; //填充帧头
- buf[1] = FRAME_HEADER;
- buf[2] = 2; //数据长度,数据帧除帧头部分数据字节数,此命令固定为2
- buf[3] = CMD_GET_BATTERY_VOLTAGE; //填充后的电池电压命令
-
- SerialX->write(buf, 4); //发送数据帧
- }
-
-
- /*********************************************************************************
- * Function: receiveHandle
- * Description: 处理串口接收数据
- * Parameters: 无输入参数
- * Return: 无返回
- * Others:
- **********************************************************************************/
- void LobotServoController::receiveHandle()
- {
- uint8_t buf[16];
- static uint8_t len = 0;
- static uint8_t getHeader = 0;
- if (!SerialX->available())
- return;
- //如果没有数据则返回
- do {
- switch (getHeader) {
- case 0:
- if (SerialX->read() == FRAME_HEADER)
- getHeader = 1;
- break;
- case 1:
- if (SerialX->read() == FRAME_HEADER)
- getHeader = 2;
- else
- getHeader = 0;
- break;
- case 2:
- len = SerialX->read();
- getHeader = 3;
- break;
- case 3:
- if (SerialX->readBytes(buf, len - 1) > 0)
- getHeader = 4;
- else{
- len = 0;
- getHeader = 0;
- break;
- }
- case 4:
- switch (buf[0]) {
- case BATTERY_VOLTAGE: //电池电压指令
- batteryVoltage = BYTE_TO_HW(buf[2], buf[1]); //高低八位组合成电池电压
- break;
- case ACTION_GROUP_RUNNING: //有动作组被运行
- numOfActinGroupRunning = buf[1]; //获得运行中动作组号
- actionGroupRunTimes = BYTE_TO_HW(buf[3], buf[2]); //高低八位组合成运行次数
- isRunning = true; //设置运行中标识为真
- break;
- case ACTION_GROUP_STOPPED: //动作组停止
- case ACTION_GROUP_COMPLETE://动作组运行完成
- isRunning = false; //设置运行中标识为假
- numOfActinGroupRunning = 0xFF; //设置运行中动作组号为0xFF
- actionGroupRunTimes = 0; //设置运行次数为0
- break;
- default:
- break;
- }
- default:
- len = 0;
- getHeader = 0;
- break;
- }
- } while (SerialX->available());
- }
复制代码
|