Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Led Cube
- *
- * PINS
- * ------------------------------------------------------
- * Data pins 22~29 mapping by PORTA[0~7]
- * Select pins 10~13 mapping by PORTB[4~7]
- * Layer Select pins 30~37 mapping by PORTC[7~0] (Invert)
- */
- #define WIDTH 8
- #define selectLayer(layer) (PORTC = 1 << layer)
- #define selectRow(y) (PORTB = (0x8f | y + 1 << 4))
- short currentX,
- currentY,
- currentZ;
- // dataMap[y][z]
- short dataMap[8][8];
- void output(int y, int z, int v) {
- if(y < 8 && y >= 0 &&
- z < 8 && z >= 0)
- dataMap[y][z] = v;
- }
- // function pointer for current effect
- void (*effect)();
- /**
- * clear all the led
- */
- void cleanEffect() {
- for(int i = 0; i < 8; i++)
- for(int j = 0; j < 8; j++)
- output(i, j, 0);
- }
- /**
- * light all the led
- */
- void fullEffect() {
- for(int i = 0; i < 8; i++)
- for(int j = 0; j < 8; j++)
- output(i, j, 255);
- }
- void rainEffect() {
- // scanning y
- for(int y = 0; y < WIDTH; y++) {
- for(int z = 0; z < WIDTH; z++) {
- for(int x = 0; x < WIDTH; x++) {
- // if dataMap(x, y, z) is HIGH
- if(dataMap[y][z] & (1 << x)) {
- // make dataMap(x, y, z) LOW
- output(y, z, dataMap[y][z] & !(0b11111111 && (1 << x)));
- // then make next layer HIGH
- output(y, z-1, dataMap[y][z-1] | (1 << x));
- }
- }
- }
- }
- dataMap[random(0, 8)][7] = (1 << random(0, 8));
- }
- void columnEffect() {
- static bool reverseFlag = 0;
- static int l = 0;
- static int sub_l = 7;
- if(reverseFlag) {
- for(int i = 0; i < 8; i++) { //from top to bottom
- output(i, l+1, 0);
- output(i, sub_l-1, 0);
- }
- } else {
- for(int i = 0; i < 8; i++) { //from bottom to top
- output(i, l-1, 0);
- output(i, sub_l+1, 0);
- }
- }
- output(0, l, 255);
- output(1, l, 129);
- output(2, l, 129);
- output(3, l, 129);
- output(4, l, 129);
- output(5, l, 129);
- output(6, l, 129);
- output(7, l, 255);
- output(0, sub_l, 0);
- output(1, sub_l, 0);
- output(2, sub_l, 0x3c);
- output(3, sub_l, 0x24);
- output(4, sub_l, 0x24);
- output(5, sub_l, 0x3c);
- output(6, sub_l, 0);
- output(7, sub_l, 0);
- if(reverseFlag) {
- l--;
- sub_l++;
- } else {
- l++;
- sub_l--;
- }
- if(l == -1 || l == 8) reverseFlag = !reverseFlag;
- }
- /**
- * fill effect
- */
- short fillLayer,fillY,fillCounter;
- bool fillreverseFlag;
- void fillEffect() {
- if(fillreverseFlag){
- dataMap[fillY][fillLayer] &= ~(1 << fillCounter);
- } else {
- dataMap[fillY][fillLayer] |= (1 << fillCounter);
- }
- fillCounter++;
- if(fillCounter == 8) {
- fillY++;
- fillCounter = 0;
- }
- if(fillY == 8) {
- fillLayer++;
- fillY = 0;
- }
- if(fillLayer == 8) {
- fillLayer = 0;
- fillreverseFlag=!fillreverseFlag;
- }
- }
- void clearAll() {
- for(int i = 0; i < 8; i++)
- for(int j = 0; j < 8; j++)
- output(i, j, 0);
- }
- void setup() {
- DDRA = 0xff; // pin 22~29 PORTA -> ENABLE Output
- DDRB = 0xf0; // pin 10~13 PORTB HIGHEST 4 bits Enable Output
- DDRC = 0xff; // pin 30~37 PORTC -> ENABLE Output (Invert)
- PORTB = 0x80; // 138 G1 Enable
- TCCR1A = 0x00; // Normal mode, just as a Timer
- TCCR1B = TCCR1B & ~0x07;
- TCCR1B = TCCR1B | 0x02; // prescaler = CPU clock/8
- TIMSK1 |= _BV(TOIE1); // enable timer overflow interrupt
- Serial.begin(9600);
- TCNT1 = -1250; // Ticks for 5ms @16 MHz,prescale=8
- currentX = 0;
- currentY = 0;
- currentZ = 0;
- effect = cleanEffect;
- }
- void loop() {};
- int counter = 0;
- ISR (TIMER1_OVF_vect) {
- PORTC = 0x00;
- if(Serial.available()) {
- char buffer;
- buffer = Serial.read();
- switch(buffer) {
- case '0':
- effect = cleanEffect;
- break;
- case '1':
- effect = fullEffect;
- break;
- case '2':
- effect = rainEffect;
- break;
- case '3':
- effect = columnEffect;
- break;
- case '4':
- effect = fillEffect;
- fillLayer = 0;
- fillY = 0;
- fillCounter = 0;
- fillreverseFlag = false;
- break;
- default:
- break;
- }
- clearAll();
- }
- counter++;
- if(counter >= 150) {
- effect();
- counter = 0;
- }
- while(currentY < 8) {
- PORTA = dataMap[currentY][currentZ]; // Output Data to Data pins dataMap[y][x]
- selectRow(currentY);
- currentY++;
- }
- selectLayer(currentZ);
- currentY = 0;
- currentZ = (++currentZ) % 8;
- TCNT1 = -1250; // Tick Reset
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement