2021-01-29 12:31:58 +01:00
|
|
|
|
|
|
|
[![Arduino CI](https://github.com/RobTillaart/MCP_ADC/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
|
2021-11-08 13:14:13 +01:00
|
|
|
[![Arduino-lint](https://github.com/RobTillaart/MCP_ADC/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/MCP_ADC/actions/workflows/arduino-lint.yml)
|
|
|
|
[![JSON check](https://github.com/RobTillaart/MCP_ADC/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/MCP_ADC/actions/workflows/jsoncheck.yml)
|
2023-09-11 20:03:59 +02:00
|
|
|
[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/MCP_ADC.svg)](https://github.com/RobTillaart/MCP_ADC/issues)
|
|
|
|
|
2021-01-29 12:31:58 +01:00
|
|
|
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/MCP_ADC/blob/master/LICENSE)
|
|
|
|
[![GitHub release](https://img.shields.io/github/release/RobTillaart/MCP_ADC.svg?maxAge=3600)](https://github.com/RobTillaart/MCP_ADC/releases)
|
2023-09-11 20:03:59 +02:00
|
|
|
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/MCP_ADC.svg)](https://registry.platformio.org/libraries/robtillaart/MCP_ADC)
|
2021-01-29 12:31:58 +01:00
|
|
|
|
2021-11-08 13:14:13 +01:00
|
|
|
|
2021-01-29 12:31:58 +01:00
|
|
|
# MCP_ADC
|
|
|
|
|
2023-09-11 20:03:59 +02:00
|
|
|
Arduino library for MCP3001 MCP3002 MCP3004 MCP3008 MCP3201 MCP3202 MCP3204 MCP3208 and compatibles.
|
2021-01-29 12:31:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
## Description
|
|
|
|
|
|
|
|
This library reads the ADC ports of the MCP ADC convertors.
|
2021-07-31 17:43:47 +02:00
|
|
|
The chips are communicates with SPI and support both hardware SPI or optional software SPI.
|
|
|
|
|
|
|
|
|
2023-08-16 10:07:24 +02:00
|
|
|
| type | bits | chan | notes |
|
|
|
|
|:----------|:------:|:------:|:--------|
|
2023-09-11 20:03:59 +02:00
|
|
|
| MCP3001 | 10 | 1 | not tested yet.
|
2023-08-16 10:07:24 +02:00
|
|
|
| MCP3002 | 10 | 2 |
|
|
|
|
| MCP3004 | 10 | 4 |
|
|
|
|
| MCP3008 | 10 | 8 |
|
2023-09-11 20:03:59 +02:00
|
|
|
| MCP3201 | 12 | 1 | test, see #13
|
2023-08-16 10:07:24 +02:00
|
|
|
| MCP3202 | 12 | 2 |
|
|
|
|
| MCP3204 | 12 | 4 |
|
|
|
|
| MCP3208 | 12 | 8 |
|
2021-01-29 12:31:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
Current version allows manual override of the hardware SPI clock as the speed is not
|
|
|
|
optimized per ADC type.
|
|
|
|
|
2021-11-08 13:14:13 +01:00
|
|
|
The MCP ADC allow single mode which compares voltage of a single channel against GND.
|
|
|
|
Furthermore they allow a differential mode which compares two channels **IN+** and **IN-**
|
|
|
|
to each other. if the **IN+** is equal or below **IN-** the ADC will return 0.
|
2021-01-29 12:31:58 +01:00
|
|
|
|
|
|
|
Build into the library is a delta mode which is a software enhanced differential mode.
|
|
|
|
This delta mode can return negative values too.
|
|
|
|
|
|
|
|
|
2023-09-11 20:03:59 +02:00
|
|
|
#### Related
|
|
|
|
|
|
|
|
- https://gammon.com.au/adc tutorial about ADC's (UNO specific)
|
|
|
|
- https://github.com/RobTillaart/ADS1x15 (12 & 16 bit ADC, I2C, slow)
|
|
|
|
- https://github.com/RobTillaart/PCF8591 (8 bit ADC + 1 bit DAC)
|
|
|
|
|
|
|
|
|
|
|
|
- https://github.com/RobTillaart/MCP_DAC
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-01-29 12:31:58 +01:00
|
|
|
## Interface
|
|
|
|
|
2023-08-16 10:07:24 +02:00
|
|
|
```cpp
|
|
|
|
#include "MCP_ADC.h"
|
|
|
|
```
|
|
|
|
|
2023-09-11 20:03:59 +02:00
|
|
|
#### Constructors
|
2023-08-16 10:07:24 +02:00
|
|
|
|
2021-01-29 12:31:58 +01:00
|
|
|
If the pins are not set in the constructor, the class will automatically
|
2023-08-16 10:07:24 +02:00
|
|
|
use the hardware SPI, otherwise it will use software SPI.
|
2021-11-08 13:14:13 +01:00
|
|
|
|
2023-09-11 20:03:59 +02:00
|
|
|
- **MCP3001(uint8_t dataIn, uint8_t dataOut, uint8_t clock)** constructor 10 bit ADC 1 channel.
|
2021-11-08 13:14:13 +01:00
|
|
|
- **MCP3002(uint8_t dataIn, uint8_t dataOut, uint8_t clock)** constructor 10 bit ADC 2 channel.
|
|
|
|
- **MCP3004(uint8_t dataIn, uint8_t dataOut, uint8_t clock)** constructor 10 bit ADC 4 channel.
|
|
|
|
- **MCP3008(uint8_t dataIn, uint8_t dataOut, uint8_t clock)** constructor 10 bit ADC 8 channel.
|
2023-08-16 10:07:24 +02:00
|
|
|
- **MCP3201(uint8_t dataIn, uint8_t dataOut, uint8_t clock)** constructor 12 bit ADC 1 channel.
|
2021-11-08 13:14:13 +01:00
|
|
|
- **MCP3202(uint8_t dataIn, uint8_t dataOut, uint8_t clock)** constructor 12 bit ADC 2 channel.
|
|
|
|
- **MCP3204(uint8_t dataIn, uint8_t dataOut, uint8_t clock)** constructor 12 bit ADC 4 channel.
|
|
|
|
- **MCP3208(uint8_t dataIn, uint8_t dataOut, uint8_t clock)** constructor 12 bit ADC 8 channel.
|
|
|
|
- **void begin(uint8_t select)** set select pin.
|
|
|
|
- **uint8_t channels()** returns the number of channels.
|
2023-09-11 20:03:59 +02:00
|
|
|
- **int16_t maxValue()** returns maxReading of ADC, typical 1023 or 4095.
|
2021-01-29 12:31:58 +01:00
|
|
|
This makes it easy to calculate relative measurements.
|
2023-09-11 20:03:59 +02:00
|
|
|
|
|
|
|
|
|
|
|
#### Base
|
|
|
|
|
2021-11-08 13:14:13 +01:00
|
|
|
- **int16_t analogRead(uint8_t channel)** reads the value of a single channel.
|
2023-08-16 10:07:24 +02:00
|
|
|
- **void analogReadMultiple(uint8_t channels[], uint8_t numChannels, int16_t readings[])**
|
|
|
|
reads multiple channels in one call. See section below.
|
2021-11-08 13:14:13 +01:00
|
|
|
- **int16_t differentialRead(uint8_t channel)** reads differential between two channels.
|
|
|
|
Check datasheet for details.
|
|
|
|
Note if the **IN+** is equal or below **IN-** this function will return 0.
|
|
|
|
- **int16_t deltaRead(uint8_t channel)** reads differential like above however it
|
|
|
|
will return a negative value if **IN+** is below **IN-**.
|
|
|
|
- **void setSPIspeed(uint32_t speed)** sets SPI clock in **Hz**, please read datasheet
|
2021-01-29 12:31:58 +01:00
|
|
|
of the ADC first to get optimal speed.
|
2021-11-08 13:14:13 +01:00
|
|
|
- **uint32_t getSPIspeed()** gets current speed in **Hz**.
|
2021-01-29 12:31:58 +01:00
|
|
|
|
|
|
|
|
2023-08-16 10:07:24 +02:00
|
|
|
### Differential channel table:
|
2021-01-29 12:31:58 +01:00
|
|
|
|
2021-11-08 13:14:13 +01:00
|
|
|
| Channel | diff IN+ | diff IN- | MCP |
|
|
|
|
|:-------:|:--------:|:--------:|---------------:|
|
2021-07-31 17:43:47 +02:00
|
|
|
| 0 | 0 | 1 | 3x02/3x04/3x08 |
|
|
|
|
| 1 | 1 | 0 | 3x02/3x04/3x08 |
|
2021-11-08 13:14:13 +01:00
|
|
|
| 2 | 2 | 3 | 3x04/3x08 |
|
|
|
|
| 3 | 3 | 2 | 3x04/3x08 |
|
|
|
|
| 4 | 4 | 5 | 3x08 |
|
|
|
|
| 5 | 5 | 4 | 3x08 |
|
|
|
|
| 6 | 6 | 7 | 3x08 |
|
|
|
|
| 7 | 7 | 6 | 3x08 |
|
2021-07-31 17:43:47 +02:00
|
|
|
|
2023-09-11 20:03:59 +02:00
|
|
|
Note: the MCP3x01 are not included in this table, not investigated yet.
|
|
|
|
|
2021-07-31 17:43:47 +02:00
|
|
|
|
2023-08-16 10:07:24 +02:00
|
|
|
### Debug
|
2021-07-31 17:43:47 +02:00
|
|
|
|
|
|
|
- **bool usesHWSPI()** returns true if HW SPI is used.
|
2023-08-16 10:07:24 +02:00
|
|
|
- **uint32_t count()** returns number of channels read since start.
|
2021-07-31 17:43:47 +02:00
|
|
|
|
|
|
|
|
|
|
|
### ESP32 specific
|
|
|
|
|
|
|
|
- **void selectHSPI()** in case hardware SPI, the ESP32 has two options HSPI and VSPI.
|
|
|
|
- **void selectVSPI()** see above.
|
|
|
|
- **bool usesHSPI()** returns true if HSPI is used.
|
|
|
|
- **bool usesVSPI()** returns true if VSPI is used.
|
2021-08-01 15:51:21 +02:00
|
|
|
|
|
|
|
The **selectVSPI()** or the **selectHSPI()** needs to be called
|
|
|
|
BEFORE the **begin()** function.
|
|
|
|
|
|
|
|
|
2023-08-16 10:07:24 +02:00
|
|
|
#### setGPIOpins() experimental
|
2021-08-01 15:51:21 +02:00
|
|
|
|
2021-11-08 13:14:13 +01:00
|
|
|
- **void setGPIOpins(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t select)**
|
2023-09-11 20:03:59 +02:00
|
|
|
overrule GPIO pins of ESP32 for hardware SPI.
|
|
|
|
This function needs to be called AFTER the **begin()** function.
|
2021-08-01 15:51:21 +02:00
|
|
|
|
2023-09-11 20:03:59 +02:00
|
|
|
in code:
|
2021-08-01 15:51:21 +02:00
|
|
|
```cpp
|
|
|
|
void setup()
|
|
|
|
{
|
|
|
|
MCP.selectVSPI();
|
|
|
|
MCP.begin(15);
|
2021-11-08 13:14:13 +01:00
|
|
|
MCP.setGPIOpins(CLK, MISO, MOSI, SELECT); // SELECT should match the parameter of begin()
|
2021-08-01 15:51:21 +02:00
|
|
|
}
|
|
|
|
```
|
2021-01-29 12:31:58 +01:00
|
|
|
|
2021-11-08 13:14:13 +01:00
|
|
|
This implementation might change in the future, e.g. leave out the select pin as it is
|
|
|
|
already known in the code.
|
|
|
|
|
2021-01-29 12:31:58 +01:00
|
|
|
|
2021-04-07 13:31:22 +02:00
|
|
|
## About SPI Speed
|
|
|
|
|
|
|
|
See https://github.com/RobTillaart/MCP_ADC/issues/3
|
|
|
|
|
|
|
|
The default SPI speed is reduced to 1 MHz.
|
|
|
|
This is the value recommended in the datasheet for 2.7V.
|
|
|
|
|
|
|
|
In a test with an ESP32 (3.3V) the library showed stable results
|
2021-12-21 15:31:31 +01:00
|
|
|
at 4 MHz and at 6 MHz it was almost good.
|
2021-04-07 13:31:22 +02:00
|
|
|
|
2023-08-16 10:07:24 +02:00
|
|
|
The maximum value read at 6 MHz was 1020 instead of 1023 (MCP3008)
|
|
|
|
which indicates that the last 2 bits got lost probably due to signal
|
|
|
|
deformation.
|
|
|
|
|
|
|
|
| Board | Voltage | safe | max |
|
|
|
|
|:-------:|:---------:|:-------:|:-------:|
|
|
|
|
| ESP32 | 2.7V | 1 MHz | 4 MHz |
|
|
|
|
| UNO | 5.0V | 2 MHz | 4 MHz |
|
2021-04-07 13:31:22 +02:00
|
|
|
|
|
|
|
|
|
|
|
For hardware SPI the ESP32 uses the VSPI pins. (see ESP examples).
|
|
|
|
|
|
|
|
|
2023-08-16 10:07:24 +02:00
|
|
|
## analogReadMultiple()
|
|
|
|
|
|
|
|
Since version 0.2.0 the **analogReadMultiple(channels[], numChannels, readings[])**
|
|
|
|
is added to the interface.
|
|
|
|
(See https://github.com/RobTillaart/MCP_ADC/pull/11 - Thanks to Alex Uta).
|
|
|
|
|
|
|
|
This function allows to read multiple channels in one call, which improves
|
|
|
|
the performance of fetching new readings from the MCP_ADC device.
|
|
|
|
The amount of gain differs per platform, so run your own performance test.
|
|
|
|
|
|
|
|
Besides fetching all ADC's in one call this function also allows to fetch
|
|
|
|
the data from a specific channel multiple times, e.g. to be averaged.
|
|
|
|
Other patterns are possible.
|
|
|
|
These scenarios need still to be tested in practice.
|
2022-11-17 13:00:17 +01:00
|
|
|
|
2023-08-16 10:07:24 +02:00
|
|
|
Finally **analogReadMultiple()** can be used to read only one channel too
|
|
|
|
by using numChannels = 1.
|
|
|
|
|
|
|
|
|
2023-09-11 20:03:59 +02:00
|
|
|
## MCP3001, MCP3201 experimental
|
2023-08-16 10:07:24 +02:00
|
|
|
|
2023-09-11 20:03:59 +02:00
|
|
|
Since 0.2.0 code for the MCP3201 has been added.
|
|
|
|
The first tests are done (see #13) which showed that the 0.2.0 implementation
|
|
|
|
was not correct.
|
|
|
|
This has been fixed in the 0.2.1 version.
|
2023-08-16 10:07:24 +02:00
|
|
|
|
2023-09-11 20:03:59 +02:00
|
|
|
Note that not all function calls make sense for the MCP3201 and MCP3001 as these
|
|
|
|
devices only have one channel. So use the library carefully.
|
2023-08-16 10:07:24 +02:00
|
|
|
|
|
|
|
Feedback is as always welcome.
|
2022-11-17 13:00:17 +01:00
|
|
|
|
|
|
|
|
2021-12-21 15:31:31 +01:00
|
|
|
## Future
|
2021-01-29 12:31:58 +01:00
|
|
|
|
2023-08-16 10:07:24 +02:00
|
|
|
#### Must
|
|
|
|
|
|
|
|
- improve documentation
|
|
|
|
- test analogReadMultiple() scenario's
|
|
|
|
- MCP3201 buy hardware and test
|
2022-11-17 13:00:17 +01:00
|
|
|
|
2023-08-16 10:07:24 +02:00
|
|
|
#### Should
|
2022-11-17 13:00:17 +01:00
|
|
|
|
2023-08-16 10:07:24 +02:00
|
|
|
- improve SWSPI for AVR
|
|
|
|
(code is under test for MCP23S17)
|
2022-11-17 13:00:17 +01:00
|
|
|
|
|
|
|
|
2023-08-16 10:07:24 +02:00
|
|
|
#### Could
|
2021-04-07 13:31:22 +02:00
|
|
|
|
2021-01-29 12:31:58 +01:00
|
|
|
|
2023-08-16 10:07:24 +02:00
|
|
|
#### Wont
|
2021-12-21 15:31:31 +01:00
|
|
|
|
|
|
|
- get / setF(float A, float B) => float readF(channel) output = A\*value + B;
|
|
|
|
it actually does float mapping. As it implies the same mapping for all it might
|
2023-08-16 10:07:24 +02:00
|
|
|
not be that useful => check multiMap library.
|
2021-12-21 15:31:31 +01:00
|
|
|
|
2023-09-11 20:03:59 +02:00
|
|
|
|
|
|
|
## Support
|
|
|
|
|
|
|
|
If you appreciate my libraries, you can support the development and maintenance.
|
|
|
|
Improve the quality of the libraries by providing issues and Pull Requests, or
|
|
|
|
donate through PayPal or GitHub sponsors.
|
|
|
|
|
|
|
|
Thank you,
|
|
|
|
|