First attempt at looping through (not full) matrix led strip...

hi gang..

so I made a mockup/prototype of an LED strip... (because I couldnt find any retail ones that has he leds right next to each other instead of spaced out over 1-3 meters...etc)

soldered everything up (best I could/saw fit)...

and wired it up to my MAX7221 chip (I have MAX7219 chips.. too but if I ever jump to use SPI...might as well stick with the MAX7221's)

and gave some test code a 'go'..

now I dont have 64 leds in my matrix.. I only have 60 leds in total on this strip.. (eventually there will be another MAX7221 chip and another 60 led matrix trip/ladder.. to make a complete 'circle' totalling 2 MAX chips and 120 leds..etc

but for now..I only have 1 led strip done.. an wired up..

I am using the LedControl library posted here.. (its very easy for a beginner to understand and the functions are easy to use understand)

however.. Im sure I am not tackling this the best way..

it seems to be glitchy when it 'starts'.. and then works itself out.. but 'feels' slow or not as fast I would have though? (maybe the LedControl lib uses delays or something?)

and Im fairly certain that is NOT the right way to stop/check at 60 leds (or at 4)..when it set up for 64 leds??

maybe a different approach using the same: "lc.setLed(0,col,row,false);" type method.

for this test.. i was simple trying to turn on each led in sequence, then reverse.. (not starting from beginning and turning off, but starting from the end)

please ignore all my PRINT() statements.. Im new to coding in Arduino/C and it 'really' helps me track and debug my own code..

I commented them out.. as they make the code VERY slow.. even if you dont have the serial monitor on/displayed

//We always have to include the library
#include "LedControl.h"

/*
Now we need a LedControl to work with.
***** These pin numbers will probably not work with your hardware *****
pin 12 is connected to the DataIn
pin 11 is connected to the CLK
pin 10 is connected to LOAD
***** Please set the number of devices you have *****
But the maximum default of 8 MAX72XX wil also work.
*/
LedControl lc=LedControl(12, 11, 10, 1);

/* we always wait a bit between updates of the display /
unsigned long delaytime=5;
int counter1=0;
/

This time we have more than one device.
But all of them have to be initialized
individually.
*/
void setup() {
Serial.begin(9600);
//we have already set the number of devices when we created the LedControl
int devices=lc.getDeviceCount();
//Serial.println("--SET UP--");
//Serial.println(devices);

//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);
}
}

void loop() {
//read the number cascaded devices
int devices=lc.getDeviceCount();

if(counter1<60){
for(int col=0;col<8;col++) {
for(int row=0;row<8;row++) {
//for(int address=0;address<devices;address++) {
lc.setLed(0,col,row,true);
//Serial.print("DEVICE");
// Serial.println(0);
// Serial.print("SECTION ");
// Serial.println(col);
//Serial.print("LED ");
//Serial.println(row);
//Serial.println("");
delay(delaytime);
counter1++;
if(counter1 == 60){
//Serial.println("");
//Serial.println("HIT 60");
//Serial.println("");
row = 8;
//counter1=60;
}
//Serial.print("COUNTER UP: ");
//Serial.print(counter1);
//Serial.println("");
//lc.setLed(address,row,col,false);
//}
}
}
}
else if(counter1>=60){
//Serial.println("");
//Serial.println("START COUNTING DOWN");
//Serial.println("");
//we have to init all devices in a loop
for(int col=7;col>=0;col--) {
//Serial.println("COL TRACE");
for(int row=7;row>=0;row--) {
//Serial.println("ROW TRACE");

//for(int address=devices;address>0;address--) {
lc.setLed(0,col,row,false);
//Serial.print("DEVICE");
//Serial.println(0);
//Serial.print("SECTION ");
//Serial.println(col);
//Serial.print("LED ");
//Serial.println(row);
//Serial.println("");
delay(delaytime);
counter1--;
if(counter1 == 4){
//Serial.println("");
//Serial.println("HIT 0");
//Serial.println("");
row = 8;
//break;
//counter1=60;
}
//Serial.print("COUNTER DOWN: ");
//Serial.print(counter1);
//Serial.println("");
//lc.setLed(address,row,col,false);
//}
}
}
}

}

and again just in CODE tags.. for those people who just cant help any other way:

//We always have to include the library
#include "LedControl.h"

/*
 Now we need a LedControl to work with.
 ***** These pin numbers will probably not work with your hardware *****
 pin 12 is connected to the DataIn 
 pin 11 is connected to the CLK 
 pin 10 is connected to LOAD 
 ***** Please set the number of devices you have *****
 But the maximum default of 8 MAX72XX wil also work.
 */
LedControl lc=LedControl(12, 11, 10, 1);

/* we always wait a bit between updates of the display */
unsigned long delaytime=5;
int counter1=0;
/* 
 This time we have more than one device. 
 But all of them have to be initialized 
 individually.
 */
void setup() {
  Serial.begin(9600);
  //we have already set the number of devices when we created the LedControl
  int devices=lc.getDeviceCount();
  //Serial.println("--SET UP--");
  //Serial.println(devices);

  //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);
  }
}

void loop() { 
  //read the number cascaded devices
  int devices=lc.getDeviceCount();

  if(counter1<60){
    for(int col=0;col<8;col++) {
      for(int row=0;row<8;row++) {
        //for(int address=0;address<devices;address++) {
        lc.setLed(0,col,row,true);
        //Serial.print("DEVICE");
        // Serial.println(0);
        //  Serial.print("SECTION ");
        // Serial.println(col);
        //Serial.print("LED ");
        //Serial.println(row);          
        //Serial.println("");
        delay(delaytime);
        counter1++;
        if(counter1 == 60){
          //Serial.println("");
          //Serial.println("HIT 60");
          //Serial.println("");
          row = 8;
          //counter1=60;
        }
        //Serial.print("COUNTER UP: ");
        //Serial.print(counter1);
        //Serial.println("");
        //lc.setLed(address,row,col,false);
        //}
      }
    }
  }
  else if(counter1>=60){
    //Serial.println("");
    //Serial.println("START COUNTING DOWN");
    //Serial.println("");
    //we have to init all devices in a loop
    for(int col=7;col>=0;col--) {
      //Serial.println("COL TRACE");
      for(int row=7;row>=0;row--) {
        //Serial.println("ROW TRACE");

        //for(int address=devices;address>0;address--) {
        lc.setLed(0,col,row,false);
        //Serial.print("DEVICE");
        //Serial.println(0);
        //Serial.print("SECTION ");
        //Serial.println(col);
        //Serial.print("LED ");
        //Serial.println(row);          
        //Serial.println("");
        delay(delaytime);
        counter1--;
        if(counter1 == 4){
          //Serial.println("");
          //Serial.println("HIT 0");
          //Serial.println("");
          row = 8;
          //break;
          //counter1=60;
        }
        //Serial.print("COUNTER DOWN: ");
        //Serial.print(counter1);
        //Serial.println("");
        //lc.setLed(address,row,col,false);
        //}
      }
    }
  }

}

maybe the LedControl lib uses delays or something?

Or maybe it's YOUR code that uses delays!

        delay(delaytime);

This is inside a nested for loop, so it gets called very often.

Don't go blaming a library for something dumb you are doing.

whos blaming? it was a question.. and learning is now DUMB?

why is it you make every post about things other than help? and more focused on being snarky and 'cool'.. :roll_eyes:
and in good old fashioned 'PaulS' style.. you would focus on something like this... instead of offering help on other aspects.

I felt I followed the 'rules' I gave background info.. I explained.. I 'tried' to do it myself.. posted 'code' for review... but I feel there is a better way to do the counting/checking for only 60 leds.

@ PaulS -feel free to just skip over my posts, your brand of 'help' isnt something I respond to, nor is it what Im looking for on this ''help forum" ...your just never happy or focused on providing 'help'...thanks

anyways...

maybe 'as well as' would have been more accurate... I dont think 'this':

unsigned long delaytime=5;
delay(delaytime);

was very long at all... and felt the reaction/re-activeness of the leds should have reflected faster?

again any advice on going about counting to the '60' vs the '64' leds...

thanks

XL97,
You are going thru each individual LED to set them to something?
I think I would make an array of 8 bytes, each byte representing 1 register that you actually write to the MAX7221.

7221registers[ ] = {put the 8 register addresses here};
7221array[ ] = {0,0,0,0,0,0,0,0};  // initialize the array
void setup(){
SPI.begin;
}
void loop(){
digitalWrite (SS,LOW);
for (x=0; x<8; x=x+1){
SPI.transfer (7221register[x]);
SPI.transfer (7221array[x]);
}
digitalWrite (SS,  HIGH);
//
// now have your code that reads buttons, makes decisions, updates the array as needed.
// the max7221 takes care of multiplexing the data you just gave it across the LEDs
// as you do other stuff
}

Hi CrossRoads-

thanks for the reply.

ok so you are suggesting to NOT use the LedControl lib any more.. and use SPI? (which I have never done before?)
(maybe I should look for a primer/tutorial on that before hand?) :wink:

yes.. I am trying to go from led_0 to led_59..turn each on 'on' (consecutively).. then go backwards... (led_59 to led_0)

:slight_smile:

there seems to be a hiccup or 'freeze' when it boots up/first plays.... then eventually gets to the 'cycle'..

Im sure there is a better way for this..

** in your sample code you provided..

you say this: "put the 8 register addresses here"

what are the 'registers' you are referring to?

Im also a bit unclear as to where "SS" is ever declared/defined for any of the digitalWrites()?

sorry.. still taking it all in. :slight_smile: hahah..

not sure if Im ready to jump to SPI communication approach without some guidance...

thanks!

XL97,
SPI is easy to use.
Yeah, I didn't show the SS pin being declared, you were able to figure that out.
Take a look at this schematic - there are 8 headers going to 8 groups of LEDs. Each group has 9 wires - the 8 anodes (which are connected to all other anodes as well) and the common cathode, one for each group.
Take the array method I wrote above and make it go thru a register, then the next register, etc.
The register address are the SPI addresses for the MAX7221 that are defined in the data sheet:

// addresses for the MAX7221, and the values/ranges to write in

#define DECODE_MODE 0x09 // write data 0xFF, Code B Decode for all digits << You will set this for No Decode mode instead
#define INTENSITY_ADDRESS 0x0A // 0x07 to start, half intensity. valid from 0x00 (min) to 0x0F (max)
#define SCANLIMIT_ADDRESS 0x0B // 0xFF, all 8 digits on
#define SHUTDOWN_ADDRESS 0x0C // 0x01, normal operation (0x01 = shutdown) - powers up in shutdown mode

#define DISPLAYTEST_ADDRESS 0x0F // 0x01 = all lights on full, 0x00 = normal ops
#define register1 0x01 // digit 0
#define register2 0x02 // digit 1
#define register3 0x03 // digit 2
#define register4 0x04 // digit 3
#define register5 0x05 // digit 4
#define register6 0x06 // digit 5
#define register7 0x07 // digit 6
#define register8 0x08 // digit 7

The MAX7221 is not hard to use, read its datasheet and write the commands you want.

WHOA!..

haha.. thanks for the reply.. but its still a bit over my head..

Im not sure its just the basics/foundation I am missing? but Im still having this disconnect, putting the pieces together..

without specifics from you code..

just the general idea perhaps the SPI communication? or maybe its just how this chip works specifically? (I think my RFID reader/writer is similar..which is why i was thinking it was SPI protocol I am not understanding)

Im not new to programing "principles" in general..but not with hardware/embedded electronics.. more web related stuff.

its all these: 0x01 all over.. (kind of overwhelming at first)..

these are hex values? (addresses) for the MAX chip...

and in the last post.. you are defining 'terms' to be used as shortcuts to certain addresses.. correct so far? (I dont want to loosely say variable..as you used the #define command and I go tin trouble for that mis-terminology before) :wink:

Some of your comments after the lines are confusing though?
#define DECODE_MODE 0x09

this line..

defines the label DECODE_MODE to be/mean 0x09 everytime its used in the code.. correct?

// write data 0xFF, Code B Decode for all digits << You will set this for No Decode mode instead

this I dont understand though?

the rest you are doing the same..

#define INTENSITY_ADDRESS 0x0A // 0x07 to start, half intensity. valid from 0x00 (min) to 0x0F (max)
#define SCANLIMIT_ADDRESS 0x0B // 0xFF, all 8 digits on
#define SHUTDOWN_ADDRESS 0x0C // 0x01, normal operation (0x01 = shutdown) - powers up in shutdown mode

in some of the comments you just noting the RANGES of VALUEs that can be used for that 'variable/defined' term...

example:
#define INTENSITY_ADDRESS 0x0A
// 0x07 to start, half intensity. valid from 0x00 (min) to 0x0F (max)

all these 'defines' still need to have values assigned to them though..or maybe more accurately put.. they need data still written to them..yes?

So would I do this in the set up function?.. or am I totally wrong in this thinking.. and when the #defines above are not addresses for quick reference..but actual assignment of data??

Also I didnt see any importing of the SPI lib? (or any others) was this just assumed? and I was supposed to know? or? should be included? (sorry.. partial code snippets lead to confusion for newbies! :slight_smile: )

I'll try to give 'SPI' a chance as you say...but I need a bit of help I guess.. =)

an overview perhaps of how this hex address/data relationship and sending it all over..etc work..

not even trying to turn on an LED yet.. trying to set those defaults of the chip firs.t. (1 step at a time)

thanks

//Pin Out:
/*
 -pin 12 is connected to the DataIn (MAX pin:1)
 -pin 11 is connected to the CLK  (MAX pin:13)
 -pin 10 is connected to LOAD/CS/SS  (MAX pin:12)
 */

#include <SPI.h>

#define DECODE_MODE 0x09 // write data 0xFF, Code B Decode for all digits  <<  You will set this for No Decode mode instead
#define INTENSITY_ADDRESS 0x0A // 0x07 to start, half intensity. valid from 0x00 (min) to 0x0F (max)
#define SCANLIMIT_ADDRESS 0x0B // 0xFF, all 8 digits on
#define SHUTDOWN_ADDRESS 0x0C  // 0x01, normal operation (0x01 = shutdown) - powers up in shutdown mode

void setup() {
  Serial.begin(9600);
  Serial.println("--SET UP CHIP--");
  digitalWrite (10,LOW);
  SPI.transfer (INTENSITY_ADDRESS, 0x07);
  digitalWrite (10,  HIGH);

}

void loop() { 
  //do whatever
}

I know that is wrong syntax.. as I just saw the transfer() method only accepts 1 parameter (val)..

also looking at the SPI examples.. I dont see any assignment of these #defines.. so Im assuming Im wrong on the whole thing? haha

0x0A is hexadecimal 0A = B00001010 = Decimal 10

"its all these: 0x01 all over.. (kind of overwhelming at first)..

these are hex values? (addresses) for the MAX chip..."
Yes they are, I recommend you look at the datasheet, their usage will become clear then.

#define INTENSITY_ADDRESS 0x0A
// #define assigns the value of 0x0A to the variablle INTENSITY_ADDRESS, and the code cannot change change it later.
// I used 0x0A as that is how the datashet uses them, makes for less mistakes
// anything after the slashes are comments, even when on the same line

I don't think you have these correct:
/*
-pin 12 is connected to the DataIn (MAX pin:1)
-pin 11 is connected to the CLK (MAX pin:13)
-pin 10 is connected to LOAD/CS/SS (MAX pin:12)
*/
Arduino D13 is SCK, this is the clock line -> to MAX7221 pin 13
Arduino D11 is the MOSI line (master out slave in), this the serial data out line -> to MAX7221 pin 1
Arduino D10 is the SS line -> to MAX7221 pin 12
(you can assign other Arduino pins as SS also - but D11-D12-D13 are SPI hardware pins)

Need changes in this section:

#include <SPI.h>  // In the IDE, select Sketch:Import Library:SPI it will add this to the top of sketch
// define the variables, #defines here, etc.

void setup() {
  Serial.begin(9600);
pinMode (10, OUTPUT);  // need this, I would do it as #define SS 10, and then just use SS tho
SPI.begin(); // starts the SPI library

  Serial.println("--SET UP CHIP--");
  digitalWrite (10,LOW);
  SPI.transfer (INTENSITY_ADDRESS);  // you are correct 1 byte per transer
  SPI.transfer ( 0x07);                         // for these lines
  digitalWrite (10,  HIGH);
}

thanks for reply..

I have been 'looking' at the datasheet.. but it has really 'clicked' yet..

sorry the pinout stuff was copy/pasted from my other attempt that uses the LedControl library and follows the pinout of these tutorials:

http://arduino.cc/playground/Main/MAX72XXHardware
&
http://arduino.cc/playground/Main/LedControl

I guess the wiring is different when wanting to use the SPI protocol?

I changed things out.. and tried to run this code.. it compiles.. ut does nothing..

(I am expecting a jerky fade in led intensity/brightness)

#include <SPI.h>  

/*
 pin D13 is connected to the DataIn (MAX7221 pin:1)
 pin D11 is connected to the CLK (MAX7221 pin:13)
 pin D10 is connected to LOAD (MAX7221 pin:12)
 */

// define the variables, #defines here, etc.
#define DECODE_MODE 0x09 // write data 0xFF, Code B Decode for all digits  <<  You will set this for No Decode mode instead
#define INTENSITY_ADDRESS 0x0A // 0x07 to start, half intensity. valid from 0x00 (min) to 0x0F (max)
#define SCANLIMIT_ADDRESS 0x0B // 0xFF, all 8 digits on
#define SHUTDOWN_ADDRESS 0x0C  // 0x01, normal operation (0x01 = shutdown) - powers up in shutdown mode

#define DISPLAYTEST_ADDRESS 0x0F // 0x01 = all lights on full, 0x00 = normal ops
#define register1 0x01 // digit 0
#define register2 0x02 // digit 1
#define  register3 0x03 // digit 2
#define register4 0x04 // digit 3
#define register5 0x05 // digit 4
#define register6 0x06 // digit 5
#define register7 0x07 // digit 6
#define register8 0x08 // digit 7

void setup() {
  Serial.begin(9600);
  Serial.println("--SET UP CHIP--");
  pinMode (10, OUTPUT);  // need this, I would do it as #define SS 10, and then just use SS tho
  SPI.begin(); // starts the SPI library  
  digitalWrite (10,LOW);
  SPI.transfer (INTENSITY_ADDRESS);  // you are correct 1 byte per transer
  SPI.transfer (0x07);                         // for these lines
  digitalWrite (10,  HIGH);
}

void loop() { 
  digitalWrite (10,LOW);
  SPI.transfer (INTENSITY_ADDRESS);  // you are correct 1 byte per transer
  SPI.transfer (0x07);                         // for these lines
  digitalWrite (10,  HIGH);

  delay(500);

  digitalWrite (10,LOW);
  SPI.transfer (INTENSITY_ADDRESS);  // you are correct 1 byte per transer
  SPI.transfer (0x08);                         // for these lines
  digitalWrite (10,  HIGH);


  delay(500);

  digitalWrite (10,LOW);
  SPI.transfer (INTENSITY_ADDRESS);  // you are correct 1 byte per transer
  SPI.transfer (0x09);                         // for these lines
  digitalWrite (10,  HIGH);


  delay(500);

  digitalWrite (10,LOW);
  SPI.transfer (INTENSITY_ADDRESS);  // you are correct 1 byte per transer
  SPI.transfer (0x0A);                         // for these lines
  digitalWrite (10,  HIGH);


  delay(500);

  digitalWrite (10,LOW);
  SPI.transfer (INTENSITY_ADDRESS);  // you are correct 1 byte per transer
  SPI.transfer (0x0B);                         // for these lines
  digitalWrite (10,  HIGH);


  delay(500);

  digitalWrite (10,LOW);
  SPI.transfer (INTENSITY_ADDRESS);  // you are correct 1 byte per transer
  SPI.transfer (0x0C);                         // for these lines
  digitalWrite (10,  HIGH);

  delay(500);
}

I have also updated the wiring as you suggested..

Yes, the wiring is different to use the ATMega SPI hardware.

What you haven't done is set up any of the registers:

digitalWrite (10,LOW);
SPI.transfer (insert_register_name_ADDRESS); //
SPI.transfer (0x0C); // and value
digitalWrite (10, HIGH);

for these registers:
DECODE_MODE 0x09 // write data 0xFF, Code B Decode for all digits << You will set this for No Decode mode instead - FIND VALUE IN THE DATASHEET
INTENSITY_ADDRESS 0x0A // 0x07 to start, half intensity. valid from 0x00 (min) to 0x0F (max)
SCANLIMIT_ADDRESS 0x0B // 0xFF, all 8 digits on
SHUTDOWN_ADDRESS 0x0C // 0x01, normal operation (0x01 = shutdown) - powers up in shutdown mode
DISPLAYTEST_ADDRESS 0x0F // 0x01 = all lights on full, 0x00 = normal ops

and then write the data you actually want to appear in these registers, which controls what appears at the LEDs (outside of writing a 1 to DISPLAYTEST_ADDRESS which turns them all on for a test):

register1 0x01 // digit 0
register2 0x02 // digit 1
register3 0x03 // digit 2
register4 0x04 // digit 3
register5 0x05 // digit 4
register6 0x06 // digit 5
register7 0x07 // digit 6
register8 0x08 // digit 7

So put the register in an array so you can reference them, and make an array to hold your display pattern

byte register [ ] = {0,1,2,3,4,5,6,7};
byte registerdata [ ] = {B00000001,B00000010, B00000100, B00001000, B00010000, B00100000, B01000000, B10000000}; // initialize with some data

Next, have a group of these in void setup to set up the control registers - each register!

digitalWrite (10,LOW);
SPI.transfer (insert_register_name_ADDRESS); //
SPI.transfer (0x0C); // and value
digitalWrite (10, HIGH);

and in void loop, write the data from an array that contains the LED pattern you want to see:

void loop(){
if (display_update == 1){ //see if "decision code" has made changes to the array
// clear flag for next pass
display_update = 0;
// now do the transfers to update the '7221 registers
for (x=0, x<8; x=x+1){
digitalWrite (10,LOW);
SPI.transfer (register[x]); // register to write to
SPI.transfer (registerdata[x]); // and value
digitalWrite (10, HIGH);
}
// "decision code"
// change registerdata[ ] based on elapsed time, buttons pressed, predefined sequence, whatever
:
:
// when all done set the update flag:
display_update = 1;
}

DOH!.. I realized I hadnt defined some of those parameters for the chip.. when thinking back on some of the initial steps I had taken when using the LedControl lib.

anyways... few thoughts..

Im very happy to be learning how to use SPI.. as Im sure I'll need to be using it more and more..especially with the board I am working on.. (DAC, uSD, these MAX chips..etc).. so I'll also need to learn now to put multiple devices on the same SPI bus/chain.. although I think I read was setting the hardware SS pin to output before any assignment of SPI pin to other devices..etc... anyways.. Im far from that point still.

I think this way (although I believe the LedControl lib also has a binary approach method available for use as well).. will help with patterns..etc..

however Im a bit confused if this really answers the purpose of the original/initial post? looping through 60 leds..instead of the [8x8] 64 leds that normally are used in this type of set-up?

I had things wired up correctly (for the LedControl lib).. and it worked..but was a bit clunky....

Id imaging.. just because Im using SPI ...I'll still run into the same flawed logic I originally used to make a 'loop/run/cycle' of only the 60 leds..etc vs using 64 leds..etc....

anyways.. back to SPI.. and your code samples.. (trying to learn as this is opening up my eyes on how the SPI RFID stuff I have works too)..

ok..

code:

#include <SPI.h>  

//-----[this is SPI hardware wiring pinout only]-----//
/* 
 Arduino pin D13 is connected to the DataIn (MAX7221 pin:13)
 Arduino pin D11 is connected to the CLK (MAX7221 pin:1)
 Arduino pin D10 is connected to LOAD (MAX7221 pin:12)
 */

// define MAX72xx default register addresses
#define DECODE_MODE 0x09 // Code B Decode Digits 0-7: 0xFF / No-Decode Mode: 0x00
#define INTENSITY_ADDRESS 0x0A // 0x07 to start, half intensity. valid from 0x00 (min) to 0x0F (max)
#define SCANLIMIT_ADDRESS 0x0B // All 8 digits on = 0xFF?? FF? Datasheet says 0x07?
#define SHUTDOWN_ADDRESS 0x0C  // Normal operation = 0x01 / Shutdown = 0x00 (powers up in shutdown mode)
#define DISPLAYTEST_ADDRESS 0x0F // 0x01 = all lights on full, 0x00 = normal ops

//---[define register addresses ['register/digit x' represent 1 section/grouping of 8 leds]---//
#define register1 0x01 // digit 0
#define register2 0x02 // digit 1
#define register3 0x03 // digit 2
#define register4 0x04 // digit 3
#define register5 0x05 // digit 4
#define register6 0x06 // digit 5
#define register7 0x07 // digit 6
#define register8 0x08 // digit 7

//--[define the SS pin]--//
#define SS 10 //hardware slave select pin on Arduino Due.

// create array to hold the register addresses
byte registerAddress[] = {
  0,1,2,3,4,5,6,7};
//byte registerAddress [] = {register0,register1,register2,register3,register4,register5,register6,register7};

// initialize array with some data/pattern
byte registerData[] = {
  B00000001,B00000010, B00000100, B00001000, B00010000, B00100000, B01000000, B10000000}; 

void setup() {
  Serial.begin(9600);
  Serial.println("--SET UP CHIP--");
  //define 'SS' pin as output (needed for SPI....even if other devices use other pins as their SS/CS pins...correct?
  pinMode (SS, OUTPUT);
  // startthe SPI library
  SPI.begin();   
  // bring 'SS' pin low
  digitalWrite (SS,LOW);

  //transfer SPI data to chip/device
  SPI.transfer (DECODE_MODE);  
  SPI.transfer (0x00);  // 0x00 - no-decode mode
  SPI.transfer (INTENSITY_ADDRESS);  
  SPI.transfer (0x0F);  // 0x0F - max on/brightness
  SPI.transfer (SCANLIMIT_ADDRESS);  
  SPI.transfer (0x07);  // 0xFF or 0x07? 0x07 - all display digits on
  SPI.transfer (SHUTDOWN_ADDRESS);  
  SPI.transfer (0x01);  // 0x01 - normal operation mode
  SPI.transfer(DISPLAYTEST_ADDRESS);
  SPI.transfer(0x00);  // 0x00 - normal operation mode

  //bring 'SS' pin high
  digitalWrite (SS,  HIGH);
}

void loop() { 
  for (int x = 0; x < 8; x++){
    digitalWrite (SS,LOW);
    SPI.transfer (registerAddress[x]);  // register to write to
    SPI.transfer (registerData[x]);  // and value 
    digitalWrite (SS,  HIGH);
  }
}

I had a few problems..errors.. I had to work through..not sure if intended or not.

1.) SCANLIMIT_ADDRESS value? you had 0xFF or something? but data sheet says 0x07? (but what do I know?) ol

2.) leaving this: byte register[] as it was.. threw an error?? (seemed to be a reserved/key word?), so ity was changed to be this: byte registerAddress[]

3.) that then threw an error further down..SPI.transfer (registerAddress); // register to write to..
saying there was a byte to byte conversion error..etc..etc... I figured you maybe were trying to pass the whole array.. but just an index of it?.. so I updated both lines to grab an array value: SPI.transfer (registerAddress[x]); // register to write to

I have no clue if this was right or wrong though... (it compiles.. but does nothing)..

Im confused as to what this 'register' array does?
seems to just be an array of consecutive numbers?

I thought perhaps the register1, register2 names should go in there instead (as indexes/references to the addresses?)

like so:

// create array to hold the register addresses
byte registerAddress[] = {
0,1,2,3,4,5,6,7};
//byte registerAddress [] = {register0,register1,register2,register3,register4,register5,register6,register7};

but that threw an error too...saying they were declared/defined in this scope..or something..etc..

Also.. can I do a 'mass' write liek that for the? (bringing the pin LOW.... do multiple SPI.transfer() calls... then bring pin HIGH again? or should it be done after each SPI.transfer()?

thanks

double post.. :slight_smile:

here is the current/latest version of the code...

however.. when I try to print out the values for register data & register address... I get nothing:

not sure if Im doing something wrong? or if tis is NOT how you pull data form an array in C/Arduino?

#include <SPI.h>  

//-----[this is SPI hardware wiring pinout only]-----//
/* 
 Arduino pin D13 is connected to the DataIn (MAX7221 pin:13)
 Arduino pin D11 is connected to the CLK (MAX7221 pin:1)
 Arduino pin D10 is connected to LOAD (MAX7221 pin:12)
 */

// define MAX72xx default register addresses
#define DECODE_MODE 0x09 // Code B Decode Digits 0-7: 0xFF / No-Decode Mode: 0x00
#define INTENSITY_ADDRESS 0x0A // 0x07 to start, half intensity. valid from 0x00 (min) to 0x0F (max)
#define SCANLIMIT_ADDRESS 0x0B // All 8 digits on = 0xFF?? FF? Datasheet says 0x07?
#define SHUTDOWN_ADDRESS 0x0C  // Normal operation = 0x01 / Shutdown = 0x00 (powers up in shutdown mode)
#define DISPLAYTEST_ADDRESS 0x0F // 0x01 = all lights on full, 0x00 = normal ops

//---[define register addresses ['register/digit x' represent 1 section/grouping of 8 leds]---//
#define register1 0x01 // digit 0
#define register2 0x02 // digit 1
#define register3 0x03 // digit 2
#define register4 0x04 // digit 3
#define register5 0x05 // digit 4
#define register6 0x06 // digit 5
#define register7 0x07 // digit 6
#define register8 0x08 // digit 7

//--[define the SS pin]--//
#define SS 10 //hardware slave select pin on Arduino Due.

// create array to hold the register addresses
//byte registerAddress[] = {0,1,2,3,4,5,6,7};
byte registerAddress[] = {register1, register2, register3, register4, register5, register6, register7, register8};

// initialize array with some data/pattern
byte registerData[] = {B00000001, B00000010, B00000100, B00001000, B00010000, B00100000, B01000000, B10000000}; 

void setup() {
  Serial.begin(9600);
  Serial.println("--SET UP CHIP--");
  //define 'SS' pin as output (needed for SPI....even if other devices use other pins as their SS/CS pins...correct?
  pinMode (SS, OUTPUT);
  // startthe SPI library
  SPI.begin();   
  // bring 'SS' pin low
  digitalWrite (SS,LOW);

  //transfer SPI data to chip/device
  SPI.transfer (DECODE_MODE);  
  SPI.transfer (0x00);  // 0x00 - no-decode mode
  SPI.transfer (INTENSITY_ADDRESS);  
  SPI.transfer (0x0F);  // 0x0F - max on/brightness
  SPI.transfer (SCANLIMIT_ADDRESS);  
  SPI.transfer (0x07);  // 0xFF or 0x07? 0x07 - all display digits on
  SPI.transfer (SHUTDOWN_ADDRESS);  
  SPI.transfer (0x01);  // 0x01 - normal operation mode
  SPI.transfer(DISPLAYTEST_ADDRESS);
  SPI.transfer(0x00);  // 0x00 - normal operation mode

  //bring 'SS' pin high
  digitalWrite (SS,  HIGH);
}

void loop() { 
  for (int x = 0; x < 8; x=x+1){
    digitalWrite (SS,LOW);
    Serial.println("");
    Serial.println("REGISTER AADDRESS");
    Serial.println(registerAddress[x]);
    Serial.println("");
    SPI.transfer (registerAddress[x]);  // register to write to
    Serial.println("REGISTER DATA");
    Serial.println(registerData[x]);
    Serial.println("");
    SPI.transfer (registerData[x]);  // and value 
    digitalWrite (SS,  HIGH);
  }
}

Try splitting these up, I don't know if you can do it as 1 burst like that.

  // bring 'SS' pin low
  digitalWrite (SS,LOW);

  //transfer SPI data to chip/device
  SPI.transfer (DECODE_MODE);  
  SPI.transfer (0x00);  // 0x00 - no-decode mode
  digitalWrite (SS,  HIGH);

digitalWrite (SS,LOW);
  SPI.transfer (INTENSITY_ADDRESS);  
  SPI.transfer (0x0F);  // 0x0F - max on/brightness
  digitalWrite (SS,  HIGH);

digitalWrite (SS,LOW);
  SPI.transfer (SCANLIMIT_ADDRESS);  
  SPI.transfer (0x07);  // 0xFF or 0x07? 0x07 - all display digits on
  digitalWrite (SS,  HIGH);

digitalWrite (SS,LOW);
  SPI.transfer (SHUTDOWN_ADDRESS);  
  SPI.transfer (0x01);  // 0x01 - normal operation mode
  digitalWrite (SS,  HIGH);

digitalWrite (SS,LOW);
  SPI.transfer(DISPLAYTEST_ADDRESS);
  SPI.transfer(0x00);  // 0x00 - normal operation mode
  //bring 'SS' pin high
  digitalWrite (SS,  HIGH);
}

and rearrange here to get rid of the delay between address & data

  for (int x = 0; x < 8; x=x+1){
    Serial.println("");
    Serial.println("REGISTER ADDRESS");
    Serial.println(registerAddress[x]);
    Serial.println("");

    Serial.println("REGISTER DATA");
    Serial.println(registerData[x]);
    Serial.println("");

    digitalWrite (SS,LOW);
    SPI.transfer (registerAddress[x]);  // register to write to
    SPI.transfer (registerData[x]);  // and value 
    digitalWrite (SS,  HIGH);
  }

I think the 'grouping' works as it is.. because if I modify DISPLAY_TEST to be 0x01 and all leds come on.

'but'.. I'll re-write as you suggested anyways to be sure. :slight_smile:

secondly.. what delays are you referring to?

the serial print()'s?

update:

this seems to give me some promising/working results..

however... at this point.. while I learned how to use SPI a little bit.. and pass the binary format of the led states per group of 8..etc..

I am still left with the original question that started this thread?

this is NOT a matrix CUBE..
this IS an LED strip/ladder (soldered in matrix wiring to individually control/address the leds)
I do NOT have 64 leds in my led strip.... I only have 60.. so I was looking for a way to control that? better than the original code posted here?

(eventually I will another MAX7221 and another strip of 60 leds.. to make a complete 'circle'. so I'll want to loop and do patterns..etc)..

is there an easy way to increment in binary? or is pre-making my patterns and storing them in an array the best approach?

example:

using the LedControl lib.. I can just set col/row and either tru or false..

easy to increment a var (number) and change either true or false to maybe 'ping/pong' up & down the led strip?

Im not sure how I would do that here? I guess two arrays?

Also.. is there any way to CLEAR the display? I start up.. my leds are on?..a quick clear setting? or do I ned to loop through each group/led to turn it off?

thanks

anyways.. here is my current code:

thanks

#include <SPI.h>  

//-----[this is SPI hardware wiring pinout only]-----//
/* 
 Arduino pin D13 is connected to the DataIn (MAX7221 pin:13)
 Arduino pin D11 is connected to the CLK (MAX7221 pin:1)
 Arduino pin D10 is connected to LOAD (MAX7221 pin:12)
 */

// define MAX72xx default register addresses
#define DECODE_MODE 0x09 // Code B Decode Digits 0-7: 0xFF / No-Decode Mode: 0x00
#define INTENSITY_ADDRESS 0x0A // 0x07 to start, half intensity. valid from 0x00 (min) to 0x0F (max)
#define SCANLIMIT_ADDRESS 0x0B // All 8 digits on = 0xFF?? FF? Datasheet says 0x07?
#define SHUTDOWN_ADDRESS 0x0C  // Normal operation = 0x01 / Shutdown = 0x00 (powers up in shutdown mode)
#define DISPLAYTEST_ADDRESS 0x0F // 0x01 = all lights on full, 0x00 = normal ops

//---[define register addresses ['register/digit x' represent 1 section/grouping of 8 leds]---//
#define register1 0x01 // digit 0
#define register2 0x02 // digit 1
#define register3 0x03 // digit 2
#define register4 0x04 // digit 3
#define register5 0x05 // digit 4
#define register6 0x06 // digit 5
#define register7 0x07 // digit 6
#define register8 0x08 // digit 7

//--[define the SS pin]--//
#define SS 10 //hardware slave select pin on Arduino Due.
//--[deifne custom val]--//
#define totalGroups 8
//--[deifne custom val]--//
#define totalLeds 60

// create array to hold the register addresses
//byte registerAddress[] = {0,1,2,3,4,5,6,7};
byte registerAddress[] = {register1, register2, register3, register4, register5, register6, register7, register8};

// initialize array with some data/pattern
//byte registerData[] = {B10000000,B01000000,B00100000,B00010000,B00001000,B00000100,B00000010,B00000001}; 

//stay on pattern/array
byte registerData[] = {B10000000,B11000000,B11100000,B11110000,B11111000,B11111100,B11111110,B11111111}; 

void setup() {
  Serial.begin(9600);
  Serial.println("--SET UP CHIP--");
  //define 'SS' pin as output (needed for SPI....even if other devices use other pins as their SS/CS pins...correct?
  pinMode (SS, OUTPUT);
  // start the SPI library
  SPI.begin(); 

  //set MAX7221 defaults
  digitalWrite (SS, LOW);
  SPI.transfer (DECODE_MODE);  
  SPI.transfer (0x00);  // 0x00 - no-decode mode
  digitalWrite (SS, HIGH);

  digitalWrite (SS, LOW);
  SPI.transfer (INTENSITY_ADDRESS);  
  SPI.transfer (0x0F);  // 0x0F - max on/brightness
  digitalWrite (SS, HIGH);

  digitalWrite (SS, LOW);
  SPI.transfer (SCANLIMIT_ADDRESS);  
  SPI.transfer (0x07);  // 0xFF or 0x07? 0x07 - all display digits on
  digitalWrite (SS, HIGH);

  digitalWrite (SS, LOW);
  SPI.transfer (SHUTDOWN_ADDRESS);  
  SPI.transfer (0x01);  // 0x01 - normal operation mode
  digitalWrite (SS, HIGH);

  digitalWrite (SS, LOW);
  SPI.transfer(DISPLAYTEST_ADDRESS);
  SPI.transfer(0x00);  // 0x00 - normal operation mode
  digitalWrite (SS, HIGH);
  
  //clear display
  for(int group=0; group<totalGroups; group++){    
      digitalWrite (SS,LOW);
      SPI.transfer (registerAddress[group]);  // register to write to
      SPI.transfer (B00000000);  // and value       
      digitalWrite (SS,HIGH);
  }

}

void loop() {   
  //clear display
  for(int group=0; group<totalGroups; group++){    
      digitalWrite (SS,LOW);
      SPI.transfer (registerAddress[group]);  // register to write to
      SPI.transfer (B00000000);  // and value       
      digitalWrite (SS,HIGH);
  }
  
  for(int group=0; group<totalGroups; group++){
    for(int led=0; led<8; led++){
      digitalWrite (SS,LOW);
      SPI.transfer (registerAddress[group]);  // register to write to
      SPI.transfer (registerData[led]);  // and value       
      digitalWrite (SS,HIGH);
      //Serial.println(registerData[led]);
      delay(5);
    }
  }




}

next iteration:

seems to light up correctly...incrementally...etc..

but I cant seem to trigger it to go back down correctly?

#include <SPI.h>  

//-----[this is SPI hardware wiring pinout only]-----//
/* 
 Arduino pin D13 is connected to the DataIn (MAX7221 pin:13)
 Arduino pin D11 is connected to the CLK (MAX7221 pin:1)
 Arduino pin D10 is connected to LOAD (MAX7221 pin:12)
 */

// define MAX72xx default register addresses
#define DECODE_MODE 0x09 // Code B Decode Digits 0-7: 0xFF / No-Decode Mode: 0x00
#define INTENSITY_ADDRESS 0x0A // 0x07 to start, half intensity. valid from 0x00 (min) to 0x0F (max)
#define SCANLIMIT_ADDRESS 0x0B // All 8 digits on = 0xFF?? FF? Datasheet says 0x07?
#define SHUTDOWN_ADDRESS 0x0C  // Normal operation = 0x01 / Shutdown = 0x00 (powers up in shutdown mode)
#define DISPLAYTEST_ADDRESS 0x0F // 0x01 = all lights on full, 0x00 = normal ops

//---[define register addresses ['register/digit x' represent 1 section/grouping of 8 leds]---//
#define register1 0x01 // digit 0
#define register2 0x02 // digit 1
#define register3 0x03 // digit 2
#define register4 0x04 // digit 3
#define register5 0x05 // digit 4
#define register6 0x06 // digit 5
#define register7 0x07 // digit 6
#define register8 0x08 // digit 7

//--[define the SS pin]--//
#define SS 10 //hardware slave select pin on Arduino Due.
//--[deifne custom val]--//
#define totalGroups 8
//--[deifne custom val]--//
#define totalLeds 60


//create var to hold delay tim
int pause = 35;
//create var to hold current led count
int ledCounter = 0;

// create array to hold the register addresses
//byte registerAddress[] = {0,1,2,3,4,5,6,7};
byte registerAddress[] = {
  register1, register2, register3, register4, register5, register6, register7, register8};

// initialize array with some data/pattern
//1 on at a time
//byte registerData[] = {B10000000,B01000000,B00100000,B00010000,B00001000,B00000100,B00000010,B00000001}; 
//incrmentally on, 1, then 2, then 3...all staying light after
byte registerData[] = {B10000000,B11000000,B11100000,B11110000,B11111000,B11111100,B11111110,B11111111}; 

//stay on pattern/array
byte ledIn[] = {B10000000,B11000000,B11100000,B11110000,B11111000,B11111100,B11111110,B11111111}; 
byte ledOut[] = {B11111110, B11111100, B11111000, B11110000, B11100000, B11000000, B10000000, B00000000}; 
//byte ledOut[] = {B00000001, B00000010, B00000100, B00001000, B00010000, B00100000, B01000000, B10000000}; 

void setup() {
  Serial.begin(9600);
  Serial.println("--SET UP CHIP--");
  //define 'SS' pin as output (needed for SPI....even if other devices use other pins as their SS/CS pins...correct?
  pinMode (SS, OUTPUT);
  // start the SPI library
  SPI.begin(); 

  //set MAX7221 defaults
  digitalWrite (SS, LOW);
  SPI.transfer (DECODE_MODE);  
  SPI.transfer (0x00);  // 0x00 - no-decode mode
  digitalWrite (SS, HIGH);

  digitalWrite (SS, LOW);
  SPI.transfer (INTENSITY_ADDRESS);  
  SPI.transfer (0x0F);  // 0x0F - max on/brightness
  digitalWrite (SS, HIGH);

  digitalWrite (SS, LOW);
  SPI.transfer (SCANLIMIT_ADDRESS);  
  SPI.transfer (0x07);  // 0xFF or 0x07? 0x07 - all display digits on
  digitalWrite (SS, HIGH);

  digitalWrite (SS, LOW);
  SPI.transfer (SHUTDOWN_ADDRESS);  
  SPI.transfer (0x01);  // 0x01 - normal operation mode
  digitalWrite (SS, HIGH);

  digitalWrite (SS, LOW);
  SPI.transfer(DISPLAYTEST_ADDRESS);
  SPI.transfer(0x00);  // 0x00 - normal operation mode
  digitalWrite (SS, HIGH);

  //clear display
  for(int group=0; group<totalGroups; group++){    
    digitalWrite (SS,LOW);
    SPI.transfer (registerAddress[group]);  // register to write to
    SPI.transfer (B00000000);  // and value       
    digitalWrite (SS,HIGH);      
  }

}

void loop() {   
  //clear display
  //for(int group=0; group<totalGroups; group++){    
  //digitalWrite (SS,LOW);
  //SPI.transfer (registerAddress[group]);  // register to write to
  //SPI.transfer (B00000000);  // and value       
  //digitalWrite (SS,HIGH);
  //}

  for(int group=0; group<totalGroups; group++){
    for(int led=0; led<8; led++){
      digitalWrite (SS,LOW);
      SPI.transfer (registerAddress[group]);  // register to write to
      SPI.transfer (ledIn[led]);  // and value       
      digitalWrite (SS,HIGH);
      delay(pause);
      ledCounter++;
      if(ledCounter >= 60){
        //count backwards
        for(int group2=totalGroups; group2>0; group2--){
          for(int led2=0; led2<8; led2++){
            digitalWrite (SS,LOW);
            SPI.transfer (registerAddress[group2-1]);  // register to write to
            SPI.transfer (ledOut[led2]);  // and value       
            digitalWrite (SS,HIGH);
            delay(pause);
            ledCounter--;
          }
        }
      }

    }
  }
}

(sorta of the same problem I had which started this thread!?? hahaha..

seems to be a bug in the COUNT down...

any ideas?

thanks

xl97,
What you had is looking good.
You could this
for(int led=0; led<8; led++){
to this
for (byte led 1; led != 0; led = led<<1){
so starts with B00000001, and shifts the 1 across until it gets shifted out of the upper end.

I realize you have a matrix, not a cube. THe '7221 controls a matrix.
Each register represents one row (or column, depending how you look at it) of that matrix.
The MAX7221 cycles thru all the registers are quite fast pace (~800 Hz refresh rate per the datasheet).

So you update the array, send it to the MAX7221.
Can send all bytes every time, or just the 1 register that changed.

Just make sure your matrix is wired up like this, even tho you may physically have it spread out to look like a long strip.

nice.. thanks for the shift bit code/example..

I do have it set-up and wired that way..

but there is still a bug 'somewhere'.. and thats in the reverse part of it..

I start.. I light led_0 in group_0.. then led_0 & led_1 in group_0.. then led_0, led_1, led_2 in group_0....etc..etc.

until I get to led_3 in group_7.. (which is a total of 60 leds..not 64)...

so I need a way to 'check/stop' at 60 leds (count 59)... and then start to reverse.. starting at led_59 and turning one off consecutively..

the code I posted has a bug/error..

when I get to the led_0 the last 4 leds (led_55-59) all go on?...

then I start lighting up leds from the beginning again..

I cant seem to put my finger on the bug or what would be doing this?

thanks again for being patient and guiding me through how to use SPI for my first time.. I needed it. :slight_smile:
Im also hoping some of what I learned will apply to working on that RFID card reader/writer hardware I got..

anyways..

Id like to focus on the logic for lighting up each led consecutively, and then back down... this is outside of any SPI protocol logic.. and is just plain for() loop and if() conditional checking..right?

"just plain for() loop and if() conditional checking..right?"

Pretty much.

//going up:

for (group = 0; group <7; group = group+1){   // first 7 rows
  for (byte led 1; led  != 0; led = led<<1){
      digitalWrite (SS,LOW);
      SPI.transfer (registerAddress[group]);  // register to write to
      SPI.transfer (ledIn[led]);  // and value       
      digitalWrite (SS,HIGH);
      delay(pause);
}
}
group = 7;  // 8th row
  for (byte led = walking 1 as above){  0000001 to 00001000, 4 LEDs only
      digitalWrite (SS,LOW);
      SPI.transfer (registerAddress[group]);  // register to write to
      SPI.transfer (ledIn[led]);  // and value       
      digitalWrite (SS,HIGH);
      delay(pause);
}
// now backwards, starting with 8th row
  for (byte led = B00001000; led = 0; led=led>>1){ // walk the other way until clear
      digitalWrite (SS,LOW);
      SPI.transfer (registerAddress[group]);  // register to write to
      SPI.transfer (ledIn[led]);  // and value       
      digitalWrite (SS,HIGH);
      delay(pause);
}
for (group = 6; group = 0; group = group -1){
  for (byte led = B10000000; led = 0; led=led>>1){ // walk the other way until clear
      digitalWrite (SS,LOW);
      SPI.transfer (registerAddress[group]);  // register to write to
      SPI.transfer (ledIn[led]);  // and value       
      digitalWrite (SS,HIGH);
      delay(pause);
}
}

(I thought I had replied to this post this morning already??) :frowning:

Thanks!.. appreciate the example of 'walking' through the shift approach...
I see you just broke up the last group (which only has 4 leds in it) in its own 'function/snippet'...

is that the best approach?

can I ask what my code had wrong with that approach/code? I cant seem to find the error? on why it had that 'bug' at the end of the count down......

Just curious to learn from it.

Once I get this down comfortably.... I need to move into 'functionalizing' (<--- is that even a word? haha).. these different 'effects/patterns' into its own function... and being able to switch form pattern/function to pattern/function by button press..etc..

so I make it the led strip (cirlce)... light up at once... stepping, consecutively in lighting each led... chaser/larson effect..
starting at the middle, and lighting up to both ends..etc..

Im trying to get things working here.. but either my attempts at hybrid code (yours and mine) dont work right.....or even just trying your alone throws errors all over.