diff options
author | William Harrington <kb0iic@berzerkula.org> | 2022-04-05 10:22:42 -0500 |
---|---|---|
committer | William Harrington <kb0iic@berzerkula.org> | 2022-04-05 10:22:42 -0500 |
commit | a63f6ae77478358b9ec80833939d917234313d39 (patch) | |
tree | 83bdda15b5bf906289f8bcb2adf5a1048c22b4c9 | |
parent | 23419f9daa6441819dcac3c2cfaf5d5adf864d3e (diff) |
-rw-r--r-- | EveryLaserXSerialChar/EveryLaserXSerialChar.ino | 1630 |
1 files changed, 815 insertions, 815 deletions
diff --git a/EveryLaserXSerialChar/EveryLaserXSerialChar.ino b/EveryLaserXSerialChar/EveryLaserXSerialChar.ino index 0b2daf9..0319087 100644 --- a/EveryLaserXSerialChar/EveryLaserXSerialChar.ino +++ b/EveryLaserXSerialChar/EveryLaserXSerialChar.ino @@ -1,815 +1,815 @@ -/*
- * Connect LED (string) to pin D4 (PC6) of the Arduino Nano Every.
- *
- * Author: William Harrington
- * Date: someday in the future
- *
- * Board: Arduino Nano Every
- * Arduino IDE 1.8.19
- */
-
-#include <avr/pgmspace.h>
-
-// https://github.com/ClemensAtElektor/Nano_Every_WS2812B
-#include <Nano_Every_WS2812B.h>
-
-typedef struct {
- char id;
- uint16_t pixels;
-} CharacterX;
-
-#define ELEMENTS(x) (sizeof(x) / sizeof(x[0]))
-
-CI_WS2812B LEDs;
-
-// Number of LaserX displays daisychained
-const int NUMDISP PROGMEM = 4;
-
-// LaserX displays have 14 SK8216's in series with with one WS2812B at the end
-const int LEDSPERDISP PROGMEM = 15;
-
-// Multiply number of LEDs per display with number of displays
-const int NUMLEDS PROGMEM = NUMDISP * LEDSPERDISP;
-
-ci_ws2812b_rgb_t rgb[NUMLEDS];
-
-uint8_t red = 0, green = 0, blue = 0;
-
-// For HSV
-float saturation = 0.5, value = 0.5;
-
-// colorSpace selector - default to True HSV
-// 0 - TrueHSV, 1 - PowerHSV, 2 - Varaible sat and val HSV, 3 - Sine RGB
-uint8_t colorSpace = 0;
-
-// color type 0 - fade, 1 - single
-uint8_t colorType = 0;
-
-// TIMER CLICKS
-const uint16_t TIMER_CLICKS PROGMEM = 4500; // 1mS periodic interrupt
-
-// Fade Delay(ms)
-uint16_t fadeDelay = 167; // 167ms fade rate at 16MHz/2 with TIMER_CLICKS interrupts
-
-// Hue
-int hue = 0;
-
-// Brightness (future use)
-int brightness = 0;
-
-// Default laserStr is empty
-String laserStr = "";
-
-// scroll type selector - default to no scroll
-// 0 - no scroll, 1 - scroll right, 2 - scroll left
-uint8_t scrollType = 0;
-
-// Scroll delay(ms)
-uint16_t scrollDelay = 1000; // 1000ms scroll rate at 16MHz/2 with TIMER_CLICKS interrupts
-
-// timer counters
-uint16_t scrollCounter = 0;
-uint16_t fadeCounter = 0;
-
-// counter for rgb sine wave with gamma fix
-float sineCounter = 0.0;
-float pi = 3.14159;
-
-const uint8_t lights[360] PROGMEM = {
- 0, 0, 0, 0, 0, 1, 1, 2,
- 2, 3, 4, 5, 6, 7, 8, 9,
- 11, 12, 13, 15, 17, 18, 20, 22,
- 24, 26, 28, 30, 32, 35, 37, 39,
- 42, 44, 47, 49, 52, 55, 58, 60,
- 63, 66, 69, 72, 75, 78, 81, 85,
- 88, 91, 94, 97, 101, 104, 107, 111,
-114, 117, 121, 124, 127, 131, 134, 137,
-141, 144, 147, 150, 154, 157, 160, 163,
-167, 170, 173, 176, 179, 182, 185, 188,
-191, 194, 197, 200, 202, 205, 208, 210,
-213, 215, 217, 220, 222, 224, 226, 229,
-231, 232, 234, 236, 238, 239, 241, 242,
-244, 245, 246, 248, 249, 250, 251, 251,
-252, 253, 253, 254, 254, 255, 255, 255,
-255, 255, 255, 255, 254, 254, 253, 253,
-252, 251, 251, 250, 249, 248, 246, 245,
-244, 242, 241, 239, 238, 236, 234, 232,
-231, 229, 226, 224, 222, 220, 217, 215,
-213, 210, 208, 205, 202, 200, 197, 194,
-191, 188, 185, 182, 179, 176, 173, 170,
-167, 163, 160, 157, 154, 150, 147, 144,
-141, 137, 134, 131, 127, 124, 121, 117,
-114, 111, 107, 104, 101, 97, 94, 91,
- 88, 85, 81, 78, 75, 72, 69, 66,
- 63, 60, 58, 55, 52, 49, 47, 44,
- 42, 39, 37, 35, 32, 30, 28, 26,
- 24, 22, 20, 18, 17, 15, 13, 12,
- 11, 9, 8, 7, 6, 5, 4, 3,
- 2, 2, 1, 1, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0};
-
-// Gamma fix for linear input values
-const uint8_t gamma[] PROGMEM = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
- 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
- 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
- 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
- 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
- 25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
- 37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
- 51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
- 69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
- 90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
- 115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
- 144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
- 177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
- 215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };
-
-const uint8_t HSVlights[61] PROGMEM = {
- 0, 4, 8, 13, 17, 21, 25, 30, 34, 38, 42, 47, 51, 55, 59, 64, 68, 72, 76,
-81, 85, 89, 93, 98, 102, 106, 110, 115, 119, 123, 127, 132, 136, 140, 144,
-149, 153, 157, 161, 166, 170, 174, 178, 183, 187, 191, 195, 200, 204, 208,
-212, 217, 221, 225, 229, 234, 238, 242, 246, 251, 255};
-
-const uint8_t HSVpower[121] PROGMEM = {
- 0, 2, 4, 6, 8, 11, 13, 15, 17, 19, 21, 23, 25, 28, 30, 32, 34, 36, 38, 40,
-42, 45, 47, 49, 51, 53, 55, 57, 59, 62, 64, 66, 68, 70, 72, 74, 76, 79, 81,
-83, 85, 87, 89, 91, 93, 96, 98, 100, 102, 104, 106, 108, 110, 113, 115, 117,
-119, 121, 123, 125, 127, 130, 132, 134, 136, 138, 140, 142, 144, 147, 149,
-151, 153, 155, 157, 159, 161, 164, 166, 168, 170, 172, 174, 176, 178, 181,
-183, 185, 187, 189, 191, 193, 195, 198, 200, 202, 204, 206, 208, 210, 212,
-215, 217, 219, 221, 223, 225, 227, 229, 232, 234, 236, 238, 240, 242, 244,
-246, 249, 251, 253, 255};
-
-// Available characters a 7 Segment display can show
-// !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~
-const CharacterX character_pixels[] PROGMEM = {
- ' ', 0b0000000000000000,
- '!', 0b0000000000011000,
- '"', 0b0001000000100000,
- '#', 0b0011000011001110,
- '$', 0b0011000011101101,
- '%', 0b0000010100100100,
- '&', 0b0000101101011001,
- '\'', 0b0000000100000000,
- '(', 0b0000100100000000,
- ')', 0b0000011000000000,
- '*', 0b0011111100000000,
- '+', 0b0011000011000000,
- ',', 0b0000010000000000,
- '-', 0b0000000011000000,
- '.', 0b0100000000000000,
- '/', 0b0000010100000000,
- '0', 0b0000000000111111,
- '1', 0b0000000100000110,
- '2', 0b0000000011011011,
- '3', 0b0000000011001111,
- '4', 0b0000000011100110,
- '5', 0b0000000011101101,
- '6', 0b0000000011111100,
- '7', 0b0010000100000001,
- '8', 0b0000000011111111,
- '9', 0b0000000011100111,
- ':', 0b0000000000000000,
- ';', 0b0000000000000000,
- '<', 0b0000100100000000,
- '=', 0b0000000011001000,
- '>', 0b0000011000000000,
- '?', 0b0010000010000011,
- '@', 0b0010000010111111,
- 'A', 0b0000000011110111,
- 'B', 0b0011000010001111,
- 'C', 0b0000000000111001,
- 'D', 0b0011000000001111,
- 'E', 0b0000000011111001,
- 'F', 0b0000000001110001,
- 'G', 0b0000000010111101,
- 'H', 0b0000000011110110,
- 'I', 0b0011000000001001,
- 'J', 0b0000000000011110,
- 'K', 0b0000100101110000,
- 'L', 0b0000000000111000,
- 'M', 0b0000001100110110,
- 'N', 0b0000101000110110,
- 'O', 0b0000000000111111,
- 'P', 0b0000000011110011,
- 'Q', 0b0000100000111111,
- 'R', 0b0000100101110001,
- 'S', 0b0000001010001101,
- 'T', 0b0011000000000001,
- 'U', 0b0000000000111110,
- 'V', 0b0000010100110000,
- 'W', 0b0000110000110110,
- 'X', 0b0000111100000000,
- 'Y', 0b0010001100000000,
- 'Z', 0b0000010100001001,
- '[', 0b0000000000111001,
- '\\', 0b0000101000000000,
- ']', 0b0000000000001111,
- '^', 0b0000001000100000,
- '_', 0b0000000000001000,
- '`', 0b0000001000000000,
- 'a', 0b0000000011110111,
- 'b', 0b0011000010001111,
- 'c', 0b0000000000111001,
- 'd', 0b0011000000001111,
- 'e', 0b0000000011111001,
- 'f', 0b0000000001110001,
- 'g', 0b0000000010111101,
- 'h', 0b0000000011110110,
- 'i', 0b0011000000001001,
- 'j', 0b0000000000011110,
- 'k', 0b0000100101110000,
- 'l', 0b0000000000111000,
- 'm', 0b0000001100110110,
- 'n', 0b0000101000110110,
- 'o', 0b0000000000111111,
- 'p', 0b0000000011110011,
- 'q', 0b0000100000111111,
- 'r', 0b0000100101110001,
- 's', 0b0000001010001101,
- 't', 0b0011000000000001,
- 'u', 0b0000000000111110,
- 'v', 0b0000010100110000,
- 'w', 0b0000110000110110,
- 'x', 0b0000111100000000,
- 'y', 0b0010001100000000,
- 'z', 0b0000010100001001,
- '{', 0b0000011001001001,
- '|', 0b0011000000000000,
- '}', 0b0000100110001001,
- '~', 0b1111111111111111,};
-
-// the real HSV rainbow
-void trueHSV(int hue) {
- if (hue<60) {
- red = 255;
- green = pgm_read_byte(&HSVlights[hue]);
- blue = 0;
- } else if (hue<120) {
- red = pgm_read_byte(&HSVlights[120-hue]);
- green = 255;
- blue = 0;
- } else if (hue<180) {
- red = 0;
- green = 255;
- blue = pgm_read_byte(&HSVlights[hue-120]);
- } else if (hue<240) {
- red = 0;
- green = pgm_read_byte(&HSVlights[240-hue]);
- blue = 255;
- } else if (hue<300) {
- red = pgm_read_byte(&HSVlights[hue-240]);
- green = 0;
- blue = 255;
- } else {
- red = 255;
- green = 0;
- blue = pgm_read_byte(&HSVlights[360-hue]);
- }
-}
-
-// variable saturation and value HSV
-void svHSV(int hue, float saturation, float value) {
- int i;
- float f,p,q,t;
- float h, s, v;
-
- //expand the u8 hue in range 0->255 to 0->359* (there are problems at exactly 360)
- h = hue;
- s = saturation;
- v = value;
-
- if(s == 0) {
- // Achromatic (grey)
- red = round(v*255);
- green = round(v*255);
- blue = round(v*255);
- return;
- }
-
- h /= 60; // sector 0 to 5
- i = floor(h);
- f = h - i; // factorial part of h
- p = v * (1 - s);
- q = v * (1 - s * f);
- t = v * (1 - s * (1 - f));
- switch(i) {
- case 0:
- red = round(255*v);
- green = round(255*t);
- blue = round(255*p);
- break;
- case 1:
- red = round(255*q);
- green = round(255*v);
- blue = round(255*p);
- break;
- case 2:
- red = round(255*p);
- green = round(255*v);
- blue = round(255*t);
- break;
- case 3:
- red = round(255*p);
- green = round(255*q);
- blue = round(255*v);
- break;
- case 4:
- red = round(255*t);
- green = round(255*p);
- blue = round(255*v);
- break;
- default: // case 5:
- red = round(255*v);
- green = round(255*p);
- blue = round(255*q);
- }
-}
-
-// the 'power-conscious' HSV rainbow
-void powerHSV(int hue) {
- if (hue<120) {
- red = pgm_read_byte(&HSVpower[120-hue]);
- green = pgm_read_byte(&HSVpower[hue]);
- blue = 0;
- } else if (hue<240) {
- red = 0;
- green = pgm_read_byte(&HSVpower[240-hue]);
- blue = pgm_read_byte(&HSVpower[hue-120]);
- } else {
- red = pgm_read_byte(&HSVpower[hue-240]);
- green = 0;
- blue = pgm_read_byte(&HSVpower[360-hue]);
- }
-}
-
-void randomHSV() {
- uint8_t color[3];
- byte count, a0, a1, a2;
- color[count] = random(256);
- a0 = count + random(1) + 1;
- color[a0 % 3] = random(256 - color[count]);
- color[(a0 + 1) % 3] = 255 - color[a0 % 3] - color[count];
- red = color[0];
- green = color[1];
- blue = color[2];
- //count += random(15); // avoid repeating patterns
- //count %= 3;
-}
-
-// sine wave rainbow
-void sineRGB(int hue) {
- red = pgm_read_byte(&lights[(hue+120)%360]);
- green = pgm_read_byte(&lights[hue]);
- blue = pgm_read_byte(&lights[(hue+240)%360]);
-}
-
-// sine wave with gamma fix
-void sineRGB_gamma_fix() {
- int redLevel = sin(sineCounter/100 + pi*2/3)*1000;
- int greenLevel = sin(sineCounter/100 + pi*4/3)*1000;
- int blueLevel = sin(sineCounter/100)*1000;
- red = pgm_read_byte(&gamma[map(redLevel,-1000,1000,0,255)]);
- green = pgm_read_byte(&gamma[map(blueLevel,-1000,1000,0,255)]);
- blue = pgm_read_byte(&gamma[map(greenLevel,-1000,1000,0,255)]);
-}
-
-uint16_t findCharacterX( byte c ) {
- CharacterX temp;
-
- for ( uint8_t i = 0; i < ELEMENTS(character_pixels); i++ )
- {
- memcpy_P( &temp, &character_pixels[i], sizeof( CharacterX ));
-
- if ( temp.id == c ) {
- return temp.pixels;
- }
- }
-
- return 0;
-}
-
-void nextColorSpace() {
-
- colorSpace++;
-
- if (colorSpace > 5) {
- colorSpace = 0;
- }
-
- switch (colorSpace) {
- case 0:
- Serial.println("True HSV colorspace");
- break;
- case 1:
- Serial.println("Power HSV colorspace");
- break;
- case 2:
- Serial.println("Var SV HSV colorspace");
- break;
- case 3:
- Serial.println("Random HSV colorspace");
- break;
- case 4:
- Serial.println("Sine RGB colorspace");
- break;
- case 5:
- Serial.println("Sine RGB gamma fix");
- break;
- default:
- break;
- }
-}
-
-void nextColorType() {
- colorType++;
-
- if (colorType > 1) {
- colorType = 0;
- }
-
- switch (colorType) {
- case 0:
- Serial.println("Fade colors");
- break;
- case 1:
- Serial.println("Single color");
- break;
- default:
- break;
- }
-}
-
-void setFadeDelay() {
- String inString = "";
- uint16_t newFadeDelay = 1000;
-
- Serial.println("Enter fade delay and hit enter");
-
- Serial.setTimeout(2500);
- inString = Serial.parseInt();
- Serial.setTimeout(1000);
-
- newFadeDelay = inString.toInt();
-
- Serial.print("New fade delay(ms): ");
- Serial.println(newFadeDelay);
-
- if (newFadeDelay > 0 && newFadeDelay < 10001) {
- fadeDelay = newFadeDelay;
- } else {
- Serial.println("Fade delay out of range (1 - 10000)");
- }
-}
-
-void setScrollDelay() {
- String inString = "";
- uint16_t newScrollDelay = 1000;
-
- Serial.println("Enter scroll delay and hit enter");
-
- Serial.setTimeout(2500);
- inString = Serial.parseInt();
- Serial.setTimeout(1000);
-
- newScrollDelay = inString.toInt();
-
- Serial.print("New scroll delay(ms): ");
- Serial.println(newScrollDelay);
-
- if (newScrollDelay > 0 && newScrollDelay < 10001) {
- scrollDelay = newScrollDelay;
- } else {
- Serial.println("Scroll delay out of range (1 - 10000)");
- }
-}
-
-void setHue() {
- if (colorType == 1) {
- String inString = "";
- int newHue = 0;
-
- // Hue isn't sent if random colorspace is selected
- // Set a color when single color type is selected
- if (colorSpace == 3 && colorType == 1) {
- Serial.println("Setting random color");
- randomHSV();
- return;
- }
-
- Serial.println("Enter hue/angle and hit enter");
-
- Serial.setTimeout(2500);
- inString = Serial.parseInt();
- Serial.setTimeout(1000);
-
- newHue = inString.toInt();
- Serial.print("New hue/angle: ");
- Serial.println(newHue);
-
- if (newHue >= 0 && newHue < 360) {
- hue = newHue;
-
- // Shift hue/angle into rgb sine wave for gamma colorspace
- sineCounter = map(hue,0,359,575,1257);
- } else {
- Serial.println("Hue/Angle out of range (0 - 359)");
- }
- }
-}
-
-void setColors() {
-
- if (colorType == 0) {
-
- sineCounter++;
- //value = fabs(sin(sineCounter/100));
- //saturation = fabs(sin(sineCounter/100 + (pi * 4/3)));
-
- if (hue < 360) {
- hue++;
- } else {
- hue = 0;
- }
- }
-
- // true rainbow
- if (colorSpace == 0)
- trueHSV(hue);
-
- // power conscious HSV rainbow
- if (colorSpace == 1)
- powerHSV(hue);
-
- // variable saturation and value HSV
- if (colorSpace == 2)
- svHSV(hue, saturation, value);
-
- // random HSV
- if (colorSpace == 3 && colorType == 0)
- randomHSV();
-
- // sinewave RGB
- if (colorSpace == 4)
- sineRGB(hue);
-
- // sinewave RGB with gamma fix
- if (colorSpace == 5)
- sineRGB_gamma_fix();
-}
-
-void setLaserStr() {
- Serial.println("Enter string and press enter");
-
- Serial.setTimeout(5000);
- String laserStrnew = Serial.readStringUntil(13);
- Serial.setTimeout(1000);
-
- laserStr = laserStrnew;
-
- // If str is less than number of displays, pad it with spaces
- if (laserStr.length() < NUMDISP) {
- for (uint8_t i = laserStr.length(); i < NUMDISP; i++) {
- laserStr = laserStr + ' ';
- }
- }
-
- Serial.println(laserStrnew);
-}
-
-void scrollText() {
- switch (scrollType) {
- case 1:
- laserStr = shiftRight(laserStr);
- break;
- case 2:
- laserStr = shiftLeft(laserStr);
- break;
- default:
- break;
- }
-}
-
-void nextScrollType() {
- scrollType++;
-
- if (scrollType > 2) {
- scrollType = 0;
- }
-
- switch (scrollType) {
- case 0:
- Serial.println("Scroll OFF");
- break;
- case 1:
- Serial.println("Scroll Right");
- break;
- case 2:
- Serial.println("Scroll Left");
- break;
- default:
- break;
- }
-}
-
-void setSaturation() {
- //if (colorType == 1) {
- String inString = "";
- float newSaturation = 0;
-
- Serial.println("Enter saturation and hit enter");
-
- Serial.setTimeout(2500);
- inString = Serial.parseFloat();
- Serial.setTimeout(1000);
-
- newSaturation = inString.toFloat();
- Serial.print("New saturation: ");
- Serial.println(newSaturation);
-
- if (newSaturation >= 0.0 && newSaturation <= 1.0) {
- saturation = newSaturation;
- } else {
- Serial.println("Saturation out of range (0.0 - 1.0)");
- }
- //}
-}
-
-void setValue() {
- String inString = "";
- float newValue = 0.0;
-
- Serial.println("Enter value and hit enter");
-
- Serial.setTimeout(2500);
- inString = Serial.parseFloat();
- Serial.setTimeout(1000);
-
- newValue = inString.toFloat();
- Serial.print("New value: ");
- Serial.println(newValue);
-
- if (newValue >= 0.0 && newValue <= 1.0) {
- value = newValue;
- } else {
- Serial.println("Value out of range (0.0 - 1.0)");
- }
-}
-
-String shiftLeft(String str) {
-
- uint8_t strlgth = str.length();
- uint8_t first = str[0];
-
- for (uint8_t i = 0; i < strlgth - 1; i++) {
- str[i] = str[i + 1];
- }
-
- str[strlgth - 1] = first;
- return str;
-}
-
-String shiftRight(String str) {
- uint8_t strlgth = str.length();
- uint8_t last = str[strlgth - 1];
-
- for (uint8_t i = (strlgth - 1); i > 0; i--) {
- str[i] = str[i - 1];
- }
-
- str[0] = last;
- return str;
-}
-
-void updateCounters() {
- scrollCounter++;
- fadeCounter++;
-}
-
-ISR(TCB1_INT_vect) {
- updateCounters();
-
- if (fadeCounter >= fadeDelay) {
- setColors();
- fadeCounter = 0;
- }
-
- TCB1.INTFLAGS |= 0x00000001;
-}
-
-void writeStr(String charStr) {
- for (int disp = 0; disp < NUMDISP; disp++) {
- uint16_t c = findCharacterX(charStr[disp]);
- for (uint8_t led = 0; led < LEDSPERDISP; led++) {
- int ledIndex = (LEDSPERDISP * disp) + led;
-
- if (c & (1 << led)) {
- //bit is 1 and set color
- rgb[ledIndex].r = red;
- rgb[ledIndex].g = green;
- rgb[ledIndex].b = blue;
- } else {
- //bit is 0 and set no color
- rgb[ledIndex].r = 0;
- rgb[ledIndex].g = 0;
- rgb[ledIndex].b = 0;
- }
- }
- }
-
- LEDs.write_string(NUMLEDS, rgb);
-
- if (scrollCounter >= scrollDelay) {
- scrollText();
- scrollCounter = 0;
- }
-}
-
-void setup(void) {
- Serial.begin(115200);
- LEDs.begin();
- Serial.println("c (colorspace) C (colortype)");
- Serial.println("d (fade delay) D (scroll delay)");
- Serial.println("h (hue) s (scroll) t (text string)");
- Serial.println("v (value) V (saturation)");
-
- // Clear interrupt
- cli();
-
- // Configure TCB1
- TCB1.CTRLA = 0; // Turn off channel for configuration
- TCB1.CTRLA |= TCB_CLKSEL_CLKDIV2_gc; // Divide system clock by 2
- TCB1.CTRLA |= TCB_ENABLE_bm; // Enable timer
- TCB1.CTRLB = 0; // Periodic interrupt mode
- TCB1.CCMP = TIMER_CLICKS; // Clocks per period
- TCB1.INTCTRL = 0x00000001; // Enable interrupt
- TCB1.CNT = 0;
-
- // Set interrupt
- sei();
-}
-
-
-void loop() {
-
- //while (Serial.available() > 1 && Serial.read() == 27) {
- while (Serial.available()) {
- // Read incoming byte
- uint8_t incomingByte = Serial.read();
-
- switch (incomingByte) {
- case 'c':
- nextColorSpace();
- break;
- case 'C':
- nextColorType();
- break;
- case 'd':
- setFadeDelay();
- break;
- case 'D':
- setScrollDelay();
- break;
- case 'h':
- case 'H':
- setHue();
- break;
- case 's':
- case 'S':
- nextScrollType();
- break;
- case 't':
- case 'T':
- setLaserStr();
- break;
- case 'v':
- setValue();
- break;
- case 'V':
- setSaturation();
- break;
- default:
- break;
- }
-
- }
-
- writeStr(laserStr);
-}
+/* + * Connect LED (string) to pin D4 (PC6) of the Arduino Nano Every. + * + * Author: William Harrington + * Date: someday in the future + * + * Board: Arduino Nano Every + * Arduino IDE 1.8.19 + */ + +#include <avr/pgmspace.h> + +// https://github.com/ClemensAtElektor/Nano_Every_WS2812B +#include <Nano_Every_WS2812B.h> + +typedef struct { + char id; + uint16_t pixels; +} CharacterX; + +#define ELEMENTS(x) (sizeof(x) / sizeof(x[0])) + +CI_WS2812B LEDs; + +// Number of LaserX displays daisychained +const int NUMDISP PROGMEM = 4; + +// LaserX displays have 14 SK8216's in series with with one WS2812B at the end +const int LEDSPERDISP PROGMEM = 15; + +// Multiply number of LEDs per display with number of displays +const int NUMLEDS PROGMEM = NUMDISP * LEDSPERDISP; + +ci_ws2812b_rgb_t rgb[NUMLEDS]; + +uint8_t red = 0, green = 0, blue = 0; + +// For HSV +float saturation = 0.5, value = 0.5; + +// colorSpace selector - default to True HSV +// 0 - TrueHSV, 1 - PowerHSV, 2 - Varaible sat and val HSV, 3 - Sine RGB +uint8_t colorSpace = 0; + +// color type 0 - fade, 1 - single +uint8_t colorType = 0; + +// TIMER CLICKS +const uint16_t TIMER_CLICKS PROGMEM = 4500; // 1mS periodic interrupt + +// Fade Delay(ms) +uint16_t fadeDelay = 167; // 167ms fade rate at 16MHz/2 with TIMER_CLICKS interrupts + +// Hue +int hue = 0; + +// Brightness (future use) +int brightness = 0; + +// Default laserStr is empty +String laserStr = ""; + +// scroll type selector - default to no scroll +// 0 - no scroll, 1 - scroll right, 2 - scroll left +uint8_t scrollType = 0; + +// Scroll delay(ms) +uint16_t scrollDelay = 1000; // 1000ms scroll rate at 16MHz/2 with TIMER_CLICKS interrupts + +// timer counters +uint16_t scrollCounter = 0; +uint16_t fadeCounter = 0; + +// counter for rgb sine wave with gamma fix +float sineCounter = 0.0; +float pi = 3.14159; + +const uint8_t lights[360] PROGMEM = { + 0, 0, 0, 0, 0, 1, 1, 2, + 2, 3, 4, 5, 6, 7, 8, 9, + 11, 12, 13, 15, 17, 18, 20, 22, + 24, 26, 28, 30, 32, 35, 37, 39, + 42, 44, 47, 49, 52, 55, 58, 60, + 63, 66, 69, 72, 75, 78, 81, 85, + 88, 91, 94, 97, 101, 104, 107, 111, +114, 117, 121, 124, 127, 131, 134, 137, +141, 144, 147, 150, 154, 157, 160, 163, +167, 170, 173, 176, 179, 182, 185, 188, +191, 194, 197, 200, 202, 205, 208, 210, +213, 215, 217, 220, 222, 224, 226, 229, +231, 232, 234, 236, 238, 239, 241, 242, +244, 245, 246, 248, 249, 250, 251, 251, +252, 253, 253, 254, 254, 255, 255, 255, +255, 255, 255, 255, 254, 254, 253, 253, +252, 251, 251, 250, 249, 248, 246, 245, +244, 242, 241, 239, 238, 236, 234, 232, +231, 229, 226, 224, 222, 220, 217, 215, +213, 210, 208, 205, 202, 200, 197, 194, +191, 188, 185, 182, 179, 176, 173, 170, +167, 163, 160, 157, 154, 150, 147, 144, +141, 137, 134, 131, 127, 124, 121, 117, +114, 111, 107, 104, 101, 97, 94, 91, + 88, 85, 81, 78, 75, 72, 69, 66, + 63, 60, 58, 55, 52, 49, 47, 44, + 42, 39, 37, 35, 32, 30, 28, 26, + 24, 22, 20, 18, 17, 15, 13, 12, + 11, 9, 8, 7, 6, 5, 4, 3, + 2, 2, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0}; + +// Gamma fix for linear input values +const uint8_t gamma[] PROGMEM = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, + 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, + 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, + 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25, + 25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36, + 37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50, + 51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68, + 69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89, + 90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114, + 115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142, + 144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175, + 177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213, + 215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 }; + +const uint8_t HSVlights[61] PROGMEM = { + 0, 4, 8, 13, 17, 21, 25, 30, 34, 38, 42, 47, 51, 55, 59, 64, 68, 72, 76, +81, 85, 89, 93, 98, 102, 106, 110, 115, 119, 123, 127, 132, 136, 140, 144, +149, 153, 157, 161, 166, 170, 174, 178, 183, 187, 191, 195, 200, 204, 208, +212, 217, 221, 225, 229, 234, 238, 242, 246, 251, 255}; + +const uint8_t HSVpower[121] PROGMEM = { + 0, 2, 4, 6, 8, 11, 13, 15, 17, 19, 21, 23, 25, 28, 30, 32, 34, 36, 38, 40, +42, 45, 47, 49, 51, 53, 55, 57, 59, 62, 64, 66, 68, 70, 72, 74, 76, 79, 81, +83, 85, 87, 89, 91, 93, 96, 98, 100, 102, 104, 106, 108, 110, 113, 115, 117, +119, 121, 123, 125, 127, 130, 132, 134, 136, 138, 140, 142, 144, 147, 149, +151, 153, 155, 157, 159, 161, 164, 166, 168, 170, 172, 174, 176, 178, 181, +183, 185, 187, 189, 191, 193, 195, 198, 200, 202, 204, 206, 208, 210, 212, +215, 217, 219, 221, 223, 225, 227, 229, 232, 234, 236, 238, 240, 242, 244, +246, 249, 251, 253, 255}; + +// Available characters a 7 Segment display can show +// !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ +const CharacterX character_pixels[] PROGMEM = { + ' ', 0b0000000000000000, + '!', 0b0000000000011000, + '"', 0b0001000000100000, + '#', 0b0011000011001110, + '$', 0b0011000011101101, + '%', 0b0000010100100100, + '&', 0b0000101101011001, + '\'', 0b0000000100000000, + '(', 0b0000100100000000, + ')', 0b0000011000000000, + '*', 0b0011111100000000, + '+', 0b0011000011000000, + ',', 0b0000010000000000, + '-', 0b0000000011000000, + '.', 0b0100000000000000, + '/', 0b0000010100000000, + '0', 0b0000000000111111, + '1', 0b0000000100000110, + '2', 0b0000000011011011, + '3', 0b0000000011001111, + '4', 0b0000000011100110, + '5', 0b0000000011101101, + '6', 0b0000000011111100, + '7', 0b0010000100000001, + '8', 0b0000000011111111, + '9', 0b0000000011100111, + ':', 0b0000000000000000, + ';', 0b0000000000000000, + '<', 0b0000100100000000, + '=', 0b0000000011001000, + '>', 0b0000011000000000, + '?', 0b0010000010000011, + '@', 0b0010000010111111, + 'A', 0b0000000011110111, + 'B', 0b0011000010001111, + 'C', 0b0000000000111001, + 'D', 0b0011000000001111, + 'E', 0b0000000011111001, + 'F', 0b0000000001110001, + 'G', 0b0000000010111101, + 'H', 0b0000000011110110, + 'I', 0b0011000000001001, + 'J', 0b0000000000011110, + 'K', 0b0000100101110000, + 'L', 0b0000000000111000, + 'M', 0b0000001100110110, + 'N', 0b0000101000110110, + 'O', 0b0000000000111111, + 'P', 0b0000000011110011, + 'Q', 0b0000100000111111, + 'R', 0b0000100101110001, + 'S', 0b0000001010001101, + 'T', 0b0011000000000001, + 'U', 0b0000000000111110, + 'V', 0b0000010100110000, + 'W', 0b0000110000110110, + 'X', 0b0000111100000000, + 'Y', 0b0010001100000000, + 'Z', 0b0000010100001001, + '[', 0b0000000000111001, + '\\', 0b0000101000000000, + ']', 0b0000000000001111, + '^', 0b0000001000100000, + '_', 0b0000000000001000, + '`', 0b0000001000000000, + 'a', 0b0000000011110111, + 'b', 0b0011000010001111, + 'c', 0b0000000000111001, + 'd', 0b0011000000001111, + 'e', 0b0000000011111001, + 'f', 0b0000000001110001, + 'g', 0b0000000010111101, + 'h', 0b0000000011110110, + 'i', 0b0011000000001001, + 'j', 0b0000000000011110, + 'k', 0b0000100101110000, + 'l', 0b0000000000111000, + 'm', 0b0000001100110110, + 'n', 0b0000101000110110, + 'o', 0b0000000000111111, + 'p', 0b0000000011110011, + 'q', 0b0000100000111111, + 'r', 0b0000100101110001, + 's', 0b0000001010001101, + 't', 0b0011000000000001, + 'u', 0b0000000000111110, + 'v', 0b0000010100110000, + 'w', 0b0000110000110110, + 'x', 0b0000111100000000, + 'y', 0b0010001100000000, + 'z', 0b0000010100001001, + '{', 0b0000011001001001, + '|', 0b0011000000000000, + '}', 0b0000100110001001, + '~', 0b1111111111111111,}; + +// the real HSV rainbow +void trueHSV(int hue) { + if (hue<60) { + red = 255; + green = pgm_read_byte(&HSVlights[hue]); + blue = 0; + } else if (hue<120) { + red = pgm_read_byte(&HSVlights[120-hue]); + green = 255; + blue = 0; + } else if (hue<180) { + red = 0; + green = 255; + blue = pgm_read_byte(&HSVlights[hue-120]); + } else if (hue<240) { + red = 0; + green = pgm_read_byte(&HSVlights[240-hue]); + blue = 255; + } else if (hue<300) { + red = pgm_read_byte(&HSVlights[hue-240]); + green = 0; + blue = 255; + } else { + red = 255; + green = 0; + blue = pgm_read_byte(&HSVlights[360-hue]); + } +} + +// variable saturation and value HSV +void svHSV(int hue, float saturation, float value) { + int i; + float f,p,q,t; + float h, s, v; + + //expand the u8 hue in range 0->255 to 0->359* (there are problems at exactly 360) + h = hue; + s = saturation; + v = value; + + if(s == 0) { + // Achromatic (grey) + red = round(v*255); + green = round(v*255); + blue = round(v*255); + return; + } + + h /= 60; // sector 0 to 5 + i = floor(h); + f = h - i; // factorial part of h + p = v * (1 - s); + q = v * (1 - s * f); + t = v * (1 - s * (1 - f)); + switch(i) { + case 0: + red = round(255*v); + green = round(255*t); + blue = round(255*p); + break; + case 1: + red = round(255*q); + green = round(255*v); + blue = round(255*p); + break; + case 2: + red = round(255*p); + green = round(255*v); + blue = round(255*t); + break; + case 3: + red = round(255*p); + green = round(255*q); + blue = round(255*v); + break; + case 4: + red = round(255*t); + green = round(255*p); + blue = round(255*v); + break; + default: // case 5: + red = round(255*v); + green = round(255*p); + blue = round(255*q); + } +} + +// the 'power-conscious' HSV rainbow +void powerHSV(int hue) { + if (hue<120) { + red = pgm_read_byte(&HSVpower[120-hue]); + green = pgm_read_byte(&HSVpower[hue]); + blue = 0; + } else if (hue<240) { + red = 0; + green = pgm_read_byte(&HSVpower[240-hue]); + blue = pgm_read_byte(&HSVpower[hue-120]); + } else { + red = pgm_read_byte(&HSVpower[hue-240]); + green = 0; + blue = pgm_read_byte(&HSVpower[360-hue]); + } +} + +void randomHSV() { + uint8_t color[3]; + byte count, a0, a1, a2; + color[count] = random(256); + a0 = count + random(1) + 1; + color[a0 % 3] = random(256 - color[count]); + color[(a0 + 1) % 3] = 255 - color[a0 % 3] - color[count]; + red = color[0]; + green = color[1]; + blue = color[2]; + //count += random(15); // avoid repeating patterns + //count %= 3; +} + +// sine wave rainbow +void sineRGB(int hue) { + red = pgm_read_byte(&lights[(hue+120)%360]); + green = pgm_read_byte(&lights[hue]); + blue = pgm_read_byte(&lights[(hue+240)%360]); +} + +// sine wave with gamma fix +void sineRGB_gamma_fix() { + int redLevel = sin(sineCounter/100 + pi*2/3)*1000; + int greenLevel = sin(sineCounter/100 + pi*4/3)*1000; + int blueLevel = sin(sineCounter/100)*1000; + red = pgm_read_byte(&gamma[map(redLevel,-1000,1000,0,255)]); + green = pgm_read_byte(&gamma[map(blueLevel,-1000,1000,0,255)]); + blue = pgm_read_byte(&gamma[map(greenLevel,-1000,1000,0,255)]); +} + +uint16_t findCharacterX( byte c ) { + CharacterX temp; + + for ( uint8_t i = 0; i < ELEMENTS(character_pixels); i++ ) + { + memcpy_P( &temp, &character_pixels[i], sizeof( CharacterX )); + + if ( temp.id == c ) { + return temp.pixels; + } + } + + return 0; +} + +void nextColorSpace() { + + colorSpace++; + + if (colorSpace > 5) { + colorSpace = 0; + } + + switch (colorSpace) { + case 0: + Serial.println("True HSV colorspace"); + break; + case 1: + Serial.println("Power HSV colorspace"); + break; + case 2: + Serial.println("Var SV HSV colorspace"); + break; + case 3: + Serial.println("Random HSV colorspace"); + break; + case 4: + Serial.println("Sine RGB colorspace"); + break; + case 5: + Serial.println("Sine RGB gamma fix"); + break; + default: + break; + } +} + +void nextColorType() { + colorType++; + + if (colorType > 1) { + colorType = 0; + } + + switch (colorType) { + case 0: + Serial.println("Fade colors"); + break; + case 1: + Serial.println("Single color"); + break; + default: + break; + } +} + +void setFadeDelay() { + String inString = ""; + uint16_t newFadeDelay = 1000; + + Serial.println("Enter fade delay and hit enter"); + + Serial.setTimeout(2500); + inString = Serial.parseInt(); + Serial.setTimeout(1000); + + newFadeDelay = inString.toInt(); + + Serial.print("New fade delay(ms): "); + Serial.println(newFadeDelay); + + if (newFadeDelay > 0 && newFadeDelay < 10001) { + fadeDelay = newFadeDelay; + } else { + Serial.println("Fade delay out of range (1 - 10000)"); + } +} + +void setScrollDelay() { + String inString = ""; + uint16_t newScrollDelay = 1000; + + Serial.println("Enter scroll delay and hit enter"); + + Serial.setTimeout(2500); + inString = Serial.parseInt(); + Serial.setTimeout(1000); + + newScrollDelay = inString.toInt(); + + Serial.print("New scroll delay(ms): "); + Serial.println(newScrollDelay); + + if (newScrollDelay > 0 && newScrollDelay < 10001) { + scrollDelay = newScrollDelay; + } else { + Serial.println("Scroll delay out of range (1 - 10000)"); + } +} + +void setHue() { + if (colorType == 1) { + String inString = ""; + int newHue = 0; + + // Hue isn't sent if random colorspace is selected + // Set a color when single color type is selected + if (colorSpace == 3 && colorType == 1) { + Serial.println("Setting random color"); + randomHSV(); + return; + } + + Serial.println("Enter hue/angle and hit enter"); + + Serial.setTimeout(2500); + inString = Serial.parseInt(); + Serial.setTimeout(1000); + + newHue = inString.toInt(); + Serial.print("New hue/angle: "); + Serial.println(newHue); + + if (newHue >= 0 && newHue < 360) { + hue = newHue; + + // Shift hue/angle into rgb sine wave for gamma colorspace + sineCounter = map(hue,0,359,575,1257); + } else { + Serial.println("Hue/Angle out of range (0 - 359)"); + } + } +} + +void setColors() { + + if (colorType == 0) { + + sineCounter++; + //value = fabs(sin(sineCounter/100)); + //saturation = fabs(sin(sineCounter/100 + (pi * 4/3))); + + if (hue < 360) { + hue++; + } else { + hue = 0; + } + } + + // true rainbow + if (colorSpace == 0) + trueHSV(hue); + + // power conscious HSV rainbow + if (colorSpace == 1) + powerHSV(hue); + + // variable saturation and value HSV + if (colorSpace == 2) + svHSV(hue, saturation, value); + + // random HSV + if (colorSpace == 3 && colorType == 0) + randomHSV(); + + // sinewave RGB + if (colorSpace == 4) + sineRGB(hue); + + // sinewave RGB with gamma fix + if (colorSpace == 5) + sineRGB_gamma_fix(); +} + +void setLaserStr() { + Serial.println("Enter string and press enter"); + + Serial.setTimeout(5000); + String laserStrnew = Serial.readStringUntil(13); + Serial.setTimeout(1000); + + laserStr = laserStrnew; + + // If str is less than number of displays, pad it with spaces + if (laserStr.length() < NUMDISP) { + for (uint8_t i = laserStr.length(); i < NUMDISP; i++) { + laserStr = laserStr + ' '; + } + } + + Serial.println(laserStrnew); +} + +void scrollText() { + switch (scrollType) { + case 1: + laserStr = shiftRight(laserStr); + break; + case 2: + laserStr = shiftLeft(laserStr); + break; + default: + break; + } +} + +void nextScrollType() { + scrollType++; + + if (scrollType > 2) { + scrollType = 0; + } + + switch (scrollType) { + case 0: + Serial.println("Scroll OFF"); + break; + case 1: + Serial.println("Scroll Right"); + break; + case 2: + Serial.println("Scroll Left"); + break; + default: + break; + } +} + +void setSaturation() { + //if (colorType == 1) { + String inString = ""; + float newSaturation = 0; + + Serial.println("Enter saturation and hit enter"); + + Serial.setTimeout(2500); + inString = Serial.parseFloat(); + Serial.setTimeout(1000); + + newSaturation = inString.toFloat(); + Serial.print("New saturation: "); + Serial.println(newSaturation); + + if (newSaturation >= 0.0 && newSaturation <= 1.0) { + saturation = newSaturation; + } else { + Serial.println("Saturation out of range (0.0 - 1.0)"); + } + //} +} + +void setValue() { + String inString = ""; + float newValue = 0.0; + + Serial.println("Enter value and hit enter"); + + Serial.setTimeout(2500); + inString = Serial.parseFloat(); + Serial.setTimeout(1000); + + newValue = inString.toFloat(); + Serial.print("New value: "); + Serial.println(newValue); + + if (newValue >= 0.0 && newValue <= 1.0) { + value = newValue; + } else { + Serial.println("Value out of range (0.0 - 1.0)"); + } +} + +String shiftLeft(String str) { + + uint8_t strlgth = str.length(); + uint8_t first = str[0]; + + for (uint8_t i = 0; i < strlgth - 1; i++) { + str[i] = str[i + 1]; + } + + str[strlgth - 1] = first; + return str; +} + +String shiftRight(String str) { + uint8_t strlgth = str.length(); + uint8_t last = str[strlgth - 1]; + + for (uint8_t i = (strlgth - 1); i > 0; i--) { + str[i] = str[i - 1]; + } + + str[0] = last; + return str; +} + +void updateCounters() { + scrollCounter++; + fadeCounter++; +} + +ISR(TCB1_INT_vect) { + updateCounters(); + + if (fadeCounter >= fadeDelay) { + setColors(); + fadeCounter = 0; + } + + TCB1.INTFLAGS |= 0x00000001; +} + +void writeStr(String charStr) { + for (int disp = 0; disp < NUMDISP; disp++) { + uint16_t c = findCharacterX(charStr[disp]); + for (uint8_t led = 0; led < LEDSPERDISP; led++) { + int ledIndex = (LEDSPERDISP * disp) + led; + + if (c & (1 << led)) { + //bit is 1 and set color + rgb[ledIndex].r = red; + rgb[ledIndex].g = green; + rgb[ledIndex].b = blue; + } else { + //bit is 0 and set no color + rgb[ledIndex].r = 0; + rgb[ledIndex].g = 0; + rgb[ledIndex].b = 0; + } + } + } + + LEDs.write_string(NUMLEDS, rgb); + + if (scrollCounter >= scrollDelay) { + scrollText(); + scrollCounter = 0; + } +} + +void setup(void) { + Serial.begin(115200); + LEDs.begin(); + Serial.println("c (colorspace) C (colortype)"); + Serial.println("d (fade delay) D (scroll delay)"); + Serial.println("h (hue) s (scroll) t (text string)"); + Serial.println("v (value) V (saturation)"); + + // Clear interrupt + cli(); + + // Configure TCB1 + TCB1.CTRLA = 0; // Turn off channel for configuration + TCB1.CTRLA |= TCB_CLKSEL_CLKDIV2_gc; // Divide system clock by 2 + TCB1.CTRLA |= TCB_ENABLE_bm; // Enable timer + TCB1.CTRLB = 0; // Periodic interrupt mode + TCB1.CCMP = TIMER_CLICKS; // Clocks per period + TCB1.INTCTRL = 0x00000001; // Enable interrupt + TCB1.CNT = 0; + + // Set interrupt + sei(); +} + + +void loop() { + + //while (Serial.available() > 1 && Serial.read() == 27) { + while (Serial.available()) { + // Read incoming byte + uint8_t incomingByte = Serial.read(); + + switch (incomingByte) { + case 'c': + nextColorSpace(); + break; + case 'C': + nextColorType(); + break; + case 'd': + setFadeDelay(); + break; + case 'D': + setScrollDelay(); + break; + case 'h': + case 'H': + setHue(); + break; + case 's': + case 'S': + nextScrollType(); + break; + case 't': + case 'T': + setLaserStr(); + break; + case 'v': + setValue(); + break; + case 'V': + setSaturation(); + break; + default: + break; + } + + } + + writeStr(laserStr); +} |