Logic discussion/help?

hey gang-

I am -not- looking for any code (yet) :slight_smile: , but more of a discussion on maybe a nice easy way to accomplish this.

Background:

MAX7221 chip(s)

1.) 1 is controlling a 3-digit, 7-segment display // this is all working fine

2.) the other chip is controlling a pcb that has 30 x SMD LEDS in a line/strip… (but of course wired up like a matrix for the MAX chip to utilize/control)

I am VERY tight on SRAM, and am currently/already using the LED CONTROL LIBRARY: http://playground.arduino.cc//Main/LedControlDemos

to work with the 3-digit display.

for the 3-digit display I have a function like so:

void updateDisplay(){
  //split main ammo count into separate digits
  int dig1 = ammoCount / 100 % 10;//3 on start  
  int dig2 = ammoCount / 10 % 10;//0 on start
  int dig3 = ammoCount % 10; //0 on start 
  lc.setDigit(0, 0, dig1, false);
  lc.setDigit(0, 1, dig2, false);
  lc.setDigit(0, 2, dig3, false);  
};

which takes a variable (ammoCount) parses it into its separate digits/numbers… and I update the display to reflect it.

Easy, simple, works great…

I am trying to wrap my head around the best way to update this ‘bar graph’ (30 x SMD LED pcb)…

my current approach is:

1.) I check to see if ‘ammoCount’ is odd or even (because I only wanna dim an led on the bar graph every OTHER fire/button press)
2.) IF ammoCount IS odd (I subtract one from another var: bargraphCounter–;, and then call want to call some function, that can take that ‘number’ (0-30) and update the bragraph…

called elsewhere (checked in main loop):

if((bargraphCount % 2) != 0){
	//odd shot fired
	bargraphCount--;
	updateBargraph();
}else{
	//do nothing about bargraph
}



//function that is called/Im working on:

void updateBargraph(){  
	if(bargraphCount > 0){
		for(int col=0;col<8;col++) {
			for(int row=0;row<4;row++) {
				//do some stuff
        
      			}
  	  	}
  }else if(bargraphCount == 0){
    //clip/bargraph counter is empty    
  }
}

I guess Im looking for some feedback on the best way to approach this?

Do I just keep with this ‘for loop’ approach?

There is only 30 leds though… so if I kept with this, would I just be using/checking/incrementing a var… and keep doing conditional checking on each loop to see if I am 30 (or whatever)

Im not sure if there is some better way to code this where it is sorta like the function above it?

updateDisplay() function…

where it just takes the ammoCount var and updates…

Maybe Im over thinking it? or missing something easy to implement?

but I cant seem to wrap my head around anything but a ‘loop’ where I sequentially turn on/off each led.

(its supposed to be a counter… where every ‘other’ button press 1 led gets dimmed/turned off… down from max:30 to 0)

thanks!

Looks like a workable approach.

Another way is to realize that you are just sending 8 bytes to the MAX7219 when you want to update the display.
So a have a couple pieces of code and an array displayArray[8]

bytes 0,1,2 are the 3 digits
bytes 3,4,5,6 are the 30 LEDs

one piece of code udpates bytes 0,1,2, sets an updateDisplay flag when something changes

one piece of code updates bytes 3,4,5,6, sets the updateDislauy flag when something changes

one piece of code checks if the flag was set, SPI.transfers out the 7 bytes, clears the flag

part 2 adds 1 to byte 3 and shifts it left, when it reaches 0xFF it does the same for the next byte and so on for byte and then 2 bits of byte 6.

if ( (buttonPush ==1) && byte3 !=0xFF){
byte3 = (byte3<<1) +1;
}

Or make a 32 bit word, and shift/add a 1 to that, then send out the 8-bit pieces of that.

well Im not using/importing the SPI lib.. (unless the Led Control lib does it behind the scenes?)..

and Im not sure if abdoning the Led Control lib at this point makes sense (alot of the sketch is done/complete, and the only thing left is to add in a quick/small function to update the bargraph to match 0-30 with the leds)

I have never really with worked with byte shifting.. (and frankly is above my pay grade currently) LOL.. :)

I was/am hoping to work out some solution using the Led Control lib (since its there and already in use elsewhere)

Was also thinking about maybe using the setRow() method?

lc.setRow(0,rowNum,B10100000);

but then would I have to have 30+ 'hard coded', 8byte values defined?

I guess I'll try and workout some sort of loop first and see where I can get to.

thanks!

coming back after a few…

geez… I keep coming back to hard coding all 30 ‘values’… each value into its own array…

like this:
//*(keep in mind only 30 leds not 32)

const byte bargraphTotal = 30;
volatile byte bargraphCount = 30;

byte c30[4]={B11111111,B11111111,B11111111,B11111100};
byte c29[4]={B01111111,B11111111,B11111111,B11111100};
byte c28[4]={B00111111,B11111111,B11111111,B11111100};
.........
byte c1[4]={B00000000,B00000000,B00000000,B00000100};
byte c0[4]={B00000000,B00000000,B00000000,B00000000};

then put all these into an array

byte counterArray[30]={c0,c1,c2,,,,,,,c29,c30];

then using that as my look up and looping through the rows, setting the leds?

like so:

void updateBargraph(){
	if(bargraphCount > 0){
		for(int i=0; i < 4; i++){
			lc.setRow(1,i,counterArray[bargraphCount][i]);
		}
	}

}

make sense?

my thoughts are though… not very efficient perhaps? better/faster way to do this?

I was thinking more of a way to do the:
byte c30[4]={B11111111,B11111111,B11111111,B11111100};
byte c29[4]={B01111111,B11111111,B11111111,B11111100};
etc…etc

dynamically when the function was called based on the bargraphCounter variable?

Im sure with the byte shifting stuff you suggested it would be easier… its just over my head to grasp right now.

*EDIT:

I cant seem to make an array of arrays? (syntax?)

bargraph_counterDemo_1:17: error: invalid conversion from ‘byte*’ to 'byte

Im not quite ‘up to par’ on the datatyping/casting yet… :frowning:

byte c30[4]={B11111111,B11111111,B11111111,B11111100};
byte c29[4]={B01111111,B11111111,B11111111,B11111100};
byte c28[4]={B00111111,B11111111,B11111111,B11111100};
.........
byte c1[4]={B00000000,B00000000,B00000000,B00000100};
byte c0[4]={B00000000,B00000000,B00000000,B00000000};

http://www.gammon.com.au/forum/?id=12153#tip1

You can have two-dimensional arrays, you know. AND put them into program memory to save RAM. Example here in my VGA output sketch:

http://www.gammon.com.au/forum/?id=11608

byte screen_font [8] [256] PROGMEM = {
// Row 1
 { 
  0xFF, 0xC0, 0xC0, 0xC9, 0xF7, 0xE3, 0xF7, 0xFF, 0x80, 0xFF, 0x80, 0xF8, 0xE1, 0xE0, 0xC0, 0xB3, 
  0xBF, 0xFE, 0xF3, 0xCC, 0xC0, 0xE0, 0xFF, 0xF3, 0xF3, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
  0xFF, 0xE7, 0xC9, 0xC9, 0xE7, 0xFF, 0xE3, 0xCF, 0xF3, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 
  0xC1, 0xE7, 0xC3, 0xC3, 0xF1, 0x81, 0xE3, 0x81, 0xC3, 0xC3, 0xFF, 0xFF, 0xF3, 0xFF, 0xCF, 0xC3, 
  0xC1, 0xE7, 0x81, 0xE1, 0x83, 0x80, 0x80, 0xE1, 0x99, 0xC3, 0xF0, 0x8C, 0x87, 0x9C, 0x9C, 0xE3, 
  0x81, 0xC3, 0x81, 0xC3, 0x81, 0x99, 0x99, 0x9C, 0x9C, 0x99, 0x80, 0xC3, 0x9F, 0xC3, 0xF7, 0xFF, 
  0xE7, 0xFF, 0x8F, 0xFF, 0xF1, 0xFF, 0xE3, 0xFF, 0x8F, 0xE7, 0xF9, 0x8F, 0xC7, 0xFF, 0xFF, 0xFF, 
  0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF1, 0xF3, 0x8F, 0xC4, 0xFF, 
  0xC3, 0xFF, 0xF1, 0xC0, 0x99, 0x8F, 0xE7, 0xFF, 0xC0, 0x99, 0x8F, 0x99, 0xC1, 0x8F, 0x9C, 0xE7, 
  0xF1, 0xFF, 0xE0, 0xC3, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0x9E, 0x99, 0xF3, 0xE3, 0x99, 0x83, 0xF8, 
  0xF1, 0xE3, 0xFF, 0xFF, 0xFF, 0x81, 0xE1, 0xE3, 0xE7, 0xFF, 0xFF, 0x9E, 0x9E, 0xF3, 0xFF, 0xFF, 
  0xEE, 0xD5, 0x92, 0xF3, 0xF3, 0xF3, 0xE4, 0xFF, 0xFF, 0xE4, 0xE4, 0xFF, 0xE4, 0xE4, 0xF3, 0xFF, 
  0xF3, 0xF3, 0xFF, 0xF3, 0xFF, 0xF3, 0xF3, 0xE4, 0xE4, 0xFF, 0xE4, 0xFF, 0xE4, 0xFF, 0xE4, 0xF3, 
  0xE4, 0xFF, 0xFF, 0xE4, 0xF3, 0xFF, 0xFF, 0xE4, 0xF3, 0xF3, 0xFF, 0x80, 0xFF, 0x87, 0xF8, 0x80, 
  0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0x81, 0xE3, 0xE3, 0xF1, 0xFF, 0xFC, 0xE3, 0xC3, 
  0xFF, 0xE7, 0xCF, 0xF3, 0xF8, 0xF3, 0xE7, 0xFF, 0xE3, 0xFF, 0xFF, 0xF8, 0xC3, 0xC7, 0xFF, 0xFF, 
  }, 
// Row 2
 { 
  0xFF, 0xBF, 0x80, 0x80, 0xE3, 0xC1, 0xF7, 0xFF, 0x80, 0xE1, 0x9E, 0xFC, 0xCC, 0xE6, 0xCE, 0xD2, 
  0x8F, 0xF8, 0xE1, 0xCC, 0x92, 0xCE, 0xFF, 0xE1, 0xE1, 0xF3, 0xF3, 0xE7, 0xFF, 0xED, 0xF3, 0x80, 
  0xFF, 0xC3, 0xC9, 0xC9, 0xC1, 0x9C, 0xC9, 0xCF, 0xE7, 0xE7, 0xCC, 0xE7, 0xFF, 0xFF, 0xFF, 0xF9, 
  0x9C, 0xC7, 0x99, 0x99, 0xE1, 0x9F, 0xCF, 0x99, 0x99, 0x99, 0xE7, 0xE7, 0xE7, 0xFF, 0xE7, 0x99, 
  0x9C, 0xC3, 0xCC, 0xCC, 0xC9, 0xCE, 0xCE, 0xCC, 0x99, 0xE7, 0xF9, 0xCC, 0xCF, 0x88, 0x8C, 0xC9, 
  0xCC, 0x99, 0xCC, 0x99, 0xA5, 0x99, 0x99, 0x9C, 0x9C, 0x99, 0x9C, 0xCF, 0xCF, 0xF3, 0xE3, 0xFF, 
  0xE7, 0xFF, 0xCF, 0xFF, 0xF9, 0xFF, 0xC9, 0xFF, 0xCF, 0xFF, 0xFF, 0xCF, 0xE7, 0xFF, 0xFF, 0xFF, 
  0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xF3, 0xE7, 0x91, 0xF7, 
  0x99, 0x99, 0xFF, 0x9E, 0xFF, 0xFF, 0xE7, 0xFF, 0x9E, 0xFF, 0xFF, 0xFF, 0x9C, 0xFF, 0xE3, 0xE7, 
  0xFF, 0xFF, 0xC9, 0x99, 0x99, 0x8F, 0x99, 0x8F, 0x99, 0xF3, 0xFF, 0xF3, 0xC9, 0x99, 0x99, 0xF2, 
  0xFF, 0xFF, 0xF1, 0xF1, 0x83, 0xFF, 0xC9, 0xC9, 0xFF, 0xFF, 0xFF, 0x9C, 0x9C, 0xF3, 0xE6, 0x99, 
  0xBB, 0xAA, 0xC4, 0xF3, 0xF3, 0xF3, 0xE4, 0xFF, 0xFF, 0xE4, 0xE4, 0xFF, 0xE4, 0xE4, 0xF3, 0xFF, 
  0xF3, 0xF3, 0xFF, 0xF3, 0xFF, 0xF3, 0xF3, 0xE4, 0xE4, 0xFF, 0xE4, 0xFF, 0xE4, 0xFF, 0xE4, 0xF3, 
  0xE4, 0xFF, 0xFF, 0xE4, 0xF3, 0xFF, 0xFF, 0xE4, 0xF3, 0xF3, 0xFF, 0x80, 0xFF, 0x87, 0xF8, 0x80, 
  0xFF, 0xC3, 0x81, 0x80, 0x99, 0xFF, 0xCC, 0xC4, 0xE7, 0xC9, 0xC9, 0xE7, 0xFF, 0xF9, 0xCF, 0x99, 
  0x81, 0xE7, 0xE7, 0xE7, 0xF2, 0xF3, 0xE7, 0xC4, 0xC9, 0xFF, 0xFF, 0xF9, 0xC9, 0xF3, 0xFF, 0xFF, 
  }, 
...

Thanks..

defining them as const bytes helps...

however.. Im confused..

do I 'have' to hard code the 'second' dimension of the array like you have done it?

so Im creating my multi-dimensional array incorrectly.. is that it? (the byte to byte conversion error?)

can I not define each array individually like Im doing (although Im guessing your way also takes up less space as well) :) .. and then push that array/reference into the main/parent array?

so I should be doing:

byte counterArray[3] [4] PROGMEM = {
  {
    B11111111,B11111111,B11111111,B11111100  } //30
  , 
  {
    B01111111,B11111111,B11111111,B11111100  } //29
  , 
  {
    B00111111,B11111111,B11111111,B11111100  } //28...etc
};

thanks!

can I not define each array individually like Im doing (although Im guessing your way also takes up less space as well) .. and then push that array/reference into the main/parent array?

You can, but then you have to number lots of variables.

defining them as const bytes helps...

Being in PROGMEM one assumes they are const.

I’d definitely not define 30x4 byte values - that’s crazy. Especially if you’re short on memory.

Do something like this:

#define MAX_COUNT 30

void updateBargraph(uint8_t count)
{
    // Create a 32 bit mask (bottom 2 bits don't matter)
    uint32_t led_mask = 0xffffffff; // 32-bit, initialize with all '1's
    led_mask >>= (MAX_COUNT - count); // Shift it over to fill in '0's from the left
    uint8_t *p = reinterpret_cast<uint8_t*>(&led_mask);

    // Now write out 4 bytes (not sure if that's the right syntax for the lc library)
    lc.setRow(1, 0, p[0]);
    lc.setRow(1, 1, p[1]);
    lc.setRow(1, 2, p[2]);
    lc.setRow(1, 3, p[3]);
}

LED control lib bit bangs the SPI out to the MAX7219. I have never used it.
MAX7219 requires setting up 4-5 registers, then just transfer out the 7 bytes for the digits.
Very simple.
My method of 32-bit variable for the 30 LEDs, also easy to break up and put the 4 bytes into the displayArray:
Use a variation of this

  // send out new LED info to shift register
  digitalWrite(latch, LOW);
  SPI.transfer( 0x000000FF & timeCombo);  // lower 8
  SPI.transfer((0x0000FF00 & timeCombo)>>8);  // middle 8
  SPI.transfer((0x00FF0000 & timeCombo)>>16); // upper 8
  digitalWrite (latch, HIGH);

thusly:

displayArray[3] = 0x000000FF & timeCombo;  // lower 8
displayArray[4] = (0x0000FF00 & timeCombo)>>8; 
displayArray[5] = (0x00FF0000 & timeCombo)>>16;
displayArray[6] = (0xFF000000 & timeCombo)>>24;

Then send to MAX7219:

digitalWrite(ssPin, LOW);
for (x=0; x<7; x=x+1){
SPI.transfer(x+1); // registers 1,2,3,4,5,6,7
SPI.tranfer(displayArray[x]); // data from array locations 0,1,2,3,4,5,6
}
digitalWrite (ssPin, HIGH);

No reason to be scared of the SPI interface.

 lc.setRow(1,i,counterArray[30-bargraphCount]);

this line seems to be throwing an error:

bargraph_counterDemo_1:59: error: invalid conversion from ‘byte*’ to ‘byte’

not sure how to go about solving this…??

//bargraph vars
const byte bargraphTotal = 30;
volatile byte bargraphCount = 30;


byte counterArray[31] [4] PROGMEM = {
  {B11111111,B11111111,B11111111,B11111100}, //30 ----
  {B01111111,B11111111,B11111111,B11111100}, //29
  {B00111111,B11111111,B11111111,B11111100}, //28
  {B00011111,B11111111,B11111111,B11111100}, //27
  {B00001111,B11111111,B11111111,B11111100}, //26
  {B00000111,B11111111,B11111111,B11111100}, //25
  {B00000011,B11111111,B11111111,B11111100}, //24
  {B00000001,B11111111,B11111111,B11111100}, //23
  {B00000000,B11111111,B11111111,B11111100}, //22
  {B00000000,B01111111,B11111111,B11111100}, //21
  {B00000000,B00111111,B11111111,B11111100}, //20 ----
  {B00000000,B00011111,B11111111,B11111100}, //19
  {B00000000,B00001111,B11111111,B11111100}, //18
  {B00000000,B00000111,B11111111,B11111100}, //17
  {B00000000,B00000011,B11111111,B11111100}, //16
  {B00000000,B00000001,B11111111,B11111100}, //15
  {B00000000,B00000000,B11111111,B11111100}, //14
  {B00000000,B00000000,B01111111,B11111100}, //13
  {B00000000,B00000000,B00111111,B11111100}, //12
  {B00000000,B00000000,B00011111,B11111100}, //11
  {B00000000,B00000000,B00001111,B11111100}, //10 -----
  {B00000000,B00000000,B00000111,B11111100}, //9
  {B00000000,B00000000,B00000011,B11111100}, //8
  {B00000000,B00000000,B00000001,B11111100}, //7
  {B00000000,B00000000,B00000000,B11111100}, //6
  {B00000000,B00000000,B00000000,B01111100}, //5
  {B00000000,B00000000,B00000000,B00111100}, //4
  {B00000000,B00000000,B00000000,B00011100}, //3
  {B00000000,B00000000,B00000000,B00001100}, //2
  {B00000000,B00000000,B00000000,B00000100}, //1
  {B00000000,B00000000,B00000000,B00000000}  //0 ----
};


void updateBargraph(){
  if(bargraphCount > 0){
    for(int i=0; i < 4; i++){
      lc.setRow(1,i,counterArray[30-bargraphCount]);
    }
  }
}

@crossroads -

**saw you posted right when I hit submit… (I have not read your post through yet)

update:

ok. it now compiles… but isnt working as I thought…

I see I forgot the second array index value parameter…

new:

void updateBargraph(){
  if(bargraphCount > 0){
    for(int i=0; i < 4; i++){
      //Serial.println((counterArray[bargraphCount][i]), BIN);
      //Serial.println((counterArray[bargraphCount][i]));
      lc.setRow(1,i,(30 - counterArray[bargraphCount][i]));
    }
    Serial.println(F(""));
  }
}

although when trying to print out the values of the array from above.. i dont think Im targetting things correctly..?

as the leds dont update correctly.. nor does the print out look right.

xl97: lc.setRow(1,i,counterArray[30-bargraphCount]);

You can't directly access PROGMEM like that. See my link above for how I get the font data out.

xl97:

byte counterArray[31] [4] PROGMEM = {

{B11111111,B11111111,B11111111,B11111100}, //30 ----
 {B01111111,B11111111,B11111111,B11111100}, //29
 {B00111111,B11111111,B11111111,B11111100}, //28
 {B00011111,B11111111,B11111111,B11111100}, //27
  … and so forth

What’s this??

Why not just something like

unsigned long bargraph = ((1 << barlength) - 1) << 2;

and you extract the individual bytes as

firstbyte =  (byte)(bargraph >> 24);
secondbyte = (byte)(bargraph >> 16);
thirdbyte =  (byte)(bargraph >> 8);
fourthbyte = (byte)bargraph;

@Nick Gammon -

I have never used PROGMEM before… so Im not really clear on how to get it out… (nor how to from your link?)

I wasnt even sure I had used it correctly to store it there, ore or less blindly copied your example and applied it my array. :slight_smile:

I did see this: ‘So, the fonts have to go into PROGMEM (program memory) and be accessed on the fly for every line, using “program memory read”.’…

I am off to google more about PROGMEM in general, and see if I can put something together I guess. :slight_smile:

I tried this:

Serial.println(pgm_read_byte(counterArray[bargraphCount][i]), BIN);
//Serial.println(pgm_read_byte(counterArray[bargraphCount][i]));

just got odd stuff in the serial monitor… :frowning:

11001110
0
0
0
.
11001110
0
0
0
.


@odometer -

hopefully I can answer…

1.) thats my attempt at defining a multidimensional array.

2.) why? because I dont know any better, if I knew, (I wouldnt need to post) :slight_smile:

Im not sure what the << are doing/do? (shifting something?)

nor what the (byte) (bargraph >> 24) is doing either…

maybe your trying to describe this, (as applied to this post)

const byte bargraphTotal = 30;
volatile byte bargraphCount = 30; // this gets decreased whenever button is pressed, and should be used as the 'source' number Im trying to create a 8 byte, binary output I guess? to represent that number on a 30 led long bar graph.


unsigned long bargraphCount = ((1 << bargraphTotal) - 1) << 2;

and then all the << stuff?

quick demo sketch (full post)

Im not clear on what Im doing wrong here? (throw me a bone) :slight_smile:

Is the data In PROGMEM?
Am I just not accessing it right?

is it having to deal with using vars to access data in PROGMEM but are not progmem data types before sending it there?
(read some threads that elude to this)

#include "LedControl.h"

//create LedControl lib instance
LedControl lc=LedControl(3, 6, 5, 2); //scab board (2 max chips)

//bargraph vars
const byte bargraphTotal = 30;
volatile byte bargraphCount = 30;

const byte counterArray[31][4] PROGMEM = {
  {B11111111,B11111111,B11111111,B11111100}, //30 ----
  {B01111111,B11111111,B11111111,B11111100}, //29
  {B00111111,B11111111,B11111111,B11111100}, //28
  {B00011111,B11111111,B11111111,B11111100}, //27
  {B00001111,B11111111,B11111111,B11111100}, //26
  {B00000111,B11111111,B11111111,B11111100}, //25
  {B00000011,B11111111,B11111111,B11111100}, //24
  {B00000001,B11111111,B11111111,B11111100}, //23
  {B00000000,B11111111,B11111111,B11111100}, //22
  {B00000000,B01111111,B11111111,B11111100}, //21
  {B00000000,B00111111,B11111111,B11111100}, //20 ----
  {B00000000,B00011111,B11111111,B11111100}, //19
  {B00000000,B00001111,B11111111,B11111100}, //18
  {B00000000,B00000111,B11111111,B11111100}, //17
  {B00000000,B00000011,B11111111,B11111100}, //16
  {B00000000,B00000001,B11111111,B11111100}, //15
  {B00000000,B00000000,B11111111,B11111100}, //14
  {B00000000,B00000000,B01111111,B11111100}, //13
  {B00000000,B00000000,B00111111,B11111100}, //12
  {B00000000,B00000000,B00011111,B11111100}, //11
  {B00000000,B00000000,B00001111,B11111100}, //10 -----
  {B00000000,B00000000,B00000111,B11111100}, //9
  {B00000000,B00000000,B00000011,B11111100}, //8
  {B00000000,B00000000,B00000001,B11111100}, //7
  {B00000000,B00000000,B00000000,B11111100}, //6
  {B00000000,B00000000,B00000000,B01111100}, //5
  {B00000000,B00000000,B00000000,B00111100}, //4
  {B00000000,B00000000,B00000000,B00011100}, //3
  {B00000000,B00000000,B00000000,B00001100}, //2
  {B00000000,B00000000,B00000000,B00000100}, //1
  {B00000000,B00000000,B00000000,B00000000}  //0 ----
};

void reloadMagazine(){
  for(int group=0;group<4;group++) {
    for(int led=0;led<8;led++) {
      delay(5);
      lc.setLed(1,group,led,true);
    }    
  }
  bargraphCount = 30;
}

void updateBargraph(){
  if(bargraphCount > 0){
    for(int i=0; i < 4; i++){
      //Serial.println((counterArray[bargraphCount][i]), BIN);
      //Serial.println((counterArray[bargraphCount][i]));
      Serial.println(pgm_read_byte_near(counterArray[bargraphCount][i]), BIN);
      //Serial.println(pgm_read_byte(counterArray[bargraphCount][0]));
      //pgm_read_byte
      //lc.setRow(1,i,(30 - counterArray[bargraphCount][i]));
    }
    Serial.println(F("."));
  }
}

void setup() {
  byte i;
  // set up serial port
  Serial.begin(9600);

  int devices=lc.getDeviceCount();
  //we have to init all devices in a loop
  for(int address=0;address<devices;address++) {
    /*The MAX72XX is in power-saving mode on startup*/
    lc.shutdown(address,false);
    /* Set the brightness to a medium values */
    lc.setIntensity(address,15);
    /* and clear the display */
    lc.clearDisplay(address);
  }  
  // Whew! We got past the tough parts.
  Serial.println(F("Ready!"));
  reloadMagazine();
  delay(1000);
}

void loop() {  
  if(bargraphCount > 0){   
   updateBargraph();
   bargraphCount--;
   }else{
   //do nothing
   }
   delay(1000);  //repeat, check bargraph display vs bargraphCount value
}

so looking at some of the example… and editing them for my sketch…

I ‘think’ I am now able to access the data in PROGMEM (somewhat) :slight_smile:

Serial.println(pgm_read_byte_near(counterArray[0] + 0), BIN);
    Serial.println(pgm_read_byte_near(counterArray[0] + 1), BIN);
    Serial.println(pgm_read_byte_near(counterArray[0] + 2), BIN);
    Serial.println(pgm_read_byte_near(counterArray[0] + 3), BIN);
    Serial.println();
    Serial.println(pgm_read_byte_near(counterArray[1] + 0), BIN);
    Serial.println(pgm_read_byte_near(counterArray[1] + 1), BIN);
    Serial.println(pgm_read_byte_near(counterArray[1] + 2), BIN);
    Serial.println(pgm_read_byte_near(counterArray[1] + 3), BIN);

seems to work as far as HARDCODING the values I want to grab…

this also seems to work in a loop… with ONE of the parameters being dynamic:

for(int i=0; i < 4; i++){
      Serial.println(pgm_read_byte_near(counterArray[0] + i), BIN);
 }

but when i try this: I get crazy output/results:

for(int i=0; i < 4; i++){
      Serial.println(pgm_read_byte_near(counterArray[bargraphCount] + i), BIN);
 }

the change being; bargraphCount as the array index… instead of hardcoding a value.

this bargraphCounter var is incremented/decreased throughout the sketch… and needs to be used in the dynamic ‘look-up’ of what index the array needs to be at (to read the 4 index of the byte array at that parent array index)

So I guess the question is:

how can I use this OUTSIDE PROGMEM variable/data in the PROGMEM_READ_BYTE method?

Serial.println(pgm_read_byte_near(counterArray[bargraphCount] + i), BIN);

thanks!

xl97:
@odometer -

hopefully I can answer…

1.) thats my attempt at defining a multidimensional array.

2.) why? because I dont know any better, if I knew, (I wouldnt need to post) :slight_smile:

Im not sure what the << are doing/do? (shifting something?)

nor what the (byte) (bargraph >> 24) is doing either…

This is what I’m trying to do:
http://arduino.cc/en/Reference/Bitshift
I suggest you familiarize yourself with the use of operators in C++ (the programming language that the Arduino development environment seems to be based on). Here is a reference I found:
http://www.cplusplus.com/doc/tutorial/operators/
Also, I strongly suggest learning the basics of datatypes and binary arithmetic, if you aren’t already familiar with them.

I had updated my post as you posted...(thanks for replying though)..

currently.. Im stuck trying to use a VARIABLE in a PROGMEM_READ_BYTE() call...

anyways.. you are right.. I dont have my experience/exposure with the Bitwise Operators in C++ (most others Im ok with)..

move ahead though...

can you explain why I cant use the variable in the PROGMEM_READ call?

I read something eluding to the fact that the var isnt defined.stored in PROGMEM... so it can use it? or accesses it different? (address?)

some sort of path/scope issue? (for that var?)

but if its a var defined in PROGMEM, then how do I dynamically update? (as it will change from 0-30)

thanks!

ok… I think its working now…

although I have a question before I move on and try to actually have it update the led bargraph…

I am getting serial output like so:

Ready!
11111111
11111111
11111111
11111100
.
1111111
11111111
11111111
11111100
.
111111
11111111
11111111
11111100
.

if you notice… the first line in each sequential group… is MISSING the leading zero’s?

is this because outputting it to Serial Monitor? will the zeros still be there if I pass it over to be used as a B00111011 (binary) value in the setRow() method in the led control library?

I tested it… it does seem to passing over the correct values… and counting the bargraph down!

Now I need to incorporate this into the MAIN sketch,… and hope I have no errors/bugs and enough space still! :slight_smile:

full code for anyone else searching/looking:

#include "LedControl.h"
#include <avr/pgmspace.h>
//create LedControl lib instance
LedControl lc=LedControl(3, 6, 5, 2); //scab board (2 max chips)

//bargraph vars
const byte bargraphTotal = 30;
volatile byte bargraphCount = 30;

PROGMEM const byte counterArray[31][4] = {
  {B11111111,B11111111,B11111111,B11111100}, //30 ----
  {B01111111,B11111111,B11111111,B11111100}, //29  
  {B00111111,B11111111,B11111111,B11111100}, //28
  {B00011111,B11111111,B11111111,B11111100}, //27
  {B00001111,B11111111,B11111111,B11111100}, //26
  {B00000111,B11111111,B11111111,B11111100}, //25
  {B00000011,B11111111,B11111111,B11111100}, //24
  {B00000001,B11111111,B11111111,B11111100}, //23
  {B00000000,B11111111,B11111111,B11111100}, //22
  {B00000000,B01111111,B11111111,B11111100}, //21
  {B00000000,B00111111,B11111111,B11111100}, //20 ----
  {B00000000,B00011111,B11111111,B11111100}, //19
  {B00000000,B00001111,B11111111,B11111100}, //18
  {B00000000,B00000111,B11111111,B11111100}, //17
  {B00000000,B00000011,B11111111,B11111100}, //16
  {B00000000,B00000001,B11111111,B11111100}, //15
  {B00000000,B00000000,B11111111,B11111100}, //14
  {B00000000,B00000000,B01111111,B11111100}, //13
  {B00000000,B00000000,B00111111,B11111100}, //12
  {B00000000,B00000000,B00011111,B11111100}, //11
  {B00000000,B00000000,B00001111,B11111100}, //10 -----
  {B00000000,B00000000,B00000111,B11111100}, //9
  {B00000000,B00000000,B00000011,B11111100}, //8
  {B00000000,B00000000,B00000001,B11111100}, //7
  {B00000000,B00000000,B00000000,B11111100}, //6
  {B00000000,B00000000,B00000000,B01111100}, //5
  {B00000000,B00000000,B00000000,B00111100}, //4
  {B00000000,B00000000,B00000000,B00011100}, //3
  {B00000000,B00000000,B00000000,B00001100}, //2
  {B00000000,B00000000,B00000000,B00000100}, //1
  {B00000000,B00000000,B00000000,B00000000}    //0 ----
};

void reloadMagazine(){
  for(int group=0;group<4;group++) {
    for(int led=0;led<8;led++) {
      delay(5);
      lc.setLed(1,group,led,true);
  }    
}
  bargraphCount = 30;
}

void updateBargraph(){
  if(bargraphCount >= 0){
    for(int i=0; i < 4; i++){
      Serial.println(pgm_read_byte_near(counterArray[30 - bargraphCount] + i), BIN);
      lc.setRow(1,i,(pgm_read_byte_near(counterArray[30 - bargraphCount] + i)));
  }
    Serial.println(F("."));
}
}

void setup() {
  byte i;
  // set up serial port
  Serial.begin(9600);

  int devices=lc.getDeviceCount();
  //we have to init all devices in a loop
  for(int address=0;address<devices;address++) {
    /*The MAX72XX is in power-saving mode on startup*/
    lc.shutdown(address,false);
    /* Set the brightness to a medium values */
    lc.setIntensity(address,15);
    /* and clear the display */
    lc.clearDisplay(address);
}  
  // Whew! We got past the tough parts.
  Serial.println(F("Ready!"));
  reloadMagazine();
  delay(1000);
} 


void loop() {
  if(bargraphCount > 0){   
    updateBargraph();
    bargraphCount--;
    //PROGMEM bargraphCount2 = bargraphCount;
}
  else{
    //do nothing
}
  delay(700);
}

xl97: ok.. I think its working now..

So, you're really going with a 120+ byte lookup table instead of using the ~6 lines of code I posted above?! What happened to being strapped for space?

is this because outputting it to Serial Monitor? will the zeros still be there if I pass it over to be used as a B00111011 (binary) value in the setRow() method in the led control library?

Yes, it's all good.

int2str:

xl97: ok.. I think its working now..

So, you're really going with a 120+ byte lookup table instead of using the ~6 lines of code I posted above?! What happened to being strapped for space?

is this because outputting it to Serial Monitor? will the zeros still be there if I pass it over to be used as a B00111011 (binary) value in the setRow() method in the led control library?

Yes, it's all good.

hahaha.. yeah I guess.

Dont get me wrong.. your initial solution looked great and totally what i was looking for (take a parameter...etc)...

but two things:

1.) I didnt fully understand it.... (which made me feel a bit odd just blindly following/applying)..

2.) when I did try it out.. it didnt work correctly. :)

A.) it didnt start from any 'end'.. but from the first led in each group (of 8)...

so if these were the leds.. (starts with all on)

15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

it would start at led 23.. count down (dim leds) to 30... then go to led 15.. and count down (dim leds) to 22......etc

B.) it would only count down to '28' (leaving 2 leds on).. (I guess there is actually 31 states including all on/off)

changing that line to this:

//led_mask >>= (bargraphTotal - count); // Shift it over to fill in '0's from the left
led_mask >>= (count); // Shift it over to fill in '0's from the left

starts them all OFF... and turns them on.. in the reverse fashion.. starting at led 8.. turning them ON down to led 1... jumping to led 16...turning them ON down to led 9...etc..

:)

So you got it working while I was asleep? Excellent.

PROGMEM can be tricky to work with, especially if you use pointers, you need to know if the pointer points to real memory or program memory.