├── .gitignore ├── LICENSE ├── README.md ├── examples ├── I2CEncoderMini │ ├── Basic_with_Callbacks │ │ └── Basic_with_Callbacks.ino │ ├── Change_Address │ │ └── Change_Address.ino │ └── README.md ├── I2CEncoderV2 │ ├── Basic │ │ └── Basic.ino │ ├── Basic_with_Callbacks │ │ └── Basic_with_Callbacks.ino │ ├── ESP32_RGB_encoder │ │ └── ESP32_RGB_encoder.ino │ ├── GPs_ADC │ │ └── GPs_ADC.ino │ ├── LCD_with_RGB_encoder │ │ └── LCD_with_RGB_encoder.ino │ ├── Matrix_3x3_RGB_encoders │ │ └── Matrix_3x3_RGB_encoders.ino │ ├── README.md │ ├── Teensy_RGB_encoder │ │ └── Teensy_RGB_encoder.ino │ ├── WEMOS_OLED │ │ └── WEMOS_OLED.ino │ ├── WEMOS_OLED_Menu │ │ └── WEMOS_OLED_Menu.ino │ └── WEMOS_OLED_Menu_Callback_EEPROM │ │ └── WEMOS_OLED_Menu_Callback_EEPROM.ino ├── I2CNavKey │ ├── Basic_with_Callbacks │ │ └── Basic_with_Callbacks.ino │ ├── Basic_with_Callbacks_Float │ │ └── Basic_with_Callbacks_Float.ino │ └── README.md ├── RGB LED Ring Small │ ├── LEDRingSmall_Demo │ │ └── LEDRingSmall_Demo.ino │ └── README.md └── RGB LED Ring │ ├── LEDRingI2CEncoder │ └── LEDRingI2CEncoder.ino │ ├── LEDRing_Demo │ └── LEDRing_Demo.ino │ └── README.md ├── keywords.txt ├── library.properties └── src ├── LEDRing.cpp ├── LEDRing.h ├── LEDRingSmall.cpp ├── LEDRingSmall.h ├── i2cEncoderLibV2.cpp ├── i2cEncoderLibV2.h ├── i2cEncoderMiniLib.cpp ├── i2cEncoderMiniLib.h ├── i2cNavKey.cpp └── i2cNavKey.h /.gitignore: -------------------------------------------------------------------------------- 1 | # ---> C 2 | # Prerequisites 3 | *.d 4 | 5 | # Object files 6 | *.o 7 | *.ko 8 | *.obj 9 | *.elf 10 | 11 | # Linker output 12 | *.ilk 13 | *.map 14 | *.exp 15 | 16 | # Precompiled Headers 17 | *.gch 18 | *.pch 19 | 20 | # Libraries 21 | *.lib 22 | *.a 23 | *.la 24 | *.lo 25 | 26 | # Shared objects (inc. Windows DLLs) 27 | *.dll 28 | *.so 29 | *.so.* 30 | *.dylib 31 | 32 | # Executables 33 | *.exe 34 | *.out 35 | *.app 36 | *.i*86 37 | *.x86_64 38 | *.hex 39 | 40 | # Debug files 41 | *.dSYM/ 42 | *.su 43 | *.idb 44 | *.pdb 45 | 46 | # Kernel Module Compile Results 47 | *.mod* 48 | *.cmd 49 | .tmp_versions/ 50 | modules.order 51 | Module.symvers 52 | Mkfile.old 53 | dkms.conf 54 | 55 | # ---> C++ 56 | # Prerequisites 57 | *.d 58 | 59 | # Compiled Object files 60 | *.slo 61 | *.lo 62 | *.o 63 | *.obj 64 | 65 | # Precompiled Headers 66 | *.gch 67 | *.pch 68 | 69 | # Compiled Dynamic libraries 70 | *.so 71 | *.dylib 72 | *.dll 73 | 74 | # Fortran module files 75 | *.mod 76 | *.smod 77 | 78 | # Compiled Static libraries 79 | *.lai 80 | *.la 81 | *.a 82 | *.lib 83 | 84 | # Executables 85 | *.exe 86 | *.out 87 | *.app 88 | 89 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DuPPa library for the Arduino IDE 2 | 3 | In this repository there is a library collection of the DuPPa boards for the Arduino IDE. 4 | 5 | All the boards are available on [DuPPa Store!](https://www.duppa.net/product-category/i2c-devices/) 6 | 7 | 8 | 9 | Currently supported boards: 10 | 11 | - [I2C Encoder V2.1](https://github.com/Fattoresaimon/I2CEncoderV2.1) Library description [here](https://github.com/Fattoresaimon/ArduinoDuPPaLib/blob/master/examples/I2CEncoderV2/README.md) 12 | - [I2C NavKey](https://github.com/Fattoresaimon/I2CNavKey) Library description [here](https://github.com/Fattoresaimon/ArduinoDuPPaLib/blob/master/examples/I2CNavKey/README.md) 13 | - [I2C Encoder Mini](https://github.com/Fattoresaimon/I2CEncoderMini) Library description [here](https://github.com/Fattoresaimon/ArduinoDuPPaLib/blob/master/examples/I2CEncoderMini/README.md) 14 | - [RGB LED Ring](https://github.com/Fattoresaimon/RGB_LED_Ring) Library description [here](https://github.com/Fattoresaimon/ArduinoDuPPaLib/blob/master/examples/RGB%20LED%20Ring/README.md) 15 | - [RGB LED Ring Small](https://github.com/Fattoresaimon/RGB_LED_Ring_Small) Library description [here](https://github.com/Fattoresaimon/ArduinoDuPPaLib/blob/master/examples/RGB%20LED%20Ring%20Small/README.md) 16 | 17 | 18 | ## Installation 19 | 20 | #### Step 1: 21 | 22 | Download the last .ZIP file of the last [release](https://github.com/Fattoresaimon/ArduinoDuPPaLib/releases) 23 | 24 | #### Step2 25 | 26 | Install on the Arduino IDE: 27 | Open Arduino IDE, under the menu **Sketch** select **Include library** then select **Add .ZIP library** 28 | 29 | In the windows select the downloaded ZIP file. 30 | 31 | 32 | 33 | If everything is done correctly, under the examples there will be the **DuPPa Library** section. 34 | -------------------------------------------------------------------------------- /examples/I2CEncoderMini/Basic_with_Callbacks/Basic_with_Callbacks.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /*This is a basic example for using the I2C Encoder mini 5 | The counter is set to work between +10 to -10, at every encoder click the counter value is printed on the terminal. 6 | It's also printet when the push button is pressed, or released or double pushed. 7 | The callback are used instead of the switch case 8 | 9 | Connections with Arduino UNO: 10 | - -> GND 11 | + -> 5V 12 | SDA -> A4 13 | SCL -> A5 14 | INT -> A3 15 | */ 16 | 17 | const int IntPin = A3; /* Definition of the interrupt pin. You can change according to your board */ 18 | //Class initialization with the I2C addresses 19 | i2cEncoderMiniLib Encoder(0x20); /* A0 is soldered */ 20 | 21 | //Callback when the CVAL is incremented 22 | void encoder_increment(i2cEncoderMiniLib* obj) { 23 | Serial.print("Increment: "); 24 | Serial.println(Encoder.readCounterByte()); 25 | } 26 | 27 | //Callback when the CVAL is decremented 28 | void encoder_decrement(i2cEncoderMiniLib* obj) { 29 | Serial.print("Decrement: "); 30 | Serial.println(Encoder.readCounterByte()); 31 | } 32 | 33 | //Callback when CVAL reach MAX 34 | void encoder_max(i2cEncoderMiniLib* obj) { 35 | Serial.print("Maximum threshold: "); 36 | Serial.println(Encoder.readCounterByte()); 37 | } 38 | 39 | //Callback when CVAL reach MIN 40 | void encoder_min(i2cEncoderMiniLib* obj) { 41 | Serial.print("Minimum threshold: "); 42 | Serial.println(Encoder.readCounterByte()); 43 | } 44 | 45 | //Callback when the encoder is pushed 46 | void encoder_push(i2cEncoderMiniLib* obj) { 47 | Serial.println("Encoder is pushed!"); 48 | } 49 | 50 | //Callback when the encoder is released 51 | void encoder_released(i2cEncoderMiniLib* obj) { 52 | Serial.println("Encoder is released"); 53 | } 54 | 55 | //Callback when the encoder is double pushed 56 | void encoder_double_push(i2cEncoderMiniLib* obj) { 57 | Serial.println("Encoder is double pushed!"); 58 | } 59 | 60 | //Callback when the encoder is long pushed 61 | void encoder_long_push(i2cEncoderMiniLib* obj) { 62 | Serial.println("Encoder is long pushed!"); 63 | } 64 | 65 | void setup(void) { 66 | pinMode(IntPin, INPUT); 67 | Wire.begin(); 68 | Serial.begin(115200); 69 | Serial.println("**** I2C Encoder Mini basic example ****"); 70 | Encoder.reset(); 71 | Encoder.begin(i2cEncoderMiniLib::WRAP_DISABLE 72 | | i2cEncoderMiniLib::DIRE_LEFT | i2cEncoderMiniLib::IPUP_ENABLE 73 | | i2cEncoderMiniLib::RMOD_X1 ); 74 | 75 | Encoder.writeCounter((int32_t) 0); /* Reset the counter value */ 76 | Encoder.writeMax((int32_t) 10); /* Set the maximum threshold*/ 77 | Encoder.writeMin((int32_t) - 10); /* Set the minimum threshold */ 78 | Encoder.writeStep((int32_t) 1); /* Set the step to 1*/ 79 | Encoder.writeDoublePushPeriod(50); /*Set a period for the double push of 500ms */ 80 | 81 | // Definition of the events 82 | Encoder.onIncrement = encoder_increment; 83 | Encoder.onDecrement = encoder_decrement; 84 | Encoder.onMax = encoder_max; 85 | Encoder.onMin = encoder_min; 86 | Encoder.onButtonPush = encoder_push; 87 | Encoder.onButtonRelease = encoder_released; 88 | Encoder.onButtonDoublePush = encoder_double_push; 89 | Encoder.onButtonLongPush = encoder_long_push; 90 | 91 | /* Enable the I2C Encoder V2 interrupts according to the previus attached callback */ 92 | Encoder.autoconfigInterrupt(); 93 | 94 | } 95 | 96 | void loop() { 97 | if (digitalRead(IntPin) == LOW) { 98 | /* Check the status of the encoder and call the callback */ 99 | Encoder.updateStatus(); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /examples/I2CEncoderMini/Change_Address/Change_Address.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* This example is used for change the address of the I2C Encoder Mini 5 | Connections with Arduino UNO: 6 | - -> GND 7 | + -> 5V 8 | SDA -> A4 9 | SCL -> A5 10 | 11 | The COM boudrate is 115200. 12 | You can use the command 'S' for find the I2C encoder mini on the I2C bus. 13 | Or you can write directly the address in decimal or hexadecimal. 14 | After after you need to write the new address in the same way. 15 | Example: 16 | 17 | **** I2C Encoder Address changer! **** 18 | All the devices must have different address! 19 | Avaiable commands: 20 | S: for searching the I2C encoder mini 21 | 0xXX or XXX: Address of the target device in hex or decimal 22 | 23 | S 24 | 25 | Scanning.... 26 | I2C Encoder mini found at 33 ( 0x21 ) !! 27 | 28 | 29 | All the devices must have different address! 30 | Avaiable commands: 31 | S: for searching the I2C encoder mini 32 | 0xXX or XXX: Address of the target device in hex or decimal 33 | 34 | 0x21 35 | 36 | Insert the desired address in hex or decimal: 37 | 38 | 24 39 | 40 | Changing address from 33 ( 0x21 ) to 24 ( 0x18 ) 41 | Address Changed! 42 | 43 | */ 44 | 45 | void ChangeAddress(uint8_t add); 46 | int8_t NewAdd(void); 47 | int8_t CommadParser(void); 48 | int8_t NumberParser(char buff[]); 49 | bool CommandRead(void); 50 | void Search(void); 51 | void PrintHEX(uint8_t i); 52 | 53 | i2cEncoderMiniLib Encoder(0x20); 54 | 55 | 56 | char c_buff[5] = {0}; 57 | uint8_t c_buff_cnt = 0; 58 | 59 | int8_t t_add; 60 | 61 | 62 | void setup(void) { 63 | Wire.begin(); 64 | Serial.begin(115200); 65 | Serial.println("\n\n**** I2C Encoder Address changer! ****"); 66 | } 67 | 68 | void loop() { 69 | Serial.println("All the devices must have different address!"); 70 | Serial.println("Avaiable commands:"); 71 | Serial.println(" S: for searching the I2C encoder mini"); 72 | Serial.println(" 0xXX or XXX: Address of the target device in hex or decimal\n"); 73 | 74 | t_add = CommadParser(); 75 | if (t_add <= 0) { 76 | switch (t_add) { 77 | case -1: 78 | Serial.println("Wrong address range!"); 79 | break; 80 | 81 | case -2: 82 | Serial.println("Wrong command!"); 83 | break; 84 | 85 | case -3: 86 | Search(); 87 | break; 88 | } 89 | } else { 90 | Encoder.address = t_add; 91 | if (Encoder.readIDCode() == 0x39) { 92 | Serial.println("Insert the desired address in hex or decimal: "); 93 | t_add = NewAdd(); 94 | if (t_add <= 0) { 95 | Serial.println("Incorrect Address!"); 96 | } else { 97 | ChangeAddress(t_add); 98 | } 99 | } else { 100 | Serial.println("No device at that address!"); 101 | } 102 | } 103 | Serial.print("\n\n"); 104 | } 105 | 106 | 107 | void ChangeAddress(uint8_t add) { 108 | Serial.print("Changing address from "); 109 | Serial.print(Encoder.address); 110 | Serial.print(" ( "); 111 | PrintHEX(Encoder.address); 112 | Serial.print(" ) to "); 113 | Serial.print(add); 114 | Serial.print(" ( "); 115 | PrintHEX(add); 116 | Serial.println(" )"); 117 | Encoder.ChangeI2CAddress(add); 118 | // delay(1000); 119 | Encoder.reset(); 120 | Encoder.address = add; 121 | if (Encoder.readIDCode() == 0x39) { 122 | Serial.println("Address Changed!"); 123 | } else { 124 | Serial.println("Error in changing address!"); 125 | } 126 | } 127 | 128 | 129 | int8_t NewAdd(void) { 130 | 131 | if (CommandRead() == true) { 132 | return (NumberParser(c_buff)); 133 | } else { 134 | return -1; 135 | } 136 | } 137 | 138 | 139 | int8_t CommadParser(void) { 140 | 141 | if (CommandRead() == true) { 142 | if ( c_buff[0] == 'S' && c_buff[1] == '\n') { 143 | return -3; 144 | } 145 | return (NumberParser(c_buff)); 146 | } else { 147 | return -2; 148 | } 149 | } 150 | 151 | 152 | int8_t NumberParser(char buff[]) { 153 | int8_t temp; 154 | if ( buff[0] == '0' && buff[1] == 'x') { 155 | temp = (int8_t)strtol(buff, NULL, 16); 156 | } else { 157 | temp = (int8_t)strtol(buff, NULL, 10); 158 | } 159 | 160 | if (temp <= 0) { 161 | return -1; 162 | } else { 163 | return temp; 164 | } 165 | 166 | } 167 | 168 | 169 | bool CommandRead(void) { 170 | c_buff_cnt = 0; 171 | while(Serial. read() >= 0); 172 | while (c_buff_cnt < 5) { 173 | if (Serial.available()) { 174 | char inChar = (char)Serial.read(); 175 | c_buff[c_buff_cnt] = inChar; 176 | c_buff_cnt++; 177 | if (inChar == '\n') 178 | return true; 179 | } 180 | } 181 | return false; 182 | } 183 | 184 | 185 | void Search(void) { 186 | uint8_t i, error; 187 | Serial.println("Scanning...."); 188 | for (i = 0; i < 0x80; i++ ) 189 | { 190 | Wire.beginTransmission(i); 191 | error = Wire.endTransmission(); 192 | 193 | if (error == 0) 194 | { 195 | Encoder.address = i; 196 | if (Encoder.readIDCode() == 0x39) { 197 | Serial.print("I2C Encoder mini found at "); 198 | Serial.print(Encoder.address); 199 | Serial.print(" ( "); 200 | PrintHEX(Encoder.address); 201 | Serial.print(" )"); 202 | Serial.println(" !!"); 203 | } 204 | } 205 | 206 | } 207 | } 208 | 209 | 210 | void PrintHEX(uint8_t i) { 211 | Serial.print("0x"); 212 | if (i < 16) 213 | Serial.print("0"); 214 | Serial.print(i, HEX); 215 | } 216 | -------------------------------------------------------------------------------- /examples/I2CEncoderMini/README.md: -------------------------------------------------------------------------------- 1 | # I2C Encoder Mini Arduino Library 2 | -------------------------------------------------------------------------------- 3 | 4 | ## Introduction 5 | 6 | Here you can find the library description of the [I2C Encoder Mini](https://github.com/Fattoresaimon/I2CEncoderMini) for the Arduino IDE. 7 | For more details of the functionality of the board, please read the Datasheet on GitHub 8 | 9 | The I2C Encoder Mini is available on [Tindie!](https://www.tindie.com/products/saimon/i2c-encoder-mini/) 10 | 11 | ## Initialization of the class 12 | 13 | The library makes available the class **i2cEncoderMiniLib** 14 | To initialize the library, you have to declare an instance of the class **i2cEncoderMiniLib** for each encoders. 15 | For example: 16 | 17 | ``` C++ 18 | i2cEncoderMiniLib encoder(0x30); 19 | ``` 20 | Declaration of one encoder with the address 0x30. The jumper A4 and A5 are shorted. 21 | 22 | ``` C++ 23 | i2cEncoderMiniLib encoder(0b0110000); 24 | ``` 25 | Declaration of the same encoder but in binary format. 26 | 27 | ```C++ 28 | i2cEncoderMiniLib encoder1(0x30); 29 | i2cEncoderMiniLib encoder2(0x32); 30 | ``` 31 | Declaration of two encoders with the address 0x30 and 0x34 in two separated variable. 32 | 33 | ```C++ 34 | i2cEncoderMiniLib encoder[2] = { i2cEncoderMiniLib(0x30), i2cEncoderMiniLib(0x34)}; 35 | ``` 36 | Declaration of an array of the two encoders with the address 0x30 and 0x34. 37 | 38 | ## Parameters 39 | 40 | Each class has also a public variable called **id** that is used for setting a custom id to each class. 41 | 42 | ```C++ 43 | i2cEncoderMiniLib encoder(0x30); 44 | encoder.id=1 45 | ``` 46 | The **id** can be useful when you declare an array of i2cEncoderMiniLib class. The **id** can be used as a index in the loops. 47 | 48 | ## Callback Configuration 49 | 50 | This library support the callback functionality. 51 | There is the possibility to link a function to a specific interrupt of the I2C Encoder V2, in this way the function is automatically called when the I2C Encoder V2 generates an interrupts. 52 | 53 | A callback function must be declared as the following: 54 | 55 | ```C++ 56 | void NAME_OF_THE_FUNCTION(i2cEncoderMiniLib* obj) 57 | ``` 58 | 59 | The argument **i2cEncoderMiniLib* obj** is the pointer to the class that called the method. 60 | 61 | There are 16 possible events: 62 | 63 | | Event | Description | 64 | |:-----------:|:----------------------------------| 65 | | onButtonRelease | Encoder push button is released | 66 | | onButtonPush | Encoder push button is pushed | 67 | | onButtonDoublePush | Encoder push button is double pushed | 68 | | onButtonLongPush | Encoder push button is long press| 69 | | onIncrement | The counter value is incremented | 70 | | onDecrement | The counter value is decremented | 71 | | onChange | The counter value is incremented or decremented | 72 | | onMax | The counter value reach the maximum threshold | 73 | | onMin | The counter value reach the minimum threshold | 74 | | onMinMax | The counter value reach the maximum or minimum threshold | 75 | 76 | 77 | #### Examples: 78 | 79 | ```C++ 80 | i2cEncoderMiniLib Encoder(0x61); // Class declaration 81 | 82 | ... 83 | 84 | // Simple callback that ist's called when the encoder is rotated 85 | void encoder_change(i2cEncoderMiniLib* obj) { 86 | Serial.println( obj->readCounterByte()); //Print on the terminal the counter value. 87 | } 88 | 89 | ... 90 | 91 | Encoder.onChange = encoder_change; //Attach the event to the callback function. 92 | 93 | } 94 | 95 | ``` 96 | 97 | If you need to remove the link with a callback, you just need to define: 98 | ```C++ 99 | Encoder.onChange=NULL; 100 | ``` 101 | 102 | ## Initialization 103 | ### void begin( uint16_t conf) 104 | This is used for initializing the encoder by writing the configuration register of the encoder. 105 | The parameters can be concatenated in OR mode. 106 | The possible parameters are the following: 107 | 108 | | Parameter | Description | 109 | | ---------- | ------------------------------------------------------ | 110 | | WRAP_ENABLE | Wrap enable. When the counter value reaches the CMAX+1, restart to the CMIN and vice versa | 111 | | WRAP_DISABLE | Wrap disable. When the counter value reaches the CMAX or CMIN, the counter stops to increasing or decreasing | 112 | | | | 113 | | DIRE_LEFT | Rotate left side to increase the value counter | 114 | | DIRE_RIGHT | Rotate right side to increase the value counter | 115 | | | | 116 | | IPUP_DISABLE | Disable the internal pull-up on the INT pin | 117 | | IPUP_ENABLE | Enable the internal pull-up on the INT pin | 118 | | | | 119 | | RMOD_X4 | Encoder in X4 mode | 120 | | RMOD_X2 | Encoder in X2 mode | 121 | | RMOD_X1 | Encoder in X1 mode | 122 | | | | 123 | | RESET | Reset the board | 124 | 125 | 126 | 127 | #### Examples: 128 | 129 | ```C++ 130 | encoder.begin(i2cEncoderMiniLib::WRAP_DISABLE | i2cEncoderMiniLib::DIRE_LEFT | i2cEncoderMiniLib::IPUP_ENABLE | i2cEncoderMiniLib::RMOD_X1 ); 131 | ``` 132 | 133 | Please remember to add the class name **i2cEncoderMiniLib::** before the parameter! 134 | 135 | ### void reset(void) 136 | 137 | Reset of the board. 138 | In this command there is 10ms delay in order to make the board correctly restart. 139 | 140 | 141 | 142 | ## Configuration 143 | 144 | ### void writeInterruptConfig(uint8_t interrupt) 145 | 146 | This method is used for enabling or disabling the interrupt source selectively. When an interrupt event occurs, the INT pin goes low and the event is stored in the status register. 147 | 148 | | Parameter | Description | 149 | |:-----------:|:-------------:| 150 | | PUSHR | Push button of the encoder is released | 151 | | PUSHP | Push button of the encoder is pressed | 152 | | PUSHD | Push button of the encoder is doule pushed | 153 | | RINC | Encoder is rotated in the increment direction | 154 | | RDEC | Encoder is rotated in the decrement direction | 155 | | RMAX | Maximum threshold is reached | 156 | | RMIN | Minimum threshold is reached | 157 | | INT_2 | An event on the interrupt 2 register occurs | 158 | 159 | #### Examples: 160 | 161 | ```C++ 162 | Encoder.writeInterruptConfig(i2cEncoderMiniLib::INT_2 | i2cEncoderMiniLib::RMIN | i2cEncoderMiniLib::RMAX | i2cEncoderMiniLib::RDEC | i2cEncoderMiniLib::RINC | i2cEncoderMiniLib::PUSHR); 163 | ``` 164 | 165 | Please remember to add the class name **i2cEncoderMiniLib::** before the parameter! 166 | 167 | ### void autoconfigInterrupt(void) 168 | 169 | This method auto configures the **INTCONF** register according to the attached callback. 170 | **For the proper use, must be called after the definition of the last event property.** 171 | 172 | ```C++ 173 | Encoder.onIncrement = encoder_increment; 174 | Encoder.onDecrement = encoder_decrement; 175 | Encoder.onMax = encoder_max; 176 | Encoder.onMin = encoder_min; 177 | Encoder.onButtonPush = encoder_push; 178 | Encoder.onButtonRelease = encoder_released; 179 | Encoder.onButtonDoublePush = encoder_double_push; 180 | /* Enable the I2C Encoder V2 interrupts according to the previus attached callback */ 181 | Encoder.autoconfigInterrupt(); 182 | 183 | ``` 184 | 185 | ### void writeDoublePushPeriod(uint8_t dperiod) 186 | 187 | This method is used for setting the window period **DPPERIOD** of the double push of the rotary encoder switch. When the value is 0, the double push option is disabled. 188 | The I2C encoder V2 will multiplies this value by 10 (value x10). 189 | 190 | #### Examples: 191 | 192 | ```C++ 193 | encoder.writeDoublePushPeriod(50); //Set a period for the double push of 500ms 194 | ``` 195 | 196 | ### void ChangeI2CAddress(uint8_t add) 197 | This methods is used to change the I2C address of the device. 198 | The changes will have effect after a reset or a power cycle of the board. 199 | 200 | **Pay attention with this command, it's not reversible!** 201 | 202 | 203 | ## Status 204 | 205 | ### bool updateStatus(void) 206 | Read from the encoder status register **ESTATUS** and save the value internally. 207 | Return value is **true** in case of some event, otherwise is **false** 208 | In case an event of the I2STATUS register, the I2STATUS is automatically be read. 209 | 210 | #### Examples: 211 | 212 | ```C++ 213 | if ( Encoder.updateStatus() == true) { 214 | // Something happens 215 | } 216 | ``` 217 | 218 | ### bool readStatus(Int_Status s) 219 | Must be called after **updateStatus()**, this method is used for checking if some event occurs on the **ESTATUS** register. 220 | Return value is **true** in case of the event occured, otherwise is **false** 221 | Possible parameters are: 222 | 223 | | Parameter | Description | 224 | |:-----------:|:-------------:| 225 | | PUSHR | Push button of the encoder is released | 226 | | PUSHP | Push button of the encoder is pressed | 227 | | PUSHD | Push button of the encoder is doule pushed | 228 | | RINC | Encoder is rotated in the increment direction | 229 | | RDEC | Encoder is rotated in the decrement direction | 230 | | RMAX | Maximum threshold is reached | 231 | | RMIN | Minimum threshold is reached | 232 | | INT2 | An event on the interrupt 2 register occurs | 233 | 234 | #### Example: 235 | ```C++ 236 | if ( Encoder.updateStatus() == true) { 237 | if ( Encoder.readStatus(i2cEncoderMiniLib::RINC)) { 238 | Serial.print("Increment "); 239 | } 240 | if ( Encoder.readStatus(i2cEncoderMiniLib::RDEC)) { 241 | Serial.print("Decrement "); 242 | } 243 | 244 | if ( Encoder.readStatus(i2cEncoderMiniLib::RMAX)) { 245 | Serial.print("Maximum threshold: "); 246 | } 247 | 248 | if ( Encoder.readStatus(i2cEncoderMiniLib::RMIN)) { 249 | Serial.print("Minimum threshold: "); 250 | } 251 | 252 | if ( Encoder.readStatus(i2cEncoderMiniLib::PUSHR)) { 253 | Serial.println("Push button Released"); 254 | } 255 | 256 | if ( Encoder.readStatus(i2cEncoderMiniLib::PUSHP)) { 257 | } 258 | 259 | if ( Encoder.readStatus(i2cEncoderMiniLib::PUSHD)) { 260 | Serial.println("Double push!"); 261 | } 262 | ``` 263 | 264 | Please remember to add the class name **i2cEncoderMiniLib::** before the parameter! 265 | 266 | ### uint8_t readStatus(void) 267 | Return the status of the register **ESTATUS** 268 | 269 | 270 | 271 | ## Reading methods 272 | 273 | ### int32_t readCounterLong(void) 274 | Return the counter value in the format **int32_t**, by reading all the 4 bytes of the counter value registers. 275 | 276 | ### int16_t readCounterInt(void) 277 | Return the counter value in the format **int16_t**, by reading the 2 LSB of the counter value registers. 278 | Useful when the counter register is between the values -32768 to 32767. 279 | 280 | ### int8_t readCounterByte(void) 281 | Return the counter value in the format **int8_t**, by reading the LSB byte of the counter value register. 282 | Useful when the counter register is between the values -128 to 127 283 | 284 | 285 | ### int32_t readMax(void) 286 | Return the maximum threshold in format **int32_t**, bye reading all the 4 bytes of the counter Max. 287 | 288 | 289 | ### int32_t readMin(void) 290 | Return the minimum threshold in format **int32_t**, by reading all the 4 byte of the counter Min. 291 | 292 | 293 | ### int32_t readStep(void) 294 | Return the minimum threshold in format **int32_t**, by reading all the 4 bytes of the ISTEP registers. 295 | 296 | ### uint8_t readDoublePushPeriod(void) 297 | Return the value of the DPPERIOD register. 298 | 299 | ### uint8_t readIDCode(uint8_t add) 300 | Return the ID code of the I2C Encoder V2.1, that is 0x53 301 | Avaiable only on the V2.1 302 | 303 | ### uint8_t readVersion(uint8_t add) 304 | Return the version of the board. 305 | Avaiable only on the V2.1 306 | 307 | ### uint8_t readEEPROM(uint8_t add) 308 | Return the value of the EEPROM register. 309 | This function automatically manage the setting of the first and second memory bank. 310 | 311 | 312 | ## Writing methods 313 | 314 | ### void writeCounter(int32_t counter) 315 | Write the counter value register with a **int32_t** number. All of the 4 bytes are wrote. 316 | 317 | ### void writeCounter(float counter) 318 | Write the counter value register with a **float** number. All of the 4 bytes are wrote. 319 | 320 | ### void writeMax(int32_t max) 321 | Write the Max register with a **int32_t** number. All of the 4 bytes are wrote. 322 | 323 | ### void writeMin(int32_t min) 324 | Write the Min register with a **int32_t** number. All of the 4 bytes are wrote. 325 | 326 | ### void writeStep(int32_t step) 327 | Write the increment step with a **int32_t** number. All of the 4 bytes are wrote. 328 | 329 | ### void writeDoublePushPeriod(uint8_t dperiod) 330 | Write the DPPERIOD register. 331 | 332 | 333 | ### void writeEEPROM(uint8_t add, uint8_t data) 334 | Write the EEPROM memory. 335 | The input parameter *add* is the address. 336 | The input parameter *data* is the data that will be written. 337 | 338 | 339 | -------------------------------------------------------------------------------- /examples/I2CEncoderV2/Basic/Basic.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /*This is a basic example for using the I2C Encoder V2 5 | The counter is set to work between +10 to -10, at every encoder click the counter value is printed on the terminal. 6 | It's also printet when the push button is pressed, or released or double pushed. 7 | 8 | 9 | Connections with Arduino UNO: 10 | - -> GND 11 | + -> 5V 12 | SDA -> A4 13 | SCL -> A5 14 | INT -> A3 15 | */ 16 | 17 | const int IntPin = A3; /* Definition of the interrupt pin. You can change according to your board /* 18 | //Class initialization with the I2C addresses*/ 19 | i2cEncoderLibV2 Encoder(0x01); /* A0 is soldered */ 20 | 21 | void setup(void) { 22 | pinMode(IntPin, INPUT); 23 | Wire.begin(); 24 | Serial.begin(115200); 25 | Serial.println("**** I2C Encoder V2 basic example ****"); 26 | /* 27 | INT_DATA= The register are considered integer. 28 | WRAP_DISABLE= The WRAP option is disabled 29 | DIRE_LEFT= Encoder left direction increase the value 30 | IPUP_ENABLE= INT pin have the pull-up enabled. 31 | RMOD_X1= Encoder configured as X1. 32 | RGB_ENCODER= type of encoder is RGB, change to STD_ENCODER in case you are using a normal rotary encoder. 33 | */ 34 | Encoder.reset(); 35 | Encoder.begin( 36 | i2cEncoderLibV2::INT_DATA | i2cEncoderLibV2::WRAP_DISABLE 37 | | i2cEncoderLibV2::DIRE_LEFT | i2cEncoderLibV2::IPUP_ENABLE 38 | | i2cEncoderLibV2::RMOD_X1 | i2cEncoderLibV2::RGB_ENCODER); 39 | 40 | // Use this in case of standard encoder! 41 | // Encoder.begin(i2cEncoderLibV2::INT_DATA | i2cEncoderLibV2::WRAP_DISABLE | i2cEncoderLibV2::DIRE_LEFT | i2cEncoderLibV2::IPUP_ENABLE | i2cEncoderLibV2::RMOD_X1 | i2cEncoderLibV2::STD_ENCODER); 42 | 43 | // try also this! 44 | // Encoder.begin(i2cEncoderLibV2::INT_DATA | i2cEncoderLibV2::WRAP_ENABLE | i2cEncoderLibV2::DIRE_LEFT | i2cEncoderLibV2::IPUP_ENABLE | i2cEncoderLibV2::RMOD_X1 | i2cEncoderLibV2::RGB_ENCODER); 45 | 46 | Encoder.writeCounter((int32_t) 0); /* Reset the counter value */ 47 | Encoder.writeMax((int32_t) 10); /* Set the maximum threshold*/ 48 | Encoder.writeMin((int32_t) - 10); /* Set the minimum threshold */ 49 | Encoder.writeStep((int32_t) 1); /* Set the step to 1*/ 50 | Encoder.writeInterruptConfig(0xff); /* Enable all the interrupt */ 51 | Encoder.writeAntibouncingPeriod(20); /* Set an anti-bouncing of 200ms */ 52 | Encoder.writeDoublePushPeriod(50); /*Set a period for the double push of 500ms */ 53 | } 54 | 55 | void loop() { 56 | 57 | if (digitalRead(IntPin) == LOW) { 58 | if (Encoder.updateStatus()) { 59 | if (Encoder.readStatus(i2cEncoderLibV2::RINC)) { 60 | Serial.print("Increment: "); 61 | Serial.println(Encoder.readCounterByte()); 62 | 63 | /* Write here your code */ 64 | 65 | } 66 | if (Encoder.readStatus(i2cEncoderLibV2::RDEC)) { 67 | Serial.print("Decrement: "); 68 | Serial.println(Encoder.readCounterByte()); 69 | 70 | /* Write here your code */ 71 | 72 | } 73 | 74 | if (Encoder.readStatus(i2cEncoderLibV2::RMAX)) { 75 | Serial.print("Maximum threshold: "); 76 | Serial.println(Encoder.readCounterByte()); 77 | 78 | /* Write here your code */ 79 | 80 | } 81 | 82 | if (Encoder.readStatus(i2cEncoderLibV2::RMIN)) { 83 | Serial.print("Minimum threshold: "); 84 | Serial.println(Encoder.readCounterByte()); 85 | 86 | /* Write here your code */ 87 | 88 | } 89 | 90 | if (Encoder.readStatus(i2cEncoderLibV2::PUSHR)) { 91 | Serial.println("Push button Released"); 92 | 93 | /* Write here your code */ 94 | 95 | } 96 | 97 | if (Encoder.readStatus(i2cEncoderLibV2::PUSHP)) { 98 | Serial.println("Push button Pressed"); 99 | 100 | /* Write here your code */ 101 | 102 | } 103 | 104 | if (Encoder.readStatus(i2cEncoderLibV2::PUSHD)) { 105 | Serial.println("Double push!"); 106 | 107 | /* Write here your code */ 108 | 109 | } 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /examples/I2CEncoderV2/Basic_with_Callbacks/Basic_with_Callbacks.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /*This is a basic example for using the I2C Encoder V2 5 | The counter is set to work between +10 to -10, at every encoder click the counter value is printed on the terminal. 6 | It's also printet when the push button is pressed, or released or double pushed. 7 | The callback are used instead of the switch case 8 | 9 | Connections with Arduino UNO: 10 | - -> GND 11 | + -> 5V 12 | SDA -> A4 13 | SCL -> A5 14 | INT -> A3 15 | */ 16 | 17 | const int IntPin = A3; /* Definition of the interrupt pin. You can change according to your board */ 18 | //Class initialization with the I2C addresses 19 | i2cEncoderLibV2 Encoder(0x01); /* A0 is soldered */ 20 | 21 | //Callback when the CVAL is incremented 22 | void encoder_increment(i2cEncoderLibV2* obj) { 23 | Serial.print("Increment: "); 24 | Serial.println(Encoder.readCounterByte()); 25 | } 26 | 27 | //Callback when the CVAL is decremented 28 | void encoder_decrement(i2cEncoderLibV2* obj) { 29 | Serial.print("Decrement: "); 30 | Serial.println(Encoder.readCounterByte()); 31 | } 32 | 33 | //Callback when CVAL reach MAX 34 | void encoder_max(i2cEncoderLibV2* obj) { 35 | Serial.print("Maximum threshold: "); 36 | Serial.println(Encoder.readCounterByte()); 37 | } 38 | 39 | //Callback when CVAL reach MIN 40 | void encoder_min(i2cEncoderLibV2* obj) { 41 | Serial.print("Minimum threshold: "); 42 | Serial.println(Encoder.readCounterByte()); 43 | } 44 | 45 | //Callback when the encoder is pushed 46 | void encoder_push(i2cEncoderLibV2* obj) { 47 | Serial.println("Encoder is pushed!"); 48 | } 49 | 50 | //Callback when the encoder is released 51 | void encoder_released(i2cEncoderLibV2* obj) { 52 | Serial.println("Encoder is released"); 53 | } 54 | 55 | //Callback when the encoder is double pushed 56 | void encoder_double_push(i2cEncoderLibV2* obj) { 57 | Serial.println("Encoder is double pushed!"); 58 | } 59 | 60 | void setup(void) { 61 | pinMode(IntPin, INPUT); 62 | Wire.begin(); 63 | Serial.begin(115200); 64 | Serial.println("**** I2C Encoder V2 basic example ****"); 65 | /* 66 | INT_DATA= The register are considered integer. 67 | WRAP_DISABLE= The WRAP option is disabled 68 | DIRE_LEFT= Encoder left direction increase the value 69 | IPUP_ENABLE= INT pin have the pull-up enabled. 70 | RMOD_X1= Encoder configured as X1. 71 | RGB_ENCODER= type of encoder is RGB, change to STD_ENCODER in case you are using a normal rotary encoder. 72 | */ 73 | Encoder.reset(); 74 | Encoder.begin( 75 | i2cEncoderLibV2::INT_DATA | i2cEncoderLibV2::WRAP_DISABLE 76 | | i2cEncoderLibV2::DIRE_LEFT | i2cEncoderLibV2::IPUP_ENABLE 77 | | i2cEncoderLibV2::RMOD_X1 | i2cEncoderLibV2::RGB_ENCODER); 78 | // Use this in case of standard encoder! 79 | // Encoder.begin(i2cEncoderLibV2::INT_DATA | i2cEncoderLibV2::WRAP_DISABLE | i2cEncoderLibV2::DIRE_LEFT | i2cEncoderLibV2::IPUP_ENABLE | i2cEncoderLibV2::RMOD_X1 | i2cEncoderLibV2::STD_ENCODER); 80 | 81 | // try also this! 82 | // Encoder.begin(i2cEncoderLibV2::INT_DATA | i2cEncoderLibV2::WRAP_ENABLE | i2cEncoderLibV2::DIRE_LEFT | i2cEncoderLibV2::IPUP_ENABLE | i2cEncoderLibV2::RMOD_X1 | i2cEncoderLibV2::RGB_ENCODER); 83 | 84 | Encoder.writeCounter((int32_t) 0); /* Reset the counter value */ 85 | Encoder.writeMax((int32_t) 10); /* Set the maximum threshold*/ 86 | Encoder.writeMin((int32_t) - 10); /* Set the minimum threshold */ 87 | Encoder.writeStep((int32_t) 1); /* Set the step to 1*/ 88 | Encoder.writeAntibouncingPeriod(20); /* Set an anti-bouncing of 200ms */ 89 | Encoder.writeDoublePushPeriod(50); /*Set a period for the double push of 500ms */ 90 | 91 | // Definition of the events 92 | Encoder.onIncrement = encoder_increment; 93 | Encoder.onDecrement = encoder_decrement; 94 | Encoder.onMax = encoder_max; 95 | Encoder.onMin = encoder_min; 96 | Encoder.onButtonPush = encoder_push; 97 | Encoder.onButtonRelease = encoder_released; 98 | Encoder.onButtonDoublePush = encoder_double_push; 99 | 100 | /* Enable the I2C Encoder V2 interrupts according to the previus attached callback */ 101 | Encoder.autoconfigInterrupt(); 102 | 103 | } 104 | 105 | void loop() { 106 | if (digitalRead(IntPin) == LOW) { 107 | /* Check the status of the encoder and call the callback */ 108 | Encoder.updateStatus(); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /examples/I2CEncoderV2/ESP32_RGB_encoder/ESP32_RGB_encoder.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /*This is a basic example for using the I2C Encoder V2 5 | The counter is set to work between +10 to -10, at every encoder click the counter value is printed on the terminal. 6 | It's also printet when the push button is released. 7 | When the encoder is turned the led turn green 8 | When the encoder reach the max or min the led turn red 9 | When the encoder is pushed, the led turn blue 10 | 11 | Connections with ESP-32 Dev Kit: 12 | - -> GND 13 | + -> 3.3V 14 | SDA -> 21 15 | SCL -> 22 16 | INT -> 23 17 | */ 18 | 19 | const int IntPin = 23; /* Definition of the interrupt pin, change according to your configuration*/ 20 | //Class initialization with the I2C addresses 21 | i2cEncoderLibV2 Encoder(0b1100001); /* For make the address 0x61 only the jumpers A0, A5 and A6 are soldered.*/ 22 | 23 | //Callback when the encoder is rotated 24 | void encoder_rotated(i2cEncoderLibV2* obj) { 25 | if ( obj->readStatus( i2cEncoderLibV2::RINC)) 26 | Serial.print("Increment: "); 27 | else 28 | Serial.print("Decrement: "); 29 | Serial.println( obj->readCounterInt()); 30 | obj->writeRGBCode(0x00FF00); 31 | } 32 | 33 | 34 | //Callback when the encoder is pushed 35 | void encoder_click(i2cEncoderLibV2* obj) { 36 | Serial.println("Push: "); 37 | obj->writeRGBCode(0x0000FF); 38 | } 39 | 40 | 41 | //Callback when the encoder reach the max or min 42 | void encoder_thresholds(i2cEncoderLibV2* obj) { 43 | if ( obj->readStatus( i2cEncoderLibV2::RMAX)) 44 | Serial.println("Max!"); 45 | else 46 | Serial.println("Min!"); 47 | 48 | obj->writeRGBCode(0xFF0000); 49 | } 50 | 51 | 52 | //Callback when the fading process finish and set the RGB led off 53 | void encoder_fade(i2cEncoderLibV2* obj) { 54 | obj->writeRGBCode(0x000000); 55 | } 56 | 57 | 58 | void setup(void) 59 | { 60 | pinMode(IntPin, INPUT); 61 | 62 | Serial.begin(115200); 63 | Serial.println("**** I2C Encoder V2 basic example ****"); 64 | /* 65 | INT_DATA= The register are considered integer. 66 | WRAP_DISABLE= The WRAP option is disabled 67 | DIRE_LEFT= Encoder left direction increase the value 68 | IPUP_ENABLE= INT pin have the pull-up enabled. 69 | RMOD_X1= Encoder configured as X1. 70 | RGB_ENCODER= type of encoder is RGB, change to STD_ENCODER in case you are using a normal rotary encoder. 71 | */ 72 | Wire.begin(); 73 | Encoder.reset(); 74 | 75 | Encoder.begin(i2cEncoderLibV2::INT_DATA |i2cEncoderLibV2:: WRAP_DISABLE | i2cEncoderLibV2::DIRE_LEFT | i2cEncoderLibV2::IPUP_ENABLE | i2cEncoderLibV2::RMOD_X1 | i2cEncoderLibV2::RGB_ENCODER); 76 | // Encoder.begin(i2cEncoderLibV2::INT_DATA | i2cEncoderLibV2::WRAP_DISABLE | i2cEncoderLibV2::DIRE_LEFT | i2cEncoderLibV2::IPUP_ENABLE | i2cEncoderLibV2::RMOD_X1 | i2cEncoderLibV2::STD_ENCODER); // try also this! 77 | // Encoder.begin(i2cEncoderLibV2::INT_DATA | i2cEncoderLibV2::WRAP_ENABLE | i2cEncoderLibV2::DIRE_LEFT | i2cEncoderLibV2::IPUP_ENABLE | i2cEncoderLibV2::RMOD_X1 | i2cEncoderLibV2::RGB_ENCODER); // try also this! 78 | 79 | Encoder.writeCounter((int32_t)0); /* Reset the counter value */ 80 | Encoder.writeMax((int32_t)10); /* Set the maximum threshold*/ 81 | Encoder.writeMin((int32_t) - 10); /* Set the minimum threshold */ 82 | Encoder.writeStep((int32_t)1); /* Set the step to 1*/ 83 | /* Configure the events */ 84 | Encoder.onChange = encoder_rotated; 85 | Encoder.onButtonRelease = encoder_click; 86 | Encoder.onMinMax = encoder_thresholds; 87 | Encoder.onFadeProcess = encoder_fade; 88 | 89 | /* Enable the I2C Encoder V2 interrupts according to the previus attached callback */ 90 | Encoder.autoconfigInterrupt(); 91 | 92 | Encoder.writeAntibouncingPeriod(20); /* Set an anti-bouncing of 200ms */ 93 | 94 | /* blink the RGB LED */ 95 | Encoder.writeRGBCode(0xFF0000); 96 | delay(250); 97 | Encoder.writeRGBCode(0x00FF00); 98 | delay(250); 99 | Encoder.writeRGBCode(0x0000FF); 100 | delay(250); 101 | Encoder.writeRGBCode(0x000000); 102 | 103 | Encoder.writeFadeRGB(3); //Fade enabled with 3ms step 104 | 105 | } 106 | 107 | void loop() { 108 | 109 | /* Waith when the INT pin goes low */ 110 | if (digitalRead(IntPin) == LOW) { 111 | /* Check the status of the encoder and call the callback */ 112 | Encoder.updateStatus(); 113 | } 114 | } -------------------------------------------------------------------------------- /examples/I2CEncoderV2/GPs_ADC/GPs_ADC.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /*In this example a standard encoder is used. 5 | The GP pins are configured as analog and 6 | the ADC vale is printed on the serial port 7 | as well as the counter value 8 | 9 | 10 | Connections with Arduino UNO: 11 | - -> GND 12 | + -> 5V 13 | SDA -> A4 14 | SCL -> A5 15 | INT -> A3 16 | */ 17 | unsigned long previousMillis = 0; 18 | const long interval = 1000; // interval between ADC reading of the GP pins 19 | 20 | const int IntPin = A3; // Change according to your board configuration 21 | 22 | //Class initialization with the I2C addresses 23 | i2cEncoderLibV2 STDEncoder(0b0001000); //Normal rotary encoder address, A3 is soldered 24 | 25 | 26 | uint8_t encoder_status, i; 27 | void setup(void) 28 | { 29 | // Reset the two encoder 30 | Wire.begin(); 31 | 32 | 33 | // Initialize the GPIO and the display 34 | pinMode(IntPin, INPUT); 35 | pinMode(LED_BUILTIN, OUTPUT); 36 | 37 | //Initialize the Serial port 38 | Serial.begin(115200); 39 | Serial.print("Encoder Test!!\n"); 40 | 41 | 42 | //Configure the Standard Encoder 43 | STDEncoder.reset(); 44 | STDEncoder.begin(i2cEncoderLibV2::INT_DATA | i2cEncoderLibV2::WRAP_DISABLE | i2cEncoderLibV2::DIRE_LEFT | i2cEncoderLibV2::IPUP_ENABLE | i2cEncoderLibV2::RMOD_X1 | i2cEncoderLibV2::STD_ENCODER); 45 | STDEncoder.writeGP1conf(i2cEncoderLibV2::GP_AN | i2cEncoderLibV2::GP_PULL_EN | i2cEncoderLibV2::GP_INT_DI); // Configure the GP pins in analog mode 46 | STDEncoder.writeGP2conf(i2cEncoderLibV2::GP_AN | i2cEncoderLibV2::GP_PULL_EN | i2cEncoderLibV2::GP_INT_DI); // Configure the GP pins in analog mode 47 | STDEncoder.writeGP3conf(i2cEncoderLibV2::GP_AN | i2cEncoderLibV2::GP_PULL_EN | i2cEncoderLibV2::GP_INT_DI); // Configure the GP pins in analog mode 48 | STDEncoder.writeCounter((int32_t) 0); 49 | STDEncoder.writeMax((int32_t) 10); 50 | STDEncoder.writeMin((int32_t) 0); 51 | STDEncoder.writeStep((int32_t) 1); 52 | STDEncoder.writeInterruptConfig(i2cEncoderLibV2::INT_2 | i2cEncoderLibV2::RINC | i2cEncoderLibV2::RDEC | i2cEncoderLibV2::RMAX | i2cEncoderLibV2::RMIN); //Enable all the interrupts 53 | STDEncoder.writeAntibouncingPeriod(20); /* Set an anti-bouncing of 200ms */ 54 | STDEncoder.updateStatus(); 55 | 56 | } 57 | 58 | void loop() { 59 | 60 | unsigned long currentMillis = millis(); 61 | 62 | if (currentMillis - previousMillis >= interval) { 63 | previousMillis = currentMillis; 64 | 65 | Serial.print("GP1: "); 66 | Serial.print(STDEncoder.readGP1()); //read the analog value of the GP1 67 | Serial.print("\tGP2: "); 68 | Serial.print(STDEncoder.readGP2()); //read the analog value of the GP2 69 | Serial.print("\tGP3: "); 70 | Serial.println(STDEncoder.readGP3()); //read the analog value of the GP3 71 | 72 | } 73 | 74 | 75 | if (digitalRead(IntPin) == LOW) { //Check for the interrupt 76 | 77 | if (STDEncoder.updateStatus()) { //Check if the normal encoder is moved 78 | 79 | //Print the counter value of the normal encoder 80 | Serial.print("Encoder: "); 81 | Serial.println(STDEncoder.readCounterInt()); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /examples/I2CEncoderV2/LCD_with_RGB_encoder/LCD_with_RGB_encoder.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | /*In this example, i want my variable counter between -10 and 10. 6 | When it reaches the limit the LED will blink red in case of minimum and will blink green when it reaches the maximum. 7 | The INT pin is readed in polling mode 8 | 9 | Connections with Arduino UNO: 10 | - -> GND 11 | + -> 5V 12 | SDA -> A4 13 | SCL -> A5 14 | INT -> 12 15 | */ 16 | unsigned long previousMillis = 0; 17 | const long interval = 100; 18 | LiquidCrystal lcd(8, 9, 4, 5, 6, 7); 19 | 20 | int lcd_key = 0; 21 | int adc_key_in = 0; 22 | #define btnRIGHT 0 23 | #define btnUP 1 24 | #define btnDOWN 2 25 | #define btnLEFT 3 26 | #define btnSELECT 4 27 | #define btnNONE 5 28 | #define ENCODER_N 2 29 | 30 | const int IntPin = A3; 31 | //Class initialization with the I2C addresses 32 | i2cEncoderLibV2 RGBEncoder(0b1100001); /* For make the address 0x61 only the jumpers A0, A5 and A6 are soldered.*/ 33 | 34 | // read the buttons 35 | int read_LCD_buttons() { 36 | adc_key_in = analogRead(0); // read the value from the sensor 37 | // my buttons when read are centered at these valies: 0, 144, 329, 504, 741 38 | // we add approx 50 to those values and check to see if we are close 39 | if (adc_key_in > 1000) 40 | return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result 41 | // For V1.1 us this threshold 42 | if (adc_key_in < 50) 43 | return btnRIGHT; 44 | if (adc_key_in < 250) 45 | return btnUP; 46 | if (adc_key_in < 450) 47 | return btnDOWN; 48 | if (adc_key_in < 650) 49 | return btnLEFT; 50 | if (adc_key_in < 850) 51 | return btnSELECT; 52 | return btnNONE; // when all others fail, return this... 53 | } 54 | 55 | uint8_t encoder_status, i; 56 | void setup(void) { 57 | Wire.begin(); 58 | Wire.setClock(400000); 59 | RGBEncoder.reset(); 60 | 61 | delay(1000); 62 | pinMode(IntPin, INPUT); 63 | pinMode(LED_BUILTIN, OUTPUT); 64 | lcd.begin(16, 2); // start the library 65 | lcd.setCursor(0, 0); 66 | 67 | Serial.begin(115200); 68 | Serial.print("Encoder Test!!\n"); 69 | 70 | RGBEncoder.begin( 71 | i2cEncoderLibV2::FLOAT_DATA | i2cEncoderLibV2::WRAP_DISABLE | i2cEncoderLibV2::DIRE_LEFT | i2cEncoderLibV2::IPUP_ENABLE | i2cEncoderLibV2::RMOD_X1 72 | | i2cEncoderLibV2::RGB_ENCODER); 73 | 74 | RGBEncoder.writeCounter((float) 0); 75 | RGBEncoder.writeMax((float) 10); 76 | RGBEncoder.writeMin((float) - 10); 77 | RGBEncoder.writeStep((float) 0.5); 78 | RGBEncoder.writeInterruptConfig(0xff); 79 | RGBEncoder.writeDoublePushPeriod(50); 80 | RGBEncoder.writeFadeRGB(1); 81 | RGBEncoder.updateStatus(); 82 | RGBEncoder.writeAntibouncingPeriod(25); 83 | RGBEncoder.writeGP1conf(i2cEncoderLibV2::GP_PWM | i2cEncoderLibV2::GP_PULL_EN | i2cEncoderLibV2::GP_INT_DI); 84 | RGBEncoder.writeGP2conf(i2cEncoderLibV2::GP_PWM | i2cEncoderLibV2::GP_PULL_EN | i2cEncoderLibV2::GP_INT_DI); 85 | RGBEncoder.writeFadeRGB(2); 86 | 87 | } 88 | 89 | void loop() { 90 | 91 | if (digitalRead(IntPin) == LOW) { 92 | Serial.println("Pin LOW "); 93 | 94 | /////////////////////////////////////////////////////////////////// 95 | if (RGBEncoder.updateStatus()) { 96 | 97 | if (RGBEncoder.readStatus(i2cEncoderLibV2::RINC)) { 98 | lcd.clear(); 99 | lcd.setCursor(0, 0); 100 | lcd.print("Inc: "); 101 | lcd.print(RGBEncoder.readCounterFloat(), 1); 102 | lcd.print(" "); 103 | if ((RGBEncoder.readStatus(i2cEncoderLibV2::RMIN) == 0) 104 | && (RGBEncoder.readStatus(i2cEncoderLibV2::RMAX) == 0)) 105 | RGBEncoder.writeLEDG(0xFF); 106 | } 107 | if (RGBEncoder.readStatus(i2cEncoderLibV2::RDEC)) { 108 | lcd.clear(); 109 | lcd.setCursor(0, 0); 110 | lcd.print("Dec: "); 111 | lcd.print(RGBEncoder.readCounterFloat(), 1); 112 | lcd.print(" "); 113 | if ((RGBEncoder.readStatus(i2cEncoderLibV2::RMIN) == 0) 114 | && (RGBEncoder.readStatus(i2cEncoderLibV2::RMAX) == 0)) 115 | RGBEncoder.writeLEDG(0xFF); 116 | } 117 | 118 | if (RGBEncoder.readStatus(i2cEncoderLibV2::RMAX)) { 119 | 120 | lcd.setCursor(0, 1); 121 | lcd.print("Counter MAX "); 122 | RGBEncoder.writeLEDR(0xFF); 123 | } 124 | 125 | if (RGBEncoder.readStatus(i2cEncoderLibV2::RMIN)) { 126 | 127 | lcd.setCursor(0, 1); 128 | lcd.print("Counter MIN "); 129 | RGBEncoder.writeLEDR(0xFF); 130 | } 131 | 132 | if (RGBEncoder.readStatus(i2cEncoderLibV2::PUSHR)) { 133 | 134 | lcd.setCursor(0, 1); 135 | lcd.print("B. Released "); 136 | RGBEncoder.writeRGBCode(0x0000FF); 137 | } 138 | 139 | if (RGBEncoder.readStatus(i2cEncoderLibV2::PUSHP)) { 140 | 141 | lcd.setCursor(0, 1); 142 | lcd.print("B. Pushed "); 143 | RGBEncoder.writeRGBCode(0x0000FF); 144 | } 145 | 146 | if (RGBEncoder.readStatus(i2cEncoderLibV2::PUSHD)) { 147 | 148 | lcd.setCursor(0, 1); 149 | lcd.print("Double Push "); 150 | RGBEncoder.writeRGBCode(0x800080); 151 | } 152 | 153 | if (RGBEncoder.readInt2(i2cEncoderLibV2::FADE_INT)) { //Check if the fade proccess finished, if yes turn off the LEDs 154 | RGBEncoder.writeRGBCode(0x0); 155 | } 156 | 157 | } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /examples/I2CEncoderV2/Matrix_3x3_RGB_encoders/Matrix_3x3_RGB_encoders.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /*In this example there are 9 I2C Encoder V2 boards with the RGB LED connected in a matrix 3x3 5 | There is also the Arduino Serial KeyPad Shield attached. 6 | 7 | Every time of one encoder is moved it's value is showed on the display 8 | In this example the data type are float 9 | 10 | Connections with Arduino UNO: 11 | - -> GND 12 | + -> 5V 13 | SDA -> A4 14 | SCL -> A5 15 | INT -> A3 16 | */ 17 | 18 | #define ENCODER_N 9 //Number limit of the encoder 19 | 20 | const int IntPin = A3; // INT pins, change according to your board 21 | 22 | //Class initialization with the I2C addresses 23 | i2cEncoderLibV2 RGBEncoder[ENCODER_N] = { i2cEncoderLibV2(0x40), 24 | i2cEncoderLibV2(0x20), i2cEncoderLibV2(0x60), i2cEncoderLibV2(0x10), 25 | i2cEncoderLibV2(0x50), i2cEncoderLibV2(0x30), i2cEncoderLibV2(0x70), 26 | i2cEncoderLibV2(0x04), i2cEncoderLibV2(0x44), 27 | }; 28 | 29 | uint8_t encoder_status, i; 30 | 31 | void encoder_rotated(i2cEncoderLibV2* obj) { 32 | if (obj->readStatus(i2cEncoderLibV2::RINC)) 33 | Serial.print("Increment "); 34 | else 35 | Serial.print("Decrement "); 36 | Serial.print(obj->id); 37 | Serial.print(": "); 38 | Serial.println(obj->readCounterInt()); 39 | obj->writeRGBCode(0x00FF00); 40 | } 41 | 42 | void encoder_click(i2cEncoderLibV2* obj) { 43 | Serial.print("Push: "); 44 | Serial.println(obj->id); 45 | obj->writeRGBCode(0x0000FF); 46 | } 47 | 48 | void encoder_thresholds(i2cEncoderLibV2* obj) { 49 | if (obj->readStatus(i2cEncoderLibV2::RMAX)) 50 | Serial.print("Max: "); 51 | else 52 | Serial.print("Min: "); 53 | Serial.println(obj->id); 54 | obj->writeRGBCode(0xFF0000); 55 | } 56 | 57 | void encoder_fade(i2cEncoderLibV2* obj) { 58 | obj->writeRGBCode(0x000000); 59 | } 60 | 61 | void setup(void) { 62 | uint8_t enc_cnt; 63 | 64 | Wire.begin(); 65 | //Reset of all the encoder ìs 66 | for (enc_cnt = 0; enc_cnt < ENCODER_N; enc_cnt++) { 67 | RGBEncoder[enc_cnt].reset(); 68 | } 69 | 70 | pinMode(IntPin, INPUT); 71 | 72 | Serial.begin(115200); 73 | Serial.print("Encoder Test!!\n"); 74 | 75 | // Initialization of the encoders 76 | for (enc_cnt = 0; enc_cnt < ENCODER_N; enc_cnt++) { 77 | RGBEncoder[enc_cnt].begin( 78 | i2cEncoderLibV2::INT_DATA | i2cEncoderLibV2::WRAP_DISABLE 79 | | i2cEncoderLibV2::DIRE_RIGHT 80 | | i2cEncoderLibV2::IPUP_ENABLE 81 | | i2cEncoderLibV2::RMOD_X1 82 | | i2cEncoderLibV2::RGB_ENCODER); 83 | RGBEncoder[enc_cnt].writeCounter((int32_t) 0); //Reset of the CVAL register 84 | RGBEncoder[enc_cnt].writeMax((int32_t) 50); //Set the maximum threshold to 50 85 | RGBEncoder[enc_cnt].writeMin((int32_t) 0); //Set the minimum threshold to 0 86 | RGBEncoder[enc_cnt].writeStep((int32_t) 1); //The step at every encoder click is 1 87 | RGBEncoder[enc_cnt].writeRGBCode(0); 88 | RGBEncoder[enc_cnt].writeFadeRGB(3); //Fade enabled with 3ms step 89 | RGBEncoder[enc_cnt].writeAntibouncingPeriod(25); //250ms of debouncing 90 | RGBEncoder[enc_cnt].writeDoublePushPeriod(0); //Set the double push period to 500ms 91 | 92 | /* Configure the events */ 93 | RGBEncoder[enc_cnt].onChange = encoder_rotated; 94 | RGBEncoder[enc_cnt].onButtonRelease = encoder_click; 95 | RGBEncoder[enc_cnt].onMinMax = encoder_thresholds; 96 | RGBEncoder[enc_cnt].onFadeProcess = encoder_fade; 97 | 98 | /* Enable the I2C Encoder V2 interrupts according to the previus attached callback */ 99 | RGBEncoder[enc_cnt].autoconfigInterrupt(); 100 | RGBEncoder[enc_cnt].id = enc_cnt; 101 | } 102 | } 103 | 104 | void loop() { 105 | uint8_t enc_cnt; 106 | 107 | if (digitalRead(IntPin) == LOW) { 108 | //Interrupt from the encoders, start to scan the encoder matrix 109 | for (enc_cnt = 0; enc_cnt < ENCODER_N; enc_cnt++) { 110 | if (digitalRead(IntPin) == HIGH) { //If the interrupt pin return high, exit from the encoder scan 111 | break; 112 | } 113 | RGBEncoder[enc_cnt].updateStatus(); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /examples/I2CEncoderV2/Teensy_RGB_encoder/Teensy_RGB_encoder.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /*This is a basic example for using the I2C Encoder V2 5 | The counter is set to work between +10 to -10, at every encoder click the counter value is printed on the terminal. 6 | It's also printet when the push button is released. 7 | When the encoder is turned the led turn green 8 | When the encoder reach the max or min the led turn red 9 | When the encoder is pushed, the led turn blue 10 | 11 | Connections with Teensy 3.6: 12 | - -> GND 13 | + -> 3.3V 14 | SDA -> 18 15 | SCL -> 19 16 | INT -> 17 17 | */ 18 | 19 | const int IntPin = 17; /* Definition of the interrupt pin, change according to your configuration*/ 20 | //Class initialization with the I2C addresses 21 | i2cEncoderLibV2 Encoder(0b1100001); /* For make the address 0x61 only the jumpers A0, A5 and A6 are soldered.*/ 22 | 23 | //Callback when the encoder is rotated 24 | void encoder_rotated(i2cEncoderLibV2* obj) { 25 | if (obj->readStatus(i2cEncoderLibV2::RINC)) 26 | Serial.print("Increment: "); 27 | else 28 | Serial.print("Decrement: "); 29 | Serial.println(obj->readCounterInt()); 30 | obj->writeRGBCode(0x00FF00); 31 | } 32 | 33 | //Callback when the encoder is pushed 34 | void encoder_click(i2cEncoderLibV2* obj) { 35 | Serial.println("Push: "); 36 | obj->writeRGBCode(0x0000FF); 37 | } 38 | 39 | //Callback when the encoder reach the max or min 40 | void encoder_thresholds(i2cEncoderLibV2* obj) { 41 | if (obj->readStatus(i2cEncoderLibV2::RMAX)) 42 | Serial.println("Max!"); 43 | else 44 | Serial.println("Min!"); 45 | 46 | obj->writeRGBCode(0xFF0000); 47 | } 48 | 49 | //Callback when the fading process finish and set the RGB led off 50 | void encoder_fade(i2cEncoderLibV2* obj) { 51 | obj->writeRGBCode(0x000000); 52 | } 53 | 54 | void setup(void) { 55 | pinMode(IntPin, INPUT); 56 | 57 | Serial.begin(115200); 58 | Serial.println("**** I2C Encoder V2 basic example ****"); 59 | /* 60 | INT_DATA= The register are considered integer. 61 | WRAP_DISABLE= The WRAP option is disabled 62 | DIRE_LEFT= Encoder left direction increase the value 63 | IPUP_ENABLE= INT pin have the pull-up enabled. 64 | RMOD_X1= Encoder configured as X1. 65 | RGB_ENCODER= type of encoder is RGB, change to STD_ENCODER in case you are using a normal rotary encoder. 66 | */ 67 | Wire.begin(); 68 | Encoder.reset(); 69 | 70 | Encoder.begin( 71 | i2cEncoderLibV2::INT_DATA | i2cEncoderLibV2::WRAP_DISABLE 72 | | i2cEncoderLibV2::DIRE_LEFT | i2cEncoderLibV2::IPUP_ENABLE 73 | | i2cEncoderLibV2::RMOD_X1 | i2cEncoderLibV2::RGB_ENCODER); 74 | // Encoder.begin(i2cEncoderLibV2::INT_DATA | i2cEncoderLibV2::WRAP_DISABLE | i2cEncoderLibV2::DIRE_LEFT | i2cEncoderLibV2::IPUP_ENABLE | i2cEncoderLibV2::RMOD_X1 | i2cEncoderLibV2::STD_ENCODER); // try also this! 75 | // Encoder.begin(i2cEncoderLibV2::INT_DATA |i2cEncoderLibV2::WRAP_ENABLE | i2cEncoderLibV2::DIRE_LEFT | i2cEncoderLibV2::IPUP_ENABLE | i2cEncoderLibV2::RMOD_X1 | i2cEncoderLibV2::RGB_ENCODER); // try also this! 76 | 77 | Encoder.writeCounter((int32_t) 0); /* Reset the counter value */ 78 | Encoder.writeMax((int32_t) 10); /* Set the maximum threshold*/ 79 | Encoder.writeMin((int32_t) - 10); /* Set the minimum threshold */ 80 | Encoder.writeStep((int32_t) 1); /* Set the step to 1*/ 81 | 82 | /* Configure the events */ 83 | Encoder.onChange = encoder_rotated; 84 | Encoder.onButtonRelease = encoder_click; 85 | Encoder.onMinMax = encoder_thresholds; 86 | Encoder.onFadeProcess = encoder_fade; 87 | 88 | /* Enable the I2C Encoder V2 interrupts according to the previus attached callback */ 89 | Encoder.autoconfigInterrupt(); 90 | 91 | Encoder.writeAntibouncingPeriod(20); /* Set an anti-bouncing of 200ms */ 92 | 93 | /* blink the RGB LED */ 94 | Encoder.writeRGBCode(0xFF0000); 95 | delay(250); 96 | Encoder.writeRGBCode(0x00FF00); 97 | delay(250); 98 | Encoder.writeRGBCode(0x0000FF); 99 | delay(250); 100 | Encoder.writeRGBCode(0x000000); 101 | 102 | Encoder.writeFadeRGB(3); //Fade enabled with 3ms step 103 | 104 | } 105 | 106 | void loop() { 107 | 108 | /* Waith when the INT pin goes low */ 109 | if (digitalRead(IntPin) == LOW) { 110 | /* Check the status of the encoder and call the callback */ 111 | Encoder.updateStatus(); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /examples/I2CEncoderV2/WEMOS_OLED/WEMOS_OLED.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | /*This is a basic example for using the I2C Encoder V2 connected to a ESP8266 WEMOS D1 with the OLED shield 8 | The counter is set to work between +10 to -10, at every encoder click the counter value is printed on the OLED display. 9 | It's also printet when the push button is pressed. 10 | When the encoder is turned left the RED led turn ON 11 | When the encoder is turned right the BLUE led turn ON 12 | When the encoder is pushed, the GREEN led turn ON 13 | 14 | Connections with WEMOS: 15 | - -> GND 16 | + -> 3.3V 17 | SDA -> D2 18 | SCL -> D1 19 | INT -> D3 20 | */ 21 | 22 | const int IntPin = 0; /* Definition of the interrupt pin*/ 23 | //Class initialization with the I2C addresses 24 | i2cEncoderLibV2 Encoder(0x61); /* For make the address 0x61 only the jumpers A0, A5 and A6 are soldered.*/ 25 | 26 | #define OLED_RESET -1 27 | Adafruit_SSD1306 display(OLED_RESET); 28 | 29 | void setup(void) { 30 | pinMode(IntPin, INPUT); 31 | /* 32 | INT_DATA= The register are considered integer. 33 | WRAP_DISABLE= The WRAP option is disabled 34 | DIRE_LEFT= Encoder left direction increase the value 35 | IPUP_ENABLE= INT pin have the pull-up enabled. 36 | RMOD_X1= Encoder configured as X1. 37 | RGB_ENCODER= type of encoder is RGB, change to STD_ENCODER in case you are using a normal rotary encoder. 38 | */ 39 | Wire.begin(); 40 | Encoder.reset(); /* Reset the I2C encoder V2 and wait 100ms */ 41 | 42 | Encoder.begin( 43 | i2cEncoderLibV2::INT_DATA | i2cEncoderLibV2::WRAP_DISABLE 44 | | i2cEncoderLibV2::DIRE_LEFT | i2cEncoderLibV2::IPUP_ENABLE 45 | | i2cEncoderLibV2::RMOD_X1 | i2cEncoderLibV2::RGB_ENCODER); 46 | // Encoder.begin(i2cEncoderLibV2::INT_DATA | i2cEncoderLibV2::WRAP_DISABLE | i2cEncoderLibV2::DIRE_LEFT | i2cEncoderLibV2::PUP_ENABLE | i2cEncoderLibV2::RMOD_X1 | i2cEncoderLibV2::STD_ENCODER); // try also this! 47 | // Encoder.begin(i2cEncoderLibV2::INT_DATA | i2cEncoderLibV2::WRAP_ENABLE | i2cEncoderLibV2::DIRE_LEFT | i2cEncoderLibV2::IPUP_ENABLE | i2cEncoderLibV2::RMOD_X1 | i2cEncoderLibV2::RGB_ENCODER); // try also this! 48 | 49 | Encoder.writeCounter((int32_t) 0); /* Reset the counter value */ 50 | Encoder.writeMax((int32_t) 10); /* Set the maximum threshold*/ 51 | Encoder.writeMin((int32_t) - 10); /* Set the minimum threshold */ 52 | Encoder.writeStep((int32_t) 1); /* Set the step to 1*/ 53 | Encoder.writeInterruptConfig( 54 | i2cEncoderLibV2::INT_2 | i2cEncoderLibV2::RMIN 55 | | i2cEncoderLibV2::RMAX | i2cEncoderLibV2::RDEC 56 | | i2cEncoderLibV2::RINC | i2cEncoderLibV2::PUSHR); /* Enable all the interrupt */ 57 | Encoder.writeAntibouncingPeriod(20); /* Set an anti-bouncing of 300ms */ 58 | Encoder.writeDoublePushPeriod(0); /*Set a period for the double push of 500ms */ 59 | 60 | display.begin(SSD1306_SWITCHCAPVCC, 0x3C); 61 | 62 | display.clearDisplay(); 63 | display.setTextSize(3); 64 | display.setTextColor(WHITE); 65 | display.clearDisplay(); 66 | display.setCursor(0, 0); 67 | display.println(0); 68 | display.display(); 69 | } 70 | 71 | void loop() { 72 | uint8_t enc_cnt; 73 | if (digitalRead(IntPin) == LOW) { 74 | if (Encoder.updateStatus()) { 75 | 76 | display.clearDisplay(); 77 | 78 | if (Encoder.readStatus(i2cEncoderLibV2::RINC)) { 79 | display.setCursor(0, 0); 80 | display.setTextSize(3); 81 | display.print(Encoder.readCounterByte()); 82 | display.setCursor(0, 25); 83 | display.setTextSize(1); 84 | display.print("Increment"); 85 | Encoder.writeLEDB(0); 86 | Encoder.writeLEDG(0); 87 | Encoder.writeLEDR(255); 88 | 89 | /* Write here your code */ 90 | 91 | } 92 | if (Encoder.readStatus(i2cEncoderLibV2::RDEC)) { 93 | display.setCursor(0, 0); 94 | display.setTextSize(3); 95 | display.print(Encoder.readCounterByte()); 96 | display.setCursor(0, 25); 97 | display.setTextSize(1); 98 | display.print("Decrement"); 99 | Encoder.writeLEDR(0); 100 | Encoder.writeLEDG(0); 101 | Encoder.writeLEDB(255); 102 | 103 | /* Write here your code */ 104 | 105 | } 106 | 107 | if (Encoder.readStatus(i2cEncoderLibV2::RMAX)) { 108 | display.setCursor(0, 0); 109 | display.setTextSize(3); 110 | display.println(Encoder.readCounterByte()); 111 | display.setCursor(0, 35); 112 | display.setTextSize(1); 113 | display.print("Maximum"); 114 | /* Write here your code */ 115 | 116 | } 117 | 118 | if (Encoder.readStatus(i2cEncoderLibV2::RMIN)) { 119 | display.setCursor(0, 0); 120 | display.setTextSize(3); 121 | display.print(Encoder.readCounterByte()); 122 | display.setCursor(0, 35); 123 | display.setTextSize(1); 124 | display.print("Minimum"); 125 | 126 | /* Write here your code */ 127 | 128 | } 129 | 130 | if (Encoder.readStatus(i2cEncoderLibV2::PUSHR)) { 131 | 132 | display.setCursor(0, 0); 133 | display.setTextSize(3); 134 | display.print(Encoder.readCounterByte()); 135 | display.setCursor(0, 25); 136 | display.setTextSize(1); 137 | display.print("Button pressed!"); 138 | 139 | /* Write here your code */ 140 | } 141 | display.display(); 142 | } 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /examples/I2CEncoderV2/WEMOS_OLED_Menu/WEMOS_OLED_Menu.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | /*This is an example of using the I2C Encoder V2 for scrolling a simple menu'. 8 | For this example is required the WEMOS and the OLED shield. 9 | There are 4 items: A, B, C, D. Each items has it's own variable. 10 | With the Encoder is possible to select the items and change it's own variable. 11 | When the encoder LED is GREEN it's possible to select the item. 12 | By clicking the encoder the LED became BLUE and it's possible to change the value of the item. 13 | With a long press (>300ms) the LED return GREEN and it's possbile to select another items. 14 | 15 | 16 | Connections with WEMOS board: 17 | - -> GND 18 | + -> 3.3V 19 | SDA -> D2 20 | SCL -> D1 21 | INT -> D3 22 | */ 23 | 24 | const int IntPin = 0; /* Definition of the interrupt pin*/ 25 | //Class initialization with the I2C addresses 26 | i2cEncoderLibV2 Encoder(0x61); /* For make the address 0x61 only the jumpers A0, A5 and A6 are soldered.*/ 27 | 28 | #define OLED_RESET -1 29 | Adafruit_SSD1306 display(OLED_RESET); 30 | 31 | uint8_t m_pos = 0; 32 | int8_t val[4] = { 0 }; /* array where it's possbile to store the 4 value of the items */ 33 | int8_t max_val[4] = { 10, 5, 20, 11 }; /* array where is store the max value of each items. Customize according to your necessity */ 34 | int8_t min_val[4] = { -3, 0, 3, -11 }; /* array where is store the min value of each items. Customize according to your necessity */ 35 | 36 | bool insert = false; /* if it's false is the item value selection, when it's true is the item selection */ 37 | 38 | void setup(void) { 39 | Wire.begin(); 40 | Encoder.reset(); /* Reset the I2C encoder V2 and wait 100ms */ 41 | 42 | pinMode(IntPin, INPUT); 43 | /* 44 | INT_DATA= The register are considered integer. 45 | WRAP_ENABLE= The WRAP option is enabled 46 | DIRE_RIGHT= Encoder right direction increase the value 47 | IPUP_ENABLE= INT pin have the pull-up enabled. 48 | RMOD_X1= Encoder configured as X1. 49 | RGB_ENCODER= type of encoder is RGB, change to STD_ENCODER in case you are using a normal rotary encoder. 50 | */ 51 | 52 | Encoder.begin( 53 | i2cEncoderLibV2::INT_DATA | i2cEncoderLibV2::WRAP_ENABLE 54 | | i2cEncoderLibV2::DIRE_RIGHT | i2cEncoderLibV2::IPUP_ENABLE 55 | | i2cEncoderLibV2::RMOD_X1 | i2cEncoderLibV2::RGB_ENCODER); 56 | Encoder.writeCounter((int32_t) 0); /* Reset the counter value */ 57 | Encoder.writeMax((int32_t) 3); /* Set the maximum threshold*/ 58 | Encoder.writeMin((int32_t) 0); /* Set the minimum threshold */ 59 | Encoder.writeStep((int32_t) 1); /* Set the step to 1*/ 60 | Encoder.writeInterruptConfig(0xff); /* Enable all the interrupt */ 61 | Encoder.writeAntibouncingPeriod(30); /* Set an anti-bouncing of 300ms */ 62 | Encoder.writeDoublePushPeriod(30); /*Set a period for the double push of 300ms */ 63 | Encoder.writeFadeRGB(1); /*Set fade to 1ms step */ 64 | Encoder.writeRGBCode(0x00ff00); /* Turn ON the green LED */ 65 | 66 | display.begin(SSD1306_SWITCHCAPVCC, 0x3C); 67 | 68 | /* initialize the item values to the minimum value */ 69 | val[0] = min_val[0]; 70 | val[1] = min_val[1]; 71 | val[2] = min_val[2]; 72 | val[3] = min_val[3]; 73 | 74 | menu(); 75 | 76 | } 77 | 78 | void loop() { 79 | 80 | if (digitalRead(IntPin) == LOW) { 81 | if (Encoder.updateStatus()) { 82 | 83 | if (Encoder.readStatus(i2cEncoderLibV2::RINC) 84 | || Encoder.readStatus(i2cEncoderLibV2::RDEC)) { 85 | if (insert == false) { 86 | m_pos = Encoder.readCounterByte(); /* change the item */ 87 | } 88 | if (insert == true) { 89 | val[m_pos] = Encoder.readCounterByte(); /* change the item value */ 90 | } 91 | } 92 | 93 | /* fast push, switch to the item value change mode */ 94 | if (Encoder.readStatus(i2cEncoderLibV2::PUSHP) 95 | && Encoder.readStatus(i2cEncoderLibV2::PUSHR)) { 96 | insert = true; 97 | Encoder.writeCounter((int32_t) val[m_pos]); /* Reset the counter value */ 98 | Encoder.writeMax((int32_t) max_val[m_pos]); /* Set the maximum threshold*/ 99 | Encoder.writeMin((int32_t) min_val[m_pos]); /* Set the minimum threshold */ 100 | Encoder.writeStep((int32_t) 1); /* Set the step to 1*/ 101 | Encoder.writeRGBCode(0x0000FF); 102 | } 103 | 104 | /* long push, switch to the selection mode */ 105 | if (Encoder.readStatus(i2cEncoderLibV2::PUSHR) 106 | && (Encoder.readStatus(i2cEncoderLibV2::PUSHP) == false)) { 107 | insert = false; 108 | Encoder.writeCounter((int32_t) 0); /* Reset the counter value */ 109 | Encoder.writeMax((int32_t) 3); /* Set the maximum threshold*/ 110 | Encoder.writeMin((int32_t) 0); /* Set the minimum threshold */ 111 | Encoder.writeStep((int32_t) 1); /* Set the step to 1*/ 112 | Encoder.writeRGBCode(0x00ff00); 113 | } 114 | 115 | menu(); 116 | 117 | } 118 | } 119 | } 120 | 121 | /* fuction that print the menu' */ 122 | void menu(void) { 123 | display.clearDisplay(); 124 | display.setTextSize(1); 125 | display.setTextColor(WHITE); 126 | display.setCursor(0, 0); 127 | display.print("Menu':"); 128 | display.setCursor(10, 10); 129 | display.print("A: "); 130 | display.print(val[0]); 131 | display.setCursor(10, 20); 132 | display.print("B: "); 133 | display.print(val[1]); 134 | display.setCursor(10, 30); 135 | display.print("C: "); 136 | display.print(val[2]); 137 | display.setCursor(10, 40); 138 | display.print("D: "); 139 | display.print(val[3]); 140 | 141 | display.setCursor(0, 10 + (m_pos * 10)); 142 | display.print(">"); 143 | 144 | display.display(); 145 | 146 | } 147 | -------------------------------------------------------------------------------- /examples/I2CEncoderV2/WEMOS_OLED_Menu_Callback_EEPROM/WEMOS_OLED_Menu_Callback_EEPROM.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | /*This is an example of using the I2C Encoder V2 for scrolling a simple menu'. 8 | For this example is required the WEMOS and the OLED shield. 9 | There are 4 items: A, B, C, D. Each items has it's own variable. 10 | With the Encoder is possible to select the items and change it's own variable. 11 | When the encoder LED is GREEN it's possible to select the item. 12 | By clicking the encoder the LED became BLUE and it's possible to change the value of the item. 13 | With a double push the item values is store in the EEPROM of the encoder. 14 | The LED return GREEN and again it's possbile to select another item. 15 | 16 | 17 | Connections with WEMOS board: 18 | - -> GND 19 | + -> 3.3V 20 | SDA -> D2 21 | SCL -> D1 22 | INT -> D3 23 | */ 24 | 25 | const int IntPin = 0; /* Definition of the interrupt pin*/ 26 | //Class initialization with the I2C addresses 27 | i2cEncoderLibV2 Encoder(0x61); /* For make the address 0x61 only the jumpers A0, A5 and A6 are soldered.*/ 28 | 29 | #define EEPROM_START_ADD 0x0F 30 | 31 | #define OLED_RESET -1 32 | Adafruit_SSD1306 display(OLED_RESET); 33 | 34 | uint8_t m_pos = 0; 35 | int8_t val[4] = { 0 }; /* array where it's possbile to store the 4 value of the items */ 36 | int8_t max_val[4] = { 10, 5, 20, 11 }; /* array where is store the max value of each items. Customize according to your necessity */ 37 | int8_t min_val[4] = { -3, 0, 3, -11 }; /* array where is store the min value of each items. Customize according to your necessity */ 38 | 39 | bool insert = false; /* if it's false is the item value selection, when it's true is the item selection */ 40 | 41 | void encoder_rotated(i2cEncoderLibV2* obj) { 42 | if (insert == false) { 43 | m_pos = obj->readCounterByte(); /* change the item */ 44 | Serial.println(m_pos); 45 | } 46 | if (insert == true) { 47 | val[m_pos] = obj->readCounterByte(); /* change the item value */ 48 | } 49 | } 50 | 51 | void encoder_click(i2cEncoderLibV2* obj) { 52 | insert = true; 53 | 54 | obj->writeCounter((int32_t) val[m_pos]); /* Reset the counter value */ 55 | obj->writeMax((int32_t) max_val[m_pos]); /* Set the maximum threshold*/ 56 | obj->writeMin((int32_t) min_val[m_pos]); /* Set the minimum threshold */ 57 | obj->writeStep((int32_t) 1); /* Set the step to 1*/ 58 | obj->writeRGBCode(0x0000FF); 59 | obj->onButtonDoublePush = encoder_Double_push; // Enable the double push interrupt 60 | } 61 | 62 | void encoder_Double_push(i2cEncoderLibV2* obj) { 63 | insert = false; 64 | obj->writeCounter((int32_t) 0); /* Reset the counter value */ 65 | obj->writeMax((int32_t) 3); /* Set the maximum threshold*/ 66 | obj->writeMin((int32_t) 0); /* Set the minimum threshold */ 67 | obj->writeStep((int32_t) 1); /* Set the step to 1*/ 68 | obj->writeRGBCode(0x00ff00); 69 | 70 | obj->writeEEPROM(EEPROM_START_ADD + m_pos, (uint8_t) val[m_pos]); 71 | obj->onButtonDoublePush = NULL; // Disable the double push interrupt 72 | 73 | } 74 | 75 | // Interurpt function when the INT pin goes low 76 | void encoder_interrupt(void) { 77 | if (Encoder.updateStatus()) { 78 | menu(); 79 | } 80 | } 81 | 82 | void setup(void) { 83 | Serial.begin(115200); 84 | Wire.begin(); 85 | Encoder.reset(); /* Reset the I2C encoder V2 and wait 100ms */ 86 | 87 | pinMode(IntPin, INPUT); 88 | attachInterrupt(digitalPinToInterrupt(IntPin), encoder_interrupt, FALLING); // Enable the interrupt on the INT pin 89 | 90 | /* 91 | INT_DATA= The register are considered integer. 92 | WRAP_ENABLE= The WRAP option is enabled 93 | DIRE_RIGHT= Encoder right direction increase the value 94 | IPUP_ENABLE= INT pin have the pull-up enabled. 95 | RMOD_X1= Encoder configured as X1. 96 | RGB_ENCODER= type of encoder is RGB, change to STD_ENCODER in case you are using a normal rotary encoder. 97 | */ 98 | 99 | Encoder.begin( 100 | i2cEncoderLibV2::INT_DATA | i2cEncoderLibV2::WRAP_ENABLE 101 | | i2cEncoderLibV2::DIRE_RIGHT | i2cEncoderLibV2::IPUP_ENABLE 102 | | i2cEncoderLibV2::RMOD_X1 | i2cEncoderLibV2::RGB_ENCODER); 103 | Encoder.writeCounter((int32_t) 0); /* Reset the counter value */ 104 | Encoder.writeMax((int32_t) 3); /* Set the maximum threshold*/ 105 | Encoder.writeMin((int32_t) 0); /* Set the minimum threshold */ 106 | Encoder.writeStep((int32_t) 1); /* Set the step to 1*/ 107 | Encoder.writeAntibouncingPeriod(30); /* Set an anti-bouncing of 300ms */ 108 | Encoder.writeDoublePushPeriod(50); /*Set a period for the double push of 300ms */ 109 | Encoder.writeFadeRGB(1); /*Set fade to 1ms step */ 110 | Encoder.writeRGBCode(0x00ff00); /* Turn ON the green LED */ 111 | 112 | // Definition of the events 113 | Encoder.onChange = encoder_rotated; 114 | Encoder.onButtonPush = encoder_click; 115 | Encoder.onButtonDoublePush = encoder_Double_push; 116 | /* Enable the I2C Encoder V2 interrupts according to the previus attached callback */ 117 | Encoder.autoconfigInterrupt(); 118 | 119 | display.begin(SSD1306_SWITCHCAPVCC, 0x3C); 120 | 121 | /* initialize the item values to the minimum value */ 122 | /* Initialie also the EEPROM contenet */ 123 | for (uint8_t i = 0; i < 4; i++) { 124 | 125 | val[i] = Encoder.readEEPROM(EEPROM_START_ADD + i); 126 | 127 | if ((val[i] > max_val[i]) || (val[i] < min_val[i])) { 128 | val[i] = min_val[i]; 129 | Encoder.writeEEPROM(EEPROM_START_ADD + i, (uint8_t) val[i]); 130 | } 131 | } 132 | 133 | menu(); 134 | } 135 | 136 | void loop() { 137 | //Nothin in the loop, 138 | } 139 | 140 | /* fuction that print the menu' */ 141 | void menu(void) { 142 | display.clearDisplay(); 143 | display.setTextSize(1); 144 | display.setTextColor(WHITE); 145 | display.setCursor(0, 0); 146 | display.print("Menu':"); 147 | display.setCursor(10, 10); 148 | display.print("A: "); 149 | display.print(val[0]); 150 | display.setCursor(10, 20); 151 | display.print("B: "); 152 | display.print(val[1]); 153 | display.setCursor(10, 30); 154 | display.print("C: "); 155 | display.print(val[2]); 156 | display.setCursor(10, 40); 157 | display.print("D: "); 158 | display.print(val[3]); 159 | 160 | display.setCursor(0, 10 + (m_pos * 10)); 161 | display.print(">"); 162 | 163 | display.display(); 164 | 165 | } 166 | -------------------------------------------------------------------------------- /examples/I2CNavKey/Basic_with_Callbacks/Basic_with_Callbacks.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /*This is a basic example for using the I2C navkey V2 5 | Every time a button is pressed it's printed on the terminal. 6 | The double push is active, with a 300ms window 7 | The encoder is set from -10 to +10 8 | 9 | 10 | Connections with Arduino UNO: 11 | - -> GND 12 | + -> 5V 13 | SDA -> A4 14 | SCL -> A5 15 | INT -> A3 16 | */ 17 | 18 | 19 | const int IntPin = A3; /* Definition of the interrupt pin*/ 20 | //Class initialization with the I2C addresses 21 | i2cNavKey navkey(0b0010000); /* Default address when no jumper are soldered */ 22 | 23 | 24 | uint8_t pwm, fade = 0; 25 | 26 | void UP_Button_Pressed(i2cNavKey* p) { 27 | Serial.println("Button UP Pressed!"); 28 | 29 | } 30 | 31 | void DOWN_Button_Pressed(i2cNavKey* p) { 32 | Serial.println("Button DOWN Pressed!"); 33 | 34 | } 35 | 36 | void LEFT_Button_Pressed(i2cNavKey* p) { 37 | Serial.println("Button LEFT Pressed!"); 38 | 39 | } 40 | 41 | void RIGHT_Button_Pressed(i2cNavKey* p) { 42 | Serial.println("Button RIGHT Pressed!"); 43 | 44 | } 45 | 46 | void CENTRAL_Button_Pressed(i2cNavKey* p) { 47 | Serial.println("Button Central Pressed!"); 48 | } 49 | 50 | void CENTRAL_Button_Double(i2cNavKey* p) { 51 | Serial.println("Button Central Double push!"); 52 | } 53 | 54 | void Encoder_Rotate(i2cNavKey* p) { 55 | Serial.println(p->readCounterInt()); 56 | 57 | } 58 | void setup(void) 59 | { 60 | pinMode(IntPin, INPUT); 61 | Wire.begin(); 62 | Serial.begin(115200); 63 | Serial.println("**** I2C navkey V2 basic example ****"); 64 | /* 65 | INT_DATA= The register are considered integer. 66 | WRAP_ENABLE= The WRAP option is enabled 67 | DIRE_RIGHT= navkey right direction increase the value 68 | IPUP_ENABLE= INT pin have the pull-up enabled. 69 | */ 70 | 71 | navkey.reset(); 72 | navkey.begin(i2cNavKey::INT_DATA | i2cNavKey::WRAP_ENABLE | i2cNavKey::DIRE_RIGHT | i2cNavKey::IPUP_ENABLE); 73 | 74 | navkey.writeCounter((int32_t)0); /* Reset the counter value */ 75 | navkey.writeMax((int32_t)10); /* Set the maximum threshold*/ 76 | navkey.writeMin((int32_t)-10); /* Set the minimum threshold */ 77 | navkey.writeStep((int32_t)1); /* Set the step to 1*/ 78 | 79 | navkey.writeDoublePushPeriod(30); /*Set a period for the double push of 300ms */ 80 | 81 | navkey.onUpPush = UP_Button_Pressed; 82 | navkey.onDownPush = DOWN_Button_Pressed; 83 | navkey.onRightPush = RIGHT_Button_Pressed; 84 | navkey.onLeftPush = LEFT_Button_Pressed; 85 | navkey.onCentralPush = CENTRAL_Button_Pressed; 86 | navkey.onCentralDoublePush = CENTRAL_Button_Double; 87 | navkey.onChange = Encoder_Rotate; 88 | 89 | navkey.autoconfigInterrupt(); /* Enable the interrupt with the attached callback */ 90 | 91 | Serial.print("ID CODE: 0x"); 92 | Serial.println(navkey.readIDCode(), HEX); 93 | Serial.print("Board Version: 0x"); 94 | Serial.println(navkey.readVersion(), HEX); 95 | 96 | } 97 | 98 | void loop() { 99 | uint8_t enc_cnt; 100 | if (digitalRead(IntPin) == LOW) { 101 | navkey.updateStatus(); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /examples/I2CNavKey/Basic_with_Callbacks_Float/Basic_with_Callbacks_Float.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /*This is a basic example for using the I2C navkey V2 5 | Every time a button is pressed it's printed on the terminal. 6 | The double push is active, with a 300ms window 7 | The encoder is set from 0.5 to 9.5 with step of 0.25 8 | 9 | 10 | Connections with Arduino UNO: 11 | - -> GND 12 | + -> 5V 13 | SDA -> A4 14 | SCL -> A5 15 | INT -> A3 16 | */ 17 | 18 | 19 | const int IntPin = A3; /* Definition of the interrupt pin*/ 20 | //Class initialization with the I2C addresses 21 | i2cNavKey navkey(0b0010000); /* Default address when no jumper are soldered */ 22 | 23 | 24 | uint8_t pwm, fade = 0; 25 | 26 | void UP_Button_Pressed(i2cNavKey* p) { 27 | Serial.println("Button UP Pressed!"); 28 | 29 | } 30 | 31 | void DOWN_Button_Pressed(i2cNavKey* p) { 32 | Serial.println("Button DOWN Pressed!"); 33 | 34 | } 35 | 36 | void LEFT_Button_Pressed(i2cNavKey* p) { 37 | Serial.println("Button LEFT Pressed!"); 38 | 39 | } 40 | 41 | void RIGHT_Button_Pressed(i2cNavKey* p) { 42 | Serial.println("Button RIGHT Pressed!"); 43 | 44 | } 45 | 46 | void CENTRAL_Button_Pressed(i2cNavKey* p) { 47 | Serial.println("Button Central Pressed!"); 48 | } 49 | 50 | void CENTRAL_Button_Double(i2cNavKey* p) { 51 | Serial.println("Button Central Double push!"); 52 | } 53 | 54 | void Encoder_Rotate(i2cNavKey* p) { 55 | Serial.println(p->readCounterFloat(),2); 56 | 57 | } 58 | void setup(void) 59 | { 60 | pinMode(IntPin, INPUT); 61 | Wire.begin(); 62 | Serial.begin(115200); 63 | Serial.println("**** I2C navkey V2 basic example ****"); 64 | /* 65 | INT_DATA= The register are considered integer. 66 | WRAP_ENABLE= The WRAP option is enabled 67 | DIRE_RIGHT= navkey right direction increase the value 68 | IPUP_ENABLE= INT pin have the pull-up enabled. 69 | */ 70 | 71 | navkey.reset(); 72 | navkey.begin(i2cNavKey::FLOAT_DATA | i2cNavKey::WRAP_ENABLE | i2cNavKey::DIRE_RIGHT | i2cNavKey::IPUP_ENABLE); 73 | 74 | navkey.writeCounter((float)0); /* Reset the counter value */ 75 | navkey.writeMax((float)9.5); /* Set the maximum threshold*/ 76 | navkey.writeMin((float)0.5); /* Set the minimum threshold */ 77 | navkey.writeStep((float)0.25); /* Set the step to 1*/ 78 | 79 | navkey.writeDoublePushPeriod(30); /*Set a period for the double push of 300ms */ 80 | 81 | navkey.onUpPush = UP_Button_Pressed; 82 | navkey.onDownPush = DOWN_Button_Pressed; 83 | navkey.onRightPush = RIGHT_Button_Pressed; 84 | navkey.onLeftPush = LEFT_Button_Pressed; 85 | navkey.onCentralPush = CENTRAL_Button_Pressed; 86 | navkey.onCentralDoublePush = CENTRAL_Button_Double; 87 | navkey.onChange = Encoder_Rotate; 88 | 89 | navkey.autoconfigInterrupt(); /* Enable the interrupt with the attached callback */ 90 | 91 | Serial.print("ID CODE: 0x"); 92 | Serial.println(navkey.readIDCode(), HEX); 93 | Serial.print("Board Version: 0x"); 94 | Serial.println(navkey.readVersion(), HEX); 95 | 96 | } 97 | 98 | void loop() { 99 | uint8_t enc_cnt; 100 | if (digitalRead(IntPin) == LOW) { 101 | navkey.updateStatus(); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /examples/I2CNavKey/README.md: -------------------------------------------------------------------------------- 1 | # I2C NavKey Arduino Library 2 | 3 | -------------------------------------------------------------------------------- 4 | 5 | ## Introduction 6 | 7 | Here you can find the library description of the [I2C NavKey](https://github.com/Fattoresaimon/I2CNavKey) for the Arduino IDE. 8 | For more details of the functionality of the board, please read the [Datasheet](https://github.com/Fattoresaimon/I2CNavKey/blob/master/I2CNavKey_v1.0.pdf) 9 | 10 | The I2C NavKey is available on [Tindie!](https://www.tindie.com/products/16624/) 11 | 12 | ## Initialization of the class 13 | 14 | The library makes available the class **i2cNavKey** 15 | To initialize the library, you have to declare an instance of the class **i2cNavKey** for each encoders. 16 | For example: 17 | 18 | ``` C++ 19 | i2cNavKey navkey(0x10); 20 | ``` 21 | Declaration of one encoder with the address 0x10. All the jumpers are open. 22 | 23 | ``` C++ 24 | i2cNavKey navkey(0b0010000); 25 | ``` 26 | Declaration of the same I2CNavKey but in binary format. 27 | 28 | ```C++ 29 | i2cNavKey navkey1(0x11); //A0 shorted 30 | i2cNavKey navkey2(0x12); //A1 shorted 31 | ``` 32 | Declaration of two I2CNavKey with the address 0x11 and 0x12 in two separated variable. 33 | 34 | ```C++ 35 | i2cNavKey encoder[2] = { i2cNavKey(0x11), i2cNavKey(0x12)}; 36 | ``` 37 | Declaration of an array of the two I2CNavKey with the address 0x11 and 0x12. 38 | 39 | ## Callback Configuration 40 | 41 | This library support the callback functionality. 42 | There is the possibility to link a function to a specific interrupt of the I2CNavKey, in this way the function is automatically called when the I2CNavKey generates an interrupts. 43 | 44 | A callback function must be declared as the following: 45 | 46 | ```C++ 47 | void NAME_OF_THE_FUNCTION(i2cNavKey* obj) 48 | ``` 49 | 50 | The argument **i2cNavKey* obj** is the pointer to the class that called the method. 51 | 52 | There are 26 possible events: 53 | 54 | | Event | Description | 55 | |:-----------:|:----------------------------------| 56 | | onArrowsPush | One of the 4 direction keys is pressed | 57 | | onArrowsRelese | One of the 4 direction keys is released | 58 | | onUpPush | Arrow up is pressed | 59 | | onUpRelease | Arrow up is released | 60 | | onDownPush | Arrow down is pressed | 61 | | onDownRelease | Arrow down is released | 62 | | onRightPush | Arrow right is pressed | 63 | | onRightRelease | Arrow right is released | 64 | | onLeftPush | Arrow left is pressed | 65 | | onLeftRelease | Arrow left is released | 66 | | onCentralPush | central button is pressed | 67 | | onCentralRelease | central button is released | 68 | | onCentralDoublePush | central button is double pushed | 69 | | onIncrement | The counter value is incremented | 70 | | onDecrement | The counter value is decremented | 71 | | onChange | The counter value is incremented or decremented | 72 | | onMax | The counter value reach the maximum threshold | 73 | | onMin | The counter value reach the minimum threshold | 74 | | onMinMax | The counter value reach the maximum or minimum threshold | 75 | | onGP1Rise | GP1 configured as input, rising edge | 76 | | onGP1Fall | GP1 configured as input, falling edge | 77 | | onGP2Rise | GP2 configured as input, rising edge | 78 | | onGP2Fall | GP2 configured as input, falling edge | 79 | | onGP3Rise | GP3 configured as input, rising edge | 80 | | onGP3Fall | GP3 configured as input, falling edge | 81 | | onFadeProcess | Fade process terminated | 82 | 83 | 84 | 85 | #### Examples: 86 | 87 | ```C++ 88 | i2cNavKey navkey(0x10);// Class declaration 89 | 90 | ... 91 | 92 | // Simple callback that ist's called when the encoder is rotated 93 | void navkey_encoder_change(i2cNavKey* obj) { 94 | Serial.println( obj->readCounterByte()); //Print on the terminal the counter value. 95 | } 96 | 97 | ... 98 | 99 | navkey.onChange = navkey_encoder_change; //Attach the event to the callback function. 100 | 101 | 102 | } 103 | 104 | ``` 105 | 106 | If you need to remove the link with a callback, you just need to define: 107 | ```C++ 108 | navkey.onChange=NULL; 109 | ``` 110 | 111 | 112 | 113 | ## Initialization 114 | 115 | ### void begin( uint8_t conf) 116 | This is used for initializing the I2CNavKey by writing the configuration register. 117 | The parameters can be concatenated in OR mode. 118 | The possible parameters are the following: 119 | 120 | | Parameter | Description | 121 | |:----------:|:------------------------------------------------------ | 122 | | INT_DATA | The Threshold, counter step and counter value are used with integer numbers | 123 | | FLOAT_DATA | The Threshold, counter step and counter value are used with floating numbers | 124 | | | | 125 | | WRAP_ENABLE | Wrap enable. When the counter value reaches the CMAX+1, restart to the CMIN and vice versa | 126 | | WRAP_DISABLE | Wrap disable. When the counter value reaches the CMAX or CMIN, the counter stops to increasing or decreasing | 127 | | | | 128 | | DIRE_LEFT | Rotate left side to increase the value counter | 129 | | DIRE_RIGHT | Rotate right side to increase the value counter | 130 | | | | 131 | | IPUP_DISABLE | Disable the internal pull-up on the INT pin | 132 | | IPUP_ENABLE | Enable the internal pull-up on the INT pin | 133 | | | | 134 | | CLK_STRECH_ENABLE | Enable the I2C clock stretch | 135 | | CLK_STRECH_DISABLE | Disable the I2C clock stretch | 136 | | | | 137 | | EEPROM_BANK1 | Select the first EEPROM bank | 138 | | EEPROM_BANK2 | Select the second EEPROM bank | 139 | | | | 140 | | RESET | Reset the board | 141 | 142 | #### Examples: 143 | 144 | ```C++ 145 | navkey.begin(i2cNavKey::INT_DATA | i2cNavKey::WRAP_ENABLE | i2cNavKey::DIRE_RIGHT | i2cNavKey::IPUP_ENABLE); 146 | ``` 147 | 148 | ### void reset(void) 149 | Reset of the board. 150 | In this command there is 8ms delay in order to make the board correctly restart. 151 | 152 | ## Configuration 153 | 154 | ### void writeGP1conf(uint8_t gp1) 155 | ### void writeGP2conf(uint8_t gp2) 156 | ### void writeGP3conf(uint8_t gp3) 157 | 158 | This 3 functions are used to configure the GP pins. The parameters are the same for all of the 3 GP pins. 159 | The interrupt configurations are used only when the pin is configured as digital input. 160 | 161 | | Parameter | Description | 162 | |:-----------:|:-------------| 163 | |GP_PWM| Set the GP pin as PWM output| 164 | |GP_OUT| Set the GP pin as digital output| 165 | |GP_AN| Set the GP pin as analog input| 166 | |GP_IN| Set the GP pin as digital input output| 167 | ||| 168 | |GP_PULL_EN| Enable the internal pull-up of the pin| 169 | |GP_PULL_DI| Disable the internal pull-up of the pin| 170 | ||| 171 | |GP_INT_DI| Disable the pin interrupt| 172 | |GP_INT_PE| Enable the interrupt at the positive edge| 173 | |GP_INT_NE| Enable the interrupt at the negative edge| 174 | |GP_INT_BE| Enable the interrupt at the positive and negative edge| 175 | 176 | #### Examples: 177 | 178 | ```C++ 179 | navkey.writeGP1conf(i2cNavKey::GP_IN | i2cNavKey::GP_PULL_EN | i2cNavKey::GP_INT_BE ); //Configure the GP1 as digital input with the pull-up enable and the interrupt enabled on both edges 180 | 181 | navkey.writeGP2conf(i2cNavKey::GP_PWM); //Configure the GP2 as PWM output 182 | 183 | ``` 184 | 185 | ### void writeInterruptConfig(uint8_t interrupt) 186 | 187 | This method is used for enabling or disabling the interrupt source selectively. When an interrupt event occurs, the INT pin goes low and the event is stored in the status register. 188 | 189 | | Parameter | Description | 190 | |:-----------:|:-------------| 191 | | UPR | Arrow up is released | 192 | | UPP | Arrow up is pressed | 193 | | DNR | Arrow down is released | 194 | | DNP | Arrow down is pressed | 195 | | RTR | Arrow right is released | 196 | | RTP | Arrow right is pressed | 197 | | LTR | Arrow left is released | 198 | | LTP | Arrow left is pressed | 199 | | CTRR | Central button is released | 200 | | CTRP | Central button is pressed | 201 | | CTRDP | Central button is double pushed | 202 | | RINC | Encoder is rotated in the increment direction | 203 | | RDEC | Encoder is rotated in the decrement direction | 204 | | RMAX | Maximum threshold is reached | 205 | | RMIN | Minimum threshold is reached | 206 | | INT_2 | An event on the interrupt 2 register occurs | 207 | 208 | ### void autoconfigInterrupt(void) 209 | This method auto configures the **INTCONF** register according to the attached callback. 210 | **For the proper use, must be called after the definition of the last event property.** 211 | 212 | ```C++ 213 | navkey.onUpPush = navkey_Up; 214 | navkey.onDownPush = navkey_Down; 215 | navkey.onLeftPush = navkey_Left; 216 | navkey.onRightPush = navkey_Right; 217 | navkey.onIncrement = navkey_increment; 218 | navkey.onDecrement = navkey_decrement; 219 | navkey.onMax = navkey_max; 220 | navkey.onMin = navkey_min; 221 | navkey.onButtonPush = navkey_push; 222 | navkey.onButtonDoublePush = navkey_double_push; 223 | /* Enable the I2C Encoder V2 interrupts according to the previus attached callback */ 224 | navkey.autoconfigInterrupt(); 225 | 226 | ``` 227 | 228 | ### void writeDoublePushPeriod(uint8_t dperiod) 229 | 230 | This method is used for setting the window period **DPPERIOD** of the double push of the central button. When the value is 0, the double push option is disabled. 231 | The I2C NavKey will multiplies this value by 10 (value x10). 232 | 233 | #### Examples: 234 | 235 | ```C++ 236 | navkey.writeDoublePushPeriod(50); //Set a period for the double push of 500ms 237 | ``` 238 | 239 | 240 | ### void writeFadeGP(uint8_t fade) 241 | 242 | This method is used for setting the fade speed **FADEGP** of the RGB LED of the rotary encoder. It the value is 0, the fade option is disabled. 243 | #### Examples: 244 | 245 | ```C++ 246 | navkey.writeFadeGP(5); //GP Fade enabled with 5ms step 247 | ``` 248 | 249 | 250 | ### void writeGammaGP1(uint8_t fade) 251 | ### void writeGammaGP2(uint8_t fade) 252 | ### void writeGammaGP3(uint8_t fade) 253 | 254 | This method is used to set a gamma correction in case the GP pin is set to PWM 255 | 256 | | Parameter | Description | 257 | |:-----------:|:-------------| 258 | | GAMMA_1 | Gamma is 1, in thi case the PWM is lenear | 259 | | GAMMA_1_8 | Gamma is 1.8 | 260 | | GAMMA_2 | Gamma is 2 | 261 | | GAMMA_2_2 | Gamma is 2.2 | 262 | | GAMMA_2_4 | Gamma is 2.4 | 263 | | GAMMA_2_6 | Gamma is 2.6 | 264 | | GAMMA_2_8 | Gamma is 2.8 | 265 | 266 | #### Examples: 267 | 268 | ```C++ 269 | navkey.writeGammaGP1(i2cNavKey::GAMMA_1); 270 | navkey.writeGammaGP2(i2cNavKey::GAMMA_2); 271 | navkey.writeGammaGP3(i2cNavKey::GAMMA_2_2); 272 | ``` 273 | 274 | 275 | ## Status 276 | 277 | ### bool updateStatus(void) 278 | Read the I2CNavKey status register **ISTATUS**. In case of events the attached callback is called. 279 | Return value is **true** in case of some event, otherwise is **false** 280 | In case an event of the I2STATUS register, the I2STATUS is automatically be read. 281 | 282 | #### Examples: 283 | 284 | ```C++ 285 | if ( navkey.updateStatus() == true) { 286 | // Something happens 287 | } 288 | ``` 289 | 290 | 291 | 292 | ### bool readStatus(uint8_t s) 293 | 294 | Must be called after **updateStatus()**, this method is used for checking if some event occurs on the **ISTATUS** register. 295 | Return value is **true** in case of the event occurred, otherwise is **false** 296 | Possible parameters are: 297 | 298 | | Parameter | Description | 299 | |:-----------:|:-------------| 300 | | UPR | Arrow up is released | 301 | | UPP | Arrow up is pressed | 302 | | DNR | Arrow down is released | 303 | | DNP | Arrow down is pressed | 304 | | RTR | Arrow right is released | 305 | | RTP | Arrow right is pressed | 306 | | LTR | Arrow left is released | 307 | | LTP | Arrow left is pressed | 308 | | CTRR | Central button is released | 309 | | CTRP | Central button is pressed | 310 | | CTRDP | Central button is double pushed | 311 | | RINC | Encoder is rotated in the increment direction | 312 | | RDEC | Encoder is rotated in the decrement direction | 313 | | RMAX | Maximum threshold is reached | 314 | | RMIN | Minimum threshold is reached | 315 | | INT_2 | An event on the interrupt 2 register occurs | 316 | 317 | #### Example: 318 | ```C++ 319 | if ( navkey.updateStatus() == true) { 320 | if ( navkey.readStatus(RINC)) { 321 | Serial.print("Increment "); 322 | } 323 | if ( navkey.readStatus(RDEC)) { 324 | Serial.print("Decrement "); 325 | } 326 | 327 | if ( navkey.readStatus(RMAX)) { 328 | Serial.print("Maximum threshold: "); 329 | } 330 | 331 | if ( navkey.readStatus(RMIN)) { 332 | Serial.print("Minimum threshold: "); 333 | } 334 | 335 | if ( navkey.readStatus(PUSHR)) { 336 | Serial.println("Push button Released"); 337 | } 338 | 339 | if ( navkey.readStatus(PUSHP)) { 340 | } 341 | 342 | if ( navkey.readStatus(PUSHD)) { 343 | Serial.println("Double push!"); 344 | } 345 | ``` 346 | 347 | 348 | ### uint8_t readStatus(void) 349 | 350 | Return the status of the register **ESTATUS** 351 | 352 | 353 | 354 | ### bool readInt2(uint8_t s) 355 | Must be called after **updateStatus()**, this method is used for checking if some event occurred on the secondary interrupt status **I2STATUS** register. 356 | Return value is **true** in case of the event occurred, otherwise is **false** 357 | Possible parameters are: 358 | 359 | | Parameter | Description | 360 | |:-----------:|:-------------| 361 | | GP1_POS | Positive edge on the GP1 pin | 362 | | GP1_NEG | Negative edge on the GP1 pin | 363 | | GP2_POS | Positive edge on the GP2 pin | 364 | | GP2_NEG |Negative edge on the GP2 pin | 365 | | GP3_POS | Positive edge on the GP3 pin| 366 | | GP3_NEG |Negative edge on the GP3 pin | 367 | | FADE_INT |Fade process finished | 368 | 369 | #### Example: 370 | ```C++ 371 | if ( navkey.updateStatus() == true) { 372 | if ( navkey.readInt2(GP1_POS)) { 373 | Serial.print("GP1 positive edge"); 374 | } 375 | if ( navkey.readInt2(GP1_NEG)) { 376 | Serial.print("GP1 negative edge "); 377 | } 378 | 379 | if ( navkey.readInt2(GP2_POS)) { 380 | Serial.print("GP2 positive edge"); 381 | } 382 | 383 | if ( navkey.readInt2(GP2_NEG)) { 384 | Serial.print("GP2 negative edge "); 385 | } 386 | 387 | if ( navkey.readInt2(GP3_POS)) { 388 | Serial.print("GP3 positive edge"); 389 | } 390 | 391 | if ( navkey.readInt2(GP3_NEG)) { 392 | Serial.print("GP3 negative edge "); 393 | } 394 | 395 | if ( navkey.readInt2(FADE_INT)) { 396 | Serial.println("Fade process finished"); 397 | } 398 | ``` 399 | 400 | ### uint8_t readInt2(void) 401 | 402 | Return the status of the register **I2STATUS** 403 | 404 | ### bool readFadeStatus(uint8_t s) 405 | 406 | When this function is called, it performs a I2C reading. 407 | This function return **true** when the fade running, otherwise return **false** 408 | 409 | | Parameter | Description | 410 | |:-----------:|:-------------| 411 | | FADE_GP1 | Fade process status of the GP1 | 412 | | FADE_GP2 | Fade process status of the GP2 | 413 | | FADE_GP3 | Fade process status of the GP3 | 414 | 415 | 416 | ### uint8_t readFadeStatus(void) 417 | Return the value of the register **FSTATUS**. 418 | 419 | 420 | ## Reading methods 421 | 422 | ### int32_t readCounterLong(void) 423 | Return the counter value in the format **int32_t**, by reading all the 4 bytes of the counter value registers. 424 | 425 | ### int16_t readCounterInt(void) 426 | Return the counter value in the format **int16_t**, by reading the 2 LSB of the counter value registers. 427 | Useful when the counter register is between the values -32768 to 32767. 428 | 429 | ### int8_t readCounterByte(void) 430 | Return the counter value in the format **int8_t**, by reading the LSB byte of the counter value register. 431 | Useful when the counter register is between the values -128 to 127 432 | 433 | ### float readCounterFloat(void) 434 | Return the counter value in the format **float**, by reading all the 4 bytes of the counter value registers. 435 | For using this function you have to configure the board with the parameter **FLOAT_DATA**. 436 | 437 | ### int32_t readMax(void) 438 | Return the maximum threshold in format **int32_t**, bye reading all the 4 bytes of the counter Max. 439 | 440 | ### float readMaxFloat(void) 441 | Return the maximum threshold in format **float**, bye reading all the 4 bytes of the counter Max. 442 | 443 | ### int32_t readMin(void) 444 | Return the minimum threshold in format **int32_t**, by reading all the 4 byte of the counter Min. 445 | 446 | ### float readMinFloat(void) 447 | Return the minimum threshold in format **float**, bye reading all the 4 bytes of the counter Min. 448 | 449 | ### int32_t readStep(void) 450 | Return the minimum threshold in format **int32_t**, by reading all the 4 bytes of the ISTEP registers. 451 | 452 | ### float readStepFloat(void) 453 | Return the step value in format **float**, by reading all the 4 bytes of the ISTEP registers . 454 | 455 | ### uint8_t readLEDR(void) 456 | Return the value of the RLED register. 457 | 458 | ### uint8_t readLEDG(void) 459 | Return the value of the GLED register. 460 | 461 | ### uint8_t readLEDB(void) 462 | Return the value of the BLED register. 463 | 464 | ### uint8_t readGP1(void) 465 | Return the value of the GP1REG register. 466 | If the **GP1** is configured as input, it's possible to read the logic status of the pin: *1* when the pin is high, otherwise *0*. 467 | If the **GP1** is configured as analog, it's possible to read the 8bit of the ADC. 468 | 469 | ### uint8_t readGP2(void) 470 | Return the value of the GP2REG register. 471 | If the **GP2** is configured as input, it's possible to read the logic status of the pin: *1* when the pin is high, otherwise *0*. 472 | If the **GP2** is configured as analog, it's possible to read the 8bit of the ADC. 473 | 474 | ### uint8_t readGP3(void) 475 | Return the value of the GP3REG register. 476 | If the **GP3** is configured as input, it's possible to read the logic status of the pin: *1* when the pin is high, otherwise *0*. 477 | If the **GP3** is configured as analog, it's possible to read the 8bit of the ADC. 478 | 479 | ### uint8_t readAntibouncingPeriod(void) 480 | Return the value of the ANTBOUNC register. 481 | 482 | ### uint8_t readDoublePushPeriod(void) 483 | Return the value of the DPPERIOD register. 484 | 485 | ### uint8_t readFadeGP(void) 486 | Return the value of the FADEGP register. 487 | 488 | ### uint8_t readEEPROM(uint8_t add) 489 | Return the value of the EEPROM register. 490 | This function automatically manage the setting of the first and second memory bank. 491 | 492 | ### uint8_t readEncoderByte(uint8_t reg) 493 | Read a generic register of the I2C Encoder V2. 494 | The input parameter is the address of the register. 495 | 496 | ### int16_t readEncoderInt(uint8_t reg) 497 | Read a generic register of the I2C Encoder V2, in 16bit format. 498 | The input parameter is starting address of the registers. 499 | 500 | ### int32_t readEncoderLong(uint8_t reg) 501 | Read a generic register of the I2C Encoder V2, in 32bit format. 502 | The input parameter is starting address of the registers. 503 | 504 | ### uint8_t readIDCode(void) 505 | Return the ID code of the I2C NavKey, it's a fixed number 0x5B 506 | 507 | ### uint8_t readVersion(void) 508 | Return the version of the I2C NavKey. 509 | 510 | 511 | ## Writing methods 512 | 513 | ### void writeCounter(int32_t counter) 514 | Write the counter value register with a **int32_t** number. All of the 4 bytes are wrote. 515 | 516 | ### void writeCounter(float counter) 517 | Write the counter value register with a **float** number. All of the 4 bytes are wrote. 518 | 519 | ### void writeMax(int32_t max) 520 | Write the Max register with a **int32_t** number. All of the 4 bytes are wrote. 521 | 522 | ### void writeMax(float max) 523 | Write the Max register with a **float** number. All of the 4 bytes are wrote. 524 | 525 | ### void writeMin(int32_t min) 526 | Write the Min register with a **int32_t** number. All of the 4 bytes are wrote. 527 | 528 | ### void writeMin(float min) 529 | Write the Min register with a **float** number. All of the 4 bytes are wrote. 530 | 531 | ### void writeStep(int32_t step) 532 | Write the increment step with a **int32_t** number. All of the 4 bytes are wrote. 533 | 534 | ### void writeStep(float step) 535 | Write the increment step with a **float** number. All of the 4 bytes are wrote. 536 | 537 | ### void writeGP1(uint8_t gp1) 538 | Write the GP1REG register. 539 | If the GP1 is configure as PWM with this method it's possible to write the PWM value. 540 | If the GP1 is configure as output with this method it's possible to write the logic status: 1 for high, while 0 for low. 541 | 542 | ### void writeGP2(uint8_t gp2) 543 | Write the GP2REG register. 544 | If the GP2 is configure as PWM with this method it's possible to write the PWM value. 545 | If the GP2 is configure as output with this method it's possible to write the logic status: 1 for high, while 0 for low. 546 | 547 | ### void writeGP3(uint8_t gp3) 548 | Write the GP3REG register. 549 | If the GP3 is configure as PWM with this method it's possible to write the PWM value. 550 | If the GP3 is configure as output with this method it's possible to write the logic status: 1 for high, while 0 for low. 551 | 552 | ### void writeDoublePushPeriod(uint8_t dperiod) 553 | Write the DPPERIOD register. 554 | 555 | ### void writeFadeGP(uint8_t fade) 556 | Write the FADEGP register. 557 | 558 | ### void writeEEPROM(uint8_t add, uint8_t data) 559 | Write the EEPROM memory. 560 | The input parameter *add* is the address. This method automatically change the first or the second bank. 561 | The input parameter *data* is the data taht will be written. 562 | 563 | -------------------------------------------------------------------------------- /examples/RGB LED Ring Small/LEDRingSmall_Demo/LEDRingSmall_Demo.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include "LEDRingSmall.h" 3 | 4 | /* 5 | Board Pinout 6 | +-----+--------+----------+-------------+ 7 | | Pin | Color | Function | Arduino pin | 8 | +-----+--------+----------+-------------+ 9 | | 1 | Red | VCC | +5V | 10 | | 2 | Black | GND | GND | 11 | | 3 | Yellow | VIO | +5V | 12 | | 4 | Green | SDA | A4 | 13 | | 5 | Blue | SCL | A5 | 14 | +-----+--------+----------+-------------+ 15 | */ 16 | 17 | const uint32_t fade1_table[24] = {0x8011EE, 0xA004DA, 0xBF00BF, 0xDA04A0, 0xEE1180, 0xFB255F, 0xFF4040, 0xFB5F25, 0xEE8011, 0xDAA004, 0xBFBF00, 0xA0DA04, 0x80EE11, 0x5FFB25, 0x40FF40, 0x25FB5F, 0x11EE80, 0x04DAA0, 0x00BFBF, 0x04A0DA, 0x1180EE, 0x255FFB, 0x4040FF, 0x5F25FB}; 18 | const uint32_t fade2_table[24] = {0xFF0000, 0xFF0004, 0xFF0020, 0xFF006B, 0xFF00FF, 0x6B00FF, 0x2000FF, 0x0400FF, 0x0000FF, 0x0004FF, 0x0020FF, 0x006BFF, 0x00FFFF, 0x00FF6B, 0x00FF20, 0x00FF04, 0x00FF00, 0x04FF00, 0x20FF00, 0x6BFF00, 0xFFFF00, 0xFF6B00, 0xFF2000, 0xFF0400}; 19 | static uint8_t j = 0; 20 | static uint8_t i = 0; 21 | static uint16_t tim = 0; 22 | static uint8_t r = 5, g = 8, b = 20, rg = 40, br = 35, bg = 17; 23 | 24 | LEDRingSmall LEDRingSmall(ISSI3746_SJ2 | ISSI3746_SJ7);//Only SJ2 and SJ7 are soldered in this example 25 | // Also check if there are the pull-UP resistors on the I2C bus. If no or the board doesn't want to work please also solder the jumper SJ9 26 | 27 | void setup(void) { 28 | 29 | Wire.begin(); 30 | Wire.setClock(400000); 31 | 32 | LEDRingSmall.LEDRingSmall_Reset(); 33 | delay(20); 34 | 35 | LEDRingSmall.LEDRingSmall_Configuration(0x01); //Normal operation 36 | LEDRingSmall.LEDRingSmall_PWMFrequencyEnable(1); 37 | LEDRingSmall.LEDRingSmall_SpreadSpectrum(0b0010110); 38 | LEDRingSmall.LEDRingSmall_GlobalCurrent(0x10); 39 | LEDRingSmall.LEDRingSmall_SetScaling(0xFF); 40 | LEDRingSmall.LEDRingSmall_PWM_MODE(); 41 | 42 | 43 | 44 | } 45 | 46 | void loop() { 47 | LEDRingSmall.LEDRingSmall_GlobalCurrent(0x10); 48 | LEDRingSmall.LEDRingSmall_PWM_MODE(); 49 | 50 | for (i = 0; i < 24; i++) { 51 | LEDRingSmall.LEDRingSmall_Set_RED(i, 0xff); 52 | delay(30); 53 | } 54 | 55 | for (i = 0; i < 24; i++) { 56 | LEDRingSmall.LEDRingSmall_Set_RED(i, 0); 57 | LEDRingSmall.LEDRingSmall_Set_GREEN(i, 0xff); 58 | delay(30); 59 | } 60 | 61 | for (i = 0; i < 24; i++) { 62 | LEDRingSmall.LEDRingSmall_Set_GREEN(i, 0); 63 | LEDRingSmall.LEDRingSmall_Set_BLUE(i, 0xff); 64 | delay(30); 65 | } 66 | 67 | for (i = 0; i < 24; i++) { 68 | 69 | LEDRingSmall.LEDRingSmall_Set_RGB(i, 0xfc6b03); 70 | delay(30); 71 | } 72 | 73 | for (i = 0; i < 24; i++) { 74 | 75 | LEDRingSmall.LEDRingSmall_Set_RGB(i, 0xfc03c6); 76 | delay(30); 77 | } 78 | // delay(2000); 79 | //LEDRingSmall.LEDRingSmall_ClearAll(); 80 | 81 | 82 | 83 | 84 | for (tim = 0; tim < 2000; tim++) { 85 | 86 | 87 | 88 | if ((tim % 5) == 0) { 89 | LEDRingSmall.LEDRingSmall_Set_RED(r, 0); 90 | r = r + 1; 91 | if (r >= 24) 92 | r = 0; 93 | LEDRingSmall.LEDRingSmall_Set_RED(r, 0xFF); 94 | } 95 | 96 | if ((tim % 6) == 0) { 97 | LEDRingSmall.LEDRingSmall_Set_GREEN(g, 0); 98 | g = g + 1; 99 | if (g >= 24) 100 | g = 0; 101 | LEDRingSmall.LEDRingSmall_Set_GREEN(g, 0xFF); 102 | } 103 | 104 | if ((tim % 8) == 0) { 105 | LEDRingSmall.LEDRingSmall_Set_BLUE(b, 0); 106 | b = b + 1; 107 | if (b >= 24) 108 | b = 0; 109 | LEDRingSmall.LEDRingSmall_Set_BLUE(b, 0xFF); 110 | } 111 | 112 | 113 | if ((tim % 7) == 0) { 114 | LEDRingSmall.LEDRingSmall_Set_BLUE(br, 0); 115 | LEDRingSmall.LEDRingSmall_Set_RED(br, 0); 116 | br = br + 1; 117 | if (br >= 24) 118 | br = 0; 119 | LEDRingSmall.LEDRingSmall_Set_BLUE(br, 0xFF); 120 | LEDRingSmall.LEDRingSmall_Set_RED(br, 0xFF); 121 | } 122 | 123 | 124 | if ((tim % 10) == 0) { 125 | LEDRingSmall.LEDRingSmall_Set_BLUE(bg, 0); 126 | LEDRingSmall.LEDRingSmall_Set_GREEN(bg, 0); 127 | bg = bg + 1; 128 | if (bg >= 24) 129 | bg = 0; 130 | LEDRingSmall.LEDRingSmall_Set_BLUE(bg, 0xFF); 131 | LEDRingSmall.LEDRingSmall_Set_GREEN(bg, 0xFF); 132 | } 133 | 134 | if ((tim % 11) == 0) { 135 | LEDRingSmall.LEDRingSmall_Set_RED(rg, 0); 136 | LEDRingSmall.LEDRingSmall_Set_GREEN(rg, 0); 137 | rg = rg + 1; 138 | if (rg >= 24) 139 | rg = 0; 140 | LEDRingSmall.LEDRingSmall_Set_RED(rg, 0xFF); 141 | LEDRingSmall.LEDRingSmall_Set_GREEN(rg, 0xFF); 142 | } 143 | 144 | delay(10); 145 | } 146 | 147 | 148 | for (tim = 0; tim < 100; tim++) { 149 | j = tim % 24; 150 | 151 | for (i = 0; i < 24; i++) { 152 | LEDRingSmall.LEDRingSmall_Set_RGB(i, fade1_table[j]); 153 | j++; 154 | if (j >= 24) 155 | j = 0; 156 | } 157 | delay(40); 158 | } 159 | 160 | for (tim = 0; tim < 100; tim++) { 161 | j = tim % 24; 162 | for (i = 0; i < 24; i++) { 163 | LEDRingSmall.LEDRingSmall_Set_RGB(i, fade2_table[j]); 164 | j++; 165 | if (j >= 24) 166 | j = 0; 167 | } 168 | delay(40); 169 | } 170 | 171 | for (i = 0xff; i > 0; i--) { 172 | 173 | LEDRingSmall.LEDRingSmall_GlobalCurrent(i); 174 | delay(20); 175 | } 176 | LEDRingSmall.LEDRingSmall_ClearAll(); 177 | LEDRingSmall.LEDRingSmall_GlobalCurrent(0xff); 178 | 179 | 180 | } 181 | -------------------------------------------------------------------------------- /examples/RGB LED Ring Small/README.md: -------------------------------------------------------------------------------- 1 | # RGB LED Ring Small Arduino Library 2 | 3 | -------------------------------------------------------------------------------- 4 | 5 | ## Introduction 6 | 7 | Here you can find the project description of the [RGB LED Ring Small](https://github.com/Fattoresaimon/RGB_LED_Ring_Small). 8 | The RGB LED Ring is based on the driver ISSI [IS31FL3746A](https://www.lumissil.com/assets/pdf/core/IS31FL3746A_DS.pdf), for more functionality please check the datasheet of the driver. 9 | At the moment the breathing effect are not implemented. 10 | 11 | The RGB LED Ring is available on [DuPPa Store!](https://www.duppa.net/shop/rgb-led-ring-small/) 12 | 13 | ## Initialization of the class 14 | 15 | The library makes available the class **LEDRingSmall** 16 | To initialize the library, you have to declare an instance of the class **LEDRingSmall** for each LED Ring. 17 | For example: 18 | 19 | ``` C++ 20 | LEDRingSmall LEDRingSmall(ISSI3746_SJ2 | ISSI3746_SJ7); 21 | ``` 22 | Declaration of the RGB LED Ring with the jumper SJ2 and SJ7 soldered. 23 | The RGB LED Ring v1.1 it have 8 Jumpers for setting the address, they are divided in 2 groups of 4 jumpers. Only 1 jumper per group should be soldered, this make 16 possible combinations. 24 | Possible combination are the following: 25 | 26 | | Jumper first group | Jumper second group | I2C Address | 27 | | ------------ | ------------ | :--: | 28 | | ISSI3746_SJ1 | ISSI3746_SJ5 | 0x60 | 29 | | ISSI3746_SJ2 | ISSI3746_SJ5 | 0x62 | 30 | | ISSI3746_SJ3 | ISSI3746_SJ5 | 0x64 | 31 | | ISSI3746_SJ4 | ISSI3746_SJ5 | 0x66 | 32 | | ISSI3746_SJ1 | ISSI3746_SJ6 | 0x68 | 33 | | ISSI3746_SJ2 | ISSI3746_SJ6 | 0x6A | 34 | | ISSI3746_SJ3 | ISSI3746_SJ6 | 0x6C | 35 | | ISSI3746_SJ4 | ISSI3746_SJ6 | 0x6E | 36 | | ISSI3746_SJ1 | ISSI3746_SJ7 | 0x70 | 37 | | ISSI3746_SJ2 | ISSI3746_SJ7 | 0x72 | 38 | | ISSI3746_SJ3 | ISSI3746_SJ7 | 0x74 | 39 | | ISSI3746_SJ4 | ISSI3746_SJ7 | 0x76 | 40 | | ISSI3746_SJ1 | ISSI3746_SJ8 | 0x78 | 41 | | ISSI3746_SJ2 | ISSI3746_SJ8 | 0x7A | 42 | | ISSI3746_SJ3 | ISSI3746_SJ8 | 0x7C | 43 | | ISSI3746_SJ4 | ISSI3746_SJ8 | 0x7E | 44 | 45 | 46 | 47 | ## Configuration 48 | 49 | ### void LEDRingSmall_Reset(void) 50 | Reset all the IS31FL3746A to the default state 51 | 52 | ### void LEDRing_Configuration(uint8_t conf) 53 | This method write the register ad the address 50h of the IS31FL3746A. Please refer the datasheet for further information. 54 | 55 | ### void LEDRing_GlobalCurrent(uint8_t conf) 56 | This method write the register 51h and it set the LEDs current. 57 | It's possible to set up to 256 step from 0 to 0xFF. 58 | Higher value make the LEDs brighter. 59 | 60 | ### void LEDRing_SetScaling(uint8_t led_n, uint8_t scal); 61 | Set the output current of each single color led. **n** is the LED number ( 1 to 72 ), **scal** is the scaling value (0 to 256) 62 | 63 | ### void LEDRing_SetScaling(uint8_t scal); 64 | Set the output current of all LED. **scal** is the scaling value (0 to 256) 65 | 66 | ### void LEDRing_PULLUP_DOWN(uint8_t pull) 67 | Configure the PULLUP and PULLDOWN resistor. You can refer to the IS31FL3746A datasheet at the 52h register for further information. 68 | 69 | ### void LEDRingSmall_SpreadSpectrum(uint8_t spread); 70 | Enable and configure the spread spectrum functionality. You can refer to the IS31FL3746A datasheet at the 60h register for further information. 71 | 72 | ### void LEDRingSmall_PWMFrequencyEnable(uint8_t PWMenable); 73 | Enable or Disable the PWM output. Write 1 for enable the PWM output, write 0 for disable the PWM output. 74 | 75 | ### void LEDRingSmall_PWMFrequencySetting(uint8_t pwmfreq); 76 | Configure the PWM frequency. It's possible to configure the PWM frequency from 29kHz to 453Hz. You can refer to the IS31FL3746A datasheet at the E2h register for further information. 77 | 78 | ### uint8_t LEDRing_Temperature(void); 79 | Get the temperature status register. Refer to the IS31FL3746A datasheet at the 24h register for further information. 80 | 81 | ### void LEDRing_PWM_MODE(void) 82 | This method set all the LEDs in PWM mode. 83 | 84 | ### void LEDRing_ClearAll(void) 85 | This method set the PWM value to 0 for each LED. 86 | 87 | ### void LEDRing_Set_RGB(uint8_t led_n, uint32_t color) 88 | Set the RGB color for a specific LED. 89 | **n** is the LED number ( 0 to 23 ), while the **color** is the RGB color in 24bit format. 90 | 91 | #### Examples: 92 | 93 | ```C++ 94 | LEDRingSmall.LEDRingSmall_Set_RGB(10, 0xFF9933); 95 | ``` 96 | 97 | ### void LEDRing_Set_RED(uint8_t led_n, uint8_t color) 98 | ### void LEDRing_Set_GREEN(uint8_t led_n, uint8_t color) 99 | ### void LEDRing_Set_BLUE(uint8_t led_n, uint8_t color) 100 | 101 | Set a specific color to a specific LED 102 | **n** is the LED number ( 0 to 24 ), while the **color** is the color in 8bit format. 103 | 104 | #### Examples: 105 | 106 | ```C++ 107 | LEDRingSmall.LEDRingSmall_Set_RED(4, 128); 108 | LEDRingSmall.LEDRingSmall_Set_GREEN(5, 200); 109 | LEDRingSmall.LEDRingSmall_Set_BLUE(6, 80); 110 | ``` 111 | -------------------------------------------------------------------------------- /examples/RGB LED Ring/LEDRingI2CEncoder/LEDRingI2CEncoder.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "LEDRing.h" 5 | 6 | 7 | /*This is a example with the RGB LED Ring plus the I2C Encoder V2.1 8 | There is a video fo this example: https://youtu.be/wR23IkYd3EY 9 | For this example you need the library TimerOne, You can do by going Sketch -> IncludeLibrary -> manage librarys and search Timer One 10 | The timer is used only for some effects... It's not mandatory 11 | 12 | 13 | Connections with Arduino UNO:d:\Users\Saimon\Documents\Arduino\libraries\ArduinoDuPPaLib-master.zip 14 | - -> GND 15 | + -> 5V 16 | SDA -> A4 17 | SCL -> A5 18 | INT -> A3 19 | */ 20 | 21 | const uint32_t fade1_table[48] = {0x8011EE, 0x900AE5, 0xA004DA, 0xB001CD, 0xBF00BF, 0xCD01B0, 0xDA04A0, 0xE50A90, 0xEE1180, 0xF51A6F, 0xFB255F, 0xFE324F, 0xFF4040, 0xFE4F32, 0xFB5F25, 0xF56F1A, 0xEE8011, 0xE5900A, 0xDAA004, 0xCDB001, 0xBFBF00, 0xB0CD01, 0xA0DA04, 0x90E50A, 0x80EE11, 0x6FF51A, 0x5FFB25, 0x4FFE32, 0x40FF40, 0x32FE4F, 0x25FB5F, 0x1AF56F, 0x11EE80, 0x0AE590, 0x04DAA0, 0x01CDB0, 0x00BFBF, 0x01B0CD, 0x04A0DA, 0x0A90E5, 0x1180EE, 0x1A6FF5, 0x255FFB, 0x324FFE, 0x4040FF, 0x4F32FE, 0x5F25FB, 0x6F1AF5, }; 22 | const uint32_t fade2_table[48] = {0xFF0000, 0xFF0001, 0xFF0004, 0xFF000E, 0xFF0020, 0xFF003E, 0xFF006B, 0xFF00AB, 0xFF00FF, 0xAB00FF, 0x6B00FF, 0x3E00FF, 0x2000FF, 0x0E00FF, 0x0400FF, 0x0100FF, 0x0000FF, 0x0001FF, 0x0004FF, 0x000EFF, 0x0020FF, 0x003EFF, 0x006BFF, 0x00ABFF, 0x00FFFF, 0x00FFAB, 0x00FF6B, 0x00FF3E, 0x00FF20, 0x00FF0E, 0x00FF04, 0x00FF01, 0x00FF00, 0x01FF00, 0x04FF00, 0x0EFF00, 0x20FF00, 0x3EFF00, 0x6BFF00, 0xABFF00, 0xFFFF00, 0xFFAB00, 0xFF6B00, 0xFF3E00, 0xFF2000, 0xFF0E00, 0xFF0400, 0xFF0100, }; 23 | 24 | uint8_t j = 0; 25 | 26 | uint8_t led_case = 5; 27 | uint8_t led_pos[6] = { 0, 0, 0, 10, 10, 0 }; 28 | uint16_t sf_Timer; 29 | 30 | const int IntPin = A3; /* Definition of the interrupt pin. You can change according to your board */ 31 | //Class initialization with the I2C addresses 32 | i2cEncoderLibV2 Encoder(0b1000000); /* A6 is soldered */ 33 | LEDRing LEDRing1(ISSI3745_SJ1 | ISSI3745_SJ5 ); 34 | 35 | void UpdateRing(uint8_t value); 36 | void timer_callback(void); 37 | uint8_t CheckRingBorder(uint8_t in); 38 | 39 | //Callback when the CVAL is incremented 40 | void encoder_change(i2cEncoderLibV2* obj) { 41 | if (led_case == 5) 42 | return; 43 | 44 | led_pos[led_case] = obj->readCounterByte(); 45 | if (led_case < 3) 46 | UpdateRing(led_pos[led_case]); 47 | 48 | Serial.print("Change: "); 49 | Serial.print(led_case); 50 | Serial.print(" val: "); 51 | Serial.println(led_pos[led_case]); 52 | } 53 | 54 | //Callback when the encoder is released 55 | // it change also the led RGB effect 56 | void encoder_released(i2cEncoderLibV2* obj) { 57 | Serial.println("Encoder is released"); 58 | led_case++; 59 | if (led_case > 5) 60 | led_case = 0; 61 | 62 | switch (led_case) { 63 | case 0: 64 | obj->writeCounter((int32_t)led_pos[led_case]); 65 | obj->writeRGBCode(0xFF0000); 66 | break; 67 | 68 | case 1: 69 | obj->writeCounter((int32_t)led_pos[led_case]); 70 | Encoder.writeRGBCode(0x00FF00); 71 | break; 72 | 73 | case 2: 74 | Encoder.writeRGBCode(0x0000FF); 75 | obj->writeCounter((int32_t)led_pos[led_case]); 76 | break; 77 | 78 | case 3: 79 | Timer1.start(); 80 | Encoder.writeMax((int32_t)100); /* Set the maximum threshold*/ 81 | Encoder.writeMin((int32_t)0); /* Set the minimum threshold */ 82 | Encoder.writeStep((int32_t)1); /* Set the step to 1*/ 83 | Encoder.writeRGBCode(0xFF00FF); 84 | obj->writeCounter((int32_t)led_pos[led_case]); 85 | break; 86 | 87 | case 4: 88 | Encoder.writeRGBCode(0x086050); 89 | obj->writeCounter((int32_t)led_pos[led_case]); 90 | break; 91 | 92 | case 5: 93 | Timer1.stop(); 94 | Encoder.writeRGBCode(0); 95 | for (uint8_t i = 0; i < 48; i++) { 96 | LEDRing1.LEDRing_Set_RGB(i, 0); 97 | delay(5); 98 | } 99 | 100 | led_case = 0; 101 | UpdateRing(led_pos[led_case]); 102 | led_case = 1; 103 | UpdateRing(led_pos[led_case]); 104 | led_case = 2; 105 | UpdateRing(led_pos[led_case]); 106 | led_case = 5; 107 | 108 | Encoder.writeMax((int32_t)47); /* Set the maximum threshold*/ 109 | Encoder.writeMin((int32_t)0); /* Set the minimum threshold */ 110 | Encoder.writeStep((int32_t)2); /* Set the step to 1*/ 111 | 112 | break; 113 | } 114 | } 115 | 116 | //Update the led Ring with the encoder position 117 | void UpdateRing(uint8_t value) { 118 | 119 | switch (led_case) { 120 | case 0: 121 | for (uint8_t i = 0; i < 48; i++) 122 | LEDRing1.LEDRing_Set_RED(i, 0); 123 | 124 | LEDRing1.LEDRing_Set_RED(CheckRingBorder(value + 2), 0x03); 125 | LEDRing1.LEDRing_Set_RED(CheckRingBorder(value + 1), 0x10); 126 | LEDRing1.LEDRing_Set_RED(CheckRingBorder(value), 0xff); 127 | LEDRing1.LEDRing_Set_RED(CheckRingBorder(value - 1), 0x10); 128 | LEDRing1.LEDRing_Set_RED(CheckRingBorder(value - 2), 0x03); 129 | break; 130 | 131 | case 1: 132 | for (uint8_t i = 0; i < 48; i++) 133 | LEDRing1.LEDRing_Set_GREEN(i, 0); 134 | LEDRing1.LEDRing_Set_GREEN(CheckRingBorder(value + 2), 0x03); 135 | LEDRing1.LEDRing_Set_GREEN(CheckRingBorder(value + 1), 0x10); 136 | LEDRing1.LEDRing_Set_GREEN(CheckRingBorder(value), 0xff); 137 | LEDRing1.LEDRing_Set_GREEN(CheckRingBorder(value - 1), 0x10); 138 | LEDRing1.LEDRing_Set_GREEN(CheckRingBorder(value - 2), 0x03); 139 | break; 140 | 141 | case 2: 142 | for (uint8_t i = 0; i < 48; i++) 143 | LEDRing1.LEDRing_Set_BLUE(i, 0); 144 | 145 | LEDRing1.LEDRing_Set_BLUE(CheckRingBorder(value + 2), 0x03); 146 | LEDRing1.LEDRing_Set_BLUE(CheckRingBorder(value + 1), 0x10); 147 | LEDRing1.LEDRing_Set_BLUE(CheckRingBorder(value), 0xff); 148 | LEDRing1.LEDRing_Set_BLUE(CheckRingBorder(value - 1), 0x10); 149 | LEDRing1.LEDRing_Set_BLUE(CheckRingBorder(value - 2), 0x03); 150 | break; 151 | } 152 | } 153 | 154 | // Callback when the Timer1 expire, used for make the LED pattern roatating 155 | void timer_callback(void) { 156 | sf_Timer++; 157 | } 158 | 159 | // Small function for wrap the led position between 0 and 47. 160 | uint8_t CheckRingBorder(uint8_t in) { 161 | 162 | if ((int8_t)in > 47) { 163 | return ((int8_t)in - 48); 164 | } 165 | if ((int8_t)in < 0) { 166 | 167 | return (48 + (int8_t)in); 168 | } 169 | return in; 170 | } 171 | 172 | void setup(void) { 173 | pinMode(IntPin, INPUT); 174 | Timer1.initialize(1000); 175 | Timer1.attachInterrupt(timer_callback); 176 | 177 | Wire.begin(); 178 | Wire.setClock(500000); 179 | Serial.begin(115200); 180 | Serial.println("**** I2C Encoder + LED Ring example ****"); 181 | 182 | Encoder.reset(); 183 | Encoder.begin(i2cEncoderLibV2::INT_DATA | i2cEncoderLibV2::WRAP_ENABLE 184 | | i2cEncoderLibV2::DIRE_LEFT | i2cEncoderLibV2::IPUP_ENABLE 185 | | i2cEncoderLibV2::RMOD_X2 | i2cEncoderLibV2::RGB_ENCODER); 186 | 187 | // The i2c encoder is set to RMOD_X2, in this way you will see the LED dot moving meawhile the encoder is in the middle of a step. 188 | 189 | Encoder.writeCounter((int32_t)0); /* Reset the counter value */ 190 | Encoder.writeMax((int32_t)47); /* Set the maximum threshold*/ 191 | Encoder.writeMin((int32_t)0); /* Set the minimum threshold */ 192 | Encoder.writeStep((int32_t)1); /* Set the step to 1*/ 193 | Encoder.writeAntibouncingPeriod(1); /* Set an anti-bouncing of 200ms */ 194 | Encoder.writeDoublePushPeriod(0); /*Set a period for the double push of 500ms */ 195 | 196 | // Definition of the encoder events 197 | Encoder.onChange = encoder_change; 198 | Encoder.onButtonRelease = encoder_released; 199 | 200 | 201 | /* Enable the I2C Encoder V2 interrupts according to the previus attached callback */ 202 | Encoder.autoconfigInterrupt(); 203 | LEDRing1.LEDRing_Reset(); 204 | delay(20); 205 | 206 | 207 | 208 | 209 | 210 | LEDRing1.LEDRing_Configuration(0x01); //Normal operation 211 | LEDRing1.LEDRing_SpreadSpectrum(0b0010110); 212 | LEDRing1.LEDRing_GlobalCurrent(0x0F); // maximum current output 213 | LEDRing1.LEDRing_PULLUP_DOWN(0x1B); 214 | LEDRing1.LEDRing_SetScaling(0xFF); 215 | 216 | LEDRing1.LEDRing_PWM_MODE(); 217 | randomSeed(analogRead(0)); 218 | 219 | // Showing some random pattern 220 | for (uint8_t i = 0; i < 100; i++) { 221 | LEDRing1.LEDRing_Set_RGB(random(47), random(0xFFFFFF)); 222 | delay(20); 223 | } 224 | for (uint8_t i = 0; i < 48; i++) { 225 | LEDRing1.LEDRing_Set_RGB(i, fade2_table[i]); 226 | delay(10); 227 | } 228 | for (uint8_t i = 0; i < 48; i++) { 229 | LEDRing1.LEDRing_Set_RGB(i, 0); 230 | delay(5); 231 | } 232 | } 233 | 234 | void loop() { 235 | uint8_t temp; 236 | //Check the Encoder Status 237 | if (digitalRead(IntPin) == LOW) { 238 | Encoder.updateStatus(); 239 | } 240 | 241 | // Make the LED pattern rotating, it's used the timer1 for the temporization. 242 | if (sf_Timer > led_pos[led_case]) { 243 | sf_Timer = 0; 244 | 245 | switch (led_case) { 246 | case 3: 247 | temp = j++; 248 | if (j >= 48) 249 | j = 0; 250 | for (uint8_t i = 0; i < 48; i++) { 251 | LEDRing1.LEDRing_Set_RGB(i, fade1_table[temp]); 252 | temp++; 253 | if (temp >= 48) 254 | temp = 0; 255 | } 256 | break; 257 | 258 | case 4: 259 | temp = j++; 260 | if (j >= 48) 261 | j = 0; 262 | for (uint8_t i = 0; i < 48; i++) { 263 | LEDRing1.LEDRing_Set_RGB(i, fade2_table[temp]); 264 | temp++; 265 | if (temp >= 48) 266 | temp = 0; 267 | } 268 | break; 269 | } 270 | } 271 | } 272 | -------------------------------------------------------------------------------- /examples/RGB LED Ring/LEDRing_Demo/LEDRing_Demo.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include "LEDRing.h" 3 | 4 | 5 | /* 6 | Board Pinout 7 | +-----+--------+----------+-------------+ 8 | | Pin | Color | Function | Arduino pin | 9 | +-----+--------+----------+-------------+ 10 | | 1 | Red | VCC | +5V | 11 | | 2 | Black | GND | GND | 12 | | 3 | Yellow | VIO | +5V | 13 | | 4 | Green | SDA | A4 | 14 | | 5 | Blue | SCL | A5 | 15 | +-----+--------+----------+-------------+ 16 | */ 17 | 18 | const uint32_t fade1_table[48] = {0x8011EE, 0x900AE5, 0xA004DA, 0xB001CD, 0xBF00BF, 0xCD01B0, 0xDA04A0, 0xE50A90, 0xEE1180, 0xF51A6F, 0xFB255F, 0xFE324F, 0xFF4040, 0xFE4F32, 0xFB5F25, 0xF56F1A, 0xEE8011, 0xE5900A, 0xDAA004, 0xCDB001, 0xBFBF00, 0xB0CD01, 0xA0DA04, 0x90E50A, 0x80EE11, 0x6FF51A, 0x5FFB25, 0x4FFE32, 0x40FF40, 0x32FE4F, 0x25FB5F, 0x1AF56F, 0x11EE80, 0x0AE590, 0x04DAA0, 0x01CDB0, 0x00BFBF, 0x01B0CD, 0x04A0DA, 0x0A90E5, 0x1180EE, 0x1A6FF5, 0x255FFB, 0x324FFE, 0x4040FF, 0x4F32FE, 0x5F25FB, 0x6F1AF5, }; 19 | const uint32_t fade2_table[48] = {0xFF0000, 0xFF0001, 0xFF0004, 0xFF000E, 0xFF0020, 0xFF003E, 0xFF006B, 0xFF00AB, 0xFF00FF, 0xAB00FF, 0x6B00FF, 0x3E00FF, 0x2000FF, 0x0E00FF, 0x0400FF, 0x0100FF, 0x0000FF, 0x0001FF, 0x0004FF, 0x000EFF, 0x0020FF, 0x003EFF, 0x006BFF, 0x00ABFF, 0x00FFFF, 0x00FFAB, 0x00FF6B, 0x00FF3E, 0x00FF20, 0x00FF0E, 0x00FF04, 0x00FF01, 0x00FF00, 0x01FF00, 0x04FF00, 0x0EFF00, 0x20FF00, 0x3EFF00, 0x6BFF00, 0xABFF00, 0xFFFF00, 0xFFAB00, 0xFF6B00, 0xFF3E00, 0xFF2000, 0xFF0E00, 0xFF0400, 0xFF0100, }; 20 | static uint8_t j = 0; 21 | static uint8_t i = 0; 22 | static uint16_t tim = 0; 23 | static uint8_t r = 5, g = 8, b = 20, rg = 40, br = 35, bg = 17; 24 | 25 | LEDRing LEDRing(ISSI3745_SJ1 | ISSI3745_SJ5); //Only SJ1 and SJ5 are soldered in this example 26 | // Also check if there are the pull-UP resistors on the I2C bus. If no or the board doesn't want to work please also solder the jumper SJ9 27 | 28 | void setup(void) { 29 | 30 | Wire.begin(); 31 | Wire.setClock(400000); 32 | LEDRing.LEDRing_Reset(); 33 | delay(20); 34 | 35 | LEDRing.LEDRing_Configuration(0x01); //Normal operation 36 | LEDRing.LEDRing_SpreadSpectrum(0b0010110); 37 | LEDRing.LEDRing_GlobalCurrent(0xFf); // maximum current output 38 | LEDRing.LEDRing_SetScaling(0xFF); 39 | 40 | LEDRing.LEDRing_PWM_MODE(); 41 | } 42 | 43 | void loop() { 44 | 45 | for (i = 0; i < 48; i++) { 46 | LEDRing.LEDRing_Set_RED(i, 0xff); 47 | delay(15); 48 | } 49 | 50 | for (i = 0; i < 48; i++) { 51 | LEDRing.LEDRing_Set_RED(i, 0); 52 | LEDRing.LEDRing_Set_GREEN(i, 0xff); 53 | delay(15); 54 | } 55 | 56 | for (i = 0; i < 48; i++) { 57 | LEDRing.LEDRing_Set_GREEN(i, 0); 58 | LEDRing.LEDRing_Set_BLUE(i, 0xff); 59 | delay(15); 60 | } 61 | 62 | for (i = 0; i < 48; i++) { 63 | 64 | LEDRing.LEDRing_Set_RGB(i, 0x6600CC); 65 | delay(15); 66 | } 67 | 68 | for (i = 0; i < 48; i++) { 69 | 70 | LEDRing.LEDRing_Set_RGB(i, 0xFF9933); 71 | delay(15); 72 | } 73 | 74 | for (i = 0; i < 48; i++) { 75 | 76 | LEDRing.LEDRing_Set_RGB(i, 0xFFFFFF); 77 | delay(15); 78 | } 79 | 80 | LEDRing.LEDRing_ClearAll(); 81 | 82 | 83 | for (tim = 0; tim < 2000; tim++) { 84 | 85 | 86 | 87 | if ((tim % 5) == 0) { 88 | LEDRing.LEDRing_Set_RED(r, 0); 89 | r = r + 1; 90 | if (r >= 48) 91 | r = 0; 92 | LEDRing.LEDRing_Set_RED(r, 0xFF); 93 | } 94 | 95 | if ((tim % 6) == 0) { 96 | LEDRing.LEDRing_Set_GREEN(g, 0); 97 | g = g + 1; 98 | if (g >= 48) 99 | g = 0; 100 | LEDRing.LEDRing_Set_GREEN(g, 0xFF); 101 | } 102 | 103 | if ((tim % 8) == 0) { 104 | LEDRing.LEDRing_Set_BLUE(b, 0); 105 | b = b + 1; 106 | if (b >= 48) 107 | b = 0; 108 | LEDRing.LEDRing_Set_BLUE(b, 0xFF); 109 | } 110 | 111 | 112 | if ((tim % 7) == 0) { 113 | LEDRing.LEDRing_Set_BLUE(br, 0); 114 | LEDRing.LEDRing_Set_RED(br, 0); 115 | br = br + 1; 116 | if (br >= 48) 117 | br = 0; 118 | LEDRing.LEDRing_Set_BLUE(br, 0xFF); 119 | LEDRing.LEDRing_Set_RED(br, 0xFF); 120 | } 121 | 122 | 123 | if ((tim % 10) == 0) { 124 | LEDRing.LEDRing_Set_BLUE(bg, 0); 125 | LEDRing.LEDRing_Set_GREEN(bg, 0); 126 | bg = bg + 1; 127 | if (bg >= 48) 128 | bg = 0; 129 | LEDRing.LEDRing_Set_BLUE(bg, 0xFF); 130 | LEDRing.LEDRing_Set_GREEN(bg, 0xFF); 131 | } 132 | 133 | if ((tim % 11) == 0) { 134 | LEDRing.LEDRing_Set_RED(rg, 0); 135 | LEDRing.LEDRing_Set_GREEN(rg, 0); 136 | rg = rg + 1; 137 | if (rg >= 48) 138 | rg = 0; 139 | LEDRing.LEDRing_Set_RED(rg, 0xFF); 140 | LEDRing.LEDRing_Set_GREEN(rg, 0xFF); 141 | } 142 | 143 | delay(5); 144 | } 145 | 146 | 147 | for (tim = 0; tim < 100; tim++) { 148 | j = tim % 48; 149 | 150 | for (i = 0; i < 48; i++) { 151 | LEDRing.LEDRing_Set_RGB(i, fade1_table[j]); 152 | j++; 153 | if (j >= 48) 154 | j = 0; 155 | } 156 | delay(20); 157 | } 158 | 159 | for (tim = 0; tim < 100; tim++) { 160 | j = tim % 48; 161 | for (i = 0; i < 48; i++) { 162 | LEDRing.LEDRing_Set_RGB(i, fade2_table[j]); 163 | j++; 164 | if (j >= 48) 165 | j = 0; 166 | } 167 | delay(20); 168 | } 169 | 170 | for (i = 0xff; i > 0; i--) { 171 | 172 | LEDRing.LEDRing_GlobalCurrent(i); 173 | delay(10); 174 | } 175 | LEDRing.LEDRing_ClearAll(); 176 | LEDRing.LEDRing_GlobalCurrent(0xff); 177 | delay(1000); 178 | LEDRing.LEDRing_PWM_MODE(); 179 | 180 | } -------------------------------------------------------------------------------- /examples/RGB LED Ring/README.md: -------------------------------------------------------------------------------- 1 | # RGB LED Ring Arduino Library 2 | 3 | -------------------------------------------------------------------------------- 4 | 5 | ## Introduction 6 | 7 | Here you can find the project description of the [RGB LED Ring Small](https://github.com/Fattoresaimon/RGB_LED_Ring). 8 | The RGB LED Ring is based on the driver ISSI [IS31FL3745](https://www.lumissil.com/assets/pdf/core/IS31FL3745_DS.pdf), for more functionality please check the datasheet of the driver. 9 | At the moment the breathing effect are not implemented. 10 | 11 | The RGB LED Ring is available on [DuPPa Store!](https://www.duppa.net/shop/rgb-led-ring/) 12 | 13 | ## Initialization of the class 14 | 15 | The library makes available the class **LEDRing** 16 | To initialize the library, you have to declare an instance of the class **LEDRing** for each LED Ring. 17 | For example: 18 | 19 | ``` C++ 20 | LEDRing LEDRing(ISSI3745_SJ1 | ISSI3745_SJ5); 21 | ``` 22 | Declaration of the RGB LED Ring with the jumper SJ1 and SJ5 soldered. 23 | The RGB LED Ring v1.1 it have 8 Jumpers for setting the address, they are divided in 2 groups of 4 jumpers. Only 1 jumper per group should be soldered, this make 16 possible combinations. 24 | Possible combination are the following: 25 | 26 | | Jumper first group | Jumper second group | I2C Address | 27 | | ------------ | ------------ | :--: | 28 | | ISSI3745_SJ1 | ISSI3745_SJ5 | 0x40 | 29 | | ISSI3745_SJ2 | ISSI3745_SJ5 | 0x42 | 30 | | ISSI3745_SJ3 | ISSI3745_SJ5 | 0x44 | 31 | | ISSI3745_SJ4 | ISSI3745_SJ5 | 0x46 | 32 | | ISSI3745_SJ1 | ISSI3745_SJ6 | 0x48 | 33 | | ISSI3745_SJ2 | ISSI3745_SJ6 | 0x4A | 34 | | ISSI3745_SJ3 | ISSI3745_SJ6 | 0x4C | 35 | | ISSI3745_SJ4 | ISSI3745_SJ6 | 0x4E | 36 | | ISSI3745_SJ1 | ISSI3745_SJ7 | 0x50 | 37 | | ISSI3745_SJ2 | ISSI3745_SJ7 | 0x52 | 38 | | ISSI3745_SJ3 | ISSI3745_SJ7 | 0x54 | 39 | | ISSI3745_SJ4 | ISSI3745_SJ7 | 0x56 | 40 | | ISSI3745_SJ1 | ISSI3745_SJ8 | 0x58 | 41 | | ISSI3745_SJ2 | ISSI3745_SJ8 | 0x5A | 42 | | ISSI3745_SJ3 | ISSI3745_SJ8 | 0x5C | 43 | | ISSI3745_SJ4 | ISSI3745_SJ8 | 0x5E | 44 | 45 | 46 | 47 | ## Configuration 48 | 49 | ### void LEDRing_Reset(void) 50 | Reset all the IS31FL3745 to the default state 51 | 52 | ### void LEDRing_Configuration(uint8_t conf) 53 | This method write the register ad the address 00h of the IS31FL3745. Please refer the datasheet for further information. 54 | 55 | ### void LEDRing_GlobalCurrent(uint8_t conf) 56 | This method write the register 01h and it set the LEDs current. 57 | It's possible to set up to 256 step from 0 to 0xFF. 58 | Higher value make the LEDs brighter. 59 | 60 | ### void LEDRing_SetScaling(uint8_t led_n, uint8_t scal); 61 | Set the output current of each led. **n** is the LED number ( 1 to 144 ), **scal** is the scaling value (0 to 256) 62 | 63 | ### void LEDRing_SetScaling(uint8_t scal); 64 | Set the output current of all LED. **scal** is the scaling value (0 to 256) 65 | 66 | ### void LEDRing_PULLUP_DOWN(uint8_t pull) 67 | Configure the PULLUP and PULLDOWN resistor. You can refer to the IS31FL3745 datasheet at the 02h register for further information. 68 | 69 | ### uint8_t LEDRing_Temperature(void); 70 | Get the temperature status register. Refer to the IS31FL3745 datasheet at the 24h register for further information. 71 | 72 | ### void LEDRing_PWM_MODE(void) 73 | This method set all the LEDs in PWM mode. 74 | 75 | ### void LEDRing_ClearAll(void) 76 | This method set the PWM value to 0 for each LED. 77 | 78 | ### void LEDRing_Set_RGB(uint8_t led_n, uint32_t color) 79 | Set the RGB color for a specific LED. 80 | **n** is the LED number ( 0 to 47 ), while the **color** is the RGB color in 24bit format. 81 | 82 | #### Examples: 83 | 84 | ```C++ 85 | LEDRing.LEDRing_Set_RGB(10, 0xFF9933); 86 | ``` 87 | 88 | ### void LEDRing_Set_RED(uint8_t led_n, uint8_t color) 89 | ### void LEDRing_Set_GREEN(uint8_t led_n, uint8_t color) 90 | ### void LEDRing_Set_BLUE(uint8_t led_n, uint8_t color) 91 | 92 | Set a specific color to a specific LED 93 | **n** is the LED number ( 0 to 47 ), while the **color** is the color in 8bit format. 94 | 95 | #### Examples: 96 | 97 | ```C++ 98 | LEDRing.LEDRing_Set_RED(4, 128); 99 | LEDRing.LEDRing_Set_GREEN(5, 200); 100 | LEDRing.LEDRing_Set_BLUE(6, 80); 101 | ``` 102 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For DuppaLibrary 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | i2cEncoderLibV2 KEYWORD1 i2cEncoderLibV2 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | begin KEYWORD2 16 | reset KEYWORD2 17 | attachInterrupt KEYWORD2 18 | deattachInterrupt KEYWORD2 19 | autoconfigInterrupt KEYWORD2 20 | readGP1conf KEYWORD2 21 | readGP2conf KEYWORD2 22 | readGP3conf KEYWORD2 23 | readInterruptConfig KEYWORD2 24 | updateStatus KEYWORD2 25 | readStatus KEYWORD2 26 | readInt2 KEYWORD2 27 | readFadeStatus KEYWORD2 28 | readCounterFloat KEYWORD2 29 | readCounterLong KEYWORD2 30 | readCounterInt KEYWORD2 31 | readCounterByte KEYWORD2 32 | readMax KEYWORD2 33 | readMaxFloat KEYWORD2 34 | readMin KEYWORD2 35 | readMinFloat KEYWORD2 36 | readStep KEYWORD2 37 | readStepFloat KEYWORD2 38 | readLEDR KEYWORD2 39 | readLEDG KEYWORD2 40 | readLEDB KEYWORD2 41 | readGP1 KEYWORD2 42 | readGP2 KEYWORD2 43 | readGP3 KEYWORD2 44 | readAntibouncingPeriod KEYWORD2 45 | readDoublePushPeriod KEYWORD2 46 | readFadeRGB KEYWORD2 47 | readFadeGP KEYWORD2 48 | readEEPROM KEYWORD2 49 | writeGP1conf KEYWORD2 50 | writeGP2conf KEYWORD2 51 | writeGP3conf KEYWORD2 52 | writeInterruptConfig KEYWORD2 53 | writeCounter KEYWORD2 54 | writeMax KEYWORD2 55 | writeMin KEYWORD2 56 | writeStep KEYWORD2 57 | writeLEDR KEYWORD2 58 | writeLEDG KEYWORD2 59 | writeLEDB KEYWORD2 60 | writeRGBCode KEYWORD2 61 | writeGP1 KEYWORD2 62 | writeGP2 KEYWORD2 63 | writeGP3 KEYWORD2 64 | writeAntibouncingPeriod KEYWORD2 65 | writeDoublePushPeriod KEYWORD2 66 | writeFadeRGB KEYWORD2 67 | writeFadeGP KEYWORD2 68 | writeEEPROM KEYWORD2 69 | writeGammaRLED KEYWORD2 70 | writeGammaGLED KEYWORD2 71 | writeGammaBLED KEYWORD2 72 | writeGammaGP1 KEYWORD2 73 | writeGammaGP2 KEYWORD2 74 | writeGammaGP3 KEYWORD2 75 | readIDCode KEYWORD2 76 | readVersion KEYWORD2 77 | ChangeI2CAddress KEYWORD2 78 | 79 | ####################################### 80 | # Constants (LITERAL1) 81 | ####################################### 82 | 83 | onButtonRelease LITERAL1 84 | onButtonPush LITERAL1 85 | onButtonDoublePush LITERAL1 86 | onIncrement LITERAL1 87 | onDecrement LITERAL1 88 | onChange LITERAL1 89 | onMax LITERAL1 90 | onMin LITERAL1 91 | onMinMax LITERAL1 92 | onGP1Rise LITERAL1 93 | onGP1Fall LITERAL1 94 | onGP2Rise LITERAL1 95 | onGP2Fall LITERAL1 96 | onGP3Rise LITERAL1 97 | onGP3Fall LITERAL1 98 | onFadeProcess LITERAL1 99 | onArrowsPush LITERAL1 100 | onArrowsRelese LITERAL1 101 | onUpPush LITERAL1 102 | onUpRelease LITERAL1 103 | onDownPush LITERAL1 104 | onDownRelease LITERAL1 105 | onRightPush LITERAL1 106 | onRightRelease LITERAL1 107 | onLeftPush LITERAL1 108 | onLeftRelease LITERAL1 109 | onCentralPush LITERAL1 110 | onCentralRelease LITERAL1 111 | onCentralDoublePush LITERAL1 112 | onButtonLongPush LITERAL1 113 | GP_PWM LITERAL1 114 | GP_OUT LITERAL1 115 | GP_AN LITERAL1 116 | GP_IN LITERAL1 117 | GP_PULL_EN LITERAL1 118 | GP_PULL_DI LITERAL1 119 | GP_INT_DI LITERAL1 120 | GP_INT_PE LITERAL1 121 | GP_INT_NE LITERAL1 122 | GP_INT_BE LITERAL1 123 | FADE_R LITERAL1 124 | FADE_G LITERAL1 125 | FADE_B LITERAL1 126 | FADES_GP1 LITERAL1 127 | FADES_GP2 LITERAL1 128 | FADES_GP3 LITERAL1 129 | GP1_POS LITERAL1 130 | GP1_NEG LITERAL1 131 | GP2_POS LITERAL1 132 | GP2_NEG LITERAL1 133 | GP3_POS LITERAL1 134 | GP3_NEG LITERAL1 135 | FADE_INT LITERAL1 136 | PUSHR LITERAL1 137 | PUSHP LITERAL1 138 | PUSHD LITERAL1 139 | RINC LITERAL1 140 | RDEC LITERAL1 141 | RMAX LITERAL1 142 | RMIN LITERAL1 143 | INT2 LITERAL1 144 | FLOAT_DATA LITERAL1 145 | INT_DATA LITERAL1 146 | WRAP_ENABLE LITERAL1 147 | WRAP_DISABLE LITERAL1 148 | DIRE_LEFT LITERAL1 149 | DIRE_RIGHT LITERAL1 150 | IPUP_DISABLE LITERAL1 151 | IPUP_ENABLE LITERAL1 152 | RMOD_X4 LITERAL1 153 | RMOD_X2 LITERAL1 154 | RMOD_X1 LITERAL1 155 | RGB_ENCODER LITERAL1 156 | STD_ENCODER LITERAL1 157 | EEPROM_BANK1 LITERAL1 158 | EEPROM_BANK2 LITERAL1 159 | RESET LITERAL1 160 | GAMMA_OFF LITERAL1 161 | GAMMA_1 LITERAL1 162 | GAMMA_1_8 LITERAL1 163 | GAMMA_2 LITERAL1 164 | GAMMA_2_2 LITERAL1 165 | GAMMA_2_4 LITERAL1 166 | GAMMA_2_6 LITERAL1 167 | GAMMA_2_8 LITERAL1 168 | CLK_STRECH_ENABLE LITERAL1 169 | CLK_STRECH_DISABLE LITERAL1 170 | REL_MODE_ENABLE LITERAL1 171 | REL_MODE_DISABLE LITERAL1 172 | REG_IDCODE LITERAL1 173 | REG_VERSION LITERAL1 174 | UPR LITERAL1 175 | UPP LITERAL1 176 | DNR LITERAL1 177 | DNP LITERAL1 178 | RTR LITERAL1 179 | RTP LITERAL1 180 | LTR LITERAL1 181 | LTP LITERAL1 182 | CTRR LITERAL1 183 | CTRP LITERAL1 184 | CTRDP LITERAL1 185 | RINC LITERAL1 186 | RDEC LITERAL1 187 | RMAX LITERAL1 188 | RMIN LITERAL1 189 | INT_2 LITERAL1 -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=DuPPa Library 2 | version=1.2.0 3 | author=DuPPa 4 | maintainer=DuPPa 5 | sentence=Allow the comunication with the I2C Encoder V2 board 6 | paragraph=This library is used with the I2C Encoder V2 board. This board allow the use of the rotary encoder on the i2c bus 7 | category=Device Control 8 | url=https://github.com/Fattoresaimon/I2CEncoderV2 9 | architectures=* 10 | -------------------------------------------------------------------------------- /src/LEDRing.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: LEDRing.c 3 | // VERSION: 1.2.. 4 | // PURPOSE: Library for LEDRing from DUPPA. chip used IS31FL3745 5 | // LICENSE: GPL v3 (http://www.gnu.org/licenses/gpl.html) 6 | // 7 | // DATASHEET: https://www.lumissil.com/assets/pdf/core/IS31FL3745_DS.pdf 8 | // 9 | // URL: 10 | // 11 | // AUTHOR: 12 | // Simone Caron 13 | // 14 | 15 | #include "LEDRing.h" 16 | #include 17 | 18 | LEDRing::LEDRing(uint8_t add) { 19 | _add = add; 20 | 21 | } 22 | 23 | 24 | void LEDRing::LEDRing_PWM_MODE(void) { 25 | selectBank(ISSI3745_PAGE0); 26 | } 27 | 28 | void LEDRing::LEDRing_Configuration(uint8_t conf) { 29 | selectBank(ISSI3745_PAGE2); 30 | writeRegister8(ISSI3745_CONFIGURATION, conf); 31 | } 32 | 33 | void LEDRing::LEDRing_SetScaling(uint8_t led_n, uint8_t scal) { 34 | selectBank(ISSI3745_PAGE1); 35 | writeRegister8(led_n, scal); 36 | } 37 | 38 | void LEDRing::LEDRing_SetScaling(uint8_t scal) { 39 | selectBank(ISSI3745_PAGE1); 40 | 41 | for (uint8_t i = 1; i < 145; i++) { 42 | writeRegister8(i, scal); 43 | } 44 | } 45 | 46 | void LEDRing::LEDRing_GlobalCurrent(uint8_t curr) { 47 | selectBank(ISSI3745_PAGE2); 48 | writeRegister8(ISSI3745_GLOBALCURRENT, curr); 49 | } 50 | 51 | void LEDRing::LEDRing_PULLUP_DOWN(uint8_t pull) { 52 | selectBank(ISSI3745_PAGE2); 53 | writeRegister8(ISSI3745_PULLUPDOWM, pull); 54 | } 55 | 56 | uint8_t LEDRing::LEDRing_Temperature(void) { 57 | selectBank(ISSI3745_PAGE2); 58 | return (readRegister8(ISSI3745_TEMPERATURE)); 59 | } 60 | 61 | void LEDRing::LEDRing_SpreadSpectrum(uint8_t spread) { 62 | selectBank(ISSI3745_PAGE2); 63 | writeRegister8(ISSI3745_SPREADSPECTRUM, spread); 64 | } 65 | 66 | void LEDRing::LEDRing_Reset(void) { 67 | selectBank(ISSI3745_PAGE2); 68 | writeRegister8(ISSI3745_RESET_REG, 0xAE); 69 | 70 | } 71 | 72 | void LEDRing::LEDRing_Set_RGB(uint8_t led_n, uint32_t color) { 73 | 74 | writeRegister8(issi_led_map[0][led_n], ((color >> 16) & 0xFF)); 75 | writeRegister8(issi_led_map[1][led_n], ((color >> 8) & 0xFF)); 76 | writeRegister8(issi_led_map[2][led_n], (color & 0xFF)); 77 | 78 | } 79 | 80 | void LEDRing::LEDRing_Set_RED(uint8_t led_n, uint8_t color) { 81 | 82 | writeRegister8(issi_led_map[0][led_n], color); 83 | 84 | } 85 | 86 | void LEDRing::LEDRing_Set_GREEN(uint8_t led_n, uint8_t color) { 87 | 88 | writeRegister8(issi_led_map[1][led_n], color); 89 | } 90 | 91 | void LEDRing::LEDRing_Set_BLUE(uint8_t led_n, uint8_t color) { 92 | 93 | writeRegister8(issi_led_map[2][led_n], color); 94 | 95 | } 96 | 97 | 98 | void LEDRing::LEDRing_ClearAll(void) { 99 | uint8_t i; 100 | 101 | LEDRing_PWM_MODE(); 102 | 103 | for (i = 1; i < 145; i++) { 104 | writeRegister8(i,0); 105 | } 106 | 107 | } 108 | 109 | void LEDRing::selectBank(uint8_t b) { 110 | writeRegister8(ISSI3745_COMMANDREGISTER_LOCK, ISSI3745_ULOCK_CODE); 111 | writeRegister8(ISSI3745_COMMANDREGISTER, b); 112 | } 113 | 114 | void LEDRing::writeRegister8(uint8_t reg, uint8_t data) { 115 | Wire.beginTransmission(_add); 116 | Wire.write(reg); 117 | Wire.write(data); 118 | Wire.endTransmission(); 119 | } 120 | 121 | void LEDRing::writeBuff(uint8_t reg, uint8_t *data, uint8_t dim) { 122 | Wire.beginTransmission(_add); 123 | Wire.write(reg); 124 | Wire.write(data, dim); 125 | Wire.endTransmission(); 126 | 127 | } 128 | 129 | uint8_t LEDRing::readRegister8(uint8_t reg) { 130 | byte rdata = 0xFF; 131 | 132 | Wire.beginTransmission(_add); 133 | Wire.write(reg); 134 | Wire.endTransmission(); 135 | Wire.requestFrom(_add, (uint8_t) 1); 136 | if (Wire.available()) { 137 | rdata = Wire.read(); 138 | } 139 | return rdata; 140 | } 141 | -------------------------------------------------------------------------------- /src/LEDRing.h: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: LEDRing.h 3 | // VERSION: 1.2.. 4 | // PURPOSE: Library for LEDRing from DUPPA. chip used IS31FL3745 5 | // LICENSE: GPL v3 (http://www.gnu.org/licenses/gpl.html) 6 | // 7 | // DATASHEET: https://www.lumissil.com/assets/pdf/core/IS31FL3745_DS.pdf 8 | // 9 | // URL: 10 | // 11 | // AUTHOR: 12 | // Simone Caron 13 | // 14 | 15 | #ifndef LEDRing_H 16 | #define LEDRing_H 17 | 18 | #if (ARDUINO >= 100) 19 | #include 20 | #else 21 | #include 22 | #endif 23 | 24 | #define ISSI3745_PAGE0 0x00 25 | #define ISSI3745_PAGE1 0x01 26 | #define ISSI3745_PAGE2 0x02 27 | 28 | #define ISSI3745_COMMANDREGISTER 0xFD 29 | #define ISSI3745_COMMANDREGISTER_LOCK 0xFE 30 | #define ISSI3745_ULOCK_CODE 0xC5 31 | 32 | #define ISSI3745_CONFIGURATION 0x00 33 | #define ISSI3745_GLOBALCURRENT 0x01 34 | #define ISSI3745_PULLUPDOWM 0x02 35 | #define ISSI3745_OPENSHORT 0x03 36 | #define ISSI3745_TEMPERATURE 0x24 37 | #define ISSI3745_SPREADSPECTRUM 0x25 38 | #define ISSI3745_RESET_REG 0x2F 39 | 40 | 41 | #define ISSI3745_SJ1 0b0100000 42 | #define ISSI3745_SJ2 0b0100001 43 | #define ISSI3745_SJ3 0b0100010 44 | #define ISSI3745_SJ4 0b0100011 45 | #define ISSI3745_SJ5 0b0100000 46 | #define ISSI3745_SJ6 0b0100100 47 | #define ISSI3745_SJ7 0b0101000 48 | #define ISSI3745_SJ8 0b0101100 49 | 50 | 51 | 52 | 53 | 54 | class LEDRing { 55 | public: 56 | 57 | LEDRing(uint8_t add); 58 | void LEDRing_PWM_MODE(void); 59 | void LEDRing_Configuration(uint8_t conf); 60 | void LEDRing_SetScaling(uint8_t led_n, uint8_t scal); 61 | void LEDRing_SetScaling(uint8_t scal); 62 | void LEDRing_GlobalCurrent(uint8_t curr); 63 | void LEDRing_PULLUP_DOWN(uint8_t pull); 64 | uint8_t LEDRing_Temperature(void); 65 | void LEDRing_SpreadSpectrum(uint8_t spread); 66 | void LEDRing_Reset(void); 67 | 68 | void LEDRing_Set_RGB(uint8_t led_n, uint32_t color); 69 | void LEDRing_Set_RED(uint8_t led_n, uint8_t color); 70 | void LEDRing_Set_GREEN(uint8_t led_n, uint8_t color); 71 | void LEDRing_Set_BLUE(uint8_t led_n, uint8_t color); 72 | void LEDRing_ClearAll(void); 73 | 74 | private: 75 | const uint8_t issi_led_map[3][48] = { 76 | {0x12, 0x24, 0x36, 0x48, 0x5A, 0x6C, 0x7E, 0x90, 0xF, 0x21, 0x33, 0x45, 0x57, 0x69, 0x7B, 0x8D, 0xC, 0x1E, 0x30, 0x42, 0x54, 0x66, 0x78, 0x8A, 0x9, 0x1B, 0x2D, 0x3F, 0x51, 0x63, 0x75, 0x87, 0x6, 0x18, 0x2A, 0x3C, 0x4E, 0x60, 0x72, 0x84, 0x3, 0x15, 0x27, 0x39, 0x4B, 0x5D, 0x6F, 0x81}, // Red 77 | {0x11, 0x23, 0x35, 0x47, 0x59, 0x6B, 0x7D, 0x8F, 0xE, 0x20, 0x32, 0x44, 0x56, 0x68, 0x7A, 0x8C, 0xB, 0x1D, 0x2F, 0x41, 0x53, 0x65, 0x77, 0x89, 0x8, 0x1A, 0x2C, 0x3E, 0x50, 0x62, 0x74, 0x86, 0x5, 0x17, 0x29, 0x3B, 0x4D, 0x5F, 0x71, 0x83, 0x2, 0x14, 0x26, 0x38, 0x4A, 0x5C, 0x6E, 0x80}, //Green 78 | {0x10, 0x22, 0x34, 0x46, 0x58, 0x6A, 0x7C, 0x8E, 0xD, 0x1F, 0x31, 0x43, 0x55, 0x67, 0x79, 0x8B, 0xA, 0x1C, 0x2E, 0x40, 0x52, 0x64, 0x76, 0x88, 0x7, 0x19, 0x2B, 0x3D, 0x4F, 0x61, 0x73, 0x85, 0x4, 0x16, 0x28, 0x3A, 0x4C, 0x5E, 0x70, 0x82, 0x1, 0x13, 0x25, 0x37, 0x49, 0x5B, 0x6D, 0x7F} //Blue 79 | }; 80 | 81 | uint8_t _add; 82 | void selectBank(uint8_t b); 83 | void writeRegister8(uint8_t reg, uint8_t data); 84 | void writeBuff(uint8_t reg, uint8_t *data, uint8_t dim); 85 | uint8_t readRegister8(uint8_t reg); 86 | }; 87 | #endif 88 | -------------------------------------------------------------------------------- /src/LEDRingSmall.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: LEDRingSmall.c 3 | // VERSION: 1.2.. 4 | // PURPOSE: Library for LEDRingSmall from DUPPA. chip used IS31FL3746A 5 | // LICENSE: GPL v3 (http://www.gnu.org/licenses/gpl.html) 6 | // 7 | // DATASHEET: https://www.lumissil.com/assets/pdf/core/IS31FL3746A_DS.pdf 8 | // 9 | // URL: 10 | // 11 | // AUTHOR: 12 | // Simone Caron 13 | // 14 | 15 | 16 | 17 | #include "LEDRingSmall.h" 18 | #include 19 | 20 | LEDRingSmall::LEDRingSmall(uint8_t add) { 21 | _add = add; 22 | } 23 | 24 | void LEDRingSmall::LEDRingSmall_PWM_MODE(void) { 25 | selectBank(ISSI3746_PAGE0); 26 | } 27 | 28 | void LEDRingSmall::LEDRingSmall_Configuration(uint8_t conf) { 29 | selectBank(ISSI3746_PAGE1); 30 | writeRegister8(ISSI3746_CONFIGURATION, conf); 31 | } 32 | 33 | void LEDRingSmall::LEDRingSmall_SetScaling(uint8_t led_n, uint8_t scal) { 34 | selectBank(ISSI3746_PAGE1); 35 | writeRegister8(led_n, scal); 36 | } 37 | 38 | void LEDRingSmall::LEDRingSmall_SetScaling(uint8_t scal) { 39 | selectBank(ISSI3746_PAGE1); 40 | 41 | for (uint8_t i = 1; i < 73; i++) { 42 | writeRegister8(i, scal); 43 | } 44 | } 45 | 46 | void LEDRingSmall::LEDRingSmall_GlobalCurrent(uint8_t curr) { 47 | selectBank(ISSI3746_PAGE1); 48 | writeRegister8(ISSI3746_GLOBALCURRENT, curr); 49 | } 50 | 51 | void LEDRingSmall::LEDRingSmall_PULLUP_DOWN(uint8_t pull) { 52 | selectBank(ISSI3746_PAGE1); 53 | writeRegister8(ISSI3746_PULLUPDOWM, pull); 54 | } 55 | 56 | 57 | uint8_t LEDRingSmall::LEDRingSmall_Temperature(void) { 58 | selectBank(ISSI3746_PAGE1); 59 | return(readRegister8(ISSI3746_TEMPERATURE)); 60 | } 61 | 62 | void LEDRingSmall::LEDRingSmall_SpreadSpectrum(uint8_t spread) { 63 | selectBank(ISSI3746_PAGE1); 64 | writeRegister8(ISSI3746_SPREADSPECTRUM, spread); 65 | } 66 | 67 | void LEDRingSmall::LEDRingSmall_Reset(void) { 68 | selectBank(ISSI3746_PAGE1); 69 | writeRegister8(ISSI3746_RESET_REG, 0xAE); 70 | } 71 | 72 | void LEDRingSmall::LEDRingSmall_PWMFrequencyEnable(uint8_t PWMenable) { 73 | selectBank(ISSI3746_PAGE1); 74 | writeRegister8(ISSI3746_PWM_FREQUENCY_ENABLE, PWMenable); 75 | } 76 | 77 | void LEDRingSmall::LEDRingSmall_PWMFrequencySetting(uint8_t pwmfreq) { 78 | selectBank(ISSI3746_PAGE1); 79 | writeRegister8(ISSI3746_PWM_FREQUENCY_SET, pwmfreq); 80 | } 81 | 82 | 83 | void LEDRingSmall::LEDRingSmall_Set_RGB(uint8_t led_n, uint32_t color) { 84 | 85 | writeRegister8(issi_led_map[0][led_n], ((color >> 16) & 0xFF)); 86 | writeRegister8(issi_led_map[1][led_n], ((color >> 8) & 0xFF)); 87 | writeRegister8(issi_led_map[2][led_n], (color & 0xFF)); 88 | } 89 | 90 | void LEDRingSmall::LEDRingSmall_Set_RED(uint8_t led_n, uint8_t color) { 91 | 92 | writeRegister8(issi_led_map[0][led_n], color); 93 | } 94 | 95 | void LEDRingSmall::LEDRingSmall_Set_GREEN(uint8_t led_n, uint8_t color) { 96 | 97 | writeRegister8(issi_led_map[1][led_n], color); 98 | 99 | } 100 | 101 | void LEDRingSmall::LEDRingSmall_Set_BLUE(uint8_t led_n, uint8_t color) { 102 | 103 | writeRegister8(issi_led_map[2][led_n], color); 104 | } 105 | 106 | void LEDRingSmall::LEDRingSmall_ClearAll(void) { 107 | uint8_t i; 108 | LEDRingSmall_PWM_MODE(); 109 | 110 | for (i = 1; i < 73; i++) { 111 | writeRegister8(i,0); 112 | } 113 | 114 | } 115 | 116 | 117 | void LEDRingSmall::selectBank(uint8_t b) { 118 | writeRegister8(ISSI3746_COMMANDREGISTER_LOCK, ISSI3746_ULOCK_CODE); 119 | writeRegister8(ISSI3746_COMMANDREGISTER, b); 120 | } 121 | 122 | void LEDRingSmall::writeRegister8(uint8_t reg, uint8_t data) { 123 | Wire.beginTransmission(_add); 124 | Wire.write(reg); 125 | Wire.write(data); 126 | Wire.endTransmission(); 127 | } 128 | 129 | void LEDRingSmall::writeBuff(uint8_t reg, uint8_t *data, uint8_t dim) { 130 | Wire.beginTransmission(_add); 131 | Wire.write(reg); 132 | Wire.write(data, dim); 133 | Wire.endTransmission(); 134 | } 135 | 136 | uint8_t LEDRingSmall::readRegister8(uint8_t reg) { 137 | byte rdata = 0xFF; 138 | 139 | Wire.beginTransmission(_add); 140 | Wire.write(reg); 141 | Wire.endTransmission(); 142 | Wire.requestFrom(_add, (uint8_t) 1); 143 | if (Wire.available()) { 144 | rdata = Wire.read(); 145 | } 146 | return rdata; 147 | } 148 | -------------------------------------------------------------------------------- /src/LEDRingSmall.h: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: LEDRingSmall.h 3 | // VERSION: 1.2.. 4 | // PURPOSE: Library for LEDRingSmall from DUPPA. chip used IS31FL3746A 5 | // LICENSE: GPL v3 (http://www.gnu.org/licenses/gpl.html) 6 | // 7 | // DATASHEET: https://www.lumissil.com/assets/pdf/core/IS31FL3746A_DS.pdf 8 | // 9 | // URL: 10 | // 11 | // AUTHOR: 12 | // Simone Caron 13 | // 14 | 15 | 16 | #ifndef LEDRingSmall_H 17 | #define LEDRingSmall_H 18 | 19 | #if (ARDUINO >= 100) 20 | #include 21 | #else 22 | #include 23 | #endif 24 | 25 | #define ISSI3746_PAGE0 0x00 26 | #define ISSI3746_PAGE1 0x01 27 | 28 | 29 | #define ISSI3746_COMMANDREGISTER 0xFD 30 | #define ISSI3746_COMMANDREGISTER_LOCK 0xFE 31 | #define ISSI3746_ID_REGISTER 0xFC 32 | #define ISSI3746_ULOCK_CODE 0xC5 33 | 34 | #define ISSI3746_CONFIGURATION 0x50 35 | #define ISSI3746_GLOBALCURRENT 0x51 36 | #define ISSI3746_PULLUPDOWM 0x52 37 | #define ISSI3746_OPENSHORT 0x53 38 | #define ISSI3746_TEMPERATURE 0x5F 39 | #define ISSI3746_SPREADSPECTRUM 0x60 40 | #define ISSI3746_RESET_REG 0x8F 41 | #define ISSI3746_PWM_FREQUENCY_ENABLE 0xE0 42 | #define ISSI3746_PWM_FREQUENCY_SET 0xE2 43 | 44 | 45 | #define ISSI3746_SJ1 0b1100000 46 | #define ISSI3746_SJ2 0b1100001 47 | #define ISSI3746_SJ3 0b1100010 48 | #define ISSI3746_SJ4 0b1100011 49 | #define ISSI3746_SJ5 0b1100000 50 | #define ISSI3746_SJ6 0b1100100 51 | #define ISSI3746_SJ7 0b1101000 52 | #define ISSI3746_SJ8 0b1101100 53 | 54 | 55 | class LEDRingSmall { 56 | public: 57 | 58 | LEDRingSmall(uint8_t add); 59 | void LEDRingSmall_PWM_MODE(void); 60 | void LEDRingSmall_Configuration(uint8_t conf); 61 | void LEDRingSmall_SetScaling(uint8_t led_n, uint8_t scal); 62 | void LEDRingSmall_SetScaling(uint8_t scal); 63 | void LEDRingSmall_GlobalCurrent(uint8_t curr); 64 | void LEDRingSmall_PULLUP_DOWN(uint8_t pull); 65 | uint8_t LEDRingSmall_Temperature(void); 66 | void LEDRingSmall_SpreadSpectrum(uint8_t spread); 67 | void LEDRingSmall_Reset(void); 68 | void LEDRingSmall_PWMFrequencyEnable(uint8_t PWMenable); 69 | void LEDRingSmall_PWMFrequencySetting(uint8_t pwmfreq); 70 | 71 | void LEDRingSmall_Set_RGB(uint8_t led_n, uint32_t color); 72 | void LEDRingSmall_Set_RED(uint8_t led_n, uint8_t color); 73 | void LEDRingSmall_Set_GREEN(uint8_t led_n, uint8_t color); 74 | void LEDRingSmall_Set_BLUE(uint8_t led_n, uint8_t color); 75 | void LEDRingSmall_ClearAll(void); 76 | 77 | private: 78 | const uint8_t issi_led_map[3][24] = { 79 | {0x48, 0x36, 0x24, 0x12, 0x45, 0x33, 0x21, 0x0F, 0x42, 0x30, 0x1E, 0x0C, 0x3F, 0x2D, 0x1B, 0x09, 0x3C, 0x2A, 0x18, 0x06, 0x39, 0x27, 0x15, 0x03}, // Red 80 | {0x47, 0x35, 0x23, 0x11, 0x44, 0x32, 0x20, 0x0E, 0x41, 0x2F, 0x1D, 0x0B, 0x3E, 0x2C, 0x1A, 0x08, 0x3B, 0x29, 0x17, 0x05, 0x38, 0x26, 0x14, 0x02}, //Green 81 | {0x46, 0x34, 0x22, 0x10, 0x43, 0x31, 0x1F, 0x0D, 0x40, 0x2E, 0x1C, 0x0A, 0x3D, 0x2B, 0x19, 0x07, 0x3A, 0x28, 0x16, 0x04, 0x37, 0x25, 0x13, 0x01}, //Blue 82 | }; 83 | 84 | uint8_t _add; 85 | void selectBank(uint8_t b); 86 | void writeRegister8(uint8_t reg, uint8_t data); 87 | void writeBuff(uint8_t reg, uint8_t *data, uint8_t dim); 88 | uint8_t readRegister8(uint8_t reg); 89 | }; 90 | #endif 91 | -------------------------------------------------------------------------------- /src/i2cEncoderLibV2.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: i2cEncoderLibV2.h 3 | // VERSION: 1.0.. 4 | // PURPOSE: Library for I2C Encoder V2.1 board with Arduino 5 | // LICENSE: GPL v3 (http://www.gnu.org/licenses/gpl.html) 6 | // 7 | // DATASHEET: 8 | // 9 | // URL: 10 | // 11 | // AUTHOR: 12 | // Simone Caron 13 | // 14 | 15 | #include "i2cEncoderLibV2.h" 16 | #include 17 | 18 | /*********************************** Public functions *************************************/ 19 | /** Class costructor **/ 20 | i2cEncoderLibV2::i2cEncoderLibV2(uint8_t add) { 21 | _add = add; 22 | } 23 | 24 | /** Used for initialize the encoder **/ 25 | void i2cEncoderLibV2::begin(uint16_t conf) { 26 | 27 | writeEncoder(REG_GCONF, (uint8_t)( conf & 0xFF)); 28 | writeEncoder(REG_GCONF2, (uint8_t)((conf >> 8) & 0xFF)); 29 | _gconf = conf; 30 | if ((conf & CLK_STRECH_ENABLE) == 0) 31 | _clockstreach = 0; 32 | else 33 | _clockstreach = 1; 34 | } 35 | 36 | /** Reset the board **/ 37 | void i2cEncoderLibV2::reset(void) { 38 | writeEncoder(REG_GCONF, (uint8_t) 0x80); 39 | delay(10); 40 | } 41 | 42 | /** Call che attached callaback if it is defined. It's a prive function only **/ 43 | void i2cEncoderLibV2::eventCaller(Callback *event) { 44 | if (*event != NULL) 45 | (*event)(this); 46 | } 47 | 48 | /** Return true if the status of the econder changed, otherwise return false. 49 | It's also call the callback, if attached **/ 50 | bool i2cEncoderLibV2::updateStatus(void) { 51 | 52 | _stat = readEncoderByte(REG_ESTATUS); 53 | _stat2 = 0; 54 | if (_stat == 0) { 55 | return false; 56 | } 57 | 58 | if (_stat & PUSHR) { 59 | eventCaller (&onButtonRelease); 60 | } 61 | if (_stat & PUSHP) { 62 | eventCaller (&onButtonPush); 63 | } 64 | if (_stat & PUSHD) { 65 | eventCaller (&onButtonDoublePush); 66 | } 67 | if (_stat & RINC) { 68 | eventCaller (&onIncrement); 69 | eventCaller (&onChange); 70 | } 71 | if (_stat & RDEC) { 72 | eventCaller (&onDecrement); 73 | eventCaller (&onChange); 74 | } 75 | if (_stat & RMAX) { 76 | eventCaller (&onMax); 77 | eventCaller (&onMinMax); 78 | } 79 | if (_stat & RMIN) { 80 | eventCaller (&onMin); 81 | eventCaller (&onMinMax); 82 | } 83 | 84 | if ((_stat & INT_2) != 0) { 85 | _stat2 = readEncoderByte(REG_I2STATUS); 86 | if (_stat2 == 0) { 87 | return true; 88 | } 89 | 90 | if (_stat2 & GP1_POS) { 91 | eventCaller (&onGP1Rise); 92 | } 93 | if (_stat2 & GP1_NEG) { 94 | eventCaller (&onGP1Fall); 95 | } 96 | if (_stat2 & GP2_POS) { 97 | eventCaller (&onGP2Rise); 98 | } 99 | if (_stat2 & GP2_NEG) { 100 | eventCaller (&onGP2Fall); 101 | } 102 | if (_stat2 & GP3_POS) { 103 | eventCaller (&onGP3Rise); 104 | } 105 | if (_stat2 & GP3_NEG) { 106 | eventCaller (&onGP3Fall); 107 | } 108 | if (_stat2 & FADE_INT) { 109 | eventCaller (&onFadeProcess); 110 | } 111 | } 112 | 113 | return true; 114 | } 115 | 116 | /*********************************** Read functions *************************************/ 117 | 118 | /** Return the GP1 Configuration**/ 119 | uint8_t i2cEncoderLibV2::readGP1conf(void) { 120 | return (readEncoderByte(REG_GP1CONF)); 121 | } 122 | 123 | /** Return the GP1 Configuration**/ 124 | uint8_t i2cEncoderLibV2::readGP2conf(void) { 125 | return (readEncoderByte(REG_GP2CONF)); 126 | } 127 | 128 | /** Return the GP1 Configuration**/ 129 | uint8_t i2cEncoderLibV2::readGP3conf(void) { 130 | return (readEncoderByte(REG_GP3CONF)); 131 | } 132 | 133 | /** Return the INT pin configuration**/ 134 | uint8_t i2cEncoderLibV2::readInterruptConfig(void) { 135 | return (readEncoderByte(REG_INTCONF)); 136 | } 137 | 138 | /** Check if a particular status match, return true is match otherwise false. Before require updateStatus() **/ 139 | bool i2cEncoderLibV2::readStatus(Int_Status s) { 140 | if ((_stat & s) != 0) { 141 | return true; 142 | } 143 | return false; 144 | } 145 | 146 | /** Return the status of the encoder **/ 147 | uint8_t i2cEncoderLibV2::readStatus(void) { 148 | return _stat; 149 | } 150 | 151 | /** Check if a particular status of the Int2 match, return true is match otherwise false. Before require updateStatus() **/ 152 | bool i2cEncoderLibV2::readInt2(Int2_Status s) { 153 | if ((_stat2 & s) != 0) { 154 | return true; 155 | } 156 | return false; 157 | } 158 | 159 | /** Return the Int2 status of the encoder. Before require updateStatus() **/ 160 | uint8_t i2cEncoderLibV2::readInt2(void) { 161 | return _stat2; 162 | } 163 | 164 | /** Return Fade process status **/ 165 | uint8_t i2cEncoderLibV2::readFadeStatus(void) { 166 | return readEncoderByte(REG_FSTATUS); 167 | } 168 | 169 | /** Check if a particular status of the Fade process match, return true is match otherwise false. **/ 170 | bool i2cEncoderLibV2::readFadeStatus(Fade_Status s) { 171 | if ((readEncoderByte(REG_FSTATUS) & s) == 1) 172 | return true; 173 | 174 | return false; 175 | } 176 | 177 | /** Return the PWM LED R value **/ 178 | uint8_t i2cEncoderLibV2::readLEDR(void) { 179 | return ((uint8_t) readEncoderByte(REG_RLED)); 180 | } 181 | 182 | /** Return the PWM LED G value **/ 183 | uint8_t i2cEncoderLibV2::readLEDG(void) { 184 | return ((uint8_t) readEncoderByte(REG_GLED)); 185 | } 186 | 187 | /** Return the PWM LED B value **/ 188 | uint8_t i2cEncoderLibV2::readLEDB(void) { 189 | return ((uint8_t) readEncoderByte(REG_BLED)); 190 | } 191 | 192 | /** Return the 32 bit value of the encoder counter **/ 193 | float i2cEncoderLibV2::readCounterFloat(void) { 194 | return (readEncoderFloat(REG_CVALB4)); 195 | } 196 | 197 | /** Return the 32 bit value of the encoder counter **/ 198 | int32_t i2cEncoderLibV2::readCounterLong(void) { 199 | return ((int32_t) readEncoderLong(REG_CVALB4)); 200 | } 201 | 202 | /** Return the 16 bit value of the encoder counter **/ 203 | int16_t i2cEncoderLibV2::readCounterInt(void) { 204 | return ((int16_t) readEncoderInt(REG_CVALB2)); 205 | } 206 | 207 | /** Return the 8 bit value of the encoder counter **/ 208 | int8_t i2cEncoderLibV2::readCounterByte(void) { 209 | return ((int8_t) readEncoderByte(REG_CVALB1)); 210 | } 211 | 212 | /** Return the Maximum threshold of the counter **/ 213 | int32_t i2cEncoderLibV2::readMax(void) { 214 | return ((int32_t) readEncoderLong(REG_CMAXB4)); 215 | } 216 | 217 | /** Return the Minimum threshold of the counter **/ 218 | int32_t i2cEncoderLibV2::readMin(void) { 219 | return ((int32_t) readEncoderLong(REG_CMINB4)); 220 | } 221 | 222 | /** Return the Maximum threshold of the counter **/ 223 | float i2cEncoderLibV2::readMaxFloat(void) { 224 | return (readEncoderFloat(REG_CMAXB4)); 225 | } 226 | 227 | /** Return the Minimum threshold of the counter **/ 228 | float i2cEncoderLibV2::readMinFloat(void) { 229 | return (readEncoderFloat(REG_CMINB4)); 230 | 231 | } 232 | 233 | /** Return the Steps increment **/ 234 | int32_t i2cEncoderLibV2::readStep(void) { 235 | return (readEncoderInt(REG_ISTEPB4)); 236 | } 237 | 238 | /** Return the Steps increment, in float variable **/ 239 | float i2cEncoderLibV2::readStepFloat(void) { 240 | return (readEncoderFloat(REG_ISTEPB4)); 241 | 242 | } 243 | 244 | /** Read GP1 register value **/ 245 | uint8_t i2cEncoderLibV2::readGP1(void) { 246 | return (readEncoderByte(REG_GP1REG)); 247 | } 248 | 249 | /** Read GP2 register value **/ 250 | uint8_t i2cEncoderLibV2::readGP2(void) { 251 | return (readEncoderByte(REG_GP2REG)); 252 | } 253 | 254 | /** Read GP3 register value **/ 255 | uint8_t i2cEncoderLibV2::readGP3(void) { 256 | return (readEncoderByte(REG_GP3REG)); 257 | } 258 | 259 | /** Read Anti-bouncing period register **/ 260 | uint8_t i2cEncoderLibV2::readAntibouncingPeriod(void) { 261 | return (readEncoderByte(REG_ANTBOUNC)); 262 | } 263 | 264 | /** Read Double push period register **/ 265 | uint8_t i2cEncoderLibV2::readDoublePushPeriod(void) { 266 | return (readEncoderByte(REG_DPPERIOD)); 267 | } 268 | 269 | /** Read the fade period of the RGB LED**/ 270 | uint8_t i2cEncoderLibV2::readFadeRGB(void) { 271 | return (readEncoderByte(REG_FADERGB)); 272 | } 273 | 274 | /** Read the fade period of the GP LED**/ 275 | uint8_t i2cEncoderLibV2::readFadeGP(void) { 276 | return (readEncoderByte(REG_FADEGP)); 277 | } 278 | 279 | /** Read the ID code **/ 280 | uint8_t i2cEncoderLibV2::readIDCode(void) { 281 | return (readEncoderByte(REG_IDCODE)); 282 | } 283 | 284 | /** Read the Version code **/ 285 | uint8_t i2cEncoderLibV2::readVersion(void) { 286 | return (readEncoderByte(REG_VERSION)); 287 | } 288 | 289 | /** Read the EEPROM memory**/ 290 | uint8_t i2cEncoderLibV2::readEEPROM(uint8_t add) { 291 | if (add <= 0x7f) { 292 | if ((_gconf & EEPROM_BANK1) != 0) { 293 | _gconf = _gconf & 0xBF; 294 | writeEncoder(REG_GCONF, _gconf); 295 | } 296 | return (readEncoderByte((REG_EEPROMS + add))); 297 | } else { 298 | if ((_gconf & EEPROM_BANK1) == 0) { 299 | _gconf = _gconf | 0x40; 300 | writeEncoder(REG_GCONF, _gconf); 301 | } 302 | return (readEncoderByte(add)); 303 | } 304 | } 305 | 306 | /*********************************** Write functions *************************************/ 307 | /** Write the GP1 configuration**/ 308 | void i2cEncoderLibV2::writeGP1conf(uint8_t gp1) { 309 | writeEncoder(REG_GP1CONF, (uint8_t) gp1); 310 | } 311 | 312 | /** Write the GP2 configuration**/ 313 | void i2cEncoderLibV2::writeGP2conf(uint8_t gp2) { 314 | writeEncoder(REG_GP2CONF, (uint8_t) gp2); 315 | } 316 | 317 | /** Write the GP3 configuration**/ 318 | void i2cEncoderLibV2::writeGP3conf(uint8_t gp3) { 319 | writeEncoder(REG_GP3CONF, (uint8_t) gp3); 320 | } 321 | 322 | /** Write the interrupt configuration **/ 323 | void i2cEncoderLibV2::writeInterruptConfig(uint8_t interrupt) { 324 | writeEncoder(REG_INTCONF, (uint8_t) interrupt); 325 | } 326 | 327 | /** Check if there is some attached callback and enable the corresponding interrupt **/ 328 | void i2cEncoderLibV2::autoconfigInterrupt(void) { 329 | uint8_t reg=0; 330 | 331 | if (onButtonRelease != NULL) 332 | reg |= PUSHR; 333 | 334 | if (onButtonPush != NULL) 335 | reg |= PUSHP; 336 | 337 | if (onButtonDoublePush != NULL) 338 | reg |= PUSHD; 339 | 340 | if (onIncrement != NULL) 341 | reg |= RINC; 342 | 343 | if (onDecrement != NULL) 344 | reg |= RDEC; 345 | 346 | if (onChange != NULL) { 347 | reg |= RINC; 348 | reg |= RDEC; 349 | } 350 | 351 | if (onMax != NULL) 352 | reg |= RMAX; 353 | 354 | if (onMin != NULL) 355 | reg |= RMIN; 356 | 357 | if (onMinMax != NULL) { 358 | reg |= RMAX; 359 | reg |= RMIN; 360 | } 361 | 362 | if (onGP1Rise != NULL) 363 | reg |= INT_2; 364 | 365 | if (onGP1Fall != NULL) 366 | reg |= INT_2; 367 | 368 | if (onGP2Rise != NULL) 369 | reg |= INT_2; 370 | 371 | if (onGP2Fall != NULL) 372 | reg |= INT_2; 373 | 374 | if (onGP3Rise != NULL) 375 | reg |= INT_2; 376 | 377 | if (onGP3Fall != NULL) 378 | reg |= INT_2; 379 | 380 | if (onFadeProcess != NULL) 381 | reg |= INT_2; 382 | 383 | writeEncoder(REG_INTCONF, (uint8_t) reg); 384 | } 385 | 386 | /** Write the counter value **/ 387 | void i2cEncoderLibV2::writeCounter(int32_t value) { 388 | writeEncoder(REG_CVALB4, value); 389 | } 390 | 391 | /** Write the counter value **/ 392 | void i2cEncoderLibV2::writeCounter(float value) { 393 | writeEncoder(REG_CVALB4, value); 394 | } 395 | 396 | /** Write the maximum threshold value **/ 397 | void i2cEncoderLibV2::writeMax(int32_t max) { 398 | writeEncoder(REG_CMAXB4, max); 399 | } 400 | 401 | /** Write the maximum threshold value **/ 402 | void i2cEncoderLibV2::writeMax(float max) { 403 | writeEncoder(REG_CMAXB4, max); 404 | } 405 | 406 | /** Write the minimum threshold value **/ 407 | void i2cEncoderLibV2::writeMin(int32_t min) { 408 | writeEncoder(REG_CMINB4, min); 409 | } 410 | 411 | /** Write the minimum threshold value **/ 412 | void i2cEncoderLibV2::writeMin(float min) { 413 | writeEncoder(REG_CMINB4, min); 414 | } 415 | 416 | /** Write the Step increment value **/ 417 | void i2cEncoderLibV2::writeStep(int32_t step) { 418 | writeEncoder(REG_ISTEPB4, step); 419 | } 420 | 421 | /** Write the Step increment value **/ 422 | void i2cEncoderLibV2::writeStep(float step) { 423 | writeEncoder(REG_ISTEPB4, step); 424 | } 425 | 426 | /** Write the PWM value of the RGB LED red **/ 427 | void i2cEncoderLibV2::writeLEDR(uint8_t rled) { 428 | writeEncoder(REG_RLED, rled); 429 | } 430 | 431 | /** Write the PWM value of the RGB LED green **/ 432 | void i2cEncoderLibV2::writeLEDG(uint8_t gled) { 433 | writeEncoder(REG_GLED, gled); 434 | } 435 | 436 | /** Write the PWM value of the RGB LED blue **/ 437 | void i2cEncoderLibV2::writeLEDB(uint8_t bled) { 438 | writeEncoder(REG_BLED, bled); 439 | } 440 | 441 | /** Write 24bit color code **/ 442 | void i2cEncoderLibV2::writeRGBCode(uint32_t rgb) { 443 | writeEncoder24bit(REG_RLED, rgb); 444 | } 445 | 446 | /** Write GP1 register, used when GP1 is set to output or PWM **/ 447 | void i2cEncoderLibV2::writeGP1(uint8_t gp1) { 448 | writeEncoder(REG_GP1REG, gp1); 449 | } 450 | 451 | /** Write GP2 register, used when GP2 is set to output or PWM **/ 452 | void i2cEncoderLibV2::writeGP2(uint8_t gp2) { 453 | writeEncoder(REG_GP2REG, gp2); 454 | } 455 | 456 | /** Write GP3 register, used when GP3 is set to output or PWM **/ 457 | void i2cEncoderLibV2::writeGP3(uint8_t gp3) { 458 | writeEncoder(REG_GP3REG, gp3); 459 | } 460 | 461 | /** Write Anti-bouncing period register **/ 462 | void i2cEncoderLibV2::writeAntibouncingPeriod(uint8_t bounc) { 463 | writeEncoder(REG_ANTBOUNC, bounc); 464 | } 465 | 466 | /** Write Anti-bouncing period register **/ 467 | void i2cEncoderLibV2::writeDoublePushPeriod(uint8_t dperiod) { 468 | writeEncoder(REG_DPPERIOD, dperiod); 469 | } 470 | 471 | /** Write Fade timing in ms **/ 472 | void i2cEncoderLibV2::writeFadeRGB(uint8_t fade) { 473 | writeEncoder(REG_FADERGB, fade); 474 | } 475 | 476 | /** Write Fade timing in ms **/ 477 | void i2cEncoderLibV2::writeFadeGP(uint8_t fade) { 478 | writeEncoder(REG_FADEGP, fade); 479 | } 480 | 481 | /** Write the Gamma value on RLED **/ 482 | void i2cEncoderLibV2::writeGammaRLED(GAMMA_PARAMETER Gamma) { 483 | writeEncoder(REG_GAMRLED, (uint8_t) Gamma); 484 | } 485 | 486 | /** Write the Gamma value on GLED **/ 487 | void i2cEncoderLibV2::writeGammaGLED(GAMMA_PARAMETER Gamma) { 488 | writeEncoder(REG_GAMGLED, (uint8_t) Gamma); 489 | } 490 | 491 | /** Write the Gamma value on BLED **/ 492 | void i2cEncoderLibV2::writeGammaBLED(GAMMA_PARAMETER Gamma) { 493 | writeEncoder(REG_GAMBLED, (uint8_t) Gamma); 494 | } 495 | 496 | /** Write the Gamma value on GP1 **/ 497 | void i2cEncoderLibV2::writeGammaGP1(GAMMA_PARAMETER Gamma) { 498 | writeEncoder(REG_GAMMAGP1, (uint8_t) Gamma); 499 | } 500 | 501 | /** Write the Gamma value on GP2 **/ 502 | void i2cEncoderLibV2::writeGammaGP2(GAMMA_PARAMETER Gamma) { 503 | writeEncoder(REG_GAMMAGP2, (uint8_t) Gamma); 504 | } 505 | 506 | /** Write the Gamma value on GP1 **/ 507 | void i2cEncoderLibV2::writeGammaGP3(GAMMA_PARAMETER Gamma) { 508 | writeEncoder(REG_GAMMAGP3, (uint8_t) Gamma); 509 | } 510 | 511 | /** Write the EEPROM memory**/ 512 | void i2cEncoderLibV2::writeEEPROM(uint8_t add, uint8_t data) { 513 | 514 | if (add <= 0x7f) { 515 | if ((_gconf & EEPROM_BANK1) != 0) { 516 | _gconf = _gconf & 0xBF; 517 | writeEncoder(REG_GCONF, _gconf); 518 | } 519 | writeEncoder((REG_EEPROMS + add), data); 520 | } else { 521 | if ((_gconf & EEPROM_BANK1) == 0) { 522 | _gconf = _gconf | 0x40; 523 | writeEncoder(REG_GCONF, _gconf); 524 | } 525 | writeEncoder(add, data); 526 | } 527 | 528 | if (_clockstreach == 0) 529 | delay(5); 530 | } 531 | 532 | /*********************************** Private functions *************************************/ 533 | /***************************** Read function to the encoder ********************************/ 534 | 535 | /** Read 1 byte from the encoder **/ 536 | uint8_t i2cEncoderLibV2::readEncoderByte(uint8_t reg) { 537 | byte rdata = 0xFF; 538 | 539 | Wire.beginTransmission(_add); 540 | Wire.write(reg); 541 | Wire.endTransmission(); 542 | Wire.requestFrom(_add, (uint8_t) 1); 543 | if (Wire.available()) { 544 | rdata = Wire.read(); 545 | } 546 | return rdata; 547 | } 548 | 549 | /** Read 2 bytes from the encoder **/ 550 | int16_t i2cEncoderLibV2::readEncoderInt(uint8_t reg) { 551 | Wire.beginTransmission(_add); 552 | Wire.write(reg); 553 | Wire.endTransmission(); 554 | Wire.requestFrom(_add, (uint8_t) 4); 555 | if (Wire.available()) { 556 | _tem_data.bval[1] = Wire.read(); 557 | _tem_data.bval[0] = Wire.read(); 558 | } 559 | return ((int16_t) _tem_data.val); 560 | } 561 | 562 | /** Read 4 bytes from the encoder **/ 563 | int32_t i2cEncoderLibV2::readEncoderLong(uint8_t reg) { 564 | 565 | Wire.beginTransmission(_add); 566 | Wire.write(reg); 567 | Wire.endTransmission(); 568 | Wire.requestFrom(_add, (uint8_t) 4); 569 | if (Wire.available()) { 570 | _tem_data.bval[3] = Wire.read(); 571 | _tem_data.bval[2] = Wire.read(); 572 | _tem_data.bval[1] = Wire.read(); 573 | _tem_data.bval[0] = Wire.read(); 574 | } 575 | return ((int32_t) _tem_data.val); 576 | } 577 | 578 | /** Read 4 bytes from the encoder **/ 579 | float i2cEncoderLibV2::readEncoderFloat(uint8_t reg) { 580 | Wire.beginTransmission(_add); 581 | Wire.write(reg); 582 | Wire.endTransmission(); 583 | Wire.requestFrom(_add, (uint8_t) 4); 584 | if (Wire.available()) { 585 | _tem_data.bval[3] = Wire.read(); 586 | _tem_data.bval[2] = Wire.read(); 587 | _tem_data.bval[1] = Wire.read(); 588 | _tem_data.bval[0] = Wire.read(); 589 | } 590 | return ((float) _tem_data.fval); 591 | } 592 | 593 | /***************************** Write function to the encoder ********************************/ 594 | /** Send to the encoder 1 byte **/ 595 | void i2cEncoderLibV2::writeEncoder(uint8_t reg, uint8_t data) { 596 | 597 | Wire.beginTransmission(_add); 598 | Wire.write(reg); 599 | Wire.write(data); 600 | Wire.endTransmission(); 601 | } 602 | 603 | /** Send to the encoder 4 byte **/ 604 | void i2cEncoderLibV2::writeEncoder(uint8_t reg, int32_t data) { 605 | uint8_t temp[4]; 606 | _tem_data.val = data; 607 | temp[0] = _tem_data.bval[3]; 608 | temp[1] = _tem_data.bval[2]; 609 | temp[2] = _tem_data.bval[1]; 610 | temp[3] = _tem_data.bval[0]; 611 | Wire.beginTransmission(_add); 612 | Wire.write(reg); 613 | Wire.write(temp, (uint8_t) 4); 614 | Wire.endTransmission(); 615 | } 616 | 617 | /** Send to the encoder 4 byte for floating number **/ 618 | void i2cEncoderLibV2::writeEncoder(uint8_t reg, float data) { 619 | 620 | uint8_t temp[4]; 621 | _tem_data.fval = data; 622 | temp[0] = _tem_data.bval[3]; 623 | temp[1] = _tem_data.bval[2]; 624 | temp[2] = _tem_data.bval[1]; 625 | temp[3] = _tem_data.bval[0]; 626 | Wire.beginTransmission(_add); 627 | Wire.write(reg); 628 | Wire.write(temp, (uint8_t) 4); 629 | Wire.endTransmission(); 630 | 631 | } 632 | 633 | /** Send to the encoder 3 byte **/ 634 | void i2cEncoderLibV2::writeEncoder24bit(uint8_t reg, uint32_t data) { 635 | uint8_t temp[3]; 636 | _tem_data.val = data; 637 | temp[0] = _tem_data.bval[2]; 638 | temp[1] = _tem_data.bval[1]; 639 | temp[2] = _tem_data.bval[0]; 640 | Wire.beginTransmission(_add); 641 | Wire.write(reg); 642 | Wire.write(temp, (uint8_t) 3); 643 | Wire.endTransmission(); 644 | 645 | } 646 | -------------------------------------------------------------------------------- /src/i2cEncoderLibV2.h: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: i2cEncoderLibV2.h 3 | // VERSION: 0.1.. 4 | // PURPOSE: Libreary for the i2c encoder board with arduinp 5 | // LICENSE: GPL v3 (http://www.gnu.org/licenses/gpl.html) 6 | // 7 | // DATASHEET: 8 | // 9 | // URL: 10 | // 11 | // AUTHOR: 12 | // Simone Caron 13 | // 14 | 15 | #ifndef i2cEncoderLibV2_H 16 | #define i2cEncoderLibV2_H 17 | 18 | #if (ARDUINO >= 100) 19 | #include 20 | #else 21 | #include 22 | #endif 23 | 24 | class i2cEncoderLibV2 { 25 | public: 26 | 27 | /*Encoder register definition*/ 28 | enum I2C_Register { 29 | REG_GCONF = 0x00, 30 | REG_GP1CONF = 0x01, 31 | REG_GP2CONF = 0x02, 32 | REG_GP3CONF = 0x03, 33 | REG_INTCONF = 0x04, 34 | REG_ESTATUS = 0x05, 35 | REG_I2STATUS = 0x06, 36 | REG_FSTATUS = 0x07, 37 | REG_CVALB4 = 0x08, 38 | REG_CVALB3 = 0x09, 39 | REG_CVALB2 = 0x0A, 40 | REG_CVALB1 = 0x0B, 41 | REG_CMAXB4 = 0x0C, 42 | REG_CMAXB3 = 0x0D, 43 | REG_CMAXB2 = 0x0E, 44 | REG_CMAXB1 = 0x0F, 45 | REG_CMINB4 = 0x10, 46 | REG_CMINB3 = 0x11, 47 | REG_CMINB2 = 0x12, 48 | REG_CMINB1 = 0x13, 49 | REG_ISTEPB4 = 0x14, 50 | REG_ISTEPB3 = 0x15, 51 | REG_ISTEPB2 = 0x16, 52 | REG_ISTEPB1 = 0x17, 53 | REG_RLED = 0x18, 54 | REG_GLED = 0x19, 55 | REG_BLED = 0x1A, 56 | REG_GP1REG = 0x1B, 57 | REG_GP2REG = 0x1C, 58 | REG_GP3REG = 0x1D, 59 | REG_ANTBOUNC = 0x1E, 60 | REG_DPPERIOD = 0x1F, 61 | REG_FADERGB = 0x20, 62 | REG_FADEGP = 0x21, 63 | REG_GAMRLED = 0x27, 64 | REG_GAMGLED = 0x28, 65 | REG_GAMBLED = 0x29, 66 | REG_GAMMAGP1 = 0x2A, 67 | REG_GAMMAGP2 = 0x2B, 68 | REG_GAMMAGP3 = 0x2C, 69 | REG_GCONF2 = 0x30, 70 | REG_IDCODE = 0x70, 71 | REG_VERSION = 0x71, 72 | REG_EEPROMS = 0x80, 73 | } I2C1_REGISTER; 74 | 75 | 76 | /* Encoder configuration bit. Use with GCONF */ 77 | enum GCONF_PARAMETER { 78 | FLOAT_DATA = 0x0001, 79 | INT_DATA = 0x0000, 80 | WRAP_ENABLE = 0x0002, 81 | WRAP_DISABLE = 0x0000, 82 | DIRE_LEFT = 0x0004, 83 | DIRE_RIGHT = 0x0000, 84 | IPUP_DISABLE = 0x0008, 85 | IPUP_ENABLE = 0x0000, 86 | RMOD_X2 = 0x0010, 87 | RMOD_X1 = 0x0000, 88 | RGB_ENCODER = 0x0020, 89 | STD_ENCODER = 0x0000, 90 | EEPROM_BANK1 = 0x0040, 91 | EEPROM_BANK2 = 0x0000, 92 | RESET = 0x0080, 93 | CLK_STRECH_ENABLE = 0x0100, 94 | CLK_STRECH_DISABLE = 0x0000, 95 | REL_MODE_ENABLE= 0x0200, 96 | REL_MODE_DISABLE = 0x0000, 97 | }; 98 | 99 | /* Encoder status bits and setting. Use with: INTCONF for set and with ESTATUS for read the bits */ 100 | enum Int_Status { 101 | PUSHR = 0x01, 102 | PUSHP = 0x02, 103 | PUSHD = 0x04, 104 | RINC = 0x08, 105 | RDEC = 0x10, 106 | RMAX = 0x20, 107 | RMIN = 0x40, 108 | INT_2 = 0x80, 109 | 110 | }; 111 | 112 | /* Encoder Int2 bits. Use to read the bits of I2STATUS */ 113 | typedef enum { 114 | GP1_POS = 0x01, 115 | GP1_NEG = 0x02, 116 | GP2_POS = 0x04, 117 | GP2_NEG = 0x08, 118 | GP3_POS = 0x10, 119 | GP3_NEG = 0x20, 120 | FADE_INT = 0x40, 121 | } Int2_Status; 122 | 123 | /* Encoder Fade status bits. Use to read the bits of FSTATUS */ 124 | typedef enum { 125 | FADE_R = 0x01, 126 | FADE_G = 0x02, 127 | FADE_B = 0x04, 128 | FADES_GP1 = 0x08, 129 | FADES_GP2 = 0x10, 130 | FADES_GP3 = 0x20, 131 | } Fade_Status; 132 | 133 | /* GPIO Configuration. Use with GP1CONF,GP2CONF,GP3CONF */ 134 | enum GP_PARAMETER { 135 | GP_PWM = 0x00, 136 | GP_OUT = 0x01, 137 | GP_AN = 0x02, 138 | GP_IN = 0x03, 139 | GP_PULL_EN = 0x04, 140 | GP_PULL_DI = 0x00, 141 | GP_INT_DI = 0x00, 142 | GP_INT_PE = 0x08, 143 | GP_INT_NE = 0x10, 144 | GP_INT_BE = 0x18, 145 | }; 146 | 147 | typedef enum { 148 | GAMMA_OFF = 0, 149 | GAMMA_1 = 1, 150 | GAMMA_1_8 = 2, 151 | GAMMA_2 = 3, 152 | GAMMA_2_2 = 4, 153 | GAMMA_2_4 = 5, 154 | GAMMA_2_6 = 6, 155 | GAMMA_2_8 = 7, 156 | 157 | } GAMMA_PARAMETER; 158 | 159 | union Data_v { 160 | float fval; 161 | int32_t val; 162 | uint8_t bval[4]; 163 | }; 164 | 165 | uint8_t id = 0x00; 166 | typedef void (*Callback)(i2cEncoderLibV2*); 167 | 168 | /* Event */ 169 | Callback onButtonRelease = NULL; 170 | Callback onButtonPush = NULL; 171 | Callback onButtonDoublePush = NULL; 172 | Callback onIncrement = NULL; 173 | Callback onDecrement = NULL; 174 | Callback onChange = NULL; 175 | Callback onMax = NULL; 176 | Callback onMin = NULL; 177 | Callback onMinMax = NULL; 178 | Callback onGP1Rise = NULL; 179 | Callback onGP1Fall = NULL; 180 | Callback onGP2Rise = NULL; 181 | Callback onGP2Fall = NULL; 182 | Callback onGP3Rise = NULL; 183 | Callback onGP3Fall = NULL; 184 | Callback onFadeProcess = NULL; 185 | 186 | /** Configuration methods **/ 187 | i2cEncoderLibV2(uint8_t add); 188 | void begin(uint16_t conf); 189 | void reset(void); 190 | void autoconfigInterrupt(void); 191 | 192 | /** Read functions **/ 193 | uint8_t readGP1conf(void); 194 | uint8_t readGP2conf(void); 195 | uint8_t readGP3conf(void); 196 | uint8_t readInterruptConfig(void); 197 | 198 | /** Status function **/ 199 | bool updateStatus(void); 200 | bool readStatus(Int_Status s); 201 | uint8_t readStatus(void); 202 | 203 | bool readInt2(Int2_Status s); 204 | uint8_t readInt2(void); 205 | 206 | bool readFadeStatus(Fade_Status s); 207 | uint8_t readFadeStatus(void); 208 | 209 | /** Encoder functions **/ 210 | float readCounterFloat(void); 211 | int32_t readCounterLong(void); 212 | int16_t readCounterInt(void); 213 | int8_t readCounterByte(void); 214 | 215 | int32_t readMax(void); 216 | float readMaxFloat(void); 217 | 218 | int32_t readMin(void); 219 | float readMinFloat(void); 220 | 221 | int32_t readStep(void); 222 | float readStepFloat(void); 223 | 224 | /** RGB LED Functions **/ 225 | uint8_t readLEDR(void); 226 | uint8_t readLEDG(void); 227 | uint8_t readLEDB(void); 228 | 229 | /** GP LED Functions **/ 230 | uint8_t readGP1(void); 231 | uint8_t readGP2(void); 232 | uint8_t readGP3(void); 233 | 234 | /** Timing registers **/ 235 | uint8_t readAntibouncingPeriod(void); 236 | uint8_t readDoublePushPeriod(void); 237 | uint8_t readFadeRGB(void); 238 | uint8_t readFadeGP(void); 239 | 240 | uint8_t readIDCode(void); 241 | uint8_t readVersion(void); 242 | 243 | /** EEPROM register **/ 244 | uint8_t readEEPROM(uint8_t add); 245 | 246 | /****** Write functions ********/ 247 | void writeGP1conf(uint8_t gp1); 248 | void writeGP2conf(uint8_t gp2); 249 | void writeGP3conf(uint8_t gp3); 250 | void writeInterruptConfig(uint8_t interrupt); 251 | 252 | /** Encoder functions **/ 253 | void writeCounter(int32_t counter); 254 | void writeCounter(float counter); 255 | 256 | void writeMax(int32_t max); 257 | void writeMax(float max); 258 | 259 | void writeMin(int32_t min); 260 | void writeMin(float min); 261 | 262 | void writeStep(int32_t step); 263 | void writeStep(float step); 264 | 265 | /** RGB LED Functions **/ 266 | void writeLEDR(uint8_t rled); 267 | void writeLEDG(uint8_t gled); 268 | void writeLEDB(uint8_t bled); 269 | void writeRGBCode(uint32_t rgb); 270 | 271 | /** GP LED Functions **/ 272 | void writeGP1(uint8_t gp1); 273 | void writeGP2(uint8_t gp2); 274 | void writeGP3(uint8_t gp3); 275 | 276 | /** Timing registers **/ 277 | void writeAntibouncingPeriod(uint8_t bounc); 278 | void writeDoublePushPeriod(uint8_t dperiod); 279 | void writeFadeRGB(uint8_t fade); 280 | void writeFadeGP(uint8_t fade); 281 | 282 | /** Gamma register **/ 283 | void writeGammaRLED(GAMMA_PARAMETER Gamma); 284 | void writeGammaGLED(GAMMA_PARAMETER Gamma); 285 | void writeGammaBLED(GAMMA_PARAMETER Gamma); 286 | void writeGammaGP1(GAMMA_PARAMETER Gamma); 287 | void writeGammaGP2(GAMMA_PARAMETER Gamma); 288 | void writeGammaGP3(GAMMA_PARAMETER Gamma); 289 | 290 | 291 | /** EEPROM register **/ 292 | void writeEEPROM(uint8_t add, uint8_t data); 293 | 294 | private: 295 | 296 | uint8_t _clockstreach; 297 | uint8_t _add = 0x00; 298 | uint8_t _stat = 0x00; 299 | uint8_t _stat2 = 0x00; 300 | uint8_t _gconf = 0x00; 301 | union Data_v _tem_data; 302 | 303 | void eventCaller(Callback *event); 304 | uint8_t readEncoderByte(uint8_t reg); 305 | int16_t readEncoderInt(uint8_t reg); 306 | int32_t readEncoderLong(uint8_t reg); 307 | float readEncoderFloat(uint8_t reg); 308 | void writeEncoder(uint8_t reg, uint8_t data); 309 | void writeEncoder(uint8_t reg, int32_t data); 310 | void writeEncoder(uint8_t reg, float data); 311 | void writeEncoder24bit(uint8_t reg, uint32_t data); 312 | 313 | }; 314 | 315 | #endif 316 | -------------------------------------------------------------------------------- /src/i2cEncoderMiniLib.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: i2cEncoderMiniLib.h 3 | // VERSION: 0.1.. 4 | // PURPOSE: Library for I2C Encoder Mini board with Arduino 5 | // LICENSE: GPL v3 (http://www.gnu.org/licenses/gpl.html) 6 | // 7 | // DATASHEET: https://github.com/Fattoresaimon/I2CEncoderMini 8 | // 9 | // URL: 10 | // 11 | // AUTHOR: 12 | // Simone Caron 13 | // 14 | 15 | #include "i2cEncoderMiniLib.h" 16 | #include 17 | 18 | /*********************************** Public functions *************************************/ 19 | /** Class costructor **/ 20 | i2cEncoderMiniLib::i2cEncoderMiniLib(uint8_t add) { 21 | address = add; 22 | } 23 | 24 | /** Used for initialize the I2C Encoder Mini **/ 25 | void i2cEncoderMiniLib::begin(uint8_t conf) { 26 | 27 | writeEncoder(REG_GCONF, (uint8_t) conf); 28 | _gconf = conf; 29 | } 30 | 31 | /** Used for reset the I2C Encoder Mini **/ 32 | void i2cEncoderMiniLib::reset(void) { 33 | writeEncoder(REG_GCONF, (uint8_t) 0x80); 34 | delay(10); 35 | } 36 | 37 | /** Call che attached callaback if it is defined. It's a prive function only **/ 38 | void i2cEncoderMiniLib::eventCaller(Callback *event) { 39 | if (*event != NULL) 40 | (*event)(this); 41 | } 42 | 43 | /** Return true if the status of the econder changed, otherwise return false. 44 | It's also call the callback, if attached **/ 45 | bool i2cEncoderMiniLib::updateStatus(void) { 46 | 47 | _stat = readEncoderByte(REG_ESTATUS); 48 | if (_stat == 0) { 49 | return false; 50 | } 51 | 52 | if (_stat & PUSHR) { 53 | eventCaller (&onButtonRelease); 54 | } 55 | if (_stat & PUSHP) { 56 | eventCaller (&onButtonPush); 57 | } 58 | if (_stat & PUSHL) { 59 | eventCaller (&onButtonLongPush); 60 | } 61 | if (_stat & PUSHD) { 62 | eventCaller (&onButtonDoublePush); 63 | } 64 | if (_stat & RINC) { 65 | eventCaller (&onIncrement); 66 | eventCaller (&onChange); 67 | } 68 | if (_stat & RDEC) { 69 | eventCaller (&onDecrement); 70 | eventCaller (&onChange); 71 | } 72 | if (_stat & RMAX) { 73 | eventCaller (&onMax); 74 | eventCaller (&onMinMax); 75 | } 76 | if (_stat & RMIN) { 77 | eventCaller (&onMin); 78 | eventCaller (&onMinMax); 79 | } 80 | 81 | return true; 82 | } 83 | 84 | /*********************************** Read functions *************************************/ 85 | 86 | /** Return the INT pin configuration**/ 87 | uint8_t i2cEncoderMiniLib::readInterruptConfig(void) { 88 | return (readEncoderByte(REG_INTCONF)); 89 | } 90 | 91 | /** Check if a particular status match, return true is match otherwise false. Before require updateStatus() **/ 92 | bool i2cEncoderMiniLib::readStatus(Int_Status s) { 93 | if ((_stat & s) != 0) { 94 | return true; 95 | } 96 | return false; 97 | } 98 | 99 | /** Return the status of the encoder **/ 100 | uint8_t i2cEncoderMiniLib::readStatus(void) { 101 | return _stat; 102 | } 103 | 104 | /** Return the 32 bit value of the encoder counter **/ 105 | int32_t i2cEncoderMiniLib::readCounterLong(void) { 106 | return ((int32_t) readEncoderLong(REG_CVALB4)); 107 | } 108 | 109 | /** Return the 16 bit value of the encoder counter **/ 110 | int16_t i2cEncoderMiniLib::readCounterInt(void) { 111 | return ((int16_t) readEncoderInt(REG_CVALB2)); 112 | } 113 | 114 | /** Return the 8 bit value of the encoder counter **/ 115 | int8_t i2cEncoderMiniLib::readCounterByte(void) { 116 | return ((int8_t) readEncoderByte(REG_CVALB1)); 117 | } 118 | 119 | /** Return the Maximum threshold of the counter **/ 120 | int32_t i2cEncoderMiniLib::readMax(void) { 121 | return ((int32_t) readEncoderLong(REG_CMAXB4)); 122 | } 123 | 124 | /** Return the Minimum threshold of the counter **/ 125 | int32_t i2cEncoderMiniLib::readMin(void) { 126 | return ((int32_t) readEncoderLong(REG_CMINB4)); 127 | } 128 | 129 | /** Return the Steps increment **/ 130 | int32_t i2cEncoderMiniLib::readStep(void) { 131 | return (readEncoderInt(REG_ISTEPB4)); 132 | } 133 | 134 | 135 | /** Read Double push period register **/ 136 | uint8_t i2cEncoderMiniLib::readDoublePushPeriod(void) { 137 | return (readEncoderByte(REG_DPPERIOD)); 138 | } 139 | 140 | /** Read the ID code **/ 141 | uint8_t i2cEncoderMiniLib::readIDCode(void) { 142 | return (readEncoderByte(REG_IDCODE)); 143 | } 144 | 145 | /** Read the Version code **/ 146 | uint8_t i2cEncoderMiniLib::readVersion(void) { 147 | return (readEncoderByte(REG_VERSION)); 148 | } 149 | 150 | /** Read the EEPROM memory**/ 151 | uint8_t i2cEncoderMiniLib::readEEPROM(uint8_t add) { 152 | 153 | return (readEncoderByte(add)); 154 | } 155 | 156 | /*********************************** Write functions *************************************/ 157 | 158 | /** Write the interrupt configuration **/ 159 | void i2cEncoderMiniLib::writeInterruptConfig(uint8_t interrupt) { 160 | writeEncoder(REG_INTCONF, (uint8_t) interrupt); 161 | } 162 | 163 | /** Check if there is some attached callback and enable the corresponding interrupt **/ 164 | void i2cEncoderMiniLib::autoconfigInterrupt(void) { 165 | uint8_t reg=0; 166 | 167 | if (onButtonRelease != NULL) 168 | reg |= PUSHR; 169 | 170 | if (onButtonPush != NULL) 171 | reg |= PUSHP; 172 | 173 | if (onButtonDoublePush != NULL) 174 | reg |= PUSHD; 175 | 176 | if (onButtonLongPush != NULL) 177 | reg |= PUSHL; 178 | 179 | if (onIncrement != NULL) 180 | reg |= RINC; 181 | 182 | if (onDecrement != NULL) 183 | reg |= RDEC; 184 | 185 | if (onChange != NULL) { 186 | reg |= RINC; 187 | reg |= RDEC; 188 | } 189 | 190 | if (onMax != NULL) 191 | reg |= RMAX; 192 | 193 | if (onMin != NULL) 194 | reg |= RMIN; 195 | 196 | if (onMinMax != NULL) { 197 | reg |= RMAX; 198 | reg |= RMIN; 199 | } 200 | 201 | writeEncoder(REG_INTCONF, (uint8_t) reg); 202 | } 203 | 204 | /** Write the counter value **/ 205 | void i2cEncoderMiniLib::writeCounter(int32_t value) { 206 | writeEncoder(REG_CVALB4, value); 207 | } 208 | 209 | /** Write the maximum threshold value **/ 210 | void i2cEncoderMiniLib::writeMax(int32_t max) { 211 | writeEncoder(REG_CMAXB4, max); 212 | } 213 | 214 | /** Write the minimum threshold value **/ 215 | void i2cEncoderMiniLib::writeMin(int32_t min) { 216 | writeEncoder(REG_CMINB4, min); 217 | } 218 | 219 | /** Write the Step increment value **/ 220 | void i2cEncoderMiniLib::writeStep(int32_t step) { 221 | writeEncoder(REG_ISTEPB4, step); 222 | } 223 | 224 | /** Write Double push period register **/ 225 | void i2cEncoderMiniLib::writeDoublePushPeriod(uint8_t dperiod) { 226 | writeEncoder(REG_DPPERIOD, dperiod); 227 | } 228 | 229 | /** Change MiniEncoder I2C address **/ 230 | void i2cEncoderMiniLib::ChangeI2CAddress(uint8_t add) { 231 | writeEncoder(REG_I2CADDRESS, add); 232 | writeEncoder(REG_I2CADDRESS, add); 233 | writeEncoder(REG_I2CADDRESS, add); 234 | delay(100); 235 | } 236 | 237 | /** Write the EEPROM memory**/ 238 | void i2cEncoderMiniLib::writeEEPROM(uint8_t add, uint8_t data) { 239 | 240 | writeEncoder((REG_EEPROMS + add), data); 241 | delay(5); 242 | } 243 | 244 | /*********************************** Private functions *************************************/ 245 | /***************************** Read function to the encoder ********************************/ 246 | 247 | /** Read 1 byte from the encoder **/ 248 | uint8_t i2cEncoderMiniLib::readEncoderByte(uint8_t reg) { 249 | byte rdata = 0xFF; 250 | 251 | Wire.beginTransmission(address); 252 | Wire.write(reg); 253 | Wire.endTransmission(); 254 | Wire.requestFrom(address, (uint8_t) 1); 255 | if (Wire.available()) { 256 | rdata = Wire.read(); 257 | } 258 | return rdata; 259 | } 260 | 261 | /** Read 2 bytes from the encoder **/ 262 | int16_t i2cEncoderMiniLib::readEncoderInt(uint8_t reg) { 263 | Wire.beginTransmission(address); 264 | Wire.write(reg); 265 | Wire.endTransmission(); 266 | Wire.requestFrom(address, (uint8_t) 4); 267 | if (Wire.available()) { 268 | _tem_data.bval[1] = Wire.read(); 269 | _tem_data.bval[0] = Wire.read(); 270 | } 271 | return ((int16_t) _tem_data.val); 272 | } 273 | 274 | /** Read 4 bytes from the encoder **/ 275 | int32_t i2cEncoderMiniLib::readEncoderLong(uint8_t reg) { 276 | 277 | Wire.beginTransmission(address); 278 | Wire.write(reg); 279 | Wire.endTransmission(); 280 | Wire.requestFrom(address, (uint8_t) 4); 281 | if (Wire.available()) { 282 | _tem_data.bval[3] = Wire.read(); 283 | _tem_data.bval[2] = Wire.read(); 284 | _tem_data.bval[1] = Wire.read(); 285 | _tem_data.bval[0] = Wire.read(); 286 | } 287 | return ((int32_t) _tem_data.val); 288 | } 289 | 290 | /***************************** Write function to the encoder ********************************/ 291 | /** Send to the encoder 1 byte **/ 292 | void i2cEncoderMiniLib::writeEncoder(uint8_t reg, uint8_t data) { 293 | 294 | Wire.beginTransmission(address); 295 | Wire.write(reg); 296 | Wire.write(data); 297 | Wire.endTransmission(); 298 | } 299 | 300 | /** Send to the encoder 4 byte **/ 301 | void i2cEncoderMiniLib::writeEncoder(uint8_t reg, int32_t data) { 302 | uint8_t temp[4]; 303 | _tem_data.val = data; 304 | temp[0] = _tem_data.bval[3]; 305 | temp[1] = _tem_data.bval[2]; 306 | temp[2] = _tem_data.bval[1]; 307 | temp[3] = _tem_data.bval[0]; 308 | Wire.beginTransmission(address); 309 | Wire.write(reg); 310 | Wire.write(temp, (uint8_t) 4); 311 | Wire.endTransmission(); 312 | } 313 | -------------------------------------------------------------------------------- /src/i2cEncoderMiniLib.h: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: i2cEncoderMiniLib.h 3 | // VERSION: 0.1.. 4 | // PURPOSE: Libreary for the i2c encoder board with arduinp 5 | // LICENSE: GPL v3 (http://www.gnu.org/licenses/gpl.html) 6 | // 7 | // DATASHEET: 8 | // 9 | // URL: 10 | // 11 | // AUTHOR: 12 | // Simone Caron 13 | // 14 | 15 | #ifndef i2cEncoderMiniLib_H 16 | #define i2cEncoderMiniLib_H 17 | 18 | #if (ARDUINO >= 100) 19 | #include 20 | #else 21 | #include 22 | #endif 23 | 24 | class i2cEncoderMiniLib { 25 | public: 26 | 27 | /*Encoder register definition*/ 28 | enum I2C_Register { 29 | REG_GCONF = 0x00, 30 | REG_INTCONF = 0x01, 31 | REG_ESTATUS = 0x02, 32 | REG_CVALB4 = 0x03, 33 | REG_CVALB3 = 0x04, 34 | REG_CVALB2 = 0x05, 35 | REG_CVALB1 = 0x06, 36 | REG_CMAXB4 = 0x07, 37 | REG_CMAXB3 = 0x08, 38 | REG_CMAXB2 = 0x09, 39 | REG_CMAXB1 = 0x0A, 40 | REG_CMINB4 = 0x0B, 41 | REG_CMINB3 = 0x0C, 42 | REG_CMINB2 = 0x0D, 43 | REG_CMINB1 = 0x0E, 44 | REG_ISTEPB4 = 0x0F, 45 | REG_ISTEPB3 = 0x10, 46 | REG_ISTEPB2 = 0x11, 47 | REG_ISTEPB1 = 0x12, 48 | REG_DPPERIOD = 0x13, 49 | REG_ADDRESS = 0x14, 50 | REG_IDCODE = 0x70, 51 | REG_VERSION = 0x71, 52 | REG_I2CADDRESS = 0x72, 53 | REG_EEPROMS = 0x81, 54 | } I2C1_REGISTER; 55 | 56 | 57 | /* Encoder configuration bit. Use with GCONF */ 58 | enum GCONF_PARAMETER { 59 | WRAP_ENABLE = 0x01, 60 | WRAP_DISABLE = 0x00, 61 | DIRE_LEFT = 0x02, 62 | DIRE_RIGHT = 0x00, 63 | IPUP_ENABLE = 0x04, 64 | IPUP_DISABLE = 0x00, 65 | RMOD_X4 = 0x10, 66 | RMOD_X2 = 0x08, 67 | RMOD_X1 = 0x00, 68 | 69 | RESET = 0x80, 70 | }; 71 | 72 | /* Encoder status bits and setting. Use with: INTCONF for set and with ESTATUS for read the bits */ 73 | enum Int_Status { 74 | PUSHR = 0x01, 75 | PUSHP = 0x02, 76 | PUSHD = 0x04, 77 | PUSHL = 0x08, 78 | RINC = 0x10, 79 | RDEC = 0x20, 80 | RMAX = 0x40, 81 | RMIN = 0x80, 82 | }; 83 | 84 | union Data_v { 85 | int32_t val; 86 | uint8_t bval[4]; 87 | }; 88 | 89 | uint8_t id = 0x00; 90 | uint8_t address = 0x00; 91 | typedef void (*Callback)(i2cEncoderMiniLib*); 92 | 93 | /* Event */ 94 | Callback onButtonRelease = NULL; 95 | Callback onButtonPush = NULL; 96 | Callback onButtonDoublePush = NULL; 97 | Callback onButtonLongPush = NULL; 98 | Callback onIncrement = NULL; 99 | Callback onDecrement = NULL; 100 | Callback onChange = NULL; 101 | Callback onMax = NULL; 102 | Callback onMin = NULL; 103 | Callback onMinMax = NULL; 104 | 105 | 106 | /** Configuration methods **/ 107 | i2cEncoderMiniLib(uint8_t add); 108 | void begin(uint8_t conf); 109 | void reset(void); 110 | void autoconfigInterrupt(void); 111 | 112 | /** Read functions **/ 113 | uint8_t readInterruptConfig(void); 114 | 115 | /** Status function **/ 116 | bool updateStatus(void); 117 | bool readStatus(Int_Status s); 118 | uint8_t readStatus(void); 119 | 120 | /** Encoder functions **/ 121 | int32_t readCounterLong(void); 122 | int16_t readCounterInt(void); 123 | int8_t readCounterByte(void); 124 | int32_t readMax(void); 125 | int32_t readMin(void); 126 | int32_t readStep(void); 127 | 128 | /** Timing registers **/ 129 | uint8_t readDoublePushPeriod(void); 130 | uint8_t readIDCode(void); 131 | uint8_t readVersion(void); 132 | 133 | /** EEPROM register **/ 134 | uint8_t readEEPROM(uint8_t add); 135 | 136 | /****** Write functions ********/ 137 | void writeInterruptConfig(uint8_t interrupt); 138 | 139 | /** Encoder functions **/ 140 | void writeCounter(int32_t counter); 141 | void writeMax(int32_t max); 142 | void writeMin(int32_t min); 143 | void writeStep(int32_t step); 144 | 145 | /** Timing registers **/ 146 | void writeDoublePushPeriod(uint8_t dperiod); 147 | void ChangeI2CAddress(uint8_t add); 148 | /** EEPROM register **/ 149 | void writeEEPROM(uint8_t add, uint8_t data); 150 | 151 | private: 152 | 153 | 154 | uint8_t _stat = 0x00; 155 | uint8_t _gconf = 0x00; 156 | union Data_v _tem_data; 157 | 158 | void eventCaller(Callback *event); 159 | uint8_t readEncoderByte(uint8_t reg); 160 | int16_t readEncoderInt(uint8_t reg); 161 | int32_t readEncoderLong(uint8_t reg); 162 | void writeEncoder(uint8_t reg, uint8_t data); 163 | void writeEncoder(uint8_t reg, int32_t data); 164 | }; 165 | 166 | #endif 167 | -------------------------------------------------------------------------------- /src/i2cNavKey.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: i2cNavKey.h 3 | // VERSION: 0.1.. 4 | // PURPOSE: Library for I2C NavKey V2 board with Arduino 5 | // LICENSE: GPL v3 (http://www.gnu.org/licenses/gpl.html) 6 | // 7 | // DATASHEET: 8 | // 9 | // URL: 10 | // 11 | // AUTHOR: 12 | // Simone Caron 13 | // 14 | 15 | #include "i2cNavKey.h" 16 | #include 17 | 18 | /*********************************** Public functions *************************************/ 19 | /** Class costructor **/ 20 | i2cNavKey::i2cNavKey(uint8_t add) { 21 | _add = add; 22 | } 23 | 24 | /** Used for initialize the NavKey **/ 25 | void i2cNavKey::begin(uint8_t conf) { 26 | 27 | 28 | writeNavKey(REG_GCONF, conf); 29 | _gconf = conf; 30 | 31 | } 32 | void i2cNavKey::reset(void) { 33 | writeNavKey(REG_GCONF, (uint8_t) 0x80); 34 | delay(10); 35 | } 36 | 37 | /** Call che attached callaback if it is defined. It's a prive function only **/ 38 | void i2cNavKey::eventCaller(Callback *event) { 39 | if (*event != NULL) 40 | (*event)(this); 41 | } 42 | 43 | /** Return true if the status of the econder changed, otherwise return false. 44 | It's also call the callback, if attached **/ 45 | bool i2cNavKey::updateStatus(void) { 46 | 47 | _stat = readNavKeyInt(REG_STATUSB2); 48 | 49 | _stat2 = 0; 50 | if (_stat == 0) { 51 | return false; 52 | } 53 | 54 | if (_stat & UPR) { 55 | eventCaller (&onUpRelease); 56 | eventCaller (&onArrowsRelese); 57 | } 58 | if (_stat & UPP) { 59 | eventCaller (&onUpPush); 60 | eventCaller (&onArrowsPush); 61 | } 62 | if (_stat & DNR) { 63 | eventCaller (&onDownRelease); 64 | eventCaller (&onArrowsRelese); 65 | } 66 | if (_stat & DNP) { 67 | eventCaller (&onDownPush); 68 | eventCaller (&onArrowsPush); 69 | } 70 | if (_stat & RTR) { 71 | eventCaller (&onRightRelease); 72 | eventCaller (&onArrowsRelese); 73 | } 74 | if (_stat & RTP) { 75 | eventCaller (&onRightPush); 76 | eventCaller (&onArrowsPush); 77 | } 78 | if (_stat & LTR) { 79 | eventCaller (&onLeftRelease); 80 | eventCaller (&onArrowsRelese); 81 | } 82 | if (_stat & LTP) { 83 | eventCaller (&onLeftPush); 84 | eventCaller (&onArrowsPush); 85 | } 86 | if (_stat & CTRR) { 87 | eventCaller (&onCentralRelease); 88 | } 89 | if (_stat & CTRP) { 90 | eventCaller (&onCentralPush); 91 | } 92 | if (_stat & CTRDP) { 93 | eventCaller (&onCentralDoublePush); 94 | } 95 | if (_stat & RINC) { 96 | eventCaller (&onIncrement); 97 | eventCaller (&onChange); 98 | } 99 | if (_stat & RDEC) { 100 | eventCaller (&onDecrement); 101 | eventCaller (&onChange); 102 | } 103 | if (_stat & RMAX) { 104 | eventCaller (&onMax); 105 | eventCaller (&onMinMax); 106 | } 107 | if (_stat & RMIN) { 108 | eventCaller (&onMin); 109 | eventCaller (&onMinMax); 110 | } 111 | 112 | if ((_stat & INT_2) != 0) { 113 | _stat2 = readNavKeyByte(REG_SSTATUS); 114 | if (_stat2 == 0) { 115 | return true; 116 | } 117 | 118 | if (_stat2 & GP1_POS) { 119 | eventCaller (&onGP1Rise); 120 | } 121 | if (_stat2 & GP1_NEG) { 122 | eventCaller (&onGP1Fall); 123 | } 124 | if (_stat2 & GP2_POS) { 125 | eventCaller (&onGP2Rise); 126 | } 127 | if (_stat2 & GP2_NEG) { 128 | eventCaller (&onGP2Fall); 129 | } 130 | if (_stat2 & GP3_POS) { 131 | eventCaller (&onGP3Rise); 132 | } 133 | if (_stat2 & GP3_NEG) { 134 | eventCaller (&onGP3Fall); 135 | } 136 | if (_stat2 & FADE_INT) { 137 | eventCaller (&onFadeProcess); 138 | } 139 | } 140 | 141 | return true; 142 | } 143 | 144 | /*********************************** Read functions *************************************/ 145 | 146 | /** Return the GP1 Configuration**/ 147 | uint8_t i2cNavKey::readGP1conf(void) { 148 | return (readNavKeyByte(REG_GP1CONF)); 149 | } 150 | 151 | /** Return the GP1 Configuration**/ 152 | uint8_t i2cNavKey::readGP2conf(void) { 153 | return (readNavKeyByte(REG_GP2CONF)); 154 | } 155 | 156 | /** Return the GP1 Configuration**/ 157 | uint8_t i2cNavKey::readGP3conf(void) { 158 | return (readNavKeyByte(REG_GP3CONF)); 159 | } 160 | 161 | /** Return the INT pin configuration**/ 162 | uint16_t i2cNavKey::readInterruptConfig(void) { 163 | return ((uint16_t)readNavKeyInt(REG_INTCONFB2)); 164 | } 165 | 166 | 167 | /** Check if a particular status match, return true is match otherwise false. Before require updateStatus() **/ 168 | bool i2cNavKey::readStatus(Int_Status s) { 169 | if ((_stat & s) != 0) { 170 | return true; 171 | } 172 | return false; 173 | } 174 | 175 | /** Return the status of the NavKey **/ 176 | uint16_t i2cNavKey::readStatus(void) { 177 | return _stat; 178 | } 179 | 180 | 181 | /** Check if a particular status of the Int2 match, return true is match otherwise false. Before require updateStatus() **/ 182 | bool i2cNavKey::readInt2(Int2_Status s) { 183 | if ((_stat2 & s) != 0) { 184 | return true; 185 | } 186 | return false; 187 | } 188 | 189 | /** Return the Int2 status of the NavKey. Before require updateStatus() **/ 190 | uint8_t i2cNavKey::readInt2(void) { 191 | return _stat2; 192 | } 193 | 194 | /** Return Fade process status **/ 195 | uint8_t i2cNavKey::readFadeStatus(void) { 196 | return readNavKeyByte(REG_FSTATUS); 197 | } 198 | 199 | /** Check if a particular status of the Fade process match, return true is match otherwise false. **/ 200 | bool i2cNavKey::readFadeStatus(Fade_Status s) { 201 | if ((readNavKeyByte(REG_FSTATUS) & s) == 1) 202 | return true; 203 | 204 | return false; 205 | } 206 | 207 | /** Return the 32 bit value of the NavKey counter **/ 208 | float i2cNavKey::readCounterFloat(void) { 209 | return (readNavKeyFloat(REG_CVALB4)); 210 | } 211 | 212 | /** Return the 32 bit value of the NavKey counter **/ 213 | int32_t i2cNavKey::readCounterLong(void) { 214 | return ((int32_t) readNavKeyLong(REG_CVALB4)); 215 | } 216 | 217 | /** Return the 16 bit value of the NavKey counter **/ 218 | int16_t i2cNavKey::readCounterInt(void) { 219 | return ((int16_t) readNavKeyInt(REG_CVALB2)); 220 | } 221 | 222 | /** Return the 8 bit value of the NavKey counter **/ 223 | int8_t i2cNavKey::readCounterByte(void) { 224 | return ((int8_t) readNavKeyByte(REG_CVALB1)); 225 | } 226 | 227 | /** Return the Maximum threshold of the counter **/ 228 | int32_t i2cNavKey::readMax(void) { 229 | return ((int32_t) readNavKeyLong(REG_CMAXB4)); 230 | } 231 | 232 | /** Return the Minimum threshold of the counter **/ 233 | int32_t i2cNavKey::readMin(void) { 234 | return ((int32_t) readNavKeyLong(REG_CMINB4)); 235 | } 236 | 237 | /** Return the Maximum threshold of the counter **/ 238 | float i2cNavKey::readMaxFloat(void) { 239 | return (readNavKeyFloat(REG_CMAXB4)); 240 | } 241 | 242 | /** Return the Minimum threshold of the counter **/ 243 | float i2cNavKey::readMinFloat(void) { 244 | return (readNavKeyFloat(REG_CMINB4)); 245 | 246 | } 247 | 248 | /** Return the Steps increment **/ 249 | int32_t i2cNavKey::readStep(void) { 250 | return (readNavKeyInt(REG_ISTEPB4)); 251 | } 252 | 253 | /** Return the Steps increment, in float variable **/ 254 | float i2cNavKey::readStepFloat(void) { 255 | return (readNavKeyFloat(REG_ISTEPB4)); 256 | 257 | } 258 | 259 | /** Read GP1 register value **/ 260 | uint8_t i2cNavKey::readGP1(void) { 261 | return (readNavKeyByte(REG_GP1REG)); 262 | } 263 | 264 | /** Read GP2 register value **/ 265 | uint8_t i2cNavKey::readGP2(void) { 266 | return (readNavKeyByte(REG_GP2REG)); 267 | } 268 | 269 | /** Read GP3 register value **/ 270 | uint8_t i2cNavKey::readGP3(void) { 271 | return (readNavKeyByte(REG_GP3REG)); 272 | } 273 | 274 | /** Read Double push period register **/ 275 | uint8_t i2cNavKey::readDoublePushPeriod(void) { 276 | return (readNavKeyByte(REG_DPPERIOD)); 277 | } 278 | 279 | /** Read the fade period of the GP LED**/ 280 | uint8_t i2cNavKey::readFadeGP(void) { 281 | return (readNavKeyByte(REG_FADEGP)); 282 | } 283 | 284 | /** Read the EEPROM memory**/ 285 | uint8_t i2cNavKey::readEEPROM(uint8_t add) { 286 | if (add <= 0x7f) { 287 | if ((_gconf & EEPROM_BANK1) != 0) { 288 | _gconf = _gconf & 0xBF; 289 | writeNavKey(REG_GCONF, _gconf); 290 | } 291 | return (readNavKeyByte((REG_EEPROMS + add))); 292 | } else { 293 | if ((_gconf & EEPROM_BANK1) == 0) { 294 | _gconf = _gconf | 0x40; 295 | writeNavKey(REG_GCONF, _gconf); 296 | } 297 | return (readNavKeyByte(add)); 298 | } 299 | } 300 | 301 | /** Read the ID code **/ 302 | uint8_t i2cNavKey::readIDCode(void) { 303 | return (readNavKeyByte(REG_IDCODE)); 304 | } 305 | 306 | /** Read the Version code **/ 307 | uint8_t i2cNavKey::readVersion(void) { 308 | return (readNavKeyByte(REG_VERSION)); 309 | } 310 | 311 | 312 | 313 | /*********************************** Write functions *************************************/ 314 | /** Write the GP1 configuration**/ 315 | void i2cNavKey::writeGP1conf(uint8_t gp1) { 316 | writeNavKey(REG_GP1CONF, gp1); 317 | } 318 | 319 | /** Write the GP2 configuration**/ 320 | void i2cNavKey::writeGP2conf(uint8_t gp2) { 321 | writeNavKey(REG_GP2CONF, gp2); 322 | } 323 | 324 | /** Write the GP3 configuration**/ 325 | void i2cNavKey::writeGP3conf(uint8_t gp3) { 326 | writeNavKey(REG_GP3CONF, gp3); 327 | } 328 | 329 | /** Write the interrupt configuration **/ 330 | void i2cNavKey::writeInterruptConfig(uint16_t interrupt) { 331 | writeNavKey(REG_INTCONFB2, interrupt); 332 | } 333 | 334 | /** Check if there is some attached callback and enable the corresponding interrupt **/ 335 | void i2cNavKey::autoconfigInterrupt(void) { 336 | uint16_t reg=0; 337 | 338 | if (onArrowsPush != NULL) 339 | reg = reg | UPP | DNP | RTP | LTP; 340 | 341 | 342 | if (onArrowsRelese != NULL) 343 | reg = reg | UPR | DNR | RTR | LTR; 344 | 345 | if (onUpPush != NULL) 346 | reg |= UPP; 347 | 348 | if (onUpRelease != NULL) 349 | reg |= UPR; 350 | 351 | if (onDownPush != NULL) 352 | reg |= DNP; 353 | 354 | if (onDownRelease != NULL) 355 | reg |= DNR; 356 | 357 | if (onRightPush != NULL) 358 | reg |= RTP; 359 | 360 | if (onRightRelease != NULL) 361 | reg |= RTR; 362 | 363 | if (onLeftPush != NULL) 364 | reg |= LTP; 365 | 366 | if (onLeftRelease != NULL) 367 | reg |= LTR; 368 | 369 | if (onCentralPush != NULL) 370 | reg |= CTRP; 371 | 372 | if (onCentralRelease != NULL) 373 | reg |= CTRR; 374 | 375 | if (onCentralDoublePush != NULL) 376 | reg |= CTRDP; 377 | 378 | if (onIncrement != NULL) 379 | reg |= RINC; 380 | 381 | if (onDecrement != NULL) 382 | reg |= RDEC; 383 | 384 | if (onChange != NULL) { 385 | reg |= RINC; 386 | reg |= RDEC; 387 | } 388 | 389 | if (onMax != NULL) 390 | reg |= RMAX; 391 | 392 | if (onMin != NULL) 393 | reg |= RMIN; 394 | 395 | if (onMinMax != NULL) { 396 | reg |= RMAX; 397 | reg |= RMIN; 398 | } 399 | 400 | if (onGP1Rise != NULL) 401 | reg |= INT_2; 402 | 403 | if (onGP1Fall != NULL) 404 | reg |= INT_2; 405 | 406 | if (onGP2Rise != NULL) 407 | reg |= INT_2; 408 | 409 | if (onGP2Fall != NULL) 410 | reg |= INT_2; 411 | 412 | if (onGP3Rise != NULL) 413 | reg |= INT_2; 414 | 415 | if (onGP3Fall != NULL) 416 | reg |= INT_2; 417 | 418 | if (onFadeProcess != NULL) 419 | reg |= INT_2; 420 | 421 | writeInterruptConfig((uint16_t) reg); 422 | } 423 | 424 | 425 | 426 | /** Write the counter value **/ 427 | void i2cNavKey::writeCounter(int32_t value) { 428 | writeNavKey(REG_CVALB4, value); 429 | } 430 | 431 | /** Write the counter value **/ 432 | void i2cNavKey::writeCounter(float value) { 433 | writeNavKey(REG_CVALB4, value); 434 | } 435 | 436 | /** Write the maximum threshold value **/ 437 | void i2cNavKey::writeMax(int32_t max) { 438 | writeNavKey(REG_CMAXB4, max); 439 | } 440 | 441 | /** Write the maximum threshold value **/ 442 | void i2cNavKey::writeMax(float max) { 443 | writeNavKey(REG_CMAXB4, max); 444 | } 445 | 446 | /** Write the minimum threshold value **/ 447 | void i2cNavKey::writeMin(int32_t min) { 448 | writeNavKey(REG_CMINB4, min); 449 | } 450 | 451 | /** Write the minimum threshold value **/ 452 | void i2cNavKey::writeMin(float min) { 453 | writeNavKey(REG_CMINB4, min); 454 | } 455 | 456 | /** Write the Step increment value **/ 457 | void i2cNavKey::writeStep(int32_t step) { 458 | writeNavKey(REG_ISTEPB4, step); 459 | } 460 | 461 | /** Write the Step increment value **/ 462 | void i2cNavKey::writeStep(float step) { 463 | writeNavKey(REG_ISTEPB4, step); 464 | } 465 | 466 | /** Write GP1 register, used when GP1 is set to output or PWM **/ 467 | void i2cNavKey::writeGP1(uint8_t gp1) { 468 | writeNavKey(REG_GP1REG, gp1); 469 | } 470 | 471 | /** Write GP2 register, used when GP2 is set to output or PWM **/ 472 | void i2cNavKey::writeGP2(uint8_t gp2) { 473 | writeNavKey(REG_GP2REG, gp2); 474 | } 475 | 476 | /** Write GP3 register, used when GP3 is set to output or PWM **/ 477 | void i2cNavKey::writeGP3(uint8_t gp3) { 478 | writeNavKey(REG_GP3REG, gp3); 479 | } 480 | 481 | /** Write Anti-bouncing period register **/ 482 | void i2cNavKey::writeDoublePushPeriod(uint8_t dperiod) { 483 | writeNavKey(REG_DPPERIOD, dperiod); 484 | } 485 | 486 | /** Write Fade timing in ms **/ 487 | void i2cNavKey::writeFadeGP(uint8_t fade) { 488 | writeNavKey(REG_FADEGP, fade); 489 | } 490 | 491 | /** Write the Gamma value on GP1 **/ 492 | void i2cNavKey::writeGammaGP1(GAMMA_PARAMETER Gamma) { 493 | writeNavKey(REG_GAMMAGP1, (uint8_t) Gamma); 494 | } 495 | 496 | /** Write the Gamma value on GP2 **/ 497 | void i2cNavKey::writeGammaGP2(GAMMA_PARAMETER Gamma) { 498 | writeNavKey(REG_GAMMAGP2, (uint8_t)Gamma); 499 | } 500 | 501 | /** Write the Gamma value on GP1 **/ 502 | void i2cNavKey::writeGammaGP3(GAMMA_PARAMETER Gamma) { 503 | writeNavKey(REG_GAMMAGP3, (uint8_t)Gamma); 504 | } 505 | 506 | /** Write the EEPROM memory**/ 507 | void i2cNavKey::writeEEPROM(uint8_t add, uint8_t data) { 508 | if (add <= 0x7f) { 509 | if ((_gconf & EEPROM_BANK1) != 0) { 510 | _gconf = _gconf & 0xBF; 511 | writeNavKey(REG_GCONF, _gconf); 512 | } 513 | writeNavKey((REG_EEPROMS + add), data); 514 | } else { 515 | if ((_gconf & EEPROM_BANK1) == 0) { 516 | _gconf = _gconf | 0x40; 517 | writeNavKey(REG_GCONF, _gconf); 518 | } 519 | writeNavKey(add, data); 520 | } 521 | } 522 | 523 | /*********************************** Private functions *************************************/ 524 | /***************************** Read function to the NavKey ********************************/ 525 | 526 | /** Read 1 byte from the NavKey **/ 527 | uint8_t i2cNavKey::readNavKeyByte(uint8_t reg) { 528 | byte rdata = 0xFF; 529 | 530 | Wire.beginTransmission(_add); 531 | Wire.write(reg); 532 | Wire.endTransmission(); 533 | Wire.requestFrom((int)_add, (int)1); 534 | if (Wire.available()) { 535 | rdata = Wire.read(); 536 | } 537 | // delay(5); 538 | return rdata; 539 | } 540 | 541 | /** Read 2 bytes from the NavKey **/ 542 | int16_t i2cNavKey::readNavKeyInt(uint8_t reg) { 543 | Wire.beginTransmission(_add); 544 | Wire.write(reg); 545 | Wire.endTransmission(); 546 | Wire.requestFrom((int)_add, (int)2); 547 | if (Wire.available()) { 548 | _tem_data.bval[1] = Wire.read(); 549 | _tem_data.bval[0] = Wire.read(); 550 | } 551 | return ((int16_t) _tem_data.wval); 552 | } 553 | 554 | /** Read 4 bytes from the NavKey **/ 555 | int32_t i2cNavKey::readNavKeyLong(uint8_t reg) { 556 | 557 | Wire.beginTransmission(_add); 558 | Wire.write(reg); 559 | Wire.endTransmission(); 560 | Wire.requestFrom((int)_add, (int)4); 561 | if (Wire.available()) { 562 | _tem_data.bval[3] = Wire.read(); 563 | _tem_data.bval[2] = Wire.read(); 564 | _tem_data.bval[1] = Wire.read(); 565 | _tem_data.bval[0] = Wire.read(); 566 | } 567 | return ((int32_t) _tem_data.val); 568 | } 569 | 570 | /** Read 4 bytes from the NavKey **/ 571 | float i2cNavKey::readNavKeyFloat(uint8_t reg) { 572 | Wire.beginTransmission(_add); 573 | Wire.write(reg); 574 | Wire.endTransmission(); 575 | Wire.requestFrom((int)_add, (int)4); 576 | if (Wire.available()) { 577 | _tem_data.bval[3] = Wire.read(); 578 | _tem_data.bval[2] = Wire.read(); 579 | _tem_data.bval[1] = Wire.read(); 580 | _tem_data.bval[0] = Wire.read(); 581 | } 582 | return ((float) _tem_data.fval); 583 | } 584 | 585 | /***************************** Write function to the NavKey ********************************/ 586 | /** Send to the NavKey 1 byte **/ 587 | void i2cNavKey::writeNavKey(uint8_t reg, uint8_t data) { 588 | 589 | Wire.beginTransmission(_add); 590 | Wire.write(reg); 591 | Wire.write(data); 592 | Wire.endTransmission(); 593 | // delay(1); 594 | 595 | } 596 | 597 | /** Send to the NavKey 4 byte **/ 598 | void i2cNavKey::writeNavKey(uint8_t reg, int32_t data) { 599 | uint8_t temp[4]; 600 | _tem_data.val = data; 601 | temp[0] = _tem_data.bval[3]; 602 | temp[1] = _tem_data.bval[2]; 603 | temp[2] = _tem_data.bval[1]; 604 | temp[3] = _tem_data.bval[0]; 605 | Wire.beginTransmission(_add); 606 | Wire.write(reg); 607 | Wire.write(temp, 4); 608 | Wire.endTransmission(); 609 | // delay(1); 610 | } 611 | 612 | 613 | /** Send to the NavKey 2 byte **/ 614 | void i2cNavKey::writeNavKey(uint8_t reg, uint16_t data) { 615 | uint8_t temp[2]; 616 | _tem_data.wval = data; 617 | temp[0] = _tem_data.bval[1]; 618 | temp[1] = _tem_data.bval[0]; 619 | Wire.beginTransmission(_add); 620 | Wire.write(reg); 621 | Wire.write(temp, 2); 622 | Wire.endTransmission(); 623 | // delay(1); 624 | } 625 | 626 | /** Send to the NavKey 4 byte for floating number **/ 627 | void i2cNavKey::writeNavKey(uint8_t reg, float data) { 628 | 629 | uint8_t temp[4]; 630 | _tem_data.fval = data; 631 | temp[0] = _tem_data.bval[3]; 632 | temp[1] = _tem_data.bval[2]; 633 | temp[2] = _tem_data.bval[1]; 634 | temp[3] = _tem_data.bval[0]; 635 | Wire.beginTransmission(_add); 636 | Wire.write(reg); 637 | Wire.write(temp, 4); 638 | Wire.endTransmission(); 639 | // delay(1); 640 | 641 | } 642 | 643 | 644 | /** Send to the NavKey 3 byte **/ 645 | void i2cNavKey::writeNavKey24bit(uint8_t reg, uint32_t data) { 646 | uint8_t temp[3]; 647 | _tem_data.val = data; 648 | temp[0] = _tem_data.bval[2]; 649 | temp[1] = _tem_data.bval[1]; 650 | temp[2] = _tem_data.bval[0]; 651 | Wire.beginTransmission(_add); 652 | Wire.write(reg); 653 | Wire.write(temp, 3); 654 | Wire.endTransmission(); 655 | // delay(1); 656 | 657 | } 658 | -------------------------------------------------------------------------------- /src/i2cNavKey.h: -------------------------------------------------------------------------------- 1 | // 2 | // FILE: i2cNavKey.h 3 | // VERSION: 0.1.. 4 | // PURPOSE: Libreary for the i2c NavKey board with arduinp 5 | // LICENSE: GPL v3 (http://www.gnu.org/licenses/gpl.html) 6 | // 7 | // DATASHEET: 8 | // 9 | // URL: 10 | // 11 | // AUTHOR: 12 | // Simone Caron 13 | // 14 | 15 | #ifndef i2cNavKey_H 16 | #define i2cNavKey_H 17 | 18 | #if (ARDUINO >= 100) 19 | #include 20 | #else 21 | #include 22 | #endif 23 | 24 | class i2cNavKey { 25 | public: 26 | /*NavKey register definition*/ 27 | enum I2C_Register { 28 | REG_GCONF = 0x00, 29 | REG_GP1CONF = 0x01, 30 | REG_GP2CONF = 0x02, 31 | REG_GP3CONF = 0x03, 32 | REG_INTCONFB2 = 0x04, 33 | REG_INTCONFB1 = 0x05, 34 | REG_STATUSB2 = 0x06, 35 | REG_STATUSB1 = 0x07, 36 | REG_SSTATUS = 0x08, 37 | REG_FSTATUS = 0x09, 38 | REG_CVALB4 = 0x0A, 39 | REG_CVALB3 = 0x0B, 40 | REG_CVALB2 = 0x0C, 41 | REG_CVALB1 = 0x0D, 42 | REG_CMAXB4 = 0x0E, 43 | REG_CMAXB3 = 0x0F, 44 | REG_CMAXB2 = 0x10, 45 | REG_CMAXB1 = 0x11, 46 | REG_CMINB4 = 0x12, 47 | REG_CMINB3 = 0x13, 48 | REG_CMINB2 = 0x14, 49 | REG_CMINB1 = 0x15, 50 | REG_ISTEPB4 = 0x16, 51 | REG_ISTEPB3 = 0x17, 52 | REG_ISTEPB2 = 0x18, 53 | REG_ISTEPB1 = 0x19, 54 | REG_GP1REG = 0x1A, 55 | REG_GP2REG = 0x1B, 56 | REG_GP3REG = 0x1C, 57 | REG_DPPERIOD = 0x1D, 58 | REG_FADEGP = 0x1E, 59 | REG_GAMMAGP1 = 0x1F, 60 | REG_GAMMAGP2 = 0x20, 61 | REG_GAMMAGP3 = 0x21, 62 | REG_IDCODE = 0x70, 63 | REG_VERSION = 0x71, 64 | REG_EEPROMS = 0x80, 65 | }; 66 | 67 | /* NavKey configuration bit. Use with GCONF */ 68 | enum GCONF_PARAMETER { 69 | FLOAT_DATA = 0x01, 70 | INT_DATA = 0x00, 71 | WRAP_ENABLE = 0x02, 72 | WRAP_DISABLE = 0x00, 73 | DIRE_LEFT = 0x04, 74 | DIRE_RIGHT = 0x00, 75 | IPUP_DISABLE = 0x08, 76 | IPUP_ENABLE = 0x00, 77 | CLK_STRECH_ENABLE = 0x10, 78 | CLK_STRECH_DISABLE = 0x00, 79 | EEPROM_BANK1 = 0x20, 80 | EEPROM_BANK2 = 0x00, 81 | RESET = 0x80, 82 | }; 83 | 84 | /* NavKey status bits and setting. Use with: INTCONF for set and with ESTATUS for read the bits */ 85 | enum Int_Status { 86 | UPR = 0x0001, 87 | UPP = 0x0002, 88 | DNR = 0x0004, 89 | DNP = 0x0008, 90 | RTR = 0x0010, 91 | RTP = 0x0020, 92 | LTR = 0x0040, 93 | LTP = 0x0080, 94 | CTRR = 0x0100, 95 | CTRP = 0x0200, 96 | CTRDP = 0x0400, 97 | RINC = 0x0800, 98 | RDEC = 0x1000, 99 | RMAX = 0x2000, 100 | RMIN = 0x4000, 101 | INT_2 = 0x8000, 102 | }; 103 | 104 | /* NavKey Int2 bits. Use to read the bits of I2STATUS */ 105 | enum Int2_Status { 106 | GP1_POS = 0x01, 107 | GP1_NEG = 0x02, 108 | GP2_POS = 0x04, 109 | GP2_NEG = 0x08, 110 | GP3_POS = 0x10, 111 | GP3_NEG = 0x20, 112 | FADE_INT = 0x40, 113 | }; 114 | 115 | /* NavKey Fade status bits. Use to read the bits of FSTATUS */ 116 | enum Fade_Status { 117 | FADES_GP1 = 0x01, FADES_GP2 = 0x02, FADES_GP3 = 0x04, 118 | }; 119 | 120 | /* GPIO Configuration. USe with GP1CONF,GP2CONF,GP3CONF */ 121 | enum GP_PARAMETER { 122 | GP_PWM = 0x00, 123 | GP_OUT = 0x01, 124 | GP_AN = 0x02, 125 | GP_IN = 0x03, 126 | GP_PULL_EN = 0x04, 127 | GP_PULL_DI = 0x00, 128 | GP_INT_DI = 0x00, 129 | GP_INT_PE = 0x08, 130 | GP_INT_NE = 0x10, 131 | GP_INT_BE = 0x18, 132 | }; 133 | 134 | typedef enum { 135 | GAMMA_1 = 0, 136 | GAMMA_1_8 = 1, 137 | GAMMA_2 = 2, 138 | GAMMA_2_2 = 3, 139 | GAMMA_2_4 = 4, 140 | GAMMA_2_6 = 5, 141 | GAMMA_2_8 = 6, 142 | 143 | } GAMMA_PARAMETER; 144 | 145 | union Data_v { 146 | float fval; 147 | uint16_t wval; 148 | int32_t val; 149 | uint8_t bval[4]; 150 | }; 151 | 152 | typedef void (*Callback)(i2cNavKey*); 153 | 154 | /* Event */ 155 | Callback onArrowsPush = NULL; 156 | Callback onArrowsRelese = NULL; 157 | Callback onUpPush = NULL; 158 | Callback onUpRelease = NULL; 159 | Callback onDownPush = NULL; 160 | Callback onDownRelease = NULL; 161 | Callback onRightPush = NULL; 162 | Callback onRightRelease = NULL; 163 | Callback onLeftPush = NULL; 164 | Callback onLeftRelease = NULL; 165 | Callback onCentralPush = NULL; 166 | Callback onCentralRelease = NULL; 167 | Callback onCentralDoublePush = NULL; 168 | Callback onIncrement = NULL; 169 | Callback onDecrement = NULL; 170 | Callback onChange = NULL; 171 | Callback onMax = NULL; 172 | Callback onMin = NULL; 173 | Callback onMinMax = NULL; 174 | Callback onGP1Rise = NULL; 175 | Callback onGP1Fall = NULL; 176 | Callback onGP2Rise = NULL; 177 | Callback onGP2Fall = NULL; 178 | Callback onGP3Rise = NULL; 179 | Callback onGP3Fall = NULL; 180 | Callback onFadeProcess = NULL; 181 | 182 | i2cNavKey(uint8_t add); 183 | void begin(uint8_t conf); 184 | void reset(void); 185 | void autoconfigInterrupt(void); 186 | 187 | /** Read functions **/ 188 | /** Configuration function **/ 189 | uint8_t readGP1conf(void); 190 | uint8_t readGP2conf(void); 191 | uint8_t readGP3conf(void); 192 | uint16_t readInterruptConfig(void); 193 | 194 | /** Status function **/ 195 | bool updateStatus(void); 196 | bool readStatus(Int_Status s); 197 | uint16_t readStatus(void); 198 | 199 | bool readInt2(Int2_Status s); 200 | uint8_t readInt2(void); 201 | 202 | bool readFadeStatus(Fade_Status s); 203 | uint8_t readFadeStatus(void); 204 | 205 | /** NavKey functions **/ 206 | float readCounterFloat(void); 207 | int32_t readCounterLong(void); 208 | int16_t readCounterInt(void); 209 | int8_t readCounterByte(void); 210 | 211 | int32_t readMax(void); 212 | float readMaxFloat(void); 213 | 214 | int32_t readMin(void); 215 | float readMinFloat(void); 216 | 217 | int32_t readStep(void); 218 | float readStepFloat(void); 219 | 220 | /** GP LED Functions **/ 221 | uint8_t readGP1(void); 222 | uint8_t readGP2(void); 223 | uint8_t readGP3(void); 224 | 225 | /** Timing registers **/ 226 | uint8_t readDoublePushPeriod(void); 227 | uint8_t readFadeGP(void); 228 | 229 | /** EEPROM register **/ 230 | uint8_t readEEPROM(uint8_t add); 231 | 232 | /** **/ 233 | uint8_t readIDCode(void); 234 | uint8_t readVersion(void); 235 | 236 | uint8_t readNavKeyByte(uint8_t reg); 237 | int16_t readNavKeyInt(uint8_t reg); 238 | int32_t readNavKeyLong(uint8_t reg); 239 | 240 | /****** Write functions ********/ 241 | void writeGP1conf(uint8_t gp1); 242 | void writeGP2conf(uint8_t gp2); 243 | void writeGP3conf(uint8_t gp3); 244 | void writeInterruptConfig(uint16_t interrupt); 245 | 246 | /** NavKey functions **/ 247 | void writeCounter(int32_t counter); 248 | void writeCounter(float counter); 249 | 250 | void writeMax(int32_t max); 251 | void writeMax(float max); 252 | 253 | void writeMin(int32_t min); 254 | void writeMin(float min); 255 | 256 | void writeStep(int32_t step); 257 | void writeStep(float step); 258 | 259 | /** GP LED Functions **/ 260 | void writeGP1(uint8_t gp1); 261 | void writeGP2(uint8_t gp2); 262 | void writeGP3(uint8_t gp3); 263 | 264 | /** Timing registers **/ 265 | void writeDoublePushPeriod(uint8_t dperiod); 266 | void writeFadeGP(uint8_t fade); 267 | 268 | void writeGammaGP1(GAMMA_PARAMETER Gamma); 269 | void writeGammaGP2(GAMMA_PARAMETER Gamma); 270 | void writeGammaGP3(GAMMA_PARAMETER Gamma); 271 | 272 | /** EEPROM register **/ 273 | void writeEEPROM(uint8_t add, uint8_t data); 274 | 275 | private: 276 | 277 | uint8_t _add = 0x00; 278 | uint16_t _stat = 0x00; 279 | uint8_t _stat2 = 0x00; 280 | uint8_t _statfade = 0x00; 281 | uint8_t _gconf = 0x00; 282 | union Data_v _tem_data; 283 | 284 | void eventCaller(Callback *event); 285 | float readNavKeyFloat(uint8_t reg); 286 | void writeNavKey(uint8_t reg, uint8_t data); 287 | void writeNavKey(uint8_t reg, uint16_t data); 288 | void writeNavKey(uint8_t reg, int32_t data); 289 | void writeNavKey(uint8_t reg, float data); 290 | void writeNavKey24bit(uint8_t reg, uint32_t data); 291 | 292 | }; 293 | 294 | #endif 295 | --------------------------------------------------------------------------------