-
Notifications
You must be signed in to change notification settings - Fork 0
/
obd.cpp
165 lines (129 loc) · 3.63 KB
/
obd.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
* obd.c
*
* Created on: 7 лист. 2020 р.
* Author: Victor
*/
#include "main.h"
#include "screens.h"
#include "can.h"
#include "obd.h"
extern bool carBrake;
extern bool carConn;
extern bool carIgnON;
extern bool carEngON;
extern bool carLightON;
extern int16_t carSpeed; //integer part of speed value
extern int16_t carRPM;
extern float carFSpeed; //full speed value - including fractional part
extern int16_t carTemp;
extern uint64_t carDate;
extern int32_t carEcon1;
extern int32_t carEcon2;
extern bool econMode; //0 - LPH (Liters Per Hour), 1 - LPK (Liters Per 100 Km)
extern uint8_t blinkCounter;
void CalcAvgEcon(uint16_t, bool);
#define ECON_AVG_BUF_SIZE 15
void HandleOBDMsg(CAN_RxHeaderTypeDef pRxHeader, uint8_t *rxData)
{
uint16_t dt;
switch (pRxHeader.ExtId)
{
case CAR_DATE_ID:
if (pRxHeader.DLC == 6)
{
carDate = *(uint64_t *)rxData;
}
break;
case CAR_SPEED_ID:
if (pRxHeader.DLC == 8 && rxData[7] == 0)
{
dt = (uint16_t)rxData[5]; //low byte
dt += ((uint16_t)rxData[4] << 8) & 0xFF00;
carSpeed = (int16_t)(dt >> 7);
carFSpeed = dt / 128; //speed value as float
}
break;
case CAR_ECTEMP_ID:
if (pRxHeader.DLC == 8)
{
carTemp = (int16_t)rxData[3] - 40;
}
break;
case CAR_ECON_ID:
if (pRxHeader.DLC == 6)
{
dt = ((((uint16_t)rxData[4]<<8) & 0xFF00) + rxData[5]);
int32_t econVal;
//economy display mode
bool ecModePrev = econMode; //to check if changed
econMode = (carSpeed >5)?true:false;
if (econMode)
econVal = (uint32_t)((dt*1000/512) / carFSpeed ); //economy in Lp100km
else
econVal = (uint32_t)(dt*10/512); //if speed<5, show economy in lph
CalcAvgEcon(econVal, (econMode != ecModePrev)); //clear the avg buf if mode changed
}
break;
case CAR_STAT1_ID:
if (pRxHeader.DLC == 8)
{
carBrake = (rxData[6] & 0x20)?true:false; //Handbrake
carLightON = (rxData[1] & 0x20)?true:false; //Light
carIgnON = ((rxData[5] & 0x18) == 0x18)?true:false; //Ignition
}
break;
case CAR_STAT3_ID:
if (pRxHeader.DLC == 8)
{
carEngON = ((rxData[0] & 0x80) == 0x80)?true:false; //Engine ON
}
break;
case CAR_RPM_ID:
if (pRxHeader.DLC == 8)
{
carRPM = ((((uint16_t)rxData[2]<<8) & 0xFF00) + rxData[3]);
}
break;
default:
break;
}
}
void RequestOBD(void)
{
//request a fuel consumption value
uint8_t message[] = {0x3,0x22,0x19,0x42,0x0,0x0,0x0,0x0};
uint32_t address = CAR_REQ_ID;
// uint8_t message[] = {0x5,0x62,0x19,0x42,0x3,0xDA};
// uint32_t address = CAR_ECON_ID;
CAN_Send(message, sizeof(message), address);
}
//calculation of average values for economy
static uint16_t buff[ECON_AVG_BUF_SIZE];
static uint8_t idx = 0;
static uint32_t iavg = 0; //instant (2 sec) average
static uint16_t count = 0; //instant average samples count
void updateAvgEcon()
{
if (count >0) carEcon1 = iavg / count; //instant (2 sec) economy
else carEcon1 = 0;
iavg = 0;
count = 0;
buff[idx++] = carEcon1; //update the long-term avg buffer
if (idx >= ECON_AVG_BUF_SIZE) idx = 0;
uint32_t s_avg = 0; //calc the sliding avg for the long-term economy value
for(int8_t i=ECON_AVG_BUF_SIZE-1;i>=0;--i) s_avg += buff[i];
carEcon2 = s_avg / ECON_AVG_BUF_SIZE;
}
void CalcAvgEcon(uint16_t val, bool resAvg)
{
if (resAvg) //reset average buffers on economy calculation mode change
{
iavg = 0;
count = 0;
for(int8_t i=ECON_AVG_BUF_SIZE-1;i>=0;--i) buff[i] = val;
idx = 0;
}
iavg += val;
++count;
}