|
| 1 | +#include <Wire.h> |
| 2 | +#include <TimerOne.h> |
| 3 | +#include <i2cEncoderLibV2.h> |
| 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: |
| 14 | + - -> GND |
| 15 | + + -> 5V |
| 16 | + SDA -> A4 |
| 17 | + SCL -> A5 |
| 18 | + INT -> A3 |
| 19 | +*/ |
| 20 | + |
| 21 | + |
| 22 | +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, }; |
| 23 | +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, }; |
| 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(0x5A); |
| 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 | + |
| 55 | +//Callback when the encoder is released |
| 56 | +// it change also the led RGB effect |
| 57 | +void encoder_released(i2cEncoderLibV2* obj) { |
| 58 | + Serial.println("Encoder is released"); |
| 59 | + led_case++; |
| 60 | + if (led_case > 5) |
| 61 | + led_case = 0; |
| 62 | + |
| 63 | + switch (led_case) { |
| 64 | + case 0: |
| 65 | + obj->writeCounter((int32_t)led_pos[led_case]); |
| 66 | + obj->writeRGBCode(0xFF0000); |
| 67 | + break; |
| 68 | + |
| 69 | + case 1: |
| 70 | + obj->writeCounter((int32_t)led_pos[led_case]); |
| 71 | + Encoder.writeRGBCode(0x00FF00); |
| 72 | + break; |
| 73 | + |
| 74 | + case 2: |
| 75 | + Encoder.writeRGBCode(0x0000FF); |
| 76 | + obj->writeCounter((int32_t)led_pos[led_case]); |
| 77 | + break; |
| 78 | + |
| 79 | + case 3: |
| 80 | + Timer1.start(); |
| 81 | + Encoder.writeMax((int32_t) 100); /* Set the maximum threshold*/ |
| 82 | + Encoder.writeMin((int32_t) 0); /* Set the minimum threshold */ |
| 83 | + Encoder.writeStep((int32_t) 1); /* Set the step to 1*/ |
| 84 | + Encoder.writeRGBCode(0xFF00FF); |
| 85 | + obj->writeCounter((int32_t)led_pos[led_case]); |
| 86 | + break; |
| 87 | + |
| 88 | + case 4: |
| 89 | + Encoder.writeRGBCode(0x086050); |
| 90 | + obj->writeCounter((int32_t)led_pos[led_case]); |
| 91 | + break; |
| 92 | + |
| 93 | + case 5: |
| 94 | + Timer1.stop(); |
| 95 | + Encoder.writeRGBCode(0); |
| 96 | + for (uint8_t i = 0; i < 48; i++) { |
| 97 | + LEDRing1.LEDRing_Set_RGB(i, 0); |
| 98 | + delay(5); |
| 99 | + } |
| 100 | + |
| 101 | + led_case = 0; |
| 102 | + UpdateRing(led_pos[led_case]); |
| 103 | + led_case = 1; |
| 104 | + UpdateRing(led_pos[led_case]); |
| 105 | + led_case = 2; |
| 106 | + UpdateRing(led_pos[led_case]); |
| 107 | + led_case = 5; |
| 108 | + |
| 109 | + Encoder.writeMax((int32_t) 47); /* Set the maximum threshold*/ |
| 110 | + Encoder.writeMin((int32_t) 0); /* Set the minimum threshold */ |
| 111 | + Encoder.writeStep((int32_t) 2); /* Set the step to 1*/ |
| 112 | + |
| 113 | + break; |
| 114 | + } |
| 115 | +} |
| 116 | + |
| 117 | +//Update the led Ring with the encoder position |
| 118 | +void UpdateRing(uint8_t value) { |
| 119 | + |
| 120 | + switch (led_case) { |
| 121 | + case 0: |
| 122 | + for (uint8_t i = 0; i < 48; i++) |
| 123 | + LEDRing1.LEDRing_Set_RED(i, 0); |
| 124 | + |
| 125 | + LEDRing1.LEDRing_Set_RED(CheckRingBorder(value + 2), 0x03); |
| 126 | + LEDRing1.LEDRing_Set_RED(CheckRingBorder(value + 1), 0x10); |
| 127 | + LEDRing1.LEDRing_Set_RED(CheckRingBorder(value), 0xff); |
| 128 | + LEDRing1.LEDRing_Set_RED(CheckRingBorder(value - 1), 0x10); |
| 129 | + LEDRing1.LEDRing_Set_RED(CheckRingBorder(value - 2), 0x03); |
| 130 | + break; |
| 131 | + |
| 132 | + case 1: |
| 133 | + for (uint8_t i = 0; i < 48; i++) |
| 134 | + LEDRing1.LEDRing_Set_GREEN(i, 0); |
| 135 | + LEDRing1.LEDRing_Set_GREEN(CheckRingBorder(value + 2), 0x03); |
| 136 | + LEDRing1.LEDRing_Set_GREEN(CheckRingBorder(value + 1), 0x10); |
| 137 | + LEDRing1.LEDRing_Set_GREEN(CheckRingBorder(value), 0xff); |
| 138 | + LEDRing1.LEDRing_Set_GREEN(CheckRingBorder(value - 1), 0x10); |
| 139 | + LEDRing1.LEDRing_Set_GREEN(CheckRingBorder(value - 2), 0x03); |
| 140 | + break; |
| 141 | + |
| 142 | + case 2: |
| 143 | + for (uint8_t i = 0; i < 48; i++) |
| 144 | + LEDRing1.LEDRing_Set_BLUE(i, 0); |
| 145 | + |
| 146 | + LEDRing1.LEDRing_Set_BLUE(CheckRingBorder(value + 2), 0x03); |
| 147 | + LEDRing1.LEDRing_Set_BLUE(CheckRingBorder(value + 1), 0x10); |
| 148 | + LEDRing1.LEDRing_Set_BLUE(CheckRingBorder(value), 0xff); |
| 149 | + LEDRing1.LEDRing_Set_BLUE(CheckRingBorder(value - 1), 0x10); |
| 150 | + LEDRing1.LEDRing_Set_BLUE(CheckRingBorder(value - 2), 0x03); |
| 151 | + break; |
| 152 | + } |
| 153 | + |
| 154 | +} |
| 155 | + |
| 156 | +// Callback when the Timer1 expire, used for make the LED pattern roatating |
| 157 | +void timer_callback(void) { |
| 158 | + sf_Timer++; |
| 159 | +} |
| 160 | + |
| 161 | +// Small function for wrap the led position between 0 and 47. |
| 162 | +uint8_t CheckRingBorder(uint8_t in) { |
| 163 | + |
| 164 | + if ((int8_t)in > 47) { |
| 165 | + return ((int8_t)in - 48); |
| 166 | + } |
| 167 | + if ((int8_t)in < 0) { |
| 168 | + |
| 169 | + return ( 48 + (int8_t)in); |
| 170 | + } |
| 171 | + return in; |
| 172 | +} |
| 173 | + |
| 174 | +void setup(void) { |
| 175 | + pinMode(IntPin, INPUT); |
| 176 | + Timer1.initialize(1000); |
| 177 | + Timer1.attachInterrupt(timer_callback); |
| 178 | + |
| 179 | + Wire.begin(); |
| 180 | + Wire.setClock(500000); |
| 181 | + Serial.begin(115200); |
| 182 | + Serial.println("**** I2C Encoder + LED Ring example ****"); |
| 183 | + |
| 184 | + Encoder.reset(); |
| 185 | + Encoder.begin(i2cEncoderLibV2::INT_DATA | i2cEncoderLibV2::WRAP_ENABLE |
| 186 | + | i2cEncoderLibV2::DIRE_LEFT | i2cEncoderLibV2::IPUP_ENABLE |
| 187 | + | i2cEncoderLibV2::RMOD_X2 | i2cEncoderLibV2::RGB_ENCODER); |
| 188 | + |
| 189 | +// 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. |
| 190 | + |
| 191 | + Encoder.writeCounter((int32_t) 0); /* Reset the counter value */ |
| 192 | + Encoder.writeMax((int32_t) 47); /* Set the maximum threshold*/ |
| 193 | + Encoder.writeMin((int32_t) 0); /* Set the minimum threshold */ |
| 194 | + Encoder.writeStep((int32_t) 1); /* Set the step to 1*/ |
| 195 | + Encoder.writeAntibouncingPeriod(1); /* Set an anti-bouncing of 200ms */ |
| 196 | + Encoder.writeDoublePushPeriod(0); /*Set a period for the double push of 500ms */ |
| 197 | + |
| 198 | + // Definition of the encoder events |
| 199 | + Encoder.onChange = encoder_change; |
| 200 | + Encoder.onButtonRelease = encoder_released; |
| 201 | + |
| 202 | + |
| 203 | + /* Enable the I2C Encoder V2 interrupts according to the previus attached callback */ |
| 204 | + Encoder.autoconfigInterrupt(); |
| 205 | + LEDRing1.LEDRing_Reset(); |
| 206 | + delay(20); |
| 207 | + |
| 208 | + LEDRing1.LEDRing_EnableAllOutput(); |
| 209 | + LEDRing1.LEDRing_Configuration(0x01); |
| 210 | + LEDRing1.LEDRing_GlobalCurrent(0xff); |
| 211 | + LEDRing1.LEDRing_PULLUP(0b110); |
| 212 | + LEDRing1.LEDRing_PULLDOWN(0b110); |
| 213 | + LEDRing1.LEDRing_PWM_MODE(); |
| 214 | + |
| 215 | + randomSeed(analogRead(0)); |
| 216 | + |
| 217 | + // Showing some random pattern |
| 218 | + for (uint8_t i = 0; i < 100; i++) { |
| 219 | + LEDRing1.LEDRing_Set_RGB(random(47), random(0xFFFFFF)); |
| 220 | + delay(20); |
| 221 | + } |
| 222 | + for (uint8_t i = 0; i < 48; i++) { |
| 223 | + LEDRing1.LEDRing_Set_RGB(i, fade2_table[i]); |
| 224 | + delay(10); |
| 225 | + } |
| 226 | + for (uint8_t i = 0; i < 48; i++) { |
| 227 | + LEDRing1.LEDRing_Set_RGB(i, 0); |
| 228 | + delay(5); |
| 229 | + } |
| 230 | +} |
| 231 | + |
| 232 | +void loop() { |
| 233 | + uint8_t temp; |
| 234 | + //Check the Encoder Status |
| 235 | + if (digitalRead(IntPin) == LOW) { |
| 236 | + Encoder.updateStatus(); |
| 237 | + } |
| 238 | + |
| 239 | + // Make the LED pattern rotating, it's used the timer1 for the temporization. |
| 240 | + if (sf_Timer > led_pos[led_case]) { |
| 241 | + sf_Timer = 0; |
| 242 | + |
| 243 | + switch (led_case) { |
| 244 | + case 3: |
| 245 | + temp = j++; |
| 246 | + if (j >= 48) |
| 247 | + j = 0; |
| 248 | + for (uint8_t i = 0; i < 48; i++) { |
| 249 | + LEDRing1.LEDRing_Set_RGB(i, fade1_table[temp]); |
| 250 | + temp++; |
| 251 | + if (temp >= 48) |
| 252 | + temp = 0; |
| 253 | + } |
| 254 | + break; |
| 255 | + |
| 256 | + case 4: |
| 257 | + temp = j++; |
| 258 | + if (j >= 48) |
| 259 | + j = 0; |
| 260 | + for (uint8_t i = 0; i < 48; i++) { |
| 261 | + LEDRing1.LEDRing_Set_RGB(i, fade2_table[temp]); |
| 262 | + temp++; |
| 263 | + if (temp >= 48) |
| 264 | + temp = 0; |
| 265 | + } |
| 266 | + break; |
| 267 | + } |
| 268 | + } |
| 269 | +} |
0 commit comments