Mercurial > public > ostc4
comparison Discovery/Src/bonex_mini.c @ 38:5f11787b4f42
include in ostc4 repository
author | heinrichsweikamp |
---|---|
date | Sat, 28 Apr 2018 11:52:34 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
37:ccc45c0e1ea2 | 38:5f11787b4f42 |
---|---|
1 /////////////////////////////////////////////////////////////////////////////// | |
2 /// -*- coding: UTF-8 -*- | |
3 /// | |
4 /// \file Discovery/Src/bonex_mini.c | |
5 /// \brief voltage to battery percentage based on bonex.c for BIS PCB | |
6 /// \author Heinrichs Weikamp gmbh | |
7 /// \date 26-March-2017 | |
8 /// | |
9 /// \details | |
10 /// | |
11 /// $Id$ | |
12 /////////////////////////////////////////////////////////////////////////////// | |
13 /// \par Copyright (c) 2014-2018 Heinrichs Weikamp gmbh | |
14 /// | |
15 /// This program is free software: you can redistribute it and/or modify | |
16 /// it under the terms of the GNU General Public License as published by | |
17 /// the Free Software Foundation, either version 3 of the License, or | |
18 /// (at your option) any later version. | |
19 /// | |
20 /// This program is distributed in the hope that it will be useful, | |
21 /// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
22 /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
23 /// GNU General Public License for more details. | |
24 /// | |
25 /// You should have received a copy of the GNU General Public License | |
26 /// along with this program. If not, see <http://www.gnu.org/licenses/>. | |
27 ////////////////////////////////////////////////////////////////////////////// | |
28 /* | |
29 ============================================================================== | |
30 ##### CAN data ##### | |
31 ============================================================================== | |
32 [..] is stored static in BONEX_CAN_Config | |
33 see example CAN_Networking for STM32303C_EVAL | |
34 | |
35 */ | |
36 | |
37 /* Includes ------------------------------------------------------------------*/ | |
38 #include "bonex_mini.h" | |
39 | |
40 /* Private variables ---------------------------------------------------------*/ | |
41 | |
42 enum | |
43 { | |
44 TYPE_ECOS = 0, | |
45 TYPE_RS = 1, | |
46 TYPE_MAX | |
47 }; | |
48 | |
49 const uint16_t loadVoltageInverted[TYPE_MAX][21] = | |
50 { | |
51 { // ECOS | |
52 0 | |
53 }, | |
54 { // RS | |
55 38000, // 0% >= index *5 ist Ergebnis Kapazit�t | |
56 38875, // 5% | |
57 39750, // 10% | |
58 40625, | |
59 41500, | |
60 42050, | |
61 42600, | |
62 43150, | |
63 43700, | |
64 44250, | |
65 44800, | |
66 45350, | |
67 45900, | |
68 46450, | |
69 47000, // 70% | |
70 47550, // 75% | |
71 48100, | |
72 48450, // 85% | |
73 48800, | |
74 49150, | |
75 49500, //100% , index = 20 | |
76 } | |
77 }; | |
78 | |
79 | |
80 uint8_t BONEX_mini_ResidualCapacityVoltageBased(float voltage_V, uint16_t ageInMilliSecondsSinceLast) | |
81 { | |
82 static uint8_t capacityStorage = 0; | |
83 static uint32_t voltage_mV_storage_32bit = 0; | |
84 static uint16_t storageCounter = 0; | |
85 | |
86 uint16_t voltage_mV = (uint16_t)(1000 * voltage_V); | |
87 | |
88 uint8_t calcNow = 0; | |
89 | |
90 if(ageInMilliSecondsSinceLast < 2000) | |
91 { | |
92 voltage_mV_storage_32bit += voltage_mV; | |
93 storageCounter++; | |
94 } | |
95 else | |
96 { | |
97 storageCounter = 0; | |
98 voltage_mV_storage_32bit = 0; | |
99 } | |
100 | |
101 | |
102 if(storageCounter >= 600) | |
103 { | |
104 voltage_mV_storage_32bit /= storageCounter; | |
105 voltage_mV = (uint16_t)voltage_mV_storage_32bit; | |
106 storageCounter = 1; | |
107 voltage_mV_storage_32bit = voltage_mV; | |
108 calcNow = 1; | |
109 } | |
110 else if(storageCounter == 1) // value immediately but not called after 600 counter ;-) | |
111 { | |
112 voltage_mV = (uint16_t)voltage_mV_storage_32bit; | |
113 calcNow = 1; | |
114 } | |
115 | |
116 if(calcNow) | |
117 { | |
118 for(int i = 20; i>=0; i--) | |
119 { | |
120 if(voltage_mV >= loadVoltageInverted[1][i]) | |
121 { | |
122 capacityStorage = i*5; | |
123 break; | |
124 } | |
125 } | |
126 } | |
127 | |
128 return capacityStorage; | |
129 } | |
130 | |
131 /* | |
132 | |
133 uint8_t BONEX_mini_ResidualCapacityVoltageBased(float voltage_V, uint16_t ageInMilliSecondsSinceLast) | |
134 { | |
135 static uint8_t capacityStorage = 0; | |
136 static uint16_t voltage_mV_storage[5] = {0,0,0,0,0}; // number six is used directly from voltage_mV | |
137 | |
138 uint32_t voltage_mV = (uint32_t)(1000 * voltage_V); | |
139 | |
140 | |
141 // if necessary reset container and return actual voltage_V as capacity | |
142 if(ageInMilliSecondsSinceLast > 2000) | |
143 { | |
144 capacityStorage = 0; | |
145 for(int i = 0; i<5; i++) | |
146 { | |
147 voltage_mV_storage[i] = 0; | |
148 } | |
149 } | |
150 | |
151 // find storage container or, if full, use it as number six and recalc voltage_mV based on those six values | |
152 int ptr = -1; | |
153 do | |
154 { | |
155 ptr++; | |
156 } while ((ptr < 5) && voltage_mV_storage[ptr] != 0); | |
157 | |
158 if(ptr == 5) | |
159 { | |
160 for(int i = 0; i<5; i++) | |
161 { | |
162 voltage_mV += voltage_mV_storage[i]; | |
163 voltage_mV_storage[i] = 0; | |
164 } | |
165 voltage_mV += 3; | |
166 voltage_mV /= 6; | |
167 capacityStorage = 0; | |
168 } | |
169 else | |
170 { | |
171 voltage_mV_storage[ptr] = voltage_mV; | |
172 } | |
173 | |
174 // calc result if update necessary | |
175 if(capacityStorage == 0) | |
176 { | |
177 for(int i = 20; i>=0; i--) | |
178 { | |
179 if(voltage_mV >= loadVoltageInverted[1][i]) | |
180 { | |
181 capacityStorage = i*5; | |
182 break; | |
183 } | |
184 } | |
185 } | |
186 return capacityStorage; | |
187 } | |
188 | |
189 #define ECOS_VMAX 290 | |
190 #define ECOS_VMIN 195 | |
191 #define ECOS_STEP 5 | |
192 | |
193 #define RS_VMAX 500 | |
194 #define RS_VMIN 360 | |
195 #define RS_STEP 5 | |
196 | |
197 #define ECOS_LENGTH (((ECOS_VMAX - ECOS_VMIN) / ECOS_STEP) + 1) | |
198 #define RS_LENGTH (((RS_VMAX - RS_VMIN) / RS_STEP) + 1) | |
199 #define MAX_LENGTH (ECOS_LENGTH>RS_LENGTH? ECOS_LENGTH:RS_LENGTH) | |
200 | |
201 | |
202 typedef struct | |
203 { | |
204 uint8_t load[3]; | |
205 } load; | |
206 | |
207 | |
208 const int32_t currentMaxLoad[TYPE_MAX] = { 17000,14000}; | |
209 const int32_t currentPartialLoad[TYPE_MAX] = { 1000, 1000}; | |
210 const uint16_t voltageCharged[TYPE_MAX] = { 280, 480}; | |
211 const uint16_t voltageMax[TYPE_MAX] = { ECOS_VMAX, RS_VMAX}; | |
212 const uint16_t voltageMin[TYPE_MAX] = { ECOS_VMIN, RS_VMIN}; | |
213 const uint8_t voltageSteps[TYPE_MAX] = { ECOS_STEP, RS_STEP}; | |
214 const uint8_t length[TYPE_MAX] = { ECOS_LENGTH, RS_LENGTH}; | |
215 | |
216 | |
217 | |
218 | |
219 | |
220 const uint8_t loadVoltage[TYPE_MAX][MAX_LENGTH][3] = | |
221 { | |
222 { | |
223 // ECOS | |
224 // no,teil,voll | |
225 { 0, 5, 0}, // voltageMin 19.5 | |
226 { 0, 5, 0}, // voltageMin + 0.5V | |
227 { 0, 5, 0}, // 20.5 | |
228 { 5, 5, 5}, // 21 | |
229 { 5, 5, 5}, // 21.5 | |
230 { 5, 10, 10}, // 22 | |
231 { 5, 10, 15}, // 22.5 | |
232 { 10, 15, 30}, // 23 | |
233 { 20, 30, 45}, // 23.5 | |
234 { 30, 40, 60}, // 24 | |
235 { 40, 50, 65}, // 24.5 | |
236 { 50, 60, 75}, // 25 | |
237 { 60, 70, 80}, // 25.5 | |
238 { 70, 80, 85}, // 26 | |
239 { 80, 90, 85}, // 26.5 | |
240 { 85, 90, 90}, // 27 | |
241 { 90, 95, 90}, // 27.5 | |
242 { 95, 95, 95}, // 28 | |
243 {100,100,100}, // 28.5 | |
244 {100,100,100}, // voltageMax 29 | |
245 }, | |
246 { | |
247 // RS | |
248 // no,teil,voll | |
249 { 0, 0, 0}, // voltageMin 36 V | |
250 { 2, 0, 2}, // voltageMin + 0.5V | |
251 { 5, 0, 5}, // 37 | |
252 { 5, 2, 5}, // | |
253 { 5, 5, 5}, // 38 | |
254 { 5, 5, 10}, // | |
255 { 5, 5, 15}, // 39 | |
256 { 7, 7, 17}, // | |
257 { 10, 10, 20}, // 40 | |
258 { 15, 12, 27}, // | |
259 { 20, 15, 35}, // 41 | |
260 { 27, 22, 42}, // | |
261 { 35, 30, 50}, // 42 | |
262 { 42, 37, 55}, // | |
263 { 50, 45, 60}, // 43 | |
264 { 55, 50, 67}, // | |
265 { 60, 55, 75}, // 44 | |
266 { 67, 57, 80}, // | |
267 { 75, 60, 85}, // 45 | |
268 { 77, 65, 87}, // | |
269 { 80, 70, 90}, // 46 | |
270 { 85, 75, 90}, // | |
271 { 90, 80, 90}, // 47 | |
272 { 92, 85, 92}, // | |
273 { 95, 90, 95}, // 48 | |
274 { 95, 92, 97}, // | |
275 { 95, 95,100}, // 49 | |
276 { 97, 97,100}, // | |
277 {100,100,100} // 50 | |
278 } | |
279 }; | |
280 | |
281 | |
282 void BONEX_calc_new_ResidualCapacity(uint8_t *residualC, uint32_t voltage_mV, int32_t current_mA, uint8_t scooterType) // as in BIS | |
283 { | |
284 uint8_t actualLoad = 0; | |
285 uint8_t remainder = 0; | |
286 uint32_t voltagePointer = 0; | |
287 | |
288 if(voltage_mV == 0) | |
289 return; | |
290 | |
291 if(scooterType >= TYPE_MAX) | |
292 return; | |
293 | |
294 if(voltage_mV < (voltageMin[scooterType] * 100)) | |
295 { | |
296 *residualC = 0; | |
297 return; | |
298 } | |
299 else | |
300 if(voltage_mV >= (voltageMax[scooterType] * 100)) | |
301 { | |
302 *residualC = 100; | |
303 return; | |
304 } | |
305 else // check if charged and reset residualC for further calculation | |
306 if(voltage_mV >= (voltageCharged[scooterType] * 100)) | |
307 { | |
308 *residualC = 100; | |
309 return; | |
310 } | |
311 | |
312 // define the line we are working | |
313 if(current_mA >= currentMaxLoad[scooterType]) | |
314 actualLoad = 2; | |
315 else | |
316 if(current_mA >= currentPartialLoad[scooterType]) | |
317 actualLoad = 1; | |
318 else | |
319 actualLoad = 0; | |
320 | |
321 voltagePointer = (voltage_mV - ((uint32_t)(voltageMin[scooterType])) * 100) / (voltageSteps[scooterType] * 100); | |
322 | |
323 // should be checked with if(... >= voltageMax) but for safety | |
324 if(voltagePointer >= length[scooterType]) | |
325 { | |
326 *residualC = 100; | |
327 return; | |
328 } | |
329 | |
330 if(loadVoltage[scooterType][voltagePointer][actualLoad] < *residualC) | |
331 *residualC = loadVoltage[scooterType][voltagePointer][actualLoad]; | |
332 else if(loadVoltage[scooterType][voltagePointer][actualLoad] >= (*residualC + 20)) | |
333 *residualC = loadVoltage[scooterType][voltagePointer][actualLoad]; | |
334 | |
335 // steps of 5 | |
336 remainder = (*residualC)%5; | |
337 if(remainder) | |
338 *residualC += (5 - remainder); | |
339 | |
340 // safety | |
341 if(*residualC > 100) | |
342 *residualC = 100; | |
343 | |
344 return; | |
345 } | |
346 */ | |
347 |