
Code for the Battery MBED
Dependencies: NRF2401P mbed-rtos mbed
Revision 0:3d91ae4fc885, committed 2015-06-12
- Comitter:
- dontknowhow
- Date:
- Fri Jun 12 14:37:27 2015 +0000
- Commit message:
- Version 1, work in progress
Changed in this revision
diff -r 000000000000 -r 3d91ae4fc885 NRF2401P.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/NRF2401P.lib Fri Jun 12 14:37:27 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/epgmdm/code/NRF2401P/#7e253c677a1f
diff -r 000000000000 -r 3d91ae4fc885 comms.cpp
diff -r 000000000000 -r 3d91ae4fc885 comms.h
diff -r 000000000000 -r 3d91ae4fc885 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Jun 12 14:37:27 2015 +0000 @@ -0,0 +1,291 @@ +#include "mbed.h" +#include "rtos.h" +#include "NRF2401P.h" + +#define BATTERY_ID "123" + +#define CAPACITY 3600 //in Joules (=1000mAh) + +#define STORAGE_READINGS 200 //86400 + +#define READING_INTERVAL 1.0 + +#define IDLING_POWER 0.001 // 1mW + +// Three different Modes, as explained in the Wiki. +#define IDLING 1 +#define CHARGING 2 +#define POWERING 3 + +Serial pc(USBTX, USBRX); // tx, rx + +// ADC inputs +AnalogIn bat_v(PTB0); +AnalogIn bat_i(PTB1); + +// The ADC measurements are run by a ticker +Ticker get_stats_tick; + +// structure for storing our data. +typedef struct { + float voltage; // instantaneous voltage in V + float current; // instantaneous current in A + float power; // instantaneous power in W + + double energy; // total energy into & out of battery in J + double c_count; // total current in & out "Coulomb count" + + float charge; // estimated charge as a percentage + int capacity; // estimated capacity in mJ + + int powers[STORAGE_READINGS]; // array to hold powers in mW + int voltages[STORAGE_READINGS]; // array to hold voltages in mV + int currents[STORAGE_READINGS]; // array to hold currents in uA + + unsigned int readings; // count of readings taken + float idling_time; // time spent idling + + char mode; // current mode of operation + bool new_data; // indicates fresh data ready to be processed, + // flag set to true by get_stats() + +} stats_t; + +// global variable for use in ticker +stats_t stats; + +// Debug function for printing to a serial port +void print_stats(Serial *out, stats_t *stats); + +// Use the ADC0 +void get_stats(stats_t *stats); + +// wrapper function, this is called by the ticker. +void get_stats_w(){ + get_stats( &stats ); +} + +// used for initializing the structure +void reset_stats(stats_t *stats); + +// seperate thread for communication +void comms_thread(void const *args); + +int main() { + + // start the comms thread + Thread thread(comms_thread); + + // start taking measurements + get_stats_tick.attach(&get_stats_w, READING_INTERVAL); + + // initialiye the stats structure + reset_stats(&stats); + + while(true){ + + // get stats has supplied some new data, analyse it. + if(stats.new_data){ + + // add the current values to the storage array + stats.powers[stats.readings - 1] = (int)( stats.power * 1000.0 ); + stats.voltages[stats.readings - 1] = (int)( stats.voltage * 1000.0 ); + stats.currents[stats.readings - 1] = (int)( stats.current * 1000.0 * 1000.0); + + // evaluate the current mode by looking at the current + if( abs(stats.power)< IDLING_POWER){ + stats.mode = IDLING; + } else if (stats.power < 0){ + stats.mode = CHARGING; + } else{ + stats.mode = POWERING; + } + + // measure the time spent idling + if(stats.mode==IDLING) + stats.idling_time += READING_INTERVAL; + + // Coulomb counting and total energy in/out + stats.c_count += stats.current * READING_INTERVAL; + stats.energy += stats.power * READING_INTERVAL; + + // estimating SOC + // http://liionbms.com/php/wp_soc_estimate.php + + if(stats.voltage > 3.5){ // Voltage Conversion + stats.charge = (stats.voltage - 3.5) * 0.1f + 0.9f; + } + else if(stats.voltage < 3.0){ // Voltage Conversion + stats.charge = (stats.voltage - 3.0) * 0.1f; + } + else{ // Coulomb Counting + stats.charge = stats.c_count / stats.capacity; + } + + // data has been analysed, reset flag + stats.new_data = false; + } + + + if(stats.readings>=STORAGE_READINGS){ // We have reached the maximum amount of readings, start again! + + reset_stats(&stats); + } + + + + } +} + + +void comms_thread(void const *args){ + + // set up nrf radio communication + long long addr1=0xAB12CD; // setup address - any 5 byte number - same as RX + int channel = 52; // [0-126] setup channel, must be same as RX + bool txOK; + char msg[32]; + char ackData[32]; + char len; + + // Setup + NRF2401P nrf1(PTD2, PTD3, PTD1, PTA13, PTD0); //mosi, miso, sclk, csn, ce) + + nrf1.quickTxSetup(channel, addr1); // sets nrf24l01+ as transmitter + + Timer att_t; // timer for sending attention commands + Timer out_t; // timer for timeouts + + + + att_t.start(); + + char c = '0'; + float voltage, current, voltage_r, current_r; + while(true){ + + // listen to pc serial for debugging + if(pc.readable()) + c = pc.getc(); + + if(c=='p'){ + print_stats(&pc, &stats); + } + if(c=='g'){ + get_stats(&stats); + } + if(c=='r'){ + voltage_r = bat_v.read(); + current_r = bat_i.read(); + + // formulas based on empirical measurements + voltage = 10.6 * voltage_r - 4.14f; + current = -1.7574 * current_r + 1.248; + + pc.printf("Voltage: %1.3f Current: %1.3f AN0: %1.3f AN1: %1.3f\r\n", voltage, current, voltage_r, current_r); + } + c = '0'; + + if(att_t.read()>1.0f){ + // Send Attention command to locker every second + + strcpy (msg, "AT"); + txOK = nrf1.transmitData(msg,strlen(msg)); + + + while(att_t.read()<2.0f){ + if (nrf1.isAckData()) { + len= nrf1.getRxData(ackData); // len is number of bytes in ackData + ackData[len] = '\0'; + + + + if (strcmp(ackData, "HELLO") == 0){ + + + + sprintf(msg, "%s1",BATTERY_ID); + + txOK = nrf1.transmitData(msg,strlen(msg)); + + + } + + break; + } + } + + att_t.reset(); + } + + Thread::wait(20); + } +} + +// reset and initialize the structure +void reset_stats(stats_t *stats){ + + stats->readings = 0; + stats->energy = 0; + stats->c_count = 0; + stats->idling_time = 0.0; + stats->capacity = CAPACITY; + stats->new_data = false; + + for( int i=0; i<STORAGE_READINGS; i++){ + stats->powers[i] = 0; + stats->voltages[i] = 0; + stats->currents[i] = 0; + } + +} + +// print some data +void print_stats(Serial *out, stats_t *stats){ + out->printf("\r\n\r\n"); + for(int i = 0; i < stats->readings; i++){ + //out->printf("Reading %3d: Voltage: %dmV Current: %duA Power: %dmW \r\n", i, stats->voltages[i], stats->currents[i], stats->powers[i]); + } + out->printf("\r\n"); + out->printf("V: %1.2fV I: %1.2fmA Power: %1.0fmW \r\n", stats->voltage, stats->current * 1000, stats->power * 1000); + out->printf("Mode: %d \r\n", stats->mode); + out->printf("Energy: %1.3fJ \r\n", stats->energy); + out->printf("Coulomb C: %1.3fC \r\n", stats->c_count); + out->printf("Time: %1.3f s \r\n", stats->readings * READING_INTERVAL); + out->printf("Readings: %d \r\n", stats->readings); + out->printf("Interval: %1.3fs \r\n", READING_INTERVAL); + out->printf("Idling t: %ds \r\n", stats->idling_time); + out->printf("Est Charge: %.0f%% \r\n", stats->charge * 100); + +} + +// every second, read the adc and save it in the structure +void get_stats(stats_t *stats){ + + if(stats->new_data){ // ERROR: stats have not been processed + pc.printf("ERROR: stats not processed\r\n"); + } + + //average over 10 readings + float current_r = 0; + float voltage_r = 0; + + for(int i = 0; i<10; i++){ + voltage_r += bat_v.read(); + current_r += bat_i.read(); + //pc.printf("%1.3f %1.3f \r\n",voltage_r, current_r); + } + + + current_r /= 10.0; + voltage_r /= 10.0; + + stats->voltage = 10.6f * voltage_r - 4.14f; + stats->current = -1.7574f * current_r + 1.252f; + + stats->power = stats->voltage * stats->current; + + stats->readings++; + + stats->new_data = true; +} \ No newline at end of file
diff -r 000000000000 -r 3d91ae4fc885 mbed-rtos.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Fri Jun 12 14:37:27 2015 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/mbed_official/code/mbed-rtos/#ed4ff3bea947
diff -r 000000000000 -r 3d91ae4fc885 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Fri Jun 12 14:37:27 2015 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/cbbeb26dbd92 \ No newline at end of file