erste Version

This commit is contained in:
Ingo Rohlf 2024-08-17 12:40:02 +02:00
commit 3fa536d4fe
4 changed files with 372 additions and 0 deletions

View file

@ -0,0 +1,372 @@
#include <Timer1.h>
#define PIN_SER 12
#define PIN_OE 11
#define PIN_RCLK 10
#define PIN_SRCLK 9
#define PIN_SRCLR 8
typedef void(*CubeEffects)(unsigned int frame);
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);
}
};
class ShiftRegister {
public:
const byte _SER = B00010000;
const byte _OE = B00001000;
const byte _RCLK = B00000100;
const byte _SRCLK = B00000010;
const byte _SRCLR = B00000001;
void 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 output_enable() {
// OUTPUT für OE auf 0 setzen
PORTB &= ~_OE; // -> LOW
}
void output_disable() {
// OUTPUT für OE auf 1 setzen
PORTB |= _OE; //-> HIGH
}
void clear_register() {
PORTB |= _SRCLR; // -> HIGH
PORTB &= ~_SRCLK; // -> LOW
PORTB &= ~_RCLK; // -> LOW
PORTB &= ~_SRCLR; // -> LOW
PORTB &= ~_SRCLR; // -> LOW
PORTB |= _SRCLR; // -> HIGH
}
void 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 register_to_output() {
//Serial.println("register_to_output");
// PORTB &= ~_RCLK; // -> LOW
PORTB |= _RCLK; // -> HIGH
//Serial.println(PORTB);
PORTB &= ~_RCLK; // -> LOW
// Serial.println(PORTB);
}
};
#define CUBESIZE 5
//ShiftRegisterSlow Register ;
ShiftRegister Register ;
#define FPS 500
#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) {
byte data = 0;
//Serial.print("Z ");
//Serial.println(layer);
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++) {
// Serial.print(cube[layer][x][y]);
Register.shift_bit((cube[layer][x][y] > level));
}
// Serial.println();
}
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));
//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[z][x][y] = random(LEDLEVEL + 1);
}
}
}
}
*/
void glow_cube(int duration) {
ende = millis() + duration * 1000;
int glow = 0;
while (millis() < ende) {
glow = ((ende - millis()) / 200) % (LEDLEVEL + 1);
for (byte x = 0; x < CUBESIZE; x++) {
for (byte y = 0; y < CUBESIZE; y++) {
for (byte z = 0; z < CUBESIZE; z++) {
cube[z][x][y] = glow;
}
}
}
delay(50);
}
}
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++) {
cube[z][x][y] = random(LEDLEVEL + 1);
}
}
}
delay(100);
}
}
void glitzer_fade_cube(int duration) {
int cleanup = 5;
for (byte x = 0; x < CUBESIZE; x++) {
for (byte y = 0; y < CUBESIZE; y++) {
for (byte z = 0; z < CUBESIZE; z++) {
cube[z][x][y] = 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[z][x][y] > 0) {
cube[z][x][y] --;
}
}
}
}
}
}
}
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[z][x][y] = 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(10)) {
case 0:
glow_cube(next_duration);
break;
case 1:
glitzer_cube(next_duration);
break;
case 2:
glitzer_fade_cube(next_duration);
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 ++;
}

Binary file not shown.

BIN
tools/Ebenen-Template.fcstd Normal file

Binary file not shown.

Binary file not shown.