Files
DeautherX-SRAciJa/DeautherX/src/SimpleButton/Buttons/RotaryEncoderI2C.cpp
2025-12-02 18:52:45 +03:00

276 lines
6.4 KiB
C++

#include "RotaryEncoderI2C.h"
namespace simplebutton {
RotaryEncoderI2C::RotaryEncoderI2C() {
setup(0x30);
}
RotaryEncoderI2C::RotaryEncoderI2C(uint8_t i2cAddress) {
setup(i2cAddress);
}
RotaryEncoderI2C::RotaryEncoderI2C(uint8_t i2cAddress, TwoWire* wire) {
setup(i2cAddress, wire);
}
RotaryEncoderI2C::~RotaryEncoderI2C() {}
void RotaryEncoderI2C::setup(uint8_t i2cAddress) {
setup(i2cAddress, &Wire);
}
void RotaryEncoderI2C::setup(uint8_t i2cAddress, TwoWire* wire) {
this->i2cAddress = i2cAddress;
this->wire = wire;
this->clockwise = new Button();
this->anticlockwise = new Button();
this->button = new Button();
setMin(-128);
setMax(127);
begin();
}
bool RotaryEncoderI2C::interrupt() {
if (interruptEnable) return digitalRead(interruptPin) == LOW;
return true;
}
void RotaryEncoderI2C::enableInterrupt(uint8_t pin, bool pullup) {
interruptPin = pin;
interruptEnable = true;
interruptPullup = pullup;
pinMode(pin, INPUT);
}
bool RotaryEncoderI2C::update() {
if (interrupt()) {
readStatus();
if (clicked()) button->click();
if (incremented()) clockwise->click();
if (decremented()) anticlockwise->click();
return true;
}
return false;
}
void RotaryEncoderI2C::begin() {
uint8_t config = 0x00;
if (interruptEnable) config = config | 0x01;
if (ledEnabled) config = config | 0x02;
if (loop) config = config | 0x04;
if (inverted) config = config | 0x08;
if (!interruptPullup) config = config | 0x10;
if (encoding) config = config | 0x20;
setConfig(config);
}
void RotaryEncoderI2C::reset() {
button->reset();
clockwise->reset();
anticlockwise->reset();
setConfig(0x80);
update();
}
bool RotaryEncoderI2C::connected() {
return error == 0;
}
String RotaryEncoderI2C::getError() {
String msg;
switch (error) {
case 0:
msg += "OK";
break;
case 1:
msg += String(F("Data too long to fit in transmit buffer"));
break;
case 2:
msg += String(F("Received NACK on transmit of address"));
break;
case 3:
msg += String(F("Received NACK on transmit of data"));
case 4:
msg += String(F("Unknown transmission error"));
break;
case 5:
msg += String(F("I2C error"));
break;
}
return msg;
}
void RotaryEncoderI2C::setConfig(uint8_t config) {
write(0x00, config);
}
void RotaryEncoderI2C::enableLed(bool led) {
ledEnabled = led;
}
void RotaryEncoderI2C::enableLoop(bool loop) {
this->loop = loop;
}
void RotaryEncoderI2C::setEncoding(uint8_t encoding) {
if (encoding == 1) this->encoding = false;
else if (encoding == 2) this->encoding = true;
}
void RotaryEncoderI2C::setInverted(bool inverted) {
this->inverted = inverted;
}
void RotaryEncoderI2C::setPos(int32_t value) {
write(0x02, value);
}
void RotaryEncoderI2C::setMin(int32_t value) {
write(0x0A, value);
}
void RotaryEncoderI2C::setMax(int32_t value) {
write(0x06, value);
}
void RotaryEncoderI2C::setLed(uint8_t valueA, uint8_t valueB) {
setLedA(valueA);
setLedB(valueB);
}
void RotaryEncoderI2C::setLedA(uint8_t value) {
if (ledEnabled) write(0x0E, value);
}
void RotaryEncoderI2C::setLedB(uint8_t value) {
if (ledEnabled) write(0x0F, value);
}
int32_t RotaryEncoderI2C::getPos() {
return read32(0x02);
}
uint8_t RotaryEncoderI2C::readStatus() {
status = read(0x01);
return status;
}
uint8_t RotaryEncoderI2C::readLedA() {
return read(0x0E);
}
uint8_t RotaryEncoderI2C::readLedB() {
return read(0x0F);
}
int32_t RotaryEncoderI2C::readMax() {
return read32(0x06);
}
int32_t RotaryEncoderI2C::readMin() {
return read32(0x0A);
}
bool RotaryEncoderI2C::clicked() {
return status & 0x01;
}
bool RotaryEncoderI2C::incremented() {
return status & 0x02;
}
bool RotaryEncoderI2C::decremented() {
return status & 0x04;
}
bool RotaryEncoderI2C::minVal() {
return status & 0x10;
}
bool RotaryEncoderI2C::maxVal() {
return status & 0x08;
}
void RotaryEncoderI2C::write(uint8_t address, uint8_t value) {
wire->beginTransmission(i2cAddress);
wire->write(address);
wire->write(value);
error = wire->endTransmission();
}
void RotaryEncoderI2C::write(uint8_t address, int32_t value) {
wire->beginTransmission(i2cAddress);
wire->write(address);
wire->write(((uint32_t)value >> 24) & 0xFF);
wire->write(((uint32_t)value >> 16) & 0xFF);
wire->write(((uint32_t)value >> 8) & 0xFF);
wire->write((uint32_t)value & 0xFF);
error = wire->endTransmission();
}
uint8_t RotaryEncoderI2C::read(uint8_t address) {
uint8_t data = 0xFF;
// ask for some sweet data
wire->beginTransmission(i2cAddress);
wire->write(address);
error = wire->endTransmission();
// read out the sweet data
wire->requestFrom(i2cAddress, (uint8_t)1);
if (wire->available() == 1) {
data = wire->read();
} else {
error = ROTARY_ENCODER_I2C_ERROR;
}
return data;
}
int32_t RotaryEncoderI2C::read32(uint8_t address) {
uint32_t data = 0xFFFFFFFF;
// ask for some sweet data
wire->beginTransmission(i2cAddress);
wire->write(address);
error = wire->endTransmission();
// read out the sweet data
wire->requestFrom(i2cAddress, (uint8_t)4);
if (wire->available() == 4) {
data = wire->read();
data = (data << 8) | wire->read();
data = (data << 8) | wire->read();
data = (data << 8) | wire->read();
} else {
error = ROTARY_ENCODER_I2C_ERROR;
}
return (int32_t)data;
}
}