mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.4.0 M5ROTATE8
This commit is contained in:
parent
6d8d7ee3af
commit
12257c41f9
@ -6,6 +6,20 @@ 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.4.0] 2024-06-15
|
||||||
|
- add **uint32_t readRGB(uint8_t channel)**
|
||||||
|
- add firmware V2 functions
|
||||||
|
- **void setButtonToggleCount(uint8_t channel, uint8_t value = 0)**
|
||||||
|
- **uint8_t getButtonToggleCount(uint8_t channel)**
|
||||||
|
- **uint8_t getButtonRegister()**
|
||||||
|
- **uint8_t getEncoderChangeFlag()**
|
||||||
|
- improved **setAddress()**
|
||||||
|
- add examples
|
||||||
|
- update readme.md
|
||||||
|
- minor edits
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
## [0.3.0] 2023-12-05
|
## [0.3.0] 2023-12-05
|
||||||
- refactor API
|
- refactor API
|
||||||
- update readme
|
- update readme
|
||||||
|
@ -18,32 +18,46 @@ Arduino library for M5 8ROTATE 8x rotary encoders.
|
|||||||
|
|
||||||
**Experimental**
|
**Experimental**
|
||||||
|
|
||||||
M5ROTATE8 is an Arduino class to read the 8 rotary encoders of the
|
M5ROTATE8 is an Arduino library to read the 8 rotary encoders of the
|
||||||
M5 8ENCODER module.
|
M5 8ENCODER device.
|
||||||
It also provides means to write RGB values to the 8 LED's in the same module.
|
It also provides means to write RGB values to the 9 LED's in the same module.
|
||||||
|
|
||||||
The rotary encoders can be read as an absolute counter (since start or reset) or as an relative counter (since last time read).
|
The rotary encoders can be read as an absolute counter, since start or reset,
|
||||||
The value can be both positive and negative depending on the direction of turns.
|
or as a relative counter since last time read.
|
||||||
The absolute counters can be given an initial value.
|
These values can be both positive and negative depending on the direction of the turns.
|
||||||
The counters can be reset per channel.
|
The absolute counters can be given an initial value e.g. to match some value in your project.
|
||||||
The library can also read the key pressed status of every rotary encoder.
|
These counters can be reset per channel.
|
||||||
|
|
||||||
The library can read the state of the mini switch.
|
Furthermore the library can read the key pressed status of every rotary encoder.
|
||||||
|
These can be used e.g. to switch mode from fine to coarse and back.
|
||||||
|
|
||||||
The library can set the RGB value of the 9 LEDS.
|
The library can set the RGB value of the 9 LEDS.
|
||||||
The RotaryEncoder module has no brightness, like the 8ANGLe unit does.
|
The RotaryEncoder module has no brightness, like the 8ANGLe unit does.
|
||||||
|
|
||||||
|
Finally the library can read the state of the mini switch.
|
||||||
|
|
||||||
First tests with hardware have been done.
|
First tests with hardware have been done.
|
||||||
**Warning:** One strange observation, the RE makes steps of size 2 and occasionally step size 1.
|
**Warning:** One strange observation, the RE makes steps of size 2 and occasionally step size 1.
|
||||||
This needs further investigation, so use with care.
|
This needs further investigation, so use with care.
|
||||||
|
|
||||||
Missing in the device is an interrupt signal e.g. on change.
|
|
||||||
One has to poll all channels for changes which is not efficient.
|
|
||||||
A single byte register that showed change since last read would allow to monitor
|
|
||||||
all 8 rotary encoders in one call.
|
|
||||||
|
|
||||||
Feedback is welcome!
|
Feedback is welcome!
|
||||||
|
|
||||||
|
#### Missing in V1
|
||||||
|
|
||||||
|
The device has no interrupt signal e.g. on change. However since firmware version V2
|
||||||
|
the device allows to read one register to see changes on all rotary encoders and one
|
||||||
|
registers to see all the button states. These enhancements improve interaction most
|
||||||
|
of the time.
|
||||||
|
|
||||||
|
Note: V2 is not tested with hardware yet.
|
||||||
|
|
||||||
|
|
||||||
|
#### Breaking change
|
||||||
|
|
||||||
|
Version 0.4.0 added support for Firmware V2 functions. See below.
|
||||||
|
If your hardware has firmware V1 these functions won't work.
|
||||||
|
|
||||||
|
|
||||||
#### Breaking change
|
#### Breaking change
|
||||||
|
|
||||||
Version 0.3.0 introduced a breaking change.
|
Version 0.3.0 introduced a breaking change.
|
||||||
@ -56,7 +70,9 @@ before calling **begin()**.
|
|||||||
#### I2C
|
#### I2C
|
||||||
|
|
||||||
The address range is in theory from 0..127, however the I2C specification
|
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.
|
states it should be between 8 and 119 as some addresses are reserved,
|
||||||
|
or have special meaning.
|
||||||
|
|
||||||
The default address is **0x41** or **65**.
|
The default address is **0x41** or **65**.
|
||||||
|
|
||||||
| clock | works | notes |
|
| clock | works | notes |
|
||||||
@ -79,6 +95,12 @@ The step size needs investigation as I would expect step size 1, always.
|
|||||||
|
|
||||||
#### Related
|
#### Related
|
||||||
|
|
||||||
|
Manufacturer
|
||||||
|
- https://github.com/m5stack/M5Unit-8Encoder
|
||||||
|
- https://github.com/m5stack/M5Unit-8Encoder/issues/1 (V2 extensions)
|
||||||
|
- https://github.com/m5stack/M5Unit-8Encoder-Internal-FW (firmware)
|
||||||
|
|
||||||
|
Libraries
|
||||||
- https://github.com/RobTillaart/M5ANGLE8
|
- https://github.com/RobTillaart/M5ANGLE8
|
||||||
- https://github.com/RobTillaart/M5ROTATE8
|
- https://github.com/RobTillaart/M5ROTATE8
|
||||||
- https://github.com/RobTillaart/rotaryDecoder
|
- https://github.com/RobTillaart/rotaryDecoder
|
||||||
@ -97,38 +119,67 @@ The step size needs investigation as I would expect step size 1, always.
|
|||||||
Default address = 0x41, default Wire.
|
Default address = 0x41, default Wire.
|
||||||
- **bool begin()** checks if address is on the I2C bus.
|
- **bool begin()** checks if address is on the I2C bus.
|
||||||
User must call wire.begin() before this one.
|
User must call wire.begin() before this one.
|
||||||
- **bool isConnected()** checks if address is on the I2C bus.
|
- **bool isConnected()** checks if the address given in the constructor, or by setAddress(),
|
||||||
|
can be found on the I2C bus.
|
||||||
- **bool setAddress(uint8_t address = M5ROTATE8_DEFAULT_ADDRESS)** set a new address for the device.
|
- **bool setAddress(uint8_t address = M5ROTATE8_DEFAULT_ADDRESS)** set a new address for the device.
|
||||||
Default address = 0x41.
|
Default address = 0x41.
|
||||||
- **uint8_t getAddress()** convenience function.
|
Returns false if address below 8 or above 119.
|
||||||
- **uint8_t getVersion()** get firmware version from device.
|
- **uint8_t getAddress()** convenience function to get the set address.
|
||||||
|
- **uint8_t getVersion()** get the firmware version from device.
|
||||||
|
|
||||||
|
|
||||||
#### Rotary encoder part
|
#### Rotary encoder part
|
||||||
|
|
||||||
- **int32_t getAbsCounter(uint8_t channel)**
|
- **int32_t getAbsCounter(uint8_t channel)**
|
||||||
Read a absolute position of the rotary encoder since reset or start.
|
Read the absolute or cumulative position of the rotary encoder since reset or start.
|
||||||
- **void setAbsCounter(uint8_t channel, int32_t value);
|
Note this can be positive or negative or zero.
|
||||||
|
- **void setAbsCounter(uint8_t channel, int32_t value)** allows to set an initial value
|
||||||
|
e.g. so it matches a setting or value in your application.
|
||||||
- **int32_t getRelCounter(uint8_t channel)**
|
- **int32_t getRelCounter(uint8_t channel)**
|
||||||
Read a relative position of the rotary encoder since reset.
|
Read a relative position of the rotary encoder since reset.
|
||||||
|
Note this can be positive or negative or zero.
|
||||||
Note: this counter will reset after each read.
|
Note: this counter will reset after each read.
|
||||||
- **bool getKeyPressed(uint8_t channel)** get key status of the rotary encoder.
|
- **bool getKeyPressed(uint8_t channel)** get the status of the key of the rotary encoder.
|
||||||
True is pressed.
|
True (1) is pressed, False (0) is not pressed.
|
||||||
- **bool resetCounter(uint8_t channel)** reset a rotary encoder.
|
- **bool resetCounter(uint8_t channel)** reset a rotary encoder.
|
||||||
- **void resetAll()** reset all counters to 0.
|
- **void resetAll()** reset all rotary encoder counters to 0.
|
||||||
|
|
||||||
|
|
||||||
#### Input switch part
|
#### Input switch part
|
||||||
|
|
||||||
- **uint8_t inputSwitch()** read status of the switch.
|
- **uint8_t inputSwitch()** read the status of the micro switch.
|
||||||
|
|
||||||
|
|
||||||
#### LED part
|
#### LED part
|
||||||
|
|
||||||
- **bool writeRGB(uint8_t channel, uint8_t R, uint8_t G, uint8_t B)** Set the RGB value of a specific LED.
|
- **bool writeRGB(uint8_t channel, uint8_t R, uint8_t G, uint8_t B)** Set the RGB value of a specific LED.
|
||||||
channel = 0..8
|
channel = 0..8 as there is one more LED than rotary encoders.
|
||||||
- **bool setAll(uint8_t R, uint8_t G, uint8_t B)** set all LEDs.
|
- **uint32_t readRGB(uint8_t channel)** read back the RGB value of specified LED as an 32 bits integer.
|
||||||
- **bool allOff()** switches all LEDs off.
|
The value is 0x00RRGGBB.
|
||||||
|
- **bool setAll(uint8_t R, uint8_t G, uint8_t B)** set all LEDs to the specified RGB value.
|
||||||
|
- **bool allOff()** switches all LEDs off, RGB = (0,0,0).
|
||||||
|
|
||||||
|
|
||||||
|
#### Firmware V2 functions
|
||||||
|
|
||||||
|
New content in registers 0x58 - 0x5F, 0x61, 0x62.
|
||||||
|
Needs testing with hardware.
|
||||||
|
|
||||||
|
- **void setButtonToggleCount(uint8_t channel, uint8_t value = 0)**
|
||||||
|
Write a starting value to the toggle counters.
|
||||||
|
- **uint8_t getButtonToggleCount(uint8_t channel)** Button toggle counting.
|
||||||
|
To be used to see if button has been pressed and released, optionally multiple times.
|
||||||
|
Reset to zero after reading.
|
||||||
|
- **uint8_t getButtonChangeMask()** returns a bit mask for all 8 buttons,
|
||||||
|
bit 0 = not pressed, bit 1 = pressed.
|
||||||
|
To be used to check all 8 buttons in just one call.
|
||||||
|
This is much faster than reading them separately one by one.
|
||||||
|
Note that this function inverts the datasheetV2 specification as it seems more logical.
|
||||||
|
- **uint8_t getEncoderChangeMask()** returns a bit mask for all 8 rotary encoders.
|
||||||
|
Bit 0 = no change, bit 1 = changed.
|
||||||
|
To be used to check all 8 encoders in one call.
|
||||||
|
This is much faster than reading them separately one by one.
|
||||||
|
Resets the whole mask (register) to zero after reading.
|
||||||
|
|
||||||
|
|
||||||
## Future
|
## Future
|
||||||
@ -140,19 +191,16 @@ channel = 0..8
|
|||||||
- investigate step size 2 / 1.
|
- investigate step size 2 / 1.
|
||||||
- An easy patch: divide by 2 resulting in step size 1 or 0
|
- An easy patch: divide by 2 resulting in step size 1 or 0
|
||||||
|
|
||||||
|
|
||||||
#### Should
|
#### Should
|
||||||
|
|
||||||
|
- test firmware V2 functions with hardware.
|
||||||
- error handling
|
- error handling
|
||||||
- optimize low level calls
|
- optimize low level calls
|
||||||
- merge into two functions => read/write array + length.
|
- merge into two functions => read/write array + length.
|
||||||
- resetAll() could be "one call"
|
- resetAll() could be "one call"
|
||||||
- **bool readRGB(channel, &R, &G, &B)**
|
- does this affect performance?
|
||||||
- or **uint32_t readRGB(uint8_t channel)**
|
- improve performance (how?)
|
||||||
- improve on return values of functions.
|
- extend performance example with V2 functions
|
||||||
- improve performance
|
|
||||||
- investigate address changes
|
|
||||||
|
|
||||||
|
|
||||||
#### Could
|
#### Could
|
||||||
|
|
||||||
@ -160,9 +208,9 @@ channel = 0..8
|
|||||||
- digital lock
|
- digital lock
|
||||||
- add unit tests
|
- add unit tests
|
||||||
|
|
||||||
|
|
||||||
#### Wont (unless)
|
#### Wont (unless)
|
||||||
|
|
||||||
|
- **bool readRGB(channel, &R, &G, &B)**
|
||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|
||||||
|
BIN
libraries/M5ROTATE8/datasheet/8Encoder_I2C_Protocol_V1.pdf
Normal file
BIN
libraries/M5ROTATE8/datasheet/8Encoder_I2C_Protocol_V1.pdf
Normal file
Binary file not shown.
BIN
libraries/M5ROTATE8/datasheet/8Encoder_I2C_Protocol_V2.pdf
Normal file
BIN
libraries/M5ROTATE8/datasheet/8Encoder_I2C_Protocol_V2.pdf
Normal file
Binary file not shown.
@ -1,7 +1,7 @@
|
|||||||
//
|
//
|
||||||
// FILE: M5ROTATE8_performance.ino
|
// FILE: M5ROTATE8_performance.ino
|
||||||
// AUTHOR: Rob Tillaart
|
// AUTHOR: Rob Tillaart
|
||||||
// PURPOSE: meansurement performance
|
// PURPOSE: measurement performance
|
||||||
// URL: https://github.com/RobTillaart/M5ROTATE8
|
// URL: https://github.com/RobTillaart/M5ROTATE8
|
||||||
|
|
||||||
|
|
||||||
@ -13,26 +13,6 @@ M5ROTATE8 MM;
|
|||||||
uint32_t start, stop;
|
uint32_t start, stop;
|
||||||
uint16_t x;
|
uint16_t x;
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
Serial.begin(115200);
|
|
||||||
Serial.println(__FILE__);
|
|
||||||
Serial.print("M5ROTATE8_LIB_VERSION: ");
|
|
||||||
Serial.println(M5ROTATE8_LIB_VERSION);
|
|
||||||
delay(100);
|
|
||||||
|
|
||||||
Wire.begin();
|
|
||||||
MM.begin();
|
|
||||||
|
|
||||||
for (uint32_t speed = 100000; speed <= 400000; speed += 100000)
|
|
||||||
{
|
|
||||||
Wire.setClock(speed);
|
|
||||||
Serial.println();
|
|
||||||
Serial.print("I2C:\t");
|
|
||||||
Serial.println(speed);
|
|
||||||
performance();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void performance()
|
void performance()
|
||||||
{
|
{
|
||||||
@ -124,6 +104,28 @@ void performance()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println(__FILE__);
|
||||||
|
Serial.print("M5ROTATE8_LIB_VERSION: ");
|
||||||
|
Serial.println(M5ROTATE8_LIB_VERSION);
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
Wire.begin();
|
||||||
|
MM.begin();
|
||||||
|
|
||||||
|
for (uint32_t speed = 100000; speed <= 400000; speed += 100000)
|
||||||
|
{
|
||||||
|
Wire.setClock(speed);
|
||||||
|
Serial.println();
|
||||||
|
Serial.print("I2C:\t");
|
||||||
|
Serial.println(speed);
|
||||||
|
performance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
M5ROTATE8 MM;
|
M5ROTATE8 MM;
|
||||||
|
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
//
|
||||||
|
// FILE: M5ROTATE8_address_change.ino
|
||||||
|
// AUTHOR: Rob Tillaart
|
||||||
|
// PURPOSE: demo
|
||||||
|
// URL: https://github.com/RobTillaart/M5ROTATE8
|
||||||
|
|
||||||
|
|
||||||
|
#include "m5rotate8.h"
|
||||||
|
|
||||||
|
|
||||||
|
M5ROTATE8 MM;
|
||||||
|
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println(__FILE__);
|
||||||
|
Serial.print("M5ROTATE8_LIB_VERSION: ");
|
||||||
|
Serial.println(M5ROTATE8_LIB_VERSION);
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
Wire.begin();
|
||||||
|
MM.begin();
|
||||||
|
MM.resetAll();
|
||||||
|
|
||||||
|
Serial.print("Before: \t");
|
||||||
|
Serial.println(MM.getAddress());
|
||||||
|
Serial.print("Connect: \t");
|
||||||
|
Serial.println(MM.isConnected());
|
||||||
|
|
||||||
|
// assumes not out of range.
|
||||||
|
MM.setAddress(MM.getAddress() + 2);
|
||||||
|
|
||||||
|
Serial.print("After: \t");
|
||||||
|
Serial.println(MM.getAddress());
|
||||||
|
Serial.print("Connect: \t");
|
||||||
|
Serial.println(MM.isConnected());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -- END OF FILE --
|
@ -0,0 +1,44 @@
|
|||||||
|
//
|
||||||
|
// FILE: M5ROTATE8_button_mask.ino
|
||||||
|
// AUTHOR: Rob Tillaart
|
||||||
|
// PURPOSE: demo firmware V2 function
|
||||||
|
// URL: https://github.com/RobTillaart/M5ROTATE8
|
||||||
|
|
||||||
|
|
||||||
|
#include "m5rotate8.h"
|
||||||
|
|
||||||
|
|
||||||
|
M5ROTATE8 MM;
|
||||||
|
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println(__FILE__);
|
||||||
|
Serial.print("M5ROTATE8_LIB_VERSION: ");
|
||||||
|
Serial.println(M5ROTATE8_LIB_VERSION);
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
Wire.begin();
|
||||||
|
MM.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
// Note: mask is inverted register.
|
||||||
|
uint8_t mask = MM.getButtonChangeMask();
|
||||||
|
if (mask != 0)
|
||||||
|
{
|
||||||
|
for (int button = 0; button < 8; button++)
|
||||||
|
{
|
||||||
|
Serial.print("Button ");
|
||||||
|
Serial.print(button);
|
||||||
|
Serial.print(" has state ");
|
||||||
|
Serial.println((mask & (1 << button)) > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -- END OF FILE --
|
@ -0,0 +1,52 @@
|
|||||||
|
//
|
||||||
|
// FILE: M5ROTATE8_button_toggle_count.ino
|
||||||
|
// AUTHOR: Rob Tillaart
|
||||||
|
// PURPOSE: demo firmware V2 function
|
||||||
|
// URL: https://github.com/RobTillaart/M5ROTATE8
|
||||||
|
|
||||||
|
|
||||||
|
#include "m5rotate8.h"
|
||||||
|
|
||||||
|
|
||||||
|
M5ROTATE8 MM;
|
||||||
|
|
||||||
|
int sum = 0;
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println(__FILE__);
|
||||||
|
Serial.print("M5ROTATE8_LIB_VERSION: ");
|
||||||
|
Serial.println(M5ROTATE8_LIB_VERSION);
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
Wire.begin();
|
||||||
|
MM.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
for (int channel = 0; channel < 8; channel++)
|
||||||
|
{
|
||||||
|
int x = MM.getButtonToggleCount(channel);
|
||||||
|
sum += x;
|
||||||
|
Serial.print(x);
|
||||||
|
Serial.print("\t");
|
||||||
|
delay(125);
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
// time to reset?
|
||||||
|
if (sum >= 25) // arbitrary condition.
|
||||||
|
{
|
||||||
|
sum = 0;
|
||||||
|
for (int channel = 0; channel < 8; channel++)
|
||||||
|
{
|
||||||
|
MM.setButtonToggleCount(channel, 0); // explicit value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -- END OF FILE --
|
@ -0,0 +1,48 @@
|
|||||||
|
//
|
||||||
|
// FILE: M5ROTATE8_encoder_mask.ino
|
||||||
|
// AUTHOR: Rob Tillaart
|
||||||
|
// PURPOSE: demo firmware V2 function
|
||||||
|
// URL: https://github.com/RobTillaart/M5ROTATE8
|
||||||
|
|
||||||
|
|
||||||
|
#include "m5rotate8.h"
|
||||||
|
|
||||||
|
|
||||||
|
M5ROTATE8 MM;
|
||||||
|
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
Serial.println(__FILE__);
|
||||||
|
Serial.print("M5ROTATE8_LIB_VERSION: ");
|
||||||
|
Serial.println(M5ROTATE8_LIB_VERSION);
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
Wire.begin();
|
||||||
|
MM.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
uint8_t mask = MM.getEncoderChangeMask();
|
||||||
|
if (mask != 0)
|
||||||
|
{
|
||||||
|
for (int encoder = 0; encoder < 8; encoder++)
|
||||||
|
{
|
||||||
|
if (mask & (1 << encoder))
|
||||||
|
{
|
||||||
|
Serial.print("Encoder ");
|
||||||
|
Serial.print(encoder);
|
||||||
|
Serial.print(" moved to ");
|
||||||
|
|
||||||
|
// read and process encoder.
|
||||||
|
Serial.println(MM.getAbsCounter(encoder));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// -- END OF FILE --
|
@ -26,6 +26,13 @@ setAll KEYWORD2
|
|||||||
allOff KEYWORD2
|
allOff KEYWORD2
|
||||||
|
|
||||||
|
|
||||||
|
# FIRMWARE V2
|
||||||
|
setButtonToggleCount KEYWORD2
|
||||||
|
getButtonToggleCount KEYWORD2
|
||||||
|
getButtonChangeMask KEYWORD2
|
||||||
|
getEncoderChangeMask KEYWORD2
|
||||||
|
|
||||||
|
|
||||||
# Constants (LITERAL1)
|
# Constants (LITERAL1)
|
||||||
M5ROTATE8_LIB_VERSION LITERAL1
|
M5ROTATE8_LIB_VERSION LITERAL1
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/RobTillaart/M5ROTATE8"
|
"url": "https://github.com/RobTillaart/M5ROTATE8"
|
||||||
},
|
},
|
||||||
"version": "0.3.0",
|
"version": "0.4.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"frameworks": "*",
|
"frameworks": "*",
|
||||||
"platforms": "*",
|
"platforms": "*",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
name=M5ROTATE8
|
name=M5ROTATE8
|
||||||
version=0.3.0
|
version=0.4.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 M5 8ROTATE 8x rotary encoders
|
sentence=Arduino library for M5 8ROTATE 8x rotary encoders
|
||||||
|
@ -1,22 +1,28 @@
|
|||||||
//
|
//
|
||||||
// FILE: m5rotate8.cpp
|
// FILE: m5rotate8.cpp
|
||||||
// AUTHOR: Rob Tillaart
|
// AUTHOR: Rob Tillaart
|
||||||
// VERSION: 0.3.0
|
// VERSION: 0.4.0
|
||||||
// PURPOSE: Arduino library for M5 8ROTATE 8x rotary encoders
|
// PURPOSE: Arduino library for M5 8ROTATE 8x rotary encoders
|
||||||
// URL: https://github.com/RobTillaart/M5ROTATE8
|
// URL: https://github.com/RobTillaart/M5ROTATE8
|
||||||
|
|
||||||
|
|
||||||
#include "m5rotate8.h"
|
#include "m5rotate8.h"
|
||||||
|
|
||||||
|
// FIRMWARE V1 REGISTERS
|
||||||
|
#define M5ROTATE8_REG_ADDRESS 0xFF
|
||||||
|
#define M5ROTATE8_REG_VERSION 0xFE
|
||||||
|
#define M5ROTATE8_REG_BASE_ABS 0x00
|
||||||
|
#define M5ROTATE8_REG_BASE_REL 0x20
|
||||||
|
#define M5ROTATE8_REG_BASE_RESET 0x40
|
||||||
|
#define M5ROTATE8_REG_BASE_BUTTON_VALUE 0x50
|
||||||
|
#define M5ROTATE8_REG_SWITCH 0x60
|
||||||
|
#define M5ROTATE8_REG_RGB 0x70
|
||||||
|
|
||||||
|
// FIRMWARE V2 REGISTERS
|
||||||
|
#define M5ROTATE8_REG_BASE_BUTTON_TOGGLE 0x58
|
||||||
|
#define M5ROTATE8_REG_ENCODER_MASK 0x61
|
||||||
|
#define M5ROTATE8_REG_BUTTON_MASK 0x62
|
||||||
|
|
||||||
#define M5ROTATE8_REG_ADDRESS 0xFF
|
|
||||||
#define M5ROTATE8_REG_VERSION 0xFE
|
|
||||||
#define M5ROTATE8_REG_BASE_ABS 0x00
|
|
||||||
#define M5ROTATE8_REG_BASE_REL 0x20
|
|
||||||
#define M5ROTATE8_REG_BASE_RESET 0x40
|
|
||||||
#define M5ROTATE8_REG_BASE_BUTTON 0x50
|
|
||||||
#define M5ROTATE8_REG_SWITCH 0x60
|
|
||||||
#define M5ROTATE8_REG_RGB 0x70
|
|
||||||
|
|
||||||
|
|
||||||
M5ROTATE8::M5ROTATE8(uint8_t address, TwoWire *wire)
|
M5ROTATE8::M5ROTATE8(uint8_t address, TwoWire *wire)
|
||||||
@ -42,6 +48,7 @@ bool M5ROTATE8::isConnected()
|
|||||||
|
|
||||||
bool M5ROTATE8::setAddress(uint8_t address)
|
bool M5ROTATE8::setAddress(uint8_t address)
|
||||||
{
|
{
|
||||||
|
if ((address < 8) || (address > 119)) return false;
|
||||||
_address = address;
|
_address = address;
|
||||||
write8(M5ROTATE8_REG_ADDRESS, _address);
|
write8(M5ROTATE8_REG_ADDRESS, _address);
|
||||||
return isConnected();
|
return isConnected();
|
||||||
@ -60,7 +67,6 @@ uint8_t M5ROTATE8::getVersion()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////
|
|
||||||
//
|
//
|
||||||
// ROTARY ENCODER PART
|
// ROTARY ENCODER PART
|
||||||
//
|
//
|
||||||
@ -88,7 +94,7 @@ bool M5ROTATE8::getKeyPressed(uint8_t channel)
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return (0 == read8(M5ROTATE8_REG_BASE_BUTTON + channel));
|
return (0 == read8(M5ROTATE8_REG_BASE_BUTTON_VALUE + channel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -112,7 +118,6 @@ void M5ROTATE8::resetAll()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////
|
|
||||||
//
|
//
|
||||||
// INPUT SWITCH PART
|
// INPUT SWITCH PART
|
||||||
//
|
//
|
||||||
@ -122,7 +127,6 @@ uint8_t M5ROTATE8::inputSwitch()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////
|
|
||||||
//
|
//
|
||||||
// LED PART
|
// LED PART
|
||||||
//
|
//
|
||||||
@ -137,6 +141,12 @@ bool M5ROTATE8::writeRGB(uint8_t channel, uint8_t R, uint8_t G, uint8_t B)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t M5ROTATE8::readRGB(uint8_t channel)
|
||||||
|
{
|
||||||
|
return read24(M5ROTATE8_REG_RGB + (channel * 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool M5ROTATE8::setAll(uint8_t R, uint8_t G, uint8_t B)
|
bool M5ROTATE8::setAll(uint8_t R, uint8_t G, uint8_t B)
|
||||||
{
|
{
|
||||||
for (uint8_t ch = 0; ch < 9; ch++)
|
for (uint8_t ch = 0; ch < 9; ch++)
|
||||||
@ -153,7 +163,47 @@ bool M5ROTATE8::allOff()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////
|
|
||||||
|
//
|
||||||
|
// FIRMWARE V2
|
||||||
|
//
|
||||||
|
bool M5ROTATE8::setButtonToggleCount(uint8_t channel, uint8_t value)
|
||||||
|
{
|
||||||
|
if (channel > 7)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return write8(M5ROTATE8_REG_BASE_BUTTON_TOGGLE + channel, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t M5ROTATE8::getButtonToggleCount(uint8_t channel)
|
||||||
|
{
|
||||||
|
if (channel > 7)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return read8(M5ROTATE8_REG_BASE_BUTTON_TOGGLE + channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 0 = no change, 1 = changed
|
||||||
|
uint8_t M5ROTATE8::getEncoderChangeMask()
|
||||||
|
{
|
||||||
|
return read8(M5ROTATE8_REG_ENCODER_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 0 = not pressed, 1 = pressed (inverted the datasheetV2 specification)
|
||||||
|
// seems more logical
|
||||||
|
uint8_t M5ROTATE8::getButtonChangeMask()
|
||||||
|
{
|
||||||
|
// invert register to be more logical IMHO.
|
||||||
|
return read8(M5ROTATE8_REG_BUTTON_MASK) ^ 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// PRIVATE
|
// PRIVATE
|
||||||
//
|
//
|
||||||
@ -198,6 +248,31 @@ bool M5ROTATE8::write24(uint8_t reg, uint8_t R, uint8_t G, uint8_t B)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t M5ROTATE8::read24(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)3) != 3)
|
||||||
|
{
|
||||||
|
// error handling
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
uint32_t value = 0;
|
||||||
|
value += _wire->read();
|
||||||
|
value <<= 8;
|
||||||
|
value += _wire->read();
|
||||||
|
value <<= 8;
|
||||||
|
value += _wire->read();
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool M5ROTATE8::write32(uint8_t reg, uint32_t value)
|
bool M5ROTATE8::write32(uint8_t reg, uint32_t value)
|
||||||
{
|
{
|
||||||
_wire->beginTransmission(_address);
|
_wire->beginTransmission(_address);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
//
|
//
|
||||||
// FILE: m5rotate8.h
|
// FILE: m5rotate8.h
|
||||||
// AUTHOR: Rob Tillaart
|
// AUTHOR: Rob Tillaart
|
||||||
// VERSION: 0.3.0
|
// VERSION: 0.4.0
|
||||||
// PURPOSE: Arduino library for M5 8ROTATE 8x rotary encoders
|
// PURPOSE: Arduino library for M5 8ROTATE 8x rotary encoders
|
||||||
// URL: https://github.com/RobTillaart/M5ROTATE8
|
// URL: https://github.com/RobTillaart/M5ROTATE8
|
||||||
|
|
||||||
@ -10,7 +10,7 @@
|
|||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
#include "Wire.h"
|
#include "Wire.h"
|
||||||
|
|
||||||
#define M5ROTATE8_LIB_VERSION (F("0.3.0"))
|
#define M5ROTATE8_LIB_VERSION (F("0.4.0"))
|
||||||
|
|
||||||
#define M5ROTATE8_DEFAULT_ADDRESS 0x41
|
#define M5ROTATE8_DEFAULT_ADDRESS 0x41
|
||||||
|
|
||||||
@ -25,15 +25,16 @@ class M5ROTATE8
|
|||||||
public:
|
public:
|
||||||
M5ROTATE8(uint8_t address = M5ROTATE8_DEFAULT_ADDRESS, TwoWire *wire = &Wire);
|
M5ROTATE8(uint8_t address = M5ROTATE8_DEFAULT_ADDRESS, TwoWire *wire = &Wire);
|
||||||
|
|
||||||
bool begin();
|
bool begin();
|
||||||
bool isConnected();
|
bool isConnected();
|
||||||
|
|
||||||
bool setAddress(uint8_t address = M5ROTATE8_DEFAULT_ADDRESS);
|
// META
|
||||||
uint8_t getAddress();
|
bool setAddress(uint8_t address = M5ROTATE8_DEFAULT_ADDRESS);
|
||||||
uint8_t getVersion();
|
uint8_t getAddress();
|
||||||
|
uint8_t getVersion();
|
||||||
|
|
||||||
// ROTARY ENCODER PART
|
// ROTARY ENCODER PART
|
||||||
// channel = 0..7
|
// channel = 0..7
|
||||||
int32_t getAbsCounter(uint8_t channel);
|
int32_t getAbsCounter(uint8_t channel);
|
||||||
bool setAbsCounter(uint8_t channel, int32_t value);
|
bool setAbsCounter(uint8_t channel, int32_t value);
|
||||||
int32_t getRelCounter(uint8_t channel);
|
int32_t getRelCounter(uint8_t channel);
|
||||||
@ -41,17 +42,33 @@ public:
|
|||||||
bool resetCounter(uint8_t channel);
|
bool resetCounter(uint8_t channel);
|
||||||
void resetAll();
|
void resetAll();
|
||||||
|
|
||||||
// INPUT SWITCH PART
|
// INPUT SWITCH PART
|
||||||
uint8_t inputSwitch();
|
uint8_t inputSwitch();
|
||||||
|
|
||||||
// LED PART
|
// LED PART
|
||||||
// channel = 0..7
|
// channel = 0..7
|
||||||
// R,G,B = 0..255
|
// R,G,B = 0..255
|
||||||
bool writeRGB(uint8_t channel, uint8_t R, uint8_t G, uint8_t B);
|
bool writeRGB(uint8_t channel, uint8_t R, uint8_t G, uint8_t B);
|
||||||
|
uint32_t readRGB(uint8_t channel);
|
||||||
bool setAll(uint8_t R, uint8_t G, uint8_t B);
|
bool setAll(uint8_t R, uint8_t G, uint8_t B);
|
||||||
bool allOff();
|
bool allOff();
|
||||||
|
|
||||||
|
|
||||||
|
// FIRMWARE V2 functions (to be verified)
|
||||||
|
// use getVersion() to check.
|
||||||
|
// channel = 0..7
|
||||||
|
// value = 0..255
|
||||||
|
// register 0x58..0x5F
|
||||||
|
bool setButtonToggleCount(uint8_t channel, uint8_t value = 0);
|
||||||
|
uint8_t getButtonToggleCount(uint8_t channel);
|
||||||
|
// register 0x61, 0x62
|
||||||
|
// 0 = no change, 1 = changed
|
||||||
|
uint8_t getEncoderChangeMask();
|
||||||
|
// 0 = not pressed, 1 = pressed (inverted the datasheetV2 specification)
|
||||||
|
// seems to be more logical.
|
||||||
|
uint8_t getButtonChangeMask();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t _address;
|
uint8_t _address;
|
||||||
|
|
||||||
@ -61,7 +78,10 @@ private:
|
|||||||
|
|
||||||
bool write8(uint8_t reg, uint8_t value);
|
bool write8(uint8_t reg, uint8_t value);
|
||||||
uint8_t read8(uint8_t reg);
|
uint8_t read8(uint8_t reg);
|
||||||
|
|
||||||
bool write24(uint8_t reg, uint8_t R, uint8_t G, uint8_t B);
|
bool write24(uint8_t reg, uint8_t R, uint8_t G, uint8_t B);
|
||||||
|
uint32_t read24(uint8_t reg);
|
||||||
|
|
||||||
bool write32(uint8_t reg, uint32_t value);
|
bool write32(uint8_t reg, uint32_t value);
|
||||||
uint32_t read32(uint8_t reg);
|
uint32_t read32(uint8_t reg);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user