hal_battery_NoPowerEnPin.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. /*********************************************************************
  2. * INCLUDES
  3. */
  4. #include "usr_config.h"
  5. #include "hal_battery.h"
  6. #include "cli.h"
  7. #define PRINTBLE 0
  8. #include "ble_comm.h"
  9. #include "exception.h"
  10. #include "ringframe.h"
  11. RINGFRAME_DEF(battlog, ringframe_size_4096);
  12. char logbuftemp[50];
  13. int logbuftemp_len = 0;
  14. #define log(...) {logbuftemp_len = sprintf(logbuftemp,__VA_ARGS__); while(ringframe_in(&battlog,logbuftemp,logbuftemp_len)!=0){ringframe_throw(&battlog);}}
  15. #include "hal_ble_client.h"
  16. char print_log = 0;
  17. void cb_BLE_Client_ERR(void* handle)
  18. {
  19. // BLE_Client_Rx_t* target = handle;
  20. DEBUG_LOG("cb_BLE_Client_ERR:%d,%d\n", 1, 1);
  21. print_log = 1;
  22. }
  23. int16_t ADC_GetValue(uint32_t channel)
  24. {
  25. int16_t temp = 0;
  26. ADC_Read(channel, &temp);
  27. return temp;
  28. }
  29. //typedef struct
  30. //{
  31. // void * p_buffer;
  32. // short size;
  33. // short index;
  34. // float sum;
  35. //} average_filter_t;
  36. //#define AVERAGE_FILTER_DEF( _name, _size ) \
  37. // float _name##_average_filter_buffer[(_size)]; \
  38. // average_filter_t _name= \
  39. // { \
  40. // .index = 0, \
  41. // .sum = 0.0f, \
  42. // .p_buffer = _name##_average_filter_buffer, \
  43. // .size = (_size), \
  44. // }
  45. //float average_filter_init(average_filter_t * p_avgf)
  46. //{
  47. // short i=0;
  48. // for(i=1;i<p_avgf->size;i++)
  49. // {
  50. // p_avgf->p_buffer[i]=0.0f;
  51. // }
  52. // p_avgf->index=0;
  53. // p_avgf->sum=0.0f;
  54. //}
  55. //float average_filter(average_filter_t * p_avgf,float value_in)
  56. //{
  57. // p_avgf->sum=0.0f;
  58. // p_avgf->p_buffer[p_avgf->index++]=value_in;
  59. //}
  60. //返回5V信号,有5V的话返回1,没有的话返回0
  61. static char charge_in(void)
  62. {
  63. uint32_t ch = nrf_gpio_pin_read(PIN_CHARGING);
  64. if (ch)
  65. {
  66. return 1;
  67. }
  68. else
  69. {
  70. return 0;
  71. }
  72. }
  73. static float filter(float value, float kg, float* preBestResult)
  74. {
  75. float new_v = value;
  76. new_v = *preBestResult * (1.0f - kg) + value * kg;
  77. *preBestResult = new_v;
  78. return new_v;
  79. }
  80. //鞋子ADC
  81. static const float poo1o[] = {0, 0, 0.0279893723606430, 0.174605323652602, 0.325796538285416, 0.495164949358988, 0.661918800578876, 0.829024800123971, 1.00225498989324, 1.17936073685608, 1.37258677752597, 1.56525700069634, 1.78680072433224, 2.00361106262195, 2.24466616203811, 2.46699160701705, 2.77834696254638, 3.12186809827754, 3.58442625993982, 4.15025435558636, 4.75855743544068, 5.51189718744822, 6.35834306864975, 7.38461196888009, 8.48997478633724, 9.43096936165977, 10.3817319764220, 11.4116388420216, 12.3939372566211, 13.5048186806524, 14.5904959858255, 15.5237940825920, 16.4790857938893, 17.8137595522187, 18.9982251103467, 20.3392608271850, 21.5817542329461, 22.7218253119165, 23.9444316340532, 25.2939077624602, 26.6264082603126, 27.6802415218000, 29.0022881606974, 30.1783424265851, 31.1179209268523, 32.2887764986448, 33.3732790985050, 34.2380544358441, 35.2041112278740, 36.0163848326001, 36.8624779801428, 37.6634899287154, 38.5186413495501, 39.4878256764553, 40.2471232681709, 41.2081417271725, 42.3322924899204, 43.7047997876243, 44.9058976548061, 46.5044971286874, 47.8927266715832, 49.8558978793141, 51.9022338412845, 54.2586141300707, 56.3903798469888, 58.7696803719223, 60.8764981712366, 62.2358527791606, 63.8383633243999, 65.5021323737117, 67.1556090613014, 69.0159229136298, 70.1420773342446, 71.2282683025524, 72.4548338447843, 73.6556507850819, 74.8128040906371, 75.8695501837768, 77.1323517287879, 78.6365237973046, 80.3752005495001, 82.8468947240450, 86.6163997907370, 91.2910588313494, 93.9702969410882, 95.4930183746766, 96.9114001488224, 97.8493292727541, 98.7169169431273, 99.3270162091455, 99.6869018017068, 99.9917942993789, 99.9689500363163, 99.97, 99.98, 99.98, 99.98, 99.98, 99.99, 99.99, 99.99};
  82. static float interp1(float x)
  83. {
  84. int absx = (int)x - 320;
  85. float max = poo1o[absx + 1];
  86. float min = poo1o[absx];
  87. float temp = x - (float)absx - 320.0f;
  88. return (max - min) * temp + min;
  89. }
  90. //返回电压百分比
  91. static float preBestResult_Voltage2power = 0;
  92. static float Voltage2power(float mV)
  93. {
  94. float rev = 0;
  95. float k = 0;
  96. static char init = 1;
  97. if (init)
  98. {
  99. preBestResult_Voltage2power = mV / 10;
  100. init = 0;
  101. }
  102. k = filter(mV / 10, 0.01, &preBestResult_Voltage2power);
  103. if (k < 320.0f)
  104. {
  105. rev = 0;
  106. }
  107. else if (k > 420.0f)
  108. {
  109. rev = 100;
  110. }
  111. else
  112. {
  113. rev = interp1(k);
  114. }
  115. return rev;
  116. }
  117. static const float chargeV2P[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0.606184684199367, 0.938307744774148, 1.30769659743727, 1.87378869014097, 2.39210582883903, 2.92471759425620, 3.79782257541779, 4.54241638183623, 5.09886597521223, 5.98930945903392, 6.49613916536905, 7.57967916311061, 8.42757721701290, 9.26589943580526, 10.3408809248851, 11.4278317273525, 12.3098089504989, 13.8095299712012, 15.4373756551577, 16.8805115746597, 18.4871688551768, 20.0578462608782, 21.6336381358003, 22.9916066660508, 24.4652374859292, 25.6565902258290, 26.8453581267414, 27.9070922567514, 28.9713295466563, 30.0209078713242, 30.9380166385130, 32.0419258329631, 33.1827748787620, 33.8691297160915, 34.8949274023278, 35.8840553861847, 36.9638277084030, 37.8687458690322, 38.9939274175310, 40.4336758333268, 41.1114865403869, 42.6160733592240, 44.2493873543177, 45.6026105469954, 47.4664557187522, 49.0734043728910, 51.2998758679562, 52.8880367841713, 54.7587352342972, 57.0178625862682, 58.8608281071146, 60.3657347075748, 62.4281274954232, 64.3086188700345, 65.8044424890286, 68.6475622104224, 72.7352289117192, 76.9893033499930, 84.0930819869950, 92.2923770276700, 96.3286261252036, 99.7542287364423};
  118. static float interp1_chargeV2P(float x)
  119. {
  120. int absx = (int)x - 350;
  121. float max = chargeV2P[absx + 1];
  122. float min = chargeV2P[absx];
  123. float temp = x - (float)absx - 350.0f;
  124. return (max - min) * temp + min;
  125. }
  126. //返回电压百分比
  127. static float preBestResult_chargeV2P_f = 0;
  128. static float chargeV2P_f(float mV)
  129. {
  130. float rev = 0;
  131. float k = 0;
  132. static char init = 1;
  133. if (init)
  134. {
  135. preBestResult_chargeV2P_f = mV / 10;
  136. init = 0;
  137. }
  138. k = filter(mV / 10, 0.05, &preBestResult_chargeV2P_f);
  139. if (k < 350.0f)
  140. {
  141. rev = 0;
  142. }
  143. else if (k > 415.0f)
  144. {
  145. rev = 100;
  146. }
  147. else
  148. {
  149. rev = interp1_chargeV2P(k);
  150. }
  151. return rev;
  152. }
  153. //返回电量百分比
  154. static float Voltage2mah(float mah, float storage_capacity)
  155. {
  156. return mah / storage_capacity * 100.0f;
  157. }
  158. //返回电压剩余绝对容量
  159. static float mah2Voltage(float P, float storage_capacity)
  160. {
  161. return storage_capacity * P / 100.0f;
  162. }
  163. static void Charge(float mV, float* mAh, float interval_s)
  164. {
  165. float A = mV / 3000.0f * 1.1f;
  166. float dmAh = A * 1000.0f * interval_s / 3600.0f;
  167. *mAh = *mAh + dmAh;
  168. }
  169. static char sta = 0;
  170. float P_mAh = 0;
  171. static float kg = 0;
  172. static float P2 = 0;
  173. static float Power_management(float mV_Battery, float mV_Charge)
  174. {
  175. static float P1 = 100;
  176. float storage_capacity = 350;
  177. static float Battery_capacity_mAh = 0;
  178. switch (sta)
  179. {
  180. case 0:
  181. if (mV_Charge > 20)
  182. {
  183. sta = 2; //充电过程
  184. P1 = chargeV2P_f(mV_Battery);
  185. Battery_capacity_mAh=mah2Voltage(P1, storage_capacity);
  186. }
  187. else
  188. {
  189. P1 = Voltage2power(mV_Battery);
  190. sta = 1; //放电过程
  191. }
  192. break;
  193. case 1://放电
  194. if (mV_Charge > 20)
  195. {
  196. sta = 2; //充电过程
  197. kg = 0;
  198. // //解决插上充电没接电池状态下突然接上电池时电量不衔接的问题
  199. // if((mV_Battery<4000)&&(P1>95.0f))
  200. // {
  201. // P1=chargeV2P_f(mV_Battery);
  202. // }
  203. Battery_capacity_mAh=mah2Voltage(P1, storage_capacity);
  204. }
  205. else
  206. {
  207. P2 = Voltage2power(mV_Battery);
  208. if (P1 > P2) //过滤刚拔掉充电线时候的虚高
  209. {
  210. P1 = P2;
  211. }
  212. //解决充满电后充电器不拔出来的情况显示不到100%的情况
  213. if (charge_in() && (P1 > 95.0f))
  214. {
  215. P1 = 100.0f;
  216. }
  217. }
  218. break;
  219. case 2://充电
  220. if (mV_Charge < 20)
  221. {
  222. sta = 1; //放电过程
  223. //初始化滤波器波器
  224. preBestResult_Voltage2power = mV_Battery / 10;
  225. if (P1 > 99.1f)
  226. {
  227. P1 = 100.0f;
  228. }
  229. }
  230. else
  231. {
  232. //---------------------------------------------------
  233. Charge(mV_Charge, &Battery_capacity_mAh, 1);
  234. P_mAh = Voltage2mah(Battery_capacity_mAh, storage_capacity);
  235. //---------------------------------------------------
  236. P2 = chargeV2P_f(mV_Battery);
  237. // log("%f\n",P2);
  238. // SEGGER_RTT_Write(0,logbuftemp, logbuftemp_len);
  239. kg = mV_Charge / 1000.0f;
  240. if (kg > 1.0f)
  241. {
  242. kg = 1.0f;
  243. }
  244. P2 = (1.0f - kg) * P2 + kg * P_mAh;
  245. if (P1 < P2) //过滤刚插上充电线时候的虚低
  246. {
  247. P1 = P2;
  248. }
  249. if (P1 > 100)
  250. {
  251. P1 = 99.9;
  252. }
  253. }
  254. break;
  255. }
  256. return P1;
  257. }
  258. int16_t hal_GetBatttery_Adc(void){
  259. int16_t adcVal;
  260. adcVal = ADC_GetValue(PIN_ADC_BAT_CHANNEL);
  261. adcVal = ADC_RESULT_IN_MILLI_VOLTS(adcVal) * 5 / 3;
  262. return adcVal;
  263. }
  264. static float adc_tp4056_power = 0;
  265. static void hal_battery_Process(void)
  266. {
  267. static int cprign = 0;
  268. #if PRINTBLE
  269. char buff[256];
  270. unsigned char len = 0;
  271. #endif
  272. int16_t adcVal;
  273. int16_t CHARGMEASURE;
  274. int16_t volTemp;
  275. int16_t volTemp_CHARGMEASURE;
  276. adcVal = ADC_GetValue(PIN_ADC_BAT_CHANNEL);
  277. volTemp = ADC_RESULT_IN_MILLI_VOLTS(adcVal) * 5 / 3; // 电池电压转换计算
  278. CHARGMEASURE = ADC_GetValue(PIN_ADC_CHARGMEASURE_CHANNEL);
  279. volTemp_CHARGMEASURE = ADC_RESULT_IN_MILLI_VOLTS(CHARGMEASURE);// 电池电压转换计算
  280. adc_tp4056_power = Power_management((float)volTemp, (float)volTemp_CHARGMEASURE);
  281. #if PRINTBLE
  282. len = sprintf(buff, "%4d ,%4d ,%4d,%f\r\n", TIME_GetTicks(), volTemp, volTemp_CHARGMEASURE, adc_tp4056_power);
  283. send_bytes_client((unsigned char*)buff, len);
  284. #endif
  285. if (cprign % 300 == 0)
  286. {
  287. log("%4d,%4d,%4d,%2.1f,%d,%2.1f,%2.1f,%2.1f\n", TIME_GetTicks(), volTemp, volTemp_CHARGMEASURE, adc_tp4056_power, sta, P_mAh, P2, kg);
  288. SEGGER_RTT_Write(0,logbuftemp, logbuftemp_len);
  289. logbuftemp[logbuftemp_len] = 0;
  290. Except_TxError(EXCEPT_DATA_BATTERY, logbuftemp);
  291. }
  292. cprign++;
  293. // cli_process(&clirtt);
  294. // uint8_t persent = 0;
  295. // persent = (uint8_t)(adc_tp4056_power+0.5f);
  296. // DEBUG_LOG("hal_battery_Process:%d,%d\n",persent,volTemp);
  297. if(print_log==1)
  298. {
  299. log("%4d,%4d,%4d,%2.1f,%d,%2.1f,%2.1f,%2.1f\n", TIME_GetTicks(), volTemp, volTemp_CHARGMEASURE, adc_tp4056_power, sta, P_mAh, P2, kg);
  300. SEGGER_RTT_Write(0,logbuftemp, logbuftemp_len);
  301. logbuftemp[logbuftemp_len] = 0;
  302. Except_TxError(EXCEPT_DATA_BATTERY, logbuftemp);
  303. print_log=2;
  304. }
  305. if (print_log==2)
  306. {
  307. unsigned char length = 0;
  308. while (ringframe_peek(&battlog, logbuftemp, &length) == 0)
  309. {
  310. if (send_bytes_client((unsigned char*)logbuftemp, length) != 0)
  311. {
  312. return;
  313. }
  314. ringframe_throw(&battlog);
  315. SEGGER_RTT_Write(0, logbuftemp, length);
  316. }
  317. print_log = 0;
  318. }
  319. }
  320. //返回的电量范围: 0~100 表示电量百分比
  321. uint8_t GetBatteryPersent(void)
  322. {
  323. uint8_t persent = 0;
  324. persent = (uint8_t)(adc_tp4056_power + 0.5f);
  325. if(persent>95)persent=100;
  326. else if((persent>85)&&(persent<=95))persent=90;
  327. else if((persent>75)&&(persent<=85))persent=80;
  328. else if((persent>65)&&(persent<=75))persent=70;
  329. else if((persent>55)&&(persent<=65))persent=60;
  330. else if((persent>45)&&(persent<=55))persent=50;
  331. else if((persent>35)&&(persent<=45))persent=40;
  332. else if((persent>25)&&(persent<=35))persent=30;
  333. else if((persent>15)&&(persent<=25))persent=20;
  334. else if((persent>10)&&(persent<=15))persent=10;
  335. if (persent > 100)
  336. {
  337. persent = 100;
  338. }
  339. else if(persent<=0)
  340. {
  341. persent = 0;
  342. }
  343. return persent;
  344. }
  345. void hal_battery_init(void)
  346. {
  347. hal_battery_Process();
  348. BLE_Client_Rx_Regist(BLE_ERR, cb_BLE_Client_ERR);
  349. Process_Start(1000, "hal_battery_Process", hal_battery_Process);
  350. }