From dee9dd4033b9b483af7f888a862b3f962ba8c16f Mon Sep 17 00:00:00 2001 From: Saimon Date: Fri, 28 Feb 2020 12:35:53 +0100 Subject: [PATCH] Added Mini Lib Added the I2C Encoder Mini library --- src/i2cEncoderMiniLib.cpp | 311 ++++++++++++++++++++++++++++++++++++++ src/i2cEncoderMiniLib.h | 167 ++++++++++++++++++++ 2 files changed, 478 insertions(+) create mode 100644 src/i2cEncoderMiniLib.cpp create mode 100644 src/i2cEncoderMiniLib.h diff --git a/src/i2cEncoderMiniLib.cpp b/src/i2cEncoderMiniLib.cpp new file mode 100644 index 0000000..43c1f57 --- /dev/null +++ b/src/i2cEncoderMiniLib.cpp @@ -0,0 +1,311 @@ +// +// FILE: i2cEncoderMiniLib.h +// VERSION: 0.1.. +// PURPOSE: Library for I2C Encoder Mini board with Arduino +// LICENSE: GPL v3 (http://www.gnu.org/licenses/gpl.html) +// +// DATASHEET: https://github.com/Fattoresaimon/I2CEncoderMini +// +// URL: +// +// AUTHOR: +// Simone Caron +// + +#include "i2cEncoderMiniLib.h" +#include + +/*********************************** Public functions *************************************/ +/** Class costructor **/ +i2cEncoderMiniLib::i2cEncoderMiniLib(uint8_t add) { + _add = add; +} + +/** Used for initialize the I2C Encoder Mini **/ +void i2cEncoderMiniLib::begin(uint8_t conf) { + + writeEncoder(REG_GCONF, (uint8_t) conf); + _gconf = conf; +} + +/** Used for reset the I2C Encoder Mini **/ +void i2cEncoderMiniLib::reset(void) { + writeEncoder(REG_GCONF, (uint8_t) 0x80); + delay(10); +} + +/** Call che attached callaback if it is defined. It's a prive function only **/ +void i2cEncoderMiniLib::eventCaller(Callback *event) { + if (*event != NULL) + (*event)(this); +} + +/** Return true if the status of the econder changed, otherwise return false. + It's also call the callback, if attached **/ +bool i2cEncoderMiniLib::updateStatus(void) { + + _stat = readEncoderByte(REG_ESTATUS); + if (_stat == 0) { + return false; + } + + if (_stat & PUSHR) { + eventCaller (&onButtonRelease); + } + if (_stat & PUSHP) { + eventCaller (&onButtonPush); + } + if (_stat & PUSHL) { + eventCaller (&onButtonLongPush); + } + if (_stat & PUSHD) { + eventCaller (&onButtonDoublePush); + } + if (_stat & RINC) { + eventCaller (&onIncrement); + eventCaller (&onChange); + } + if (_stat & RDEC) { + eventCaller (&onDecrement); + eventCaller (&onChange); + } + if (_stat & RMAX) { + eventCaller (&onMax); + eventCaller (&onMinMax); + } + if (_stat & RMIN) { + eventCaller (&onMin); + eventCaller (&onMinMax); + } + + return true; +} + +/*********************************** Read functions *************************************/ + +/** Return the INT pin configuration**/ +uint8_t i2cEncoderMiniLib::readInterruptConfig(void) { + return (readEncoderByte(REG_INTCONF)); +} + +/** Check if a particular status match, return true is match otherwise false. Before require updateStatus() **/ +bool i2cEncoderMiniLib::readStatus(Int_Status s) { + if ((_stat & s) != 0) { + return true; + } + return false; +} + +/** Return the status of the encoder **/ +uint8_t i2cEncoderMiniLib::readStatus(void) { + return _stat; +} + +/** Return the 32 bit value of the encoder counter **/ +int32_t i2cEncoderMiniLib::readCounterLong(void) { + return ((int32_t) readEncoderLong(REG_CVALB4)); +} + +/** Return the 16 bit value of the encoder counter **/ +int16_t i2cEncoderMiniLib::readCounterInt(void) { + return ((int16_t) readEncoderInt(REG_CVALB2)); +} + +/** Return the 8 bit value of the encoder counter **/ +int8_t i2cEncoderMiniLib::readCounterByte(void) { + return ((int8_t) readEncoderByte(REG_CVALB1)); +} + +/** Return the Maximum threshold of the counter **/ +int32_t i2cEncoderMiniLib::readMax(void) { + return ((int32_t) readEncoderLong(REG_CMAXB4)); +} + +/** Return the Minimum threshold of the counter **/ +int32_t i2cEncoderMiniLib::readMin(void) { + return ((int32_t) readEncoderLong(REG_CMINB4)); +} + +/** Return the Steps increment **/ +int32_t i2cEncoderMiniLib::readStep(void) { + return (readEncoderInt(REG_ISTEPB4)); +} + + +/** Read Double push period register **/ +uint8_t i2cEncoderMiniLib::readDoublePushPeriod(void) { + return (readEncoderByte(REG_DPPERIOD)); +} + +/** Read the ID code **/ +uint8_t i2cEncoderMiniLib::readIDCode(void) { + return (readEncoderByte(REG_IDCODE)); +} + +/** Read the Version code **/ +uint8_t i2cEncoderMiniLib::readVersion(void) { + return (readEncoderByte(REG_VERSION)); +} + +/** Read the EEPROM memory**/ +uint8_t i2cEncoderMiniLib::readEEPROM(uint8_t add) { + + return (readEncoderByte(add)); +} + +/*********************************** Write functions *************************************/ + +/** Write the interrupt configuration **/ +void i2cEncoderMiniLib::writeInterruptConfig(uint8_t interrupt) { + writeEncoder(REG_INTCONF, (uint8_t) interrupt); +} + +/** Check if there is some attached callback and enable the corresponding interrupt **/ +void i2cEncoderMiniLib::autoconfigInterrupt(void) { + uint8_t reg; + + if (onButtonRelease != NULL) + reg |= PUSHR; + + if (onButtonPush != NULL) + reg |= PUSHP; + + if (onButtonDoublePush != NULL) + reg |= PUSHD; + + if (onButtonLongPush != NULL) + reg |= PUSHL; + + if (onIncrement != NULL) + reg |= RINC; + + if (onDecrement != NULL) + reg |= RDEC; + + if (onChange != NULL) { + reg |= RINC; + reg |= RDEC; + } + + if (onMax != NULL) + reg |= RMAX; + + if (onMin != NULL) + reg |= RMIN; + + if (onMinMax != NULL) { + reg |= RMAX; + reg |= RMIN; + } + + writeEncoder(REG_INTCONF, (uint8_t) reg); +} + +/** Write the counter value **/ +void i2cEncoderMiniLib::writeCounter(int32_t value) { + writeEncoder(REG_CVALB4, value); +} + +/** Write the maximum threshold value **/ +void i2cEncoderMiniLib::writeMax(int32_t max) { + writeEncoder(REG_CMAXB4, max); +} + +/** Write the minimum threshold value **/ +void i2cEncoderMiniLib::writeMin(int32_t min) { + writeEncoder(REG_CMINB4, min); +} + +/** Write the Step increment value **/ +void i2cEncoderMiniLib::writeStep(int32_t step) { + writeEncoder(REG_ISTEPB4, step); +} + +/** Write Double push period register **/ +void i2cEncoderMiniLib::writeDoublePushPeriod(uint8_t dperiod) { + writeEncoder(REG_DPPERIOD, dperiod); +} + +/** Write Anti-bouncing period register **/ +void i2cEncoderMiniLib::ChangeI2CAddress(uint8_t add) { + writeEncoder(REG_I2CADDRESS, add); + writeEncoder(REG_I2CADDRESS, add); + writeEncoder(REG_I2CADDRESS, add); +} + +/** Write the EEPROM memory**/ +void i2cEncoderMiniLib::writeEEPROM(uint8_t add, uint8_t data) { + + writeEncoder((REG_EEPROMS + add), data); + delay(5); +} + +/*********************************** Private functions *************************************/ +/***************************** Read function to the encoder ********************************/ + +/** Read 1 byte from the encoder **/ +uint8_t i2cEncoderMiniLib::readEncoderByte(uint8_t reg) { + byte rdata = 0xFF; + + Wire.beginTransmission(_add); + Wire.write(reg); + Wire.endTransmission(); + Wire.requestFrom(_add, (uint8_t) 1); + if (Wire.available()) { + rdata = Wire.read(); + } + return rdata; +} + +/** Read 2 bytes from the encoder **/ +int16_t i2cEncoderMiniLib::readEncoderInt(uint8_t reg) { + Wire.beginTransmission(_add); + Wire.write(reg); + Wire.endTransmission(); + Wire.requestFrom(_add, (uint8_t) 4); + if (Wire.available()) { + _tem_data.bval[1] = Wire.read(); + _tem_data.bval[0] = Wire.read(); + } + return ((int16_t) _tem_data.val); +} + +/** Read 4 bytes from the encoder **/ +int32_t i2cEncoderMiniLib::readEncoderLong(uint8_t reg) { + + Wire.beginTransmission(_add); + Wire.write(reg); + Wire.endTransmission(); + Wire.requestFrom(_add, (uint8_t) 4); + if (Wire.available()) { + _tem_data.bval[3] = Wire.read(); + _tem_data.bval[2] = Wire.read(); + _tem_data.bval[1] = Wire.read(); + _tem_data.bval[0] = Wire.read(); + } + return ((int32_t) _tem_data.val); +} + +/***************************** Write function to the encoder ********************************/ +/** Send to the encoder 1 byte **/ +void i2cEncoderMiniLib::writeEncoder(uint8_t reg, uint8_t data) { + + Wire.beginTransmission(_add); + Wire.write(reg); + Wire.write(data); + Wire.endTransmission(); +} + +/** Send to the encoder 4 byte **/ +void i2cEncoderMiniLib::writeEncoder(uint8_t reg, int32_t data) { + uint8_t temp[4]; + _tem_data.val = data; + temp[0] = _tem_data.bval[3]; + temp[1] = _tem_data.bval[2]; + temp[2] = _tem_data.bval[1]; + temp[3] = _tem_data.bval[0]; + Wire.beginTransmission(_add); + Wire.write(reg); + Wire.write(temp, (uint8_t) 4); + Wire.endTransmission(); +} diff --git a/src/i2cEncoderMiniLib.h b/src/i2cEncoderMiniLib.h new file mode 100644 index 0000000..44dd321 --- /dev/null +++ b/src/i2cEncoderMiniLib.h @@ -0,0 +1,167 @@ +// +// FILE: i2cEncoderMiniLib.h +// VERSION: 0.1.. +// PURPOSE: Libreary for the i2c encoder board with arduinp +// LICENSE: GPL v3 (http://www.gnu.org/licenses/gpl.html) +// +// DATASHEET: +// +// URL: +// +// AUTHOR: +// Simone Caron +// + +#ifndef i2cEncoderMiniLib_H +#define i2cEncoderMiniLib_H + +#if (ARDUINO >= 100) +#include +#else +#include +#endif + +class i2cEncoderMiniLib { + public: + + /*Encoder register definition*/ + enum I2C_Register { + REG_GCONF = 0x00, + REG_INTCONF = 0x01, + REG_ESTATUS = 0x02, + REG_CVALB4 = 0x03, + REG_CVALB3 = 0x04, + REG_CVALB2 = 0x05, + REG_CVALB1 = 0x06, + REG_CMAXB4 = 0x07, + REG_CMAXB3 = 0x08, + REG_CMAXB2 = 0x09, + REG_CMAXB1 = 0x0A, + REG_CMINB4 = 0x0B, + REG_CMINB3 = 0x0C, + REG_CMINB2 = 0x0D, + REG_CMINB1 = 0x0E, + REG_ISTEPB4 = 0x0F, + REG_ISTEPB3 = 0x10, + REG_ISTEPB2 = 0x11, + REG_ISTEPB1 = 0x12, + REG_DPPERIOD = 0x13, + REG_ADDRESS = 0x14, + REG_IDCODE = 0x70, + REG_VERSION = 0x71, + REG_I2CADDRESS = 0x72, + REG_EEPROMS = 0x80, + } I2C1_REGISTER; + + + /* Encoder configuration bit. Use with GCONF */ + enum GCONF_PARAMETER { + WRAP_ENABLE = 0x01, + WRAP_DISABLE = 0x00, + DIRE_LEFT = 0x02, + DIRE_RIGHT = 0x00, + IPUP_ENABLE = 0x04, + IPUP_DISABLE = 0x00, + RMOD_X4 = 0x10, + RMOD_X2 = 0x08, + RMOD_X1 = 0x00, + + RESET = 0x80, + }; + + /* Encoder status bits and setting. Use with: INTCONF for set and with ESTATUS for read the bits */ + enum Int_Status { + PUSHR = 0x01, + PUSHP = 0x02, + PUSHD = 0x04, + PUSHL = 0x08, + RINC = 0x10, + RDEC = 0x20, + RMAX = 0x40, + RMIN = 0x80, + }; + + union Data_v { + int32_t val; + uint8_t bval[4]; + }; + + uint8_t id = 0x00; + typedef void (*Callback)(i2cEncoderMiniLib*); + + /* Event */ + Callback onButtonRelease = NULL; + Callback onButtonPush = NULL; + Callback onButtonDoublePush = NULL; + Callback onButtonLongPush = NULL; + Callback onIncrement = NULL; + Callback onDecrement = NULL; + Callback onChange = NULL; + Callback onMax = NULL; + Callback onMin = NULL; + Callback onMinMax = NULL; + + + /** Configuration methods **/ + i2cEncoderMiniLib(uint8_t add); + void begin(uint8_t conf); + void reset(void); + void autoconfigInterrupt(void); + + /** Read functions **/ + uint8_t readInterruptConfig(void); + + /** Status function **/ + bool updateStatus(void); + bool readStatus(Int_Status s); + uint8_t readStatus(void); + + /** Encoder functions **/ + int32_t readCounterLong(void); + int16_t readCounterInt(void); + int8_t readCounterByte(void); + int32_t readMax(void); + int32_t readMin(void); + int32_t readStep(void); + + /** Timing registers **/ + uint8_t readAntibouncingPeriod(void); + uint8_t readDoublePushPeriod(void); + uint8_t readIDCode(void); + uint8_t readVersion(void); + + /** EEPROM register **/ + uint8_t readEEPROM(uint8_t add); + + /****** Write functions ********/ + void writeInterruptConfig(uint8_t interrupt); + + /** Encoder functions **/ + void writeCounter(int32_t counter); + void writeMax(int32_t max); + void writeMin(int32_t min); + void writeStep(int32_t step); + + /** Timing registers **/ + void writeAntibouncingPeriod(uint8_t bounc); + void writeDoublePushPeriod(uint8_t dperiod); + void ChangeI2CAddress(uint8_t add); + /** EEPROM register **/ + void writeEEPROM(uint8_t add, uint8_t data); + + private: + + uint8_t _add = 0x00; + uint8_t _stat = 0x00; + uint8_t _gconf = 0x00; + union Data_v _tem_data; + + void eventCaller(Callback *event); + uint8_t readEncoderByte(uint8_t reg); + int16_t readEncoderInt(uint8_t reg); + int32_t readEncoderLong(uint8_t reg); + void writeEncoder(uint8_t reg, uint8_t data); + void writeEncoder(uint8_t reg, int32_t data); +}; + +#endif