/ neoMatrixMkI / neoMatrixMkI.ino
neoMatrixMkI.ino
1 // SPDX-FileCopyrightText: 2017 John Park for Adafruit Industries 2 // 3 // SPDX-License-Identifier: MIT 4 5 #include "Arduino.h" 6 #include "Keypad.h" 7 #include "Neosegment.h" 8 #include <stdlib.h> 9 10 #define SERIAL_BAUD 115200 11 #define nDigits 6 // number of digits in display 12 #define NEOSEGPIN 12 13 #define LEDbrightness 255 // 0 to 255 14 /* 15 Segment mapping 16 5 17 ___ 18 4 | | 6 19 |___| 20 | 3 | 21 0 |___| 2 22 23 1 24 */ 25 int buttonPin = 11; //pushbutton 26 int ledPin = 13; // select the pin for the LED 27 int knobUpperPin = A3; // input pin for a potentiometer 28 int knobLowerPin = A2; // input pin for a potentiometer 29 int knobUpper = 0; // variable to store the value coming from the sensor 30 int knobLower = 0; // variable to store the value coming from the sensor 31 32 int buttonState; 33 int lastButtonState = LOW; 34 long lastDebounceTime = 0; 35 long debounceDelay = 50; 36 37 38 //initialize the neosegment object 39 Neosegment neosegment(nDigits, NEOSEGPIN, LEDbrightness); 40 uint16_t i, j; 41 42 //set up the keypad 43 const byte ROWS = 4; //four rows 44 const byte COLS = 3; //three columns 45 char keys[ROWS][COLS] = { 46 {'1','2','3'}, 47 {'4','5','6'}, 48 {'7','8','9'}, 49 {'*','0','#'} 50 }; 51 byte rowPins[ROWS] = {5, 6, 7, 8}; //connect to the row pinouts of the keypad 52 byte colPins[COLS] = {2, 3, 4}; //connect to the column pinouts of the keypad 53 54 //initialize the keypad object 55 Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); 56 57 //use to set digit cursor position 58 int neoCounter = 0; 59 60 //gamma correction table 61 const uint8_t PROGMEM gamma8[] = { 62 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 64 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 65 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 66 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 67 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 68 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25, 69 25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36, 70 37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50, 71 51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68, 72 69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89, 73 90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114, 74 115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142, 75 144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175, 76 177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213, 77 215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 }; 78 79 void setup(){ 80 Serial.begin(SERIAL_BAUD); 81 pinMode(ledPin, OUTPUT); 82 pinMode(buttonPin, INPUT_PULLUP); 83 digitalWrite(ledPin, HIGH); //turn on the LED 84 85 neosegment.begin(); 86 neosegment.clearAll(); 87 for(int i = 0; i < 6; i++){ //turn on green lines, top row, L to R 88 neosegment.setSegment(i, 5, 0, 40, 0); //the '3' segment is middle dash 89 tone(A1, 330, 100); 90 delay(50); 91 } 92 neosegment.setSegment(5, 6, 0, 40, 0); 93 tone(A1, 330, 100); 94 delay(50); 95 neosegment.setSegment(5, 2, 0, 40, 0); 96 tone(A1, 330, 100); 97 delay(50); 98 neosegment.clearAll(); 99 100 for(int i = 5; i > -1; i--){ //turn on green lines, bottom row, R to L 101 neosegment.setSegment(i, 1, 0, 40, 0); //the '3' segment is middle dash 102 tone(A1, 330, 100); 103 delay(50); 104 } 105 neosegment.setSegment(0, 0, 0, 40, 0); 106 tone(A1, 330, 100); 107 delay(50); 108 neosegment.clearAll(); 109 110 for(int i = 0; i < 6; i++){ //turn on green lines, middle row, L to R 111 neosegment.setSegment(i, 3, 0, 40, 0); //the '3' segment is middle dash 112 tone(A1, 440, 100); 113 delay(100); 114 } 115 } 116 117 void loop(){ 118 //read button 119 int buttonReading = digitalRead(buttonPin); 120 if (buttonReading != lastButtonState) { 121 lastDebounceTime = millis(); 122 } 123 if ((millis() - lastDebounceTime) > debounceDelay){ 124 buttonState = buttonReading; 125 } 126 Serial.println(buttonState); 127 if(buttonState){ 128 digitalWrite(ledPin, LOW); 129 } 130 else{ 131 digitalWrite(ledPin, HIGH); 132 } 133 lastButtonState = buttonReading; 134 135 //read knobs 136 knobUpper = analogRead(knobUpperPin); //used for hue 137 knobLower = analogRead(knobLowerPin); //used for value 138 //map knob range 139 int knobUpperMapped = map(knobUpper, 0, 700, 360, 0); 140 int knobLowerMapped = map(knobLower, 0, 700, 700, 0); 141 //constrain knob range 142 knobUpperMapped = constrain(knobUpperMapped, 0, 360); 143 knobLowerMapped = constrain(knobLowerMapped, 0, 700); 144 //map to hue range 145 //int knobHue = map(knobUpperMapped, 0, 255, 0, 360); 146 //knobHue = constrain(knobHue, 0, 360); 147 float knobHue = ((float)knobUpperMapped); 148 //map to value range 149 float knobValue = ((float)knobLowerMapped / 700); 150 151 float r, g, b; 152 float h = knobHue; 153 float s = 1.0; 154 float v = knobValue; 155 156 HSVtoRGB(&r, &g, &b, h, s, v); //convert HSV to RGB 157 uint8_t r_byte = (int)(r * 255); 158 uint8_t g_byte = (int)(g * 255); 159 uint8_t b_byte = (int)(b * 255); 160 161 //apply gamma correction table values 162 r_byte = pgm_read_byte(&gamma8[r_byte]); 163 g_byte = pgm_read_byte(&gamma8[g_byte]); 164 b_byte = pgm_read_byte(&gamma8[b_byte]); 165 166 char key = keypad.getKey(); 167 168 if (key != NO_KEY){ // a key has been pressed 169 Serial.print("key: "); 170 Serial.println(key); 171 int neoKey = key - '0'; //terminate w zero so don't get ASCII code 172 173 //enter with '#' 174 if(key == '#'){ 175 neosegment.clearAll(); 176 delay(35); 177 neosegment.setSegment(5, 2, 40, 40, 40); 178 neosegment.setSegment(5, 6, 40, 40, 40); 179 delay(35); 180 tone(A1, 660, 100); 181 for(int i = 5; i > -1; i--){ //from right to left 182 neosegment.setSegment(i, 1, 40, 40, 40); 183 neosegment.setSegment(i, 5, 40, 40, 40); 184 delay(35); 185 tone(A1, 660, 100); 186 } 187 neosegment.setSegment(0, 0, 40, 40, 40); 188 neosegment.setSegment(0, 4, 40, 40, 40); 189 tone(A1, 660, 100); 190 neoCounter = 0; 191 192 //letters that appear in upper: A, E, F, H, I, J, L, P, S, U 193 //letters that appear in lower: b, c, d, g, n, o, q, r, t 194 delay(1000); 195 neosegment.clearAll(); 196 delay(1000); 197 neosegment.setDigit(5, 'a', 23, 0, 12); 198 tone(A1, 220, 100); 199 delay(500); 200 neosegment.setDigit(4, 'a', 23, 0, 12); 201 neosegment.setDigit(5, 'c', 23, 0, 12); 202 tone(A1, 220, 100); 203 delay(500); 204 neosegment.setDigit(3, 'a', 23, 0, 12); 205 neosegment.setDigit(4, 'c', 23, 0, 12); 206 neosegment.setDigit(5, 'o', 23, 0, 12); 207 tone(A1, 220, 100); 208 delay(500); 209 neosegment.setDigit(2, 'a', 23, 0, 12); 210 neosegment.setDigit(3, 'c', 23, 0, 12); 211 neosegment.setDigit(4, 'o', 23, 0, 12); 212 neosegment.setDigit(5, 'r', 23, 0, 12); 213 tone(A1, 220, 100); 214 delay(500); 215 neosegment.setDigit(1, 'a', 23, 0, 12); 216 neosegment.setDigit(2, 'c', 23, 0, 12); 217 neosegment.setDigit(3, 'o', 23, 0, 12); 218 neosegment.setDigit(4, 'r', 23, 0, 12); 219 neosegment.setDigit(5, 'n', 23, 0, 12); 220 tone(A1, 220, 100); 221 delay(2000); 222 223 for(int x=0; x<50; x++){ 224 neosegment.setDigit(2, 'c', 0, x, 0); 225 delay(15); 226 } 227 for(int x=0; x<50; x++){ 228 neosegment.setDigit(4, 'r', x, x, 0); 229 delay(15); 230 } 231 for(int x=0; x<50; x++){ 232 neosegment.setDigit(3, 'o', 0, x, x); 233 delay(15); 234 } 235 for(int x=0; x<50; x++){ 236 neosegment.setDigit(5, 'n', x, 0, 0); 237 delay(15); 238 } 239 for(int x=0; x<50; x++){ 240 neosegment.setDigit(1, 'A', x/2, x/2, x/2); 241 delay(15); 242 } 243 delay(500); 244 neosegment.setDigit(1, 'a', 23, 0, 12); 245 neosegment.setDigit(2, 'c', 23, 0, 12); 246 neosegment.setDigit(3, 'o', 23, 0, 12); 247 neosegment.setDigit(4, 'r', 23, 0, 12); 248 neosegment.setDigit(5, 'n', 23, 0, 12); 249 tone(A1, 220, 100); 250 delay(1700); 251 neosegment.clearAll(); 252 delay(500); 253 for(int i = 0; i < 6; i++){ //turn on green lines, middle row, L to R 254 neosegment.setSegment(i, 3, 0, 40, 0); //the '3' segment is middle dash 255 //tone(A1, 440, 100); 256 delay(100); 257 } 258 } 259 260 //special function with '*' 261 else if(key == '*'){ //show HUE value 262 neosegment.clearAll(); 263 264 neosegment.setDigit(0, 'h', 0, 30, 0); 265 neosegment.setDigit(1, 'u', 0, 30, 0); 266 neosegment.setDigit(2, 'e', 0, 30, 0); 267 268 int ones = (((int)knobHue) % 10); 269 int tens = ((((int)knobHue)/10) % 10); 270 int hundreds = ((((int)knobHue)/100) % 10); 271 272 neosegment.setDigit(5, ones, r_byte, g_byte, b_byte); 273 neosegment.setDigit(4, tens, r_byte, g_byte, b_byte); 274 neosegment.setDigit(3, hundreds, r_byte, g_byte, b_byte); 275 Serial.print("red byte: "); 276 Serial.println(r_byte); 277 278 tone(A1, ((knobHue+31)), 200); 279 neoCounter = 0; 280 } 281 282 //number keys 283 else{ // display numbers 284 if(neoCounter%6 == 0){ //clear when screen gets full 285 neosegment.clearAll(); 286 } 287 int neoPosition = (neoCounter % 6); //use modulo operation to loop 288 //through the positions 289 int BLUE = knobUpperMapped; 290 neosegment.setDigit(neoPosition, neoKey, r_byte, g_byte, b_byte); 291 neoCounter++; 292 tone(A1, ((knobUpperMapped * neoKey) + 31), 170); //+31 deals with 293 //the 0 key 294 } 295 } 296 } 297 298 //function to convert Hue, Saturation, Value to Red, Green, Blue 299 void HSVtoRGB(float *r, float *g, float *b, float h, float s, float v){ 300 //HSV is in HUE: degrees, SATURATION: 0 to 1.0, VALUE: 0 to 1.0 301 int i; 302 float f, p, q, t; 303 if( s == 0 ) { 304 // achromatic (grey) 305 *r = *g = *b = v; 306 return; 307 } 308 h /= 60; // sector 0 to 5 309 i = floor( h ); 310 f = h - i; // factorial part of h 311 p = v * ( 1 - s ); 312 q = v * ( 1 - s * f ); 313 t = v * ( 1 - s * ( 1 - f ) ); 314 switch( i ) { 315 case 0: 316 *r = v; 317 *g = t; 318 *b = p; 319 break; 320 case 1: 321 *r = q; 322 *g = v; 323 *b = p; 324 break; 325 case 2: 326 *r = p; 327 *g = v; 328 *b = t; 329 break; 330 case 3: 331 *r = p; 332 *g = q; 333 *b = v; 334 break; 335 case 4: 336 *r = t; 337 *g = p; 338 *b = v; 339 break; 340 default: // case 5: 341 *r = v; 342 *g = p; 343 *b = q; 344 break; 345 } 346 }