Version 4 - letzter Stand 03.09.2017
This commit is contained in:
parent
4c21998682
commit
41b5d939c6
15 changed files with 614 additions and 710 deletions
110
src/src/CubeAnimations.cpp
Normal file
110
src/src/CubeAnimations.cpp
Normal file
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
39
src/src/CubeAnimations.h
Normal file
39
src/src/CubeAnimations.h
Normal file
|
|
@ -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__
|
||||||
|
|
@ -1,176 +0,0 @@
|
||||||
#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
|
|
||||||
|
|
@ -1,181 +0,0 @@
|
||||||
#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
|
|
||||||
56
src/src/CubeRegister.cpp
Normal file
56
src/src/CubeRegister.cpp
Normal file
|
|
@ -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
|
||||||
|
};
|
||||||
34
src/src/CubeRegister.h
Normal file
34
src/src/CubeRegister.h
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
|
||||||
|
#ifndef __CubeRegister__
|
||||||
|
#define __CubeRegister__
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
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
|
||||||
|
|
@ -1,164 +0,0 @@
|
||||||
#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
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
class Led{
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
@ -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;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
207
src/src/LedCube.cpp
Normal file
207
src/src/LedCube.cpp
Normal file
|
|
@ -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);
|
||||||
|
}
|
||||||
|
};
|
||||||
49
src/src/LedCube.h
Normal file
49
src/src/LedCube.h
Normal file
|
|
@ -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__
|
||||||
74
src/src/LedCube555_V4.ino
Normal file
74
src/src/LedCube555_V4.ino
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
#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();
|
||||||
|
};*/
|
||||||
|
|
@ -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 <20> 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 <20> 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 <20> AVR Status Register (page 14)
|
|
||||||
sreg = SREG;
|
|
||||||
// Disable interrupts
|
|
||||||
cli();
|
|
||||||
// Write TCNTn
|
|
||||||
resetTimer1Unsafe();
|
|
||||||
// Restore global interrupt flag
|
|
||||||
SREG = sreg;
|
|
||||||
}
|
|
||||||
41
src/src/TimerOne.h
Normal file
41
src/src/TimerOne.h
Normal file
|
|
@ -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 <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
Loading…
Reference in a new issue