0.3.4 MCP4725

This commit is contained in:
rob tillaart 2022-10-17 10:40:05 +02:00
parent fa85fad22b
commit 9e7544633d
9 changed files with 368 additions and 59 deletions

View File

@ -1,3 +1,18 @@
platforms:
rpipico:
board: rp2040:rp2040:rpipico
package: rp2040:rp2040
gcc:
features:
defines:
- ARDUINO_ARCH_RP2040
warnings:
flags:
packages:
rp2040:rp2040:
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
compile:
# Choosing to run compilation tests on 2 different Arduino platforms
platforms:
@ -7,5 +22,7 @@ compile:
# - leonardo
- m4
- esp32
# - esp8266
- esp8266
# - mega2560
- rpipico

View File

@ -0,0 +1,82 @@
# Change Log MCP4725
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.3.4] - 2022-10-17
- Add RP2040 support (kudos to intubun)
- Add RP2040 in build-CI
- Add changelog.md
## [0.3.3] - 2021-12-21
- update library.json,
- update license
- minor edits
## [0.3.2] - 2021-06-06
- Verify input of setPercentage()
## [0.3.1] - 2021-05-27
- Fix Arduino-CI / Arduino-lint
## [0.3.0] - 2021-01-15
- Add WireN support (e.g. teensy)
----
## [0.2.3] - 2020-12-26
- Arduino-CI,
- add bool isConnected(),
- update bool begin()
## [0.2.2] - 2020-07-05
- add get/setPercentage();
## [0.2.1] - 2020-07-04
- Add yield();
- add getLastWriteEEPROM();
- update readme.md
- update keywords.txt
## [0.2.0] - 2020-06-20
- use #pragma once;
- remove pre 1.0 support;
- refactor a lot
- rename RDY() -> ready()
----
## [0.1.9] - 2019-10-14
- replace AVR specific TWBR with \_wire->setClock() #131
## [0.1.8] - 2018-10-24
- fix read only variables #115 (kudos to perl1234)
## [0.1.7] - 2017-04-20
- refactor the removed timeout (Thanks to Koepel)
## [0.1.6] - 2017-04-19
- refactor
- remove timeout - https://github.com/RobTillaart/Arduino/issues/63
## [0.1.05] - 2015-03-06
- refactoring, stricter interfaces
## [0.1.04] - 2013-12-04
- improved the generalCall code (still experimental)
## [0.1.03] - 2013-12-01
- added powerDownMode code
## [0.1.02] - 2013-12-01
- added readEEPROM()
- added RDY()
## [0.1.01] - 2013-11-30
- added readDAC()
- added writeDAC(registerwrite)
## [0.1.00] - 2013-11-24
- initial version

View File

@ -2,40 +2,20 @@
// FILE: MCP4725.cpp
// AUTHOR: Rob Tillaart
// PURPOSE: Arduino library for 12 bit I2C DAC - MCP4725
// VERSION: 0.3.3
// VERSION: 0.3.4
// 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
// RDY() -> ready()
// 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.3.0 2021-01-15 Add WireN support (e.g. teensy)
// 0.3.1 2021-05-27 Fix Arduino-CI / Arduino-lint
// 0.3.2 2021-06-06 Verify input of setPercentage()
// 0.3.3 2021-12-21 update library.json, license, minor edits
// HISTORY see changelog.md
#include "MCP4725.h"
// registerMode
// registerMode
#define MCP4725_DAC 0x40
#define MCP4725_DACEEPROM 0x60
// page 22
// page 22
#define MCP4725_GC_RESET 0x06
#define MCP4725_GC_WAKEUP 0x09
@ -70,6 +50,25 @@ bool MCP4725::begin(const uint8_t dataPin, const uint8_t clockPin)
}
#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()
{
@ -112,8 +111,8 @@ int MCP4725::setPercentage(float percentage)
}
// unfortunately it is not possible to write a different value
// to the DAC and EEPROM simultaneously or write EEPROM only.
// unfortunately it is not possible to write a different value
// to the DAC and EEPROM simultaneously or write EEPROM only.
int MCP4725::writeDAC(const uint16_t value, const bool EEPROM)
{
if (value > MCP4725_MAXVALUE) return MCP4725_VALUE_ERROR;
@ -148,9 +147,9 @@ uint16_t MCP4725::readEEPROM()
}
// depending on bool EEPROM the value of PDM is written to
// (false) DAC or
// (true) DAC & EEPROM,
// depending on bool EEPROM the value of PDM is written to
// (false) DAC or
// (true) DAC & EEPROM,
int MCP4725::writePowerDownMode(const uint8_t PDM, const bool EEPROM)
{
_powerDownMode = (PDM & 0x03); // mask PDM bits only (written later low level)
@ -178,9 +177,9 @@ uint8_t MCP4725::readPowerDownModeDAC()
}
// PAGE 22 - experimental
// DAC value is reset to EEPROM value
// need to reflect this in cached value
// PAGE 22 - experimental
// DAC value is reset to EEPROM value
// need to reflect this in cached value
int MCP4725::powerOnReset()
{
int rv = _generalCall(MCP4725_GC_RESET);
@ -189,9 +188,9 @@ int MCP4725::powerOnReset()
}
// PAGE 22 - experimental
// _powerDownMode DAC resets to 0 -- PDM EEPROM stays same !!!
// need to reflect this in cached value
// PAGE 22 - experimental
// _powerDownMode DAC resets to 0 -- PDM EEPROM stays same !!!
// need to reflect this in cached value
int MCP4725::powerOnWakeUp()
{
int rv = _generalCall(MCP4725_GC_WAKEUP);
@ -199,7 +198,7 @@ int MCP4725::powerOnWakeUp()
return rv;
}
// PAGE 18 DATASHEET
// PAGE 18 DATASHEET
int MCP4725::_writeFastMode(const uint16_t value)
{
uint8_t l = value & 0xFF;
@ -213,8 +212,8 @@ int MCP4725::_writeFastMode(const uint16_t value)
}
// ready checks if the last write to EEPROM has been written.
// until ready all writes to the MCP4725 are ignored!
// ready checks if the last write to EEPROM has been written.
// until ready all writes to the MCP4725 are ignored!
bool MCP4725::ready()
{
yield();
@ -224,8 +223,8 @@ bool MCP4725::ready()
}
// PAGE 19 DATASHEET
// reg = MCP4725_DAC | MCP4725_EEPROM
// PAGE 19 DATASHEET
// reg = MCP4725_DAC | MCP4725_EEPROM
int MCP4725::_writeRegisterMode(const uint16_t value, uint8_t reg)
{
if (reg & MCP4725_DACEEPROM)
@ -243,15 +242,15 @@ int MCP4725::_writeRegisterMode(const uint16_t value, uint8_t reg)
}
// PAGE 20 DATASHEET
// typical 3 or 5 bytes
// 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();
if (rv != 0) return 0; // error
// readbytes will always be equal or smaller to length
// readbytes will always be equal or smaller to length
uint8_t readBytes = _wire->requestFrom(_deviceAddress, length);
uint8_t cnt = 0;
while (cnt < readBytes)
@ -262,7 +261,7 @@ uint8_t MCP4725::_readRegister(uint8_t* buffer, const uint8_t length)
}
// name comes from datasheet
// name comes from datasheet
int MCP4725::_generalCall(const uint8_t gc)
{
_wire->beginTransmission(0); // _deviceAddress

View File

@ -3,7 +3,7 @@
// FILE: MCP4725.h
// AUTHOR: Rob Tillaart
// PURPOSE: Arduino library for 12 bit I2C DAC - MCP4725
// VERSION: 0.3.3
// VERSION: 0.3.4
// URL: https://github.com/RobTillaart/MCP4725
//
@ -12,21 +12,21 @@
#include "Arduino.h"
#define MCP4725_VERSION (F("0.3.3"))
#define MCP4725_VERSION (F("0.3.4"))
// constants
// CONSTANTS
#define MCP4725_MAXVALUE 4095
// errors
// ERRORS
#define MCP4725_OK 0
#define MCP4725_VALUE_ERROR -999
#define MCP4725_REG_ERROR -998
#define MCP4725_NOT_CONNECTED -997
// powerDown Mode - TODO ENUM?
// powerDown Mode - TODO ENUM?
#define MCP4725_PDMODE_NORMAL 0x00
#define MCP4725_PDMODE_1K 0x01
#define MCP4725_PDMODE_100K 0x02
@ -41,31 +41,36 @@ public:
#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();
// uses writeFastMode
// uses writeFastMode
int setValue(const uint16_t value = 0);
// returns last value set - cached - much faster than readDAC();
// returns last value set - cached - much faster than readDAC();
uint16_t getValue();
// 0..100.0% - no input check.
// 0..100.0% - no input check.
int setPercentage(float percentage = 0);
float getPercentage() { return getValue() * (100.0 / MCP4725_MAXVALUE); };
int writeDAC(const uint16_t value, const bool EEPROM = false);
// RDY is 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
// experimental
int writePowerDownMode(const uint8_t PDM, const bool EEPROM = false);
uint8_t readPowerDownModeEEPROM();
uint8_t readPowerDownModeDAC();
@ -76,7 +81,7 @@ public:
private:
uint8_t _deviceAddress;
uint16_t _lastValue;
uint8_t _powerDownMode; // DATASHEET P15?
uint8_t _powerDownMode; // DATASHEET P15?
int _writeFastMode(const uint16_t value);
uint32_t _lastWriteEEPROM;

View File

@ -100,6 +100,14 @@ If one need more DAC's one might have a look at the MCP4728
It has 4 channels per chip (no experience /library yet)
### RP2040 specific
- **bool begin(int sda, int scl)** begin communication with the DAC.
It has the parameter for selecting on which pins the communication should happen.
Check RP2040 Pinout for compatible pins.
When Wire1 is used, it needs to be specified in the constructor with "&Wire1"
## Operation
See examples

View File

@ -0,0 +1,27 @@
platforms:
rpipico:
board: rp2040:rp2040:rpipico
package: rp2040:rp2040
gcc:
features:
defines:
- ARDUINO_ARCH_RP2040
warnings:
flags:
packages:
rp2040:rp2040:
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
compile:
# Choosing to run compilation tests on 2 different Arduino platforms
platforms:
# - uno
# - due
# - zero
# - leonardo
# - m4
# - esp32
# - esp8266
# - mega2560
- rpipico

View File

@ -0,0 +1,171 @@
//
// 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.
// other signals are less difficult so have a slightly larger range.
//
// PLATFORM SINUS SQUARE SAWTOOTH TRIANGLE
// UNO -100 Hz
// ESP32 -200 Hz -1000 -250 -100
//
#include "MCP4725.h"
#include "Wire.h"
uint16_t freq = 100;
uint32_t period = 0;
uint32_t halvePeriod = 0;
// q = square
// s = sinus
// w = sawtooth
// t = stair
// r = random
char mode = 'q';
MCP4725 MCP(0x63, &Wire1);
uint16_t count;
uint32_t lastTime = 0;
// LOOKUP TABLE SINE
uint16_t sine[360];
void setup()
{
Serial.begin(115200);
// fill table
for (int i = 0; i < 361; i++)
{
sine[i] = 2047 + round(2047 * sin(i * PI / 180));
}
MCP.begin(26, 27);
Wire1.setClock(800000);
MCP.setValue(0);
if (!MCP.isConnected())
{
Serial.println("err");
while (1);
}
period = 1e6 / freq;
halvePeriod = period / 2;
while (1)
{
yield();
uint32_t now = micros();
count++;
if (now - lastTime > 100000)
{
lastTime = now;
// Serial.println(count); // show # updates per 0.1 second
count = 0;
if (Serial.available())
{
int c = Serial.read();
switch (c)
{
case '+':
freq++;
break;
case '-':
freq--;
break;
case '*':
freq *= 10;
break;
case '/':
freq /= 10;
break;
case '0' ... '9':
freq *= 10;
freq += (c - '0');
break;
case 'c':
freq = 0;
break;
case 'A':
break;
case 'a':
break;
case 'q':
case 's':
case 'w':
case 't':
case 'r':
case 'z':
case 'm':
case 'h':
mode = c;
break;
default:
break;
}
period = 1e6 / freq;
halvePeriod = period / 2;
Serial.print(freq);
// Serial.print('\t');
// Serial.print(period);
// Serial.print('\t');
// Serial.print(halvePeriod);
Serial.println();
}
}
uint32_t t = now % period;
switch (mode)
{
case 'q':
if (t < halvePeriod ) MCP.setValue(4095);
else MCP.setValue(0);
break;
case 'w':
MCP.setValue(t * 4095 / period );
break;
case 't':
if (t < halvePeriod) MCP.setValue(t * 4095 / halvePeriod);
else MCP.setValue( (period - t) * 4095 / halvePeriod );
break;
case 'r':
MCP.setValue(random(4096));
break;
case 'z': // zero
MCP.setValue(0);
break;
case 'h': // high
MCP.setValue(4095);
break;
case 'm': // mid
MCP.setValue(2047);
break;
default:
case 's':
// reference
// float f = ((PI * 2) * t)/period;
// MCP.setValue(2047 + 2047 * sin(f));
//
int idx = (360 * t) / period;
MCP.setValue(sine[idx]); // lookuptable
break;
}
}
}
void loop()
{
}
// -- END OF FILE --

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/MCP4725.git"
},
"version": "0.3.3",
"version": "0.3.4",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*",

View File

@ -1,5 +1,5 @@
name=MCP4725
version=0.3.3
version=0.3.4
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for 12 bit I2C DAC - MCP4725