From 2a3c9fc96a3ed7d0a81ca0d3507248eca321762c Mon Sep 17 00:00:00 2001 From: Ingo Rohlf Date: Sat, 17 Aug 2024 12:57:38 +0200 Subject: [PATCH 1/4] Arduino 168, PlatormIO Projekt --- src/.gitignore | 4 + src/.travis.yml | 65 +++ src/LedCube555_V2.ino | 668 ----------------------------- src/lib/readme.txt | 38 ++ src/platformio.ini | 10 + src/src/CubeBase.h | 175 ++++++++ src/src/CubeEffects.h | 181 ++++++++ src/{ => src}/CubeRegister.cpp | 0 src/{ => src}/CubeRegister.h | 0 src/src/CubeTextEffects.h | 164 +++++++ src/{ => src}/LedCube555_V1.ino_V1 | 0 src/src/LedCube555_V3.ino | 64 +++ src/{ => src}/Timer1.cpp | 0 src/{ => src}/Timer1.h | 0 14 files changed, 701 insertions(+), 668 deletions(-) create mode 100644 src/.gitignore create mode 100644 src/.travis.yml delete mode 100644 src/LedCube555_V2.ino create mode 100644 src/lib/readme.txt create mode 100644 src/platformio.ini create mode 100644 src/src/CubeBase.h create mode 100644 src/src/CubeEffects.h rename src/{ => src}/CubeRegister.cpp (100%) rename src/{ => src}/CubeRegister.h (100%) create mode 100644 src/src/CubeTextEffects.h rename src/{ => src}/LedCube555_V1.ino_V1 (100%) create mode 100644 src/src/LedCube555_V3.ino rename src/{ => src}/Timer1.cpp (100%) rename src/{ => src}/Timer1.h (100%) diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..ef55f84 --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,4 @@ +.pioenvs +.clang_complete +.gcc-flags.json +.piolibdeps diff --git a/src/.travis.yml b/src/.travis.yml new file mode 100644 index 0000000..9171b89 --- /dev/null +++ b/src/.travis.yml @@ -0,0 +1,65 @@ +# Continuous Integration (CI) is the practice, in software +# engineering, of merging all developer working copies with a shared mainline +# several times a day < http://docs.platformio.org/en/stable/ci/index.html > +# +# Documentation: +# +# * Travis CI Embedded Builds with PlatformIO +# < https://docs.travis-ci.com/user/integration/platformio/ > +# +# * PlatformIO integration with Travis CI +# < http://docs.platformio.org/en/stable/ci/travis.html > +# +# * User Guide for `platformio ci` command +# < http://docs.platformio.org/en/stable/userguide/cmd_ci.html > +# +# +# Please choice one of the following templates (proposed below) and uncomment +# it (remove "# " before each line) or use own configuration according to the +# Travis CI documentation (see above). +# + + +# +# Template #1: General project. Test it using existing `platformio.ini`. +# + +# language: python +# python: +# - "2.7" +# +# sudo: false +# cache: +# directories: +# - "~/.platformio" +# +# install: +# - pip install -U platformio +# +# script: +# - platformio run + + +# +# Template #2: The project is intended to by used as a library with examples +# + +# language: python +# python: +# - "2.7" +# +# sudo: false +# cache: +# directories: +# - "~/.platformio" +# +# env: +# - PLATFORMIO_CI_SRC=path/to/test/file.c +# - PLATFORMIO_CI_SRC=examples/file.ino +# - PLATFORMIO_CI_SRC=path/to/test/directory +# +# install: +# - pip install -U platformio +# +# script: +# - platformio ci --lib="." --board=TYPE_1 --board=TYPE_2 --board=TYPE_N diff --git a/src/LedCube555_V2.ino b/src/LedCube555_V2.ino deleted file mode 100644 index be3f7ef..0000000 --- a/src/LedCube555_V2.ino +++ /dev/null @@ -1,668 +0,0 @@ -#include - -#include "./Timer1.h" - -#include "CubeRegister.h" - - - -typedef void(*CubeEffects)(unsigned int frame); - - -#define CUBESIZE 5 - -//ShiftRegisterSlow Register ; -CubeRegister Register ; - - - -#define FPS 60 -#define LEDLEVEL 8 - -byte cube[CUBESIZE][CUBESIZE][CUBESIZE]; -volatile unsigned long frame = 0; -unsigned long start; -unsigned long ende; - - -void draw_cube_layer(byte layer, byte level) { - - for (byte z = 0; z < CUBESIZE; z++) { - Register.shift_bit(z == layer); - } - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - - Register.shift_bit((cube[x][y][layer] > level)); - } - - } - Register.register_to_output(); -} - -void setup() { - // Disable Arduino's default millisecond counter (from now on, millis(), micros(), - // delay() and delayMicroseconds() will not work) - - Serial.begin(115200); - //disableMillis(); - Register.reset(); - Register.output_enable(); - //randomize_cube(); - - - // Prepare Timer1 to count - // On 16 MHz Arduino boards, this function has a resolution of 4us - // On 8 MHz Arduino boards, this function has a resolution of 8us - startTimer1(1000000 / (FPS * LEDLEVEL * CUBESIZE)); - - //draw_cube_layer(1, 1); -} -/* - void randomize_cube() { - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - cube[x][y][z] = random(LEDLEVEL + 1); - } - } - } - } -*/ - -void fill_cube(byte brightness) { - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - cube[x][y][z] = min(brightness, LEDLEVEL); - } - } - } -} -/* - void gravity_cube(int x,int y, int z){ - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - cube[x][y][z] = ; - } - } - } - - } -*/ - -void dimm_cube(int diff = -1) { - diff = constrain(diff, -LEDLEVEL, LEDLEVEL); - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - cube[x][y][z] = constrain( cube[x][y][z] + diff, 0, LEDLEVEL); - /* if (cube[x][y][z] > LEDLEVEL) { - cube[x][y][z] = LEDLEVEL; - } else if (cube[x][y][z] < 0) { - cube[x][y][z] = 0; - }*/ - } - } - } -} - -void rotate_ac_cube(int steps) { - byte x = 0; - byte y = 0; - byte backup; - - for (int s = 0 ; s <= steps; s++) { - for (byte z = 0; z < CUBESIZE; z++) { - Serial.println("--------------- GO ---------"); - Serial.println("Backup: 0,0" + (String)(backup)); - - backup = cube[0][0][z]; - - // shift west-side y=0, x=0..max - Serial.println("Links"); - y = 0; - for ( x = 1; x < CUBESIZE; x++) { - Serial.println("x" + (String)(x - 1) + ",y" + (String)y + " <= " + "x" + (String)x + ",y" + (String)y); - cube[x - 1][y][z] = cube[x][y][z]; - }; - - // shift north-side y=0..max, x = max - Serial.println("Vorne"); - x = CUBESIZE - 1; - for (y = 1; y < CUBESIZE; y++) { - Serial.println("x" + (String)(x) + ",y" + (String)(y - 1) + " <= " + "x" + (String)x + ",y" + (String)y); - cube[x][y - 1][z] = cube[x][y][z]; - } - - // shift east-side y=max, x=max..1 - Serial.println("Rechts"); - y = CUBESIZE - 1; - for (x = CUBESIZE - 2 ; x < CUBESIZE; x--) { - Serial.println("x" + (String)(x + 1) + ",y" + (String)y + " <= " + "x" + (String)x + ",y" + (String)y); - cube[x + 1][y][z] = cube[x][y][z]; - } - - x = 0; - Serial.println("Hinten"); - for (y = CUBESIZE - 2 ; y > 0; --y) { - Serial.println("x" + (String)(x) + ",y" + (String)(y + 1) + " <= " + "x" + (String)x + ",y" + (String)y); - cube[x][y + 1][z] = cube[x][y][z]; - } - - Serial.println("Backup: x0,y1 <= " + (String)(backup)); - cube[0][1][z] = backup; - } - delay(50); - } -}; - - -void rotate_cube(int steps, unsigned int frame_delay = 100) { - byte x = 0; - byte y = 0; - byte backup; - - for (int s = 0 ; s < steps; s++) { - for (byte z = 0; z < CUBESIZE; z++) { - backup = cube[0][0][z]; - - // 0,0 -> 0,4 : v - x = 0; - for (y = 1; y < CUBESIZE ; y++) { - cube[x][y - 1][z] = cube[x][y][z]; - }; - - y = CUBESIZE - 1; - for (x = 1; x < CUBESIZE ; x++) { - cube[x - 1][y][z] = cube[x][y][z]; - } - - x = CUBESIZE - 1; - for (y = CUBESIZE - 2 ; y < CUBESIZE ; --y) { - cube[x][y + 1][z] = cube[x][y][z] ; - } - - y = 0 ; - for (x = CUBESIZE - 2 ; x < CUBESIZE ; --x) { - cube[x + 1][y][z] = cube[x][y][z]; - } - cube[1][0][z] = backup; - } - delay(frame_delay); - } -}; - - - -const unsigned long CHAR_5BIT[] = { - 0B0000000000000000000000000, // 36 SPACE (32) - 0B0010000100001000000000100, // 37 ! (33) - 0B0000001010010100000000000, // 36 " (34) - 0B0101011111010101111101010, // 36 # (35) - 0B0111010100011100010101110, // 36 $ (36) - 0B0000101010001000101010000, // 36 % (37) - 0B1000001100011001001011100, // 36 & (38) ?? - 0B0010000100000000000000000, // 36 '(39) - 0B0001000100001000010000010, // 36 ( (40) - 0B0100000100001000010001000, // 36 ) (41) - 0B0000000100011100101000000, // 36 * (42) - 0B0000000100011100010000000, // 36 + (43) - 0B0000000000000000010001000, // 36 , (44) - 0B0000000000011100000000000, // 36 - (45) - 0B0000000000000000000000100, // 39 . (46) - 0B0000100010001000100010000, // 36 / (45) - 0B0111010011101011100101110, // 26 0 (48) - 0B0010001100001000010001110, // 27 1 (49) - 0B1111000001011101000011111, // 28 2 (50) - 0B1111000001011100000111110, // 29 3 - 0B0010001000101001111100100, // 30 4 - 0B1111110000111100000111110, // 31 5 - 0B1111110000111101000111110, // 32 6 - 0B1111100001000100010000100, // 33 7 - 0B0111010001011101000101110, // 34 8 - 0B0111010001011110000111110, // 35 9 (57) - 0B0000000100000000000000100, // 38 : (58) - 0B0000000100000000010001000, // 38 ; (59) - 0B0000100010001000000000001, // 38 < (60) - 0B0000001110000000111000000, // 36 = (61) - 0B1000001000001000100010000, // 38 > (62) - 0B0111010001001100000000100, // 38 ? (63) - 0B0111010111100010111001100, // 38 @ (64 - 0B0111010001111111000110001, // 0 A (97/65) - 0B1111110001111101000111111, // 1 B - 0B0111110000100001000001111, // 2 C - 0B1111010001100011000111110, // 3 D - 0B1111110000111101000011111, // 4 E - 0B1111110000111001000010000, // 5 F - 0B0111110000100111000101111, // 6 G - 0B1000110001111111000110001, // 7 H - 0B0111000100001000010001110, // 8 I - 0B0001100001000011000101111, // 9 J - 0B1000110010111001001010001, // 10 K - 0B1000010000100001000011111, // 11 L - 0B1000111011101011000110001, // 12 M - 0B1000111001101011001110001, // 13 N - 0B0111010001100011000101110, // 14 O - 0B1111010001111101000010000, // 15 P - 0B1111110001101011111100010, // 16 Q - 0B1111010001111101000110001, // 17 R - 0B0111110000011100000111110, // 18 S - 0B1111100100001000010000100, // 19 T - 0B1000110001100011000101110, // 20 U - 0B1000110001010100101000100, // 21 V - 0B1000110001101011010101010, // 22 W - 0B1000101010001000101010001, // 23 X - 0B1000110001010100010000100, // 24 Y - 0B1111100010001000100011111, // 25 Z (122/90) - 0B0011100100001000010000111, // 38 [ (91) - 0B1000001000001000001000001, // 38 \ (92) - 0B1110000100001000010011100, // 38 ] (93) - 0B0010001001000000000000000, // 36 ^ (94) - 0B0000000000000000000011111, // 36 _ (95) - 0B0010000001000000000000000, // 36 ` (96) - 0B0011000100011000010000110, // 36 { (123) - 0B0010000100001000010000100, // 36 | (124) - 0B0110000100001100010001100, // 36 } (125) - 0B0000001000101010001000000, // 36 ~ (126) - 0B0000001010111110111000100 // 41 @ -> Herz (44) - - -}; -unsigned long char_to_5bits(char zeichen) { - // upper case letters + digits - if ((zeichen >= 32) & (zeichen <= 96)) { - return CHAR_5BIT[zeichen - 32]; - } - // lower case letters - if ((zeichen >= 97) & (zeichen <= 122)) { - return CHAR_5BIT[zeichen - 64]; - } - // digits - if ((zeichen >= 123) & (zeichen <= 126)) { - return CHAR_5BIT[zeichen - 22]; - } - return CHAR_5BIT[69]; -} - -// 5 * 5 bits/row, top to bottom -/* - const unsigned long CHAR_5BIT[42] = { - 0B0111010001111111000110001, // 0 A (97/65) - 0B1111110001111101000111111, // 1 B - 0B0111110000100001000001111, // 2 C - 0B1111010001100011000111110, // 3 D - 0B1111110000111101000011111, // 4 E - 0B1111110000111001000010000, // 5 F - 0B0111110000100111000101111, // 6 G - 0B1000110001111111000110001, // 7 H - 0B0111000100001000010001110, // 8 I - 0B0001100001000011000101111, // 9 J - 0B1000110010111001001010001, // 10 K - 0B1000010000100001000011111, // 11 L - 0B1000111011101011000110001, // 12 M - 0B1000111001101011001110001, // 13 N - 0B0111010001100011000101110, // 14 O - 0B1111010001111101000010000, // 15 P - 0B1111110001101011111100010, // 16 Q - 0B1111010001111101000110001, // 17 R - 0B0111110000011100000111110, // 18 S - 0B1111100100001000010000100, // 19 T - 0B1000110001100011000101110, // 20 U - 0B1000110001010100101000100, // 21 V - 0B1000110001101011010101010, // 22 W - 0B1000101010001000101010001, // 23 X - 0B1000110001010100010000100, // 24 Y - 0B1111100010001000100011111, // 25 Z (122/90) - 0B0111010011101011100101110, // 26 ZERO (48) - 0B0010001100001000010001110, // 27 ONE (49) - 0B1111000001011101000011111, // 28 TWO (50) - 0B1111000001011100000111110, // 29 THREE - 0B0010001000101001111100100, // 30 FOUR - 0B1111110000111100000111110, // 31 FIVE - 0B1111110000111101000111110, // 32 SIX - 0B1111100001000100010000100, // 33 SEVEN - 0B0111010001011101000101110, // 34 EIGHT - 0B0111010001011110000111110, // 35 NINE (57) - 0B0000000000000000000000000, // 36 SPACE (32) - 0B0010000100001000000000100, // 37 EXCL (33) - 0B0000000100000000000000100, // 38 COLON (58) - 0B0000000000000000000000100, // 39 POINT (46) - 0B0000000000000000010001000, // 40 COMMA (44) - 0B0000001010111110111000100 // 41 @ -> Herz (44) - }; -*/ -unsigned long char_to_5bits__(char zeichen) { - // special chars - switch (zeichen) { - case 32: return CHAR_5BIT[36]; - case 33: return CHAR_5BIT[37]; - case 58: return CHAR_5BIT[38]; - case 46: return CHAR_5BIT[39]; - case 44: return CHAR_5BIT[40]; - case 64: return CHAR_5BIT[41]; - } - - // upper case letters - if ((zeichen >= 65) & (zeichen <= 90)) { - return CHAR_5BIT[zeichen - 65]; - } - // lower case letters - if ((zeichen >= 97) & (zeichen <= 122)) { - return CHAR_5BIT[zeichen - 97]; - } - // digits - if ((zeichen >= 48) & (zeichen <= 57)) { - return CHAR_5BIT[zeichen - 22]; - } -} - -void write_char(char zeichen, int ebene = 0, byte brightness = LEDLEVEL) { - ebene = constrain(ebene, 0, CUBESIZE - 1); - unsigned long pattern = char_to_5bits(zeichen); - unsigned long mask = 0B1000000000000000000000000; - Serial.println("\nPattern: " + (String)(pattern)); - for (byte y = 0; y < CUBESIZE; y++) { - for (byte x = 0; x < CUBESIZE; x++) { - Serial.print( pattern & mask ); - if (pattern & mask) { - cube[(CUBESIZE - 1) - x][ebene][y] = brightness ; - } else { - cube[(CUBESIZE - 1) - x][ebene][y] = 0 ; - } - mask >>= 1; - //mask = mask << 1; - } - } -} - -void banner_cube(const char *message, int frame_delay = 100) { - - unsigned long pattern;// = char_to_5bits(zeichen); - unsigned long mask;// = 0B1000000000000000000000000; - - for (size_t mp = 0; mp < strlen(message); mp++ ) { - - pattern = char_to_5bits(message[mp]); - mask = 0B1000000000000000000000000; - for (byte y = 0; y < CUBESIZE; y++) { - mask = 0B1000000000000000000000000; - mask >>= y;// * CUBESIZE; - for (byte z = 0; z < CUBESIZE; z++) { - if (pattern & mask) { - cube[0][CUBESIZE - 1][z] = LEDLEVEL; - } else { - cube[0][CUBESIZE - 1][z] = 0; - } - cube[CUBESIZE - 1][CUBESIZE - 1][z] = 0; - mask >>= CUBESIZE; - } - rotate_cube(1, 150); - } - rotate_cube(1, 150); - } - - for (byte cols = 0; cols < (CUBESIZE * 3 - 2); cols++) { - for (byte z = 0; z < CUBESIZE; z++) { - cube[CUBESIZE - 1][CUBESIZE - 1][z] = 0; - } - rotate_cube(1, 150); - - } -} - -void hello_cube(int duration) { - - const char* message = "mama ist die beste!@!@@ " ; - - for (size_t mp = 0; mp < strlen(message); mp++ ) { - int s = CUBESIZE - 1; - for (int i = 0; i < (CUBESIZE + LEDLEVEL); i++) { - dimm_cube(LEDLEVEL / -2); - write_char(message[mp], max(s, 0), LEDLEVEL); - s--; - delay(50); - } - delay(200); - } - fill_cube(0); -} - -void text_cube(const char *message) { - - for (size_t mp = 0; mp < strlen(message); mp++ ) { - int s = CUBESIZE - 1; - for (int i = 0; i < (CUBESIZE + LEDLEVEL); i++) { - dimm_cube(LEDLEVEL / -2 ); - write_char(message[mp], max(s, 0), LEDLEVEL); - s--; - delay(50); - } - delay(200); - } - - fill_cube(0); -} - -void glow_cube(int duration) { - ende = millis() + duration * 1000; - int glow = 0; - int glch = 1; - fill_cube(glow); - while (millis() < ende) { - glow += glch; // ((ende - millis()) / 200) % (LEDLEVEL + 1); - if (glow <= 0) { - glow = 0; - glch = 1; - } else if (glow >= LEDLEVEL) { - glow = LEDLEVEL; - glch = -1; - } - fill_cube(glow); - - delay(100); - } -} - - -void glitzer_cube(int duration) { - start = millis(); - ende = millis() + duration * 1000; - //while ((millis() - start) < 5000 ) { - while (millis() < ende) { - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - if (random(2) > 0) { - cube[x][y][z] = LEDLEVEL; - } else { - cube[x][y][z] = 0; - } - } - } - } - delay(50); - } -} - -void glitzer_cube_levels(int duration) { - start = millis(); - ende = millis() + duration * 1000; - //while ((millis() - start) < 5000 ) { - while (millis() < ende) { - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - cube[x][y][z] = random(LEDLEVEL + 1); - } - } - } - delay(50); - } -} - - -void glitzer_fade_cube(int duration) { - int cleanup = 5; - fill_cube(0); - /*for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - cube[x][y][z] = 0; - } - } - }*/ - /* for (byte n = 0; n < traces; n++) { - punkt.randomize(); - punkt.show(); - } - */ - ende = millis() + duration * 1000; - while (millis() < ende) { - - //while ((millis() - start) < 10000 ) { - //punkt.randomize(); - //punkt.show(); - cube[random(CUBESIZE)][random(CUBESIZE)][random(CUBESIZE)] = random(LEDLEVEL + 1); - cube[random(CUBESIZE)][random(CUBESIZE)][random(CUBESIZE)] = random(LEDLEVEL + 1); - delay(25); - cleanup --; - if (cleanup <= 0) { - cleanup = 5; - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - if (cube[x][y][z] > 0) { - cube[x][y][z] --; - } - } - } - } - - } - } -} - -void dots_cube(int duration) { - byte x; - byte y; - int speed = 50; - fill_cube(0); - for ( x = 0; x < CUBESIZE; x++) { - for ( y = 0; y < CUBESIZE; y++) { - cube[x][y][0] = LEDLEVEL; - } - } - - - ende = millis() + duration * 1000; - while (millis() < ende) { - x = random(CUBESIZE); - y = random(CUBESIZE); - - if (cube[x][y][0] == 0) { - for (int z = CUBESIZE - 1; z >= 0; --z) { - - if (z <= (CUBESIZE - 2)) - cube[x][y][z + 2] = 0; - cube[x][y][z + 1] = LEDLEVEL / 2; - cube[x][y][z] = LEDLEVEL; - delay(speed); - } - - } else { - for (int z = 1; z < CUBESIZE; z++) { - - if (z >= 2) - cube[x][y][z - 2] = 0; - cube[x][y][z - 1] = LEDLEVEL / 2; - cube[x][y][z] = LEDLEVEL; - delay(speed); - } - } - for (byte z = 1; z < CUBESIZE - 1; z++) { - cube[x][y][z] = 0; - } - } -} - -void template_cube(int duration) { - // prepare something - ende = millis() + duration * 1000; - while (millis() < ende) { - // manipulate cube[][][] - delay(25); - } -} - -// const char* messages = {"I°U", "mama ist die allerbeste!°!°", "benjamin", "annika", "5x5x5 led-cube"}; -static const char* const messages[] = {"I°U", "mama ist die allerbeste!°!°", "benjamin", "annika", "5x5x5 led-cube"}; -int message_count = 5; - -void loop() { - int next_duration = random(10, 20); - switch (random(0, 10)) { - case 0: - glow_cube(next_duration); - break; - case 1: - glitzer_cube(next_duration); - break; - case 2: - glitzer_cube_levels(next_duration); - break; - case 3: - glitzer_fade_cube(next_duration); - break; - case 4: - dots_cube(next_duration); - break; - - case 6: - banner_cube(messages[random(message_count)]); - break; - case 7: - text_cube(messages[random(message_count)]); - break; -/* - case 8: - if (random(10) > 5) - text_cube("LED-Cube 5*5*5"); - else - banner_cube("LED-Cube 5*5*5 "); - -*/ - /*write_char('v', 0); - write_char('x', 4); - - rotate_cube(10); - fill_cube(0);*/ - } - - - /* glitzer_cube(random(5, 20)); - glitzer_fade_cube(random(5, 20)); - */ -} - - - -// Define the function which will handle the notifications (interrupts) -ISR(timer1Event) -{ - // if (Serial) - // Serial.println(frame); - - // Reset Timer1 (resetTimer1 should be the first operation for better timer precision) - resetTimer1(); - // For a smaller and faster code, the line above could safely be replaced with a call - // to the function resetTimer1Unsafe() as, despite its name, it IS safe to call - // that function in here (interrupts are disabled) - - // Make sure to do your work as fast as possible, since interrupts are automatically - // disabled when this event happens (refer to interrupts() and noInterrupts() for - // more information on that) - draw_cube_layer(frame % CUBESIZE, frame % LEDLEVEL); - frame ++; -} diff --git a/src/lib/readme.txt b/src/lib/readme.txt new file mode 100644 index 0000000..0d0e7be --- /dev/null +++ b/src/lib/readme.txt @@ -0,0 +1,38 @@ + +This directory is intended for the project specific (private) libraries. +PlatformIO will compile them to static libraries and link to executable file. + +The source code of each library should be placed in separate directory, like +"lib/private_lib/[here are source files]". + +For example, see how can be organized `Foo` and `Bar` libraries: + +|--lib +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| |--Foo +| | |- Foo.c +| | |- Foo.h +| |- readme.txt --> THIS FILE +|- platformio.ini +|--src + |- main.c + +Then in `src/main.c` you should use: + +#include +#include + +// rest H/C/CPP code + +PlatformIO will find your libraries automatically, configure preprocessor's +include paths and build them. + +See additional options for PlatformIO Library Dependency Finder `lib_*`: + +http://docs.platformio.org/en/stable/projectconf.html#lib-install + diff --git a/src/platformio.ini b/src/platformio.ini new file mode 100644 index 0000000..4b88ea8 --- /dev/null +++ b/src/platformio.ini @@ -0,0 +1,10 @@ +# +# PlatformIO Project Configuration File +# +# Please make sure to read documentation with examples first +# http://docs.platformio.org/en/stable/projectconf.html +# +[env:nanoatmega168] +platform = atmelavr +framework = arduino +board = nanoatmega168 diff --git a/src/src/CubeBase.h b/src/src/CubeBase.h new file mode 100644 index 0000000..5b8842d --- /dev/null +++ b/src/src/CubeBase.h @@ -0,0 +1,175 @@ +#ifndef __CUBE_BASE__ +#define __CUBE_BASE__ + +#include "./Timer1.h" +#include "CubeRegister.h" +#include +CubeRegister myRegister = CubeRegister(); + +#define CUBESIZE 5 +#define FPS 60 +#define LEDLEVEL 8 + +byte cube[CUBESIZE][CUBESIZE][CUBESIZE]; + +volatile unsigned long frame = 0; + +void init_cube(void) { + myRegister.reset(); + myRegister.output_enable(); + startTimer1(1000000 / (FPS * LEDLEVEL * CUBESIZE)); +} + +void draw_cube_layer(byte layer, byte level) { + + for (byte z = 0; z < CUBESIZE; z++) { + myRegister.shift_bit(z == layer); + } + for (byte x = 0; x < CUBESIZE; x++) { + for (byte y = 0; y < CUBESIZE; y++) { + myRegister.shift_bit((cube[x][y][layer] > level)); + } + } + myRegister.register_to_output(); +} + +void fill_cube(byte brightness) { + for (byte x = 0; x < CUBESIZE; x++) { + for (byte y = 0; y < CUBESIZE; y++) { + for (byte z = 0; z < CUBESIZE; z++) { + cube[x][y][z] = min(brightness, LEDLEVEL); + } + } + } +} + +void dimm_cube(int diff = -1) { + diff = constrain(diff, -LEDLEVEL, LEDLEVEL); + for (byte x = 0; x < CUBESIZE; x++) { + for (byte y = 0; y < CUBESIZE; y++) { + for (byte z = 0; z < CUBESIZE; z++) { + cube[x][y][z] = constrain(cube[x][y][z] + diff, 0, LEDLEVEL); + } + } + } +} + +void cube_rotate_cover(int steps, unsigned int frame_delay = 100) { + byte x = 0; + byte y = 0; + byte backup; + + for (int s = 0; s < steps; s++) { + for (byte z = 0; z < CUBESIZE; z++) { + backup = cube[0][0][z]; + + // 0,0 -> 0,4 : v + x = 0; + for (y = 1; y < CUBESIZE; y++) { + cube[x][y - 1][z] = cube[x][y][z]; + }; + + y = CUBESIZE - 1; + for (x = 1; x < CUBESIZE; x++) { + cube[x - 1][y][z] = cube[x][y][z]; + } + + x = CUBESIZE - 1; + for (y = CUBESIZE - 2; y < CUBESIZE; --y) { + cube[x][y + 1][z] = cube[x][y][z]; + } + + y = 0; + for (x = CUBESIZE - 2; x < CUBESIZE; --x) { + cube[x + 1][y][z] = cube[x][y][z]; + } + cube[1][0][z] = backup; + } + delay(frame_delay); + } +}; + +void rotate_cube(int steps, unsigned int frame_delay = 100) { + byte x = 0; + byte y = 0; + byte backup; + + for (int s = 0; s < steps; s++) { + for (byte z = 0; z < CUBESIZE; z++) { + backup = cube[0][0][z]; + + // 0,0 -> 0,4 : v + x = 0; + for (y = 1; y < CUBESIZE; y++) { + cube[x][y - 1][z] = cube[x][y][z]; + }; + + y = CUBESIZE - 1; + for (x = 1; x < CUBESIZE; x++) { + cube[x - 1][y][z] = cube[x][y][z]; + } + + x = CUBESIZE - 1; + for (y = CUBESIZE - 2; y < CUBESIZE; --y) { + cube[x][y + 1][z] = cube[x][y][z]; + } + + y = 0; + for (x = CUBESIZE - 2; x < CUBESIZE; --x) { + cube[x + 1][y][z] = cube[x][y][z]; + } + cube[1][0][z] = backup; + } + delay(frame_delay); + } +}; + +/* + void gravity_cube(int x,int y, int z){ + for (byte x = 0; x < CUBESIZE; x++) { + for (byte y = 0; y < CUBESIZE; y++) { + for (byte z = 0; z < CUBESIZE; z++) { + cube[x][y][z] = ; + } + } + } + + } + */ + +/* + void randomize_cube() { + for (byte x = 0; x < CUBESIZE; x++) { + for (byte y = 0; y < CUBESIZE; y++) { + for (byte z = 0; z < CUBESIZE; z++) { + cube[x][y][z] = random(LEDLEVEL + 1); + } + } + } + } + */ + +// Define the function which will handle the notifications (interrupts) +ISR(timer1Event) { + // if (Serial) + // Serial.println(frame); + + // Reset Timer1 (resetTimer1 should be the first operation for better timer + // precision) + resetTimer1(); + // For a smaller and faster code, the line above could safely be replaced with + // a call + // to the function resetTimer1Unsafe() as, despite its name, it IS safe to + // call + // that function in here (interrupts are disabled) + + // Make sure to do your work as fast as possible, since interrupts are + // automatically + // disabled when this event happens (refer to interrupts() and noInterrupts() + // for + // more information on that) + draw_cube_layer(frame % CUBESIZE, frame % LEDLEVEL); + frame++; +}; + +#endif diff --git a/src/src/CubeEffects.h b/src/src/CubeEffects.h new file mode 100644 index 0000000..7b67b75 --- /dev/null +++ b/src/src/CubeEffects.h @@ -0,0 +1,181 @@ +#ifndef __CUBE_EFFECTS__ +#define __CUBE_EFFECTS__ + +#include "CubeBase.h" +#include + +// unsigned long effect_start; +unsigned long effect_ende; +#define MAX_DURATION 20 +#define MIN_DURATION 10 + +void cube_effect_template(int duration = 0) { + // prepare something + if (duration <= 0) + duration = random(MIN_DURATION, MAX_DURATION); + effect_ende = millis() + duration * 1000; + while (millis() < effect_ende) { + // manipulate cube[][][] + delay(25); + } +} + +void cube_startup(int duration = 0) { + if (duration <= 0) + duration = random(MIN_DURATION, MAX_DURATION); + effect_ende = millis() + duration * 1000; + fill_cube(0); + for (int y = 0; y < LEDLEVEL; y++) { + for (int i = 0; i < LEDLEVEL; i++) { + cube[CUBESIZE / 2][CUBESIZE / 2][CUBESIZE - 1] = random(0, y); + delay(25); + } + } + cube[CUBESIZE / 2][CUBESIZE / 2][CUBESIZE - 1] = LEDLEVEL; + delay(250); + for (int z = CUBESIZE - 1; z > 0; z--) { + delay(250); + cube[CUBESIZE / 2][CUBESIZE / 2][z] += LEDLEVEL; + } + + while (millis() < effect_ende) { + } +}; + +void cube_effect_glow(int duration = 0) { + if (duration <= 0) + duration = random(MIN_DURATION, MAX_DURATION); + effect_ende = millis() + duration * 1000; + int glow = 0; + int glch = 1; + fill_cube(glow); + while (millis() < effect_ende) { + glow += glch; // ((effect_ende - millis()) / 200) % (LEDLEVEL + 1); + if (glow <= 0) { + glow = 0; + glch = 1; + } else if (glow >= LEDLEVEL) { + glow = LEDLEVEL; + glch = -1; + } + fill_cube(glow); + + delay(100); + } +}; + +void cube_effect_glitzer(int duration = 0) { + if (duration <= 0) + duration = random(MIN_DURATION, MAX_DURATION); + effect_ende = millis() + duration * 1000; + while (millis() < effect_ende) { + for (byte x = 0; x < CUBESIZE; x++) { + for (byte y = 0; y < CUBESIZE; y++) { + for (byte z = 0; z < CUBESIZE; z++) { + if (random(2) > 0) { + cube[x][y][z] = LEDLEVEL; + } else { + cube[x][y][z] = 0; + } + } + } + } + delay(50); + } +}; + +void cube_effect_glitzer_levels(int duration = 0) { + if (duration <= 0) + duration = random(MIN_DURATION, MAX_DURATION); + effect_ende = millis() + duration * 1000; + + while (millis() < effect_ende) { + for (byte x = 0; x < CUBESIZE; x++) { + for (byte y = 0; y < CUBESIZE; y++) { + for (byte z = 0; z < CUBESIZE; z++) { + cube[x][y][z] = random(LEDLEVEL + 1); + } + } + } + delay(50); + } +}; + +void cube_effect_glitzer_fade(int duration = 0) { + int cleanup = 5; + fill_cube(0); + + if (duration <= 0) + duration = random(MIN_DURATION, MAX_DURATION); + effect_ende = millis() + duration * 1000; + while (millis() < effect_ende) { + + // while ((millis() - effect_start) < 10000 ) { + // punkt.randomize(); + // punkt.show(); + cube[random(CUBESIZE)][random(CUBESIZE)][random(CUBESIZE)] = + random(LEDLEVEL + 1); + cube[random(CUBESIZE)][random(CUBESIZE)][random(CUBESIZE)] = + random(LEDLEVEL + 1); + delay(25); + cleanup--; + if (cleanup <= 0) { + cleanup = 5; + for (byte x = 0; x < CUBESIZE; x++) { + for (byte y = 0; y < CUBESIZE; y++) { + for (byte z = 0; z < CUBESIZE; z++) { + if (cube[x][y][z] > 0) { + cube[x][y][z]--; + } + } + } + } + } + } +}; + +void cube_effect_dots(int duration = 0) { + byte x; + byte y; + int speed = 50; + fill_cube(0); + for (x = 0; x < CUBESIZE; x++) { + for (y = 0; y < CUBESIZE; y++) { + cube[x][y][0] = LEDLEVEL; + } + } + + if (duration <= 0) + duration = random(MIN_DURATION, MAX_DURATION); + effect_ende = millis() + duration * 1000; + while (millis() < effect_ende) { + x = random(CUBESIZE); + y = random(CUBESIZE); + + if (cube[x][y][0] == 0) { + for (int z = CUBESIZE - 1; z >= 0; --z) { + + if (z <= (CUBESIZE - 2)) + cube[x][y][z + 2] = 0; + cube[x][y][z + 1] = LEDLEVEL / 2; + cube[x][y][z] = LEDLEVEL; + delay(speed); + } + + } else { + for (int z = 1; z < CUBESIZE; z++) { + + if (z >= 2) + cube[x][y][z - 2] = 0; + cube[x][y][z - 1] = LEDLEVEL / 2; + cube[x][y][z] = LEDLEVEL; + delay(speed); + } + } + for (byte z = 1; z < CUBESIZE - 1; z++) { + cube[x][y][z] = 0; + } + } +}; + +#endif diff --git a/src/CubeRegister.cpp b/src/src/CubeRegister.cpp similarity index 100% rename from src/CubeRegister.cpp rename to src/src/CubeRegister.cpp diff --git a/src/CubeRegister.h b/src/src/CubeRegister.h similarity index 100% rename from src/CubeRegister.h rename to src/src/CubeRegister.h diff --git a/src/src/CubeTextEffects.h b/src/src/CubeTextEffects.h new file mode 100644 index 0000000..f817773 --- /dev/null +++ b/src/src/CubeTextEffects.h @@ -0,0 +1,164 @@ +#ifndef __CUBE_TEXT_EFFECTS__ +#define __CUBE_TEXT_EFFECTS__ + +#include "./Timer1.h" +#include "CubeBase.h" +#include + +const unsigned long CHAR_5BIT[] = { + 0B0000000000000000000000000, // 36 SPACE (32) + 0B0010000100001000000000100, // 37 ! (33) + 0B0000001010010100000000000, // 36 " (34) + 0B0101011111010101111101010, // 36 # (35) + 0B0111010100011100010101110, // 36 $ (36) + 0B0000101010001000101010000, // 36 % (37) + 0B1000001100011001001011100, // 36 & (38) ?? + 0B0010000100000000000000000, // 36 '(39) + 0B0001000100001000010000010, // 36 ( (40) + 0B0100000100001000010001000, // 36 ) (41) + 0B0000000100011100101000000, // 36 * (42) + 0B0000000100011100010000000, // 36 + (43) + 0B0000000000000000010001000, // 36 , (44) + 0B0000000000011100000000000, // 36 - (45) + 0B0000000000000000000000100, // 39 . (46) + 0B0000100010001000100010000, // 36 / (45) + 0B0111010011101011100101110, // 26 0 (48) + 0B0010001100001000010001110, // 27 1 (49) + 0B1111000001011101000011111, // 28 2 (50) + 0B1111000001011100000111110, // 29 3 + 0B0010001000101001111100100, // 30 4 + 0B1111110000111100000111110, // 31 5 + 0B1111110000111101000111110, // 32 6 + 0B1111100001000100010000100, // 33 7 + 0B0111010001011101000101110, // 34 8 + 0B0111010001011110000111110, // 35 9 (57) + 0B0000000100000000000000100, // 38 : (58) + 0B0000000100000000010001000, // 38 ; (59) + 0B0000100010001000000000001, // 38 < (60) + 0B0000001110000000111000000, // 36 = (61) + 0B1000001000001000100010000, // 38 > (62) + 0B0111010001001100000000100, // 38 ? (63) + 0B0111010111100010111001100, // 38 @ (64 + 0B0111010001111111000110001, // 0 A (97/65) + 0B1111110001111101000111111, // 1 B + 0B0111110000100001000001111, // 2 C + 0B1111010001100011000111110, // 3 D + 0B1111110000111101000011111, // 4 E + 0B1111110000111001000010000, // 5 F + 0B0111110000100111000101111, // 6 G + 0B1000110001111111000110001, // 7 H + 0B0111000100001000010001110, // 8 I + 0B0001100001000011000101111, // 9 J + 0B1000110010111001001010001, // 10 K + 0B1000010000100001000011111, // 11 L + 0B1000111011101011000110001, // 12 M + 0B1000111001101011001110001, // 13 N + 0B0111010001100011000101110, // 14 O + 0B1111010001111101000010000, // 15 P + 0B1111110001101011111100010, // 16 Q + 0B1111010001111101000110001, // 17 R + 0B0111110000011100000111110, // 18 S + 0B1111100100001000010000100, // 19 T + 0B1000110001100011000101110, // 20 U + 0B1000110001010100101000100, // 21 V + 0B1000110001101011010101010, // 22 W + 0B1000101010001000101010001, // 23 X + 0B1000110001010100010000100, // 24 Y + 0B1111100010001000100011111, // 25 Z (122/90) + 0B0011100100001000010000111, // 38 [ (91) + 0B1000001000001000001000001, // 38 \ (92) + 0B1110000100001000010011100, // 38 ] (93) + 0B0010001001000000000000000, // 36 ^ (94) + 0B0000000000000000000011111, // 36 _ (95) + 0B0010000001000000000000000, // 36 ` (96) + 0B0011000100011000010000110, // 36 { (123) + 0B0010000100001000010000100, // 36 | (124) + 0B0110000100001100010001100, // 36 } (125) + 0B0000001000101010001000000, // 36 ~ (126) + 0B0000001010111110111000100 // 41 @ -> Herz (44) +}; + +unsigned long char_to_5bits(char zeichen) { + // upper case letters + digits + if ((zeichen >= 32) & (zeichen <= 96)) { + return CHAR_5BIT[zeichen - 32]; + } + // lower case letters + if ((zeichen >= 97) & (zeichen <= 122)) { + return CHAR_5BIT[zeichen - 64]; + } + // digits + if ((zeichen >= 123) & (zeichen <= 126)) { + return CHAR_5BIT[zeichen - 22]; + } + return CHAR_5BIT[69]; +} + +void write_char(char zeichen, int ebene = 0, byte brightness = LEDLEVEL) { + ebene = constrain(ebene, 0, CUBESIZE - 1); + unsigned long pattern = char_to_5bits(zeichen); + unsigned long mask = 0B1000000000000000000000000; + for (byte y = 0; y < CUBESIZE; y++) { + for (byte x = 0; x < CUBESIZE; x++) { + if (pattern & mask) { + cube[(CUBESIZE - 1) - x][ebene][y] = brightness; + } else { + cube[(CUBESIZE - 1) - x][ebene][y] = 0; + } + mask >>= 1; + } + } +} + +void cube_text_warp(const char *message) { + + for (size_t mp = 0; mp < strlen(message); mp++) { + int s = CUBESIZE - 1; + for (int i = 0; i < (CUBESIZE + LEDLEVEL); i++) { + dimm_cube(LEDLEVEL / -2); + write_char(message[mp], max(s, 0), LEDLEVEL); + s--; + delay(50); + } + delay(200); + } + + fill_cube(0); +} + +void cube_text_banner(const char *message, int frame_delay = 100) { + + unsigned long pattern; // = char_to_5bits(zeichen); + unsigned long mask; // = 0B1000000000000000000000000; + fill_cube(0); + + for (size_t mp = 0; mp < strlen(message); mp++) { + + pattern = char_to_5bits(message[mp]); + mask = 0B1000000000000000000000000; + for (byte y = 0; y < CUBESIZE; y++) { + mask = 0B1000000000000000000000000; + mask >>= y; // * CUBESIZE; + for (byte z = 0; z < CUBESIZE; z++) { + if (pattern & mask) { + cube[0][CUBESIZE - 1][z] = LEDLEVEL; + } else { + cube[0][CUBESIZE - 1][z] = 0; + } + cube[CUBESIZE - 1][CUBESIZE - 1][z] = 0; + mask >>= CUBESIZE; + } + cube_rotate_cover(1, 150); + } + cube_rotate_cover(1, 150); + } + + for (byte cols = 0; cols < (CUBESIZE * 3 - 2); cols++) { + for (byte z = 0; z < CUBESIZE; z++) { + cube[CUBESIZE - 1][CUBESIZE - 1][z] = 0; + } + cube_rotate_cover(1, 150); + } +}; + +#endif diff --git a/src/LedCube555_V1.ino_V1 b/src/src/LedCube555_V1.ino_V1 similarity index 100% rename from src/LedCube555_V1.ino_V1 rename to src/src/LedCube555_V1.ino_V1 diff --git a/src/src/LedCube555_V3.ino b/src/src/LedCube555_V3.ino new file mode 100644 index 0000000..c20dcaa --- /dev/null +++ b/src/src/LedCube555_V3.ino @@ -0,0 +1,64 @@ +#include + +#include "CubeBase.h" +#include "CubeEffects.h" +#include "CubeTextEffects.h" + +void setup() { + Serial.begin(115200); + init_cube(); + cube_startup(); +} + +// const char* messages = {"I°U", "mama ist die allerbeste!°!°", "benjamin", +// "annika", "5x5x5 led-cube"}; +static const char *const messages[] = {"I°U", "mama ist die allerbeste!°!°", + "benjamin", "annika", "5x5x5 led-cube"}; +int message_count = 5; + +void loop() { + // int next_duration = random(10, 20); + switch (random(0, 10)) { + case 0: + cube_effect_glow(); + break; + case 1: + cube_effect_glitzer(); + break; + case 2: + cube_effect_glitzer_levels(); + break; + case 3: + cube_effect_glitzer_fade(); + break; + case 4: + cube_effect_dots(); + break; + case 5: + cube_startup(); + break; + case 6: + cube_text_banner(messages[random(message_count)]); + break; + case 7: + cube_text_warp(messages[random(message_count)]); + break; + /* + case 8: + if (random(10) > 5) + text_cube("LED-Cube 5*5*5"); + else + banner_cube("LED-Cube 5*5*5 "); + + */ + /*write_char('v', 0); + write_char('x', 4); + + rotate_cube(10); + fill_cube(0);*/ + } + + /* glitzer_cube(random(5, 20)); + glitzer_fade_cube(random(5, 20)); + */ +} diff --git a/src/Timer1.cpp b/src/src/Timer1.cpp similarity index 100% rename from src/Timer1.cpp rename to src/src/Timer1.cpp diff --git a/src/Timer1.h b/src/src/Timer1.h similarity index 100% rename from src/Timer1.h rename to src/src/Timer1.h From d55d2036ed7b5fff8558af81b71b36e79a31e1be Mon Sep 17 00:00:00 2001 From: Ingo Rohlf Date: Sat, 17 Aug 2024 12:58:45 +0200 Subject: [PATCH 2/4] Arduino 368, mehr Effekte, mehr Helligkeitsstufen --- src/platformio.ini | 4 +- src/src/CubeBase.h | 44 ++++++++++- src/src/CubeEffects.h | 156 +++++++++++++++++++++++++++++++++++++ src/src/CubeEffects.h.gch | Bin 0 -> 9475 bytes src/src/CubeRegister.h.gch | Bin 0 -> 9475 bytes src/src/CubeTextEffects.h | 2 +- src/src/LedCube555_V3.ino | 31 ++++++-- 7 files changed, 224 insertions(+), 13 deletions(-) create mode 100644 src/src/CubeEffects.h.gch create mode 100644 src/src/CubeRegister.h.gch diff --git a/src/platformio.ini b/src/platformio.ini index 4b88ea8..580f312 100644 --- a/src/platformio.ini +++ b/src/platformio.ini @@ -4,7 +4,7 @@ # Please make sure to read documentation with examples first # http://docs.platformio.org/en/stable/projectconf.html # -[env:nanoatmega168] +[env:nanoatmega328] platform = atmelavr framework = arduino -board = nanoatmega168 +board = nanoatmega328 diff --git a/src/src/CubeBase.h b/src/src/CubeBase.h index 5b8842d..407f032 100644 --- a/src/src/CubeBase.h +++ b/src/src/CubeBase.h @@ -7,8 +7,8 @@ CubeRegister myRegister = CubeRegister(); #define CUBESIZE 5 -#define FPS 60 -#define LEDLEVEL 8 +#define FPS 50 +#define LEDLEVEL 16 byte cube[CUBESIZE][CUBESIZE][CUBESIZE]; @@ -54,6 +54,46 @@ void dimm_cube(int diff = -1) { } } +void cube_move_x(int diff) { + diff = constrain(diff, -CUBESIZE, CUBESIZE); + byte from; + for (byte v = 0; v < CUBESIZE; v++) { + from = (v + diff) % CUBESIZE; + for (byte a = 0; a < CUBESIZE; a++) { + for (byte b = 0; b < CUBESIZE; b++) { + cube[v][a][b] = cube[from][a][b]; + } + } + } +} +void cube_move_y(int diff) { + diff = constrain(diff, -CUBESIZE, CUBESIZE); + byte from; + for (byte v = 0; v < CUBESIZE; v++) { + from = (v + diff) % CUBESIZE; + for (byte a = 0; a < CUBESIZE; a++) { + for (byte b = 0; b < CUBESIZE; b++) { + cube[a][v][b] = cube[a][from][b]; + } + } + } +} + + +void cube_move_z(int diff) { + diff = constrain(diff, -CUBESIZE, CUBESIZE); + byte from; + for (byte v = 0; v < CUBESIZE; v++) { + from = (v + diff) % CUBESIZE; + for (byte a = 0; a < CUBESIZE; a++) { + for (byte b = 0; b < CUBESIZE; b++) { + cube[a][b][v] = cube[a][b][from]; + } + } + } +} + + void cube_rotate_cover(int steps, unsigned int frame_delay = 100) { byte x = 0; byte y = 0; diff --git a/src/src/CubeEffects.h b/src/src/CubeEffects.h index 7b67b75..5536c48 100644 --- a/src/src/CubeEffects.h +++ b/src/src/CubeEffects.h @@ -177,5 +177,161 @@ void cube_effect_dots(int duration = 0) { } } }; +void cube_life(int duration = 0) { + int speed = 50; + int value; + int min = LEDLEVEL * 2; + int max = LEDLEVEL * 4; + + if (duration <= 0) + duration = random(MIN_DURATION, MAX_DURATION); + + // mit zufallsmuster füllen + fill_cube(0); + + for (byte x = 0; x < CUBESIZE; x++) { + for (byte y = 0; y < CUBESIZE; y++) { + for (byte z = 0; z < CUBESIZE; z++) { + if (random(100) >= 50) { + cube[x][y][z] = random(LEDLEVEL + 1); + } + } + } + } + effect_ende = millis() + duration * 1000; + + while (millis() < effect_ende) { + + for (byte x = 0; x < CUBESIZE; x++) { + for (byte y = 0; y < CUBESIZE; y++) { + for (byte z = 0; z < CUBESIZE; z++) { + value = 0; + value += cube[(x - 1) % CUBESIZE][y][z]; + value += cube[(x + 1) % CUBESIZE][y][z]; + value += cube[x][(y - 1) % CUBESIZE][z]; + value += cube[x][(y + 1) % CUBESIZE][z]; + value += cube[x][y][(z - 1) % CUBESIZE]; + value += cube[x][y][(z + 1) % CUBESIZE]; + if ((value < min) || (value >= max)) { + if (cube[x][y][z] > 0) { + cube[x][y][z]--; + }; + + } else { + if (cube[x][y][z] < LEDLEVEL) { + cube[x][y][z]++; + }; + } + } + } + } + + delay(speed); + } +} + +struct Dot { + byte x; + byte y; + byte z; + int vx; + int vy; + int vz; + byte value; +}; + +void cube_moving_dots(int duration = 0) { + int speed = 100; + int dotcount = 2; + Dot dots[dotcount]; + //Dot dot; + for (byte d = 0; d < dotcount; d++) { + dots[d].x = random(CUBESIZE) * 10; + dots[d].y = random(CUBESIZE) * 10; + dots[d].z = random(CUBESIZE) * 10; + dots[d].vx = random(20) - 10; + dots[d].vy = random(20) - 10; + dots[d].vz = random(20) - 10; + dots[d].value = random(LEDLEVEL / 2, LEDLEVEL); + } + // Serial.println("cube: moving "+String(dotcount)+" dots"); + if (duration <= 0) + duration = random(MIN_DURATION, MAX_DURATION); + effect_ende = millis() + duration * 1000; + + // mit zufallsmuster füllen + fill_cube(0); + while (millis() < effect_ende) { + // dimm_cube(LEDLEVEL/-4); + // fill_cube(0); + for (byte d = 0; d < dotcount; d++) { + + cube[dots[d].x / 10][dots[d].y / 10][dots[d].z / 10] = 0; + + if (((dots[d].x + dots[d].vx) <= 0) || + ((dots[d].x + dots[d].vx) >= CUBESIZE * 10)) + dots[d].vx = -dots[d].vx; + if (((dots[d].y + dots[d].vy) <= 0) || + ((dots[d].y + dots[d].vy) >= CUBESIZE * 10)) + dots[d].vy = -dots[d].vy; + if (((dots[d].z + dots[d].vz) <= 0) || + ((dots[d].z + dots[d].vz) >= CUBESIZE * 10)) + dots[d].vz = -dots[d].vz; + + dots[d].x = (dots[d].x + dots[d].vx); + dots[d].y = (dots[d].y + dots[d].vy); + dots[d].z = (dots[d].z + dots[d].vz); + + // Serial.println("Dot + // ["+String(dot.x)+"]["+String(dot.y)+"]["+String(dot.z)+"] / + // ["+String((int)dot.vx)+"]["+String((int)dot.vy)+"]["+String((int)dot.vz)+"] + // = "+String(dot.value)); + cube[dots[d].x / 10][dots[d].y / 10][dots[d].z / 10] = dots[d].value; + } + + delay(speed); + } +} + +void cube_shifting_layer(int duration = 0) { + int speed = 50; + int value,x,y; + fill_cube(0); + for (x = 0; x < CUBESIZE; x++) { + for (y = 0; y < CUBESIZE; y++) { + cube[x][y][0] = LEDLEVEL; + } + } + + if (duration <= 0) + duration = random(MIN_DURATION, MAX_DURATION); + effect_ende = millis() + duration * 1000; + + while (millis() < effect_ende) { + value = random(4); + + switch (value) { + case 0: + cube_move_x(1); + break; + case 1: + cube_move_x(-1); + break; + case 2: + cube_move_y(1); + break; + case 3: + cube_move_y(-1); + break; + case 4: + cube_move_z(1); + break; + case 5: + cube_move_z(-1); + break; + } + delay(speed); + } +} #endif diff --git a/src/src/CubeEffects.h.gch b/src/src/CubeEffects.h.gch new file mode 100644 index 0000000000000000000000000000000000000000..e4bf2984d99e2ab98701cf72f988de8b79277b4f GIT binary patch literal 9475 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 SA%dpWn3h}K-by_~cmD?}9iLAC literal 0 HcmV?d00001 diff --git a/src/src/CubeRegister.h.gch b/src/src/CubeRegister.h.gch new file mode 100644 index 0000000000000000000000000000000000000000..e4bf2984d99e2ab98701cf72f988de8b79277b4f GIT binary patch literal 9475 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 SA%dpWn3h}K-by_~cmD?}9iLAC literal 0 HcmV?d00001 diff --git a/src/src/CubeTextEffects.h b/src/src/CubeTextEffects.h index f817773..99f2b58 100644 --- a/src/src/CubeTextEffects.h +++ b/src/src/CubeTextEffects.h @@ -115,7 +115,7 @@ void cube_text_warp(const char *message) { for (size_t mp = 0; mp < strlen(message); mp++) { int s = CUBESIZE - 1; for (int i = 0; i < (CUBESIZE + LEDLEVEL); i++) { - dimm_cube(LEDLEVEL / -2); + dimm_cube(LEDLEVEL / -4); write_char(message[mp], max(s, 0), LEDLEVEL); s--; delay(50); diff --git a/src/src/LedCube555_V3.ino b/src/src/LedCube555_V3.ino index c20dcaa..48f376e 100644 --- a/src/src/LedCube555_V3.ino +++ b/src/src/LedCube555_V3.ino @@ -5,37 +5,45 @@ #include "CubeTextEffects.h" void setup() { - Serial.begin(115200); +// Serial.begin(115200); init_cube(); - cube_startup(); + randomSeed(analogRead(A0) + analogRead(A1) + analogRead(A2)); +// cube_startup(); } // const char* messages = {"I°U", "mama ist die allerbeste!°!°", "benjamin", // "annika", "5x5x5 led-cube"}; -static const char *const messages[] = {"I°U", "mama ist die allerbeste!°!°", - "benjamin", "annika", "5x5x5 led-cube"}; +//static const char *const messages[] = {"I°U", "mama ist die allerbeste!°!°", +// "benjamin", "annika", "5x5x5 led-cube"}; +static const char *const messages[] = {"silvester", "2017>2018", "2018", + "ohh, ahh", "led-cube"}; + int message_count = 5; void loop() { + + // int next_duration = random(10, 20); - switch (random(0, 10)) { + //switch (9) { + switch (random(20)) { case 0: cube_effect_glow(); break; case 1: - cube_effect_glitzer(); + cube_effect_glitzer_fade(); break; case 2: cube_effect_glitzer_levels(); break; case 3: - cube_effect_glitzer_fade(); + cube_effect_glitzer(); break; case 4: cube_effect_dots(); break; case 5: - cube_startup(); + //cube_startup(); + cube_effect_glitzer_levels(); break; case 6: cube_text_banner(messages[random(message_count)]); @@ -43,6 +51,13 @@ void loop() { case 7: cube_text_warp(messages[random(message_count)]); break; + case 8: + cube_life(); + break; + case 9: + // Serial.println("cube_moving_dots"); + cube_moving_dots(); + break; /* case 8: if (random(10) > 5) From 4c21998682f28806c49ac02207a0c255813dcc94 Mon Sep 17 00:00:00 2001 From: Ingo Rohlf Date: Sat, 17 Aug 2024 13:03:22 +0200 Subject: [PATCH 3/4] Version 4 - funktionerte wohl nicht --- src/src/CubeBase.h | 45 +-- src/src/CubeEffects.h | 156 ----------- src/src/CubeEffects.h.gch | Bin 9475 -> 0 bytes src/src/CubeRegister.cpp | 53 ---- src/src/CubeRegister.h | 73 ----- src/src/CubeRegister.h.gch | Bin 9475 -> 0 bytes src/src/CubeTextEffects.h | 2 +- src/src/LED.cpp | 5 + src/src/LED.h | 11 + src/src/LedCube555_V1.ino_V1 | 518 ----------------------------------- src/src/LedCube555_V3.ino | 79 ------ src/src/TimerOne.cpp | 101 +++++++ 12 files changed, 121 insertions(+), 922 deletions(-) delete mode 100644 src/src/CubeEffects.h.gch delete mode 100644 src/src/CubeRegister.cpp delete mode 100644 src/src/CubeRegister.h delete mode 100644 src/src/CubeRegister.h.gch create mode 100644 src/src/LED.cpp create mode 100644 src/src/LED.h delete mode 100644 src/src/LedCube555_V1.ino_V1 delete mode 100644 src/src/LedCube555_V3.ino create mode 100644 src/src/TimerOne.cpp diff --git a/src/src/CubeBase.h b/src/src/CubeBase.h index 407f032..d9462e2 100644 --- a/src/src/CubeBase.h +++ b/src/src/CubeBase.h @@ -4,11 +4,12 @@ #include "./Timer1.h" #include "CubeRegister.h" #include + CubeRegister myRegister = CubeRegister(); #define CUBESIZE 5 -#define FPS 50 -#define LEDLEVEL 16 +#define FPS 60 +#define LEDLEVEL 8 byte cube[CUBESIZE][CUBESIZE][CUBESIZE]; @@ -54,46 +55,6 @@ void dimm_cube(int diff = -1) { } } -void cube_move_x(int diff) { - diff = constrain(diff, -CUBESIZE, CUBESIZE); - byte from; - for (byte v = 0; v < CUBESIZE; v++) { - from = (v + diff) % CUBESIZE; - for (byte a = 0; a < CUBESIZE; a++) { - for (byte b = 0; b < CUBESIZE; b++) { - cube[v][a][b] = cube[from][a][b]; - } - } - } -} -void cube_move_y(int diff) { - diff = constrain(diff, -CUBESIZE, CUBESIZE); - byte from; - for (byte v = 0; v < CUBESIZE; v++) { - from = (v + diff) % CUBESIZE; - for (byte a = 0; a < CUBESIZE; a++) { - for (byte b = 0; b < CUBESIZE; b++) { - cube[a][v][b] = cube[a][from][b]; - } - } - } -} - - -void cube_move_z(int diff) { - diff = constrain(diff, -CUBESIZE, CUBESIZE); - byte from; - for (byte v = 0; v < CUBESIZE; v++) { - from = (v + diff) % CUBESIZE; - for (byte a = 0; a < CUBESIZE; a++) { - for (byte b = 0; b < CUBESIZE; b++) { - cube[a][b][v] = cube[a][b][from]; - } - } - } -} - - void cube_rotate_cover(int steps, unsigned int frame_delay = 100) { byte x = 0; byte y = 0; diff --git a/src/src/CubeEffects.h b/src/src/CubeEffects.h index 5536c48..7b67b75 100644 --- a/src/src/CubeEffects.h +++ b/src/src/CubeEffects.h @@ -177,161 +177,5 @@ void cube_effect_dots(int duration = 0) { } } }; -void cube_life(int duration = 0) { - int speed = 50; - int value; - int min = LEDLEVEL * 2; - int max = LEDLEVEL * 4; - - if (duration <= 0) - duration = random(MIN_DURATION, MAX_DURATION); - - // mit zufallsmuster füllen - fill_cube(0); - - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - if (random(100) >= 50) { - cube[x][y][z] = random(LEDLEVEL + 1); - } - } - } - } - effect_ende = millis() + duration * 1000; - - while (millis() < effect_ende) { - - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - value = 0; - value += cube[(x - 1) % CUBESIZE][y][z]; - value += cube[(x + 1) % CUBESIZE][y][z]; - value += cube[x][(y - 1) % CUBESIZE][z]; - value += cube[x][(y + 1) % CUBESIZE][z]; - value += cube[x][y][(z - 1) % CUBESIZE]; - value += cube[x][y][(z + 1) % CUBESIZE]; - if ((value < min) || (value >= max)) { - if (cube[x][y][z] > 0) { - cube[x][y][z]--; - }; - - } else { - if (cube[x][y][z] < LEDLEVEL) { - cube[x][y][z]++; - }; - } - } - } - } - - delay(speed); - } -} - -struct Dot { - byte x; - byte y; - byte z; - int vx; - int vy; - int vz; - byte value; -}; - -void cube_moving_dots(int duration = 0) { - int speed = 100; - int dotcount = 2; - Dot dots[dotcount]; - //Dot dot; - for (byte d = 0; d < dotcount; d++) { - dots[d].x = random(CUBESIZE) * 10; - dots[d].y = random(CUBESIZE) * 10; - dots[d].z = random(CUBESIZE) * 10; - dots[d].vx = random(20) - 10; - dots[d].vy = random(20) - 10; - dots[d].vz = random(20) - 10; - dots[d].value = random(LEDLEVEL / 2, LEDLEVEL); - } - // Serial.println("cube: moving "+String(dotcount)+" dots"); - if (duration <= 0) - duration = random(MIN_DURATION, MAX_DURATION); - effect_ende = millis() + duration * 1000; - - // mit zufallsmuster füllen - fill_cube(0); - while (millis() < effect_ende) { - // dimm_cube(LEDLEVEL/-4); - // fill_cube(0); - for (byte d = 0; d < dotcount; d++) { - - cube[dots[d].x / 10][dots[d].y / 10][dots[d].z / 10] = 0; - - if (((dots[d].x + dots[d].vx) <= 0) || - ((dots[d].x + dots[d].vx) >= CUBESIZE * 10)) - dots[d].vx = -dots[d].vx; - if (((dots[d].y + dots[d].vy) <= 0) || - ((dots[d].y + dots[d].vy) >= CUBESIZE * 10)) - dots[d].vy = -dots[d].vy; - if (((dots[d].z + dots[d].vz) <= 0) || - ((dots[d].z + dots[d].vz) >= CUBESIZE * 10)) - dots[d].vz = -dots[d].vz; - - dots[d].x = (dots[d].x + dots[d].vx); - dots[d].y = (dots[d].y + dots[d].vy); - dots[d].z = (dots[d].z + dots[d].vz); - - // Serial.println("Dot - // ["+String(dot.x)+"]["+String(dot.y)+"]["+String(dot.z)+"] / - // ["+String((int)dot.vx)+"]["+String((int)dot.vy)+"]["+String((int)dot.vz)+"] - // = "+String(dot.value)); - cube[dots[d].x / 10][dots[d].y / 10][dots[d].z / 10] = dots[d].value; - } - - delay(speed); - } -} - -void cube_shifting_layer(int duration = 0) { - int speed = 50; - int value,x,y; - fill_cube(0); - for (x = 0; x < CUBESIZE; x++) { - for (y = 0; y < CUBESIZE; y++) { - cube[x][y][0] = LEDLEVEL; - } - } - - if (duration <= 0) - duration = random(MIN_DURATION, MAX_DURATION); - effect_ende = millis() + duration * 1000; - - while (millis() < effect_ende) { - value = random(4); - - switch (value) { - case 0: - cube_move_x(1); - break; - case 1: - cube_move_x(-1); - break; - case 2: - cube_move_y(1); - break; - case 3: - cube_move_y(-1); - break; - case 4: - cube_move_z(1); - break; - case 5: - cube_move_z(-1); - break; - } - delay(speed); - } -} #endif diff --git a/src/src/CubeEffects.h.gch b/src/src/CubeEffects.h.gch deleted file mode 100644 index e4bf2984d99e2ab98701cf72f988de8b79277b4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9475 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 SA%dpWn3h}K-by_~cmD?}9iLAC diff --git a/src/src/CubeRegister.cpp b/src/src/CubeRegister.cpp deleted file mode 100644 index fcd2419..0000000 --- a/src/src/CubeRegister.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "CubeRegister.h" - -void CubeRegister::reset() { - // Port B Pin 8 - 13 - //Serial.println("reset"); - DDRB |= _SER; // _SER als Output - DDRB |= _OE; // _OE als Output - DDRB |= _RCLK; // _RCLK als Output - DDRB |= _SRCLK; // _SRCLK als Output - DDRB |= _SRCLR; // _SRCLR als Output - - output_disable(); - clear_register(); - register_to_output(); - // Serial.println(PORTB); -}; - -void CubeRegister::output_enable() { - // OUTPUT für OE auf 0 setzen - PORTB &= ~_OE; // -> LOW -}; -void CubeRegister::output_disable() { - // OUTPUT für OE auf 1 setzen - PORTB |= _OE; //-> HIGH -}; -void CubeRegister::clear_register() { - PORTB |= _SRCLR; // -> HIGH - PORTB &= ~_SRCLK; // -> LOW - PORTB &= ~_RCLK; // -> LOW - PORTB &= ~_SRCLR; // -> LOW - PORTB &= ~_SRCLR; // -> LOW - PORTB |= _SRCLR; // -> HIGH -}; - -void CubeRegister::shift_bit(bool bit) { - //Serial.println("shift_bit " + (String)(bit)); - if (bit == LOW) { - PORTB &= ~_SER; // -> LOW - } else { - PORTB |= _SER; // -> HIGH - } - PORTB |= _SRCLK; // -> HIGH - PORTB &= ~_SRCLK; // -> LOW -}; - -void CubeRegister::register_to_output() { - //Serial.println("register_to_output"); - // PORTB &= ~_RCLK; // -> LOW - PORTB |= _RCLK; // -> HIGH - //Serial.println(PORTB); - PORTB &= ~_RCLK; // -> LOW - // Serial.println(PORTB); -}; diff --git a/src/src/CubeRegister.h b/src/src/CubeRegister.h deleted file mode 100644 index d3051ca..0000000 --- a/src/src/CubeRegister.h +++ /dev/null @@ -1,73 +0,0 @@ - -#ifndef __CubeRegister__ -#define __CubeRegister__ -#include - -class CubeRegister { - public: - static const byte _SER = 0x10; // 0b00010000; - static const byte _OE = 0x08; // 0b00001000; - static const byte _RCLK = 0x04; // 0b00000100; - static const byte _SRCLK = 0x02; // 0b00000010; - static const byte _SRCLR = 0x01; // 0b00000001; - - void reset(void); - void output_enable(void); - void output_disable(void); - void clear_register(void); - void shift_bit(bool bit); - void register_to_output(void); - -}; - -/* - Version with digitalWrite - #define PIN_SER 12 - #define PIN_OE 11 - #define PIN_RCLK 10 - #define PIN_SRCLK 9 - #define PIN_SRCLR 8 - - class ShiftRegisterSlow { - public: - - void reset() { - pinMode(PIN_SER, OUTPUT); - pinMode(PIN_OE, OUTPUT); - pinMode(PIN_RCLK, OUTPUT); - pinMode(PIN_SRCLK, OUTPUT); - pinMode(PIN_SRCLR, OUTPUT); - - output_disable(); - clear_register(); - register_to_output(); - } - - void output_enable() { - digitalWrite(PIN_OE, LOW); - } - void output_disable() { - digitalWrite(PIN_OE, HIGH); - } - - void clear_register() { - digitalWrite(PIN_SRCLR, HIGH); - digitalWrite(PIN_SRCLK, LOW); - digitalWrite(PIN_RCLK, LOW); - digitalWrite(PIN_SRCLR, LOW); - digitalWrite(PIN_SRCLR, LOW); - digitalWrite(PIN_SRCLR, HIGH); - } - - void shift_bit(bool bit) { - digitalWrite(PIN_SER, bit); - digitalWrite(PIN_SRCLK, HIGH); - digitalWrite(PIN_SRCLK, LOW); - } - void register_to_output() { - digitalWrite(PIN_RCLK, HIGH); - digitalWrite(PIN_RCLK, LOW); - } - }; -*/ -#endif diff --git a/src/src/CubeRegister.h.gch b/src/src/CubeRegister.h.gch deleted file mode 100644 index e4bf2984d99e2ab98701cf72f988de8b79277b4f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9475 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 SA%dpWn3h}K-by_~cmD?}9iLAC diff --git a/src/src/CubeTextEffects.h b/src/src/CubeTextEffects.h index 99f2b58..f817773 100644 --- a/src/src/CubeTextEffects.h +++ b/src/src/CubeTextEffects.h @@ -115,7 +115,7 @@ void cube_text_warp(const char *message) { for (size_t mp = 0; mp < strlen(message); mp++) { int s = CUBESIZE - 1; for (int i = 0; i < (CUBESIZE + LEDLEVEL); i++) { - dimm_cube(LEDLEVEL / -4); + dimm_cube(LEDLEVEL / -2); write_char(message[mp], max(s, 0), LEDLEVEL); s--; delay(50); diff --git a/src/src/LED.cpp b/src/src/LED.cpp new file mode 100644 index 0000000..1c88a62 --- /dev/null +++ b/src/src/LED.cpp @@ -0,0 +1,5 @@ + + +class Led{ + +}; diff --git a/src/src/LED.h b/src/src/LED.h new file mode 100644 index 0000000..4d6c3b1 --- /dev/null +++ b/src/src/LED.h @@ -0,0 +1,11 @@ + +#include "Led.h" + +Led::Led(byte x, byte y, byte z, byte brightness){ + _x=x; + _y=y; + _z=z; + _brightness = brightness; +}; + + diff --git a/src/src/LedCube555_V1.ino_V1 b/src/src/LedCube555_V1.ino_V1 deleted file mode 100644 index 5ce5b06..0000000 --- a/src/src/LedCube555_V1.ino_V1 +++ /dev/null @@ -1,518 +0,0 @@ -#include - -#include "./Timer1.h" - -#include "CubeRegister.h" - - - -typedef void(*CubeEffects)(unsigned int frame); - - -#define CUBESIZE 5 - -//ShiftRegisterSlow Register ; -CubeRegister Register ; - - - -#define FPS 60 -#define LEDLEVEL 8 - -byte cube[CUBESIZE][CUBESIZE][CUBESIZE]; -volatile unsigned long frame = 0; -unsigned long start; -unsigned long ende; - - -class LED { - public: - byte x; - byte y; - byte z; - byte value; - - void show() { - cube[x][y][z] = value; - } - void hide() { - cube[x][y][z] = 0; - } - - void randomize() { - x = random(CUBESIZE + 1); - y = random(CUBESIZE + 1); - z = random(CUBESIZE + 1); - value = random(LEDLEVEL + 1); - } -}; - -class Vector { - public: - int dx; - int dy; - int dz; -}; - -void draw_cube_layer(byte layer, byte level) { - - for (byte z = 0; z < CUBESIZE; z++) { - Register.shift_bit(z == layer); - } - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - - Register.shift_bit((cube[x][y][layer] > level)); - } - - } - Register.register_to_output(); -} - -void setup() { - // Disable Arduino's default millisecond counter (from now on, millis(), micros(), - // delay() and delayMicroseconds() will not work) - - Serial.begin(115200); - //disableMillis(); - Register.reset(); - Register.output_enable(); - //randomize_cube(); - - - // Prepare Timer1 to count - // On 16 MHz Arduino boards, this function has a resolution of 4us - // On 8 MHz Arduino boards, this function has a resolution of 8us - startTimer1(1000000 / (FPS * LEDLEVEL * CUBESIZE)); - - //draw_cube_layer(1, 1); -} -/* - void randomize_cube() { - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - cube[x][y][z] = random(LEDLEVEL + 1); - } - } - } - } -*/ - -void fill_cube(byte brightness) { - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - cube[x][y][z] = min(brightness, LEDLEVEL); - } - } - } -} -/* - void gravity_cube(int x,int y, int z){ - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - cube[x][y][z] = ; - } - } - } - - } -*/ - -void dimm_cube(int diff = -1) { - diff = constrain(diff, -LEDLEVEL, LEDLEVEL); - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - cube[x][y][z] = constrain( cube[x][y][z] + diff, 0, LEDLEVEL); - /* if (cube[x][y][z] > LEDLEVEL) { - cube[x][y][z] = LEDLEVEL; - } else if (cube[x][y][z] < 0) { - cube[x][y][z] = 0; - }*/ - } - } - } -} - -const unsigned long CHAR_5BIT[42] = { - 0B0111010001111111000110001, // 0 A (97/65) - 0B1111110001111101000111111, // 1 B - 0B0111110000100001000001111, // 2 C - 0B1111010001100011000111110, // 3 D - 0B1111110000111101000011111, // 4 E - 0B1111110000111001000010000, // 5 F - 0B0111110000100111000101111, // 6 G - 0B1000110001111111000110001, // 7 H - 0B0111000100001000010001110, // 8 I - 0B0001100001000011000101111, // 9 J - 0B1000110010111001001010001, // 10 K - 0B1000010000100001000011111, // 11 L - 0B1000111011101011000110001, // 12 M - 0B1000111001101011001110001, // 13 N - 0B0111010001100011000101110, // 14 O - 0B1111010001111101000010000, // 15 P - 0B1111110001101011111100010, // 16 Q - 0B1111010001111101000110001, // 17 R - 0B0111110000011100000111110, // 18 S - 0B1111100100001000010000100, // 19 T - 0B1000110001100011000101110, // 20 U - 0B1000110001010100101000100, // 21 V - 0B1000110001101011010101010, // 22 W - 0B1000101010001000101010001, // 23 X - 0B1000110001010100010000100, // 24 Y - 0B1111100010001000100011111, // 25 Z (122/90) - 0B0111010011101011100101110, // 26 ZERO (48) - 0B0010001100001000010001110, // 27 ONE (49) - 0B1111000001011101000011111, // 28 TWO (50) - 0B1111000001011100000111110, // 29 THREE - 0B0010001000101001111100100, // 30 FOUR - 0B1111110000111100000111110, // 31 FIVE - 0B1111110000111101000111110, // 32 SIX - 0B1111100001000100010000100, // 33 SEVEN - 0B0111010001011101000101110, // 34 EIGHT - 0B0111010001011110000111110, // 35 NINE (57) - 0B0000000000000000000000000, // 36 SPACE (32) - 0B0010000100001000000000100, // 37 EXCL (33) - 0B0000000100000000000000100, // 38 COLON (58) - 0B0000000000000000000000100, // 39 POINT (46) - 0B0000000000000000010001000, // 40 COMMA (44) - 0B0000001010111110111000100 // 41 @ -> Herz (44) -}; - -unsigned long char_to_5bits(char zeichen) { - // special chars - switch (zeichen) { - case 32: return CHAR_5BIT[36]; - case 33: return CHAR_5BIT[37]; - case 58: return CHAR_5BIT[38]; - case 46: return CHAR_5BIT[39]; - case 44: return CHAR_5BIT[40]; - case 64: return CHAR_5BIT[41]; - } - - // upper case letters - if ((zeichen >= 65) & (zeichen <= 90)) { - return CHAR_5BIT[zeichen - 65]; - } - // lower case letters - if ((zeichen >= 97) & (zeichen <= 122)) { - return CHAR_5BIT[zeichen - 97]; - } - // digits - if ((zeichen >= 48) & (zeichen <= 57)) { - return CHAR_5BIT[zeichen - 22]; - } -} - -void write_char(char zeichen, int ebene, byte brightness = LEDLEVEL) { - ebene = constrain(ebene, 0, CUBESIZE - 1); - unsigned long pattern = char_to_5bits(zeichen); - unsigned long mask = 0B1000000000000000000000000; - Serial.println("\nPattern: " + (String)(pattern)); - for (byte y = 0; y < CUBESIZE; y++) { - for (byte x = 0; x < CUBESIZE; x++) { - Serial.print( pattern & mask ); - if (pattern & mask) { - cube[(CUBESIZE - 1) - x][ebene][y] = brightness ; - } else { - cube[(CUBESIZE - 1) - x][ebene][y] = 0 ; - } - mask >>= 1; - //mask = mask << 1; - } - } -} - - -void hello_cube(int duration) { - - const char* message = "mama ist die beste!@!@@ " ; - - for (size_t mp = 0; mp < strlen(message); mp++ ) { - int s = CUBESIZE - 1; - for (int i = 0; i < (CUBESIZE + LEDLEVEL); i++) { - dimm_cube(LEDLEVEL / -2); - write_char(message[mp], max(s, 0), LEDLEVEL); - s--; - delay(50); - } - delay(200); - } -} - -void text_cube(const char *message){ - - for (size_t mp = 0; mp < strlen(message); mp++ ) { - int s = CUBESIZE - 1; - for (int i = 0; i < (CUBESIZE + LEDLEVEL); i++) { - dimm_cube(LEDLEVEL / -2 ); - write_char(message[mp], max(s, 0), LEDLEVEL); - s--; - delay(50); - } - delay(200); - } - -} - -void glow_cube(int duration) { - ende = millis() + duration * 1000; - int glow = 0; - int glch = 1; - fill_cube(glow); - while (millis() < ende) { - glow += glch; // ((ende - millis()) / 200) % (LEDLEVEL + 1); - if (glow <= 0){ - glow = 0; - glch = 1; - } else if (glow >= LEDLEVEL){ - glow = LEDLEVEL; - glch = -1; - } - fill_cube(glow); - - delay(100); - } -} - - -void glitzer_cube(int duration) { - start = millis(); - ende = millis() + duration * 1000; - //while ((millis() - start) < 5000 ) { - while (millis() < ende) { - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - if (random(2) > 0) { - cube[x][y][z] = LEDLEVEL; - } else { - cube[x][y][z] = 0; - } - } - } - } - delay(50); - } -} - -void glitzer_cube_levels(int duration) { - start = millis(); - ende = millis() + duration * 1000; - //while ((millis() - start) < 5000 ) { - while (millis() < ende) { - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - cube[x][y][z] = random(LEDLEVEL + 1); - } - } - } - delay(50); - } -} - - -void glitzer_fade_cube(int duration) { - int cleanup = 5; - fill_cube(0); - /*for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - cube[x][y][z] = 0; - } - } - }*/ - /* for (byte n = 0; n < traces; n++) { - punkt.randomize(); - punkt.show(); - } - */ - ende = millis() + duration * 1000; - while (millis() < ende) { - - //while ((millis() - start) < 10000 ) { - //punkt.randomize(); - //punkt.show(); - cube[random(CUBESIZE)][random(CUBESIZE)][random(CUBESIZE)] = random(LEDLEVEL + 1); - cube[random(CUBESIZE)][random(CUBESIZE)][random(CUBESIZE)] = random(LEDLEVEL + 1); - delay(25); - cleanup --; - if (cleanup <= 0) { - cleanup = 5; - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - if (cube[x][y][z] > 0) { - cube[x][y][z] --; - } - } - } - } - - } - } -} - -void dots_cube(int duration) { - byte x; - byte y; - int speed = 50; - fill_cube(0); - for ( x = 0; x < CUBESIZE; x++) { - for ( y = 0; y < CUBESIZE; y++) { - cube[x][y][0] = LEDLEVEL; - } - } - - - ende = millis() + duration * 1000; - while (millis() < ende) { - x = random(CUBESIZE); - y = random(CUBESIZE); - - if (cube[x][y][0] == 0) { - for (int z = CUBESIZE - 1; z >= 0; --z) { - - if (z <= (CUBESIZE - 2)) - cube[x][y][z + 2] = 0; - cube[x][y][z + 1] = LEDLEVEL / 2; - cube[x][y][z] = LEDLEVEL; - delay(speed); - } - - } else { - for (int z = 1; z < CUBESIZE; z++) { - - if (z >= 2) - cube[x][y][z - 2] = 0; - cube[x][y][z - 1] = LEDLEVEL / 2; - cube[x][y][z] = LEDLEVEL; - delay(speed); - } - } - for (byte z = 1; z < CUBESIZE - 1; z++) { - cube[x][y][z] = 0; - } - - - - - } - - -} - -void template_cube(int duration) { - // prepare something - ende = millis() + duration * 1000; - while (millis() < ende) { - // manipulate cube[][][] - delay(25); - } -} - -void traces_cube() { - start = millis(); - int traces = 5; - LED origin[traces]; - LED leds[traces]; - LED ziel[traces]; - - int steps[traces]; - int pos[traces]; - - for (byte n = 0; n < traces; n++) { - origin[n] = LED(); - origin[n].randomize(); - origin[n].z = 0; - leds[n] = LED(); - ziel[n] = LED(); - ziel[n].randomize(); - ziel[n].z = CUBESIZE - 1; - steps[n] = random(5, 20); - pos[n] = 0; - } - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - cube[x][y][z] = 0; - } - } - } - - while ((millis() - start) < 5000 ) { - for (byte n = 0; n < traces; n++) { - - leds[n].hide(); - pos[n] ++; - leds[n].x = origin[n].x + ( (ziel[n].x - origin[n].x) * pos[n] / steps[n]); - leds[n].y = origin[n].y + ( (ziel[n].y - origin[n].y) * pos[n] / steps[n]); - leds[n].z = (origin[n]).z + ( ((ziel[n]).z - origin[n].z) * pos[n] / steps[n]); - leds[n].show(); - - } - - delay(100); - } -} - - -void loop() { - int next_duration = random(5, 10); - switch (random(0, 10)) { - case 0: - glow_cube(next_duration); - break; - case 1: - glitzer_cube(next_duration); - break; - case 2: - glitzer_cube_levels(next_duration); - break; - case 3: - glitzer_fade_cube(next_duration); - break; - case 4: - dots_cube(next_duration); - break; - case 5: - text_cube("i@u"); - break; - case 6: - text_cube("benjamin"); - break; - case 7: - text_cube("annika"); - break; - } - - - /* glitzer_cube(random(5, 20)); - glitzer_fade_cube(random(5, 20)); - */ -} - - - -// Define the function which will handle the notifications (interrupts) -ISR(timer1Event) -{ - // if (Serial) - // Serial.println(frame); - - // Reset Timer1 (resetTimer1 should be the first operation for better timer precision) - resetTimer1(); - // For a smaller and faster code, the line above could safely be replaced with a call - // to the function resetTimer1Unsafe() as, despite its name, it IS safe to call - // that function in here (interrupts are disabled) - - // Make sure to do your work as fast as possible, since interrupts are automatically - // disabled when this event happens (refer to interrupts() and noInterrupts() for - // more information on that) - draw_cube_layer(frame % CUBESIZE, frame % LEDLEVEL); - frame ++; -} diff --git a/src/src/LedCube555_V3.ino b/src/src/LedCube555_V3.ino deleted file mode 100644 index 48f376e..0000000 --- a/src/src/LedCube555_V3.ino +++ /dev/null @@ -1,79 +0,0 @@ -#include - -#include "CubeBase.h" -#include "CubeEffects.h" -#include "CubeTextEffects.h" - -void setup() { -// Serial.begin(115200); - init_cube(); - randomSeed(analogRead(A0) + analogRead(A1) + analogRead(A2)); -// cube_startup(); -} - -// const char* messages = {"I°U", "mama ist die allerbeste!°!°", "benjamin", -// "annika", "5x5x5 led-cube"}; -//static const char *const messages[] = {"I°U", "mama ist die allerbeste!°!°", -// "benjamin", "annika", "5x5x5 led-cube"}; -static const char *const messages[] = {"silvester", "2017>2018", "2018", - "ohh, ahh", "led-cube"}; - -int message_count = 5; - -void loop() { - - - // int next_duration = random(10, 20); - //switch (9) { - switch (random(20)) { - case 0: - cube_effect_glow(); - break; - case 1: - cube_effect_glitzer_fade(); - break; - case 2: - cube_effect_glitzer_levels(); - break; - case 3: - cube_effect_glitzer(); - break; - case 4: - cube_effect_dots(); - break; - case 5: - //cube_startup(); - cube_effect_glitzer_levels(); - break; - case 6: - cube_text_banner(messages[random(message_count)]); - break; - case 7: - cube_text_warp(messages[random(message_count)]); - break; - case 8: - cube_life(); - break; - case 9: - // Serial.println("cube_moving_dots"); - cube_moving_dots(); - break; - /* - case 8: - if (random(10) > 5) - text_cube("LED-Cube 5*5*5"); - else - banner_cube("LED-Cube 5*5*5 "); - - */ - /*write_char('v', 0); - write_char('x', 4); - - rotate_cube(10); - fill_cube(0);*/ - } - - /* glitzer_cube(random(5, 20)); - glitzer_fade_cube(random(5, 20)); - */ -} diff --git a/src/src/TimerOne.cpp b/src/src/TimerOne.cpp new file mode 100644 index 0000000..d5e896c --- /dev/null +++ b/src/src/TimerOne.cpp @@ -0,0 +1,101 @@ +/* + * Interrupt and PWM utilities for 16 bit Timer1 on ATmega168/328 + * Original code by Jesse Tane for http://labs.ideo.com August 2008 + * Modified March 2009 by Jérôme Despatis and Jesse Tane for ATmega328 support + * Modified June 2009 by Michael Polli and Jesse Tane to fix a bug in setPeriod() which caused the timer to stop + * + * This is free software. You can redistribute it and/or modify it under + * the terms of Creative Commons Attribution 3.0 United States License. + * To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/us/ + * or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA. + * + */ + +#include "TimerOne.h" + +TimerOne Timer1; // preinstatiate + +ISR(TIMER1_OVF_vect) // interrupt service routine that wraps a user defined function supplied by attachInterrupt +{ + Timer1.isrCallback(); +} + +void TimerOne::initialize(long microseconds) +{ + TCCR1A = 0; // clear control register A + TCCR1B = _BV(WGM13); // set mode as phase and frequency correct pwm, stop the timer + setPeriod(microseconds); +} + +void TimerOne::setPeriod(long microseconds) +{ + long cycles = (F_CPU * microseconds) / 2000000; // the counter runs backwards after TOP, interrupt is at BOTTOM so divide microseconds by 2 + if(cycles < RESOLUTION) clockSelectBits = _BV(CS10); // no prescale, full xtal + else if((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11); // prescale by /8 + else if((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11) | _BV(CS10); // prescale by /64 + else if((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12); // prescale by /256 + else if((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12) | _BV(CS10); // prescale by /1024 + else cycles = RESOLUTION - 1, clockSelectBits = _BV(CS12) | _BV(CS10); // request was out of bounds, set as maximum + ICR1 = pwmPeriod = cycles; // ICR1 is TOP in p & f correct pwm mode + TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12)); + TCCR1B |= clockSelectBits; // reset clock select register +} + +void TimerOne::setPwmDuty(char pin, int duty) +{ + unsigned long dutyCycle = pwmPeriod; + dutyCycle *= duty; + dutyCycle >>= 10; + if(pin == 1 || pin == 9) OCR1A = dutyCycle; + else if(pin == 2 || pin == 10) OCR1B = dutyCycle; +} + +void TimerOne::pwm(char pin, int duty, long microseconds) // expects duty cycle to be 10 bit (1024) +{ + if(microseconds > 0) setPeriod(microseconds); + if(pin == 1 || pin == 9) { + DDRB |= _BV(PORTB1); // sets data direction register for pwm output pin + TCCR1A |= _BV(COM1A1); // activates the output pin + } + else if(pin == 2 || pin == 10) { + DDRB |= _BV(PORTB2); + TCCR1A |= _BV(COM1B1); + } + setPwmDuty(pin, duty); + start(); +} + +void TimerOne::disablePwm(char pin) +{ + if(pin == 1 || pin == 9) TCCR1A &= ~_BV(COM1A1); // clear the bit that enables pwm on PB1 + else if(pin == 2 || pin == 10) TCCR1A &= ~_BV(COM1B1); // clear the bit that enables pwm on PB2 +} + +void TimerOne::attachInterrupt(void (*isr)(), long microseconds) +{ + if(microseconds > 0) setPeriod(microseconds); + isrCallback = isr; // register the user's callback with the real ISR + TIMSK1 = _BV(TOIE1); // sets the timer overflow interrupt enable bit + sei(); // ensures that interrupts are globally enabled + start(); +} + +void TimerOne::detachInterrupt() +{ + TIMSK1 &= ~_BV(TOIE1); // clears the timer overflow interrupt enable bit +} + +void TimerOne::start() +{ + TCCR1B |= clockSelectBits; +} + +void TimerOne::stop() +{ + TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12)); // clears all clock selects bits +} + +void TimerOne::restart() +{ + TCNT1 = 0; +} From 41b5d939c6ffcdf1b84cc1bb6c5bc41d2ae58be1 Mon Sep 17 00:00:00 2001 From: Ingo Rohlf Date: Sat, 17 Aug 2024 13:05:57 +0200 Subject: [PATCH 4/4] Version 4 - letzter Stand 03.09.2017 --- src/src/CubeAnimations.cpp | 110 ++++++++++++++++++++ src/src/CubeAnimations.h | 39 +++++++ src/src/CubeBase.h | 176 ------------------------------- src/src/CubeEffects.h | 181 -------------------------------- src/src/CubeRegister.cpp | 56 ++++++++++ src/src/CubeRegister.h | 34 ++++++ src/src/CubeTextEffects.h | 164 ----------------------------- src/src/LED.cpp | 5 - src/src/LED.h | 11 -- src/src/LedCube.cpp | 207 +++++++++++++++++++++++++++++++++++++ src/src/LedCube.h | 49 +++++++++ src/src/LedCube555_V4.ino | 74 +++++++++++++ src/src/Timer1.cpp | 169 ------------------------------ src/src/TimerOne.cpp | 8 +- src/src/TimerOne.h | 41 ++++++++ 15 files changed, 614 insertions(+), 710 deletions(-) create mode 100644 src/src/CubeAnimations.cpp create mode 100644 src/src/CubeAnimations.h delete mode 100644 src/src/CubeBase.h delete mode 100644 src/src/CubeEffects.h create mode 100644 src/src/CubeRegister.cpp create mode 100644 src/src/CubeRegister.h delete mode 100644 src/src/CubeTextEffects.h delete mode 100644 src/src/LED.cpp delete mode 100644 src/src/LED.h create mode 100644 src/src/LedCube.cpp create mode 100644 src/src/LedCube.h create mode 100644 src/src/LedCube555_V4.ino delete mode 100644 src/src/Timer1.cpp create mode 100644 src/src/TimerOne.h diff --git a/src/src/CubeAnimations.cpp b/src/src/CubeAnimations.cpp new file mode 100644 index 0000000..a0b06c6 --- /dev/null +++ b/src/src/CubeAnimations.cpp @@ -0,0 +1,110 @@ + +#include "CubeAnimations.h" + +CubeAnimations::CubeAnimations( + LedCube myCube, + unsigned char throttle = 50, + unsigned int duration = 15000): + myCube(myCube), + speed(throttle), + duration(duration){ + +}; + +void CubeAnimations::start(void){ + myCube.reset(); + myCube.start(); +} + +void CubeAnimations::stop(void){ + myCube.reset(); +} + +void CubeAnimations::setSpeed(unsigned char throttle){ + speed = constrain(throttle, 0, 100); +} + +void CubeAnimations::setDuration(unsigned int duration){ + duration = constrain(duration, 0, 100); +} + +bool CubeAnimations::isRunning(void){ + return millis() <= effect_ende; +} + +void CubeAnimations::startAnimation(void){ + effect_ende = millis() + duration; +} +void CubeAnimations::wait(unsigned long time){ + delay((time * speed)/ 100); +} + +void CubeAnimations::glow(void){ + startAnimation(); + unsigned char glow = 0; + bool glow_up; + while (isRunning()){ + if (glow == 0){ + glow_up = true; + } else if (glow == myCube.shades()) { + glow_up = false; + } + glow_up ? glow++ : glow--; + myCube.fill(glow); + wait(200); + } +} + +void CubeAnimations::glitter(unsigned char filling = 50){ + startAnimation(); + filling = constrain(filling, 0, 100); + unsigned char value; + while (isRunning()){ + for (byte x = 0; x < myCube.size(); x++) { + for (byte y = 0; y < myCube.size(); y++) { + for (byte z = 0; z < myCube.size(); z++) { + value = random(100) < filling ? myCube.shades() : 0; + myCube.pixel(x,y,z, value); + } + } + } + wait(100); + } +} + +void CubeAnimations::shaded_glitter(unsigned char filling = 50){ + startAnimation(); + filling = constrain(filling, 0, 100); + unsigned char value; + while (isRunning()){ + for (byte x = 0; x < myCube.size(); x++) { + for (byte y = 0; y < myCube.size(); y++) { + for (byte z = 0; z < myCube.size(); z++) { + value = random(100) < filling ? random(myCube.shades() + 1) : 0; + myCube.pixel(x,y,z, value); + } + } + } + wait(100); + } +} + +void CubeAnimations::dimed_glitter(unsigned char filling = 50){ + startAnimation(); + filling = constrain(filling, 0, 100); + // (total_leds * filling) / (100 * shades) + // (125 * 50) / (100 * 8) = 7 + unsigned char update_count = (myCube.size()^3 * 100) / (filling * myCube.shades()); + unsigned char x,y,z; + + while (isRunning()){ + myCube.shade(-1); + for (unsigned char n=0;n<=update_count;n++){ + x = random(myCube.size()); + y = random(myCube.size()); + z = random(myCube.size()); + myCube.pixel(x,y,z, random(myCube.shades() + 1)); + } + wait(100); + } +} diff --git a/src/src/CubeAnimations.h b/src/src/CubeAnimations.h new file mode 100644 index 0000000..aa01666 --- /dev/null +++ b/src/src/CubeAnimations.h @@ -0,0 +1,39 @@ +#ifndef __CUBE_ANIMATIONS__ +#define __CUBE_ANIMATIONS__ +#include "LedCube.h" + +class CubeAnimations{ + + + +public: + CubeAnimations( + LedCube myCube, + unsigned char throttle, + unsigned int duration + ); + void start(void); + void stop(void); + void setSpeed(unsigned char throttle); + void setDuration(unsigned int duration); + bool isRunning(void); + + void glow(void); + void glitter( unsigned char filling); + void shaded_glitter(unsigned char filling); + void dimed_glitter(unsigned char filling); + + +private: + void startAnimation(void); + void wait(unsigned long time); + + LedCube myCube; + unsigned char status; + unsigned char speed; + unsigned int duration; + unsigned long effect_ende; +}; + + +#endif //__CUBE_ANIMATIONS__ diff --git a/src/src/CubeBase.h b/src/src/CubeBase.h deleted file mode 100644 index d9462e2..0000000 --- a/src/src/CubeBase.h +++ /dev/null @@ -1,176 +0,0 @@ -#ifndef __CUBE_BASE__ -#define __CUBE_BASE__ - -#include "./Timer1.h" -#include "CubeRegister.h" -#include - -CubeRegister myRegister = CubeRegister(); - -#define CUBESIZE 5 -#define FPS 60 -#define LEDLEVEL 8 - -byte cube[CUBESIZE][CUBESIZE][CUBESIZE]; - -volatile unsigned long frame = 0; - -void init_cube(void) { - myRegister.reset(); - myRegister.output_enable(); - startTimer1(1000000 / (FPS * LEDLEVEL * CUBESIZE)); -} - -void draw_cube_layer(byte layer, byte level) { - - for (byte z = 0; z < CUBESIZE; z++) { - myRegister.shift_bit(z == layer); - } - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - myRegister.shift_bit((cube[x][y][layer] > level)); - } - } - myRegister.register_to_output(); -} - -void fill_cube(byte brightness) { - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - cube[x][y][z] = min(brightness, LEDLEVEL); - } - } - } -} - -void dimm_cube(int diff = -1) { - diff = constrain(diff, -LEDLEVEL, LEDLEVEL); - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - cube[x][y][z] = constrain(cube[x][y][z] + diff, 0, LEDLEVEL); - } - } - } -} - -void cube_rotate_cover(int steps, unsigned int frame_delay = 100) { - byte x = 0; - byte y = 0; - byte backup; - - for (int s = 0; s < steps; s++) { - for (byte z = 0; z < CUBESIZE; z++) { - backup = cube[0][0][z]; - - // 0,0 -> 0,4 : v - x = 0; - for (y = 1; y < CUBESIZE; y++) { - cube[x][y - 1][z] = cube[x][y][z]; - }; - - y = CUBESIZE - 1; - for (x = 1; x < CUBESIZE; x++) { - cube[x - 1][y][z] = cube[x][y][z]; - } - - x = CUBESIZE - 1; - for (y = CUBESIZE - 2; y < CUBESIZE; --y) { - cube[x][y + 1][z] = cube[x][y][z]; - } - - y = 0; - for (x = CUBESIZE - 2; x < CUBESIZE; --x) { - cube[x + 1][y][z] = cube[x][y][z]; - } - cube[1][0][z] = backup; - } - delay(frame_delay); - } -}; - -void rotate_cube(int steps, unsigned int frame_delay = 100) { - byte x = 0; - byte y = 0; - byte backup; - - for (int s = 0; s < steps; s++) { - for (byte z = 0; z < CUBESIZE; z++) { - backup = cube[0][0][z]; - - // 0,0 -> 0,4 : v - x = 0; - for (y = 1; y < CUBESIZE; y++) { - cube[x][y - 1][z] = cube[x][y][z]; - }; - - y = CUBESIZE - 1; - for (x = 1; x < CUBESIZE; x++) { - cube[x - 1][y][z] = cube[x][y][z]; - } - - x = CUBESIZE - 1; - for (y = CUBESIZE - 2; y < CUBESIZE; --y) { - cube[x][y + 1][z] = cube[x][y][z]; - } - - y = 0; - for (x = CUBESIZE - 2; x < CUBESIZE; --x) { - cube[x + 1][y][z] = cube[x][y][z]; - } - cube[1][0][z] = backup; - } - delay(frame_delay); - } -}; - -/* - void gravity_cube(int x,int y, int z){ - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - cube[x][y][z] = ; - } - } - } - - } - */ - -/* - void randomize_cube() { - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - cube[x][y][z] = random(LEDLEVEL + 1); - } - } - } - } - */ - -// Define the function which will handle the notifications (interrupts) -ISR(timer1Event) { - // if (Serial) - // Serial.println(frame); - - // Reset Timer1 (resetTimer1 should be the first operation for better timer - // precision) - resetTimer1(); - // For a smaller and faster code, the line above could safely be replaced with - // a call - // to the function resetTimer1Unsafe() as, despite its name, it IS safe to - // call - // that function in here (interrupts are disabled) - - // Make sure to do your work as fast as possible, since interrupts are - // automatically - // disabled when this event happens (refer to interrupts() and noInterrupts() - // for - // more information on that) - draw_cube_layer(frame % CUBESIZE, frame % LEDLEVEL); - frame++; -}; - -#endif diff --git a/src/src/CubeEffects.h b/src/src/CubeEffects.h deleted file mode 100644 index 7b67b75..0000000 --- a/src/src/CubeEffects.h +++ /dev/null @@ -1,181 +0,0 @@ -#ifndef __CUBE_EFFECTS__ -#define __CUBE_EFFECTS__ - -#include "CubeBase.h" -#include - -// unsigned long effect_start; -unsigned long effect_ende; -#define MAX_DURATION 20 -#define MIN_DURATION 10 - -void cube_effect_template(int duration = 0) { - // prepare something - if (duration <= 0) - duration = random(MIN_DURATION, MAX_DURATION); - effect_ende = millis() + duration * 1000; - while (millis() < effect_ende) { - // manipulate cube[][][] - delay(25); - } -} - -void cube_startup(int duration = 0) { - if (duration <= 0) - duration = random(MIN_DURATION, MAX_DURATION); - effect_ende = millis() + duration * 1000; - fill_cube(0); - for (int y = 0; y < LEDLEVEL; y++) { - for (int i = 0; i < LEDLEVEL; i++) { - cube[CUBESIZE / 2][CUBESIZE / 2][CUBESIZE - 1] = random(0, y); - delay(25); - } - } - cube[CUBESIZE / 2][CUBESIZE / 2][CUBESIZE - 1] = LEDLEVEL; - delay(250); - for (int z = CUBESIZE - 1; z > 0; z--) { - delay(250); - cube[CUBESIZE / 2][CUBESIZE / 2][z] += LEDLEVEL; - } - - while (millis() < effect_ende) { - } -}; - -void cube_effect_glow(int duration = 0) { - if (duration <= 0) - duration = random(MIN_DURATION, MAX_DURATION); - effect_ende = millis() + duration * 1000; - int glow = 0; - int glch = 1; - fill_cube(glow); - while (millis() < effect_ende) { - glow += glch; // ((effect_ende - millis()) / 200) % (LEDLEVEL + 1); - if (glow <= 0) { - glow = 0; - glch = 1; - } else if (glow >= LEDLEVEL) { - glow = LEDLEVEL; - glch = -1; - } - fill_cube(glow); - - delay(100); - } -}; - -void cube_effect_glitzer(int duration = 0) { - if (duration <= 0) - duration = random(MIN_DURATION, MAX_DURATION); - effect_ende = millis() + duration * 1000; - while (millis() < effect_ende) { - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - if (random(2) > 0) { - cube[x][y][z] = LEDLEVEL; - } else { - cube[x][y][z] = 0; - } - } - } - } - delay(50); - } -}; - -void cube_effect_glitzer_levels(int duration = 0) { - if (duration <= 0) - duration = random(MIN_DURATION, MAX_DURATION); - effect_ende = millis() + duration * 1000; - - while (millis() < effect_ende) { - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - cube[x][y][z] = random(LEDLEVEL + 1); - } - } - } - delay(50); - } -}; - -void cube_effect_glitzer_fade(int duration = 0) { - int cleanup = 5; - fill_cube(0); - - if (duration <= 0) - duration = random(MIN_DURATION, MAX_DURATION); - effect_ende = millis() + duration * 1000; - while (millis() < effect_ende) { - - // while ((millis() - effect_start) < 10000 ) { - // punkt.randomize(); - // punkt.show(); - cube[random(CUBESIZE)][random(CUBESIZE)][random(CUBESIZE)] = - random(LEDLEVEL + 1); - cube[random(CUBESIZE)][random(CUBESIZE)][random(CUBESIZE)] = - random(LEDLEVEL + 1); - delay(25); - cleanup--; - if (cleanup <= 0) { - cleanup = 5; - for (byte x = 0; x < CUBESIZE; x++) { - for (byte y = 0; y < CUBESIZE; y++) { - for (byte z = 0; z < CUBESIZE; z++) { - if (cube[x][y][z] > 0) { - cube[x][y][z]--; - } - } - } - } - } - } -}; - -void cube_effect_dots(int duration = 0) { - byte x; - byte y; - int speed = 50; - fill_cube(0); - for (x = 0; x < CUBESIZE; x++) { - for (y = 0; y < CUBESIZE; y++) { - cube[x][y][0] = LEDLEVEL; - } - } - - if (duration <= 0) - duration = random(MIN_DURATION, MAX_DURATION); - effect_ende = millis() + duration * 1000; - while (millis() < effect_ende) { - x = random(CUBESIZE); - y = random(CUBESIZE); - - if (cube[x][y][0] == 0) { - for (int z = CUBESIZE - 1; z >= 0; --z) { - - if (z <= (CUBESIZE - 2)) - cube[x][y][z + 2] = 0; - cube[x][y][z + 1] = LEDLEVEL / 2; - cube[x][y][z] = LEDLEVEL; - delay(speed); - } - - } else { - for (int z = 1; z < CUBESIZE; z++) { - - if (z >= 2) - cube[x][y][z - 2] = 0; - cube[x][y][z - 1] = LEDLEVEL / 2; - cube[x][y][z] = LEDLEVEL; - delay(speed); - } - } - for (byte z = 1; z < CUBESIZE - 1; z++) { - cube[x][y][z] = 0; - } - } -}; - -#endif diff --git a/src/src/CubeRegister.cpp b/src/src/CubeRegister.cpp new file mode 100644 index 0000000..65a2fb0 --- /dev/null +++ b/src/src/CubeRegister.cpp @@ -0,0 +1,56 @@ +#include "CubeRegister.h" + +CubeRegister CubeRegisterPortB; + +void CubeRegister::reset() { + // Port B Pin 8 - 13 + //Serial.println("reset"); + DDRB |= _SER; // _SER als Output + DDRB |= _OE; // _OE als Output + DDRB |= _RCLK; // _RCLK als Output + DDRB |= _SRCLK; // _SRCLK als Output + DDRB |= _SRCLR; // _SRCLR als Output + + output_disable(); + clear_register(); + register_to_output(); + // Serial.println(PORTB); +}; + +void CubeRegister::output_enable() { + // OUTPUT für OE auf 0 setzen + PORTB &= ~_OE; // -> LOW +}; +void CubeRegister::output_disable() { + // OUTPUT für OE auf 1 setzen + PORTB |= _OE; //-> HIGH +}; + +void CubeRegister::clear_register() { + PORTB |= _SRCLR; // -> HIGH + PORTB &= ~_SRCLK; // -> LOW + PORTB &= ~_RCLK; // -> LOW + PORTB &= ~_SRCLR; // -> LOW + PORTB &= ~_SRCLR; // -> LOW + PORTB |= _SRCLR; // -> HIGH +}; + +void CubeRegister::shift_bit(bool bit) { + // + // copy bit to SER (input) of shift regitster + if (bit == LOW) { + PORTB &= ~_SER; // -> LOW + } else { + PORTB |= _SER; // -> HIGH + } + // clock signal for shift registers + PORTB |= _SRCLK; // -> HIGH + PORTB &= ~_SRCLK; // -> LOW +}; + +// copy shift registers to output registers +void CubeRegister::register_to_output() { + // clock signal for output registers + PORTB |= _RCLK; // -> HIGH + PORTB &= ~_RCLK; // -> LOW +}; diff --git a/src/src/CubeRegister.h b/src/src/CubeRegister.h new file mode 100644 index 0000000..48a4045 --- /dev/null +++ b/src/src/CubeRegister.h @@ -0,0 +1,34 @@ + +#ifndef __CubeRegister__ +#define __CubeRegister__ +#include + +class CubeRegister { + public: + /* + singnals for IC SN74HC595 8-bit shift registers with 3-state output registers + SER - PIN 14 + OE - PIN 13 + RCLK - PIN 12 + SRCLK - PIN 11 + SRCLR - PIN 10 + */ + + // bitmasks for PORTB Pin 8 - 13 + static const byte _SER = 0x10; // 0b00010000; // D12 + static const byte _OE = 0x08; // 0b00001000; // D11 + static const byte _RCLK = 0x04; // 0b00000100; // D10 + static const byte _SRCLK = 0x02; // 0b00000010; // D9 + static const byte _SRCLR = 0x01; // 0b00000001; // D8 + + void reset(void); + void output_enable(void); + void output_disable(void); + void clear_register(void); + void shift_bit(bool bit); + void register_to_output(void); + +}; + +extern CubeRegister CubeRegisterPortB; +#endif diff --git a/src/src/CubeTextEffects.h b/src/src/CubeTextEffects.h deleted file mode 100644 index f817773..0000000 --- a/src/src/CubeTextEffects.h +++ /dev/null @@ -1,164 +0,0 @@ -#ifndef __CUBE_TEXT_EFFECTS__ -#define __CUBE_TEXT_EFFECTS__ - -#include "./Timer1.h" -#include "CubeBase.h" -#include - -const unsigned long CHAR_5BIT[] = { - 0B0000000000000000000000000, // 36 SPACE (32) - 0B0010000100001000000000100, // 37 ! (33) - 0B0000001010010100000000000, // 36 " (34) - 0B0101011111010101111101010, // 36 # (35) - 0B0111010100011100010101110, // 36 $ (36) - 0B0000101010001000101010000, // 36 % (37) - 0B1000001100011001001011100, // 36 & (38) ?? - 0B0010000100000000000000000, // 36 '(39) - 0B0001000100001000010000010, // 36 ( (40) - 0B0100000100001000010001000, // 36 ) (41) - 0B0000000100011100101000000, // 36 * (42) - 0B0000000100011100010000000, // 36 + (43) - 0B0000000000000000010001000, // 36 , (44) - 0B0000000000011100000000000, // 36 - (45) - 0B0000000000000000000000100, // 39 . (46) - 0B0000100010001000100010000, // 36 / (45) - 0B0111010011101011100101110, // 26 0 (48) - 0B0010001100001000010001110, // 27 1 (49) - 0B1111000001011101000011111, // 28 2 (50) - 0B1111000001011100000111110, // 29 3 - 0B0010001000101001111100100, // 30 4 - 0B1111110000111100000111110, // 31 5 - 0B1111110000111101000111110, // 32 6 - 0B1111100001000100010000100, // 33 7 - 0B0111010001011101000101110, // 34 8 - 0B0111010001011110000111110, // 35 9 (57) - 0B0000000100000000000000100, // 38 : (58) - 0B0000000100000000010001000, // 38 ; (59) - 0B0000100010001000000000001, // 38 < (60) - 0B0000001110000000111000000, // 36 = (61) - 0B1000001000001000100010000, // 38 > (62) - 0B0111010001001100000000100, // 38 ? (63) - 0B0111010111100010111001100, // 38 @ (64 - 0B0111010001111111000110001, // 0 A (97/65) - 0B1111110001111101000111111, // 1 B - 0B0111110000100001000001111, // 2 C - 0B1111010001100011000111110, // 3 D - 0B1111110000111101000011111, // 4 E - 0B1111110000111001000010000, // 5 F - 0B0111110000100111000101111, // 6 G - 0B1000110001111111000110001, // 7 H - 0B0111000100001000010001110, // 8 I - 0B0001100001000011000101111, // 9 J - 0B1000110010111001001010001, // 10 K - 0B1000010000100001000011111, // 11 L - 0B1000111011101011000110001, // 12 M - 0B1000111001101011001110001, // 13 N - 0B0111010001100011000101110, // 14 O - 0B1111010001111101000010000, // 15 P - 0B1111110001101011111100010, // 16 Q - 0B1111010001111101000110001, // 17 R - 0B0111110000011100000111110, // 18 S - 0B1111100100001000010000100, // 19 T - 0B1000110001100011000101110, // 20 U - 0B1000110001010100101000100, // 21 V - 0B1000110001101011010101010, // 22 W - 0B1000101010001000101010001, // 23 X - 0B1000110001010100010000100, // 24 Y - 0B1111100010001000100011111, // 25 Z (122/90) - 0B0011100100001000010000111, // 38 [ (91) - 0B1000001000001000001000001, // 38 \ (92) - 0B1110000100001000010011100, // 38 ] (93) - 0B0010001001000000000000000, // 36 ^ (94) - 0B0000000000000000000011111, // 36 _ (95) - 0B0010000001000000000000000, // 36 ` (96) - 0B0011000100011000010000110, // 36 { (123) - 0B0010000100001000010000100, // 36 | (124) - 0B0110000100001100010001100, // 36 } (125) - 0B0000001000101010001000000, // 36 ~ (126) - 0B0000001010111110111000100 // 41 @ -> Herz (44) -}; - -unsigned long char_to_5bits(char zeichen) { - // upper case letters + digits - if ((zeichen >= 32) & (zeichen <= 96)) { - return CHAR_5BIT[zeichen - 32]; - } - // lower case letters - if ((zeichen >= 97) & (zeichen <= 122)) { - return CHAR_5BIT[zeichen - 64]; - } - // digits - if ((zeichen >= 123) & (zeichen <= 126)) { - return CHAR_5BIT[zeichen - 22]; - } - return CHAR_5BIT[69]; -} - -void write_char(char zeichen, int ebene = 0, byte brightness = LEDLEVEL) { - ebene = constrain(ebene, 0, CUBESIZE - 1); - unsigned long pattern = char_to_5bits(zeichen); - unsigned long mask = 0B1000000000000000000000000; - for (byte y = 0; y < CUBESIZE; y++) { - for (byte x = 0; x < CUBESIZE; x++) { - if (pattern & mask) { - cube[(CUBESIZE - 1) - x][ebene][y] = brightness; - } else { - cube[(CUBESIZE - 1) - x][ebene][y] = 0; - } - mask >>= 1; - } - } -} - -void cube_text_warp(const char *message) { - - for (size_t mp = 0; mp < strlen(message); mp++) { - int s = CUBESIZE - 1; - for (int i = 0; i < (CUBESIZE + LEDLEVEL); i++) { - dimm_cube(LEDLEVEL / -2); - write_char(message[mp], max(s, 0), LEDLEVEL); - s--; - delay(50); - } - delay(200); - } - - fill_cube(0); -} - -void cube_text_banner(const char *message, int frame_delay = 100) { - - unsigned long pattern; // = char_to_5bits(zeichen); - unsigned long mask; // = 0B1000000000000000000000000; - fill_cube(0); - - for (size_t mp = 0; mp < strlen(message); mp++) { - - pattern = char_to_5bits(message[mp]); - mask = 0B1000000000000000000000000; - for (byte y = 0; y < CUBESIZE; y++) { - mask = 0B1000000000000000000000000; - mask >>= y; // * CUBESIZE; - for (byte z = 0; z < CUBESIZE; z++) { - if (pattern & mask) { - cube[0][CUBESIZE - 1][z] = LEDLEVEL; - } else { - cube[0][CUBESIZE - 1][z] = 0; - } - cube[CUBESIZE - 1][CUBESIZE - 1][z] = 0; - mask >>= CUBESIZE; - } - cube_rotate_cover(1, 150); - } - cube_rotate_cover(1, 150); - } - - for (byte cols = 0; cols < (CUBESIZE * 3 - 2); cols++) { - for (byte z = 0; z < CUBESIZE; z++) { - cube[CUBESIZE - 1][CUBESIZE - 1][z] = 0; - } - cube_rotate_cover(1, 150); - } -}; - -#endif diff --git a/src/src/LED.cpp b/src/src/LED.cpp deleted file mode 100644 index 1c88a62..0000000 --- a/src/src/LED.cpp +++ /dev/null @@ -1,5 +0,0 @@ - - -class Led{ - -}; diff --git a/src/src/LED.h b/src/src/LED.h deleted file mode 100644 index 4d6c3b1..0000000 --- a/src/src/LED.h +++ /dev/null @@ -1,11 +0,0 @@ - -#include "Led.h" - -Led::Led(byte x, byte y, byte z, byte brightness){ - _x=x; - _y=y; - _z=z; - _brightness = brightness; -}; - - diff --git a/src/src/LedCube.cpp b/src/src/LedCube.cpp new file mode 100644 index 0000000..feb1b6d --- /dev/null +++ b/src/src/LedCube.cpp @@ -0,0 +1,207 @@ +#include "LedCube.h" +//#include "TimerOne.h" +#include "TimerOne.h" + + +LedCube myCube(DEFAULT_CUBESIZE, DEFAULT_SHADES, CubeRegisterPortB); +myCube.framerate(DEFAULT_FRAMERATE); + + +LedCube::LedCube( const unsigned char size, + const unsigned char shades, + CubeRegister output = CubeRegister()) +:_cubesize(size), _shades(shades), myRegister(output){ + _framerate = DEFAULT_FRAMERATE; + +// unsigned char pixels[5][5][5]; + pixels = new unsigned char**[_cubesize]; + for (unsigned char x=0;x<_cubesize;x++){ + pixels[x] = new unsigned char*[_cubesize]; + for (unsigned char y=0;y<_cubesize;y++){ + pixels[x][y] = new unsigned char[_cubesize]; + } + } + + reset(); +}; + +LedCube::~LedCube(void){ + for (unsigned char x=0;x<_cubesize;x++){ + for (unsigned char y=0;y<_cubesize;y++){ + delete [] pixels[x][y]; + } + delete [] pixels[x]; + } + delete [] pixels; + +} + +void LedCube::toSerial(void){ + if (Serial){ + Serial.println("LedCube "+ String(_cubesize) + "x"+ String(_cubesize) +"x"+ String(_cubesize) +" @" + String(_framerate)+ "Hz and " + String(_shades) + " shades of grey\n"); + } +} + + +void LedCube::start(void){ + reset(); + myRegister.reset(); + myRegister.output_enable(); + if (Serial){ Serial.println("[LedCube] startTimer1(" + String(1000000 / (_framerate * _shades * _cubesize)) + ");"); } + delay(500); + + //startTimer1(1000000 / (_framerate * _shades * _cubesize)); + + unsigned long timer_interval = 1000000 / (_framerate * _shades * _cubesize); + Timer1.initialize(timer_interval); + Timer1.attachInterrupt(myCube.draw_layer); + + + delay(500); + if (Serial){ Serial.println("LedCube::start :-)"); } +} + +void LedCube::reset(void){ + Timer1.detachInterrupt(); + //resetTimer1(); + myRegister.reset(); + layer = 0; + level = 0; + +} + +void LedCube::framerate(unsigned char framerate){ + _framerate = framerate; +} + +unsigned char LedCube::size(void){ + return _cubesize; +} + +unsigned char LedCube::shades(void){ + return _shades; +} + +unsigned char LedCube::pixel(unsigned char x, unsigned char y, unsigned char z){ + return pixels[x][y][z]; +} + +void LedCube::pixel(unsigned char x, unsigned char y, unsigned char z, unsigned char value){ + pixels[x][y][z] = constrain(value, 0, _shades); +} + + void LedCube::draw_layer(void){ + + layer = layer++ % _cubesize; + if (layer == 0){ + level = level++ % _shades; + }; + + for (unsigned char z = 0; z < _cubesize; z++) { + myRegister.shift_bit(z == layer); + } + for (unsigned char x = 0; x < _cubesize; x++) { + for (unsigned char y = 0; y < _cubesize; y++) { + myRegister.shift_bit((pixels[x][y][layer] > level)); + } + } + myRegister.register_to_output(); +} + +void LedCube::fill(unsigned char brightness){ + + unsigned char value = min(brightness, _shades); + for (unsigned char x = 0; x < _cubesize; x++) { + for (unsigned char y = 0; y < _cubesize; y++) { + for (unsigned char z = 0; z < _cubesize; z++) { + pixels[x][y][z] = value; + } + } + } +} + +void LedCube::shade(char diff = -1){ + + char value = constrain(diff, -_shades, _shades); + + for (unsigned char x = 0; x < _cubesize; x++) { + for (unsigned char y = 0; y < _cubesize; y++) { + for (unsigned char z = 0; z < _cubesize; z++) { + pixels[x][y][z] = constrain(pixels[x][y][z] + value, 0, _shades); + } + } + } +} + +void LedCube::rotate_cover(int steps, unsigned int frame_delay = 100) { + unsigned char x = 0; + unsigned char y = 0; + unsigned char z = 0; + unsigned char backup; + + for (int s = 0; s < steps; s++) { + for (z = 0; z < _cubesize; z++) { + backup = pixels[0][0][z]; + + // 0,0 -> 0,4 : v + x = 0; + for (y = 1; y < _cubesize; y++) { + pixels[x][y - 1][z] = pixels[x][y][z]; + }; + + y = _cubesize - 1; + for (x = 1; x < _cubesize; x++) { + pixels[x - 1][y][z] = pixels[x][y][z]; + } + + x = _cubesize - 1; + for (y = _cubesize - 2; y < _cubesize; --y) { + pixels[x][y + 1][z] = pixels[x][y][z]; + } + + y = 0; + for (x = _cubesize - 2; x < _cubesize; --x) { + pixels[x + 1][y][z] = pixels[x][y][z]; + } + pixels[1][0][z] = backup; + } + delay(frame_delay); + } +}; + +void LedCube::rotate(int steps, unsigned int frame_delay = 100) { + unsigned char x = 0; + unsigned char y = 0; + unsigned char z = 0; + unsigned char backup; + + + for (int s = 0; s < steps; s++) { + for (z = 0; z < _cubesize; z++) { + backup = pixels[0][0][z]; + + // 0,0 -> 0,4 : v + x = 0; + for (y = 1; y < _cubesize; y++) { + pixels[x][y - 1][z] = pixels[x][y][z]; + }; + + y = _cubesize - 1; + for (x = 1; x < _cubesize; x++) { + pixels[x - 1][y][z] = pixels[x][y][z]; + } + + x = _cubesize - 1; + for (y = _cubesize - 2; y < _cubesize; --y) { + pixels[x][y + 1][z] = pixels[x][y][z]; + } + + y = 0; + for (x = _cubesize - 2; x < _cubesize; --x) { + pixels[x + 1][y][z] = pixels[x][y][z]; + } + pixels[1][0][z] = backup; + } + delay(frame_delay); + } +}; diff --git a/src/src/LedCube.h b/src/src/LedCube.h new file mode 100644 index 0000000..681b28d --- /dev/null +++ b/src/src/LedCube.h @@ -0,0 +1,49 @@ +#ifndef __LedCube__ +#define __LedCube__ + +#include "CubeRegister.h" +#define DEFAULT_FRAMERATE 30 +#define DEFAULT_SHADES 8 + +#define DEFAULT_CUBESIZE 5 + +class LedCube { + public: + LedCube(unsigned char size, unsigned char shades, CubeRegister output); + ~LedCube(); + + void start(void); + void reset(void); + void draw_layer(); + void framerate(unsigned char framerate); + unsigned char shades(void); + unsigned char size(void); + + void toSerial(void); + + unsigned char pixel(unsigned char x, unsigned char y, unsigned char z); + void pixel(unsigned char x, unsigned char y, unsigned char z, unsigned char value); + + + void fill(unsigned char brightness); + // void dim(unsigned char diff); + void shade(char diff); + void rotate_cover(int steps, unsigned int frame_delay); + void rotate(int steps, unsigned int frame_delay); + + + private: + const unsigned char _cubesize; + const unsigned char _shades; + unsigned char _framerate; + CubeRegister myRegister; + + volatile unsigned char layer = 0; + volatile unsigned char level = 0; + unsigned char ***pixels; +}; + +extern LedCube myCube; + + +#endif // __LedCube__ diff --git a/src/src/LedCube555_V4.ino b/src/src/LedCube555_V4.ino new file mode 100644 index 0000000..55cf4cf --- /dev/null +++ b/src/src/LedCube555_V4.ino @@ -0,0 +1,74 @@ +#include + +#include "LedCube.h" +#include "CubeAnimations.h" +CubeRegister out; +// new LedCube 5x5x5, 8 greytones +LedCube cube(5,8, out); + +// new CubeAnimations with cube, speed (0-100%), duration in ms (default: 15000ms) +CubeAnimations animation(cube, 50, 5000); + + + +void setup() { + Serial.begin(115200); + + cube.framerate(30); + cube.toSerial(); + delay(1000); + cube.start(); + + + + Serial.println("setup() done."); + + +} + +//static const char *const messages[] = {"I°arduino", "make: something", +// "einfach.machen.", "5x5x5 led-cube"}; +//int message_count = 5; + +void loop() { + // int next_duration = random(10, 20); + int ani = random(0,10); + if (Serial){ + Serial.println("next Animation: " + String(ani)); + } + switch (ani) { + case 0: + + animation.glow(); + break; + case 1: + animation.glitter(40); + break; + case 2: + animation.shaded_glitter(60); + break; + case 3: + animation.dimed_glitter(70); + break; + case 4: + + break; + case 5: + + break; + case 6: + + break; + case 7: + + break; + + } + +}; + +/* +ISR(TIMER1_COMPA_vect) { + + cube.draw_layer(); +};*/ diff --git a/src/src/Timer1.cpp b/src/src/Timer1.cpp deleted file mode 100644 index b6eeadb..0000000 --- a/src/src/Timer1.cpp +++ /dev/null @@ -1,169 +0,0 @@ -// -// ArduinoTimer is distributed under the FreeBSD License -// -// Copyright (c) 2013, Carlos Rafael Gimenes das Neves -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// The views and conclusions contained in the software and documentation are those -// of the authors and should not be interpreted as representing official policies, -// either expressed or implied, of the FreeBSD Project. -// -// https://github.com/carlosrafaelgn/ArduinoTimer -// -#if defined(ARDUINO) && ARDUINO >= 100 -#include "Arduino.h" -#else -#include "WProgram.h" -#endif -#include "Timer1.h" - -uint8_t __timer1Control; -uint16_t __timer1CounterValue; -// On 16 MHz Arduino boards, this function has a resolution of 4us, for intervals <= 262000, a resolution of 16us for intervals <= 1048000, and a resolution of 64us for intervals <= 4194000 -// On 8 MHz Arduino boards, this function has a resolution of 8us, for intervals <= 524000, a resolution of 32us for intervals <= 2097000, and a resolution os 128us for intervals <= 8388000 -void startTimer1(uint32_t microsecondsInterval) { - pauseTimer1(); - // 18. Timer/Counter 0, 1, 3, 4, and 5 Prescaler (page 169) - // 17.9.1 Normal Mode (page 149) - TCCR1A = 0; - TCCR1C = 0; - // 17.11.5 TCCR1B (page 160) - // 0 0 0 No clock source (Timer/Counter stopped) - // 0 0 1 clkIO/1 (No prescaling) - // 0 1 0 clkIO/8 (From prescaler) - // 0 1 1 clkIO/64 (From prescaler) - // 1 0 0 clkIO/256 (From prescaler) - // 1 0 1 clkIO/1024 (From prescaler) -#if (F_CPU == 16000000L) - if (microsecondsInterval <= 262000L) { - __timer1Control = B00000011; - // The proper way of doing this would be: - // 65536 - (microsecondsInterval / 4) - // But, in order to save one 32-bit operation, this "- 1" is necessary... - __timer1CounterValue = 65535 - ((uint16_t)(microsecondsInterval >> 2) - 1); - } else if (microsecondsInterval <= 1048000L) { - __timer1Control = B00000100; - __timer1CounterValue = 65535 - ((uint16_t)(microsecondsInterval >> 4) - 1); - } else { - __timer1Control = B00000101; - __timer1CounterValue = 65535 - ((uint16_t)(microsecondsInterval >> 6) - 1); - } -#elif (F_CPU == 8000000L) - if (microsecondsInterval <= 524000L) { - __timer1Control = B00000011; - __timer1CounterValue = 65535 - ((uint16_t)(microsecondsInterval >> 3) - 1); - } else if (microsecondsInterval <= 2097000L) { - __timer1Control = B00000100; - __timer1CounterValue = 65535 - ((uint16_t)(microsecondsInterval >> 5) - 1); - } else { - __timer1Control = B00000101; - __timer1CounterValue = 65535 - ((uint16_t)(microsecondsInterval >> 7) - 1); - } -#else -#error("Unsupported CPU frequency") -#endif - resetTimer1(); - // 17.11.37 TIFR1 � Timer/Counter1 Interrupt Flag Register (page 167) - TIFR1 = 0; - TIMSK1 = 1; - resumeTimer1(); -} -// On 16 MHz Arduino boards, this function has a resolution of 4us -// On 8 MHz Arduino boards, this function has a resolution of 8us -void startCountingTimer1(void) { - pauseTimer1(); - TCCR1A = 0; - TCCR1C = 0; -#if (F_CPU == 16000000L) || (F_CPU == 8000000L) - __timer1Control = B00000011; - __timer1CounterValue = 0; -#else -#error("Unsupported CPU frequency") -#endif - resetTimer1(); - TIFR1 = 0; - TIMSK1 = 0; - resumeTimer1(); -} -// On 16 MHz Arduino boards, this function has a resolution of 16us -// On 8 MHz Arduino boards, this function has a resolution of 32us -void startSlowCountingTimer1(void) { - pauseTimer1(); - TCCR1A = 0; - TCCR1C = 0; -#if (F_CPU == 16000000L) || (F_CPU == 8000000L) - __timer1Control = B00000100; - __timer1CounterValue = 0; -#else -#error("Unsupported CPU frequency") -#endif - resetTimer1(); - TIFR1 = 0; - TIMSK1 = 0; - resumeTimer1(); -} -// On 16 MHz Arduino boards, this function has a resolution of 64us -// On 8 MHz Arduino boards, this function has a resolution of 128us -void startUltraSlowCountingTimer1(void) { - pauseTimer1(); - TCCR1A = 0; - TCCR1C = 0; -#if (F_CPU == 16000000L) || (F_CPU == 8000000L) - __timer1Control = B00000101; - __timer1CounterValue = 0; -#else -#error("Unsupported CPU frequency") -#endif - resetTimer1(); - TIFR1 = 0; - TIMSK1 = 0; - resumeTimer1(); -} -uint16_t readTimer1(void) { - // 17.3 Accessing 16-bit Registers (page 138) - uint8_t sreg; - uint16_t i; - // Save global interrupt flag - // 7.4.1 SREG � AVR Status Register (page 14) - sreg = SREG; - // Disable interrupts - cli(); - // Read TCNTn - i = readTimer1Unsafe(); - // Restore global interrupt flag - SREG = sreg; - return i; -} -void resetTimer1(void) { - // 17.3 Accessing 16-bit Registers (page 138) - uint8_t sreg; - // Save global interrupt flag - // 7.4.1 SREG � AVR Status Register (page 14) - sreg = SREG; - // Disable interrupts - cli(); - // Write TCNTn - resetTimer1Unsafe(); - // Restore global interrupt flag - SREG = sreg; -} diff --git a/src/src/TimerOne.cpp b/src/src/TimerOne.cpp index d5e896c..7a52ae0 100644 --- a/src/src/TimerOne.cpp +++ b/src/src/TimerOne.cpp @@ -5,8 +5,8 @@ * Modified June 2009 by Michael Polli and Jesse Tane to fix a bug in setPeriod() which caused the timer to stop * * This is free software. You can redistribute it and/or modify it under - * the terms of Creative Commons Attribution 3.0 United States License. - * To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/us/ + * the terms of Creative Commons Attribution 3.0 United States License. + * To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/us/ * or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA. * */ @@ -22,7 +22,7 @@ ISR(TIMER1_OVF_vect) // interrupt service routine that wraps a user def void TimerOne::initialize(long microseconds) { - TCCR1A = 0; // clear control register A + TCCR1A = 0; // clear control register A TCCR1B = _BV(WGM13); // set mode as phase and frequency correct pwm, stop the timer setPeriod(microseconds); } @@ -82,7 +82,7 @@ void TimerOne::attachInterrupt(void (*isr)(), long microseconds) void TimerOne::detachInterrupt() { - TIMSK1 &= ~_BV(TOIE1); // clears the timer overflow interrupt enable bit + TIMSK1 &= ~_BV(TOIE1); // clears the timer overflow interrupt enable bit } void TimerOne::start() diff --git a/src/src/TimerOne.h b/src/src/TimerOne.h new file mode 100644 index 0000000..385b5c6 --- /dev/null +++ b/src/src/TimerOne.h @@ -0,0 +1,41 @@ +/* + * Interrupt and PWM utilities for 16 bit Timer1 on ATmega168/328 + * Original code by Jesse Tane for http://labs.ideo.com August 2008 + * Modified March 2009 by Jérôme Despatis and Jesse Tane for ATmega328 support + * Modified June 2009 by Michael Polli and Jesse Tane to fix a bug in setPeriod() which caused the timer to stop + * + * This is free software. You can redistribute it and/or modify it under + * the terms of Creative Commons Attribution 3.0 United States License. + * To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/us/ + * or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA. + * + */ + +#include +#include + +#define RESOLUTION 65536 // Timer1 is 16 bit + +class TimerOne +{ + public: + + // properties + unsigned int pwmPeriod; + unsigned char clockSelectBits; + + // methods + void initialize(long microseconds=1000000); + void start(); + void stop(); + void restart(); + void pwm(char pin, int duty, long microseconds=-1); + void disablePwm(char pin); + void attachInterrupt(void (*isr)(), long microseconds=-1); + void detachInterrupt(); + void setPeriod(long microseconds); + void setPwmDuty(char pin, int duty); + void (*isrCallback)(); +}; + +extern TimerOne Timer1;