3D cube Led Code - Same Logic. Need help with different memory usage approach.

Guys i have this code and i want the same logic of the code but i don't want to use the Flash Memory and the PROGMEM approach. Because i want to modify the Led sequence in runtime and i would like to use a modifiable char[] in function loop() instead of const char PROGMEM
. ¿Any Idea?.

ORIGINAL CODE:

/4x4x4 LED Cube Show 1
//This one was written by someone else, i dont know who, however if you want credit, message me!

#include <avr/pgmspace.h> // allows use of PROGMEM to store patterns in flash

#define CUBESIZE 4
#define PLANESIZE CUBESIZE*CUBESIZE
#define PLANETIME 2000 // time each plane is displayed in us -> 100 Hz refresh
#define TIMECONST 10// 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

const char PROGMEM PatternTable[] = {
  B1111,B1111,B1111,B0110   ,B1111,B1111,B1111,B0000   ,B1111,B1111,B1111,B0110  ,B1111,B1111,B1001,B1111   , 100, 
  B1111,B1111,B0110,B1111   ,B1111,B1111,B0000,B1111   ,B1111,B1111,B0110,B1111  ,B1111,B1111,B1001,B1111   , 100,
  B1111,B0110,B1111,B1111   ,B1111,B0000,B1111,B1111   ,B1111,B0110,B1111,B1111  ,B1111,B1001,B1111,B1111   , 100, 
  B0110,B1111,B1111,B1111   ,B0000,B1111,B1111,B1111   ,B0110,B1111,B1111,B1111  ,B1001,B1111,B1111,B1111   , 100, 
  
  
  B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, 0 
};

int LEDPin[] = {13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, A5, A4};
int PlanePin[] = {A0, A1, A2, A3};
// initialization
void setup()
{
int pin; // loop counter
// set up LED pins as output (active HIGH)
for (pin=0; pin<PLANESIZE; pin++) {
pinMode( LEDPin[pin], OUTPUT );
}
// set up plane pins as outputs (active LOW)
for (pin=0; pin<CUBESIZE; pin++) {
pinMode( PlanePin[pin], OUTPUT );
}
}




/*
** 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
*/




// 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
ledpin = 0;
for (ledrow=0; ledrow<CUBESIZE; ledrow++) {
for (ledcol=0; ledcol<CUBESIZE; ledcol++) {
digitalWrite( LEDPin[ledpin++], PatternBuf[patbufidx] & (1 << ledcol) );
}
patbufidx++;
}

// turn current plane on
digitalWrite( PlanePin[plane], HIGH );
// delay PLANETIME us
delayMicroseconds( PLANETIME );
} // for plane
} // while <EndTime
} while (DisplayTime > 0); // read patterns until time=0 which signals end
}

Here is s different approach in my blog

Hi Marco_c. Thank you. i have downloaded the library but i don´t find any example or documentation on how to use it. ¿Could you direct me to it?

Anyways i still looking forward for any response to my petition. I'm already familiarized with the code i posted, i only need to replace the PROGMEM use to any kind of modifiable String[] or Char[].

Documentation is pretty much the blog article. From that and knowing how your own cube needs to be programmed most people can do their own thing.

What i'm trying to do is this.....I'm designing an application in c# that connects to the arduino serial port , sending the data led sequence in a string text , but with the code posted i cannot read the data and modify the const char PROGMEM PatternTable[] variable in runtime. I'm looking forn an approach to do this with the code above or similar one.

The easy way to convert this to SRAM is to remove the PROGMEM modifier from the variable declarations. You will probably run out of memory unless your pattern is very short. An SD card might be a better storage medium.

Hi MorganS. I have tried , and i spent many hours trying but no sucess, i don't undestand very well this code and i have problems to replace the first lines

memcpy_P( PatternBuf, PatternTable+PatternIdx, PLANESIZE ); //Don't know how to replace this to make it work with a normal char array
PatternIdx += PLANESIZE;

// read DisplayTime from PROGMEM and increment index
DisplayTime = pgm_read_byte_near( PatternTable + PatternIdx++ );

I'm designing a application in c# thats connects to the arduino serial port

In your current code you are using the hardware serial pins (0 and 1) to control LEDs so cannot use them for serial input as well. It looks like you are using a Uno and have no spare pins to move the connections currently using pins 0 and 1

UKHeliBob thank you for the info.

I'll get the Arduino Mega instead to overcome that. ¿ Any idea how to deal with the code?

The Mega has 8K of SRAM compared with the 2K of the Uno so you may solve both problems at the same time by using a Mega

If you are not using PROGMEM to store the data, why are you using memcpy_P() to copy from PROGMEM?

Hi PAUL, i posted the original code.

I don't know what i should leave and what i should replace. I would like to know if i can replace the const char PROGMEM PatternTable[] = {......} //This i cannot modify in the runtime program

to something like

void loop()
{
char PatternTable[] = {.........} //This would be filled with data from Serial.Read in runtime program

..
...
..
}

¿What should i modify?

What should i modify?

A lot of stuff. First, you remove the PROGMEM designation from the variable declaration. Then, you change all functions that try to access the data to access the data from SRAM, not PROGMEM (memcpy, not memcpy_P, for instance).

Hi PaulS, Thank you, i have advanced a little.

Still not working 100%. ¿How should i replace "pgm_read_byte_near"?

Original line code:

" DisplayTime = pgm_read_byte_near( PatternTable + PatternIdx++ ); "

DisplayTime = PatternTable + PatternIdx++;

PaulS.

When i put that line i get
"exit status 1
invalid conversion from 'char*' to 'byte {aka unsigned char}' [-fpermissive]" .

I know this is basic and sorry about that, im learning about arduino programming.

FrankIQ:
PaulS.

When i put that line i get
"exit status 1
invalid conversion from 'char*' to 'byte {aka unsigned char}' [-fpermissive]" .

I know this is basic and sorry about that, im learning about arduino programming.

change (line 77)

    DisplayTime = PatternTable + PatternIdx++;

to

    DisplayTime = PatternTable [ PatternIdx++ ];

Hi arduinodlb, Works perfect!! Thank you!!!

I'm dealing with the communication between the C# application and the arduino code.

Somehow the string i pass from the c# app it's not saved as it supposed to be in the PatternTable[],

I pass from C# app to arduino for example, a string with the text format: "B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,1000,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,0";

if (Serial.available() > 0)
{
String Read = Serial.read();

int SIZE = (Read.length() + 1);
char PatternTable[SIZE];

Read.toCharArray(PatternTable,SIZE);
}

The code compiles but the leds sequence is not working like when i define directly on the arduino code:

char PatternTable[] = {B0000,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,1000,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,B1111,0};

I know is has to do with the string text convertion to binary char array, but i can't find on web how to deal with this.

Any help will be appreciated

String Read = Serial.read();

The read() method returns ONE character. It is silly to make a String out of that.

int SIZE = (Read.length() + 1);

It is pointless to use this to compute that SIZE is 2. By convention, all capital letter names are reserved for constants. Constants do not appear on the left of an equal size. They are defined using const.

char PatternTable[SIZE];

Read.toCharArray(PatternTable,SIZE);

More pointless code.