Mercurial > public > ostc4
diff Discovery/Src/bonex_mini.c @ 38:5f11787b4f42
include in ostc4 repository
author | heinrichsweikamp |
---|---|
date | Sat, 28 Apr 2018 11:52:34 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Discovery/Src/bonex_mini.c Sat Apr 28 11:52:34 2018 +0200 @@ -0,0 +1,347 @@ +/////////////////////////////////////////////////////////////////////////////// +/// -*- coding: UTF-8 -*- +/// +/// \file Discovery/Src/bonex_mini.c +/// \brief voltage to battery percentage based on bonex.c for BIS PCB +/// \author Heinrichs Weikamp gmbh +/// \date 26-March-2017 +/// +/// \details +/// +/// $Id$ +/////////////////////////////////////////////////////////////////////////////// +/// \par Copyright (c) 2014-2018 Heinrichs Weikamp gmbh +/// +/// This program is free software: you can redistribute it and/or modify +/// it under the terms of the GNU General Public License as published by +/// the Free Software Foundation, either version 3 of the License, or +/// (at your option) any later version. +/// +/// This program is distributed in the hope that it will be useful, +/// but WITHOUT ANY WARRANTY; without even the implied warranty of +/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/// GNU General Public License for more details. +/// +/// You should have received a copy of the GNU General Public License +/// along with this program. If not, see <http://www.gnu.org/licenses/>. +////////////////////////////////////////////////////////////////////////////// +/* + ============================================================================== + ##### CAN data ##### + ============================================================================== + [..] is stored static in BONEX_CAN_Config + see example CAN_Networking for STM32303C_EVAL + + */ + +/* Includes ------------------------------------------------------------------*/ +#include "bonex_mini.h" + +/* Private variables ---------------------------------------------------------*/ + +enum +{ + TYPE_ECOS = 0, + TYPE_RS = 1, + TYPE_MAX +}; + +const uint16_t loadVoltageInverted[TYPE_MAX][21] = +{ + { // ECOS + 0 + }, + { // RS + 38000, // 0% >= index *5 ist Ergebnis Kapazit�t + 38875, // 5% + 39750, // 10% + 40625, + 41500, + 42050, + 42600, + 43150, + 43700, + 44250, + 44800, + 45350, + 45900, + 46450, + 47000, // 70% + 47550, // 75% + 48100, + 48450, // 85% + 48800, + 49150, + 49500, //100% , index = 20 + } +}; + + +uint8_t BONEX_mini_ResidualCapacityVoltageBased(float voltage_V, uint16_t ageInMilliSecondsSinceLast) +{ + static uint8_t capacityStorage = 0; + static uint32_t voltage_mV_storage_32bit = 0; + static uint16_t storageCounter = 0; + + uint16_t voltage_mV = (uint16_t)(1000 * voltage_V); + + uint8_t calcNow = 0; + + if(ageInMilliSecondsSinceLast < 2000) + { + voltage_mV_storage_32bit += voltage_mV; + storageCounter++; + } + else + { + storageCounter = 0; + voltage_mV_storage_32bit = 0; + } + + + if(storageCounter >= 600) + { + voltage_mV_storage_32bit /= storageCounter; + voltage_mV = (uint16_t)voltage_mV_storage_32bit; + storageCounter = 1; + voltage_mV_storage_32bit = voltage_mV; + calcNow = 1; + } + else if(storageCounter == 1) // value immediately but not called after 600 counter ;-) + { + voltage_mV = (uint16_t)voltage_mV_storage_32bit; + calcNow = 1; + } + + if(calcNow) + { + for(int i = 20; i>=0; i--) + { + if(voltage_mV >= loadVoltageInverted[1][i]) + { + capacityStorage = i*5; + break; + } + } + } + + return capacityStorage; +} + +/* + +uint8_t BONEX_mini_ResidualCapacityVoltageBased(float voltage_V, uint16_t ageInMilliSecondsSinceLast) +{ + static uint8_t capacityStorage = 0; + static uint16_t voltage_mV_storage[5] = {0,0,0,0,0}; // number six is used directly from voltage_mV + + uint32_t voltage_mV = (uint32_t)(1000 * voltage_V); + + + // if necessary reset container and return actual voltage_V as capacity + if(ageInMilliSecondsSinceLast > 2000) + { + capacityStorage = 0; + for(int i = 0; i<5; i++) + { + voltage_mV_storage[i] = 0; + } + } + + // find storage container or, if full, use it as number six and recalc voltage_mV based on those six values + int ptr = -1; + do + { + ptr++; + } while ((ptr < 5) && voltage_mV_storage[ptr] != 0); + + if(ptr == 5) + { + for(int i = 0; i<5; i++) + { + voltage_mV += voltage_mV_storage[i]; + voltage_mV_storage[i] = 0; + } + voltage_mV += 3; + voltage_mV /= 6; + capacityStorage = 0; + } + else + { + voltage_mV_storage[ptr] = voltage_mV; + } + + // calc result if update necessary + if(capacityStorage == 0) + { + for(int i = 20; i>=0; i--) + { + if(voltage_mV >= loadVoltageInverted[1][i]) + { + capacityStorage = i*5; + break; + } + } + } + return capacityStorage; +} + +#define ECOS_VMAX 290 +#define ECOS_VMIN 195 +#define ECOS_STEP 5 + +#define RS_VMAX 500 +#define RS_VMIN 360 +#define RS_STEP 5 + +#define ECOS_LENGTH (((ECOS_VMAX - ECOS_VMIN) / ECOS_STEP) + 1) +#define RS_LENGTH (((RS_VMAX - RS_VMIN) / RS_STEP) + 1) +#define MAX_LENGTH (ECOS_LENGTH>RS_LENGTH? ECOS_LENGTH:RS_LENGTH) + + +typedef struct +{ + uint8_t load[3]; +} load; + + +const int32_t currentMaxLoad[TYPE_MAX] = { 17000,14000}; +const int32_t currentPartialLoad[TYPE_MAX] = { 1000, 1000}; +const uint16_t voltageCharged[TYPE_MAX] = { 280, 480}; +const uint16_t voltageMax[TYPE_MAX] = { ECOS_VMAX, RS_VMAX}; +const uint16_t voltageMin[TYPE_MAX] = { ECOS_VMIN, RS_VMIN}; +const uint8_t voltageSteps[TYPE_MAX] = { ECOS_STEP, RS_STEP}; +const uint8_t length[TYPE_MAX] = { ECOS_LENGTH, RS_LENGTH}; + + + + + +const uint8_t loadVoltage[TYPE_MAX][MAX_LENGTH][3] = +{ + { + // ECOS + // no,teil,voll + { 0, 5, 0}, // voltageMin 19.5 + { 0, 5, 0}, // voltageMin + 0.5V + { 0, 5, 0}, // 20.5 + { 5, 5, 5}, // 21 + { 5, 5, 5}, // 21.5 + { 5, 10, 10}, // 22 + { 5, 10, 15}, // 22.5 + { 10, 15, 30}, // 23 + { 20, 30, 45}, // 23.5 + { 30, 40, 60}, // 24 + { 40, 50, 65}, // 24.5 + { 50, 60, 75}, // 25 + { 60, 70, 80}, // 25.5 + { 70, 80, 85}, // 26 + { 80, 90, 85}, // 26.5 + { 85, 90, 90}, // 27 + { 90, 95, 90}, // 27.5 + { 95, 95, 95}, // 28 + {100,100,100}, // 28.5 + {100,100,100}, // voltageMax 29 + }, + { + // RS + // no,teil,voll + { 0, 0, 0}, // voltageMin 36 V + { 2, 0, 2}, // voltageMin + 0.5V + { 5, 0, 5}, // 37 + { 5, 2, 5}, // + { 5, 5, 5}, // 38 + { 5, 5, 10}, // + { 5, 5, 15}, // 39 + { 7, 7, 17}, // + { 10, 10, 20}, // 40 + { 15, 12, 27}, // + { 20, 15, 35}, // 41 + { 27, 22, 42}, // + { 35, 30, 50}, // 42 + { 42, 37, 55}, // + { 50, 45, 60}, // 43 + { 55, 50, 67}, // + { 60, 55, 75}, // 44 + { 67, 57, 80}, // + { 75, 60, 85}, // 45 + { 77, 65, 87}, // + { 80, 70, 90}, // 46 + { 85, 75, 90}, // + { 90, 80, 90}, // 47 + { 92, 85, 92}, // + { 95, 90, 95}, // 48 + { 95, 92, 97}, // + { 95, 95,100}, // 49 + { 97, 97,100}, // + {100,100,100} // 50 + } +}; + + +void BONEX_calc_new_ResidualCapacity(uint8_t *residualC, uint32_t voltage_mV, int32_t current_mA, uint8_t scooterType) // as in BIS +{ + uint8_t actualLoad = 0; + uint8_t remainder = 0; + uint32_t voltagePointer = 0; + + if(voltage_mV == 0) + return; + + if(scooterType >= TYPE_MAX) + return; + + if(voltage_mV < (voltageMin[scooterType] * 100)) + { + *residualC = 0; + return; + } + else + if(voltage_mV >= (voltageMax[scooterType] * 100)) + { + *residualC = 100; + return; + } + else // check if charged and reset residualC for further calculation + if(voltage_mV >= (voltageCharged[scooterType] * 100)) + { + *residualC = 100; + return; + } + + // define the line we are working + if(current_mA >= currentMaxLoad[scooterType]) + actualLoad = 2; + else + if(current_mA >= currentPartialLoad[scooterType]) + actualLoad = 1; + else + actualLoad = 0; + + voltagePointer = (voltage_mV - ((uint32_t)(voltageMin[scooterType])) * 100) / (voltageSteps[scooterType] * 100); + + // should be checked with if(... >= voltageMax) but for safety + if(voltagePointer >= length[scooterType]) + { + *residualC = 100; + return; + } + + if(loadVoltage[scooterType][voltagePointer][actualLoad] < *residualC) + *residualC = loadVoltage[scooterType][voltagePointer][actualLoad]; + else if(loadVoltage[scooterType][voltagePointer][actualLoad] >= (*residualC + 20)) + *residualC = loadVoltage[scooterType][voltagePointer][actualLoad]; + + // steps of 5 + remainder = (*residualC)%5; + if(remainder) + *residualC += (5 - remainder); + + // safety + if(*residualC > 100) + *residualC = 100; + + return; +} +*/ +