Merge branch 'arduino' into 'main'
Arduino Version See merge request projekte/led-cube-555!1
This commit is contained in:
commit
db4e4da799
9 changed files with 1593 additions and 0 deletions
53
src/CubeRegister.cpp
Normal file
53
src/CubeRegister.cpp
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#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);
|
||||||
|
};
|
||||||
73
src/CubeRegister.h
Normal file
73
src/CubeRegister.h
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
|
||||||
|
#ifndef __CubeRegister__
|
||||||
|
#define __CubeRegister__
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
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
|
||||||
518
src/LedCube555_V1.ino_V1
Normal file
518
src/LedCube555_V1.ino_V1
Normal file
|
|
@ -0,0 +1,518 @@
|
||||||
|
#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;
|
||||||
|
|
||||||
|
|
||||||
|
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 ++;
|
||||||
|
}
|
||||||
668
src/LedCube555_V2.ino
Normal file
668
src/LedCube555_V2.ino
Normal file
|
|
@ -0,0 +1,668 @@
|
||||||
|
#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 ++;
|
||||||
|
}
|
||||||
169
src/Timer1.cpp
Normal file
169
src/Timer1.cpp
Normal file
|
|
@ -0,0 +1,169 @@
|
||||||
|
//
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
112
src/Timer1.h
Normal file
112
src/Timer1.h
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
#ifndef Timer1_h
|
||||||
|
#define Timer1_h
|
||||||
|
|
||||||
|
// Reference documentation:
|
||||||
|
// http://www.atmel.com/devices/atmega2560.aspx
|
||||||
|
// http://www.atmel.com/devices/atmega328.aspx
|
||||||
|
//
|
||||||
|
// Timer 1 is available on ATmega168, ATmega328 and on ATmega2560
|
||||||
|
// All other timers are only available on ATmega2560
|
||||||
|
//
|
||||||
|
// (The page and chapter numbers refer to the ATmega2560 documentation)
|
||||||
|
|
||||||
|
//*********************************************************************************
|
||||||
|
// ATmega168, ATmega328: Using Timer 1 disables PWM (analogWrite) on pins 9 and 10
|
||||||
|
// ATmega2560: Using Timer 1 disables PWM (analogWrite) on pins 11 and 12
|
||||||
|
//*********************************************************************************
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
// 16.9.6 TIMSK0 <20> Timer/Counter Interrupt Mask Register (page 134)
|
||||||
|
#ifndef disableMillis
|
||||||
|
#define disableMillis() TIMSK0 &= ~1
|
||||||
|
#endif
|
||||||
|
#ifndef enableMillis
|
||||||
|
#define enableMillis() TIMSK0 |= 1
|
||||||
|
#endif
|
||||||
|
#ifndef microsFromCounting
|
||||||
|
#if (F_CPU == 16000000L)
|
||||||
|
#define microsFromCounting(COUNTING) ((COUNTING) << 2)
|
||||||
|
#elif (F_CPU == 8000000L)
|
||||||
|
#define microsFromCounting(COUNTING) ((COUNTING) << 3)
|
||||||
|
#else
|
||||||
|
#error("Unsupported CPU frequency")
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef microsFromSlowCounting
|
||||||
|
#if (F_CPU == 16000000L)
|
||||||
|
#define microsFromSlowCounting(SLOWCOUNTING) ((SLOWCOUNTING) << 4)
|
||||||
|
#elif (F_CPU == 8000000L)
|
||||||
|
#define microsFromSlowCounting(SLOWCOUNTING) ((SLOWCOUNTING) << 5)
|
||||||
|
#else
|
||||||
|
#error("Unsupported CPU frequency")
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef microsFromUltraSlowCounting
|
||||||
|
#if (F_CPU == 16000000L)
|
||||||
|
#define microsFromUltraSlowCounting(SLOWCOUNTING) ((SLOWCOUNTING) << 6)
|
||||||
|
#elif (F_CPU == 8000000L)
|
||||||
|
#define microsFromUltraSlowCounting(SLOWCOUNTING) ((SLOWCOUNTING) << 7)
|
||||||
|
#else
|
||||||
|
#error("Unsupported CPU frequency")
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern uint8_t __timer1Control;
|
||||||
|
extern uint16_t __timer1CounterValue;
|
||||||
|
#define readTimer1Unsafe() TCNT1
|
||||||
|
#define resetTimer1Unsafe() TCNT1 = __timer1CounterValue
|
||||||
|
#define pauseTimer1() TCCR1B = 0
|
||||||
|
#define resumeTimer1() TCCR1B = __timer1Control
|
||||||
|
extern void startTimer1(uint32_t microsecondsInterval);
|
||||||
|
extern void startCountingTimer1(void);
|
||||||
|
extern void startSlowCountingTimer1(void);
|
||||||
|
extern void startUltraSlowCountingTimer1(void);
|
||||||
|
extern uint16_t readTimer1(void);
|
||||||
|
extern void resetTimer1(void);
|
||||||
|
|
||||||
|
// 17.9.1 Normal Mode (page 149)
|
||||||
|
// The simplest mode of operation is the Normal mode (WGMn3:0 = 0). In this mode the counting
|
||||||
|
// direction is always up (incrementing), and no counter clear is performed. The counter simply
|
||||||
|
// overruns when it passes its maximum 16-bit value (MAX = 0xFFFF) and then restarts from the
|
||||||
|
// BOTTOM (0x0000). In normal operation the Timer/Counter Overflow Flag (TOVn) will be set in
|
||||||
|
// the same timer clock cycle as the TCNTn becomes zero. The TOVn Flag in this case behaves
|
||||||
|
// like a 17th bit, except that it is only set, not cleared. However, combined with the timer overflow
|
||||||
|
// interrupt that automatically clears the TOVn Flag, the timer resolution can be increased by software.
|
||||||
|
// There are no special cases to consider in the Normal mode, a new counter value can be
|
||||||
|
// written anytime.
|
||||||
|
#define timer1Event TIMER1_OVF_vect
|
||||||
|
|
||||||
|
#endif
|
||||||
BIN
tools/5x5x5 Bohrschablone (1,27cm).odg
Normal file
BIN
tools/5x5x5 Bohrschablone (1,27cm).odg
Normal file
Binary file not shown.
BIN
tools/Ebenen-Template.fcstd
Normal file
BIN
tools/Ebenen-Template.fcstd
Normal file
Binary file not shown.
BIN
tools/Ebenen-Template.fcstd1
Normal file
BIN
tools/Ebenen-Template.fcstd1
Normal file
Binary file not shown.
Loading…
Reference in a new issue