Has base BMU code but sends dummy temperature and voltage readings to test CAN

Dependencies:   CUER_CAN DS1820 LTC2943 LTC6804 mbed

Fork of BMS_BMUCore_Max by CUER

Files at this revision

API Documentation at this revision

Comitter:
maxv008
Date:
Sun Jul 02 01:45:39 2017 +0000
Parent:
13:7b42af989cd1
Child:
15:e901aff1f5b3
Commit message:
Added a proper unique identification to the temperature CAN. Implemented an interrupt based CAN read setup, currently configured with Dummy data and test code that will be cleaned up in a future commit

Changed in this revision

CANParserBMU.cpp Show annotated file Show diff for this revision Revisions of this file
CANParserBMU.h Show annotated file Show diff for this revision Revisions of this file
Data_Types_BMU.h Show annotated file Show diff for this revision Revisions of this file
LTC6804.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/CANParserBMU.cpp	Wed Jun 28 16:56:33 2017 +0000
+++ b/CANParserBMU.cpp	Sun Jul 02 01:45:39 2017 +0000
@@ -9,21 +9,29 @@
 /**
 * This function is rewritten to give readings for individual probes rather than
 * for specific CMU. As a consequence, 0x800 onwards is being used for these probes,
-* as everything above about 0x700 is unused by the Tritium standard. Additionally,
-* instead of using uint16, floats will be used since only one temperature reading
-* is needed per message, allowing 32 bits per reading, and float is the natural
-* type obtained by the sensor.
+* as everything above about 0x700 is unused by the Tritium standard. The ID value
+* for the probe is based on the ROM field of DS1820, entries 1-6 being the unique
+* serial value.
 */
-CANMessage createTemperatureTelemetry(uint8_t offset, uint32_t ProbeID, float Temperature)
+CANMessage createTemperatureTelemetry(uint8_t offset, char ProbeROM[8], float Temperature)
 {
     CANMessage msg;
     msg.len = 8;
     msg.id = TEMPERATURE_BASE_ID + offset; // for temp it is 0x800 onwards
     CAN_Data data;
 
-    data.setLower_uLong(ProbeID);
-    data.setUpperFloat(Temperature);
+    //data.setLower_uLong(ProbeID);
+    //data.setUpperFloat(Temperature);
 
+    for(int i = 1; i <= 6; i++) //ID portion of ROM array
+    {
+        data.set_u8(i - 1, ProbeROM[i]);
+    }
+    //Conversion of float to a short, requires multiplying by 100 to not lose precision
+    float temp100 = Temperature * 100;
+    short shortTemp = (short) temp100;
+    data.set_16(3, shortTemp);//There seems to be an error in the function definition for set_16, (ushort instead of short)
+    
     for (int i = 0; i<8; i++) {
         msg.data[i] = data.get_u8(i);
     }
@@ -33,6 +41,7 @@
 /**
 * Takes a CANMessage with precondition that it stores temperature of an individual
 * probe and returns an individual_temperature object containing ID and reading.
+* The ID is stores in ROM array entry 1-6, other entries may be invalid.
 */
 individual_temperature decodeTemperatureTelemetry(CANMessage msg)
 {
@@ -40,8 +49,13 @@
     CAN_Data decode;
     
     decode.importCANData(msg);
-    probe_reading.measurement = decode.getUpperFloat();
-    probe_reading.ID = decode.getLower_uLong();
+    short shortTemp = decode.get_16(3);
+    probe_reading.measurement = ((float)shortTemp) / 100;
+    
+    for(int i = 1; i <=6; i++)
+    {
+        probe_reading.ROMID[i] = decode.get_u8(i-1);    
+    }
     
     return probe_reading;
 }
--- a/CANParserBMU.h	Wed Jun 28 16:56:33 2017 +0000
+++ b/CANParserBMU.h	Sun Jul 02 01:45:39 2017 +0000
@@ -13,7 +13,7 @@
 #define BATTERY_PACK_STATUS_ID 0xFA
 
 //@TODO add some comments
-CANMessage createTemperatureTelemetry(uint8_t offset, uint32_t ProbeID, float Temperature);
+CANMessage createTemperatureTelemetry(uint8_t offset, char * ROMID, float Temperature);
 
 individual_temperature decodeTemperatureTelemetry(CANMessage msg);
 
--- a/Data_Types_BMU.h	Wed Jun 28 16:56:33 2017 +0000
+++ b/Data_Types_BMU.h	Sun Jul 02 01:45:39 2017 +0000
@@ -38,12 +38,16 @@
 #define MIN_CELL_VOLTAGE 1
 #define MAX_CELL_TEMPERATURE 1
 
+//CAN Buffer
+#define CAN_BUFFER_SIZE 255 //Setting this to be quite large, should be equal to max # of ids expected to recieve
+
 // Delay
 #define LOOP_DELAY_S 0.1 // TODO is this delay the correct length?
 
 struct individual_temperature{
     // Structure that will store a temperature value and also an ID 
-    uint8_t ID; // CMU number
+    char ROMID[8]; //ROM array for temperature sensor, subset of it is useful as ID
+    //ROMID 1-6 are the useful values for this case, ignore the rest
     float measurement;
 };
 
--- a/LTC6804.lib	Wed Jun 28 16:56:33 2017 +0000
+++ b/LTC6804.lib	Sun Jul 02 01:45:39 2017 +0000
@@ -1,1 +1,1 @@
-http://developer.mbed.org/teams/CUER/code/LTC6804/#f664ee0ebb1a
+http://developer.mbed.org/teams/CUER/code/LTC6804/#1e49052d2fd1
--- a/main.cpp	Wed Jun 28 16:56:33 2017 +0000
+++ b/main.cpp	Sun Jul 02 01:45:39 2017 +0000
@@ -10,7 +10,6 @@
 #include "SPI_I2C_Parser.h"
 
 
-
 using namespace CAN_IDs;
 
 // Function definitions
@@ -18,20 +17,28 @@
 void read_temperature_sensors(BMU_data &measurements);
 void update_SOC();
 void init();
+void interruptHandler();
+void CANDataSentCallback();
 void write_SOC_EEPROM(BMU_data &measurements,uint16_t start_address);
 uint16_t read_EEPROM_startup(BMU_data &measurements);
 uint32_t check_measurements(BMU_data &measurements);
 void take_measurements(BMU_data &measurements);
+void test_read_CAN_buffer();
 bool test_read_voltage_CAN(uint16_t readings[], int can_ids[]);
 void test_CAN_send();
 void test_CAN_read();
 
 CAN can(CAN_READ_PIN, CAN_WRITE_PIN); //Create a CAN object to handle CAN comms
+CANMessage buffer[CAN_BUFFER_SIZE]; //CAN receive buffer
+bool safe_to_write[CAN_BUFFER_SIZE]; //Semaphore bit indicating that it's safe to write to the software buffer
+bool CAN_data_sent = false;
+
 uint16_t eeprom_start_address; //the initial address where we store/read SoC values
 
 Timeout loop_delay;
 bool delay_finished = false;
 
+
 void loop_delay_callback(void)
 {
     delay_finished = true;
@@ -46,7 +53,7 @@
     int can_ids[9];
     
     
-    while(true)
+    /**while(true)
     {
         for (int i = 0; i < 9; ++i) {
             while(!test_read_voltage_CAN(&volt_readings[(i*4)], &can_ids[i]));
@@ -59,7 +66,7 @@
         }
         printf("\r\n");
         
-    }
+    } */
     init();
     
     
@@ -90,7 +97,10 @@
         */
 
         // CAN bus
-        transmit_data(measurements,status);
+        CAN_data_sent = false;//Currently does nothing, adding this line in more places then using
+        //while(!CAN_data_sent); in order to ensure sending completes
+        //transmit_data(measurements,status);
+        test_read_CAN_buffer();
         
         /*
         // Conserve power - enter a low powered mode
@@ -132,11 +142,17 @@
     }
     
     //Transmitting all of the individual probes:
-    for(int i = 0; i < NO_TEMPERATURE_SENSORS; i++)
+    //for(uint8_t i = 0; i < devices_found; i++) REPLACED BY DUMMY LOOP
+    for(uint8_t i = 0; i < 10; i++)
     {
-        individual_temperature reading = measurements.temperature_measurements[i];
-        msg = createTemperatureTelemetry(i, reading.ID, reading.measurement);
-        can.write(msg);
+        individual_temperature tempreading = measurements.temperature_measurements[i];
+        msg = createTemperatureTelemetry(i, &tempreading.ROMID[0], tempreading.measurement);
+        if(can.write(msg))
+            printf("Message sent succesfully \r\n");
+        else
+            printf("message failed to send \r\n");
+        individual_temperature testOut = decodeTemperatureTelemetry(msg);
+        printf("ID[6] is %d and temp is %f \r\n",testOut.ROMID[6],testOut.measurement);
         wait(0.1);
     }
 
@@ -230,12 +246,13 @@
     isotherm_12V_pin = 0;
     min_temperature = probe[0]->temperature('C');
     max_temperature = min_temperature; // Initially set the max and min temperature equal
-    for (int i=0; i<devices_found; i++) {
-        //The ID seems to be set arbitrarily here, might make sense to change
-        //to a constant ID for each sensor to more easily recover the reading.
-        measurements.temperature_measurements[i].ID = i;
+    /**for (int i=0; i<devices_found; i++) {
+        for(int j = 0; j < 7; j++)
+            measurements.temperature_measurements[i].ROMID[j] = probe[i]->ROM[j];
         measurements.temperature_measurements[i].measurement = probe[i] ->temperature('C');
-
+        
+        
+        
         if(measurements.temperature_measurements[i].measurement > max_temperature) {
             max_temperature = measurements.temperature_measurements[i].measurement;
         } else if (measurements.temperature_measurements[i].measurement < min_temperature) {
@@ -243,7 +260,22 @@
         }
         
         printf("Device %d temperature is %3.3f degrees Celcius.\r\n",i+1 ,probe[i]->temperature('C'));
+    }ABOVE BLOCK REPLACED BY DUMMY MEASUREMENTS */
+    //Dummy data goes here
+    for(int i = 0; i < 10; i++)
+    {
+        for(int j = 0; j < 7; j++)
+            measurements.temperature_measurements[i].ROMID[j] = j;
+        
+        measurements.temperature_measurements[i].measurement = 22.7 + (float) i;
+        
+        if(measurements.temperature_measurements[i].measurement > max_temperature) {
+            max_temperature = measurements.temperature_measurements[i].measurement;
+        } else if (measurements.temperature_measurements[i].measurement < min_temperature) {
+            min_temperature = measurements.temperature_measurements[i].measurement;
+        }
     }
+    
     //There is also a CMU # component of this struct, currently unfilled, perhaps not needed at all.
     measurements.max_cell_temp.temperature = max_temperature;
     measurements.min_cell_temp.temperature = min_temperature;
@@ -282,14 +314,18 @@
     //TODO Use LTC6804_acquireVoltage to fill this array, and then properly format
     //it to be sent over CAN
     
-    LTC6804_acquireVoltage(cellvoltages);
-    
+    //LTC6804_acquireVoltage(cellvoltages); REPLACED BY DUMMY DATA
+    for(int i = 0; i < NO_CMUS; i++)
+    {
+        for(int j = 0; j < 12; j++)
+            cellvoltages[i][j] = i*j; //Just to have some data variation   
+    }
     for(int i=0; i<NO_CMUS; i++){
        for(int j=0; j<12; j++){
-             measurements.cell_voltages[i].voltages[j] =  cellvoltages[i][j] / 10;
-             printf("Cellvoltage[%d][%d] = %d \r\n",i,j,cellvoltages[i][j] /10);   
+             measurements.cell_voltages[i].voltages[j] =  cellvoltages[i][j]; // / 10; REMOVED FOR DUMMY DATA
+             //printf("Cellvoltage[%d][%d] = %d \r\n",i,j,cellvoltages[i][j]); // SAME AS ABOVE /10);   
        }   
-    }
+    } 
     
     //Add code to take all temperature measurements and add it to measurements struct.
     read_temperature_sensors(measurements);
@@ -304,8 +340,68 @@
 {
     temperature_init(); // Initialise the temperature sensors
     LTC2943_initialise(); //Initialises the fixed parameters of the LTC2943
+    
+    for(int i=0; i<CAN_BUFFER_SIZE; i++) 
+    {
+        buffer[i].id = BLANK_ID;
+        //("%d",buffer[i].id);
+        safe_to_write[i]= true;
+    }
+    
+    //Initialise CAN stuff, attach CAN interrupt handlers
+    can.frequency(CAN_BIT_RATE); //set transmission rate to agreed bit rate (ELEC-006)
+    can.reset(); // (FUNC-018)
+    can.attach(&interruptHandler, CAN::RxIrq); //receive interrupt handler
+    can.attach(&CANDataSentCallback, CAN::TxIrq); //send interrupt handler
+
+}
+
+void CANDataSentCallback(void) {
+    CAN_data_sent = true;
+    printf("Some CAN was sent \r\n");
 }
 
+void interruptHandler()
+{
+    CANMessage msg;
+    if(can.read(msg))
+        printf("interrupt reached with id %d \r\n",msg.id);
+    else
+        printf("reading failed \r\n");
+    for(int i=0; i<CAN_BUFFER_SIZE; i++) {
+        if((buffer[i].id == msg.id || buffer[i].id==BLANK_ID) && safe_to_write[i]) {
+           //("id %d added to buffer \r\n", msg.id);
+           buffer[i] = msg;
+           //return required so that only first blank buffer entry is converted to incoming message ID each time new message ID is encountered
+           return;
+        }
+    }
+}
+
+void test_read_CAN_buffer()
+{
+    //Import the data from the buffer into a non-volatile, more usable format
+    CAN_Data can_data[CAN_BUFFER_SIZE]; //container for all of the raw data
+    int received_CAN_IDs[CAN_BUFFER_SIZE]; //needed to keep track of which IDs we've received so far
+    for (int i = 0; i<CAN_BUFFER_SIZE; ++i) 
+    {
+        safe_to_write[i] = false;
+        can_data[i].importCANData(buffer[i]);
+        received_CAN_IDs[i] = buffer[i].id;
+        safe_to_write[i] = true;
+    }
+    
+    for(int i = 0; i < CAN_BUFFER_SIZE; i++)
+    {
+        individual_temperature testpoint;
+        if(!(buffer[i].id == BLANK_ID) && buffer[i].id < 10)
+        {
+            testpoint = decodeTemperatureTelemetry(buffer[i]);
+            printf("Temperature is %f and ID[5] is %d \r\n", testpoint.measurement, testpoint.ROMID[5]);      
+        }else if(buffer[i].id == 1538)
+            printf("id 1538 was recieved\r\n");    
+    }
+}
 bool test_read_voltage_CAN(uint16_t readings[], int can_ids[])
 {
     CANMessage msg;