Im trying to get the old 4x4x4 program working with the new cube (I modded the program to work with my common anode cube), and it was working fine, till I converted the cube over to shift registers.
Here is what im working on:
#include <avr/pgmspace.h> // alHIGHs use of PROGMEM to store patterns in flash
#define CUBESIZE 4
#define PLANESIZE CUBESIZE*CUBESIZE
#define PLANETIME 3333 // time each plane is displayed in us -> 100 Hz refresh
#define TIMECONST 100 // multiplies DisplayTime to get ms - why not =100?
// LED Pattern Table in PROGMEM - last column is display time in 100ms units
// TODO this could be a lot more compact but not with binary pattern representation
prog_uchar PROGMEM PatternTable[] = {
// blink on and off
// Common anode, so we send plane pin high, and column pin low to light.
// 1= off, 0=on
// First group of each block is the right plane
// first 4 groups of 4 character blocks is bottom plane second is second layer, ...
// first character in segment is front plane
//Collumn spin Clockwise 360
B0111,B1011,B1101,B1110,B0111,B1011,B1101,B1110,B0111,B1011,B1101,B1110,B0111,B1011,B1101,B1110,01,
B1111,B0011,B1100,B1111,B1111,B0011,B1100,B1111,B1111,B0011,B1100,B1111,B1111,B0011,B1100,B1111,01,
B1111,B1100,B0011,B1111,B1111,B1100,B0011,B1111,B1111,B1100,B0011,B1111,B1111,B1100,B0011,B1111,01,
B1110,B1101,B1011,B0111,B1110,B1101,B1011,B0111,B1110,B1101,B1011,B0111,B1110,B1101,B1011,B0111,01,
B1101,B1101,B1011,B1011,B1101,B1101,B1011,B1011,B1101,B1101,B1011,B1011,B1101,B1101,B1011,B1011,01,
B1011,B1011,B1101,B1101,B1011,B1011,B1101,B1101,B1011,B1011,B1101,B1101,B1011,B1011,B1101,B1101,01,
// this is a dummy element for end of table (duration=0) aka !!!DO NOT TOUCH!!!
B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, 0
};
/*
** Defining pins in array makes it easier to rearrange how cube is wired
** Adjust numbers here until LEDs flash in order - L to R, T to B
** Note that analog inputs 0-5 are also digital outputs 14-19!
** Pin DigitalOut0 (serial RX) and AnalogIn5 are left open for future apps
*/
int LEDPin[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
int PlanePin[] = {11, 10, 9, 6};
int dataPin = 7; //Data I added these for Shift Register
int clockPin = 12; // Clock
int latchPin = 13; // Latch
// initialization
void setup()
{
int pin; // loop counter
// set up LED pins as output (active LOW)
//for (pin=0; pin<PLANESIZE; pin++) {
// pinMode( LEDPin[pin], OUTPUT ); Edited out because we dont use them pins
// setup Shift Register pins instead of 16 arduino pins.
{
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
// set up plane pins as outputs (active HIGH)
for (pin=0; pin<CUBESIZE; pin++) {
pinMode( PlanePin[pin], OUTPUT );
}
}
// display pattern in table until DisplayTime is zero (then repeat)
void loop()
{
// declare variables
byte PatternBuf[PLANESIZE]; // saves current pattern from PatternTable
int PatternIdx;
byte DisplayTime; // time*100ms to display pattern
unsigned long EndTime;
int plane; // loop counter for cube refresh
int patbufidx; // indexes which byte from pattern buffer
int ledrow; // counts LEDs in refresh loop
int ledcol; // counts LEDs in refresh loop
int ledpin; // counts LEDs in refresh loop
// Initialize PatternIdx to beginning of pattern table
PatternIdx = 0;
// loop over entries in pattern table - while DisplayTime>0
do {
// read pattern from PROGMEM and save in array
memcpy_P( PatternBuf, PatternTable+PatternIdx, PLANESIZE );
PatternIdx += PLANESIZE;
// read DisplayTime from PROGMEM and increment index
DisplayTime = pgm_read_byte_near( PatternTable + PatternIdx++ );
// compute EndTime from current time (ms) and DisplayTime
EndTime = millis() + ((unsigned long) DisplayTime) * TIMECONST;
// loop while DisplayTime>0 and current time < EndTime
while ( millis() < EndTime ) {
patbufidx = 0; // reset index counter to beginning of buffer
// loop over planes
for (plane=0; plane<CUBESIZE; plane++) {
// turn previous plane off
if (plane==0) {
digitalWrite( PlanePin[CUBESIZE-1], LOW );
} else {
digitalWrite( PlanePin[plane-1], LOW );
}
// load current plane pattern data into ports
// Plane pins are taken care of above, this routine handles the 16
// LED pins(columns), originally 16 pins are now going to 2 shift registers
// using dataPin, clockPin, latchPin.
/* Original code
ledpin = 0;
for (ledrow=0; ledrow<CUBESIZE; ledrow++) {
for (ledcol=0; ledcol<CUBESIZE; ledcol++) {
digitalWrite( LEDPin[ledpin++], PatternBuf[patbufidx] & (1 << ledcol) );
}
patbufidx++;
}
*/
// hrm. gotta figure out how to jamb 2 bytes of patternbuf
shiftOut( dataPin, clockPin, PatternBuf[patbufidx]);
shiftOut( dataPin, clockPin, PatternBuf[patbufidx+1]);
}
//patbufidx++; //tying to pass 2 8bits, instead of 16 bits)
}
// turn current plane on HIGH in my case of common anode.
digitalWrite( PlanePin[plane], HIGH );
// delay PLANETIME us
delayMicroseconds( PLANETIME );
} // for plane
} // while <EndTime
} while (DisplayTime > 0); // read patterns until time=0 which signals end
}
void shiftOut(int dataPin, int clockPin, byte dataOut) {
// we add shiftout to move bits out pin 7 instead of the 16 pins
// previously used.
// This shifts 8 bits out MSB first,
//on the rising edge of the clock,
//clock idles low
// Somehow, gotta get
//internal function setup
int i=0;
int pinState;
//for each bit in the byte myDataOut?
//NOTICE THAT WE ARE COUNTING DOWN in our for loop
//This means that %00000001 or "1" will go through such
//that it will be pin Q0 that lights.
for (i=7; i>0; i--)
{
digitalWrite(clockPin, 0);
//if the value passed to myDataOut and a bitmask result
// true then... so if we are at i=6 and our value is
// %11010100 it would the code compares it to %01000000
// and proceeds to set pinState to 1.
if (dataOut & (1<<i))
{
pinState= 0; // Inverted for common anode
}
else
{
pinState= 1; // Inverted for common anode
}
//Sets the pin to HIGH or LOW depending on pinState
digitalWrite(dataPin, pinState); // this is where data is sent to the shift register.
//register shifts bits on upstroke of clock pin
digitalWrite(clockPin, 1);
}
}
I've taken the shiftout that I have working (from the previous post). put it in the 4x4x4 cube code, and am trying to convert the bit that turns the pins on (was pins 0-15) to serialize the data to the shift registers.
I think what this does is takes 2 8bit fields of data, and send them to the individual 16 pins (LEDPin(), but what I need is that data sent to the shift registers.
Original code:
ledpin = 0;
for (ledrow=0; ledrow<CUBESIZE; ledrow++) {
for (ledcol=0; ledcol<CUBESIZE; ledcol++) {
digitalWrite( LEDPin[ledpin++], PatternBuf[patbufidx] & (1 << ledcol) );
}
patbufidx++;
}
Heres my mess of code that doesnt work.
// hrm. gotta figure out how to jamb 2 bytes of patternbuf
shiftOut( dataPin, clockPin, PatternBuf[patbufidx]);
shiftOut( dataPin, clockPin, PatternBuf[patbufidx+1]);
}
//patbufidx++; //tying to pass 2 bytes, instead of 16 bits)
}
It gives me this error:
PatternsSR.cpp: In function ‘void loop()’:
PatternsSR.cpp:137:1: error: expected ‘while’ before ‘}’ token
PatternsSR.cpp:137:1: error: expected ‘(’ before ‘}’ token
PatternsSR.cpp:137:1: error: expected primary-expression before ‘}’ token
PatternsSR.cpp:137:1: error: expected ‘)’ before ‘}’ token
PatternsSR.cpp:137:1: error: expected ‘;’ before ‘}’ token
PatternsSR.cpp: At global scope:
PatternsSR.cpp:138:1: error: expected declaration before ‘}’ token
This is line 137:
void shiftOut(int dataPin, int clockPin, byte dataOut) {
I could use some help, I think its close to working, but I think maybe im missing something obvious.