#pragma once #include #include "deviceBase.h" using namespace std; // 超声波驱鸟炮 #define EXPEL_WRITE (0x15) #define EXPEL_READ (0x05) #define EXPEL_POWER_OFF (0) #define EXPEL_POWER_ON (1<<7) #define EXPEL_PLAY_DISPEL (1<<6) #define EXPEL_TURN_OFF_DISPEL (0) #define EXPEL_NOT_FIRE (0) #define EXPEL_SINGLE_FIRE (1<<4) #define EXPEL_BURST_FIRE (2<<4) #define EXPEL_TURN_LEFT_CANCEL (0) #define EXPEL_TURN_LEFT_ENABLE (1<<3) #define EXPEL_TURN_RIGHT_CANCEL (0) #define EXPEL_TURN_RIGHT_ENABLE (1<<2) #define EXPEL_TURN_UP_CANCEL (0) #define EXPEL_TURN_UP_ENABLE (1<<1) #define EXPEL_TURN_DOWN_CANCEL (0) #define EXPEL_TURN_DOWM_ENABLE (1) #define EXPEL_STAUS_ACK 0x05 typedef struct{ int deviceId; uint8_t cmd; }UltControl; class deviceUlt:public deviceBase { private: uint8_t pressure; uint8_t commamd; int16_t current; uint16_t voltage; enum RECV_STEP{ STEP_HEAD = 0, STEP_ADDR = 1, STEP_LEN = 2, STEP_DIR = 3, STEP_DATA = 4 }; typedef struct { uint8_t dataCount; uint8_t dataLength; uint8_t dataCheckSum; uint8_t data[11]; enum RECV_STEP step = STEP_HEAD; }ExpelComm; ExpelComm _comm; public: deviceUlt():deviceBase() { this->setDeviceToken(serial); this->setDeviceInfo("北京首都机场 民航大板协议"); this->setBaudRate(115200); } ~deviceUlt(){} void serialization(){} bool deserialization(){ return true; } void setPressure(uint8_t Pressure){ pressure = Pressure; } void setCommamd(uint8_t Commamd){ commamd = Commamd; } void setCurrent(int16_t Current){ current = Current; } void setVoltage(uint16_t Voltage){ voltage = Voltage; } uint8_t getPressure(){ return pressure; } uint8_t getCommamd(){ return commamd; } int16_t getCurrent(){ return current; } uint16_t getVoltage(){ return voltage; } static void serialization(UltControl ultControl, char *data, bool status = false){ data[0] = 0xaa; data[1] = (uint8_t)ultControl.deviceId; data[2] = 0x06; if(status) data[3] = 0x05; else data[3] = 0x15; data[4] = ultControl.cmd; data[5] = 0; for (int i = 0; i < 5; i++) { data[5] += data[i]; } } bool deserialization(const uint8_t *data, int len, int &msg_id){ if(data[0] != 0xbb){ return false; } uint8_t dataCheckSum = 0; for(int i = 0; i < len - 1; i++){ dataCheckSum += data[i]; } if(dataCheckSum != data[len - 1]){ return false; } msg_id = data[3]; if(msg_id == EXPEL_STAUS_ACK){ this->setDeviceId(to_string(data[1])); this->pressure = (data[9]&0x80) >> 7; this->commamd = (data[4]); this->current = (int16_t)(data[8]<<8 || data[7]); this->voltage = uint16_t(data[6]<<8 || data[5]); } return true; } bool Consumer(uint8_t *data, int len, int &msg_id){ bool ReceiveSuccessful = false; if(this->Type != 1 && len > 0) return true; for(int i = 0; i < len; i++){ switch(_comm.step){ case STEP_HEAD: if(data[i] == 0xbb){ _comm.data[0] = 0xbb; _comm.step = STEP_ADDR; } break; case STEP_ADDR: _comm.data[1] = data[i]; _comm.step = STEP_LEN; break; case STEP_LEN: if (data[i] == 0x0B) { _comm.data[2] = 0x0B; _comm.dataLength = 0x0B; _comm.step = STEP_DIR; } else { _comm.step = STEP_HEAD; } break; case STEP_DIR: if (data[i] == 0x05) { _comm.data[3] = 0x05; _comm.step = STEP_DATA; _comm.dataCount = 4; } else { _comm.step = STEP_HEAD; } break; case STEP_DATA: _comm.data[_comm.dataCount++] = data[i]; if(_comm.dataCount == _comm.dataLength){ ReceiveSuccessful = true; _comm.step = STEP_HEAD; } break; default: _comm.step = STEP_HEAD; break; } } if(!ReceiveSuccessful) { return false; } return deserialization(_comm.data, _comm.dataLength, msg_id); } /** * @description: 打开 * @param {int} deivceId * @return {*} */ int32_t Open(std::string DeviceId, uint8_t* data, int& length){ UltControl ultControl; ultControl.deviceId = std::atoi(DeviceId.c_str()); ultControl.cmd = EXPEL_POWER_ON | EXPEL_PLAY_DISPEL | EXPEL_BURST_FIRE; length = 6; serialization(ultControl, (char*)data); return 0; } /** * @description: 关闭 * @param {int} deivceId * @return {*} */ int32_t Close(std::string DeviceId, uint8_t* data, int& length){ UltControl ultControl; ultControl.deviceId = std::atoi(DeviceId.c_str()); ultControl.cmd = EXPEL_POWER_OFF | EXPEL_TURN_OFF_DISPEL | EXPEL_NOT_FIRE; length = 6; serialization(ultControl, (char*)data); return 0; } /** * @description: 开炮 * @param {int} deivceId * @return {*} */ int32_t Fire(std::string DeviceId, uint8_t* data, int& length){ return Open(DeviceId, data, length); } /** * @description: 状态 * @param {int} deivceId * @return {*} */ int32_t Status(std::string DeviceId, uint8_t* data, int& length){ UltControl ultControl; ultControl.deviceId = std::atoi(DeviceId.c_str()); ultControl.cmd = 0; length = 6; bool staus = true; serialization(ultControl, (char*)data, staus); return 0; } /** * @description: 判定msg是否为status * @param {int} &msg_id * @return {*} */ bool getStatusMsg(int &msg_id){ if(msg_id != EXPEL_STAUS_ACK) return false; return true; } /** * @description: 构建设备信息 * @param {SendDevice&} sendDevice * @return {*} */ void BuildDeviceInfo(SendDevice& sendDevice){ sendDevice.deviceId = atoi(this->getDeviceId().c_str()); sendDevice.commandCode = "1"; sendDevice.status = 1; sendDevice.workStatus = 1; sendDevice.powerStatus = 1; sendDevice.batteryStatus = 1; sendDevice.num = 0; sendDevice.oxyPressure = 0; sendDevice.gasPressure = 0; sendDevice.remark = ""; sendDevice.attr1 = std::to_string(this->getVoltage()); // 电压 sendDevice.attr2 = std::to_string(this->getCurrent()); // 电流 sendDevice.attr3 = std::to_string(this->getPressure()); // 声压 } };