aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Harrington <kb0iic@berzerkula.org>2022-04-05 10:22:42 -0500
committerWilliam Harrington <kb0iic@berzerkula.org>2022-04-05 10:22:42 -0500
commita63f6ae77478358b9ec80833939d917234313d39 (patch)
tree83bdda15b5bf906289f8bcb2adf5a1048c22b4c9
parent23419f9daa6441819dcac3c2cfaf5d5adf864d3e (diff)
Normalize all line endings.HEADmaster
-rw-r--r--EveryLaserXSerialChar/EveryLaserXSerialChar.ino1630
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);
+}