/ 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  }