Platformio #2

Merged
ingo merged 4 commits from platformio into main 2024-08-17 13:08:36 +02:00
14 changed files with 701 additions and 668 deletions
Showing only changes of commit 2a3c9fc96a - Show all commits

4
src/.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
.pioenvs
.clang_complete
.gcc-flags.json
.piolibdeps

65
src/.travis.yml Normal file
View file

@ -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

View file

@ -1,668 +0,0 @@
#include <Arduino.h>
#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 ++;
}

38
src/lib/readme.txt Normal file
View file

@ -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 <Foo.h>
#include <Bar.h>
// 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

10
src/platformio.ini Normal file
View file

@ -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

175
src/src/CubeBase.h Normal file
View file

@ -0,0 +1,175 @@
#ifndef __CUBE_BASE__
#define __CUBE_BASE__
#include "./Timer1.h"
#include "CubeRegister.h"
#include <Arduino.h>
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

181
src/src/CubeEffects.h Normal file
View file

@ -0,0 +1,181 @@
#ifndef __CUBE_EFFECTS__
#define __CUBE_EFFECTS__
#include "CubeBase.h"
#include <Arduino.h>
// 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

164
src/src/CubeTextEffects.h Normal file
View file

@ -0,0 +1,164 @@
#ifndef __CUBE_TEXT_EFFECTS__
#define __CUBE_TEXT_EFFECTS__
#include "./Timer1.h"
#include "CubeBase.h"
#include <Arduino.h>
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

64
src/src/LedCube555_V3.ino Normal file
View file

@ -0,0 +1,64 @@
#include <Arduino.h>
#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));
*/
}