@ -10,14 +10,15 @@ extern const AP_HAL::HAL &hal;
@@ -10,14 +10,15 @@ extern const AP_HAL::HAL &hal;
AP_BattMonitor_Serial_BattGo : : AP_BattMonitor_Serial_BattGo ( AP_BattMonitor & mon ,
AP_BattMonitor : : BattMonitor_State & mon_state ,
AP_BattMonitor_Params & params ,
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 ( ) ;
uart = serial_manager . find_serial ( AP_SerialManager : : SerialProtocol_Battery , serial_instance ) ;
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,
@@ -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
{
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 )
{
if ( uart ! = nullptr )
{
requestBattData ( BATTGO_CMD_REQUEST_ACTUAL_DATA ) ;
requestBattData ( BATTGO_CMD_REQUEST_PARAM ) ;
requestBattData ( BATTGO_CMD_REQUEST_HISTORY ) ;
gcs ( ) . send_text ( MAV_SEVERITY_INFO , " into BattGo::init() " ) ;
requestBattData ( BATTGO_CMD_REQUEST_ACTUAL_DATA ) ;
requestBattData ( BATTGO_CMD_REQUEST_PARAM ) ;
requestBattData ( BATTGO_CMD_REQUEST_HISTORY ) ;
}
}
bool isparse = false ;
bool AP_BattMonitor_Serial_BattGo : : get_reading ( ) //TODO need to Refactor
{
if ( uart = = nullptr )
{
return false ;
}
int16_t numc ;
numc = uart - > available ( ) ;
uint8_t data ;
bool parsed = false ;
if ( numc = = 0 )
gcs ( ) . send_text ( MAV_SEVERITY_INFO , " uasart num:%d " , numc ) ;
isparse = false ;
for ( int16_t i = 0 ; i < numc ; i + + )
{
data = uart - > read ( ) ;
switch ( step )
{
case 0 :
if ( Head1 = = data )
{
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 ;
rxProcess ( data ) ;
if ( isparse ) {
isparse = true ;
return true ;
}
}
return parsed ;
return isparse ;
}
void AP_BattMonitor_Serial_BattGo : : gotoStepAddr ( uint8_t & data )
{
step = 2 ; //next step
addr = data ;
check_sum = data ;
}
// void AP_BattMonitor_Serial_BattGo::gotoStepAddr(uint8_t &data)
// {
// step = 2; //next step
// addr = data;
// check_sum = data;
// }
void AP_BattMonitor_Serial_BattGo : : requestBattData ( uint8_t data )
{
//发送data主要 0x40 0x42 0x44 地址0x21 及计算crc 均不会出现0x55,故不做0x55处理
uint8_t send_data [ 6 ] ;
uint8_t send_data [ 13 ] ;
send_data [ 0 ] = 0x55 ;
send_data [ 1 ] = 0x2 1 ;
send_data [ 2 ] = 0x01 ;
send_data [ 1 ] = 0x12 ;
send_data [ 2 ] = 0x08 ;
send_data [ 3 ] = data ;
uint16_t crc = send_data [ 1 ] + send_data [ 2 ] + send_data [ 3 ] ;
send_data [ 4 ] = crc & 0xff ;
send_data [ 5 ] = crc > > 8 & 0xff ;
send_data [ 4 ] = 0 ;
send_data [ 5 ] = 0 ;
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 ) )
{
uart - > write ( & send_data [ 0 ] , sizeof ( send_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)
// void AP_BattMonitor_Serial_BattGo::setPayLoadData(uint8_t &usart_data)
// {
// if (!is_read_header )
// if (payload_counter < payload_length)
// {
// target_data = usart_data;
// switch (step)
// {
// 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;
// data_buf[payload_counter] = usart_data;
// payload_counter++;
// }
// 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 ( )
{
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 dt = tnow - _interim_state . last_time_micros ;
_interim_state . voltage = 0 ;
for ( uint8_t i = 0 ; i < 6 ; 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 . 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 ;
_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 ) ;
//gcs().send_text(MAV_SEVERITY_INFO," _interim_state.cell_voltages: %f", _interim_state.voltage);
_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
if ( _interim_state . last_time_micros ! = 0 & & dt < 2000000 )
{
@ -338,7 +156,7 @@ bool AP_BattMonitor_Serial_BattGo::parseBattGo()
@@ -338,7 +156,7 @@ bool AP_BattMonitor_Serial_BattGo::parseBattGo()
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 . connect_status = data_buf [ 2 ] ;
battgo_info_t . sub_software_ver = data_buf [ 3 ] ;
@ -362,7 +180,7 @@ bool AP_BattMonitor_Serial_BattGo::parseBattGo()
@@ -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 day = data_buf [ 34 ] & 0x3e > > 1 ;
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_mon = month ;
@ -393,18 +211,18 @@ bool AP_BattMonitor_Serial_BattGo::parseBattGo()
@@ -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 . 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_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_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 . 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 . 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 . 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 . 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 . under_vol_abr_times = ( data_buf [ 105 ] < < 8 ) | data_buf [ 104 ] ;
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 . 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 . 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_full_set = ( data_buf [ 114 ] < < 8 ) | data_buf [ 113 ] ;
battgo_info_t . self_discharge_times = ( data_buf [ 115 ] < < 8 ) ;
gcs ( ) . update_serial_battgo_info ( & battgo_info_t ) ;
//requestBattData(BATTGO_CMD_REQUEST_HISTORY);
@ -412,17 +230,20 @@ bool AP_BattMonitor_Serial_BattGo::parseBattGo()
@@ -412,17 +230,20 @@ bool AP_BattMonitor_Serial_BattGo::parseBattGo()
}
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 + + ) {
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 + + )
{
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 + + ) {
battgo_history_t . Internal_resistance [ i ] = ( data_buf [ 20 + 2 * i + 1 ] < < 8 ) | data_buf [ 20 + 2 * 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 . charge_state = data_buf [ 32 ] ;
gcs ( ) . update_serial_battgo_history ( & battgo_history_t ) ;
gcs ( ) . update_serial_battgo_history ( & battgo_history_t ) ;
return true ;
}
return false ;
@ -430,9 +251,12 @@ bool AP_BattMonitor_Serial_BattGo::parseBattGo()
@@ -430,9 +251,12 @@ bool AP_BattMonitor_Serial_BattGo::parseBattGo()
void AP_BattMonitor_Serial_BattGo : : read ( )
{
requestBattData ( 0x42 ) ;
requestBattData ( 0x42 ) ;
if ( get_reading ( ) )
{
if ( parseBattGo ( ) ) {
uint32_t tnow = AP_HAL : : micros ( ) ;
// timeout after 5 seconds
if ( ( tnow - _interim_state . last_time_micros ) > AP_BATTMONITOR_SERIAL_TIMEOUT_MICROS )
@ -442,13 +266,19 @@ void AP_BattMonitor_Serial_BattGo::read()
@@ -442,13 +266,19 @@ void AP_BattMonitor_Serial_BattGo::read()
// Copy over relevant states over to main state
// WITH_SEMAPHORE(_sem_battmon);
_state . temperature = _interim_state . temperature ;
_state . cell_voltages = _interim_state . cell_voltages ;
_state . voltage = _interim_state . voltage ;
_state . current_amps = _interim_state . current_amps ;
_state . consumed_mah = _interim_state . consumed_mah ;
_state . consumed_wh = _interim_state . consumed_wh ;
_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 ;
}
}
}
@ -456,3 +286,91 @@ void AP_BattMonitor_Serial_BattGo::notice_to_send_battgo_param()
@@ -456,3 +286,91 @@ void AP_BattMonitor_Serial_BattGo::notice_to_send_battgo_param()
{
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 ;
}
}