0.1.0 M5ANGLE8

This commit is contained in:
Rob Tillaart 2023-08-04 11:48:55 +02:00
parent 0ae3c7fcf6
commit 32b114e1b6
19 changed files with 837 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

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 M5ANGLE8
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] - 2023-08-03
- initial version

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023-2023 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.

View File

@ -0,0 +1,125 @@
[![Arduino CI](https://github.com/RobTillaart/M5ANGLE8/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
[![Arduino-lint](https://github.com/RobTillaart/M5ANGLE8/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/M5ANGLE8/actions/workflows/arduino-lint.yml)
[![JSON check](https://github.com/RobTillaart/M5ANGLE8/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/M5ANGLE8/actions/workflows/jsoncheck.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/M5ANGLE8/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/release/RobTillaart/M5ANGLE8.svg?maxAge=3600)](https://github.com/RobTillaart/M5ANGLE8/releases)
# M5ANGLE8
Arduino library for M5 8ANGLE 8x12 bit potentiometers.
## Description
**Experimental**
M5ANGLE8 is an Arduino class to read the potentiometers of the M5 8ANGLE module.
It also provides means to write RGB values to the 8 LED's in the same module.
The potentiometers can be read with 8 bit (faster) or 12 bit.
Derived from the latter this library also supports 9, 10 and 11 bit.
So the range can be chosen to match your application.
Furthermore the library can set the RGB value + brightness of the 8 LEDS.
No tests with hardware have been done yet, so use with care.
Feedback welcome!
#### I2C
The address range is in theory from 0..127, however the I2C specification
states it should be between 8 and 119 as some addresses are reserved.
TODO to what clock does it work?
| clock | works |
|:-------:|:-------:|
| 100 KHz | |
| 200 KHz | |
| 400 KHz | |
| 600 KHz | |
| 800 KHz | |
#### Accuracy
- how stable are the potentiometers? noise?
- how easy are they set "exactly"?
280° for 4095 values is 14~15 steps per degree.
#### Related
- https://github.com/RobTillaart/GAMMA
- https://github.com/RobTillaart/map2colour
## Interface
```cpp
#include "M5ANGLE8.h"
```
- **M5ANGLE8(uint8_t address = M5ANGLE8_DEFAULT_ADDRESS, TwoWire \*wire = &Wire)** constructor.
Default address = 0x43, default Wire.
- **bool begin(int sda, int scl)** ESP32 et al.
- **bool begin()** initialize I2C, check if connected.
- **bool isConnected()** checks if address is on the I2C bus.
- **bool setAddress(uint8_t address = M5ANGLE8_DEFAULT_ADDRESS)** set a new address for the device.
Default 0x43.
- **uint8_t getAddress()** convenience function.
- **uint8_t getVersion()** get firmware version from device.
#### IO part
- **uint16_t analogRead(uint8_t channel, uint8_t resolution = 12)**
Read a potentiometer, resolution can be set from 8..12 bit, constrained.
- **uint8_t inputSwitch()** read status of the switch.
- **bool writeRGB(uint8_t channel, uint8_t R, uint8_t G, uint8_t B, uint8_t brightness)**
Set the RGB value and brightness of a LED.
- **bool allOff()** switch all LEDs off.
Returns true.
## Future
#### Must
- improve documentation
- test with hardware
#### Should
- error handling
- **bool writeBrightness(channel)**
- **bool readRGB(channel, &R, &G, &B, &brightness)**
- improve on return values of functions.
#### Could
- add examples
- complex wave generator (freq, p0..p6 7 harmonics)
- digital lock - 4096^8 possibilities in theory. 256^8 = 2^64 is enough...
even 8^8 = 16 million.
switch => verify trigger
- dynamic "multi-mapping", set 8 points to match a curve.
- equalizer 2x4 band (stereo)
- LED colour mapping green -> yellow -> red.
- investigate pulsating LED, how much performance costs?
- investigate "optimal" polling frequency
- add unit tests
- check performance
- caching?
- version (not interesting),
- RGB values = 32 bytes
- improve performance
- faster **allOff()** writing 2x 16 bytes dedicated.
- read all analog ports in one call. (array of values).
#### Wont (unless)
- write separate colour channels?

View File

@ -0,0 +1,38 @@
//
// FILE: M5ANGLE8_analog12_demo.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo (works well with build in plotter)
// URL: https://github.com/RobTillaart/M5ANGLE8
#include "m5angle8.h"
M5ANGLE8 MM;
void setup()
{
Serial.begin(115200);
Serial.print("M5ANGLE8_LIB_VERSION: ");
Serial.println(M5ANGLE8_LIB_VERSION);
delay(100);
Wire.begin();
MM.begin();
}
void loop()
{
for (int ch = 0; ch < 8; ch++)
{
Serial.print(MM.analogRead(ch));
Serial.print("\t");
}
Serial.print(MM.inputSwitch());
Serial.print("\n");
delay(100);
}
// -- END OF FILE --

View File

@ -0,0 +1,38 @@
//
// FILE: M5ANGLE8_demo.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo (works well with build in plotter)
// URL: https://github.com/RobTillaart/M5ANGLE8
#include "m5angle8.h"
M5ANGLE8 MM;
void setup()
{
Serial.begin(115200);
Serial.print("M5ANGLE8_LIB_VERSION: ");
Serial.println(M5ANGLE8_LIB_VERSION);
delay(100);
Wire.begin();
MM.begin();
}
void loop()
{
for (int ch = 0; ch < 8; ch++)
{
Serial.print(MM.analogRead(ch, 8)); // low resolution 0..255
Serial.print("\t");
}
Serial.print(MM.inputSwitch());
Serial.print("\n");
delay(100);
}
// -- END OF FILE --

View File

@ -0,0 +1,38 @@
//
// FILE: M5ANGLE8_led_demo.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo
// URL: https://github.com/RobTillaart/M5ANGLE8
#include "m5angle8.h"
M5ANGLE8 MM;
void setup()
{
Serial.begin(115200);
Serial.print("M5ANGLE8_LIB_VERSION: ");
Serial.println(M5ANGLE8_LIB_VERSION);
delay(100);
Wire.begin();
MM.begin();
}
void loop()
{
for (int ch = 0; ch < 8; ch++)
{
Serial.println(ch);
MM.writeRGB(ch, 0, 0, 255, 100);
delay(125);
MM.writeRGB(ch, 0, 0, 0, 0);
delay(125);
}
}
// -- END OF FILE --

View File

@ -0,0 +1,39 @@
//
// FILE: M5ANGLE8_analog12_demo.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo (works well with build in plotter)
// URL: https://github.com/RobTillaart/M5ANGLE8
#include "m5angle8.h"
M5ANGLE8 MM;
void setup()
{
Serial.begin(115200);
Serial.print("M5ANGLE8_LIB_VERSION: ");
Serial.println(M5ANGLE8_LIB_VERSION);
delay(100);
Wire.begin();
MM.begin();
}
void loop()
{
for (int ch = 0; ch < 8; ch++)
{
uint16_t val = MM.analogRead(ch);
MM.writeRGB(ch, val / 16, 0, 0, 50);
Serial.print(val);
Serial.print("\t");
}
Serial.print("\n");
delay(20);
}
// -- END OF FILE --

View File

@ -0,0 +1,79 @@
//
// FILE: M5ANGLE8_performance.ino
// AUTHOR: Rob Tillaart
// PURPOSE: meansurement performance
// URL: https://github.com/RobTillaart/M5ANGLE8
#include "m5angle8.h"
M5ANGLE8 MM;
uint32_t start, stop;
uint16_t x;
void setup()
{
Serial.begin(115200);
Serial.print("M5ANGLE8_LIB_VERSION: ");
Serial.println(M5ANGLE8_LIB_VERSION);
delay(100);
Wire.begin();
MM.begin();
start = micros();
for (int ch = 0; ch < 8; ch++)
{
MM.writeRGB(ch, 128, 128, 128, 50);
}
stop = micros();
Serial.print("writeRGB:\t");
Serial.println((stop - start) / 8.0);
delay(100);
start = micros();
MM.allOff();
stop = micros();
Serial.print("allOff:\t");
Serial.println(stop - start);
delay(100);
start = micros();
x = MM.inputSwitch();
stop = micros();
Serial.print("inputSwitch:\t");
Serial.println(stop - start);
delay(100);
start = micros();
x = MM.analogRead(3);
stop = micros();
Serial.print("a-read H:\t");
Serial.println(stop - start);
delay(100);
start = micros();
x = MM.analogRead(3, 8);
stop = micros();
Serial.print("a-read L:\t");
Serial.println(stop - start);
delay(100);
}
void loop()
{
for (int ch = 0; ch < 8; ch++)
{
Serial.print(MM.analogRead(ch));
Serial.print("\t");
}
Serial.print(MM.inputSwitch());
Serial.print("\n");
delay(10);
}
// -- END OF FILE --

View File

@ -0,0 +1,22 @@
# Syntax Colouring Map For M5ANGLE8
# Data types (KEYWORD1)
M5ANGLE8 KEYWORD1
# Methods and Functions (KEYWORD2)
begin KEYWORD2
isConnected KEYWORD2
setAddress KEYWORD2
getAddress KEYWORD2
getVersion KEYWORD2
analogRead KEYWORD2
inputSwitch KEYWORD2
writeRGB KEYWORD2
allOff KEYWORD2
# Constants (LITERAL1)
M5ANGLE8_LIB_VERSION LITERAL1

View File

@ -0,0 +1,23 @@
{
"name": "M5ANGLE8",
"keywords": "M5ANGLE8, analog, angle.",
"description": "Arduino library for M5 8ANGLE 8x12 bit potentiometers.",
"authors":
[
{
"name": "Rob Tillaart",
"email": "Rob.Tillaart@gmail.com",
"maintainer": true
}
],
"repository":
{
"type": "git",
"url": "https://github.com/RobTillaart/M5ANGLE8"
},
"version": "0.1.0",
"license": "MIT",
"frameworks": "*",
"platforms": "*",
"headers": "M5ANGLE8.h"
}

View File

@ -0,0 +1,11 @@
name=M5ANGLE8
version=0.1.0
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino library for M5 8ANGLE 8x12 bit potentiometers.
paragraph=
category=Signal Input/Output
url=https://github.com/RobTillaart/M5ANGLE8
architectures=*
includes=m5angle8.h
depends=

View File

@ -0,0 +1,197 @@
//
// FILE: m5angle8.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: Arduino library for M5 8ANGLE 8x12 bit potentiometers
// URL: https://github.com/RobTillaart/M5ANGLE8
#include "m5angle8.h"
// REGISTERS
#define M5ANGLE8_REG_ADDRESS 0xFF
#define M5ANGLE8_REG_VERSION 0xFE
#define M5ANGLE8_REG_BASE_ANA12 0x00
#define M5ANGLE8_REG_BASE_ANA8 0x10
#define M5ANGLE8_REG_SWITCH 0x20
#define M5ANGLE8_REG_RGB 0x30
M5ANGLE8::M5ANGLE8(uint8_t address, TwoWire *wire)
{
_address = address;
_wire = wire;
}
#if defined (ESP8266) || defined(ESP32)
bool M5ANGLE8::begin(int dataPin, int clockPin)
{
if ((dataPin < 255) && (clockPin < 255))
{
_wire->begin(dataPin, clockPin);
} else {
_wire->begin();
}
if (! isConnected()) return false;
return true;
}
#endif
bool M5ANGLE8::begin()
{
_wire->begin();
if (! isConnected()) return false;
return true;
}
bool M5ANGLE8::isConnected()
{
_wire->beginTransmission(_address);
return (_wire->endTransmission() == 0);
}
bool M5ANGLE8::setAddress(uint8_t address)
{
_address = address;
write8(M5ANGLE8_REG_ADDRESS, _address);
return isConnected();
}
uint8_t M5ANGLE8::getAddress()
{
return _address;
}
uint8_t M5ANGLE8::getVersion()
{
return read8(M5ANGLE8_REG_VERSION);
}
////////////////////////////////////////////////
//
// INPUT PART
//
uint16_t M5ANGLE8::analogRead(uint8_t channel, uint8_t resolution)
{
if (channel > 7)
{
return M5ANGLE8_ERR_CHANNEL;
}
if (resolution <= 8)
{
return (uint16_t) read8(M5ANGLE8_REG_BASE_ANA8 + channel);
}
uint16_t value = read16(M5ANGLE8_REG_BASE_ANA12 + (channel << 1));
if (resolution == 11) value >>= 1;
else if (resolution == 10) value >>= 2;
else if (resolution == 9) value >>= 3;
return value;
}
uint8_t M5ANGLE8::inputSwitch()
{
return read8(M5ANGLE8_REG_SWITCH);
}
bool M5ANGLE8::writeRGB(uint8_t channel, uint8_t R, uint8_t G, uint8_t B, uint8_t brightness)
{
if (channel > 7)
{
return false;
}
if (brightness > 100) brightness = 100;
write32(M5ANGLE8_REG_RGB + (channel << 2), R, G, B, brightness);
return true;
}
bool M5ANGLE8::allOff()
{
for (uint8_t ch = 0; ch < 8; ch++)
{
write32(M5ANGLE8_REG_RGB + (ch << 2), 0, 0, 0, 0);
}
return true;
}
////////////////////////////////////////////////
//
// PRIVATE
//
bool M5ANGLE8::write8(uint8_t reg, uint8_t value)
{
_wire->beginTransmission(_address);
_wire->write(reg);
_wire->write(value);
_error = _wire->endTransmission();
return (_error == 0);
}
uint8_t M5ANGLE8::read8(uint8_t reg)
{
_wire->beginTransmission(_address);
_wire->write(reg);
_error = _wire->endTransmission();
if (_error != 0)
{
// error handling
return 0;
}
if (_wire->requestFrom(_address, (uint8_t)1) != 1)
{
// error handling
return 0;
}
return _wire->read();
}
uint16_t M5ANGLE8::read16(uint8_t reg)
{
uint16_t value = 0;
_wire->beginTransmission(_address);
_wire->write(reg);
_error = _wire->endTransmission();
if (_error != 0)
{
// error handling
return 0;
}
if (_wire->requestFrom(_address, (uint8_t)2) != 2)
{
// error handling
return 0;
}
value += _wire->read();
value <<= 8;
value += _wire->read();
return value;
}
bool M5ANGLE8::write32(uint8_t reg, uint8_t R, uint8_t G, uint8_t B, uint8_t brightness)
{
_wire->beginTransmission(_address);
_wire->write(reg);
_wire->write(R);
_wire->write(G);
_wire->write(B);
_wire->write(brightness);
_error = _wire->endTransmission();
return (_error == 0);
}
// -- END OF FILE --

View File

@ -0,0 +1,66 @@
#pragma once
//
// FILE: m5angle8.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: Arduino library for M58ANGLE 8x12 bit potentiometers
// URL: https://github.com/RobTillaart/M5ANGLE8
#include "Arduino.h"
#include "Wire.h"
#define M5ANGLE8_LIB_VERSION (F("0.1.0"))
#define M5ANGLE8_DEFAULT_ADDRESS 0x43
// prelim error handling
#define M5ANGLE8_OK 0x0000
#define M5ANGLE8_ERR_CHANNEL 0xFF00
#define M5ANGLE8_ERROR 0xFFFF
class M5ANGLE8
{
public:
M5ANGLE8(uint8_t address = M5ANGLE8_DEFAULT_ADDRESS, TwoWire *wire = &Wire);
#if defined (ESP8266) || defined(ESP32)
bool begin(int sda, int scl);
#endif
bool begin();
bool isConnected();
// address = 8..119 (NXP spec)
bool setAddress(uint8_t address = M5ANGLE8_DEFAULT_ADDRESS);
uint8_t getAddress();
uint8_t getVersion();
// IO PART
// channel = 0..7
// resolution = 8 (0..255) anything else ==> 12 (0..4095)
uint16_t analogRead(uint8_t channel, uint8_t resolution = 12);
uint8_t inputSwitch();
// channel = 0..7
// R,G,B = 0..255
// brightness = 0..100 (will be constrained).
bool writeRGB(uint8_t channel, uint8_t R, uint8_t G, uint8_t B, uint8_t brightness);
bool allOff();
private:
uint8_t _address;
int _error;
TwoWire* _wire;
bool write8(uint8_t reg, uint8_t value);
uint8_t read8(uint8_t reg);
uint16_t read16(uint8_t reg);
bool write32(uint8_t reg, uint8_t R, uint8_t G, uint8_t B, uint8_t brightness);
};
// -- END OF FILE --

View File

@ -0,0 +1,51 @@
//
// FILE: unit_test_001.cpp
// AUTHOR: Rob Tillaart
// DATE: 2023-08-03
// PURPOSE: unit tests for the M5ANGLE8 library
// https://github.com/RobTillaart/M5ANGLE8
// https://github.com/Arduino-CI/arduino_ci/blob/master/REFERENCE.md
//
// supported assertions
// ----------------------------
// assertEqual(expected, actual)
// assertNotEqual(expected, actual)
// assertLess(expected, actual)
// assertMore(expected, actual)
// assertLessOrEqual(expected, actual)
// assertMoreOrEqual(expected, actual)
// assertTrue(actual)
// assertFalse(actual)
// assertNull(actual)
#include <ArduinoUnitTests.h>
#include "Arduino.h"
#include "m5angle8.h"
unittest_setup()
{
fprintf(stderr, "M5ANGLE8_LIB_VERSION: %s\n", (char *) M5ANGLE8_LIB_VERSION);
}
unittest_teardown()
{
}
unittest(test_constructor)
{
M5ANGLE8 MM;
assertEqual(1, 1);
}
unittest_main()
// -- END OF FILE --