diff --git a/micro/fuel_gauge.c b/micro/fuel_gauge.c index c4e1e6ab52d3f5b2c45b96be90d32d2fcce00b48..0e32e11f58d84965fc2414e350b5e0d7c7afb7ca 100755 --- a/micro/fuel_gauge.c +++ b/micro/fuel_gauge.c @@ -6,32 +6,31 @@ #include "a2d.h" short int battery_voltage; -short int input_current; -short int output_current; +float input_current; +float output_current; // battery I2C slave address unsigned char battery_id; unsigned char EEMEM ee_battery_id=0x31; // remaining_capacity -float remaining_capacity; -//float EEMEM ee_remaining_capacity=108000000.0;//mAs -float EEMEM ee_remaining_capacity=30000.0;//mAh +volatile unsigned short int remaining_capacity; +unsigned short int EEMEM ee_remaining_capacity=30000;//mAh // maximum capacity -volatile float maximum_capacity; -//float EEMEM ee_maximum_capacity=108000000.0;//mAs -float EEMEM ee_maximum_capacity=30000.0;//mAh +volatile unsigned short int maximum_capacity; +unsigned short int EEMEM ee_maximum_capacity=30000;//mAh // charge cycles -volatile short int charge_cycles; -short int EEMEM ee_charge_cycles=0; +volatile unsigned short int charge_cycles; +unsigned short int EEMEM ee_charge_cycles=0; +// accumutaed_capacity +float accumulated_capacity; -const float current_gain=48.828125;//mA -//const float period=0.001984*4;//s -const float period=0.000002204444;//h +const double current_gain=48.828125;//mA +const double period=0.00000222222;//h (8 ms) void update_fuel_gauge(void) { - float current_ma; + short int increment=0; outb(TCNT0,131);// reload the timer value // read the voltage and temperature from the battery @@ -39,26 +38,33 @@ void update_fuel_gauge(void) input_current=adc_get_averaged_channel(6)*current_gain; output_current=adc_get_averaged_channel(7)*current_gain; // update the internal variables - remaining_capacity=remaining_capacity-(input_current*period); + accumulated_capacity+=(input_current-output_current)*period; + increment=(short int)accumulated_capacity; + accumulated_capacity-=increment; + remaining_capacity-=increment; + if(remaining_capacity>maximum_capacity) + remaining_capacity=maximum_capacity; + if(remaining_capacity<0) + remaining_capacity=0; } void fuel_gauge_init(void) { // read the data from the EEPROM battery_id=eeprom_read_byte(&ee_battery_id); - remaining_capacity=eeprom_read_float(&ee_remaining_capacity); - maximum_capacity=eeprom_read_float(&ee_maximum_capacity); + remaining_capacity=eeprom_read_word(&ee_remaining_capacity); + maximum_capacity=eeprom_read_word(&ee_maximum_capacity); charge_cycles=eeprom_read_word(&ee_charge_cycles); + accumulated_capacity=0.0; // initialize the timer timerInit(); timer0SetPrescaler(TIMER_CLK_DIV1024); - outb(TCNT0, 131); + outb(TCNT0,131); timerAttach(TIMER0OVERFLOW_INT,update_fuel_gauge); // attach timer functions // initialize the i2c peripheral i2cInit(); - i2cSetBitrate(100); // initialize the a2d converter a2dInit(); a2dSetPrescaler(ADC_PRESCALE_DIV128); @@ -70,35 +76,66 @@ void fuel_gauge_init(void) short int get_time_to_charged(void) { - return ((maximum_capacity-remaining_capacity)*60)/output_current; + return ((maximum_capacity-remaining_capacity)*60.0)/output_current; } short int get_time_to_discharged(void) { - return (remaining_capacity*60)/input_current; + return (remaining_capacity*60.0)/input_current; } short int get_input_current(void) { - return input_current; + return (short int)input_current; } short int get_output_current(void) { - return output_current; + return (short int)output_current; } -short int get_voltage(void) +void get_voltage(unsigned char *voltage) { - return 0; + unsigned char read_cmd,i; + unsigned char voltage_data[18]; + + // read the voltage registers of the battery + // send the read request + read_cmd=0x30; + if(i2cMasterSendNI(0x62,1,&read_cmd)==I2C_OK) + { + if(i2cMasterReceiveNI(0x62,18,voltage_data)==I2C_OK) + { + for(i=0;i<16;i++) + voltage[i]=voltage_data[i+2]; + } + } +} + +void get_temperature(unsigned char *temp1, unsigned char *temp2) +{ + unsigned char temp_data[6]; + unsigned char read_cmd; + + read_cmd=0x4A;// device start read address + if(i2cMasterSendNI(0x62,1,&read_cmd)==I2C_OK) + { + if(i2cMasterReceiveNI(0x62,6,temp_data)==I2C_OK) + { + temp1[0]=temp_data[2]; + temp1[1]=temp_data[3]; + temp2[0]=temp_data[4]; + temp2[1]=temp_data[5]; + } + } } short int get_remaining_capacity(void) { - return (short int)remaining_capacity; + return (short int)(remaining_capacity); } short int get_max_capacity(void) { - return maximum_capacity; + return (short int)(maximum_capacity); } diff --git a/micro/fuel_gauge.h b/micro/fuel_gauge.h index 75f9542c5a7d9cc7aa37980d43a8ac75f46ce302..c3f4d5acb63501752cc265ed9e7801cfbcc5c101 100755 --- a/micro/fuel_gauge.h +++ b/micro/fuel_gauge.h @@ -6,7 +6,8 @@ short int get_time_to_charged(void); short int get_time_to_discharged(void); short int get_input_current(void); short int get_output_current(void); -short int get_voltage(void); +void get_voltage(unsigned char *voltage); +void get_temperature(unsigned char *temp1, unsigned char *temp2); short int get_remaining_capacity(void); short int get_max_capacity(void); diff --git a/micro/gpio.c b/micro/gpio.c index 7a3d193685ace226d770b1d6f8741e1e7b3c59d8..37ab5b7fece1c12c7dac2b49aa897ad52b3f4f68 100755 --- a/micro/gpio.c +++ b/micro/gpio.c @@ -12,6 +12,7 @@ void InitGPIO(void) // PC1 as an output (load_control) DDRC=DDRC&0xF3;// PC2 as an input (UVP) // Pc3 as an input (OVP) + PORTC=0x00; } @@ -40,9 +41,9 @@ void handle_battery(void) { if(is_battery_present()) { - if(under_voltage_protection()) - disable_battery(); - else +// if(under_voltage_protection()) +// disable_battery(); +// else enable_battery(); } else @@ -53,15 +54,15 @@ void handle_load(void) { if(is_battery_present()) { - if(under_voltage_protection()) - disable_load(); - else - { +// if(under_voltage_protection()) +// disable_load(); +// else +// { if(is_load_on()) enable_load(); else disable_load(); - } +// } } else { diff --git a/micro/i2c.c b/micro/i2c.c index bcdc5d4ab85c915b0399933ffda4918627ff2273..00a527e52fff9bc240070dd196f6772a89eb85be 100755 --- a/micro/i2c.c +++ b/micro/i2c.c @@ -234,7 +234,7 @@ u08 i2cMasterSendNI(u08 deviceAddr, u08 length, u08* data) // transmit stop condition // leave with TWEA on for slave receiving i2cSendStop(); - while( !(inb(TWCR) & BV(TWSTO)) ); + while( !(inb(TWCR) & BV(TWEA)) ); // enable TWI interrupt sbi(TWCR, TWIE); diff --git a/micro/tibi_dabo_battery.c b/micro/tibi_dabo_battery.c index 230477446707374f309d220a9021ad00fc7e9a2a..3cab20cb699fbbab2b795b520bb6ec1bcc589b8b 100755 --- a/micro/tibi_dabo_battery.c +++ b/micro/tibi_dabo_battery.c @@ -12,12 +12,14 @@ #include "fuel_gauge.h" +#include "i2c.h" + typedef struct { unsigned char header[2]; - short int battery_voltage; - short int temperature1; - short int temperature2; + unsigned char battery_voltage[16]; + unsigned char temperature1[2]; + unsigned char temperature2[2]; unsigned char status; // bit 0: battery_present // bit 1: charger_present; @@ -33,11 +35,8 @@ typedef struct int main (void) { -// unsigned char read_cmd[2]; -// unsigned char voltage_data[18]; -// unsigned char temp_data[6]; + unsigned char i; TBatteryInfo info; - int i=0; // initialize the GPIO InitGPIO(); @@ -53,74 +52,30 @@ int main (void) info.header[1]=0xAA; while(1) { - // read the voltage registers of the battery - // send the read request -/* read_cmd[0]=0x30;// device start read address - read_cmd[1]=18;// read length - if(i2cMasterSendNI(0x60,2,read_cmd)==I2C_OK) - { - if(i2cMasterReceiveNI(0x60,18,voltage_data)==I2C_OK) - { - info.cell1_voltage[0]=voltage_data[2]; - info.cell1_voltage[1]=voltage_data[3]; - info.cell2_voltage[0]=voltage_data[4]; - info.cell2_voltage[1]=voltage_data[5]; - info.cell3_voltage[0]=voltage_data[6]; - info.cell3_voltage[1]=voltage_data[7]; - info.cell4_voltage[0]=voltage_data[8]; - info.cell4_voltage[1]=voltage_data[9]; - info.cell5_voltage[0]=voltage_data[10]; - info.cell5_voltage[1]=voltage_data[11]; - info.cell6_voltage[0]=voltage_data[12]; - info.cell6_voltage[1]=voltage_data[13]; - info.cell7_voltage[0]=voltage_data[14]; - info.cell7_voltage[1]=voltage_data[15]; - info.cell8_voltage[0]=voltage_data[16]; - info.cell8_voltage[1]=voltage_data[17]; - // read the voltage registers of the battery - // send the read request - read_cmd[0]=0x4A;// device start read address - read_cmd[1]=6;// read length - if(i2cMasterSendNI(0x60,2,read_cmd)==I2C_OK) - { - if(i2cMasterReceiveNI(0x60,6,temp_data)==I2C_OK) - { - info.temperature1[0]=temp_data[2]; - info.temperature1[1]=temp_data[3]; - info.temperature2[0]=temp_data[4]; - info.temperature2[1]=temp_data[5]; - info.battery_present=is_battery_present(); - info.charger_present=is_charger_present(); - info.load_on=is_load_on(); - info.UVP=under_voltage_protection(); - info.OVP=over_voltage_protection(); - } - } - } - }*/ - _delay_ms(1000); - handle_battery(); - handle_load(); - info.battery_voltage=get_voltage(); - info.status=0x00; - if(is_battery_present()) - info.status|=0x01; - if(is_charger_present()) - info.status|=0x02; - if(is_load_on()) - info.status|=0x04; - if(under_voltage_protection()) - info.status|=0x08; - if(over_voltage_protection()) - info.status|=0x10; - info.current_in=get_input_current(); - info.current_out=get_output_current(); - info.rem_capacity=get_remaining_capacity(); - info.time_to_charged=get_time_to_charged(); - info.time_to_discharged=get_time_to_discharged(); - // send tha information packet - for(i=0;i<sizeof(TBatteryInfo);i++) - uartSendByte(((unsigned char *)&info)[i]); + _delay_ms(1000); + handle_battery(); + handle_load(); + get_voltage(info.battery_voltage); + get_temperature(info.temperature1,info.temperature2); + info.status=0x00; + if(is_battery_present()) + info.status|=0x01; + if(is_charger_present()) + info.status|=0x02; + if(is_load_on()) + info.status|=0x04; + if(under_voltage_protection()) + info.status|=0x08; + if(over_voltage_protection()) + info.status|=0x10; + info.current_in=get_input_current(); + info.current_out=get_output_current(); + info.rem_capacity=get_remaining_capacity(); + info.time_to_charged=get_time_to_charged(); + info.time_to_discharged=get_time_to_discharged(); + // send tha information packet + for(i=0;i<sizeof(TBatteryInfo);i++) + uartSendByte(((unsigned char *)&info)[i]); } } diff --git a/micro/timer.c b/micro/timer.c index 07398e0e1da87a5cd1e2db345bf50f3055235dee..434685b8abacd8592cb383b75fcd1caab84a85a1 100755 --- a/micro/timer.c +++ b/micro/timer.c @@ -235,7 +235,7 @@ void timerPause(unsigned short pause_ms) } } - /* old inaccurate code, for reference + //old inaccurate code, for reference // calculate delay for [pause_ms] milliseconds u16 prescaleDiv = 1<<(pgm_read_byte(TimerPrescaleFactor+inb(TCCR0))); diff --git a/src/examples/segway_battery_test.cpp b/src/examples/segway_battery_test.cpp index 1e7e1a9bf58730641262de1f2954fb5c0aff87c1..db77aef80c68018c833204107f7aeea8d2b9d533 100755 --- a/src/examples/segway_battery_test.cpp +++ b/src/examples/segway_battery_test.cpp @@ -11,6 +11,7 @@ int main(int argc, char *argv[]) while(1) { try{ + std::cout << "Battery voltage: " << battery.get_current_voltage() << " V" << std::endl; std::cout << "Input current: " << battery.get_input_current() << " mA" << std::endl; std::cout << "Output current: " << battery.get_output_current() << " mA" << std::endl; std::cout << "Remaining capacity: " << battery.get_remaining_capacity() << " mAh" << std::endl; diff --git a/src/segway_battery.cpp b/src/segway_battery.cpp index 19f8404fcc0aaa61de5e877d87847e41e3e8058d..e28fb38a23d4dbc7c65b386816beed76a79ec85d 100755 --- a/src/segway_battery.cpp +++ b/src/segway_battery.cpp @@ -86,7 +86,7 @@ void CSegway_Battery::parse_packet(unsigned char *data, int len) { int i=0; static int pos=-2; - static unsigned char packet_data[17]; + static unsigned char packet_data[31]; for(i=0;i<len;i++) { @@ -94,24 +94,37 @@ void CSegway_Battery::parse_packet(unsigned char *data, int len) { if(data[i]==0x55) pos++; + else + pos=-2; } else if(pos==-1) { if(data[i]==0xAA) pos++; + else + pos=-2; } else { packet_data[pos]=data[i]; pos++; - if(pos==17) + if(pos==31) { pos=-2; - this->info.current_in=packet_data[7]+packet_data[8]*256; - this->info.current_out=packet_data[9]+packet_data[10]*256; - this->info.rem_capacity=packet_data[11]+packet_data[12]*256; - this->info.time_to_charged=packet_data[13]+packet_data[14]*256; - this->info.time_to_discharged=packet_data[15]+packet_data[16]*256; + this->info.battery_voltage=(packet_data[0])+(packet_data[1]<<8); + this->info.battery_voltage+=(packet_data[2])+(packet_data[3]<<8); + this->info.battery_voltage+=(packet_data[4])+(packet_data[5]<<8); + this->info.battery_voltage+=(packet_data[6])+(packet_data[7]<<8); + this->info.battery_voltage+=(packet_data[8])+(packet_data[9]<<8); + this->info.battery_voltage+=(packet_data[10])+(packet_data[11]<<8); + this->info.battery_voltage+=(packet_data[12])+(packet_data[13]<<8); + this->info.battery_voltage+=(packet_data[14])+(packet_data[15]<<8); + this->info.battery_voltage/=6.5536; + this->info.current_in=packet_data[21]+packet_data[22]*256; + this->info.current_out=packet_data[23]+packet_data[24]*256; + this->info.rem_capacity=packet_data[25]+packet_data[26]*256; + this->info.time_to_charged=packet_data[27]+packet_data[28]*256; + this->info.time_to_discharged=packet_data[29]+packet_data[30]*256; } } } @@ -119,7 +132,7 @@ void CSegway_Battery::parse_packet(unsigned char *data, int len) double CSegway_Battery::get_current_voltage(void) { - return 0.0; + return this->info.battery_voltage; } double CSegway_Battery::get_current_temperature(void)