A public repository for BMS algorithms for a NUCLEO BOARD.

Dependencies:   mbed

Hi Everyone!

Welcome to this repository from Howey's Research Group at the University of Oxford.

The code published here incorporates BMS algorithms for diagnosis functions such as SOC, SOH and Power estimation on a Kokam 53Ah Li-ion battery. This code was designed to work with a NUCLEO F401-RE board and to be tested with a dSPACE HIL Simulator. A short guide on how the set up works is available at https://bitbucket.org/ff95/bms .

The code is made up of three key parts. "Headers" and "Source" folders and the "main.cpp" file. As the code was generated by converting a Simulink model ( available on the BitBucket page), the headers and source code files generated by the conversion are in the corresponding "Headers" and "Source" folders. The "main.cpp" file sets up the ADC, the USB data transmission and starts the estimation (once a character "y" has been received by the computer it is connected to). It also transmits the data from the estimation via USB. Explanation on how to set up the communication with the board is available at BitBucket webpage, from where a MATLAB file can be downloaded which allows real time communication.

For any questions you can contact the author at federicomariaferrari@gmail.com .

The Simulink and Matlab files, together with a short guide, are all available at: https://bitbucket.org/ff95/bms.

Thanks for trying this out!

Federico

Committer:
fmferrari
Date:
Wed Dec 07 20:27:27 2016 +0000
Revision:
5:dad47e5b9586
Parent:
4:dc0c58eedabb
Child:
6:cb71171a7108
Not working try 1;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
fmferrari 0:1e567a5a99c3 1 /**
fmferrari 0:1e567a5a99c3 2 * @author Damien Frost
fmferrari 0:1e567a5a99c3 3 *
fmferrari 0:1e567a5a99c3 4 * @section LICENSE
fmferrari 0:1e567a5a99c3 5 *
fmferrari 0:1e567a5a99c3 6 * Copyright (c) 2016 Damien Frost
fmferrari 0:1e567a5a99c3 7 *
fmferrari 0:1e567a5a99c3 8 * Permission is hereby granted, free of charge, to any person obtaining a copy
fmferrari 0:1e567a5a99c3 9 * of this software and associated documentation files (the "Software"), to deal
fmferrari 0:1e567a5a99c3 10 * in the Software without restriction, including without limitation the rights
fmferrari 0:1e567a5a99c3 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
fmferrari 0:1e567a5a99c3 12 * copies of the Software, and to permit persons to whom the Software is
fmferrari 0:1e567a5a99c3 13 * furnished to do so, subject to the following conditions:
fmferrari 0:1e567a5a99c3 14 *
fmferrari 0:1e567a5a99c3 15 * The above copyright notice and this permission notice shall be included in
fmferrari 0:1e567a5a99c3 16 * all copies or substantial portions of the Software.
fmferrari 0:1e567a5a99c3 17 *
fmferrari 0:1e567a5a99c3 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
fmferrari 0:1e567a5a99c3 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
fmferrari 0:1e567a5a99c3 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
fmferrari 0:1e567a5a99c3 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
fmferrari 0:1e567a5a99c3 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
fmferrari 0:1e567a5a99c3 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
fmferrari 0:1e567a5a99c3 24 * THE SOFTWARE.
fmferrari 0:1e567a5a99c3 25 *
fmferrari 0:1e567a5a99c3 26 * @file "main.cpp"
fmferrari 0:1e567a5a99c3 27 *
fmferrari 0:1e567a5a99c3 28 * @section DESCRIPTION
fmferrari 0:1e567a5a99c3 29 * Simple Internet of Things main program. The device sends data every 3
fmferrari 0:1e567a5a99c3 30 * seconds, and can receive data from a server.
fmferrari 0:1e567a5a99c3 31 *
fmferrari 0:1e567a5a99c3 32 */
fmferrari 0:1e567a5a99c3 33
fmferrari 0:1e567a5a99c3 34 #include "mbed.h"
fmferrari 0:1e567a5a99c3 35 #include "globals.h"
fmferrari 0:1e567a5a99c3 36 #include "WiflyInterface.h"
fmferrari 0:1e567a5a99c3 37 #include "Commands.h"
fmferrari 0:1e567a5a99c3 38 #include "Websocket.h"
fmferrari 0:1e567a5a99c3 39 #include "ADC.h"
fmferrari 0:1e567a5a99c3 40 #include "pwm.h"
fmferrari 5:dad47e5b9586 41 #include "mbed_model.h"
fmferrari 0:1e567a5a99c3 42
fmferrari 0:1e567a5a99c3 43 //#define DEBUG
fmferrari 0:1e567a5a99c3 44 #define INFOMESSAGES
fmferrari 0:1e567a5a99c3 45 #define WARNMESSAGES
fmferrari 0:1e567a5a99c3 46 #define ERRMESSAGES
fmferrari 0:1e567a5a99c3 47 #define FUNCNAME "IoT"
fmferrari 0:1e567a5a99c3 48 #include "messages.h"
fmferrari 0:1e567a5a99c3 49
fmferrari 0:1e567a5a99c3 50
fmferrari 0:1e567a5a99c3 51
fmferrari 3:2360864c12e2 52
fmferrari 0:1e567a5a99c3 53 // Main Loop!
fmferrari 0:1e567a5a99c3 54 int main() {
fmferrari 0:1e567a5a99c3 55 unsigned int wifi_cmd = NO_WIFI_CMD;
fmferrari 0:1e567a5a99c3 56 float wifi_data = 0.0f;
fmferrari 0:1e567a5a99c3 57 unsigned int ADCRaw;
fmferrari 0:1e567a5a99c3 58 char msg[128];
fmferrari 0:1e567a5a99c3 59
fmferrari 0:1e567a5a99c3 60 // Set the IoT ID:
fmferrari 0:1e567a5a99c3 61 IoT_ID = 5;
fmferrari 0:1e567a5a99c3 62
fmferrari 0:1e567a5a99c3 63 // Set the Auto reconnect flag:
fmferrari 0:1e567a5a99c3 64 IotStatus.SetFlag(SF_AUTOCONNECT);
fmferrari 0:1e567a5a99c3 65
fmferrari 0:1e567a5a99c3 66 // Send a startup message to serial port:
fmferrari 0:1e567a5a99c3 67 INFO("");
fmferrari 0:1e567a5a99c3 68 INFO("");
fmferrari 0:1e567a5a99c3 69 INFO("Starting up...");
fmferrari 0:1e567a5a99c3 70 INFO("CPU SystemCoreClock is %d Hz", SystemCoreClock);
fmferrari 0:1e567a5a99c3 71
fmferrari 0:1e567a5a99c3 72 // Configure the ADC to sample the internal temperature sensor. You cannot
fmferrari 0:1e567a5a99c3 73 // use AnalogIn() unfortunately...
fmferrari 0:1e567a5a99c3 74 ConfigureADC();
fmferrari 0:1e567a5a99c3 75
fmferrari 4:dc0c58eedabb 76 // Check for the wifi module
fmferrari 4:dc0c58eedabb 77 WifiPresent.mode(PullDown);
fmferrari 4:dc0c58eedabb 78 if(WifiPresent == 1){
fmferrari 4:dc0c58eedabb 79 IotStatus.SetFlag(SS_WIFIPRESENT);
fmferrari 4:dc0c58eedabb 80 }
fmferrari 4:dc0c58eedabb 81
fmferrari 4:dc0c58eedabb 82 if(IotStatus.CheckFlag(SS_WIFIPRESENT)){
fmferrari 0:1e567a5a99c3 83
fmferrari 4:dc0c58eedabb 84 // Connect to the wifi network. It will basically get stuck here until it
fmferrari 4:dc0c58eedabb 85 // connects to the network.
fmferrari 4:dc0c58eedabb 86 SetupNetwork(5000);
fmferrari 4:dc0c58eedabb 87
fmferrari 4:dc0c58eedabb 88 // Configure the baud rate of the wifi shield:
fmferrari 4:dc0c58eedabb 89 // This will make our wireless transmissions much faster.
fmferrari 4:dc0c58eedabb 90 ws.setBaud(115200);
fmferrari 4:dc0c58eedabb 91 wait(0.5f);
fmferrari 4:dc0c58eedabb 92 }
fmferrari 0:1e567a5a99c3 93
fmferrari 0:1e567a5a99c3 94 // Configure the PWM module:
fmferrari 0:1e567a5a99c3 95 ConfigurePWM(Duty_us, PwmPeriod_us);
fmferrari 0:1e567a5a99c3 96 // Turn on the PWM:
fmferrari 0:1e567a5a99c3 97 TurnOnPWM(true);
fmferrari 0:1e567a5a99c3 98
fmferrari 0:1e567a5a99c3 99 // Check to see we are connected to the network:
fmferrari 0:1e567a5a99c3 100 if(IotStatus.CheckFlag(SF_WIRELESSCONNECTED)){
fmferrari 0:1e567a5a99c3 101 // Try to connect to the WebSocket server:
fmferrari 0:1e567a5a99c3 102 sprintf(msg, "ws://%s:%d/ws", SERVER_IP, WS_PORT);
fmferrari 0:1e567a5a99c3 103 ws.Initialize(msg);
fmferrari 0:1e567a5a99c3 104 INFO("Connecting to Websocket Server on %s...", msg);
fmferrari 0:1e567a5a99c3 105 if(ws.connect()){
fmferrari 0:1e567a5a99c3 106 // Set a status flag:
fmferrari 0:1e567a5a99c3 107 INFO("Connected.");
fmferrari 0:1e567a5a99c3 108 IotStatus.SetFlag(SF_SERVERCONNECTED);
fmferrari 0:1e567a5a99c3 109 }else{
fmferrari 0:1e567a5a99c3 110 // We could not connect right now..
fmferrari 0:1e567a5a99c3 111 IotStatus.ClearFlag(SF_SERVERCONNECTED);
fmferrari 0:1e567a5a99c3 112 INFO("Could not connect to server, will try again later.");
fmferrari 0:1e567a5a99c3 113 ReconnectAttempts++;
fmferrari 0:1e567a5a99c3 114 }
fmferrari 0:1e567a5a99c3 115 }
fmferrari 0:1e567a5a99c3 116
fmferrari 0:1e567a5a99c3 117 // Start the display timer which will send data to the server every
fmferrari 0:1e567a5a99c3 118 // 3 seconds.
fmferrari 0:1e567a5a99c3 119 DisplayTimer.start();
fmferrari 0:1e567a5a99c3 120
fmferrari 0:1e567a5a99c3 121 // Inifinite main loop:
fmferrari 0:1e567a5a99c3 122 while(1) {
fmferrari 0:1e567a5a99c3 123
fmferrari 0:1e567a5a99c3 124 // Process the wifi command:
fmferrari 0:1e567a5a99c3 125 if(wifi_cmd > NO_WIFI_CMD){
fmferrari 0:1e567a5a99c3 126 // Modify the desired variable:
fmferrari 0:1e567a5a99c3 127 ModifyVariable(wifi_cmd, wifi_data);
fmferrari 0:1e567a5a99c3 128 // Reset the command:
fmferrari 0:1e567a5a99c3 129 wifi_cmd = NO_WIFI_CMD;
fmferrari 0:1e567a5a99c3 130 }
fmferrari 0:1e567a5a99c3 131
fmferrari 0:1e567a5a99c3 132 // Check for new wifi data:
fmferrari 0:1e567a5a99c3 133 if((wifi_cmd == NO_WIFI_CMD)){
fmferrari 0:1e567a5a99c3 134 ReceiveNetworkData(&wifi_cmd, &wifi_data);
fmferrari 0:1e567a5a99c3 135 }
fmferrari 0:1e567a5a99c3 136
fmferrari 0:1e567a5a99c3 137 // Send the network data every 3 seconds:
fmferrari 0:1e567a5a99c3 138 if(DisplayTimer.read()>(3.0f)){
fmferrari 0:1e567a5a99c3 139 // Sample the internal temperature sensor:
fmferrari 0:1e567a5a99c3 140 STARTADCCONVERSION;
fmferrari 0:1e567a5a99c3 141 // Wait for the conversion to complete:
fmferrari 0:1e567a5a99c3 142 while(!ADCCONVERSIONCOMPLETE);
fmferrari 0:1e567a5a99c3 143 // Save the raw value from the ADC:
fmferrari 0:1e567a5a99c3 144 ADCRaw = ADC1->DR;
fmferrari 0:1e567a5a99c3 145 // Calculate the temperature using information from the datasheet:
fmferrari 0:1e567a5a99c3 146 TempSensor = ((((float)ADCRaw)/ADC_MAX)*IT_VMAX - IT_V25)/IT_AVG_SLOPE + 25.0f;
fmferrari 0:1e567a5a99c3 147 // Output the result:
fmferrari 0:1e567a5a99c3 148 DBG("TempSensor = %.5f", TempSensor);
fmferrari 0:1e567a5a99c3 149 DBG("ADC1->DR = %d", ADCRaw);
fmferrari 0:1e567a5a99c3 150
fmferrari 5:dad47e5b9586 151 // INFO("SOC is, %f", mbed_model_Y.SOC);
fmferrari 2:089480a12fa2 152
fmferrari 0:1e567a5a99c3 153 // Send data over network:
fmferrari 0:1e567a5a99c3 154 SendNetworkData();
fmferrari 0:1e567a5a99c3 155
fmferrari 0:1e567a5a99c3 156 // Increment a counter:
fmferrari 0:1e567a5a99c3 157 SendCounter++;
fmferrari 0:1e567a5a99c3 158
fmferrari 0:1e567a5a99c3 159 // Reset the timer:
fmferrari 0:1e567a5a99c3 160 DisplayTimer.reset();
fmferrari 0:1e567a5a99c3 161
fmferrari 0:1e567a5a99c3 162 }
fmferrari 0:1e567a5a99c3 163 } // while(1)
fmferrari 0:1e567a5a99c3 164 } // main()