mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.2.0 MCP4261
This commit is contained in:
parent
4dfce7b8ef
commit
76bdcc7125
@ -6,5 +6,22 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
|||||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
|
|
||||||
|
## [0.2.0] - 2024-07-09
|
||||||
|
- refactor 0.1.0 implementation
|
||||||
|
- use less magic numbers
|
||||||
|
- reimplement protected functions
|
||||||
|
- remove parameter from **begin()** reads value from device. (breaking)
|
||||||
|
- fix the supported range to 0..256 (was 255).
|
||||||
|
- add **uint16_t getValueDevice(uint8_t pm)**
|
||||||
|
- add **uint16_t getValueNV(uint8_t pm)**
|
||||||
|
- add **void setTCONMask(uint16_t mask)**
|
||||||
|
- add **uint16_t getTCONMask()**
|
||||||
|
- add **uint16_t getStatusMask()**
|
||||||
|
- add **bool setEEPROM(uint8_t index, uint16_t value)**
|
||||||
|
- add **uint16_t getEEPROM(uint8_t index)**
|
||||||
|
- update readme.md
|
||||||
|
- minor edits.
|
||||||
|
|
||||||
|
|
||||||
## [0.1.0] - 2024-02-21
|
## [0.1.0] - 2024-02-21
|
||||||
- initial version
|
- initial version
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// FILE: MCP4261.cpp
|
// FILE: MCP4261.cpp
|
||||||
// AUTHOR: Rob Tillaart
|
// AUTHOR: Rob Tillaart
|
||||||
// VERSION: 0.1.0
|
// VERSION: 0.2.0
|
||||||
// DATE: 2024-02-21
|
// DATE: 2024-02-21
|
||||||
// PURPOSE: Arduino library for MCP4261 SPI based digital potentiometers.
|
// PURPOSE: Arduino library for MCP4261 SPI based digital potentiometers.
|
||||||
// URL: https://github.com/RobTillaart/MCP4261
|
// URL: https://github.com/RobTillaart/MCP4261
|
||||||
@ -10,18 +10,21 @@
|
|||||||
#include "MCP4261.h"
|
#include "MCP4261.h"
|
||||||
|
|
||||||
|
|
||||||
// see page 18 datasheet
|
#define MCP4261_CMD_WRITE 0x00
|
||||||
#define MCP4261_IGNORE_CMD 0x00
|
#define MCP4261_CMD_INCR 0x04
|
||||||
#define MCP4261_WRITE_CMD 0x00
|
#define MCP4261_CMD_DECR 0x08
|
||||||
#define MCP4261_SHUTDOWN_CMD 0x20
|
#define MCP4261_CMD_READ 0x0C
|
||||||
#define MCP4261_NONE_CMD 0x30
|
|
||||||
|
#define MCP4261_REG_TCON 0x04
|
||||||
|
#define MCP4261_REG_STATUS 0x05
|
||||||
|
#define MCP4261_REG_EEPROM(x) (0x06 + x)
|
||||||
|
|
||||||
|
|
||||||
// HARDWARE SPI
|
// HARDWARE SPI
|
||||||
MCP4261::MCP4261(uint8_t select, uint8_t shutdown, __SPI_CLASS__ * mySPI)
|
MCP4261::MCP4261(uint8_t select, uint8_t shutdown, __SPI_CLASS__ * mySPI)
|
||||||
{
|
{
|
||||||
_pmCount = 2;
|
_pmCount = 2;
|
||||||
_maxValue = 255;
|
_maxValue = MCP42XX_MAX_VALUE;
|
||||||
_select = select;
|
_select = select;
|
||||||
_shutdown = shutdown;
|
_shutdown = shutdown;
|
||||||
_dataIn = 255;
|
_dataIn = 255;
|
||||||
@ -37,7 +40,7 @@ MCP4261::MCP4261(uint8_t select, uint8_t shutdown, __SPI_CLASS__ * mySPI)
|
|||||||
MCP4261::MCP4261(uint8_t select, uint8_t shutdown, uint8_t dataIn, uint8_t dataOut, uint8_t clock)
|
MCP4261::MCP4261(uint8_t select, uint8_t shutdown, uint8_t dataIn, uint8_t dataOut, uint8_t clock)
|
||||||
{
|
{
|
||||||
_pmCount = 2;
|
_pmCount = 2;
|
||||||
_maxValue = 255;
|
_maxValue = MCP42XX_MAX_VALUE;
|
||||||
_select = select;
|
_select = select;
|
||||||
_shutdown = shutdown;
|
_shutdown = shutdown;
|
||||||
_dataIn = dataIn;
|
_dataIn = dataIn;
|
||||||
@ -48,7 +51,7 @@ MCP4261::MCP4261(uint8_t select, uint8_t shutdown, uint8_t dataIn, uint8_t dataO
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MCP4261::begin(uint16_t value)
|
void MCP4261::begin()
|
||||||
{
|
{
|
||||||
pinMode(_select, OUTPUT);
|
pinMode(_select, OUTPUT);
|
||||||
digitalWrite(_select, HIGH);
|
digitalWrite(_select, HIGH);
|
||||||
@ -71,7 +74,9 @@ void MCP4261::begin(uint16_t value)
|
|||||||
digitalWrite(_dataOut, LOW);
|
digitalWrite(_dataOut, LOW);
|
||||||
digitalWrite(_clock, LOW);
|
digitalWrite(_clock, LOW);
|
||||||
}
|
}
|
||||||
reset(value);
|
// get initial values from device.
|
||||||
|
getValueDevice(0);
|
||||||
|
getValueDevice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -83,6 +88,11 @@ void MCP4261::reset(uint16_t value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t MCP4261::pmCount()
|
||||||
|
{
|
||||||
|
return _pmCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@ -102,10 +112,9 @@ bool MCP4261::setValue(uint8_t pm, uint16_t value)
|
|||||||
if (value > _maxValue) return false;
|
if (value > _maxValue) return false;
|
||||||
_value[pm] = value;
|
_value[pm] = value;
|
||||||
|
|
||||||
uint8_t cmd = 0x00;
|
uint8_t value1 = MCP4261_CMD_WRITE | (pm << 4);
|
||||||
if (pm == 1) cmd = 0x10;
|
if (value > 0xFF) value1 |= (value >> 8); // high bits
|
||||||
if (value > 0xFF) cmd |= (value >> 8); // high bits
|
writeRegister2(value1, value & 0xFF);
|
||||||
writeDevice(2, cmd, value & 0xFF);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,15 +126,23 @@ uint16_t MCP4261::getValue(uint8_t pm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t MCP4261::getValueDevice(uint8_t pm)
|
||||||
|
{
|
||||||
|
if (pm >= _pmCount) return 0;
|
||||||
|
uint8_t value1 = MCP4261_CMD_READ | (pm << 4);
|
||||||
|
_value[pm] = readRegister(value1);
|
||||||
|
return _value[pm];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool MCP4261::incrValue(uint8_t pm)
|
bool MCP4261::incrValue(uint8_t pm)
|
||||||
{
|
{
|
||||||
if (pm >= _pmCount) return false;
|
if (pm >= _pmCount) return false;
|
||||||
if (_value[pm] >= _maxValue) return false;
|
if (_value[pm] >= _maxValue) return false;
|
||||||
_value[pm]++;
|
_value[pm]++;
|
||||||
|
|
||||||
uint8_t cmd = 0x04;
|
uint8_t value1 = MCP4261_CMD_INCR | (pm << 4);
|
||||||
if (pm == 1) cmd = 0x14;
|
writeRegister1(value1);
|
||||||
writeDevice(1, cmd, cmd); // value2 = DUMMY
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,9 +153,8 @@ bool MCP4261::decrValue(uint8_t pm)
|
|||||||
if (_value[pm] == 0) return false;
|
if (_value[pm] == 0) return false;
|
||||||
_value[pm]--;
|
_value[pm]--;
|
||||||
|
|
||||||
uint8_t cmd = 0x08;
|
uint8_t value1 = MCP4261_CMD_DECR | (pm << 4);
|
||||||
if (pm == 1) cmd = 0x18;
|
writeRegister1(value1);
|
||||||
writeDevice(1, cmd, cmd); // value2 = DUMMY
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,24 +169,81 @@ bool MCP4261::setValueNV(uint8_t pm, uint16_t value)
|
|||||||
if (pm >= _pmCount) return false;
|
if (pm >= _pmCount) return false;
|
||||||
if (value > _maxValue) return false;
|
if (value > _maxValue) return false;
|
||||||
|
|
||||||
uint8_t cmd = 0x20;
|
uint8_t value1 = MCP4261_CMD_WRITE | ((pm + 2) << 4);
|
||||||
if (pm == 1) cmd = 0x30;
|
if (value > 0xFF) value1 |= (value >> 8); // high bits
|
||||||
if (value > 0xFF) cmd |= (value >> 8); // high bits
|
writeRegister2(value1, value & 0xFF);
|
||||||
writeDevice(2, cmd, value & 0xFF);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t MCP4261::getValueNV(uint8_t pm)
|
||||||
|
{
|
||||||
|
if (pm >= _pmCount) return 0;
|
||||||
|
uint8_t value1 = MCP4261_CMD_READ | ((pm + 2) << 4);
|
||||||
|
return readRegister(value1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// MISC
|
// TERMINAL CONTROL
|
||||||
//
|
//
|
||||||
uint8_t MCP4261::pmCount()
|
void MCP4261::setTCONMask(uint16_t mask)
|
||||||
{
|
{
|
||||||
return _pmCount;
|
uint8_t value1 = MCP4261_CMD_WRITE | (MCP4261_REG_TCON << 4);
|
||||||
|
mask &= 0xFF; // only lower 8 bits used.
|
||||||
|
writeRegister2(value1, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t MCP4261::getTCONMask()
|
||||||
|
{
|
||||||
|
uint8_t value1 = MCP4261_CMD_READ | (MCP4261_REG_TCON << 4);
|
||||||
|
uint16_t mask = readRegister(value1);
|
||||||
|
return mask & 0x01FF; // 0x1FF to get bit 8 which is always HIGH.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// STATUS
|
||||||
|
//
|
||||||
|
uint16_t MCP4261::getStatusMask()
|
||||||
|
{
|
||||||
|
uint8_t value1 = MCP4261_CMD_READ | (MCP4261_REG_STATUS << 4);
|
||||||
|
uint16_t mask = readRegister(value1);
|
||||||
|
return mask & 0x1F;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// EEPROM
|
||||||
|
//
|
||||||
|
bool MCP4261::setEEPROM(uint8_t index, uint16_t value)
|
||||||
|
{
|
||||||
|
if (index > 9) return false;
|
||||||
|
if (value > 0x1FF) return false; // 511
|
||||||
|
uint8_t value1 = MCP4261_CMD_WRITE | (MCP4261_REG_EEPROM(index) << 4);
|
||||||
|
if (value > 0xFF) value1 |= (value >> 8);
|
||||||
|
writeRegister2(value1, value & 0xFF);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t MCP4261::getEEPROM(uint8_t index)
|
||||||
|
{
|
||||||
|
if (index > 9) return 0; // 0xFFFF ?
|
||||||
|
uint8_t value1 = MCP4261_CMD_READ | (MCP4261_REG_EEPROM(index) << 4);
|
||||||
|
uint16_t value = readRegister(value1);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// POWER
|
||||||
|
//
|
||||||
void MCP4261::powerOn()
|
void MCP4261::powerOn()
|
||||||
{
|
{
|
||||||
digitalWrite(_shutdown, HIGH);
|
digitalWrite(_shutdown, HIGH);
|
||||||
@ -217,48 +290,86 @@ bool MCP4261::usesHWSPI()
|
|||||||
// PROTECTED
|
// PROTECTED
|
||||||
//
|
//
|
||||||
|
|
||||||
/*
|
|
||||||
TODO - see page 46
|
|
||||||
- need read8, read16
|
|
||||||
- bid8, bidi16
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// USES SPI MODE 0
|
// USES SPI MODE 0
|
||||||
//
|
//
|
||||||
void MCP4261::writeDevice(uint8_t count, uint8_t value1, uint8_t value2)
|
void MCP4261::writeRegister1(uint8_t value1)
|
||||||
{
|
{
|
||||||
digitalWrite(_select, LOW);
|
digitalWrite(_select, LOW);
|
||||||
if (_hwSPI)
|
if (_hwSPI)
|
||||||
{
|
{
|
||||||
_mySPI->beginTransaction(_spi_settings);
|
_mySPI->beginTransaction(_spi_settings);
|
||||||
_mySPI->transfer(value1);
|
_mySPI->transfer(value1);
|
||||||
if (count == 2) _mySPI->transfer(value2);
|
|
||||||
_mySPI->endTransaction();
|
_mySPI->endTransaction();
|
||||||
}
|
}
|
||||||
else // Software SPI
|
else // Software SPI
|
||||||
{
|
{
|
||||||
swSPI_write(value1);
|
swSPI_write(value1);
|
||||||
if (count == 2) swSPI_write(value2);
|
|
||||||
}
|
}
|
||||||
digitalWrite(_select, HIGH);
|
digitalWrite(_select, HIGH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MCP4261::writeRegister2(uint8_t value1, uint8_t value2)
|
||||||
|
{
|
||||||
|
digitalWrite(_select, LOW);
|
||||||
|
if (_hwSPI)
|
||||||
|
{
|
||||||
|
_mySPI->beginTransaction(_spi_settings);
|
||||||
|
_mySPI->transfer(value1);
|
||||||
|
_mySPI->transfer(value2);
|
||||||
|
_mySPI->endTransaction();
|
||||||
|
}
|
||||||
|
else // Software SPI
|
||||||
|
{
|
||||||
|
swSPI_write(value1);
|
||||||
|
swSPI_write(value2);
|
||||||
|
}
|
||||||
|
digitalWrite(_select, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t MCP4261::readRegister(uint8_t value)
|
||||||
|
{
|
||||||
|
uint16_t rv = 0;
|
||||||
|
digitalWrite(_select, LOW);
|
||||||
|
if (_hwSPI)
|
||||||
|
{
|
||||||
|
_mySPI->beginTransaction(_spi_settings);
|
||||||
|
rv += _mySPI->transfer(value);
|
||||||
|
rv <<= 8;
|
||||||
|
rv += _mySPI->transfer(0x00);
|
||||||
|
_mySPI->endTransaction();
|
||||||
|
}
|
||||||
|
else // Software SPI
|
||||||
|
{
|
||||||
|
rv += swSPI_write(value);
|
||||||
|
rv <<= 8;
|
||||||
|
rv += swSPI_write(0x00);
|
||||||
|
}
|
||||||
|
digitalWrite(_select, HIGH);
|
||||||
|
rv &= 0x01FF; // 9 bits data only
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// MSBFIRST
|
// MSBFIRST
|
||||||
void MCP4261::swSPI_write(uint8_t value)
|
uint8_t MCP4261::swSPI_write(uint8_t value)
|
||||||
{
|
{
|
||||||
uint8_t clk = _clock;
|
uint8_t clk = _clock;
|
||||||
uint8_t dao = _dataOut;
|
uint8_t dao = _dataOut;
|
||||||
|
uint8_t dai = _dataIn;
|
||||||
|
uint8_t val = 0;
|
||||||
|
|
||||||
// MSBFIRST
|
// MSBFIRST
|
||||||
for (uint8_t mask = 0x80; mask; mask >>= 1)
|
for (uint8_t mask = 0x80; mask; mask >>= 1)
|
||||||
{
|
{
|
||||||
digitalWrite(dao,(value & mask));
|
digitalWrite(dao,(value & mask));
|
||||||
digitalWrite(clk, HIGH);
|
digitalWrite(clk, HIGH);
|
||||||
|
if (digitalRead(dai)) val |= mask;
|
||||||
digitalWrite(clk, LOW);
|
digitalWrite(clk, LOW);
|
||||||
}
|
}
|
||||||
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
//
|
//
|
||||||
// FILE: MCP4261.h
|
// FILE: MCP4261.h
|
||||||
// AUTHOR: Rob Tillaart
|
// AUTHOR: Rob Tillaart
|
||||||
// VERSION: 0.1.0
|
// VERSION: 0.2.0
|
||||||
// DATE: 2024-02-21
|
// DATE: 2024-02-21
|
||||||
// PURPOSE: Arduino library for MCP4261 SPI based digital potentiometers.
|
// PURPOSE: Arduino library for MCP4261 SPI based digital potentiometers.
|
||||||
// URL: https://github.com/RobTillaart/MCP4261
|
// URL: https://github.com/RobTillaart/MCP4261
|
||||||
@ -12,7 +12,7 @@
|
|||||||
#include "SPI.h"
|
#include "SPI.h"
|
||||||
|
|
||||||
|
|
||||||
#define MCP4261_LIB_VERSION (F("0.1.0"))
|
#define MCP4261_LIB_VERSION (F("0.2.0"))
|
||||||
|
|
||||||
|
|
||||||
#ifndef MCP41XX_MIDDLE_VALUE
|
#ifndef MCP41XX_MIDDLE_VALUE
|
||||||
@ -20,16 +20,16 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MCP41XX_MAX_VALUE
|
#ifndef MCP41XX_MAX_VALUE
|
||||||
#define MCP41XX_MAX_VALUE 129
|
#define MCP41XX_MAX_VALUE 128
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef MCP42XX_MIDDLE_VALUE
|
#ifndef MCP42XX_MIDDLE_VALUE
|
||||||
#define MCP42XX_MIDDLE_VALUE 129
|
#define MCP42XX_MIDDLE_VALUE 128
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MCP42XX_MAX_VALUE
|
#ifndef MCP42XX_MAX_VALUE
|
||||||
#define MCP42XX_MAX_VALUE 257
|
#define MCP42XX_MAX_VALUE 256
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -53,36 +53,71 @@ public:
|
|||||||
// SOFTWARE SPI
|
// SOFTWARE SPI
|
||||||
MCP4261(uint8_t select, uint8_t shutdown, uint8_t dataIn, uint8_t dataOut, uint8_t clock);
|
MCP4261(uint8_t select, uint8_t shutdown, uint8_t dataIn, uint8_t dataOut, uint8_t clock);
|
||||||
|
|
||||||
void begin(uint16_t value);
|
void begin();
|
||||||
void reset(uint16_t value);
|
void reset(uint16_t value);
|
||||||
uint8_t pmCount();
|
uint8_t pmCount();
|
||||||
|
|
||||||
|
//
|
||||||
|
// SET VOLATILE VALUE
|
||||||
|
//
|
||||||
// set both potmeters (just a wrapper)
|
// set both potmeters (just a wrapper)
|
||||||
bool setValue(uint16_t value);
|
bool setValue(uint16_t value);
|
||||||
// set single potmeter (0 or 1)
|
// set single potmeter (0 or 1)
|
||||||
bool setValue(uint8_t pm, uint16_t value);
|
bool setValue(uint8_t pm, uint16_t value);
|
||||||
|
// from cache or device
|
||||||
uint16_t getValue(uint8_t pm = 0);
|
uint16_t getValue(uint8_t pm = 0);
|
||||||
|
uint16_t getValueDevice(uint8_t pm = 0);
|
||||||
|
|
||||||
bool incrValue(uint8_t pm);
|
bool incrValue(uint8_t pm = 0);
|
||||||
bool decrValue(uint8_t pm);
|
bool decrValue(uint8_t pm = 0);
|
||||||
|
|
||||||
// Set non volatile potmeter
|
//
|
||||||
// not tested
|
// SET NON-VOLATILE VALUE
|
||||||
|
//
|
||||||
bool setValueNV(uint8_t pm, uint16_t value);
|
bool setValueNV(uint8_t pm, uint16_t value);
|
||||||
|
uint16_t getValueNV(uint8_t pm); // always from device
|
||||||
|
|
||||||
|
//
|
||||||
|
// TERMINAL CONTROL (bit masks to elaborate)
|
||||||
|
//
|
||||||
|
void setTCONMask(uint16_t mask); // only lower 9 bits used.
|
||||||
|
uint16_t getTCONMask();
|
||||||
|
|
||||||
|
//
|
||||||
|
// STATUS read only (not implemented High Voltage commands).
|
||||||
|
//
|
||||||
|
// BIT Description
|
||||||
|
// --------------------------
|
||||||
|
// 0 Write Protect
|
||||||
|
// 1 Shut Down
|
||||||
|
// 2 Wiper Lock 0
|
||||||
|
// 3 Wiper Lock 1
|
||||||
|
// 4 EEPROM Write Active
|
||||||
|
uint16_t getStatusMask();
|
||||||
|
|
||||||
|
//
|
||||||
|
// EEPROM
|
||||||
|
//
|
||||||
|
// index = 0..9 value = 0..511
|
||||||
|
bool setEEPROM(uint8_t index, uint16_t value);
|
||||||
|
uint16_t getEEPROM(uint8_t index);
|
||||||
|
|
||||||
|
//
|
||||||
|
// POWER
|
||||||
|
//
|
||||||
|
void powerOn();
|
||||||
|
void powerOff();
|
||||||
|
bool isPowerOn();
|
||||||
|
|
||||||
|
//
|
||||||
|
// SPI
|
||||||
|
//
|
||||||
// speed in Hz
|
// speed in Hz
|
||||||
void setSPIspeed(uint32_t speed);
|
void setSPIspeed(uint32_t speed);
|
||||||
uint32_t getSPIspeed();
|
uint32_t getSPIspeed();
|
||||||
bool usesHWSPI(); // debugging
|
bool usesHWSPI(); // debugging
|
||||||
|
|
||||||
|
|
||||||
// MISC
|
|
||||||
void powerOn();
|
|
||||||
void powerOff();
|
|
||||||
bool isPowerOn();
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint8_t _dataIn;
|
uint8_t _dataIn;
|
||||||
uint8_t _dataOut;
|
uint8_t _dataOut;
|
||||||
@ -96,8 +131,11 @@ protected:
|
|||||||
uint8_t _pmCount;
|
uint8_t _pmCount;
|
||||||
uint16_t _maxValue;
|
uint16_t _maxValue;
|
||||||
|
|
||||||
void writeDevice(uint8_t count, uint8_t value1, uint8_t value2);
|
|
||||||
void swSPI_write(uint8_t value);
|
void writeRegister1(uint8_t value1);
|
||||||
|
void writeRegister2(uint8_t value1, uint8_t value2);
|
||||||
|
uint16_t readRegister(uint8_t reg);
|
||||||
|
uint8_t swSPI_write(uint8_t value);
|
||||||
|
|
||||||
__SPI_CLASS__ * _mySPI;
|
__SPI_CLASS__ * _mySPI;
|
||||||
SPISettings _spi_settings;
|
SPISettings _spi_settings;
|
||||||
|
@ -8,8 +8,6 @@
|
|||||||
[![GitHub release](https://img.shields.io/github/release/RobTillaart/MCP4261.svg?maxAge=3600)](https://github.com/RobTillaart/MCP4261/releases)
|
[![GitHub release](https://img.shields.io/github/release/RobTillaart/MCP4261.svg?maxAge=3600)](https://github.com/RobTillaart/MCP4261/releases)
|
||||||
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/MCP4261.svg)](https://registry.platformio.org/libraries/robtillaart/MCP4261)
|
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/MCP4261.svg)](https://registry.platformio.org/libraries/robtillaart/MCP4261)
|
||||||
|
|
||||||
[![Commits since latest](https://img.shields.io/github/commits-since/RobTillaart/MCP4261/latest)](https://github.com/RobTillaart/MCP4261/commits/master)
|
|
||||||
|
|
||||||
|
|
||||||
# MCP4261
|
# MCP4261
|
||||||
|
|
||||||
@ -24,87 +22,122 @@ The MCP4261 library supports both hardware SPI and software SPI up to 10 MHz.
|
|||||||
|
|
||||||
These series of potmeters (rheostats) come in values of 5, 10, 50 and 100 kΩ (±20%).
|
These series of potmeters (rheostats) come in values of 5, 10, 50 and 100 kΩ (±20%).
|
||||||
|
|
||||||
Where other potmeters uses a range of 0..127 or 0.255, these series potmeters
|
Where other potmeters uses a range of 0..127 or 0..255, these series potmeters
|
||||||
use a range 0..129 and 0..257. This implies some extra care to set the wiper
|
use a range 0..128 (129 steps) and 0..256 (257 steps).
|
||||||
to end position.
|
This implies some extra care to set the wiper to end position.
|
||||||
|
|
||||||
The library supports setting the value of the potmeters and caches this setting.
|
The library supports setting the value of the potmeters and caches this setting.
|
||||||
This way it can be retrieved very fast.
|
This way it can be retrieved very fast.
|
||||||
|
The library also support to fetch the value from the device.
|
||||||
|
This is useful to get the start value in **begin()** and more.
|
||||||
|
|
||||||
Furthermore the library has two functions to increase and decrease
|
Furthermore the library has two functions to increase and decrease
|
||||||
the value of a potmeter.
|
the value of a potmeter.
|
||||||
|
|
||||||
|
The library supports reading / writing the **Terminal Control** register.
|
||||||
|
This allows one to disconnect either, A, B or the Wiper pin from the internal
|
||||||
|
resistor array. (needs investigation how it works in detail).
|
||||||
|
|
||||||
Feedback, issues and improvements are welcome,
|
The library can read the **Status** register, this is e.g. needed to see if one can
|
||||||
Please open an issue on GitHub.
|
write to EEPROM or to the NON-Volatile registers (power on values).
|
||||||
|
Note the library does not check this.
|
||||||
|
Furthermore the status register shows the status of both the shutdown and write
|
||||||
|
protect pins.
|
||||||
|
The **Status** register also shows the wiper lock state, however the library
|
||||||
|
does not support locking/unlocking the wipers.
|
||||||
|
|
||||||
|
Finally the library supports setting and getting from the 10 **EEPROM** locations.
|
||||||
|
Only 9 bits, so the values 0..511 are supported.
|
||||||
|
E.g. one could use these to store 5 x 2 wiper states or something more exciting.
|
||||||
|
|
||||||
|
|
||||||
### Not implemented yet
|
#### Obsolete
|
||||||
|
|
||||||
The library is under development and not all functionality is implemented.
|
Version 0.2.0 has many additional functions and some were fixed so 0.1.x versions
|
||||||
(as I only needed to set values).
|
are obsolete.
|
||||||
|
|
||||||
- EEPROM, 10 addresses of 10 bits. (MCP4261 et al )
|
|
||||||
- Non volatile registers for power on setup.. (partially)
|
#### Feedback
|
||||||
- read back from device
|
|
||||||
- read status
|
The library is tested only limited with a MCP4261, so feedback, issues and
|
||||||
- TCON register
|
improvements are as always welcome. Please open an issue on GitHub.
|
||||||
- High Voltage something?
|
|
||||||
|
|
||||||
|
|
||||||
### Compatibles
|
### Compatibles
|
||||||
|
|
||||||
These are the devices that should work with this library.
|
These are the devices that should work with this library.
|
||||||
Only the 4261 is tested.
|
However only the MCP4261 is tested.
|
||||||
|
|
||||||
| Number | Type | pots | POR | MaxValue | Notes |
|
| Number | Type | pots | POR | MaxValue | Notes |
|
||||||
|:--------:|:--------:|:------:|:--------:|:----------:|:--------|
|
|:--------:|:--------:|:------:|:--------:|:----------:|:--------|
|
||||||
| MCP4141 | Potmeter | 1 | NV-Wiper | 129 |
|
| MCP4141 | Potmeter | 1 | NV-Wiper | 128 |
|
||||||
| MCP4142 | Rheostat | 1 | NV-Wiper | 129 |
|
| MCP4142 | Rheostat | 1 | NV-Wiper | 128 |
|
||||||
| MCP4161 | Potmeter | 1 | NV-Wiper | 257 |
|
| MCP4161 | Potmeter | 1 | NV-Wiper | 256 |
|
||||||
| MCP4162 | Rheostat | 1 | NV-Wiper | 257 |
|
| MCP4162 | Rheostat | 1 | NV-Wiper | 256 |
|
||||||
| MCP4241 | Potmeter | 2 | NV-Wiper | 129 |
|
| MCP4241 | Potmeter | 2 | NV-Wiper | 128 |
|
||||||
| MCP4242 | Rheostat | 2 | NV-Wiper | 129 |
|
| MCP4242 | Rheostat | 2 | NV-Wiper | 128 |
|
||||||
| MCP4261 | Potmeter | 2 | NV-Wiper | 257 | base class
|
| MCP4261 | Potmeter | 2 | NV-Wiper | 256 | base class, under test.
|
||||||
| MCP4262 | Rheostat | 2 | NV-Wiper | 257 |
|
| MCP4262 | Rheostat | 2 | NV-Wiper | 256 |
|
||||||
|
|
||||||
To investigate:
|
|
||||||
|
#### To investigate:
|
||||||
|
|
||||||
MCP4131/32/51/52, MCP4231/32/51/52, these have no NV RAM so they
|
MCP4131/32/51/52, MCP4231/32/51/52, these have no NV RAM so they
|
||||||
have a POR power on reset of middle value (= half max value.
|
have a POR (power on reset) of the middle value (= half max value).
|
||||||
|
Support EEPROM?
|
||||||
|
|
||||||
MCP4151 Reichelt
|
|
||||||
MCP4262 Mouser
|
|
||||||
|
|
||||||
|
|
||||||
### Related
|
### Related
|
||||||
|
|
||||||
TODO: list of other digital pot meters / rheostats.
|
Mainly other digital potentiometers / rheostats.
|
||||||
|
|
||||||
|
- https://github.com/RobTillaart/AD520x
|
||||||
|
- https://github.com/RobTillaart/AD524X
|
||||||
|
- https://github.com/RobTillaart/AD5245
|
||||||
|
- https://github.com/RobTillaart/AD5144A
|
||||||
|
- https://github.com/RobTillaart/AD5263
|
||||||
|
- https://github.com/RobTillaart/MCP_POT
|
||||||
|
- https://github.com/RobTillaart/MCP4261
|
||||||
|
- https://github.com/RobTillaart/X9C10X
|
||||||
|
|
||||||
|
|
||||||
#### Related
|
#### Registers
|
||||||
|
|
||||||
|
Table 4.1 from datasheet (p 29)
|
||||||
|
|
||||||
|
| Address | Function | Memory Type | Notes |
|
||||||
| Address | Function | Memory Type |
|
|:---------:|:------------------------:|:--------------|:--------|
|
||||||
|:---------:|:------------------------:|:--------------|
|
| 00h | Volatile Wiper 0 | RAM | range 0..256 (128)
|
||||||
| 00h | Volatile Wiper 0 | RAM |
|
| 01h | Volatile Wiper 1 | RAM | range 0..256 (128)
|
||||||
| 01h | Volatile Wiper 1 | RAM |
|
| 02h | Non-Volatile Wiper 0 | EEPROM | set Power on Reset, range idem.
|
||||||
| 02h | Non-Volatile Wiper 0 | EEPROM |
|
| 03h | Non-Volatile Wiper 1 | EEPROM | set Power on Reset, range idem.
|
||||||
| 03h | Non-Volatile Wiper 1 | EEPROM |
|
|
||||||
| 04h | Volatile TCON Register | RAM |
|
| 04h | Volatile TCON Register | RAM |
|
||||||
| 05h | Status Register | RAM |
|
| 05h | Status Register | RAM | read only
|
||||||
| 06h | Data EEPROM | EEPROM |
|
| 06-0Fh | Data EEPROM | EEPROM | 10 values, range 0..511
|
||||||
| 07h | Data EEPROM | EEPROM |
|
|
||||||
| 08h | Data EEPROM | EEPROM |
|
Is this overview needed?
|
||||||
| 09h | Data EEPROM | EEPROM |
|
|
||||||
| 0Ah | Data EEPROM | EEPROM |
|
## Performance indication
|
||||||
| 0Bh | Data EEPROM | EEPROM |
|
|
||||||
| 0Ch | Data EEPROM | EEPROM |
|
See performance example.
|
||||||
| 0Dh | Data EEPROM | EEPROM |
|
|
||||||
| 0Eh | Data EEPROM | EEPROM |
|
Indicative times in microseconds, version 0.2.0
|
||||||
| 0Fh | Data EEPROM | EEPROM |
|
|
||||||
|
| | function | 1 MHz | 2 MHz | 4 MHz | 8 MHz | SW SPI |
|
||||||
|
|:-----:|:-----------------|:-------:|:-------:|:-------:|:-------:|:--------:|
|
||||||
|
| UNO | setValue | 34.4 | 26.4 | 22.3 | 20.3 | 312.5 |
|
||||||
|
| UNO | getValue | 0.8 | 0.8 | 0.8 | 0.8 | 0.8 |
|
||||||
|
| UNO | getValueDevice | 36.4 | 28.34 | 24.4 | 22.3 | 314.3 |
|
||||||
|
| UNO | incrValue | 24.2 | 20.2 | 18.2 | 17.2 | 162.9 |
|
||||||
|
| UNO | decrValue | 23.9 | 20.0 | 17.9 | 16.9 | 162.6 |
|
||||||
|
|
||||||
|
Other boards might be added.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- EEPROM and NON-Volatile registers read performance is in the same order as the
|
||||||
|
getValueDevice() function.
|
||||||
|
- EEPROM and NON-Volatile registers write performance is in the same order as the
|
||||||
|
setValue() function, however depends on if there was a recent write (< 5 ms ago).
|
||||||
|
|
||||||
|
|
||||||
## Interface
|
## Interface
|
||||||
@ -117,50 +150,90 @@ TODO: list of other digital pot meters / rheostats.
|
|||||||
### Constructor
|
### Constructor
|
||||||
|
|
||||||
- **MCP4261(uint8_t select, uint8_t shutdown, \__SPI_CLASS__ \* mySPI = &SPI)**
|
- **MCP4261(uint8_t select, uint8_t shutdown, \__SPI_CLASS__ \* mySPI = &SPI)**
|
||||||
HW SPI constructor.
|
HW SPI constructor. If the shutDown pin is not used, is should be set to 255.
|
||||||
- **MCP4261(uint8_t select, uint8_t shutdown, uint8_t dataIn, uint8_t dataOut, uint8_t clock)**
|
- **MCP4261(uint8_t select, uint8_t shutdown, uint8_t dataIn, uint8_t dataOut, uint8_t clock)**
|
||||||
SW SPI Constructor. The dataIn pin is not used yet.
|
SW SPI Constructor. If the shutDown pin is not used, is should be set to 255.
|
||||||
- **void begin(uint8_t value)** user must explicit set initial value.
|
- **void begin()** initializes the device and reads the default values of the two potmeters
|
||||||
- **void reset(uint8_t value)** user must explicit set initial value.
|
from the device. These values are cached.
|
||||||
|
- **void reset(uint16_t value)** resets the device, and sets both wipers to an explicit value.
|
||||||
- **uint8_t pmCount()** returns 1 or 2, depending on device type.
|
- **uint8_t pmCount()** returns 1 or 2, depending on device type.
|
||||||
|
|
||||||
|
|
||||||
### Set Volatile Values
|
### Set Volatile Values
|
||||||
|
|
||||||
- **bool setValue(uint8_t value)** set all potmeters to the same value. (wrapper).
|
- **bool setValue(uint16_t value)** set all potmeters to the same value. (wrapper).
|
||||||
|
Value can be 0..256 (128 depending on type).
|
||||||
Returns true.
|
Returns true.
|
||||||
- **bool setValue(uint8_t pm, uint8_t value)** set single potmeter (0 or 1).
|
- **bool setValue(uint8_t pm, uint16_t value)** set a single potmeter (0 or 1).
|
||||||
Returns false if pm > pmCount.
|
Returns false if pm > pmCount or if value too large.
|
||||||
- **uint8_t getValue(uint8_t pm = 0)** returns value from cache.
|
- **uint16_t getValue(uint8_t pm = 0)** returns value from cache. (fast).
|
||||||
- **bool incrValue(uint8_t pm)**
|
- **uint16_t getValueDevice(uint8_t pm = 0)** returns value from the device. (robust).
|
||||||
- **bool decrValue(uint8_t pm)**
|
- **bool incrValue(uint8_t pm = 0)** increments potmeter by 1 if possible.
|
||||||
|
Returns false if this fails, e.g. max value reached.
|
||||||
|
- **bool decrValue(uint8_t pm = 0)** decrements potmeter by 1 if possible.
|
||||||
|
Returns false if this fails, e.g. zero reached.
|
||||||
|
|
||||||
|
|
||||||
### Set Volatile Values
|
### Set NON-Volatile Values
|
||||||
|
|
||||||
**Experimental**
|
- **bool setValueNV(uint8_t pm, uint16_t value)** set the power on reset value for potmeter.
|
||||||
|
- **uint16_t getValueNV(uint8_t pm)** retrieves set value from device.
|
||||||
|
|
||||||
TODO: how does this fit in interface as reset() always sets a value.
|
The NV functions do not check the status register if an EEPROM write is pending.
|
||||||
|
If you want to write both registers you need to pause 5-10 ms between the calls.
|
||||||
|
|
||||||
- **bool setValueNV(uint8_t pm, uint16_t value)**
|
|
||||||
|
### Terminal Control register (TCON)
|
||||||
|
|
||||||
|
Needs more investigation how this works in detail.
|
||||||
|
|
||||||
|
To connect and disconnect the A, B and Wiper from the internal resistor array.
|
||||||
|
See datasheet form details.
|
||||||
|
|
||||||
|
- **void setTCONMask(uint16_t mask)**
|
||||||
|
- **uint16_t getTCONMask()**
|
||||||
|
|
||||||
|
|
||||||
|
### Status register
|
||||||
|
|
||||||
|
See datasheet form details.
|
||||||
|
|
||||||
|
- **uint16_t getStatusMask()** read only bit mask, (5 bits used).
|
||||||
|
|
||||||
|
| bit | Description | notes |
|
||||||
|
|:-----:|:----------------------|:--------|
|
||||||
|
| 0 | Write Protect |
|
||||||
|
| 1 | Shut Down |
|
||||||
|
| 2 | Wiper Lock 0 | not supported
|
||||||
|
| 3 | Wiper Lock 1 | not supported
|
||||||
|
| 4 | EEPROM Write Active |
|
||||||
|
|
||||||
|
|
||||||
### EEPROM
|
### EEPROM
|
||||||
|
|
||||||
Not implemented yet
|
- **bool setEEPROM(uint8_t index, uint16_t value)** index = 0..9 value = 0..511.
|
||||||
|
Returns false if index > 9 or value out of range.
|
||||||
|
- **uint16_t getEEPROM(uint8_t index)** Returns set value, or 0 if index > 9.
|
||||||
|
|
||||||
|
The EEPROM functions do not check the status register if an EEPROM write is
|
||||||
|
pending. (might take up to 10 ms).
|
||||||
|
|
||||||
|
If you want to write multiple registers you need to pause 5-10 ms between the calls.
|
||||||
|
|
||||||
### SPI
|
### SPI
|
||||||
|
|
||||||
Note changing the SPI speed might affect other devices on the same SPI bus.
|
Note changing the SPI speed might affect other devices on the same SPI bus.
|
||||||
So use with care.
|
So use with care.
|
||||||
|
|
||||||
- **void setSPIspeed(uint32_t speed)** default 1MHz, typical 4 MHz.
|
- **void setSPIspeed(uint32_t speed)** default 1 MHz, typical 4 MHz.
|
||||||
- **uint32_t getSPIspeed()** idem.
|
- **uint32_t getSPIspeed()** idem.
|
||||||
- **bool usesHWSPI()** idem.
|
- **bool usesHWSPI()** idem, depends on which constructor used.
|
||||||
|
|
||||||
|
|
||||||
### Power
|
### Power
|
||||||
|
|
||||||
|
Uses the shutdown pin from the constructor.
|
||||||
|
|
||||||
- **void powerOn()** idem.
|
- **void powerOn()** idem.
|
||||||
- **void powerOff()** idem.
|
- **void powerOff()** idem.
|
||||||
- **bool isPowerOn()** idem.
|
- **bool isPowerOn()** idem.
|
||||||
@ -174,29 +247,37 @@ So use with care.
|
|||||||
|
|
||||||
#### Should
|
#### Should
|
||||||
|
|
||||||
- read registers.
|
- investigate compatibility (what is supported)
|
||||||
- read values.
|
- MCP4131/32/51/52,
|
||||||
- status register
|
- MCP4231/32/51/52
|
||||||
- TCON
|
- pending EEPROM write?
|
||||||
|
- blocking 5-10 ms?, see page 10 datasheet.
|
||||||
|
- status check for EEPROM? (robust, also in MT environment)
|
||||||
|
- lastEE_timestamp? (fast, works if long ago)
|
||||||
|
- mix?
|
||||||
|
- What is a good strategy?
|
||||||
|
- **bool isEEWritePending()**? should be non-blocking.
|
||||||
|
- Also for the NV write function as one needs to write two registers.
|
||||||
|
- elaborate TCON settings.
|
||||||
|
- investigate behaviour.
|
||||||
|
|
||||||
#### Could
|
#### Could
|
||||||
|
|
||||||
- EEPROM support
|
- support write protect pin.
|
||||||
- 10 registers, 10 bit
|
- define pin, set, get
|
||||||
- bool writeEEPROM(address, uint16_t value);
|
- investigate error handling
|
||||||
- uint16_t readEEPROM(address);
|
|
||||||
- write to non-volatile register 02/03 to set Power On Reset values
|
|
||||||
- read when reset?
|
|
||||||
- how to fit in use model.
|
|
||||||
- unit tests
|
|
||||||
- examples
|
|
||||||
- error handling
|
|
||||||
- improve return values
|
- improve return values
|
||||||
- investigate performance
|
- investigate performance
|
||||||
- AVR SW SPI?
|
- extend performance sketch.
|
||||||
|
- other boards, extend table.
|
||||||
|
- AVR SW SPI? (only on request)
|
||||||
|
- const usage?
|
||||||
|
|
||||||
#### Won't
|
#### Won't
|
||||||
|
|
||||||
|
- add unit tests (takes too much time).
|
||||||
|
- High voltage functions
|
||||||
|
|
||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|
||||||
|
@ -25,13 +25,12 @@ void setup()
|
|||||||
|
|
||||||
SPI.begin();
|
SPI.begin();
|
||||||
|
|
||||||
pot.begin(0); // initial value
|
pot.begin();
|
||||||
|
|
||||||
// test_extremes();
|
test_extremes();
|
||||||
//test_sinus();
|
test_sinus();
|
||||||
test_sawtooth();
|
test_sawtooth();
|
||||||
test_incr_decr();
|
test_incr_decr();
|
||||||
//test_timing();
|
|
||||||
|
|
||||||
Serial.println("\nDone...");
|
Serial.println("\nDone...");
|
||||||
}
|
}
|
||||||
@ -115,33 +114,4 @@ void test_incr_decr()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void test_timing()
|
|
||||||
{
|
|
||||||
Serial.println(__FUNCTION__);
|
|
||||||
delay(10);
|
|
||||||
|
|
||||||
start = micros();
|
|
||||||
for (int i = 0; i < 1000; i++)
|
|
||||||
{
|
|
||||||
pot.setValue(0, i++); // auto wrap is fast...
|
|
||||||
}
|
|
||||||
stop = micros();
|
|
||||||
Serial.print("1000 x setValue():\t");
|
|
||||||
Serial.println(stop - start);
|
|
||||||
delay(10);
|
|
||||||
|
|
||||||
volatile int x = 0;
|
|
||||||
start = micros();
|
|
||||||
for (int i = 0; i < 500; i++)
|
|
||||||
{
|
|
||||||
x += pot.getValue(0);
|
|
||||||
x += pot.getValue(1);
|
|
||||||
}
|
|
||||||
stop = micros();
|
|
||||||
Serial.print("1000 x getValue():\t");
|
|
||||||
Serial.println(stop - start);
|
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -- END OF FILE --
|
// -- END OF FILE --
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
//
|
||||||
|
// FILE: MCP4261_demo_eeprom.ino
|
||||||
|
// AUTHOR: Rob Tillaart
|
||||||
|
// PURPOSE: demo
|
||||||
|
// URL: https://github.com/RobTillaart/MCP4261
|
||||||
|
|
||||||
|
|
||||||
|
#include "MCP4261.h"
|
||||||
|
|
||||||
|
|
||||||
|
// select, shutdown, dataIn, dataOut, clock == SOFTWARE SPI
|
||||||
|
// MCP4261 pot(10, 6, 7, 8, 9);
|
||||||
|
|
||||||
|
// select, shutdown, &SPI === HW SPI UNO clock = 13, dataOut = 11
|
||||||
|
MCP4261 pot(10, 6, &SPI);
|
||||||
|
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println(__FILE__);
|
||||||
|
|
||||||
|
SPI.begin();
|
||||||
|
|
||||||
|
pot.begin();
|
||||||
|
|
||||||
|
for (int address = 0; address < 10; address++)
|
||||||
|
{
|
||||||
|
Serial.print(address);
|
||||||
|
Serial.print("\t");
|
||||||
|
Serial.println(pot.getEEPROM(address));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int address = 0; address < 10; address++)
|
||||||
|
{
|
||||||
|
int x = random(512);
|
||||||
|
pot.setEEPROM(address, x);
|
||||||
|
delay(20);
|
||||||
|
Serial.println(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int address = 0; address < 10; address++)
|
||||||
|
{
|
||||||
|
Serial.print(address);
|
||||||
|
Serial.print("\t");
|
||||||
|
Serial.println(pot.getEEPROM(address));
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("\nDone...");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -- END OF FILE --
|
@ -0,0 +1,44 @@
|
|||||||
|
//
|
||||||
|
// FILE: MCP4261_demo_read.ino
|
||||||
|
// AUTHOR: Rob Tillaart
|
||||||
|
// PURPOSE: demo
|
||||||
|
// URL: https://github.com/RobTillaart/MCP4261
|
||||||
|
|
||||||
|
|
||||||
|
#include "MCP4261.h"
|
||||||
|
|
||||||
|
|
||||||
|
// select, shutdown, dataIn, dataOut, clock == SOFTWARE SPI
|
||||||
|
// MCP4261 pot(10, 6, 7, 8, 9);
|
||||||
|
|
||||||
|
// select, shutdown, &SPI === HW SPI UNO clock = 13, dataOut = 11
|
||||||
|
MCP4261 pot(10, 6, &SPI);
|
||||||
|
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println(__FILE__);
|
||||||
|
|
||||||
|
SPI.begin();
|
||||||
|
pot.begin();
|
||||||
|
|
||||||
|
for (int v = 0; v < 258; v++)
|
||||||
|
{
|
||||||
|
pot.setValue(1, v);
|
||||||
|
int x = pot.getValueDevice(1);
|
||||||
|
Serial.print(v);
|
||||||
|
Serial.print("\t");
|
||||||
|
Serial.println(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("\nDone...");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -- END OF FILE --
|
@ -0,0 +1,46 @@
|
|||||||
|
//
|
||||||
|
// FILE: MCP4261_demo_tcon.ino
|
||||||
|
// AUTHOR: Rob Tillaart
|
||||||
|
// PURPOSE: demo
|
||||||
|
// URL: https://github.com/RobTillaart/MCP4261
|
||||||
|
//
|
||||||
|
// needs investigation
|
||||||
|
|
||||||
|
#include "MCP4261.h"
|
||||||
|
|
||||||
|
|
||||||
|
// select, shutdown, dataIn, dataOut, clock == SOFTWARE SPI
|
||||||
|
// MCP4261 pot(10, 6, 7, 8, 9);
|
||||||
|
|
||||||
|
// select, shutdown, &SPI === HW SPI UNO clock = 13, dataOut = 11
|
||||||
|
MCP4261 pot(10, 6, &SPI);
|
||||||
|
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println(__FILE__);
|
||||||
|
|
||||||
|
SPI.begin();
|
||||||
|
|
||||||
|
pot.begin();
|
||||||
|
pot.setValue(123);
|
||||||
|
|
||||||
|
int status = pot.getStatusMask();
|
||||||
|
Serial.println(status);
|
||||||
|
|
||||||
|
int tcon = pot.getTCONMask();
|
||||||
|
Serial.println(tcon, BIN); // bit 8 always 1
|
||||||
|
|
||||||
|
// ??? TODO
|
||||||
|
|
||||||
|
Serial.println("\nDone...");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -- END OF FILE --
|
@ -13,10 +13,10 @@ uint32_t start, stop;
|
|||||||
|
|
||||||
|
|
||||||
// select, shutdown, dataIn, dataOut, clock == SOFTWARE SPI
|
// select, shutdown, dataIn, dataOut, clock == SOFTWARE SPI
|
||||||
// MCP4261 pot(10, 6, 7, 8, 9);
|
MCP4261 pot(10, 6, 7, 8, 9);
|
||||||
|
|
||||||
// select, shutdown, &SPI === HW SPI UNO clock = 13, data = 11
|
// select, shutdown, &SPI === HW SPI UNO clock = 13, data = 11
|
||||||
MCP4261 pot(10, 6, &SPI);
|
// MCP4261 pot(10, 6, &SPI);
|
||||||
|
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
@ -29,7 +29,7 @@ void setup()
|
|||||||
|
|
||||||
SPI.begin();
|
SPI.begin();
|
||||||
|
|
||||||
pot.begin(0); // initial value
|
pot.begin();
|
||||||
pot.setSPIspeed(1000000);
|
pot.setSPIspeed(1000000);
|
||||||
test_timing();
|
test_timing();
|
||||||
pot.setSPIspeed(2000000);
|
pot.setSPIspeed(2000000);
|
||||||
@ -84,6 +84,19 @@ void test_timing()
|
|||||||
Serial.println((stop - start) / 500.0);
|
Serial.println((stop - start) / 500.0);
|
||||||
delay(100);
|
delay(100);
|
||||||
|
|
||||||
|
start = micros();
|
||||||
|
for (int i = 0; i < 250; i++)
|
||||||
|
{
|
||||||
|
x += pot.getValueDevice(0);
|
||||||
|
x += pot.getValueDevice(1);
|
||||||
|
}
|
||||||
|
stop = micros();
|
||||||
|
Serial.print("500 x getValueDevice():\t");
|
||||||
|
Serial.print(stop - start);
|
||||||
|
Serial.print("\t");
|
||||||
|
Serial.println((stop - start) / 500.0);
|
||||||
|
delay(100);
|
||||||
|
|
||||||
pot.setValue(0);
|
pot.setValue(0);
|
||||||
start = micros();
|
start = micros();
|
||||||
for (int i = 0; i < 250; i++)
|
for (int i = 0; i < 250; i++)
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
|
||||||
|
BOARD: Arduino UNO
|
||||||
|
IDE: 1.8.19
|
||||||
|
|
||||||
|
MCP4261_performance.ino
|
||||||
|
MCP4261_LIB_VERSION: 0.2.0
|
||||||
|
|
||||||
|
HW SPI
|
||||||
|
|
||||||
|
|
||||||
|
test_timing
|
||||||
|
SPI: 1000000
|
||||||
|
500 x setValue(): 156244 312.49
|
||||||
|
500 x getValue(): 388 0.78
|
||||||
|
500 x getValueDevice(): 157156 314.31
|
||||||
|
500 x incrValue(): 81420 162.84
|
||||||
|
500 x decrValue(): 81304 162.61
|
||||||
|
|
||||||
|
test_timing
|
||||||
|
SPI: 2000000
|
||||||
|
500 x setValue(): 156240 312.48
|
||||||
|
500 x getValue(): 380 0.76
|
||||||
|
500 x getValueDevice(): 157156 314.31
|
||||||
|
500 x incrValue(): 81428 162.86
|
||||||
|
500 x decrValue(): 81296 162.59
|
||||||
|
|
||||||
|
test_timing
|
||||||
|
SPI: 4000000
|
||||||
|
500 x setValue(): 156236 312.47
|
||||||
|
500 x getValue(): 380 0.76
|
||||||
|
500 x getValueDevice(): 157152 314.30
|
||||||
|
500 x incrValue(): 81424 162.85
|
||||||
|
500 x decrValue(): 81296 162.59
|
||||||
|
|
||||||
|
test_timing
|
||||||
|
SPI: 8000000
|
||||||
|
500 x setValue(): 156240 312.48
|
||||||
|
500 x getValue(): 380 0.76
|
||||||
|
500 x getValueDevice(): 157148 314.30
|
||||||
|
500 x incrValue(): 81428 162.86
|
||||||
|
500 x decrValue(): 81296 162.59
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SW SPI
|
||||||
|
|
||||||
|
500 x setValue(): 156240 312.48
|
||||||
|
500 x getValue(): 380 0.76
|
||||||
|
500 x getValueDevice(): 157148 314.30
|
||||||
|
500 x incrValue(): 81428 162.86
|
||||||
|
500 x decrValue(): 81296 162.59
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Done...
|
@ -0,0 +1,32 @@
|
|||||||
|
platforms:
|
||||||
|
rpipico:
|
||||||
|
board: rp2040:rp2040:rpipico
|
||||||
|
package: rp2040:rp2040 # name:architecture:board
|
||||||
|
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
|
||||||
|
teensy:Teensy:
|
||||||
|
url: https://www.pjrc.com/teensy/package_teensy_index.json
|
||||||
|
|
||||||
|
|
||||||
|
compile:
|
||||||
|
# Choosing to run compilation tests on 2 different Arduino platforms
|
||||||
|
platforms:
|
||||||
|
# - uno
|
||||||
|
# - due
|
||||||
|
# - zero
|
||||||
|
# - leonardo
|
||||||
|
# - m4
|
||||||
|
# - esp32
|
||||||
|
# - esp8266
|
||||||
|
# - mega2560
|
||||||
|
# - rpipico
|
||||||
|
|
@ -0,0 +1,48 @@
|
|||||||
|
//
|
||||||
|
// FILE: MCP4261_register_read.ino
|
||||||
|
// AUTHOR: Rob Tillaart
|
||||||
|
// PURPOSE: demo
|
||||||
|
// URL: https://github.com/RobTillaart/MCP4261
|
||||||
|
//
|
||||||
|
// Works when readRegister() is made public.
|
||||||
|
// meant for testing only.
|
||||||
|
|
||||||
|
#include "MCP4261.h"
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t start, stop;
|
||||||
|
|
||||||
|
|
||||||
|
// select, shutdown, dataIn, dataOut, clock == SOFTWARE SPI
|
||||||
|
// MCP4261 pot(10, 6, 7, 8, 9);
|
||||||
|
|
||||||
|
// select, shutdown, &SPI === HW SPI UNO clock = 13, dataOut = 11
|
||||||
|
MCP4261 pot(10, 6, &SPI);
|
||||||
|
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println(__FILE__);
|
||||||
|
|
||||||
|
SPI.begin();
|
||||||
|
|
||||||
|
pot.begin();
|
||||||
|
|
||||||
|
for (int r = 0; r < 16; r++)
|
||||||
|
{
|
||||||
|
Serial.print(r);
|
||||||
|
Serial.print("\t");
|
||||||
|
Serial.println(pot.readRegister(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("\nDone...");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -- END OF FILE --
|
@ -19,21 +19,31 @@ pmCount KEYWORD2
|
|||||||
|
|
||||||
setValue KEYWORD2
|
setValue KEYWORD2
|
||||||
getValue KEYWORD2
|
getValue KEYWORD2
|
||||||
|
getValueDevice KEYWORD2
|
||||||
|
|
||||||
incrValue KEYWORD2
|
incrValue KEYWORD2
|
||||||
decrValue KEYWORD2
|
decrValue KEYWORD2
|
||||||
|
|
||||||
setValueNV KEYWORD2
|
setValueNV KEYWORD2
|
||||||
|
getValueNV KEYWORD2
|
||||||
|
|
||||||
setSPIspeed KEYWORD2
|
setTCONMask KEYWORD2
|
||||||
getSPIspeed KEYWORD2
|
getTCONMask KEYWORD2
|
||||||
|
getStatusMask KEYWORD2
|
||||||
|
|
||||||
|
setEEPROM KEYWORD2
|
||||||
|
getEEPROM KEYWORD2
|
||||||
|
|
||||||
powerOn KEYWORD2
|
powerOn KEYWORD2
|
||||||
powerOff KEYWORD2
|
powerOff KEYWORD2
|
||||||
isPowerOn KEYWORD2
|
isPowerOn KEYWORD2
|
||||||
|
|
||||||
|
setSPIspeed KEYWORD2
|
||||||
|
getSPIspeed KEYWORD2
|
||||||
|
|
||||||
usesHWSPI KEYWORD2
|
usesHWSPI KEYWORD2
|
||||||
|
|
||||||
|
|
||||||
# Constants (LITERAL1)
|
# Constants (LITERAL1)
|
||||||
MCP4261_LIB_VERSION LITERAL1
|
MCP4261_LIB_VERSION LITERAL1
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/RobTillaart/MCP4261.git"
|
"url": "https://github.com/RobTillaart/MCP4261.git"
|
||||||
},
|
},
|
||||||
"version": "0.1.0",
|
"version": "0.2.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"frameworks": "*",
|
"frameworks": "*",
|
||||||
"platforms": "*",
|
"platforms": "*",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
name=MCP4261
|
name=MCP4261
|
||||||
version=0.1.0
|
version=0.2.0
|
||||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||||
sentence=Arduino library for MCP4261 SPI based digital potentiometers.
|
sentence=Arduino library for MCP4261 SPI based digital potentiometers.
|
||||||
|
@ -40,9 +40,9 @@ unittest_teardown()
|
|||||||
unittest(test_constants)
|
unittest(test_constants)
|
||||||
{
|
{
|
||||||
assertEqual(64, MCP41XX_MIDDLE_VALUE);
|
assertEqual(64, MCP41XX_MIDDLE_VALUE);
|
||||||
assertEqual(129, MCP41XX_MAX_VALUE);
|
assertEqual(128, MCP41XX_MAX_VALUE);
|
||||||
assertEqual(129, MCP42XX_MIDDLE_VALUE);
|
assertEqual(128, MCP42XX_MIDDLE_VALUE);
|
||||||
assertEqual(257, MCP42XX_MAX_VALUE);
|
assertEqual(256, MCP42XX_MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user