-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCarProbe.cpp
144 lines (110 loc) · 3.71 KB
/
CarProbe.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
#include <Arduino.h>
#include "Root4root_INA219.h"
#include "View.h"
#include "CarProbe.h"
void setup()
{
pinMode(RELAY, OUTPUT); //Power activation pin.
pinMode(PFET, OUTPUT); //Power activation pin.
pinMode(PROBE, OUTPUT); //Ohm Ω meter pin
pinMode(POWER_BUTTON, INPUT); //Power activation button
digitalWrite(POWER_BUTTON, HIGH); //Enable internal pull-up resistor
digitalWrite(RELAY, LOW); //External power relay (30A)
digitalWrite(PFET, LOW); //Internal PFET relay
digitalWrite(PROBE, LOW); //Probe pin
ina219.begin(20000, 10); //Calibration, max expected current 20A, shunt resistance in mOhm
ina219.changeConfig(
INA219_CONFIG_SHUNT_ADC_RESOLUTION_12BIT_8S_4260US,
INA219_CONFIG_SHUNT_ADC_RESOLUTION_MASK
);
view.init();
}
void loop() {
if (powerButtonHandler()) {
return; //Go to the next loop() iteration
}
autoMode();
}
void autoMode()
{
digitalWrite(PROBE, LOW);
uint16_t voltage = ina219.getBusVoltage_mV();
if (voltage < 5) { //Less than 5 mV !
measureResistance();
} else {
view.displayVoltage(voltage);
}
}
void measureResistance()
{
digitalWrite(PROBE, HIGH);
uint16_t voltage = ina219.getBusVoltage_mV();
if (voltage < 2) {
view.displayResistance(0);
return;
}
if (voltage >= 5000) {
view.displayResistance(-1); //Infinite - any value less than 0
return;
}
//R2=VoR1/(Vs-Vo);
//Since resistance is 1000 Ohm we keep voltage in mV
view.displayResistance(voltage/(REFERENCE - voltage/1000.0));
}
bool powerButtonHandler()
{
static bool currentOutputState = false;
bool currentButtonState = readButtonRoutine();
if (currentOutputState == true) {
view.displayCurrent(ina219.getCurrent_mA());
}
if (currentOutputState == currentButtonState) {
return currentOutputState;
}
if (currentButtonState == true) {
digitalWrite(PROBE, LOW);
digitalWrite(PFET, HIGH);
view.magenta();
view.displayCurrent(ina219.getCurrent_mA(), true);
} else {
digitalWrite(PFET, LOW);
view.black();
}
currentOutputState = currentButtonState;
return currentOutputState;
}
bool readButtonRoutine() //strict EMI protection and debounce
{
static uint16_t pushDuration = 0;
static uint32_t previousTime = millis(); //in case multiple buttons, could be moved level up
static bool normalizedButtonState = false; //which'll be returned to the caller
bool rawButtonState = digitalRead(POWER_BUTTON);
//unlock pushDuration timer, start action if button pressed
if (rawButtonState == PRESSED_BUTTON_STATE && pushDuration == 0) {
++pushDuration;
previousTime = millis();
}
if (pushDuration == 0) { //idle guard...
return normalizedButtonState;
}
uint16_t timeDifference = millis() - previousTime;
if (timeDifference == 0) { //minimum time chunk is 1ms
return normalizedButtonState;
}
previousTime = millis();
//EMI protection, including severe ones
if (rawButtonState == PRESSED_BUTTON_STATE) {
uint16_t tempResult = pushDuration + timeDifference;
pushDuration = (tempResult > BUTTON_PUSH_DURATION) ? BUTTON_PUSH_DURATION : tempResult;
} else {
++timeDifference; //decrease slightly faster to gain EMI protection even more...
pushDuration -= (timeDifference > pushDuration) ? pushDuration : timeDifference;
}
if (pushDuration == BUTTON_PUSH_DURATION) {
normalizedButtonState = true;
}
if (pushDuration == 0) {
normalizedButtonState = false;
}
return normalizedButtonState;
}