From 009a98153794b5796834b9827a864469149e3053 Mon Sep 17 00:00:00 2001 From: Rob Tillaart Date: Wed, 6 Mar 2024 22:09:22 +0100 Subject: [PATCH] 0.1.0 MAX520 --- libraries/MAX520/.arduino-ci.yml | 27 +++ libraries/MAX520/.github/FUNDING.yml | 4 + .../MAX520/.github/workflows/arduino-lint.yml | 13 ++ .../.github/workflows/arduino_test_runner.yml | 17 ++ .../MAX520/.github/workflows/jsoncheck.yml | 18 ++ libraries/MAX520/CHANGELOG.md | 10 ++ libraries/MAX520/LICENSE | 21 +++ libraries/MAX520/MAX520.cpp | 163 ++++++++++++++++++ libraries/MAX520/MAX520.h | 67 +++++++ libraries/MAX520/README.md | 157 +++++++++++++++++ .../examples/MAX520_demo/MAX520_demo.ino | 41 +++++ .../examples/MAX521_demo/MAX521_demo.ino | 42 +++++ libraries/MAX520/keywords.txt | 27 +++ libraries/MAX520/library.json | 23 +++ libraries/MAX520/library.properties | 11 ++ libraries/MAX520/test/unit_test_001.cpp | 73 ++++++++ 16 files changed, 714 insertions(+) create mode 100644 libraries/MAX520/.arduino-ci.yml create mode 100644 libraries/MAX520/.github/FUNDING.yml create mode 100644 libraries/MAX520/.github/workflows/arduino-lint.yml create mode 100644 libraries/MAX520/.github/workflows/arduino_test_runner.yml create mode 100644 libraries/MAX520/.github/workflows/jsoncheck.yml create mode 100644 libraries/MAX520/CHANGELOG.md create mode 100644 libraries/MAX520/LICENSE create mode 100644 libraries/MAX520/MAX520.cpp create mode 100644 libraries/MAX520/MAX520.h create mode 100644 libraries/MAX520/README.md create mode 100644 libraries/MAX520/examples/MAX520_demo/MAX520_demo.ino create mode 100644 libraries/MAX520/examples/MAX521_demo/MAX521_demo.ino create mode 100644 libraries/MAX520/keywords.txt create mode 100644 libraries/MAX520/library.json create mode 100644 libraries/MAX520/library.properties create mode 100644 libraries/MAX520/test/unit_test_001.cpp diff --git a/libraries/MAX520/.arduino-ci.yml b/libraries/MAX520/.arduino-ci.yml new file mode 100644 index 00000000..25980972 --- /dev/null +++ b/libraries/MAX520/.arduino-ci.yml @@ -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 diff --git a/libraries/MAX520/.github/FUNDING.yml b/libraries/MAX520/.github/FUNDING.yml new file mode 100644 index 00000000..90d9ab4c --- /dev/null +++ b/libraries/MAX520/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms + +github: RobTillaart + diff --git a/libraries/MAX520/.github/workflows/arduino-lint.yml b/libraries/MAX520/.github/workflows/arduino-lint.yml new file mode 100644 index 00000000..8a26f14a --- /dev/null +++ b/libraries/MAX520/.github/workflows/arduino-lint.yml @@ -0,0 +1,13 @@ + +name: Arduino-lint + +on: [push, pull_request] +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: arduino/arduino-lint-action@v1 + with: + library-manager: update + compliance: strict diff --git a/libraries/MAX520/.github/workflows/arduino_test_runner.yml b/libraries/MAX520/.github/workflows/arduino_test_runner.yml new file mode 100644 index 00000000..fadfa904 --- /dev/null +++ b/libraries/MAX520/.github/workflows/arduino_test_runner.yml @@ -0,0 +1,17 @@ +--- +name: Arduino CI + +on: [push, pull_request] + +jobs: + runTest: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.6 + - run: | + gem install arduino_ci + arduino_ci.rb diff --git a/libraries/MAX520/.github/workflows/jsoncheck.yml b/libraries/MAX520/.github/workflows/jsoncheck.yml new file mode 100644 index 00000000..37a11298 --- /dev/null +++ b/libraries/MAX520/.github/workflows/jsoncheck.yml @@ -0,0 +1,18 @@ +name: JSON check + +on: + push: + paths: + - '**.json' + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: json-syntax-check + uses: limitusus/json-syntax-check@v1 + with: + pattern: "\\.json$" + diff --git a/libraries/MAX520/CHANGELOG.md b/libraries/MAX520/CHANGELOG.md new file mode 100644 index 00000000..6d5161dd --- /dev/null +++ b/libraries/MAX520/CHANGELOG.md @@ -0,0 +1,10 @@ +# Change Log MAX520/521 + +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.1.0] - 2024-03-06 +- initial version diff --git a/libraries/MAX520/LICENSE b/libraries/MAX520/LICENSE new file mode 100644 index 00000000..37fe70e5 --- /dev/null +++ b/libraries/MAX520/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024-2024 Rob Tillaart + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libraries/MAX520/MAX520.cpp b/libraries/MAX520/MAX520.cpp new file mode 100644 index 00000000..28a94bba --- /dev/null +++ b/libraries/MAX520/MAX520.cpp @@ -0,0 +1,163 @@ +// +// FILE: MAX520.cpp +// AUTHOR: Rob Tillaart +// DATE: 2024-03-06 +// VERSION: 0.1.0 +// PURPOSE: Arduino library for MAX520/521 4/8 channel 8 bit DAC. +// URL: https://github.com/RobTillaart/MAX520 + + +#include "MAX520.h" + +#define MAX520_RESET 0x10 +#define MAX520_POWERDOWN 0x08 +#define MAX520_WAKEUP 0x00 + + +/////////////////////////////////////////////////////////// +// +// CONSTRUCTOR +// +MAX520::MAX520(const uint8_t deviceAddress, TwoWire *wire) +{ + _address = deviceAddress; + _wire = wire; + _channels = 4; + _error = MAX520_OK; +} + + +bool MAX520::begin() +{ + if (! isConnected()) return false; + for (int i = 0; i < _channels; i++) + { + _values[i] = 0; + } + return true; +} + + +bool MAX520::isConnected() +{ + _wire->beginTransmission(_address); + return ( _wire->endTransmission() == 0); +} + + +bool MAX520::setAddress(const uint8_t deviceAddress) +{ + _address = deviceAddress; + return isConnected(); +} + + +uint8_t MAX520::getAddress() +{ + return _address; +} + + +uint8_t MAX520::getChannels() +{ + return _channels; +} + + +/////////////////////////////////////////////////////////// +// +// READ WRITE +// +int MAX520::write(uint8_t channel, uint8_t value) +{ + if (channel >= _channels) return MAX520_CHANNEL_ERROR; + + _values[channel] = value; + + uint8_t command = channel; + _wire->beginTransmission(_address); + _wire->write(command); + _wire->write(value); + return _wire->endTransmission(); +} + + +// TODO optimize. page 11 figure 7 +int MAX520::write(uint8_t * values) +{ + for (int i = 0; i < _channels; i++) + { + uint8_t rv = write(i, values[i]); + if (rv != MAX520_OK) + { + return rv; + } + } + return MAX520_OK; +} + + +int MAX520::read(uint8_t channel) +{ + if (channel >= _channels) + { + _error = MAX520_CHANNEL_ERROR; + return 255; // buggy + } + _error = MAX520_OK; + return _values[channel]; +} + + +/////////////////////////////////////////////////////////// +// +// RESET (page 11) and POWER DOWN (page12) +// +int MAX520::reset() +{ + _wire->beginTransmission(_address); + _wire->write(MAX520_RESET); + return _wire->endTransmission(); +} + + +int MAX520::powerDown() +{ + _wire->beginTransmission(_address); + _wire->write(MAX520_POWERDOWN); + return _wire->endTransmission(); +} + + +int MAX520::wakeUp() +{ + _wire->beginTransmission(_address); + _wire->write(MAX520_WAKEUP); + return _wire->endTransmission(); +} + + +/////////////////////////////////////////////////////////// +// +// DEBUG +// +int MAX520::lastError() +{ + int e = _error; + _error = MAX520_OK; // reset error after read, is this wise? + return e; +} + + +/////////////////////////////////////////////////////////// +// +// DERIVED CLASS MAX521 +// +MAX521::MAX521(uint8_t deviceAddress, TwoWire *wire) : MAX520(deviceAddress, wire) +{ + _channels = 8; +} + + +// -- END OF FILE -- + diff --git a/libraries/MAX520/MAX520.h b/libraries/MAX520/MAX520.h new file mode 100644 index 00000000..7143b996 --- /dev/null +++ b/libraries/MAX520/MAX520.h @@ -0,0 +1,67 @@ +#pragma once +// +// FILE: MAX520.h +// AUTHOR: Rob Tillaart +// DATE: 2024-03-06 +// VERSION: 0.1.0 +// PURPOSE: Arduino library for MAX520/521 4/8 channel 8 bit DAC. +// URL: https://github.com/RobTillaart/MAX520 + + +#include "Arduino.h" +#include "Wire.h" + + +#define MAX520_LIB_VERSION (F("0.1.0")) + +#define MAX520_OK 0x00 +#define MAX520_CHANNEL_ERROR 0x81 +#define MAX520_I2C_ERROR 0x82 + + +class MAX520 +{ +public: + explicit MAX520(uint8_t deviceAddress = 0x20, TwoWire *wire = &Wire); + + bool begin(); + bool isConnected(); + + + // note: setting the address corrupt internal buffer values + // a read8() / write8() call updates them. + bool setAddress(uint8_t deviceAddress); + uint8_t getAddress(); + + uint8_t getChannels(); + + int write(uint8_t channel, uint8_t value); + int write(uint8_t * values); // write 4/8 values at once. + int read(uint8_t channel); + + int reset(); + int powerDown(); + int wakeUp(); + + int lastError(); + +protected: + uint8_t _address; + uint8_t _channels; + uint8_t _values[8]; + int _error; + + TwoWire* _wire; +}; + + +class MAX521 : public MAX520 +{ +public: + MAX521(uint8_t deviceAddress = 0x20, TwoWire *wire = &Wire); +}; + + + +// -- END OF FILE -- + diff --git a/libraries/MAX520/README.md b/libraries/MAX520/README.md new file mode 100644 index 00000000..7b514034 --- /dev/null +++ b/libraries/MAX520/README.md @@ -0,0 +1,157 @@ + +[![Arduino CI](https://github.com/RobTillaart/MAX520/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci) +[![Arduino-lint](https://github.com/RobTillaart/MAX520/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/MAX520/actions/workflows/arduino-lint.yml) +[![JSON check](https://github.com/RobTillaart/MAX520/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/MAX520/actions/workflows/jsoncheck.yml) +[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/MAX520.svg)](https://github.com/RobTillaart/MAX520/issues) + +[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/MAX520/blob/master/LICENSE) +[![GitHub release](https://img.shields.io/github/release/RobTillaart/MAX520.svg?maxAge=3600)](https://github.com/RobTillaart/MAX520/releases) +[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/MAX520.svg)](https://registry.platformio.org/libraries/robtillaart/MAX520) + + +# MAX520 + +Arduino library for MAX520/521 4/8 channel 8 bit DAC. + + +## Description + +**Experimental** + +The MAX520 is a 4 channel 8 bit DAC. It has no output buffer amplifiers, +giving it very low supply current. + +The output range of the MAX520 4 DACs depends on the 4 VREF inputs. +You can have e.g. one from 0.0-5.0V one from 0.0-3.3V and two from 0.0-2.5V. + + +The MAX521 is a 8 channel 8 bit DAC. +The output range of the MAX521 8 DACs depends on the **FIVE** VREF inputs. +OUT0..OUT3 use VREF0..VREF3 and OUT4..OUT7 all use VREF4. + + +After calling **begin()** the user has to write the values per DAC or call **reset()** + +#### Related + +TODO other DAC libraries. + + + +## I2C + +#### I2C addresses + +| device | address pins | addresses | +|:--------:|:--------------:|:--------------:| +| MAX520 | 3 | 0x20 .. 0x27 | +| MAX521 | 2 | 0x20 .. 0x23 | + + +#### I2C Performance + +up to 400 KHz. + + +#### I2C multiplexing + +Sometimes you need to control more devices than possible with the default +address range the device provides. +This is possible with an I2C multiplexer e.g. TCA9548 which creates up +to eight channels (think of it as I2C subnets) which can use the complete +address range of the device. + +Drawback of using a multiplexer is that it takes more administration in +your code e.g. which device is on which channel. +This will slow down the access, which must be taken into account when +deciding which devices are on which channel. +Also note that switching between channels will slow down other devices +too if they are behind the multiplexer. + +- https://github.com/RobTillaart/TCA9548 + + +## Interface + +```cpp +#include "MAX520.h" +``` + +**MAX520_INITIAL_VALUE** is a define 0xFF that can be set compile time or before +the include of "MAX520.h" to overrule the default value used with the **begin()** call. + + +#### Constructor + +- **MAX520(uint8_t deviceAddress = 0x20, TwoWire \*wire = &Wire)** Constructor with optional address, default 0x20, +and the optional Wire interface as parameter. +- **bool begin(uint8_t value = MAX520_INITIAL_VALUE)** set the initial value (default 0xFF) for the DACS. +- **bool isConnected()** checks if the address set in the constructor or by **setAddress()** is visible on the I2C bus. +- **bool setAddress(uint8_t deviceAddress)** sets the device address after construction. +Can be used to switch between MAX520 modules runtime. Note this corrupts internal buffered values, +so one might need to call **write()** again. Returns true if address can be found on I2C bus. +- **uint8_t getAddress()** Returns the device address. +- **uint8_t getChannels()** Returns the number of channels (4 or 8). + + +#### Read and Write + +- **int write(uint8_t channel, uint8_t value)** writes value to chosen DAC. +- **int write(uint8_t \* values)** writes to all DACs. user must take care that array is large enough (4/8). +- **int read(uint8_t channel)** returns the last written value to chosen DAC. (from cache). + + +#### Reset and power down + +- **int reset()** TODO what values? +- **int powerDown()** +- **int wakeUp()** + +TODO + +#### Miscellaneous + +- **int lastError()** returns the last error from the lib. (see .h file). + + +## Error codes + +| name | value | description | +|:-----------------------|:-------:|:--------------------------| +| MAX520_OK | 0x00 | no error | +| MAX520_CHANNEL_ERROR | 0x81 | channel nr out of range | +| MAX520_I2C_ERROR | 0x82 | I2C communication error | + + + +## Future + +#### Must + +- improve documentation. +- test with hardware +- stabilize. + +#### Should + +- error handling + +#### Could + + + +#### Wont + +- add percentage API +- add vref array + add voltage interface + + +## Support + +If you appreciate my libraries, you can support the development and maintenance. +Improve the quality of the libraries by providing issues and Pull Requests, or +donate through PayPal or GitHub sponsors. + +Thank you, + + diff --git a/libraries/MAX520/examples/MAX520_demo/MAX520_demo.ino b/libraries/MAX520/examples/MAX520_demo/MAX520_demo.ino new file mode 100644 index 00000000..bd330b91 --- /dev/null +++ b/libraries/MAX520/examples/MAX520_demo/MAX520_demo.ino @@ -0,0 +1,41 @@ +// +// FILE: MAX520_demo.ino +// AUTHOR: Rob Tillaart +// PURPOSE: demo MAX520 +// URL: https://github.com/RobTillaart/MAX520 + + +#include "MAX520.h" + +MAX520 mx(0x38); + + +void setup() +{ + Serial.begin(115200); + Serial.println(__FILE__); + Serial.print("MAX520_LIB_VERSION:\t"); + Serial.println(MAX520_LIB_VERSION); + + Wire.begin(); + + mx.begin(); + +} + + +void loop() +{ + for (int ch = 0; ch < mx.getChannels(); ch++) + { + for (int value = 0; value < 256; value++) + { + mx.write(ch, value); + delay(100); + Serial.println(mx.read(ch)); + } + } +} + + +// -- END OF FILE -- diff --git a/libraries/MAX520/examples/MAX521_demo/MAX521_demo.ino b/libraries/MAX520/examples/MAX521_demo/MAX521_demo.ino new file mode 100644 index 00000000..10ea5c31 --- /dev/null +++ b/libraries/MAX520/examples/MAX521_demo/MAX521_demo.ino @@ -0,0 +1,42 @@ +// +// FILE: MAX521_demo.ino +// AUTHOR: Rob Tillaart +// PURPOSE: demo MAX521 +// URL: https://github.com/RobTillaart/MAX520 + + +#include "MAX520.h" + +MAX521 mx(0x38); + + +void setup() +{ + Serial.begin(115200); + Serial.println(__FILE__); + Serial.print("MAX520_LIB_VERSION:\t"); + Serial.println(MAX520_LIB_VERSION); + + Wire.begin(); + + mx.begin(); + +} + + +void loop() +{ + for (int ch = 0; ch < mx.getChannels(); ch++) + { + for (int value = 0; value < 256; value++) + { + mx.write(ch, value); + delay(100); + Serial.println(mx.read(ch)); + } + } +} + + +// -- END OF FILE -- + diff --git a/libraries/MAX520/keywords.txt b/libraries/MAX520/keywords.txt new file mode 100644 index 00000000..363c0727 --- /dev/null +++ b/libraries/MAX520/keywords.txt @@ -0,0 +1,27 @@ +# Syntax Colouring Map for MAX520 + + +# Data types (KEYWORD1) +MAX520 KEYWORD1 + + +# Methods and Functions (KEYWORD2) +begin KEYWORD2 +isConnected KEYWORD2 +setAddress KEYWORD2 +getAddress KEYWORD2 + +getChannels KEYWORD2 + +write KEYWORD2 +read KEYWORD2 + + +# Constants ( LITERAL1) +MAX520_LIB_VERSION LITERAL1 + +MAX520_OK LITERAL1 +PCF8574_OK LITERAL1 +MAX520_CHANNEL_ERROR LITERAL1 +MAX520_I2C_ERROR LITERAL1 + diff --git a/libraries/MAX520/library.json b/libraries/MAX520/library.json new file mode 100644 index 00000000..02cb046e --- /dev/null +++ b/libraries/MAX520/library.json @@ -0,0 +1,23 @@ +{ + "name": "MAX520", + "keywords": "I2C, MAX520, MAX521, DAC", + "description": "Arduino library for MAX520/521 4/8 channel 8 bit DAC.", + "authors": + [ + { + "name": "Rob Tillaart", + "email": "Rob.Tillaart@gmail.com", + "maintainer": true + } + ], + "repository": + { + "type": "git", + "url": "https://github.com/RobTillaart/MAX520.git" + }, + "version": "0.1.0", + "license": "MIT", + "frameworks": "*", + "platforms": "*", + "headers": "MAX520.h" +} diff --git a/libraries/MAX520/library.properties b/libraries/MAX520/library.properties new file mode 100644 index 00000000..d3e75ba2 --- /dev/null +++ b/libraries/MAX520/library.properties @@ -0,0 +1,11 @@ +name=MAX520 +version=0.1.0 +author=Rob Tillaart +maintainer=Rob Tillaart +sentence=Arduino library for MAX520/521 4/8 channel 8 bit DAC. +paragraph= +category=Signal Input/Output +url=https://github.com/RobTillaart/MAX520.git +architectures=* +includes=MAX520.h +depends= diff --git a/libraries/MAX520/test/unit_test_001.cpp b/libraries/MAX520/test/unit_test_001.cpp new file mode 100644 index 00000000..0997137e --- /dev/null +++ b/libraries/MAX520/test/unit_test_001.cpp @@ -0,0 +1,73 @@ +// +// FILE: unit_test_001.cpp +// AUTHOR: Rob Tillaart +// VERSION: 0.1.0 +// DATE: 2024-03-06 +// PURPOSE: unit tests for the MAX520/521 4/8 channel DAC +// https://github.com/RobTillaart/MAX520 +// https://github.com/Arduino-CI/arduino_ci/blob/master/REFERENCE.md +// + +// supported assertions +// ---------------------------- +// assertEqual(expected, actual); // a == b +// assertNotEqual(unwanted, actual); // a != b +// assertComparativeEquivalent(expected, actual); // abs(a - b) == 0 or (!(a > b) && !(a < b)) +// assertComparativeNotEquivalent(unwanted, actual); // abs(a - b) > 0 or ((a > b) || (a < b)) +// assertLess(upperBound, actual); // a < b +// assertMore(lowerBound, actual); // a > b +// assertLessOrEqual(upperBound, actual); // a <= b +// assertMoreOrEqual(lowerBound, actual); // a >= b +// assertTrue(actual); +// assertFalse(actual); +// assertNull(actual); + +// // special cases for floats +// assertEqualFloat(expected, actual, epsilon); // fabs(a - b) <= epsilon +// assertNotEqualFloat(unwanted, actual, epsilon); // fabs(a - b) >= epsilon +// assertInfinity(actual); // isinf(a) +// assertNotInfinity(actual); // !isinf(a) +// assertNAN(arg); // isnan(a) +// assertNotNAN(arg); // !isnan(a) + +#include + + +#include "Arduino.h" +#include "MAX520.h" + + +MAX520 mx(0x38); + + +unittest_setup() +{ + fprintf(stderr, "MAX520_LIB_VERSION: %s\n", (char *) MAX520_LIB_VERSION); +} + + +unittest_teardown() +{ +} + + +unittest(test_begin) +{ + MAX520 mx0(0x38); + Wire.begin(); + mx0.begin(); + assertEqual(4, mx0.getChannels()); + + + MAX521 mx1(0x38); + Wire.begin(); + mx1.begin(); + assertEqual(8, mx1.getChannels()); +} + + +unittest_main() + + +// -- END OF FILE -- +