Skip to content

Commit

Permalink
refactor API, begin() (#33)
Browse files Browse the repository at this point in the history
- refactor API, begin()
- update readme.md
- add **uint8_t getAddress()**
- update examples
- fix **MCP4725_voltage.ino** example
- minor edits
  • Loading branch information
RobTillaart authored Dec 8, 2023
1 parent fef0925 commit 485874d
Show file tree
Hide file tree
Showing 18 changed files with 154 additions and 365 deletions.
13 changes: 11 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,18 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.3.8] - 2023-09-25
- add Wire1 support for ESP32
## [0.4.0] - 2023-12-08
- refactor API, begin()
- update readme.md
- add **uint8_t getAddress()**
- update examples
- fix **MCP4725_voltage.ino** example
- minor edits

----

## [0.3.9] - 2023-09-25
- add Wire1 support for ESP32

## [0.3.8] - 2023-09-18
- fix #30 Voltage functions (wrapper).
Expand Down
54 changes: 9 additions & 45 deletions MCP4725.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// FILE: MCP4725.cpp
// AUTHOR: Rob Tillaart
// PURPOSE: Arduino library for 12 bit I2C DAC - MCP4725
// VERSION: 0.3.9
// VERSION: 0.4.0
// URL: https://github.com/RobTillaart/MCP4725


Expand All @@ -29,51 +29,9 @@ MCP4725::MCP4725(const uint8_t deviceAddress, TwoWire *wire)
}


#if defined(ESP8266) || defined(ESP32)

bool MCP4725::begin(const uint8_t dataPin, const uint8_t clockPin)
{
if ((dataPin < 255) && (clockPin < 255))
{
_wire->begin(dataPin, clockPin);
} else {
_wire->begin();
}
if (isConnected())
{
_lastValue = readDAC();
_powerDownMode = readPowerDownModeDAC();
return true;
}
return false;
}

#endif


#if defined (ARDUINO_ARCH_RP2040)

bool MCP4725::begin(int sda, int scl)
{
_wire->setSDA(sda);
_wire->setSCL(scl);
_wire->begin();

if (isConnected())
{
_lastValue = readDAC();
_powerDownMode = readPowerDownModeDAC();
return true;
}
return false;
}

#endif


bool MCP4725::begin()
{
_wire->begin();
if ((_deviceAddress < 0x60) || (_deviceAddress > 0x67)) return false;
if (! isConnected()) return false;

_lastValue = readDAC();
Expand All @@ -89,9 +47,15 @@ bool MCP4725::isConnected()
}


uint8_t MCP4725::getAddress()
{
return _deviceAddress;
}


int MCP4725::setValue(const uint16_t value)
{
if (value == _lastValue) return 0;
if (value == _lastValue) return MCP4725_OK;
if (value > MCP4725_MAXVALUE) return MCP4725_VALUE_ERROR;
int rv = _writeFastMode(value);
if (rv == 0) _lastValue = value;
Expand Down
20 changes: 4 additions & 16 deletions MCP4725.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@
// FILE: MCP4725.h
// AUTHOR: Rob Tillaart
// PURPOSE: Arduino library for 12 bit I2C DAC - MCP4725
// VERSION: 0.3.9
// VERSION: 0.4.0
// URL: https://github.com/RobTillaart/MCP4725
//


#include "Wire.h"
#include "Arduino.h"


#define MCP4725_VERSION (F("0.3.9"))
#define MCP4725_VERSION (F("0.4.0"))


// CONSTANTS
Expand All @@ -38,23 +37,12 @@
class MCP4725
{
public:
// address = 0x60..0x67
explicit MCP4725(const uint8_t deviceAddress, TwoWire *wire = &Wire);

#if defined(ESP8266) || defined(ESP32)

bool begin(const uint8_t dataPin, const uint8_t clockPin);

#endif

#if defined (ARDUINO_ARCH_RP2040)

bool begin(int sda, int scl);

#endif

bool begin();
bool isConnected();

uint8_t getAddress();

// uses writeFastMode
int setValue(const uint16_t value = 0);
Expand Down
36 changes: 30 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,22 @@ The output of the MCP4725 depends on the voltage supplied, which is in the range
of 2.7V .. 5.5V. Check datasheet for the details.


#### 0.4.0 Breaking change

Version 0.4.0 introduced a breaking change.
You cannot set the pins in **begin()** any more.
This reduces the dependency of processor dependent Wire implementations.
The user has to call **Wire.begin()** and can optionally set the Wire pins
before calling **begin()**.


#### Related

- https://github.com/RobTillaart/AD56x8 (multi channel)
- https://github.com/RobTillaart/AD568X (single channel lower resolution)
- https://github.com/RobTillaart/MCP_DAC (SPI interface)


## Interface

```cpp
Expand All @@ -33,11 +49,11 @@ of 2.7V .. 5.5V. Check datasheet for the details.
### Constructor

- **MCP4725(uint8_t deviceAddress, TwoWire \*wire = &Wire)** Constructor, needs I2C address, optional set Wire bus
- **bool begin(uint8_t dataPin, uint8_t clockPin)** for ESP32. Returns true if connected.
- **bool begin()** for UNO and other boards with hard wired I2C pins.
- **bool begin()** initializes internals.
Returns false if address out of range.
Returns true if deviceAddress can be found on the I2C bus.
- **bool isConnected()** returns true if device (address) can be seen on the I2C bus.

- **uint8_t getAddress())** returns address set in constructor.

### Base

Expand Down Expand Up @@ -71,12 +87,13 @@ If one know the specific timing of a sensor one can tune this or even make it ad
(Since 0.3.8)
Assumes linear behaviour over 12 bit from 0..4095 == 0 .. maxVoltage.
The default value is 5.0 volt.
Allows sort of calibration e.g. setting maxVoltage to 4.9 Volt.
Allows sort of calibration e.g. setting maxVoltage to 4.952 Volt.
Furthermore it can be a preferred interface over percentage and raw values.

- **void setMaxVoltage(float v = 5.0)** configures maximum voltage of Vout.
- **float getMaxVoltage()** return set maximum.
- **void setVoltage(float v)** set the DAC to voltage v.
This maps the voltage to 0..4095 and calls **setValue()**
- **float getVoltage()** get the current setting as a voltage

If this behaviour is not precise enough or should be more "complex" the user can
Expand Down Expand Up @@ -121,7 +138,7 @@ MCP4725A3T-E/CH: 0110 011U 0x66 - 0x67
```

If one need more DAC's one might have a look at the MCP4728
It has 4 channels per chip (no experience /library yet)
It has 4 channels per chip (no experience / library yet)


#### RP2040 specific
Expand Down Expand Up @@ -168,7 +185,7 @@ Note that other multiplexers do exist.
Need to do more tests to see how this solution behaves in practice.
Verified to work - see https://forum.arduino.cc/t/using-digital-pins-to-control-two-mcp4725-modules/1161482/7.

The assumption here is that the devices are all from the same address range.
The assumption here is that the devices are all from the same address range (factory bits).

You can control multiple MCP4725 over the hardware I2C bus with an extra IO pin per device.
- Connect the address pin of every MCP4725 to an IO pin which will work as a **SELECT** pin.
Expand All @@ -188,11 +205,18 @@ You can control multiple MCP4725 over the hardware I2C bus with an extra IO pin

- test the powerDown modes / functions.
- test A0 (address bit) as SELECT pin.
- optimize
- voltage interface uses float divisions => store reciprocate?
- takes 2 extra floats.

#### Could

- extend unit tests

#### Wont

- MCP4725_VERSION ==> MCP4725_LIB_VERSION


## Support

Expand Down
9 changes: 5 additions & 4 deletions examples/MCP4725_minimal/MCP4725_minimal.ino
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,24 @@
// FILE: mcp4725_minimal.ino
// AUTHOR: Rob Tillaart
// PURPOSE: Minimal sketch MCP4725 (#29)
// DATE: 2023-09-13
// URL: https://github.com/RobTillaart/MCP4725


#include "Wire.h"
#include "MCP4725.h"

MCP4725 MCP(0x62); // 0x62 or 0x63
MCP4725 MCP(0x62);


void setup()
{
Serial.begin(115200);

Serial.print("MCP4725 test program: ");
Serial.println(__FILE__);
Serial.print("MCP4725_VERSION: ");
Serial.println(MCP4725_VERSION);

Wire.begin();

MCP.begin();
MCP.setValue(1000);

Expand Down
11 changes: 6 additions & 5 deletions examples/MCP4725_wave_generator/MCP4725_wave_generator.ino
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// FILE: MCP4725_wave_generator.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo function generators
// DATE: 2021-01-07
// URL: https://github.com/RobTillaart/FunctionGenerator
//
// depending on the platform, the range of "smooth" sinus is limited.
Expand Down Expand Up @@ -42,17 +41,19 @@ uint16_t sine[361];
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("MCP4725_VERSION: ");
Serial.println(MCP4725_VERSION);

Wire.begin();
// Wire.setClock(3400000);

// fill table
for (int i = 0; i < 361; i++)
{
sine[i] = 2047 + round(2047 * sin(i * PI / 180));
}

Wire.begin();
// ESP32
// MCP.begin(27, 26);
// Wire.setClock(3400000);
MCP.begin();
Wire.setClock(800000);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// FILE: MCP4725_wave_generator_RP2040.ino
// AUTHOR: Rob Tillaart / Intubun
// PURPOSE: demo function generators
// DATE: 2021-01-07
// URL: https://github.com/RobTillaart/FunctionGenerator
//
// depending on the platform, the range of "smooth" sinus is limited.
Expand Down Expand Up @@ -42,14 +41,21 @@ uint16_t sine[361];
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("MCP4725_VERSION: ");
Serial.println(MCP4725_VERSION);

// Wire.setSDA(16); // adjust if needed
// Wire.setSCL(17);
Wire.begin();

// fill table
for (int i = 0; i < 361; i++)
{
sine[i] = 2047 + round(2047 * sin(i * PI / 180));
}

MCP.begin(26, 27);
MCP.begin();
Wire1.setClock(800000);

MCP.setValue(0);
Expand Down Expand Up @@ -155,9 +161,9 @@ void setup()
break;
default:
case 's':
// reference
// float f = ((PI * 2) * t)/period;
// MCP.setValue(2047 + 2047 * sin(f));
// reference
// float f = ((PI * 2) * t)/period;
// MCP.setValue(2047 + 2047 * sin(f));
//
int idx = (360 * t) / period;
MCP.setValue(sine[idx]); // fetch from lookup table
Expand All @@ -172,4 +178,4 @@ void loop()
}


// -- END OF FILE --
// -- END OF FILE --
7 changes: 4 additions & 3 deletions examples/mcp4725_isConnected/mcp4725_isConnected.ino
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// FILE: mcp4725_isConnected.ino
// AUTHOR: Rob Tillaart
// PURPOSE: test mcp4725 lib
// DATE: 2020-12-26
// URL: https://github.com/RobTillaart/MCP4725
//
// test to see behaviour when sensor is not connected and reconnected again. E.g. loose wires..
Expand All @@ -11,18 +10,20 @@
#include "Wire.h"
#include "MCP4725.h"

MCP4725 MCP(0x62); // 0x62 or 0x63
MCP4725 MCP(0x62);

bool connected = false;


void setup()
{
Serial.begin(115200);

Serial.println(__FILE__);
Serial.print("MCP4725_VERSION: ");
Serial.println(MCP4725_VERSION);

Wire.begin();

if (MCP.begin() == false)
{
Serial.println("Could not find sensor");
Expand Down
Loading

0 comments on commit 485874d

Please sign in to comment.