Skip to content

Commit

Permalink
Fix #15 Support WireN + refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
RobTillaart committed Jan 15, 2021
1 parent 00d79ea commit fb8be1c
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 94 deletions.
102 changes: 55 additions & 47 deletions MCP4725.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,32 @@
// FILE: MCP4725.cpp
// AUTHOR: Rob Tillaart
// PURPOSE: Arduino library for 12 bit I2C DAC - MCP4725
// VERSION: 0.2.3
// VERSION: 0.3.0
// URL: https://github.com/RobTillaart/MCP4725
//
// HISTORY:
// 0.1.00 2013-11-24 initial version
// 0.1.01 2013-11-30 added readDAC() & writeDAC (registerwrite)
// 0.1.02 2013-12-01 added readEEPROM() & RDY()
// 0.1.03 2013-12-01 added powerDownMode code
// 0.1.04 2013-12-04 improved the generalCall code (still experimental)
// 0.1.05 2015-03-06 refactoring, stricter interfaces
// 0.1.6 - 2017-04-19 refactor + remove timeout - https://github.com/RobTillaart/Arduino/issues/63
// 0.1.7 - 2017-04-20 refactor the removed timeout (Thanks to Koepel)
// 0.1.8 - 2018-10-24 fix read only var #115 (kudos to perl1234)
// 0.1.9 - 2019-10-14 replace AVR specific TWBR with Wire.setClock() #131
// 0.2.0 2020-06-20 #pragma; remove pre 1.0 support; refactor a lot
// HISTORY:
// 0.1.00 2013-11-24 initial version
// 0.1.01 2013-11-30 added readDAC() & writeDAC (registerwrite)
// 0.1.02 2013-12-01 added readEEPROM() & RDY()
// 0.1.03 2013-12-01 added powerDownMode code
// 0.1.04 2013-12-04 improved the generalCall code (still experimental)
// 0.1.05 2015-03-06 refactoring, stricter interfaces
// 0.1.6 2017-04-19 refactor + remove timeout - https://github.com/RobTillaart/Arduino/issues/63
// 0.1.7 2017-04-20 refactor the removed timeout (Thanks to Koepel)
// 0.1.8 2018-10-24 fix read only var #115 (kudos to perl1234)
// 0.1.9 2019-10-14 replace AVR specific TWBR with _wire->setClock() #131
// 0.2.0 2020-06-20 #pragma; remove pre 1.0 support; refactor a lot
// RDY() -> ready()
// 0.2.1 2020-07-04 Add yield(); add getLastWriteEEPROM();
// 0.2.1 2020-07-04 Add yield(); add getLastWriteEEPROM();
// update readme.md + keywords.txt
// 0.2.2 2020-07-05 add get/setPercentage();
// 0.2.3 2020-12-26 arduino-CI, bool isConnected(), bool begin()
// 0.2.2 2020-07-05 add get/setPercentage();
// 0.2.3 2020-12-26 arduino-CI, bool isConnected(), bool begin()
// 0.3.0 2021-01-15 Add WireN support (e.g. teensy)


#include "MCP4725.h"


// registerMode
#define MCP4725_DAC 0x40
#define MCP4725_DACEEPROM 0x60
Expand All @@ -34,19 +37,26 @@
#define MCP4725_GC_WAKEUP 0x09


MCP4725::MCP4725(const uint8_t deviceAddress)
MCP4725::MCP4725(const uint8_t deviceAddress, TwoWire *wire)
{
_deviceAddress = deviceAddress;
_lastValue = 0;
_powerDownMode = 0;
_deviceAddress = deviceAddress;
_wire = wire;
_lastValue = 0;
_powerDownMode = 0;
_lastWriteEEPROM = 0;
}


#if defined(ESP8266) || defined(ESP32)
bool MCP4725::begin(const uint8_t dataPin, const uint8_t clockPin)
{
Wire.begin(dataPin, clockPin);
_wire = &Wire;
if ((dataPin < 255) && (clockPin < 255))
{
_wire->begin(dataPin, clockPin);
} else {
_wire->begin();
}
if (isConnected())
{
_lastValue = readDAC();
Expand All @@ -60,21 +70,19 @@ bool MCP4725::begin(const uint8_t dataPin, const uint8_t clockPin)

bool MCP4725::begin()
{
Wire.begin();
if (isConnected())
{
_lastValue = readDAC();
_powerDownMode = readPowerDownModeDAC();
return true;
}
return false;
_wire->begin();
if (! isConnected()) return false;

_lastValue = readDAC();
_powerDownMode = readPowerDownModeDAC();
return true;
}


bool MCP4725::isConnected()
{
Wire.beginTransmission(_deviceAddress);
return (Wire.endTransmission() == 0);
_wire->beginTransmission(_deviceAddress);
return (_wire->endTransmission() == 0);
}


Expand Down Expand Up @@ -188,10 +196,10 @@ int MCP4725::_writeFastMode(const uint16_t value)
uint8_t h = ((value / 256) & 0x0F); // set C0 = C1 = 0, no PDmode
h = h | (_powerDownMode << 4);

Wire.beginTransmission(_deviceAddress);
Wire.write(h);
Wire.write(l);
return Wire.endTransmission();
_wire->beginTransmission(_deviceAddress);
_wire->write(h);
_wire->write(l);
return _wire->endTransmission();
}


Expand All @@ -216,29 +224,29 @@ int MCP4725::_writeRegisterMode(const uint16_t value, uint8_t reg)
}
uint8_t h = (value / 16);
uint8_t l = (value & 0x0F) << 4;
Wire.beginTransmission(_deviceAddress);
_wire->beginTransmission(_deviceAddress);
reg = reg | (_powerDownMode << 1);
Wire.write(reg);
Wire.write(h);
Wire.write(l);
return Wire.endTransmission();
_wire->write(reg);
_wire->write(h);
_wire->write(l);
return _wire->endTransmission();
}


// PAGE 20 DATASHEET
// typical 3 or 5 bytes
uint8_t MCP4725::_readRegister(uint8_t* buffer, const uint8_t length)
{
Wire.beginTransmission(_deviceAddress);
int rv = Wire.endTransmission();
_wire->beginTransmission(_deviceAddress);
int rv = _wire->endTransmission();
if (rv != 0) return 0; // error

// readbytes will always be equal or smaller to length
uint8_t readBytes = Wire.requestFrom(_deviceAddress, length);
uint8_t readBytes = _wire->requestFrom(_deviceAddress, length);
uint8_t cnt = 0;
while (cnt < readBytes)
{
buffer[cnt++] = Wire.read();
buffer[cnt++] = _wire->read();
}
return readBytes;
}
Expand All @@ -247,9 +255,9 @@ uint8_t MCP4725::_readRegister(uint8_t* buffer, const uint8_t length)
// name comes from datasheet
int MCP4725::_generalCall(const uint8_t gc)
{
Wire.beginTransmission(0); // _deviceAddress
Wire.write(gc);
return Wire.endTransmission();
_wire->beginTransmission(0); // _deviceAddress
_wire->write(gc);
return _wire->endTransmission();
}

// -- END OF FILE --
88 changes: 50 additions & 38 deletions MCP4725.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,78 +3,90 @@
// FILE: MCP4725.h
// AUTHOR: Rob Tillaart
// PURPOSE: Arduino library for 12 bit I2C DAC - MCP4725
// VERSION: 0.2.3
// VERSION: 0.3.0
// URL: https://github.com/RobTillaart/MCP4725
// HISTORY: See MCP4725.cpp
//


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

#define MCP4725_VERSION "0.2.3"

#define MCP4725_VERSION ((F("0.3.0"))


// constants
#define MCP4725_MAXVALUE 4095


// errors
#define MCP4725_OK 0
#define MCP4725_VALUE_ERROR -999
#define MCP4725_REG_ERROR -998
#define MCP4725_NOT CONNECTED -997


// powerDown Mode - TODO ENUM?
#define MCP4725_PDMODE_NORMAL 0x00
#define MCP4725_PDMODE_1K 0x01
#define MCP4725_PDMODE_100K 0x02
#define MCP4725_PDMODE_500K 0x03


class MCP4725
{
public:
explicit MCP4725(const uint8_t deviceAddress);
explicit MCP4725(const uint8_t deviceAddress, TwoWire *wire = &Wire);

#if defined(ESP8266) || defined(ESP32)
bool begin(const uint8_t dataPin, const uint8_t clockPin);
bool begin(const uint8_t dataPin, const uint8_t clockPin);
#endif
bool begin();
bool isConnected();

// uses writeFastMode
int setValue(const uint16_t value = 0);
// returns last value set - cached - much faster than readDAC();
uint16_t getValue();

// 0..100.0% - no input check.
int setPercentage(float perc = 0) { return setValue(round(perc * (0.01 * MCP4725_MAXVALUE))); };
float getPercentage() { return getValue() * (100.0 / MCP4725_MAXVALUE); };

int writeDAC(const uint16_t value, const bool EEPROM = false);
// RDY will be depreciated in the future, use ready() instead.
inline bool RDY() { return ready(); };
bool ready();
uint32_t getLastWriteEEPROM() { return _lastWriteEEPROM; };
uint16_t readDAC();
uint16_t readEEPROM();

// experimental
int writePowerDownMode(const uint8_t PDM, const bool EEPROM = false);
uint8_t readPowerDownModeEEPROM();
uint8_t readPowerDownModeDAC();
int powerOnReset();
int powerOnWakeUp();
bool begin();
bool isConnected();


// uses writeFastMode
int setValue(const uint16_t value = 0);
// returns last value set - cached - much faster than readDAC();
uint16_t getValue();


// 0..100.0% - no input check.
int setPercentage(float perc = 0) { return setValue(round(perc * (0.01 * MCP4725_MAXVALUE))); };
float getPercentage() { return getValue() * (100.0 / MCP4725_MAXVALUE); };


int writeDAC(const uint16_t value, const bool EEPROM = false);
// RDY isdepreciated in the future, use ready() instead.
// inline bool RDY() { return ready(); };
bool ready();
uint32_t getLastWriteEEPROM() { return _lastWriteEEPROM; };
uint16_t readDAC();
uint16_t readEEPROM();


// experimental
int writePowerDownMode(const uint8_t PDM, const bool EEPROM = false);
uint8_t readPowerDownModeEEPROM();
uint8_t readPowerDownModeDAC();
int powerOnReset();
int powerOnWakeUp();


private:
uint8_t _deviceAddress;
uint16_t _lastValue;
uint8_t _powerDownMode; // DATASHEET P15?
int _writeFastMode(const uint16_t value);
uint32_t _lastWriteEEPROM;
uint8_t _deviceAddress;
uint16_t _lastValue;
uint8_t _powerDownMode; // DATASHEET P15?
int _writeFastMode(const uint16_t value);
uint32_t _lastWriteEEPROM;

int _writeRegisterMode(const uint16_t value, uint8_t reg);
uint8_t _readRegister(uint8_t* buffer, const uint8_t length);
int _writeRegisterMode(const uint16_t value, uint8_t reg);
uint8_t _readRegister(uint8_t* buffer, const uint8_t length);

int _generalCall(const uint8_t gc);
int _generalCall(const uint8_t gc);

TwoWire* _wire;
};

// -- END OF FILE --
20 changes: 14 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

Arduino library for 12 bit I2C DAC - MCP4725


## Description

The MCP4725 is an I2C 12 bit Digital to Analog Converter (DAC). It is possible to have
Expand All @@ -16,11 +17,19 @@ 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.


- **MCP4725(deviceAddress)** Constructor, needs I2C address
## Interface

### Constructor

- **MCP4725(deviceAddress, TwoWire \*wire = &Wire);)** Constructor, needs I2C address, optional set Wire bus
- **begin(dataPin, clockPin)** for ESP32. Returns true if connected.
- **begin()** for UNO and other boards with hard wired I2C pins. Returns true if connected.
Only suppport for Wire so not for Wire1 or Wire2 etc
- **isConnected()** returns true if device (address) can be seen on the I2C bus.


### base

- **setValue(value)** value = 0 .. 4095
Uses writeFastMode and does not write to EEPROM.
Therfore it does not update the lastWriteEEPROM timestamp.
Expand All @@ -42,11 +51,6 @@ When writing to EEPROM with **writeDAC()** one should check it is at least 50 ms
If one know the specific timing of a sensor one can tune this or even make it adaptive.


### Depreciated

- **RDY()** depreciated, replaced by **ready()**


## Experimental

Check datasheet for these functions, (not tested enough yet).
Expand All @@ -63,6 +67,7 @@ checking when and how long the sensor blocks needs to be verified in detail in p


## Address Notes

The address of the MCP4725 in the demo sketches is set to 0x62 as that
was the address of the sensor I had during writing.
According to the datasheet the address has the following bit pattern:
Expand All @@ -75,15 +80,18 @@ address 011000FFU (so 0x6?)
This means you can have at most 8 MCP4725 in one I2C bus (without multiplexing).
You have to specify the factory bits in your order, but not all shops might
provide all versions of the MCP4725.

```
MCP4725A0T-E/CH: 0110 000U 0x60 - 0x61
MCP4725A1T-E/CH: 0110 001U 0x62 - 0x63
MCP4725A2T-E/CH: 0110 010U 0x64 - 0x65
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)


## Operation

See examples
2 changes: 1 addition & 1 deletion examples/mcp4725_keypad/.arduino-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ compile:
- leonardo
- due
- zero

libraries:
- "I2CKeyPad"
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/MCP4725.git"
},
"version":"0.2.3",
"version":"0.3.0",
"frameworks": "arduino",
"platforms": "*"
}
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=MCP4725
version=0.2.3
version=0.3.0
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for 12 bit I2C DAC - MCP4725
Expand Down

0 comments on commit fb8be1c

Please sign in to comment.