-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPicoAnalogCorrection.cpp
126 lines (95 loc) · 2.91 KB
/
PicoAnalogCorrection.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
/*
Arduino Pico Analog Correction
https://github.com/NuclearPhoenixx/Arduino-Pico-Analog-Correction/
*/
#include "PicoAnalogCorrection.h"
PicoAnalogCorrection::PicoAnalogCorrection(size_t adc_res, float vref) {
_adc_init = false;
_adc_res = adc_res;
_max_channel = pow(2, adc_res) - 1;
_gnd_offset = 0;
_vcc_offset = 0;
_vref = vref;
setCorrectionValues();
}
PicoAnalogCorrection::PicoAnalogCorrection(size_t adc_res, size_t gnd_val, size_t vcc_val) {
_adc_init = false;
_adc_res = adc_res;
_max_channel = pow(2, adc_res) - 1;
_gnd_offset = gnd_val;
_vcc_offset = vcc_val;
_vref = 3.3;
setCorrectionValues();
}
PicoAnalogCorrection::PicoAnalogCorrection(size_t adc_res, float vref, size_t gnd_val, size_t vcc_val) {
_adc_init = false;
_adc_res = adc_res;
_max_channel = pow(2, adc_res) - 1;
_vref = vref;
_gnd_offset = gnd_val;
_vcc_offset = vcc_val;
setCorrectionValues();
}
void PicoAnalogCorrection::setCorrectionValues() {
if(_vcc_offset == 0) {
_a = 1.0;
} else {
_a = _max_channel / (_vcc_offset - _gnd_offset);
}
_d = - _a * _gnd_offset;
return;
}
void PicoAnalogCorrection::calibrateAdc(size_t gnd_pin, size_t vcc_pin, size_t avg_size) {
float gnd_value = .0;
for(size_t i = 0; i < avg_size; i++) {
gnd_value += float(analogRead(gnd_pin));
}
_gnd_offset = gnd_value/avg_size;
float vcc_value = .0;
for(size_t i = 0; i < avg_size; i++) {
vcc_value += float(analogRead(vcc_pin));
}
_vcc_offset = vcc_value/avg_size;
setCorrectionValues();
return;
}
void PicoAnalogCorrection::returnCalibrationValues() {
Serial.println("(" + String(_gnd_offset) + ", " + String(_vcc_offset) + ")");
return;
}
void PicoAnalogCorrection::analogReadResolution(size_t adc_res) {
_adc_res = adc_res;
::analogReadResolution(adc_res);
}
int PicoAnalogCorrection::analogRead(size_t pin) {
digitalWrite(PS_PIN, HIGH); // Disable power-saving
//delayMicroseconds(2); // Cooldown for the converter to stabilize?
int value = ::analogRead(pin); // Use normal Arduino analogRead func
digitalWrite(PS_PIN, LOW); // Re-enable power-saving
return value;
}
int PicoAnalogCorrection::analogCRead(size_t pin, size_t avg_size) {
float value = .0;
for(size_t i = 0; i < avg_size; i++) {
//value += float( map(analogRead(pin), _gnd_offset, _vcc_offset, 0, _max_channel) );
value += float( _a * analogRead(pin) + _d );
}
return round(value/avg_size);
}
float PicoAnalogCorrection::analogReadTemp(pactemp_t type) {
if (!_adc_init) {
adc_init();
_adc_init = true;
}
adc_set_temp_sensor_enabled(true);
delay(1); // Allow things to settle. Without this, readings can be erratic
adc_select_input(4); // Temperature sensor is analog pin 4
int v = adc_read();
adc_set_temp_sensor_enabled(false);
float t = 27.0f - ((v * _vref / pow(2, _adc_res)) - 0.706f) / 0.001721f; // From the datasheet with custom values for ADC res and Vref voltage
if (type == PAC_F) {
return t * 1.8f + 32.0f;
} else {
return t;
}
}