LTC6811 Battery Management System with ADuCM3029.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 
00002 #include "mbed.h"
00003 #include "bms.h"
00004 #include "LTC681x.h"
00005 #include "LTC6811.h"
00006 
00007 #define UI_BUFFER_SIZE 64
00008 #define SERIAL_TERMINATOR '\n'
00009 
00010 #define ENABLED 1
00011 #define DISABLED 0
00012 
00013 #define DATALOG_ENABLED 1
00014 #define DATALOG_DISABLED 0
00015 DigitalOut led1(LED1);
00016 Serial pc(USBTX, USBRX);
00017 
00018 void run_command(uint32_t cmd);
00019 void measurement_loop(uint8_t datalog_en);
00020 void print_menu();
00021 void print_cells(uint8_t datalog_en);
00022 void print_open();
00023 void print_aux(uint8_t datalog_en);
00024 void print_stat();
00025 void print_config();
00026 void print_rxconfig();
00027 void print_pec(void);
00028 void serial_print_hex(uint8_t data);
00029 void check_error(int error);
00030 //char get_char();
00031 //void read_config_data(uint8_t cfg_data[][6], uint8_t nIC);
00032 
00033 /**********************************************************
00034   Setup Variables
00035   The following variables can be modified to
00036   configure the software.
00037 
00038 ***********************************************************/
00039 const uint8_t TOTAL_IC = 1;//!<number of ICs in the daisy chain
00040 char ui_buffer[UI_BUFFER_SIZE];
00041 
00042 
00043 //ADC Command Configurations
00044 //const uint8_t ADC_OPT = ADC_OPT_DISABLED; // See LTC6811_daisy.h for Options
00045 const uint8_t ADC_CONVERSION_MODE = MD_7KHZ_3KHZ;//MD_7KHZ_3KHZ; //MD_26HZ_2KHZ;//MD_7KHZ_3KHZ; // See LTC6811_daisy.h for Options
00046 const uint8_t ADC_DCP = DCP_DISABLED; // See LTC6811_daisy.h for Options
00047 const uint8_t CELL_CH_TO_CONVERT = CELL_CH_ALL; // See LTC6811_daisy.h for Options
00048 const uint8_t AUX_CH_TO_CONVERT = AUX_CH_ALL; // See LTC6811_daisy.h for Options
00049 const uint8_t STAT_CH_TO_CONVERT = STAT_CH_ALL; // See LTC6811_daisy.h for Options
00050 
00051 const uint16_t MEASUREMENT_LOOP_TIME = 500;//milliseconds(mS)
00052 
00053 //Under Voltage and Over Voltage Thresholds
00054 const uint16_t OV_THRESHOLD = 41000; // Over voltage threshold ADC Code. LSB = 0.0001
00055 const uint16_t UV_THRESHOLD = 30000; // Under voltage threshold ADC Code. LSB = 0.0001
00056 
00057 //Loop Measurement Setup These Variables are ENABLED or DISABLED Remember ALL CAPS
00058 const uint8_t WRITE_CONFIG = DISABLED; // This is ENABLED or DISABLED
00059 const uint8_t READ_CONFIG = DISABLED; // This is ENABLED or DISABLED
00060 const uint8_t MEASURE_CELL = ENABLED; // This is ENABLED or DISABLED
00061 const uint8_t MEASURE_AUX = DISABLED; // This is ENABLED or DISABLED
00062 const uint8_t MEASURE_STAT = DISABLED; //This is ENABLED or DISABLED
00063 const uint8_t PRINT_PEC = DISABLED; //This is ENABLED or DISABLED
00064 
00065 
00066 // Read data from the serial interface into the ui_buffer buffer
00067 uint8_t read_data();
00068 
00069 // Read a float value from the serial interface
00070 float read_float();
00071 
00072 // Read an integer from the serial interface.
00073 // The routine can recognize Hex, Decimal, Octal, or Binary
00074 // Example:
00075 // Hex:     0x11 (0x prefix)
00076 // Decimal: 17
00077 // Octal:   O21 (leading letter O prefix)
00078 // Binary:  B10001 (leading letter B prefix)
00079 int32_t read_int();
00080 
00081 // Read a string from the serial interface.  Returns a pointer to the ui_buffer.
00082 char *read_string();
00083 
00084 // Read a character from the serial interface
00085 int8_t read_char();
00086 
00087 /************************************
00088   END SETUP
00089 *************************************/
00090 
00091 /******************************************************
00092  *** Global Battery Variables received from 681x commands
00093  These variables store the results from the LTC6811
00094  register reads and the array lengths must be based
00095  on the number of ICs on the stack
00096  ******************************************************/
00097 
00098 cell_asic bms_ic[TOTAL_IC];
00099 
00100 /*!*********************************************************************
00101   \brief main loop
00102 ***********************************************************************/
00103 int main(void)
00104 {
00105     uint32_t user_command;
00106     
00107     pc.baud(115200);
00108     spi_enable();
00109     LTC681x_init_cfg(TOTAL_IC, bms_ic);
00110     LTC6811_reset_crc_count(TOTAL_IC,bms_ic);
00111     LTC6811_init_reg_limits(TOTAL_IC,bms_ic);
00112     print_menu();
00113 
00114     while(1) {
00115         //pc.printf("check 00\n");
00116         //while(!pc.readable()) {
00117         wait(0.3);
00118         //    pc.printf("check 001\n");
00119         //}         // Check for user input
00120         //pc.printf("check 01\n");
00121         user_command = read_int();      // Read the user commandi
00122         pc.printf("command -> %d \n", user_command);
00123         run_command(user_command);
00124     }
00125 }
00126 
00127 /*!*****************************************
00128   \brief executes the user command
00129 *******************************************/
00130 
00131 void run_command(uint32_t cmd)
00132 {
00133     int8_t error = 0;
00134     uint32_t conv_time = 0;
00135 //    uint32_t user_command;
00136     int8_t readIC=0;
00137     char input = 0;
00138     switch (cmd) {
00139 
00140         case 1: // Write Configuration Register
00141             wakeup_sleep(TOTAL_IC);
00142             LTC6811_wrcfg(TOTAL_IC,bms_ic);
00143             print_config();
00144             break;
00145 
00146         case 2: // Read Configuration Register
00147             wakeup_sleep(TOTAL_IC);
00148             error = LTC6811_rdcfg(TOTAL_IC,bms_ic);
00149             check_error(error);
00150             print_rxconfig();
00151             break;
00152 
00153         case 3: // Start Cell ADC Measurement
00154             wakeup_sleep(TOTAL_IC);
00155             LTC6811_adcv(ADC_CONVERSION_MODE,ADC_DCP,CELL_CH_TO_CONVERT);
00156             conv_time = LTC6811_pollAdc();
00157             pc.printf("cell conversion completed in:");
00158             pc.printf("%.1f",((float)conv_time/1000));
00159             pc.printf("mS\n");
00160             break;
00161 
00162         case 4: // Read Cell Voltage Registers
00163             wakeup_sleep(TOTAL_IC);
00164             error = LTC6811_rdcv(0, TOTAL_IC,bms_ic); // Set to read back all cell voltage registers
00165             check_error(error);
00166             print_cells(DATALOG_DISABLED);
00167             break;
00168 
00169         case 5: // Start GPIO ADC Measurement
00170             wakeup_sleep(TOTAL_IC);
00171             LTC6811_adax(ADC_CONVERSION_MODE , AUX_CH_TO_CONVERT);
00172             LTC6811_pollAdc();
00173             pc.printf("aux conversion completed\n");
00174             pc.printf("\n");
00175             break;
00176 
00177         case 6: // Read AUX Voltage Registers
00178             wakeup_sleep(TOTAL_IC);
00179             error = LTC6811_rdaux(0,TOTAL_IC,bms_ic); // Set to read back all aux registers
00180             check_error(error);
00181             print_aux(DATALOG_DISABLED);
00182             break;
00183 
00184         case 7: // Start Status ADC Measurement
00185             wakeup_sleep(TOTAL_IC);
00186             LTC6811_adstat(ADC_CONVERSION_MODE, STAT_CH_TO_CONVERT);
00187             LTC6811_pollAdc();
00188             pc.printf("stat conversion completed\n");
00189             pc.printf("\n");
00190             break;
00191 
00192         case 8: // Read Status registers
00193             wakeup_sleep(TOTAL_IC);
00194             error = LTC6811_rdstat(0,TOTAL_IC,bms_ic); // Set to read back all aux registers
00195             check_error(error);
00196             print_stat();
00197             break;
00198 
00199         case 9: // Loop Measurements
00200             pc.printf("transmit 'm' to quit\n");
00201             wakeup_sleep(TOTAL_IC);
00202             LTC6811_wrcfg(TOTAL_IC,bms_ic);
00203             while (input != 'm') {
00204                 //if (pc.readable()) {
00205                     input = read_char();
00206                 //}
00207 
00208                 measurement_loop(DATALOG_DISABLED);
00209 
00210                 wait_ms(MEASUREMENT_LOOP_TIME);
00211             }
00212             //print_menu();
00213             break;
00214 
00215         case 10: // Run open wire self test
00216             print_pec();
00217 
00218             break;
00219 
00220         case 11: // Read in raw configuration data
00221             LTC6811_reset_crc_count(TOTAL_IC,bms_ic);
00222             break;
00223 
00224         case 12:  // Run the ADC/Memory Self Test
00225             wakeup_sleep(TOTAL_IC);
00226             error = LTC6811_run_cell_adc_st(CELL,ADC_CONVERSION_MODE,bms_ic);
00227             pc.printf("%d", error);
00228             pc.printf(" : errors detected in Digital Filter and CELL Memory\n");
00229 
00230             wakeup_sleep(TOTAL_IC);
00231             error = LTC6811_run_cell_adc_st(AUX,ADC_CONVERSION_MODE, bms_ic);
00232             pc.printf("%d",error);
00233             pc.printf(" : errors detected in Digital Filter and AUX Memory\n");
00234 
00235             wakeup_sleep(TOTAL_IC);
00236             error = LTC6811_run_cell_adc_st(STAT,ADC_CONVERSION_MODE, bms_ic);
00237             pc.printf("%d",error);
00238             pc.printf(" : errors detected in Digital Filter and STAT Memory\n");
00239             print_menu();
00240             break;
00241 
00242         case 13: // Enable a discharge transistor
00243             pc.printf("Please enter the Spin number\n");
00244             readIC = (int8_t)read_int();
00245             LTC6811_set_discharge(readIC,TOTAL_IC,bms_ic);
00246             wakeup_sleep(TOTAL_IC);
00247             LTC6811_wrcfg(TOTAL_IC,bms_ic);
00248             print_config();
00249             break;
00250 
00251         case 14: // Clear all discharge transistors
00252             clear_discharge(TOTAL_IC,bms_ic);
00253             wakeup_sleep(TOTAL_IC);
00254             LTC6811_wrcfg(TOTAL_IC,bms_ic);
00255             print_config();
00256             break;
00257 
00258         case 15: // Clear all ADC measurement registers
00259             wakeup_sleep(TOTAL_IC);
00260             LTC6811_clrcell();
00261             LTC6811_clraux();
00262             LTC6811_clrstat();
00263             pc.printf("All Registers Cleared\n");
00264             break;
00265 
00266         case 16: // Run the Mux Decoder Self Test
00267             wakeup_sleep(TOTAL_IC);
00268             LTC6811_diagn();
00269             wait_ms(5);
00270             error = LTC6811_rdstat(0,TOTAL_IC,bms_ic); // Set to read back all aux registers
00271             check_error(error);
00272             error = 0;
00273             for (int ic = 0;
00274                     ic<TOTAL_IC;
00275                     ic++) {
00276                 if (bms_ic[ic].stat.mux_fail[0] != 0) error++;
00277             }
00278             if (error==0) pc.printf("Mux Test: PASS\n");
00279             else pc.printf("Mux Test: FAIL\n");
00280 
00281             break;
00282 
00283         case 17: // Run ADC Overlap self test
00284             wakeup_sleep(TOTAL_IC);
00285             error = (int8_t)LTC6811_run_adc_overlap(TOTAL_IC,bms_ic);
00286             if (error==0) pc.printf("Overlap Test: PASS\n");
00287             else pc.printf("Overlap Test: FAIL\n");
00288             break;
00289 
00290         case 18: // Run ADC Redundancy self test
00291             wakeup_sleep(TOTAL_IC);
00292             error = LTC6811_run_adc_redundancy_st(ADC_CONVERSION_MODE,AUX,TOTAL_IC, bms_ic);
00293             pc.printf("%d",error);
00294             pc.printf(" : errors detected in AUX Measurement\n");
00295 
00296             wakeup_sleep(TOTAL_IC);
00297             error = LTC6811_run_adc_redundancy_st(ADC_CONVERSION_MODE,STAT,TOTAL_IC, bms_ic);
00298             pc.printf("%d",error);
00299             pc.printf(" : errors detected in STAT Measurement\n");
00300             break;
00301 
00302         case 19:
00303             LTC6811_run_openwire(TOTAL_IC, bms_ic);
00304             print_open();
00305             break;
00306 
00307         case 20: //Datalog print option Loop Measurements
00308             pc.printf("transmit 'm' to quit\n");
00309             wakeup_sleep(TOTAL_IC);
00310             LTC6811_wrcfg(TOTAL_IC,bms_ic);
00311             while (input != 'm') {
00312                 //if (pc.readable()) {
00313                     input = read_char();
00314                 //}
00315 
00316                 measurement_loop(DATALOG_ENABLED);
00317 
00318                 wait_ms(MEASUREMENT_LOOP_TIME);
00319             }
00320             print_menu();
00321             break;
00322 
00323         case 'm': //prints menu
00324             print_menu();
00325             break;
00326 
00327         default:
00328             pc.printf("Incorrect Option\n");
00329             break;
00330     }
00331 }
00332 
00333 void measurement_loop(uint8_t datalog_en)
00334 {
00335     int8_t error = 0;
00336     if (WRITE_CONFIG == ENABLED) {
00337         wakeup_sleep(TOTAL_IC);
00338         LTC6811_wrcfg(TOTAL_IC,bms_ic);
00339         print_config();
00340     }
00341 
00342     if (READ_CONFIG == ENABLED) {
00343         wakeup_sleep(TOTAL_IC);
00344         error = LTC6811_rdcfg(TOTAL_IC,bms_ic);
00345         check_error(error);
00346         print_rxconfig();
00347     }
00348 
00349     if (MEASURE_CELL == ENABLED) {
00350         wakeup_idle(TOTAL_IC);
00351         LTC6811_adcv(ADC_CONVERSION_MODE,ADC_DCP,CELL_CH_TO_CONVERT);
00352         LTC6811_pollAdc();
00353         wakeup_idle(TOTAL_IC);
00354         error = LTC6811_rdcv(0, TOTAL_IC,bms_ic);
00355         check_error(error);
00356         print_cells(datalog_en);
00357 
00358     }
00359 
00360     if (MEASURE_AUX == ENABLED) {
00361         wakeup_idle(TOTAL_IC);
00362         LTC6811_adax(ADC_CONVERSION_MODE , AUX_CH_ALL);
00363         LTC6811_pollAdc();
00364         wakeup_idle(TOTAL_IC);
00365         error = LTC6811_rdaux(0,TOTAL_IC,bms_ic); // Set to read back all aux registers
00366         check_error(error);
00367         print_aux(datalog_en);
00368     }
00369 
00370     if (MEASURE_STAT == ENABLED) {
00371         wakeup_idle(TOTAL_IC);
00372         LTC6811_adstat(ADC_CONVERSION_MODE, STAT_CH_ALL);
00373         LTC6811_pollAdc();
00374         wakeup_idle(TOTAL_IC);
00375         error = LTC6811_rdstat(0,TOTAL_IC,bms_ic); // Set to read back all aux registers
00376         check_error(error);
00377         print_stat();
00378     }
00379 
00380     if (PRINT_PEC == ENABLED) {
00381         print_pec();
00382     }
00383 
00384 }
00385 
00386 
00387 /*!*********************************
00388   \brief Prints the main menu
00389 ***********************************/
00390 void print_menu()
00391 {
00392     pc.printf("Please enter LTC6811 Command\n");
00393     pc.printf("Write Configuration: 1            | Reset PEC Counter: 11\n");
00394     pc.printf("Read Configuration: 2             | Run ADC Self Test: 12\n");
00395     pc.printf("Start Cell Voltage Conversion: 3  | Set Discharge: 13\n");
00396     pc.printf("Read Cell Voltages: 4             | Clear Discharge: 14\n");
00397     pc.printf("Start Aux Voltage Conversion: 5   | Clear Registers: 15\n");
00398     pc.printf("Read Aux Voltages: 6              | Run Mux Self Test: 16\n");
00399     pc.printf("Start Stat Voltage Conversion: 7  | Run ADC overlap Test: 17\n");
00400     pc.printf("Read Stat Voltages: 8             | Run Digital Redundancy Test: 18\n");
00401     pc.printf("loop Measurements: 9              | Run Open Wire Test: 19\n");
00402     pc.printf("Read PEC Errors: 10               |  Loop measurements with datalog output: 20\n");
00403     pc.printf("\n");
00404     pc.printf("Please enter command:\n");
00405     pc.printf("\n");
00406 }
00407 
00408 /*!************************************************************
00409   \brief Prints cell voltage codes to the serial port
00410  *************************************************************/
00411 void print_cells(uint8_t datalog_en)
00412 {
00413     for (int current_ic = 0 ; current_ic < TOTAL_IC; current_ic++) {
00414 
00415         if (datalog_en == 0) {
00416             pc.printf("IC%d, ", current_ic+1);
00417             for (int i=0; i<bms_ic[0].ic_reg.cell_channels; i++) {
00418                 pc.printf("C%d:", i+1);
00419                 pc.printf("%.4f, ", bms_ic[current_ic].cells.c_codes[i]*0.0001);
00420             }
00421             pc.printf("\n");
00422         } else {
00423             pc.printf("Cells, ");
00424             for (int i=0; i<bms_ic[0].ic_reg.cell_channels; i++) {
00425                 pc.printf("%.4f, ",bms_ic[current_ic].cells.c_codes[i]*0.0001);
00426             }
00427         }
00428 
00429     }
00430     pc.printf("\n");
00431 }
00432 
00433 /*!****************************************************************************
00434   \brief Prints Open wire test results to the serial port
00435  *****************************************************************************/
00436 void print_open()
00437 {
00438     for (int current_ic =0 ; current_ic < TOTAL_IC; current_ic++) {
00439         if (bms_ic[current_ic].system_open_wire == 0) {
00440             pc.printf("No Opens Detected on IC%d\n", current_ic+1);
00441         } else {
00442             for (int cell=0; cell<bms_ic[0].ic_reg.cell_channels+1; cell++) {
00443                 if ((bms_ic[current_ic].system_open_wire &(1<<cell))>0) {
00444                     pc.printf("There is an open wire on IC%d Channel: %d\n", current_ic + 1, cell);
00445                 }
00446             }
00447         }
00448     }
00449 }
00450 
00451 /*!****************************************************************************
00452   \brief Prints GPIO voltage codes and Vref2 voltage code onto the serial port
00453  *****************************************************************************/
00454 void print_aux(uint8_t datalog_en)
00455 {
00456 
00457     for (int current_ic =0 ; current_ic < TOTAL_IC; current_ic++) {
00458         if (datalog_en == 0) {
00459             pc.printf(" IC%d", current_ic+1);
00460             for (int i=0; i < 5; i++) {
00461                 pc.printf(" GPIO-%d:%.4f,", i+1, bms_ic[current_ic].aux.a_codes[i]*0.0001);
00462             }
00463             pc.printf("Vref2:%.4f\n", bms_ic[current_ic].aux.a_codes[5]*0.0001);
00464         } else {
00465             pc.printf("AUX, ");
00466             for (int i=0; i < 6; i++) {
00467                 pc.printf("%.4f,", bms_ic[current_ic].aux.a_codes[i]*0.0001);
00468             }
00469         }
00470     }
00471     pc.printf("\n");
00472 }
00473 
00474 /*!****************************************************************************
00475   \brief Prints Status voltage codes and Vref2 voltage code onto the serial port
00476  *****************************************************************************/
00477 void print_stat()
00478 {
00479 
00480     for (int current_ic =0 ; current_ic < TOTAL_IC; current_ic++) {
00481         pc.printf("IC%d", current_ic+1);
00482         pc.printf(" SOC:%.4f,", bms_ic[current_ic].stat.stat_codes[0]*0.0001*20);
00483         pc.printf(" Itemp:%.4f,", bms_ic[current_ic].stat.stat_codes[1]*0.0001);
00484         pc.printf(" VregA:%.4f,", bms_ic[current_ic].stat.stat_codes[2]*0.0001);
00485         pc.printf(" VregD:%.4f\n", bms_ic[current_ic].stat.stat_codes[3]*0.0001);
00486     }
00487 
00488     pc.printf("\n");
00489 }
00490 
00491 /*!******************************************************************************
00492  \brief Prints the configuration data that is going to be written to the LTC6811
00493  to the serial port.
00494  ********************************************************************************/
00495 void print_config()
00496 {
00497     int cfg_pec;
00498 
00499     pc.printf("Written Configuration: \n");
00500     for (int current_ic = 0; current_ic<TOTAL_IC; current_ic++) {
00501         pc.printf(" IC ");
00502         pc.printf("%d", current_ic+1);
00503         pc.printf(": ");
00504         pc.printf("0x");
00505         serial_print_hex(bms_ic[current_ic].config.tx_data[0]);
00506         pc.printf(", 0x");
00507         serial_print_hex(bms_ic[current_ic].config.tx_data[1]);
00508         pc.printf(", 0x");
00509         serial_print_hex(bms_ic[current_ic].config.tx_data[2]);
00510         pc.printf(", 0x");
00511         serial_print_hex(bms_ic[current_ic].config.tx_data[3]);
00512         pc.printf(", 0x");
00513         serial_print_hex(bms_ic[current_ic].config.tx_data[4]);
00514         pc.printf(", 0x");
00515         serial_print_hex(bms_ic[current_ic].config.tx_data[5]);
00516         pc.printf(", Calculated PEC: 0x");
00517         cfg_pec = pec15_calc(6,&bms_ic[current_ic].config.tx_data[0]);
00518         serial_print_hex((uint8_t)(cfg_pec>>8));
00519         pc.printf(", 0x");
00520         serial_print_hex((uint8_t)(cfg_pec));
00521         pc.printf("\n");
00522     }
00523     pc.printf("\n");
00524 }
00525 
00526 /*!*****************************************************************
00527  \brief Prints the configuration data that was read back from the
00528  LTC6811 to the serial port.
00529  *******************************************************************/
00530 void print_rxconfig()
00531 {
00532     pc.printf("Received Configuration ");
00533     for (int current_ic=0; current_ic<TOTAL_IC; current_ic++) {
00534         pc.printf(" IC ");
00535         pc.printf("%d", current_ic+1);
00536         pc.printf(": 0x");
00537         serial_print_hex(bms_ic[current_ic].config.rx_data[0]);
00538         pc.printf(", 0x");
00539         serial_print_hex(bms_ic[current_ic].config.rx_data[1]);
00540         pc.printf(", 0x");
00541         serial_print_hex(bms_ic[current_ic].config.rx_data[2]);
00542         pc.printf(", 0x");
00543         serial_print_hex(bms_ic[current_ic].config.rx_data[3]);
00544         pc.printf(", 0x");
00545         serial_print_hex(bms_ic[current_ic].config.rx_data[4]);
00546         pc.printf(", 0x");
00547         serial_print_hex(bms_ic[current_ic].config.rx_data[5]);
00548         pc.printf(", Received PEC: 0x");
00549         serial_print_hex(bms_ic[current_ic].config.rx_data[6]);
00550         pc.printf(", 0x");
00551         serial_print_hex(bms_ic[current_ic].config.rx_data[7]);
00552         pc.printf("\n");
00553     }
00554     pc.printf("\n");
00555 }
00556 
00557 void print_pec()
00558 {
00559     for (int current_ic=0; current_ic<TOTAL_IC; current_ic++) {
00560         pc.printf("\n%d", bms_ic[current_ic].crc_count.pec_count);
00561         pc.printf(" : PEC Errors Detected on IC");
00562         pc.printf("%d\n", current_ic+1);
00563     }
00564 }
00565 
00566 
00567 void serial_print_hex(uint8_t data)
00568 {
00569     if (data < 16) {
00570         pc.printf("0x0%X", data);
00571     } else
00572         pc.printf("0x%X", data);
00573 }
00574 
00575 //Function to check error flag and print PEC error message
00576 void check_error(int error)
00577 {
00578     if (error == -1) {
00579         pc.printf("A PEC error was detected in the received data");
00580     }
00581 }
00582 
00583 
00584 // hex conversion constants
00585 char hex_digits[16]= {
00586     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
00587 };
00588 
00589 // global variables
00590 
00591 char hex_to_byte_buffer[5]= {
00592     '0', 'x', '0', '0', '\0'
00593 };               // buffer for ASCII hex to byte conversion
00594 char byte_to_hex_buffer[3]= {
00595     '\0','\0','\0'
00596 };
00597 
00598 // Read data from the serial interface into the ui_buffer
00599 uint8_t read_data()
00600 {
00601     uint8_t index = 0; //index to hold current location in ui_buffer
00602     int c; // single character used to store incoming keystrokes
00603     //pc.printf("check 1\n");
00604     while (index < UI_BUFFER_SIZE-1) {
00605         //pc.printf("check 2\n");
00606         c = pc.getc(); //read one character
00607         //return c;
00608         //pc.printf("check 3\n");
00609         
00610         if (((char) c == '\r') || ((char) c == '\n')) break; // if carriage return or linefeed, stop and return data
00611         if ( ((char) c == '\x7F') || ((char) c == '\x08') ) { // remove previous character (decrement index) if Backspace/Delete key pressed      index--;
00612             if (index > 0) index--;
00613         } else if (c >= 0) {
00614             ui_buffer[index++]=(char) c; // put character into ui_buffer
00615         }
00616         //pc.printf("check 4\n");
00617         
00618     }
00619     ui_buffer[index]='\0';  // terminate string with NULL
00620 
00621     if ((char) c == '\r') {  // if the "last" character was a carriage return, also clear linefeed if it is next character
00622         wait_ms(1);
00623         //pc.printf("check 5\n");
00624         
00625         if (pc.readable()==1) {
00626             //pc.printf("check 6\n");
00627             pc.getc(); // if linefeed appears, read it and throw it away
00628         }
00629         //pc.printf("check 7\n");
00630         
00631     }
00632     //pc.printf("check 8\n");
00633         
00634     return index; // return number of characters, not including null terminator
00635 }
00636 
00637 // Read a float value from the serial interface
00638 float read_float()
00639 {
00640     float data;
00641     read_data();
00642     data = atof(ui_buffer);
00643     return(data);
00644 }
00645 
00646 // Read an integer from the serial interface.
00647 // The routine can recognize Hex, Decimal, Octal, or Binary
00648 // Example:
00649 // Hex:     0x11 (0x prefix)
00650 // Decimal: 17
00651 // Octal:   021 (leading zero prefix)
00652 // Binary:  B10001 (leading B prefix)
00653 int32_t read_int()
00654 {
00655     int32_t data;
00656     read_data();
00657     if (ui_buffer[0] == 'm')
00658         return('m');
00659     if ((ui_buffer[0] == 'B') || (ui_buffer[0] == 'b')) {
00660         data = strtol(ui_buffer+1, NULL, 2);
00661     } else
00662         data = strtol(ui_buffer, NULL, 0);
00663     return(data);
00664 }
00665 
00666 // Read a string from the serial interface.  Returns a pointer to the ui_buffer.
00667 char *read_string()
00668 {
00669     read_data();
00670     return(ui_buffer);
00671 }
00672 
00673 // Read a character from the serial interface
00674 int8_t read_char()
00675 {
00676     read_data();
00677     return(ui_buffer[0]);
00678 }