-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCube.cpp
116 lines (107 loc) · 2.97 KB
/
Cube.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include "Cube.h"
Cube::Cube()
{
// Configure the necessary pins as output
pinMode(SERIAL_IN, OUTPUT);
pinMode(INPUT_CLK, OUTPUT);
pinMode(LATCH_CLK, OUTPUT);
pinMode(UPDATE_CLK, OUTPUT);
pinMode(RESET, OUTPUT);
pinMode(SET, OUTPUT);
}
void Cube::bufferLED(byte x, byte y, byte z)
{
// Ensure the specified LED is within the bounds of the cube
if (x > (size - 1) || y > (size - 1) || z > (size - 1)) return;
// Convert the x,y position to a mapping of the format used for the buffer
/*
* (0, 0) --> 000000000000001 -> 1
* (1, 0) --> 000000000000010 -> 2
* (2, 0) --> 000000000000100 -> 4
* ...
* (3, 3) --> 1000000000000000 -> 32768
*/
unsigned short mapped = pow(2, (x + size*y)) + 0.5;
// Add the LED to the buffer
buffer[z] = buffer[z] | mapped;
}
void Cube::bufferFromMatrix(bool m[size][size][size])
{
for (byte x = 0; x < 4; x++)
{
for (byte y = 0; y < 4; y++)
{
for (byte z = 0; z < 4; z++)
{
if (m[x][y][z])
{
bufferLED(x, y, z);
}
}
}
}
}
void Cube::toggleLED(byte x, byte y, byte z)
{
buffer[z] ^= 1 << (x + size*y);
}
void Cube::clearBuffer()
{
for (byte i = 0; i < size; i++) buffer[i] = 0;
}
void Cube::reset()
{
clearBuffer();
// Remove any active LEDs
display();
// Clear the layer shift register
digitalWrite(RESET, LOW);
delayMicroseconds(period);
digitalWrite(RESET, HIGH);
delayMicroseconds(period);
// Start the layer shift register
digitalWrite(SET, HIGH);
delayMicroseconds(period);
digitalWrite(UPDATE_CLK, HIGH);
delayMicroseconds(period);
digitalWrite(UPDATE_CLK, LOW);
delayMicroseconds(period); // probably not necessary
digitalWrite(SET, LOW);
}
void Cube::display()
{
// Update each layer (z-axis)
for (byte i = 0; i < size; i++)
{
// Update x-y plane
for (byte j = 0; j < size*size; j++)
{
// Retrieve the state of bit j on the current layer
byte curr = (buffer[i] >> (size*size - 1 - j)) & 1;
// Load in the bit
digitalWrite(SERIAL_IN, curr);
// Toggle the input clock to push the bit through
digitalWrite(INPUT_CLK, HIGH);
// Provide time for the input to update
delayMicroseconds(period);
// Toggle the input clock to wait for the next bit
digitalWrite(INPUT_CLK, LOW);
// Provide time to wait for the next bit
delayMicroseconds(period);
}
// Toggle the latch clock to save the output
digitalWrite(LATCH_CLK, HIGH);
// Provide time for the output to latch
delayMicroseconds(period);
// Toggle the latch clock before loading new data
digitalWrite(LATCH_CLK, LOW);
// Provide time before changing the layer
delayMicroseconds(period);
// Toggle the update clock to switch to the next layer
digitalWrite(UPDATE_CLK, HIGH);
// Provide time to switch layers
delayMicroseconds(period);
// Toggle the update clock to work with the selected layer
digitalWrite(UPDATE_CLK, LOW);
}
}