0.1.0 MAX520

This commit is contained in:
Rob Tillaart 2024-03-06 22:09:22 +01:00
parent 55152137f2
commit 009a981537
16 changed files with 714 additions and 0 deletions

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

4
libraries/MAX520/.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,4 @@
# These are supported funding model platforms
github: RobTillaart

View File

@ -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

View File

@ -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

View File

@ -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$"

View File

@ -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

21
libraries/MAX520/LICENSE Normal file
View File

@ -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.

163
libraries/MAX520/MAX520.cpp Normal file
View File

@ -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 --

67
libraries/MAX520/MAX520.h Normal file
View File

@ -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 --

157
libraries/MAX520/README.md Normal file
View File

@ -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,

View File

@ -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 --

View File

@ -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 --

View File

@ -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

View File

@ -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"
}

View File

@ -0,0 +1,11 @@
name=MAX520
version=0.1.0
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
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=

View File

@ -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 <ArduinoUnitTests.h>
#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 --