|
|
@ -10,14 +10,15 @@ extern const AP_HAL::HAL &hal; |
|
|
|
AP_BattMonitor_Serial_BattGo::AP_BattMonitor_Serial_BattGo(AP_BattMonitor &mon, |
|
|
|
AP_BattMonitor_Serial_BattGo::AP_BattMonitor_Serial_BattGo(AP_BattMonitor &mon, |
|
|
|
AP_BattMonitor::BattMonitor_State &mon_state, |
|
|
|
AP_BattMonitor::BattMonitor_State &mon_state, |
|
|
|
AP_BattMonitor_Params ¶ms, |
|
|
|
AP_BattMonitor_Params ¶ms, |
|
|
|
uint8_t serial_instance) : AP_BattMonitor_Backend(mon, mon_state, params) |
|
|
|
uint8_t serial_instance) :
|
|
|
|
|
|
|
|
AP_BattMonitor_Backend(mon, mon_state, params) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
const AP_SerialManager &serial_manager = AP::serialmanager(); |
|
|
|
const AP_SerialManager &serial_manager = AP::serialmanager(); |
|
|
|
uart = serial_manager.find_serial(AP_SerialManager::SerialProtocol_Battery, serial_instance); |
|
|
|
uart = serial_manager.find_serial(AP_SerialManager::SerialProtocol_Battery, serial_instance); |
|
|
|
if (uart != nullptr) |
|
|
|
if (uart != nullptr) |
|
|
|
{ |
|
|
|
{ |
|
|
|
uart->begin(serial_manager.find_baudrate(AP_SerialManager::SerialProtocol_Rangefinder, serial_instance)); |
|
|
|
uart->begin(serial_manager.find_baudrate(AP_SerialManager::SerialProtocol_Battery, serial_instance)); |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
@ -28,298 +29,115 @@ AP_BattMonitor_Serial_BattGo::AP_BattMonitor_Serial_BattGo(AP_BattMonitor &mon, |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
bool AP_BattMonitor_Serial_BattGo::detect(uint8_t serial_instance) //how to used
|
|
|
|
bool AP_BattMonitor_Serial_BattGo::detect(uint8_t serial_instance) //how to used
|
|
|
|
{ |
|
|
|
{ |
|
|
|
return AP::serialmanager().find_serial(AP_SerialManager::SerialProtocol_Rangefinder, serial_instance) != nullptr; |
|
|
|
return AP::serialmanager().find_serial(AP_SerialManager::SerialProtocol_Battery, serial_instance) != nullptr; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void AP_BattMonitor_Serial_BattGo::init(void) |
|
|
|
void AP_BattMonitor_Serial_BattGo::init(void) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (uart != nullptr) |
|
|
|
if (uart != nullptr) |
|
|
|
{ |
|
|
|
{ |
|
|
|
requestBattData(BATTGO_CMD_REQUEST_ACTUAL_DATA); |
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"into BattGo::init()"); |
|
|
|
requestBattData(BATTGO_CMD_REQUEST_PARAM); |
|
|
|
requestBattData(BATTGO_CMD_REQUEST_ACTUAL_DATA); |
|
|
|
requestBattData(BATTGO_CMD_REQUEST_HISTORY); |
|
|
|
requestBattData(BATTGO_CMD_REQUEST_PARAM); |
|
|
|
|
|
|
|
requestBattData(BATTGO_CMD_REQUEST_HISTORY); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
bool isparse =false; |
|
|
|
bool AP_BattMonitor_Serial_BattGo::get_reading() //TODO need to Refactor
|
|
|
|
bool AP_BattMonitor_Serial_BattGo::get_reading() //TODO need to Refactor
|
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
if (uart == nullptr) |
|
|
|
if (uart == nullptr) |
|
|
|
{ |
|
|
|
{ |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int16_t numc; |
|
|
|
int16_t numc; |
|
|
|
numc = uart->available(); |
|
|
|
numc = uart->available(); |
|
|
|
uint8_t data; |
|
|
|
uint8_t data; |
|
|
|
|
|
|
|
if(numc == 0) |
|
|
|
bool parsed = false; |
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"uasart num:%d",numc); |
|
|
|
|
|
|
|
isparse = false; |
|
|
|
for (int16_t i = 0; i < numc; i++) |
|
|
|
for (int16_t i = 0; i < numc; i++) |
|
|
|
{ |
|
|
|
{ |
|
|
|
data = uart->read(); |
|
|
|
data = uart->read(); |
|
|
|
switch (step) |
|
|
|
rxProcess(data); |
|
|
|
{ |
|
|
|
if(isparse){ |
|
|
|
case 0: |
|
|
|
isparse = true; |
|
|
|
if (Head1 == data) |
|
|
|
return true; |
|
|
|
{ |
|
|
|
|
|
|
|
payload_counter = 0; |
|
|
|
|
|
|
|
payload_length = 0; |
|
|
|
|
|
|
|
step++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
is_read_header = false; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case 1: //addr
|
|
|
|
|
|
|
|
if (!is_read_header) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (Head1 != data) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
addr = data; |
|
|
|
|
|
|
|
check_sum = data; |
|
|
|
|
|
|
|
step++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
is_read_header = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else //this data is 0x55
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
is_read_header = false; |
|
|
|
|
|
|
|
if (Head1 == data) // is repeat data
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
addr = data; |
|
|
|
|
|
|
|
step++; |
|
|
|
|
|
|
|
check_sum = data; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ //last data 0x55 is header, this data is addr,next step =2;
|
|
|
|
|
|
|
|
gotoStepAddr(data); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case 2: //payload_length;
|
|
|
|
|
|
|
|
if (!is_read_header) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (Head1 != data) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
payload_length = data; |
|
|
|
|
|
|
|
check_sum += data; |
|
|
|
|
|
|
|
step++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
is_read_header = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else //this data is 0x55
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
is_read_header = false; |
|
|
|
|
|
|
|
if (Head1 == data) // is repeat data
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
payload_length = data; |
|
|
|
|
|
|
|
check_sum += data; |
|
|
|
|
|
|
|
step++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ //last data 0x55 is header, this data is addr,next step =2;
|
|
|
|
|
|
|
|
gotoStepAddr(data); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case 3: //payloaddata
|
|
|
|
|
|
|
|
if (!is_read_header) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (Head1 != data) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
setPayLoadData(data); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
is_read_header = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else //this data is 0x55
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
is_read_header = false; |
|
|
|
|
|
|
|
if (Head1 == data) |
|
|
|
|
|
|
|
{ // is repeat data
|
|
|
|
|
|
|
|
setPayLoadData(data); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ //last data 0x55 is header, this data is addr,next step =2;
|
|
|
|
|
|
|
|
gotoStepAddr(data); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case 4: //crc_a
|
|
|
|
|
|
|
|
if (!is_read_header) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (Head1 == data) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
is_read_header = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if ((check_sum & 0x00ff) != data) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
step = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
step++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else //this data is 0x55
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
is_read_header = false; |
|
|
|
|
|
|
|
if (Head1 == data) // is repeat data
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if ((check_sum & 0x00ff) != data) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
step = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
step++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ //last data 0x55 is header, this data is addr,next step =2;
|
|
|
|
|
|
|
|
gotoStepAddr(data); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case 5: //crc_b
|
|
|
|
|
|
|
|
if (!is_read_header) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (Head1 == data) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
is_read_header = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (((check_sum >> 8) & 0x00ff) == data) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (parseBattGo()) |
|
|
|
|
|
|
|
parsed = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
step = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else //this data is 0x55
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
is_read_header = false; |
|
|
|
|
|
|
|
if (Head1 == data) // is repeat data
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (((check_sum >> 8) & 0x00ff) == data) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (parseBattGo()) |
|
|
|
|
|
|
|
parsed = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
step = 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ //last data 0x55 is header, this data is addr,next step =2;
|
|
|
|
|
|
|
|
gotoStepAddr(data); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return parsed; |
|
|
|
return isparse; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void AP_BattMonitor_Serial_BattGo::gotoStepAddr(uint8_t &data) |
|
|
|
// void AP_BattMonitor_Serial_BattGo::gotoStepAddr(uint8_t &data)
|
|
|
|
{ |
|
|
|
// {
|
|
|
|
step = 2; //next step
|
|
|
|
// step = 2; //next step
|
|
|
|
addr = data; |
|
|
|
// addr = data;
|
|
|
|
check_sum = data; |
|
|
|
// check_sum = data;
|
|
|
|
} |
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
void AP_BattMonitor_Serial_BattGo::requestBattData(uint8_t data) |
|
|
|
void AP_BattMonitor_Serial_BattGo::requestBattData(uint8_t data) |
|
|
|
{ |
|
|
|
{ |
|
|
|
//发送data主要 0x40 0x42 0x44 地址0x21 及计算crc 均不会出现0x55,故不做0x55处理
|
|
|
|
//发送data主要 0x40 0x42 0x44 地址0x21 及计算crc 均不会出现0x55,故不做0x55处理
|
|
|
|
uint8_t send_data[6]; |
|
|
|
uint8_t send_data[13]; |
|
|
|
send_data[0] = 0x55; |
|
|
|
send_data[0] = 0x55; |
|
|
|
send_data[1] = 0x21; |
|
|
|
send_data[1] = 0x12; |
|
|
|
send_data[2] = 0x01; |
|
|
|
send_data[2] = 0x08; |
|
|
|
send_data[3] = data; |
|
|
|
send_data[3] = data; |
|
|
|
uint16_t crc = send_data[1] + send_data[2] + send_data[3]; |
|
|
|
send_data[4] = 0; |
|
|
|
send_data[4] = crc & 0xff; |
|
|
|
send_data[5] = 0; |
|
|
|
send_data[5] = crc >> 8 & 0xff; |
|
|
|
send_data[6] = 0; |
|
|
|
|
|
|
|
send_data[7] = 0; |
|
|
|
|
|
|
|
send_data[8] = 0; |
|
|
|
|
|
|
|
send_data[9] = 0; |
|
|
|
|
|
|
|
send_data[10] = 0; |
|
|
|
|
|
|
|
uint16_t crc = send_data[1] + send_data[2] + send_data[3]; //Notice :other data is 0 ,so no need to add to culcalate crc
|
|
|
|
|
|
|
|
send_data[11] = crc & 0xff; //64
|
|
|
|
|
|
|
|
send_data[12] = crc >> 8 & 0xff; //00
|
|
|
|
if (uart->txspace() > sizeof(send_data)) |
|
|
|
if (uart->txspace() > sizeof(send_data)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
uart->write(&send_data[0], sizeof(send_data)); |
|
|
|
uart->write(&send_data[0], sizeof(send_data)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void AP_BattMonitor_Serial_BattGo::setPayLoadData(uint8_t &usart_data) |
|
|
|
// void AP_BattMonitor_Serial_BattGo::setPayLoadData(uint8_t &usart_data)
|
|
|
|
{ |
|
|
|
|
|
|
|
if (payload_counter < payload_length) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
data_buf[payload_counter] = usart_data; |
|
|
|
|
|
|
|
payload_counter++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
step++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// void AP_BattMonitor_Serial_BattGo::doWithReadHeaderData(uint8_t &usart_data, uint8_t target_data, uint8_t step, uint8_t &payload_length, uint8_t &payload_count, uint8_t *data_buf, bool &is_read_header)
|
|
|
|
|
|
|
|
// {
|
|
|
|
// {
|
|
|
|
// if (!is_read_header)
|
|
|
|
// if (payload_counter < payload_length)
|
|
|
|
// {
|
|
|
|
// {
|
|
|
|
// target_data = usart_data;
|
|
|
|
// data_buf[payload_counter] = usart_data;
|
|
|
|
// switch (step)
|
|
|
|
// payload_counter++;
|
|
|
|
// {
|
|
|
|
|
|
|
|
// case 1: //addr
|
|
|
|
|
|
|
|
// check_sum = 0;
|
|
|
|
|
|
|
|
// step++;
|
|
|
|
|
|
|
|
// case 2: //payload_length;
|
|
|
|
|
|
|
|
// payload_length = usart_data;
|
|
|
|
|
|
|
|
// step++;
|
|
|
|
|
|
|
|
// break;
|
|
|
|
|
|
|
|
// case 3: //data
|
|
|
|
|
|
|
|
// if (payload_count < payload_length)
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// data_buf[payload_count] = usart_data;
|
|
|
|
|
|
|
|
// payload_count++;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// break;
|
|
|
|
|
|
|
|
// default:
|
|
|
|
|
|
|
|
// break;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// check_sum += usart_data;
|
|
|
|
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// else
|
|
|
|
// {
|
|
|
|
// {
|
|
|
|
|
|
|
|
// step++;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
mavlink_battgo_info_t battgo_info_t; |
|
|
|
|
|
|
|
mavlink_battgo_history_t battgo_history_t ; |
|
|
|
mavlink_battgo_info_t battgo_info_t; |
|
|
|
|
|
|
|
mavlink_battgo_history_t battgo_history_t; |
|
|
|
bool AP_BattMonitor_Serial_BattGo::parseBattGo() |
|
|
|
bool AP_BattMonitor_Serial_BattGo::parseBattGo() |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
if (data_buf[0] == 0x43) |
|
|
|
if (data_buf[0] == 0x43) |
|
|
|
{ //电池实时数据
|
|
|
|
{ //电池实时数据
|
|
|
|
|
|
|
|
gcs().send_text(MAV_SEVERITY_INFO,"into battgo 0x43 battgo realtime data"); |
|
|
|
uint32_t tnow = AP_HAL::micros(); |
|
|
|
uint32_t tnow = AP_HAL::micros(); |
|
|
|
uint32_t dt = tnow - _interim_state.last_time_micros; |
|
|
|
uint32_t dt = tnow - _interim_state.last_time_micros; |
|
|
|
|
|
|
|
_interim_state.voltage =0; |
|
|
|
for (uint8_t i = 0; i < 6; i++) |
|
|
|
for (uint8_t i = 0; i < 6; i++) |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint16_t valtemp = ((data_buf[4 + 2 * i] << 8) & 0xff00) + data_buf[3 + 2 * i]; |
|
|
|
uint16_t valtemp = ((data_buf[4 + 2 * i] << 8) & 0xff00) + data_buf[3 + 2 * i]; |
|
|
|
_interim_state.cell_voltages.cells[i] = valtemp; |
|
|
|
_interim_state.cell_voltages.cells[i] = valtemp; |
|
|
|
_interim_state.voltage += valtemp; |
|
|
|
// gcs().send_text(MAV_SEVERITY_INFO," _interim_state.cell_voltages.cells[%d]: %d",i,valtemp);
|
|
|
|
|
|
|
|
_interim_state.voltage += valtemp/1000.0; |
|
|
|
|
|
|
|
_has_cell_voltages = true; |
|
|
|
} |
|
|
|
} |
|
|
|
_interim_state.temperature = data_buf[15] - 128; |
|
|
|
//gcs().send_text(MAV_SEVERITY_INFO," _interim_state.cell_voltages: %f", _interim_state.voltage);
|
|
|
|
_interim_state.temperature_time = AP_HAL::millis(); |
|
|
|
|
|
|
|
_interim_state.current_amps = data_buf[16] + (data_buf[17] << 8) + (data_buf[18] << 16) + (data_buf[19] << 24); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_interim_state.temperature = (int8_t)data_buf[15] ; |
|
|
|
|
|
|
|
//gcs().send_text(MAV_SEVERITY_INFO," _interim_state.temperature: %f", _interim_state.temperature);
|
|
|
|
|
|
|
|
_interim_state.temperature_time = AP_HAL::millis(); |
|
|
|
|
|
|
|
_interim_state.current_amps =( data_buf[16] + (data_buf[17] << 8) + (data_buf[18] << 16) + (data_buf[19] << 24))/1000.0; |
|
|
|
|
|
|
|
//gcs().send_text(MAV_SEVERITY_INFO," _interim_state.current_amps: %f", _interim_state.current_amps/1000.0);
|
|
|
|
// update total current drawn since startup
|
|
|
|
// update total current drawn since startup
|
|
|
|
if (_interim_state.last_time_micros != 0 && dt < 2000000) |
|
|
|
if (_interim_state.last_time_micros != 0 && dt < 2000000) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -338,7 +156,7 @@ bool AP_BattMonitor_Serial_BattGo::parseBattGo() |
|
|
|
else if (data_buf[0] == 0x41) |
|
|
|
else if (data_buf[0] == 0x41) |
|
|
|
{ |
|
|
|
{ |
|
|
|
//电池参数
|
|
|
|
//电池参数
|
|
|
|
|
|
|
|
// gcs().send_text(MAV_SEVERITY_INFO,"into battgo 0x41 battgo info");
|
|
|
|
battgo_info_t.channal_num = data_buf[1]; |
|
|
|
battgo_info_t.channal_num = data_buf[1]; |
|
|
|
battgo_info_t.connect_status = data_buf[2]; |
|
|
|
battgo_info_t.connect_status = data_buf[2]; |
|
|
|
battgo_info_t.sub_software_ver = data_buf[3]; |
|
|
|
battgo_info_t.sub_software_ver = data_buf[3]; |
|
|
@ -362,7 +180,7 @@ bool AP_BattMonitor_Serial_BattGo::parseBattGo() |
|
|
|
uint8_t hour = (data_buf[33] & 0xF0 << 4) | (data_buf[34] & 0x01 << 1); |
|
|
|
uint8_t hour = (data_buf[33] & 0xF0 << 4) | (data_buf[34] & 0x01 << 1); |
|
|
|
uint8_t day = data_buf[34] & 0x3e >> 1; |
|
|
|
uint8_t day = data_buf[34] & 0x3e >> 1; |
|
|
|
uint8_t month = (data_buf[34] & 0xc0 >> 6) | (data_buf[35] & 0x03); |
|
|
|
uint8_t month = (data_buf[34] & 0xc0 >> 6) | (data_buf[35] & 0x03); |
|
|
|
uint16_t year = (data_buf[35] & 0xFC >> 2 )+ 2017; |
|
|
|
uint16_t year = (data_buf[35] & 0xFC >> 2) + 2017; |
|
|
|
|
|
|
|
|
|
|
|
battgo_info_t.production_time_year = year; |
|
|
|
battgo_info_t.production_time_year = year; |
|
|
|
battgo_info_t.production_time_mon = month; |
|
|
|
battgo_info_t.production_time_mon = month; |
|
|
@ -393,18 +211,18 @@ bool AP_BattMonitor_Serial_BattGo::parseBattGo() |
|
|
|
battgo_info_t.battery_core_vol[i] = (data_buf[75 + 2 * i + 1] << 8) | (data_buf[75 + 2 * i]); |
|
|
|
battgo_info_t.battery_core_vol[i] = (data_buf[75 + 2 * i + 1] << 8) | (data_buf[75 + 2 * i]); |
|
|
|
} |
|
|
|
} |
|
|
|
battgo_info_t.current_temp = data_buf[87]; |
|
|
|
battgo_info_t.current_temp = data_buf[87]; |
|
|
|
battgo_info_t.actual_discharge_vol = (data_buf[91] << 24) | (data_buf[90] << 16) | (data_buf[89] << 8) |data_buf[88]; |
|
|
|
battgo_info_t.actual_discharge_vol = (data_buf[91] << 24) | (data_buf[90] << 16) | (data_buf[89] << 8) | data_buf[88]; |
|
|
|
battgo_info_t.actual_charge_vol = (data_buf[95] << 24) | (data_buf[94] << 16) | (data_buf[93] << 8) |data_buf[92]; |
|
|
|
battgo_info_t.actual_charge_vol = (data_buf[95] << 24) | (data_buf[94] << 16) | (data_buf[93] << 8) | data_buf[92]; |
|
|
|
battgo_info_t.batt_cycle_times = (data_buf[97] << 8) |data_buf[96]; |
|
|
|
battgo_info_t.batt_cycle_times = (data_buf[97] << 8) | data_buf[96]; |
|
|
|
battgo_info_t.batt_abr_times = (data_buf[99] << 8) |data_buf[98]; |
|
|
|
battgo_info_t.batt_abr_times = (data_buf[99] << 8) | data_buf[98]; |
|
|
|
battgo_info_t.temp_abr_times = (data_buf[101] << 8) |data_buf[100]; |
|
|
|
battgo_info_t.temp_abr_times = (data_buf[101] << 8) | data_buf[100]; |
|
|
|
battgo_info_t.temp_abr_times = (data_buf[101] << 8) |data_buf[100]; |
|
|
|
battgo_info_t.temp_abr_times = (data_buf[101] << 8) | data_buf[100]; |
|
|
|
battgo_info_t.over_vol_abr_times = (data_buf[103] << 8) |data_buf[102]; |
|
|
|
battgo_info_t.over_vol_abr_times = (data_buf[103] << 8) | data_buf[102]; |
|
|
|
battgo_info_t.under_vol_abr_times = (data_buf[105] << 8) |data_buf[104]; |
|
|
|
battgo_info_t.under_vol_abr_times = (data_buf[105] << 8) | data_buf[104]; |
|
|
|
battgo_info_t.soft_crash_times = data_buf[106]; |
|
|
|
battgo_info_t.soft_crash_times = data_buf[106]; |
|
|
|
battgo_info_t.current_charged_set = (data_buf[110] << 24) | (data_buf[109] << 16) | (data_buf[108] << 8) |data_buf[107]; |
|
|
|
battgo_info_t.current_charged_set = (data_buf[110] << 24) | (data_buf[109] << 16) | (data_buf[108] << 8) | data_buf[107]; |
|
|
|
battgo_info_t.vol_stored_set = (data_buf[112] << 8) |data_buf[111]; |
|
|
|
battgo_info_t.vol_stored_set = (data_buf[112] << 8) | data_buf[111]; |
|
|
|
battgo_info_t.vol_stored_full_set = (data_buf[114] << 8) |data_buf[113]; |
|
|
|
battgo_info_t.vol_stored_full_set = (data_buf[114] << 8) | data_buf[113]; |
|
|
|
battgo_info_t.self_discharge_times = (data_buf[115] << 8); |
|
|
|
battgo_info_t.self_discharge_times = (data_buf[115] << 8); |
|
|
|
gcs().update_serial_battgo_info(&battgo_info_t); |
|
|
|
gcs().update_serial_battgo_info(&battgo_info_t); |
|
|
|
//requestBattData(BATTGO_CMD_REQUEST_HISTORY);
|
|
|
|
//requestBattData(BATTGO_CMD_REQUEST_HISTORY);
|
|
|
@ -412,17 +230,20 @@ bool AP_BattMonitor_Serial_BattGo::parseBattGo() |
|
|
|
} |
|
|
|
} |
|
|
|
else if (data_buf[0] == 0x45) //
|
|
|
|
else if (data_buf[0] == 0x45) //
|
|
|
|
{ |
|
|
|
{ |
|
|
|
battgo_history_t.last_charge_cap = (data_buf[7] << 24) | (data_buf[6] << 16) | (data_buf[5] << 8) |data_buf[4]; |
|
|
|
// gcs().send_text(MAV_SEVERITY_INFO,"into battgo 0x45 battgo history");
|
|
|
|
|
|
|
|
battgo_history_t.last_charge_cap = (data_buf[7] << 24) | (data_buf[6] << 16) | (data_buf[5] << 8) | data_buf[4]; |
|
|
|
|
|
|
|
|
|
|
|
for(int i=0;i<6;i++){ |
|
|
|
for (int i = 0; i < 6; i++) |
|
|
|
battgo_history_t.battery_core_vol[i] = (data_buf[8+2*i+1]<<8)|data_buf[8+2*i]; |
|
|
|
{ |
|
|
|
} |
|
|
|
battgo_history_t.battery_core_vol[i] = (data_buf[8 + 2 * i + 1] << 8) | data_buf[8 + 2 * i]; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for(int i=0;i<6;i++){ |
|
|
|
for (int i = 0; i < 6; i++) |
|
|
|
battgo_history_t.Internal_resistance[i] = (data_buf[20+2*i+1]<<8)|data_buf[20+2*i]; |
|
|
|
{ |
|
|
|
} |
|
|
|
battgo_history_t.Internal_resistance[i] = (data_buf[20 + 2 * i + 1] << 8) | data_buf[20 + 2 * i]; |
|
|
|
|
|
|
|
} |
|
|
|
battgo_history_t.charge_state = data_buf[32]; |
|
|
|
battgo_history_t.charge_state = data_buf[32]; |
|
|
|
gcs().update_serial_battgo_history(&battgo_history_t); |
|
|
|
gcs().update_serial_battgo_history(&battgo_history_t); |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
return false; |
|
|
|
return false; |
|
|
@ -430,9 +251,12 @@ bool AP_BattMonitor_Serial_BattGo::parseBattGo() |
|
|
|
|
|
|
|
|
|
|
|
void AP_BattMonitor_Serial_BattGo::read() |
|
|
|
void AP_BattMonitor_Serial_BattGo::read() |
|
|
|
{ |
|
|
|
{ |
|
|
|
requestBattData(0x42); |
|
|
|
requestBattData(0x42); |
|
|
|
|
|
|
|
|
|
|
|
if (get_reading()) |
|
|
|
if (get_reading()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
if (parseBattGo()){ |
|
|
|
|
|
|
|
|
|
|
|
uint32_t tnow = AP_HAL::micros(); |
|
|
|
uint32_t tnow = AP_HAL::micros(); |
|
|
|
// timeout after 5 seconds
|
|
|
|
// timeout after 5 seconds
|
|
|
|
if ((tnow - _interim_state.last_time_micros) > AP_BATTMONITOR_SERIAL_TIMEOUT_MICROS) |
|
|
|
if ((tnow - _interim_state.last_time_micros) > AP_BATTMONITOR_SERIAL_TIMEOUT_MICROS) |
|
|
@ -442,13 +266,19 @@ void AP_BattMonitor_Serial_BattGo::read() |
|
|
|
|
|
|
|
|
|
|
|
// Copy over relevant states over to main state
|
|
|
|
// Copy over relevant states over to main state
|
|
|
|
// WITH_SEMAPHORE(_sem_battmon);
|
|
|
|
// WITH_SEMAPHORE(_sem_battmon);
|
|
|
|
_state.temperature = _interim_state.temperature; |
|
|
|
|
|
|
|
|
|
|
|
_state.cell_voltages = _interim_state.cell_voltages; |
|
|
|
_state.voltage = _interim_state.voltage; |
|
|
|
_state.voltage = _interim_state.voltage; |
|
|
|
_state.current_amps = _interim_state.current_amps; |
|
|
|
_state.current_amps = _interim_state.current_amps; |
|
|
|
_state.consumed_mah = _interim_state.consumed_mah; |
|
|
|
_state.consumed_mah = _interim_state.consumed_mah; |
|
|
|
_state.consumed_wh = _interim_state.consumed_wh; |
|
|
|
_state.consumed_wh = _interim_state.consumed_wh; |
|
|
|
_state.last_time_micros = _interim_state.last_time_micros; |
|
|
|
_state.last_time_micros = _interim_state.last_time_micros; |
|
|
|
|
|
|
|
//...
|
|
|
|
|
|
|
|
_state.temperature = _interim_state.temperature; |
|
|
|
|
|
|
|
_state.temperature_time = _interim_state.temperature_time; |
|
|
|
|
|
|
|
//...
|
|
|
|
_state.healthy = _interim_state.healthy; |
|
|
|
_state.healthy = _interim_state.healthy; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -456,3 +286,91 @@ void AP_BattMonitor_Serial_BattGo::notice_to_send_battgo_param() |
|
|
|
{ |
|
|
|
{ |
|
|
|
gcs().send_message(MSG_BATTGAO_INFO); |
|
|
|
gcs().send_message(MSG_BATTGAO_INFO); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void AP_BattMonitor_Serial_BattGo::rxProcess(uint8_t data) { |
|
|
|
|
|
|
|
if (data == 0x55) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
m_SyncByteCount++; |
|
|
|
|
|
|
|
if (m_SyncByteCount & 0x01) |
|
|
|
|
|
|
|
return ;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (m_SyncByteCount & 0x01)
|
|
|
|
|
|
|
|
m_eRxStatus = rsWaitAddres; |
|
|
|
|
|
|
|
m_SyncByteCount = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (m_eRxStatus) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
case rsWaitSync: |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case rsWaitAddres: |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (data != 0x21) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
m_eRxStatus = rsWaitSync; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
check_sum = data; |
|
|
|
|
|
|
|
m_eRxStatus = rsWaitLength; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case rsWaitLength: |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (data < 2) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
m_eRxStatus = rsWaitSync; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
m_u08RXCnt = 0; |
|
|
|
|
|
|
|
payload_length = data; |
|
|
|
|
|
|
|
check_sum += data; |
|
|
|
|
|
|
|
m_eRxStatus = rsWaitData; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case rsWaitData: |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
data_buf[m_u08RXCnt] = data; |
|
|
|
|
|
|
|
m_u08RXCnt++; |
|
|
|
|
|
|
|
check_sum += data; |
|
|
|
|
|
|
|
if (m_u08RXCnt >= payload_length) |
|
|
|
|
|
|
|
m_eRxStatus = rsWaitChkSumL; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case rsWaitChkSumL: |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (data == (check_sum & 0xFF)) |
|
|
|
|
|
|
|
m_eRxStatus = rsWaitChkSumH; |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
m_eRxStatus = rsWaitSync; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case rsWaitChkSumH: |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (data == ((check_sum >> 8) & 0xFF)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
//m_bMessege = TRUE;
|
|
|
|
|
|
|
|
isparse = true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
m_eRxStatus = rsWaitSync; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
m_eRxStatus = rsWaitSync; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|