Page 1 of 3

8x8x8 cube programming

Posted: Tue Sep 01, 2020 10:10 am
by BobBurton
Loading this sketch onto the cube

Code: Select all

#include "HC8x8x8Cube.h"

void setup()
{
  Serial.begin(115200);
  CubeInit();
  CubeClearBuffer();
}

void loop()
{
  Matrix_Buffer[7][7] = 0x01;
  //  Base_LED(true);
  delay(1000);
  //Serial.println();
  Matrix_Buffer[7][7] = 0x00;
  delay(1000);
}
should, I believe, cause the top/right LED on the front face of the cube to blink, but the cube LED shows no sign of activity

Uncommenting either or both of the Serial.print() or Base_LED() function calls makes the LED behave as I would expect, ie blinking

Have you any idea what is going on here ?

Re: 8x8x8 cube programming

Posted: Tue Sep 01, 2020 3:00 pm
by andrew
So the advertised way of controlling the LEDs is with the SetVoxel() function. You have cunningly found the Matrix_Buffer array by looking at the source files but this bypasses the above function and has caused you to run foul of a compiler optimisation. In your sketch you are writing a value to the array, waiting a little, then writing another value to the same location. As you know by looking at the source code the library in the background reads this array and pushes it out to the matrix buffers via a timer interrupt vector.

The problem is that the compiler doesn't know about about the timer interrupt function and just sees that you're writing a value to an array and then writing another value to it without ever reading back from the array in between. As such it sees the first write as pointless and removes it. If you want to continue using the Matrix_Buffer array you'll need to make two small modification to the library to tell the compiler not to do this. In the HC8x8x8Cube.cpp file locate this line:

  1. /* Buffer to store the LED pattern that will be output to the cube */
  2. byte Matrix_Buffer[8][8];
and change it to this:

  1. /* Buffer to store the LED pattern that will be output to the cube */
  2. volatile byte Matrix_Buffer[8][8];

The in the HC8x8x8Cube.h file locate this line:

  1. /* Buffer used to hold the current 8x8x8 pattern currently being displayed by the cube */
  2. extern byte Matrix_Buffer[8][8];

And change it to this:

  1. /* Buffer used to hold the current 8x8x8 pattern currently being displayed by the cube */
  2. extern volatile byte Matrix_Buffer[8][8];

Re: 8x8x8 cube programming

Posted: Wed Sep 02, 2020 2:04 pm
by BobBurton
Thanks for the reply
You have cunningly found the Matrix_Buffer array by looking at the source files but this bypasses the above function and has caused you to run foul of a compiler optimisation.
Hardly very cunning, as you have posted examples using it directly in my other thread and a quick peek at the library code reveals the array, but I understand the cause of the problem, your explanation and fix, which I have implemented

However, even when using the SetVoxel() and ClearVoxel() functions the optimisation problem still occurs because what they do is to write a value to the Matrix_Buffer array as do many other library functions

Re: 8x8x8 cube programming

Posted: Wed Sep 02, 2020 3:54 pm
by andrew
However, even when using the SetVoxel() and ClearVoxel() functions the optimisation problem still occurs because what they do is to write a value to the Matrix_Buffer array as do many other library functions

Well those functions are actually doing a read - modify - write to the array. So the array is always read back before doing another write.

Re: 8x8x8 cube programming

Posted: Wed Sep 02, 2020 10:00 pm
by BobBurton
those functions are actually doing a read - modify - write to the array. So the array is always read back before doing another write.
If Matrix_Buffer is not declared as volatile then this

Code: Select all

void loop()
{
  SetVoxel(0, 0, 0);
  delay(1000);
  ClearVoxel(0, 0, 0);
  delay(1000);
}
produce no output on the cube so perhaps

Code: Select all

	Matrix_Buffer[z][7 - y] |= 0x80 >> x;	
and

Code: Select all

	Matrix_Buffer[z][7 - y] &= ~(0x80 >> x);
are not being seen by the compiler as a read - modify - write to the array

Re: 8x8x8 cube programming

Posted: Thu Sep 03, 2020 2:41 pm
by andrew
Odd, those commands are used extensively in the demo patterns and they work fine for that. It's quite an old library now so I wonder if some update with the Arduino IDE has broken it at some point. I'll get that fix added to the library anyway.

Re: 8x8x8 cube programming

Posted: Thu Sep 03, 2020 3:29 pm
by BobBurton
I have not noticed any problems with the demo but there is a lot going on in it. Running simpler patterns, which is what I am doing, shows things up, particularly when I am trying to get my head around what is happening in 3D space in the cube

You said earlier in this thread or my other one that not many people are interested in programming the cube which is perhaps why the problems have not been found sooner

Re: 8x8x8 cube programming

Posted: Sun Sep 06, 2020 7:52 am
by andrew
You said earlier in this thread or my other one that not many people are interested in programming the cube which is perhaps why the problems have not been found sooner
Sadly yes although it's possible a recent update to the IDE has broken it. I've uploaded the latest version of the library to the software section anyway. Thanks again for your help.

Re: 8x8x8 cube programming

Posted: Sun Sep 06, 2020 8:04 pm
by BobBurton
Thanks again for your help.
I am glad to have been of some help.

I have something else to try that may allow the brightness of the cube to be controlled and I will let you know how I get on

Re: 8x8x8 cube programming

Posted: Mon Sep 07, 2020 10:43 am
by BobBurton
Well, that was easy

I disconnected pin 6 of the 3 to 8 decoder from VCC and connected it to Arduino pin 5. Now an analogWrite() to pin 5 sets the brightness of the cube as a whole with no visible ill effects

It is particularly effective with a block of LEDs lit and a variation of PWM value over time to produce a pulsing effect and of course a SetBrightness() function in the library would only be a couple of lines of code.

I have also experimented with changing the brightness of one or more layers by changing the PWM level for particular values of RowIndex in the ISR. Whilst it works it is not very effective visually, so is probably not worth implementing

Whilst making changes to the PCB you might like to consider incorporating the change to add control of brightness and adding a function to the library.

I will update this thread if I have any more bright ( :D ) ideas