Skip to content

Commit 941f29e

Browse files
allow custom ADC resolutions
1 parent 4e79022 commit 941f29e

File tree

5 files changed

+27
-24
lines changed

5 files changed

+27
-24
lines changed

PicoAnalogCorrection.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
#include "PicoAnalogCorrection.h"
77

88

9-
PicoAnalogCorrection::PicoAnalogCorrection(int gnd_val, int vcc_val) {
9+
PicoAnalogCorrection::PicoAnalogCorrection(size_t adc_res, size_t gnd_val, size_t vcc_val) {
10+
_max_channel = pow(2, adc_res) - 1;
1011
_gnd_offset = gnd_val;
1112
_vcc_offset = vcc_val;
1213
setCorrectionValues();
@@ -17,7 +18,7 @@ void PicoAnalogCorrection::setCorrectionValues() {
1718
if(_vcc_offset == 0) {
1819
_a = 1.0;
1920
} else {
20-
_a = 4095.0 / (_vcc_offset - _gnd_offset);
21+
_a = _max_channel / (_vcc_offset - _gnd_offset);
2122
}
2223
_d = - _a * _gnd_offset;
2324
return;
@@ -26,19 +27,19 @@ void PicoAnalogCorrection::setCorrectionValues() {
2627

2728
void PicoAnalogCorrection::calibrateAdc(size_t gnd_pin, size_t vcc_pin, size_t avg_size) {
2829
float gnd_value = .0;
29-
30+
3031
for(size_t i = 0; i < avg_size; i++) {
3132
gnd_value += float(analogRead(gnd_pin));
3233
}
3334
_gnd_offset = gnd_value/avg_size;
34-
35+
3536
float vcc_value = .0;
36-
37+
3738
for(size_t i = 0; i < avg_size; i++) {
3839
vcc_value += float(analogRead(vcc_pin));
3940
}
4041
_vcc_offset = vcc_value/avg_size;
41-
42+
4243
setCorrectionValues();
4344
return;
4445
}
@@ -53,23 +54,22 @@ void PicoAnalogCorrection::returnCalibrationValues() {
5354
int PicoAnalogCorrection::analogRead(size_t pin) {
5455
digitalWrite(PS_PIN, HIGH); // Disable power-saving
5556
delayMicroseconds(2); // Cooldown, maybe useless?
56-
57+
5758
int value = ::analogRead(pin); // Use normal Arduino analogRead func
58-
59+
5960
digitalWrite(PS_PIN, LOW); // Re-enable power-saving
60-
61+
6162
return value;
6263
}
6364

6465

6566
int PicoAnalogCorrection::analogCRead(size_t pin, size_t avg_size) {
6667
float value = .0;
67-
68+
6869
for(size_t i = 0; i < avg_size; i++) {
69-
//value += float( map(analogRead(pin), _gnd_offset, _vcc_offset, 0, 4095) );
70+
//value += float( map(analogRead(pin), _gnd_offset, _vcc_offset, 0, _max_channel) );
7071
value += float( _a * analogRead(pin) + _d );
7172
}
72-
73+
7374
return round(value/avg_size);
7475
}
75-

PicoAnalogCorrection.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@
1414

1515
class PicoAnalogCorrection {
1616
private:
17-
int _gnd_offset, _vcc_offset;
17+
int _max_channel, _gnd_offset, _vcc_offset;
1818
float _a, _d;
19-
19+
2020
void setCorrectionValues();
21-
21+
2222
public:
23-
PicoAnalogCorrection(int gnd_val=0, int vcc_val=0);
24-
23+
PicoAnalogCorrection(size_t adc_res=12, size_t gnd_val=0, size_t vcc_val=0);
24+
2525
void calibrateAdc(size_t gnd_pin, size_t vcc_pin, size_t avg_size=100);
2626
void returnCalibrationValues();
27-
27+
2828
int analogRead(size_t pin);
2929
int analogCRead(size_t pin, size_t avg_size=1);
3030
};

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Both of these temporarily disable the power-saving mode to improve noise. Only t
2727
2828
## Limitations
2929
30-
This library is limited to a very simple linear calibration since there are practically only two trusted voltages available to be measured: GND (0V) and VCC (3.3V). This means that the calibration will ensure that the ADC measures GND as 0 and VCC as 4095 with any value in between beeing distributed linearly within these two.
30+
This library is limited to a very simple linear calibration since there are practically only two trusted voltages available to be measured: GND (0V) and VCC (3.3V). This means that the calibration will ensure that the ADC measures GND as 0 and VCC as the maximum channel number (depending on your resolution, e.g. 4095) with any value in between being distributed linearly within these two.
3131
3232
In addition, as the very helpful [Raspberry Pi Pico datasheet](https://datasheets.raspberrypi.com/pico/pico-datasheet.pdf) suggests, the on-board power supply noise and accuracy are not the best. To get the best results possible, you need to use an external voltage reference. This, however, introduces additonal drawbacks.
3333

examples/SimpleCalibration/SimpleCalibration.ino

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,24 @@
99
* Serial Monitor. Paste them into the
1010
* PicoAnalogCorrection constructor and you're done.
1111
*
12-
* MIT, 2021, Phoenix1747
12+
* You can also define a custom ADC resolution.
13+
*
14+
* MIT, 2022, Phoenix1747
1315
*/
1416

1517
#include <PicoAnalogCorrection.h>
1618

1719
const uint8_t GND_PIN = A1; // GND meas pin
1820
const uint8_t VCC_PIN = A0; // VCC meas pin
21+
const uint8_t ADC_RES = 12; // ADC bits
1922

20-
PicoAnalogCorrection pico;
23+
PicoAnalogCorrection pico(ADC_RES);
2124

2225
void setup() {
2326
pinMode(GND_PIN, INPUT);
2427
pinMode(VCC_PIN, INPUT);
2528

26-
analogReadResolution(12); // 12-bit ADC, 4096 channels
29+
analogReadResolution(ADC_RES);
2730

2831
// Calibrate ADC using an average of 5000 measurements
2932
pico.calibrateAdc(GND_PIN, VCC_PIN, 5000);

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=PicoAnalogCorrection
2-
version=1.1.3
2+
version=1.2.0
33
author=Phoenix1747
44
maintainer=Phoenix1747
55
sentence=Arduino library to calibrate and improve ADC measurements with the Raspberry Pi Pico.

0 commit comments

Comments
 (0)