Skip to content

Commit

Permalink
fix #18, rename analogRead() to read() (#19)
Browse files Browse the repository at this point in the history
- fix #18, support for Arduino ESP32 S3 - breaking change
- update examples
- Fix #17, readme.md
  • Loading branch information
RobTillaart committed Dec 18, 2023
1 parent 23c1042 commit f04d43c
Show file tree
Hide file tree
Showing 14 changed files with 121 additions and 117 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.4.0] - 2023-12-18
- fix #18, support for Arduino ESP32 S3 - breaking change
- update examples
- Fix #17, readme.md

----

## [0.3.0] - 2023-11-29
- refactor constructor interface - breaking changes.
- minimize conditional code. -- create SPI_CLASS macro to solve it.
Expand Down
6 changes: 3 additions & 3 deletions MCP_ADC.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// FILE: MCP_ADC.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.3.0
// VERSION: 0.4.0
// DATE: 2019-10-24
// PURPOSE: Arduino library for MCP3001, MCP3002, MCP3004, MCP3008, MCP3201, MCP3202, MCP3204, MCP3208
// URL: https://github.com/RobTillaart/MCP_ADC
Expand Down Expand Up @@ -80,14 +80,14 @@ uint32_t MCP_ADC::count()
}


int16_t MCP_ADC::analogRead(uint8_t channel)
int16_t MCP_ADC::read(uint8_t channel)
{
if (channel >= _channels) return 0;
return readADC(channel, true);
}


void MCP_ADC::analogReadMultiple(uint8_t channels[], uint8_t numChannels, int16_t readings[])
void MCP_ADC::readMultiple(uint8_t channels[], uint8_t numChannels, int16_t readings[])
{
readADCMultiple(channels, numChannels, readings);
}
Expand Down
28 changes: 17 additions & 11 deletions MCP_ADC.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,24 @@
//
// FILE: MCP_ADC.h
// AUTHOR: Rob Tillaart
// VERSION: 0.3.0
// VERSION: 0.4.0
// DATE: 2019-10-24
// PURPOSE: Arduino library for MCP3001, MCP3002, MCP3004, MCP3008, MCP3201, MCP3202, MCP3204, MCP3208
// URL: https://github.com/RobTillaart/MCP_ADC
//


// #if defined(BOARD_HAS_PIN_REMAP) && !defined(BOARD_USES_HW_GPIO_NUMBERS)
// #error please read readme.md for Arduino NANO ESP32 bug
// #endif


#include "Arduino.h"
#include "SPI.h"


#define MCP_ADC_LIB_VERSION (F("0.3.0"))
#define MCP_ADC_LIB_VERSION (F("0.4.0"))


#ifndef __SPI_CLASS__
#if defined(ARDUINO_ARCH_RP2040)
Expand All @@ -37,8 +43,8 @@ class MCP_ADC
uint8_t channels();
int16_t maxValue();

int16_t analogRead(uint8_t channel);
void analogReadMultiple(uint8_t channels[], uint8_t numChannels, int16_t readings[]);
int16_t read(uint8_t channel);
void readMultiple(uint8_t channels[], uint8_t numChannels, int16_t readings[]);
int16_t differentialRead(uint8_t channel);
int16_t deltaRead(uint8_t channel);

Expand Down Expand Up @@ -94,7 +100,7 @@ class MCP3002 : public MCP_ADC
{
public:
MCP3002(__SPI_CLASS__ * mySPI = &SPI);
MCP3002(uint8_t dataIn, uint8_t dataOut, uint8_t clock);
MCP3002(uint8_t dataIn, uint8_t dataOut, uint8_t clock);
uint8_t buildRequest(uint8_t channel, bool single, uint8_t * data);
};

Expand All @@ -103,7 +109,7 @@ class MCP3004 : public MCP_ADC
{
public:
MCP3004(__SPI_CLASS__ * mySPI = &SPI);
MCP3004(uint8_t dataIn, uint8_t dataOut, uint8_t clock);
MCP3004(uint8_t dataIn, uint8_t dataOut, uint8_t clock);
uint8_t buildRequest(uint8_t channel, bool single, uint8_t * data);
};

Expand All @@ -112,7 +118,7 @@ class MCP3008 : public MCP_ADC
{
public:
MCP3008(__SPI_CLASS__ * mySPI = &SPI);
MCP3008(uint8_t dataIn, uint8_t dataOut, uint8_t clock);
MCP3008(uint8_t dataIn, uint8_t dataOut, uint8_t clock);
uint8_t buildRequest(uint8_t channel, bool single, uint8_t * data);
};

Expand All @@ -121,7 +127,7 @@ class MCP3201 : public MCP_ADC
{
public:
MCP3201(__SPI_CLASS__ * mySPI = &SPI);
MCP3201(uint8_t dataIn, uint8_t dataOut, uint8_t clock);
MCP3201(uint8_t dataIn, uint8_t dataOut, uint8_t clock);
uint8_t buildRequest(uint8_t channel, bool single, uint8_t * data);
};

Expand All @@ -130,7 +136,7 @@ class MCP3202 : public MCP_ADC
{
public:
MCP3202(__SPI_CLASS__ * mySPI = &SPI);
MCP3202(uint8_t dataIn, uint8_t dataOut, uint8_t clock);
MCP3202(uint8_t dataIn, uint8_t dataOut, uint8_t clock);
uint8_t buildRequest(uint8_t channel, bool single, uint8_t * data);
};

Expand All @@ -139,7 +145,7 @@ class MCP3204 : public MCP_ADC
{
public:
MCP3204(__SPI_CLASS__ * mySPI = &SPI);
MCP3204(uint8_t dataIn, uint8_t dataOut, uint8_t clock);
MCP3204(uint8_t dataIn, uint8_t dataOut, uint8_t clock);
uint8_t buildRequest(uint8_t channel, bool single, uint8_t * data);
};

Expand All @@ -148,7 +154,7 @@ class MCP3208 : public MCP_ADC
{
public:
MCP3208(__SPI_CLASS__ * mySPI = &SPI);
MCP3208(uint8_t dataIn, uint8_t dataOut, uint8_t clock);
MCP3208(uint8_t dataIn, uint8_t dataOut, uint8_t clock);
uint8_t buildRequest(uint8_t channel, bool single, uint8_t * data);
};

Expand Down
123 changes: 57 additions & 66 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,53 @@ Arduino library for MCP3001 MCP3002 MCP3004 MCP3008 MCP3201 MCP3202 MCP3204 MCP3
## Description

This library reads the ADC ports of the MCP ADC convertors.
The chips are communicates with SPI and support both hardware SPI or optional software SPI.
The chips are 1 to 8 channels, 10 or 12 bit and communicates with SPI.
The library supports both hardware SPI and software SPI.


| type | bits | chan | notes |
|:----------|:------:|:------:|:--------|
| MCP3001 | 10 | 1 | not tested yet.
| MCP3002 | 10 | 2 |
| MCP3004 | 10 | 4 |
| MCP3008 | 10 | 8 |
| MCP3201 | 12 | 1 | test, see #13
| MCP3202 | 12 | 2 |
| MCP3204 | 12 | 4 |
| MCP3208 | 12 | 8 |
| type | bits | channels | notes |
|:----------|:------:|:----------:|:--------|
| MCP3001 | 10 | 1 | not tested yet.
| MCP3002 | 10 | 2 |
| MCP3004 | 10 | 4 |
| MCP3008 | 10 | 8 |
| MCP3201 | 12 | 1 | test, see #13
| MCP3202 | 12 | 2 |
| MCP3204 | 12 | 4 |
| MCP3208 | 12 | 8 |


Current version allows manual override of the hardware SPI clock as the speed is not
optimized per ADC type.

The MCP ADC allow single mode which compares voltage of a single channel against GND.
The MCP ADC's allow a single mode read 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.
to each other.
If the **IN+** is equal or below **IN-** the ADC will return 0.

Build into the library is a delta mode which is a software enhanced differential mode.
This delta mode can return negative values too.


#### 0.4.0 Breaking change

The version 0.4.0 has breaking changes in the interface.
The rationale is that the programming environment of the **Arduino ESP32 S3**
board uses a remapping by means of the include file **io_pin_remap.h**.
This file remaps the pins of several core Arduino functions.
The remapping is implemented by #define macros and these implement "hard" text
replacements without considering context.
The effect is that methods from this class (and several others) which have the same
name as those Arduino core functions will be remapped into something not working.

The following library functions have been renamed:

| old name | new name | notes |
|:----------------------|:-----------------|:--------|
| analogRead() | read() | bugfix.
| analogReadMultiple() | readMultiple() | for consistency.


#### 0.3.0 Breaking change

The version 0.3.0 has breaking changes in the interface.
Expand Down Expand Up @@ -88,8 +109,8 @@ This makes it easy to calculate relative measurements.

#### Base

- **int16_t analogRead(uint8_t channel)** reads the value of a single channel.
- **void analogReadMultiple(uint8_t channels[], uint8_t numChannels, int16_t readings[])**
- **int16_t read(uint8_t channel)** reads the value of a single channel.
- **void readMultiple(uint8_t channels[], uint8_t numChannels, int16_t readings[])**
reads multiple channels in one call. See section below.
- **int16_t differentialRead(uint8_t channel)** reads differential between two channels.
Check datasheet for details.
Expand All @@ -103,68 +124,38 @@ of the ADC first to get optimal speed.

### Differential channel table:

| Channel | diff IN+ | diff IN- | MCP |
|:-------:|:--------:|:--------:|---------------:|
| 0 | 0 | 1 | 3x02/3x04/3x08 |
| 1 | 1 | 0 | 3x02/3x04/3x08 |
| 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 |

Note: the MCP3x01 are not included in this table, not investigated yet.


### Debug
| Channel | diff IN+ | diff IN- | 3x02 | 3x04 | 3x08 |
|:-------:|:--------:|:--------:|:----:|:----:|:----:|
| 0 | 0 | 1 | V | V | V |
| 1 | 1 | 0 | V | V | V |
| 2 | 2 | 3 | | V | V |
| 3 | 3 | 2 | | V | V |
| 4 | 4 | 5 | | | V |
| 5 | 5 | 4 | | | V |
| 6 | 6 | 7 | | | V |
| 7 | 7 | 6 | | | V |

- **bool usesHWSPI()** returns true if HW SPI is used.
- **uint32_t count()** returns number of channels read since start.

Note: the MCP3x01 ADC's are not included in this table, not investigated yet.

### 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.

The **selectVSPI()** or the **selectHSPI()** needs to be called
BEFORE the **begin()** function.


#### setGPIOpins() experimental

- **void setGPIOpins(uint8_t clk, uint8_t miso, uint8_t mosi, uint8_t select)**
overrule GPIO pins of ESP32 for hardware SPI.
This function needs to be called AFTER the **begin()** function.

in code:
```cpp
void setup()
{
MCP.selectVSPI();
MCP.begin(15);
MCP.setGPIOpins(CLK, MISO, MOSI, SELECT); // SELECT should match the parameter of begin()
}
```
### Debug

This implementation might change in the future, e.g. leave out the select pin as it is
already known in the code.
- **bool usesHWSPI()** returns true if hardware SPI is used.
- **uint32_t count()** returns number of channels reads since start.


## 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.
This is the value recommended in the datasheet for 2.7 Volt.

In a test with an ESP32 (3.3V) the library showed stable results
at 4 MHz and at 6 MHz it was almost good.

The maximum value read at 6 MHz was 1020 instead of 1023 (MCP3008)
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.

Expand All @@ -177,9 +168,9 @@ deformation.
For hardware SPI the ESP32 uses the VSPI pins. (see ESP examples).


## analogReadMultiple()
## ReadMultiple()

Since version 0.2.0 the **analogReadMultiple(channels[], numChannels, readings[])**
Since version 0.2.0 the **readMultiple(channels[], numChannels, readings[])**
is added to the interface.
(See https://github.com/RobTillaart/MCP_ADC/pull/11 - Thanks to Alex Uta).

Expand All @@ -192,7 +183,7 @@ 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.

Finally **analogReadMultiple()** can be used to read only one channel too
Finally **readMultiple()** can be used to read only one channel too
by using numChannels = 1.


Expand All @@ -204,7 +195,7 @@ was not correct.
This has been fixed in the 0.2.1 version.

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.
devices only have one channel. So use the library carefully with these ADC's.

Feedback is as always welcome.

Expand All @@ -214,7 +205,7 @@ Feedback is as always welcome.
#### Must

- improve documentation
- test analogReadMultiple() scenario's
- test readMultiple() scenario's
- MCP3201 buy hardware and test

#### Should
Expand Down
4 changes: 2 additions & 2 deletions examples/MCP3002_analogRead/MCP3002_analogRead.ino
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ void loop()
Serial.print("mcp1:\t");
for (int channel = 0 ; channel < mcp1.channels(); channel++)
{
uint16_t val = mcp1.analogRead(channel);
uint16_t val = mcp1.read(channel);
Serial.print(val);
Serial.print("\t");
}
Serial.println();
Serial.print("mcp2:\t");
for (int channel = 0 ; channel < mcp2.channels(); channel++)
{
uint16_t val = mcp2.analogRead(channel);
uint16_t val = mcp2.read(channel);
Serial.print(val);
Serial.print("\t");
}
Expand Down
4 changes: 2 additions & 2 deletions examples/MCP3008_analogRead/MCP3008_analogRead.ino
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ void loop()
Serial.print("mcp1:\t");
for (int channel = 0 ; channel < mcp1.channels(); channel++)
{
uint16_t val = mcp1.analogRead(channel);
uint16_t val = mcp1.read(channel);
Serial.print(val);
Serial.print("\t");
}
Serial.println();
Serial.print("mcp2:\t");
for (int channel = 0 ; channel < mcp2.channels(); channel++)
{
uint16_t val = mcp2.analogRead(channel);
uint16_t val = mcp2.read(channel);
Serial.print(val);
Serial.print("\t");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void loop()
Serial.print("\tmcp1:\t");
for (int channel = 0 ; channel < mcp1.channels(); channel++)
{
uint16_t val = mcp1.analogRead(channel);
uint16_t val = mcp1.read(channel);
Serial.print(val);
Serial.print("\t");
delay(1); // added so single reads are better visible on a scope
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ void loop()
Serial.print("\tmcp1:\t");
for (int channel = 0 ; channel < mcp1.channels(); channel++)
{
uint16_t val = mcp1.analogRead(channel);
uint16_t val = mcp1.read(channel);
Serial.print(val);
Serial.print("\t");
delay(1); // added so single reads are better visible on a scope
Expand Down
Loading

0 comments on commit f04d43c

Please sign in to comment.