Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Controlling more than 1 Max7219 (goal is 6)


Best Answer vader7071 , 23 January 2014 - 03:20 PM

Ok, here is a copy of the files I am using in a txt format.   First off.  Thank you to Paul Newton on the forum and to Paul from Baltimore Hackerspace.  (Yeah, I thought the same thing until I realized P. Newton is from the UK).  These 2 gentlemen have been so patient helping me solve this problem and have taught me so much.   Now, onto the solution.  I realize this in not the "end all be all" solution.  There are probably more ways to do this, and I am sure I will learn them in time, but this is what I have now.   Finding code to control 1 Max7219 was fairly easy.  I did notice a common thread though.  Most every successful max7219 program had an external file called max7219.cs (or some variant there of).  This external file setup the chip and setup the spi configuration.  But we are not talking about 1 chip here, we want more.   So with the help of the Pauls, here is what I have.   Setup.  I am running multiple max7219 chips to an 8x8 led grid.  Here is what I am using.   program.cs is the guts.  This is where you make the display you want.  max7219.cs is the chip driver.  Without this file, it won't work.   Notes in max719.cs first.  To run multiple chips, there is a section titled "maxDouble".  Looks like:  

// Sends 1 Command / Data pair to two driver chips   public void maxDouble(byte reg1, byte col1, byte reg2, byte col2)      {         // LOAD low         loadPin.Write(false);          // Transmit Register 1         putByte(reg1);         // Transmit Column 1         putByte(col1);         // Transmit Register 2         putByte(reg2);         // Transmit Column 2         putByte(col2);          // LOAD high latches data sent         loadPin.Write(true);      }
You have to have a reg and a col per chip.  So, if you wanted to run 5 chips, there would be a reg1, reg 2, reg 3, reg 4, reg 5 plus the additional lines below making reg 1-5.  Same for col.  This is the first part of controlling multiple chips with different data on each.   Ok, we have made the changes to max7219.cs, now on to program.cs. In program.cs we have 2 areas to look at.  First is near the bottom and says:  
for (v = 0; v < animations[animation_num][0].Length; v++)   {      driver.maxDouble         (            (byte)((v % 8) + 1), animations[animation_num][1][v], //chip 2 (end of line)            (byte)((v % 8) + 1), animations[animation_num][0][v]  //chip 1 (closest to Netduino)         );      Thread.Sleep(10);  // delay set to write next column   }
This is setup for 2 chips.  If we go to the 5 discussed earlier, you will modify it to the following:  
for (v = 0; v < animations[animation_num][0].Length; v++)   {      driver.maxDouble      (         (byte)((v % 8) + 1), animations[animation_num][4][v], //chip 5 (end of line)         (byte)((v % 8) + 1), animations[animation_num][3][v], //chip 4         (byte)((v % 8) + 1), animations[animation_num][2][v], //chip 3         (byte)((v % 8) + 1), animations[animation_num][1][v], //chip 2         (byte)((v % 8) + 1), animations[animation_num][0][v]  //chip 1      );      Thread.Sleep(10);  // delay set to write next column   }
  (notice the change in count from 4 to 0?  That is how we are addressing the chips).   This is the only modification to be done in this area.  You only change here if you are wanting to have more than 2 chips from the example supplied.  Notice though that the chips count from the last chip in the line to the closest chip to the Netduino.  That is key and will be referenced below.   the sleep command is what slows the counting process down.  Increase the value, the update time is slower, decrease, the leds move faster.  the time is in milliseconds.   Now that is all the setup.  But we still don't have our "pretty".  Here is the pretty.  Going back up in the code, there is a section that starts:   byte[][][] animations = new byte[][][]   This is where the pretty is stored.  The reason for 3 sets of brackets is to allow for more than one "pretty".  I won't go into too much detail here, but hopefully as I explain what is where you will see what is going on.   The code:  
byte[][][] animations = new byte[][][]   {      //Annimation index 0      new byte[][]      {         //Chip 1 output (closest to Netduino)         new byte[]         {            0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,            0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01         },          //Chip 2 output (end of line)         new byte[]         {            0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,            0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe         }      }   };
  (now this is extremely simplified).   Each row is 8 bytes long.  Each hex value controls one column of lights.  So to control the whole grid, I have to send 8 hex values total.  0x00 = no lights, 0xff = all lights in a column.  the lights count in binary 1 being the highest led and 128 being the lowest led. One comment about this. Both bytes MUST be the same length. If you are showing something on chip 2 but want chip 1 blank, you MUST send 0x00 as long as you are sending something to chip 2. If they are different lengths, it will fault the program.   The attached code currently scrolls "VA" across 2 displays.  I am in the process of expanding it to say "VADER RULES!" but as you can see, that will take time.  I am sure there are better ways to do it, in fact I am almost positive, but I am learning myself, and this is helping me to better understand what is going on.   Upcoming updates for this for my uses, multiple scrolling messages.  I will have "VADER RULES!" and then have it setup to output random values so the leds just flash and then have it set so the random is running and then every so often, "VADER RULES!" scrolls across and back to random flashing. Go to the full post


  • Please log in to reply
31 replies to this topic

#21 vader7071

vader7071

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationDothan, AL

Posted 21 January 2014 - 05:38 PM

Ok, I realize I am blasting here, but reading a bunch and thoughts running through my head.  Sorry.

 

Following the trail of breadcrumbs between the datasheet and the working code, I see a path.  The datasheet says you have to set the decode mode and the scan limit.  In the code I copied elsewhere, I am tracking lines that look like this: (see code section at base of post)

 

 
Once those 2 snippets run, I can do whatever I want with the chip.  I can write whatever value I want to the display (in this code, it requires I write in a byte 8 units long in a decimal count).
 
Do you think this is where I may be off?  I have been looking so long I am about to go crosseyed.  May be a good time to take a rest and let my head calm down.
*****************************In program.cs, the following snippets are run***************************************** private static void DisplayTestMode()         {            _max.SetDisplayTest(Max72197221.DisplayTestRegister.NormalOperation);        } private static void ShutdownTestMode()         {            _max.SetDecodeMode(Max72197221.DecodeModeRegister.NoDecodeMode);            _max.SetDigitScanLimit(7);            _max.SetIntensity(3);             _max.Display(new byte[] { 255, 129, 189, 165, 165, 189, 129, 255});             for(int I = 0; I < 3; I++)             {                Thread.Sleep(500);                 _max.Shutdown();                Thread.Sleep(500);                _max.Shutdown(Max72197221.ShutdownRegister.NormalOperation);            }        } ********************************They reference file max72197221.cs below*************************************** public enum DisplayTestRegister         {            NormalOperation,            DisplayTestMode        } public enum DecodeModeRegister         {            NoDecodeMode,            DecodeDigit0,            DecodeDigit1,            DecodeDigit2,            DecodeDigit3,            DecodeDigit4,            DecodeDigit5,            DecodeDigit6,            DecodeDigit7,            DecodeDigitAll = 255        }
 
 
 

 



#22 Paul Newton

Paul Newton

    Advanced Member

  • Members
  • PipPipPip
  • 724 posts
  • LocationBerkshire, UK

Posted 22 January 2014 - 07:32 PM

Sorry I have not been online for a day.

 

The datasheet says:

On initial power-up, all control registers are reset, the display is blanked, and the MAX7219/MAX7221 enter shutdown mode. Program the display driver prior to display use. Otherwise, it will initially be set to scan one digit, it will not decode data in the data registers, and the intensity register will be set to its minimum value.

 

So its is mostly the opposite to what you would want at power on!

 

It also says:

The display driver can be programmed while in shutdown mode, and shutdown mode can be overridden by the display-test function.

 

And:

The display-test register operates in two modes: normal and display test. Display-test mode turns all LEDs on by overriding, but not altering, all controls and digit registers (including the shutdown register).

 

So if you wrote a simple loop to set the mode between normal and display test, it should overide the shutdown and flash all the LEDs ON and OFF.

 

That looks like what the ShutdownTestMode() function does above, but I am confused about what the Shutdown() function is actually doing.

 

[Short intermission while I clean up the mess the cat just left in the kitchen. :wacko: ]

 

If the test works, then lets look at the other registers:

  • Decode mode: sets whether the display should be a BCD 7-seg "decoder", each bit controls a digit, 1 = BCD, 0 = normal. So you want 0x00 to set them all to dot matrix (no decode mode). The words above say thei is the reset setting.
  • Intensity: sets the on time for the PWM dimmer control, 0x00 minimum to 0x0F maximum. Display test uses the top setting - so I would start with 0x0F or 0x0E.
  • Scan limit: sets how many digits or columns to drive, 0x00 - one, up to 0x07 for all eight. So you want 0x07.
  • Shutdown: obvious, 0 - shutdown, 1 - ON.
  • Display Test: obvious, 0 - Normal, Test - 1

 

So the complete set should be:

  • Decode mode off: 0x09, 0x00
  • Intensity lots: 0x0A, 0x0F
  • Scan limit all: 0x0B, 0x07
  • Shutdown no: 0x0C, 0x01
  • Display Test no : 0x0F, 0x00

I wonder what register 0x0E does?

 

Each command needs to be written as a pair of bytes, not one great long sequence.

 

My original code had Intensity, Scan limit, and shutdown. Maybe adding the Decode mode and display test writes will help. (I am sure they are not needed after a reset).........

 

Don't give up.

 

 



#23 Paul Newton

Paul Newton

    Advanced Member

  • Members
  • PipPipPip
  • 724 posts
  • LocationBerkshire, UK

Posted 22 January 2014 - 07:37 PM

Question.  Where in the code above is the CS pin being triggered?  Is the xSPIConfig controlling that?

 

Also, I think I am on to something.  I am rereading the datasheet and it mentions setting the decode mode, scan limit and a few other variables.  Gonna tweak on that.

Yes the SPI config specifies the pin to use for the strobe, it will set/clear the strobe at the start of the transfer and then do the opposite at the end. The more bytes you send the longer the strobe is high or low, that way the whole array of data gets written out (across multiple devices in the chain) before the final edge that latches them all into the registers.



#24 vader7071

vader7071

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationDothan, AL

Posted 23 January 2014 - 02:04 AM

Got it working!!!!!  Tweaking the code some for a display, and once I have it working, I'll post the code to share and a commentary on how it works.



#25 Paul Newton

Paul Newton

    Advanced Member

  • Members
  • PipPipPip
  • 724 posts
  • LocationBerkshire, UK

Posted 23 January 2014 - 03:19 PM

Well done.

 

(Now you get to tackle the next problem :P )



#26 vader7071

vader7071

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationDothan, AL

Posted 23 January 2014 - 03:20 PM   Best Answer

Ok, here is a copy of the files I am using in a txt format.   First off.  Thank you to Paul Newton on the forum and to Paul from Baltimore Hackerspace.  (Yeah, I thought the same thing until I realized P. Newton is from the UK).  These 2 gentlemen have been so patient helping me solve this problem and have taught me so much.   Now, onto the solution.  I realize this in not the "end all be all" solution.  There are probably more ways to do this, and I am sure I will learn them in time, but this is what I have now.   Finding code to control 1 Max7219 was fairly easy.  I did notice a common thread though.  Most every successful max7219 program had an external file called max7219.cs (or some variant there of).  This external file setup the chip and setup the spi configuration.  But we are not talking about 1 chip here, we want more.   So with the help of the Pauls, here is what I have.   Setup.  I am running multiple max7219 chips to an 8x8 led grid.  Here is what I am using.   program.cs is the guts.  This is where you make the display you want.  max7219.cs is the chip driver.  Without this file, it won't work.   Notes in max719.cs first.  To run multiple chips, there is a section titled "maxDouble".  Looks like:  
// Sends 1 Command / Data pair to two driver chips   public void maxDouble(byte reg1, byte col1, byte reg2, byte col2)      {         // LOAD low         loadPin.Write(false);          // Transmit Register 1         putByte(reg1);         // Transmit Column 1         putByte(col1);         // Transmit Register 2         putByte(reg2);         // Transmit Column 2         putByte(col2);          // LOAD high latches data sent         loadPin.Write(true);      }
You have to have a reg and a col per chip.  So, if you wanted to run 5 chips, there would be a reg1, reg 2, reg 3, reg 4, reg 5 plus the additional lines below making reg 1-5.  Same for col.  This is the first part of controlling multiple chips with different data on each.   Ok, we have made the changes to max7219.cs, now on to program.cs. In program.cs we have 2 areas to look at.  First is near the bottom and says:  
for (v = 0; v < animations[animation_num][0].Length; v++)   {      driver.maxDouble         (            (byte)((v % 8) + 1), animations[animation_num][1][v], //chip 2 (end of line)            (byte)((v % 8) + 1), animations[animation_num][0][v]  //chip 1 (closest to Netduino)         );      Thread.Sleep(10);  // delay set to write next column   }
This is setup for 2 chips.  If we go to the 5 discussed earlier, you will modify it to the following:  
for (v = 0; v < animations[animation_num][0].Length; v++)   {      driver.maxDouble      (         (byte)((v % 8) + 1), animations[animation_num][4][v], //chip 5 (end of line)         (byte)((v % 8) + 1), animations[animation_num][3][v], //chip 4         (byte)((v % 8) + 1), animations[animation_num][2][v], //chip 3         (byte)((v % 8) + 1), animations[animation_num][1][v], //chip 2         (byte)((v % 8) + 1), animations[animation_num][0][v]  //chip 1      );      Thread.Sleep(10);  // delay set to write next column   }
  (notice the change in count from 4 to 0?  That is how we are addressing the chips).   This is the only modification to be done in this area.  You only change here if you are wanting to have more than 2 chips from the example supplied.  Notice though that the chips count from the last chip in the line to the closest chip to the Netduino.  That is key and will be referenced below.   the sleep command is what slows the counting process down.  Increase the value, the update time is slower, decrease, the leds move faster.  the time is in milliseconds.   Now that is all the setup.  But we still don't have our "pretty".  Here is the pretty.  Going back up in the code, there is a section that starts:   byte[][][] animations = new byte[][][]   This is where the pretty is stored.  The reason for 3 sets of brackets is to allow for more than one "pretty".  I won't go into too much detail here, but hopefully as I explain what is where you will see what is going on.   The code:  
byte[][][] animations = new byte[][][]   {      //Annimation index 0      new byte[][]      {         //Chip 1 output (closest to Netduino)         new byte[]         {            0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,            0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01         },          //Chip 2 output (end of line)         new byte[]         {            0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,            0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe         }      }   };
  (now this is extremely simplified).   Each row is 8 bytes long.  Each hex value controls one column of lights.  So to control the whole grid, I have to send 8 hex values total.  0x00 = no lights, 0xff = all lights in a column.  the lights count in binary 1 being the highest led and 128 being the lowest led. One comment about this. Both bytes MUST be the same length. If you are showing something on chip 2 but want chip 1 blank, you MUST send 0x00 as long as you are sending something to chip 2. If they are different lengths, it will fault the program.   The attached code currently scrolls "VA" across 2 displays.  I am in the process of expanding it to say "VADER RULES!" but as you can see, that will take time.  I am sure there are better ways to do it, in fact I am almost positive, but I am learning myself, and this is helping me to better understand what is going on.   Upcoming updates for this for my uses, multiple scrolling messages.  I will have "VADER RULES!" and then have it setup to output random values so the leds just flash and then have it set so the random is running and then every so often, "VADER RULES!" scrolls across and back to random flashing.

Attached Files


  • Paul Newton likes this

#27 Paul Newton

Paul Newton

    Advanced Member

  • Members
  • PipPipPip
  • 724 posts
  • LocationBerkshire, UK

Posted 23 January 2014 - 08:10 PM

Never been to Baltimore; in fact my only stop on US soil was a transit lounge while they mucked out the plane.

 

Nice to see you've taken the time to describe the interesting bits in an easy to understand post. B)

 

Now you know it works, and have proven what needs to be written to the displays, I think your next step should be to try and use the on board SPI hardware. Since this seems to be so hit and miss, a gradual approach might be good - perhaps initially you could use your bit bashing code to make sure the displays are set up, and then switch over to use the SPI hardware to write some test patterns. Then move the setup commands one by one onto the SPI hardware until its all running using the just the hardware SPI.

 

Then the fun part:

 

As you develop it, think about how you might want to drive it in the future - for example:

  • Try not to limit the functions to fixed numbers of displays - use loops to setup the pairs of control bytes for any number of displays.
  • Passing arrays of bytes to functions will be useful.
  • You will proably want to address a single column of pixels on a single display at some stage. You might have a function that allows you to setRow(digit, column, rowValue); To do this, you use the "No-Op" value for the first byte going to all the "other" chips so that they don't repsond to the command going to the desired chip.
  • Then add a function that calls the above function eight times for the same digit to write all eight columns one after another.
  • You will get fed up writing the bitmaps by hand, so will probably want to just write text directly to the display. Think about how to store the bitmaps for each letter of the alphabet so you can "write" ascii letters to the driver using the second function above.
  • If the driver remembers the previous writes, you can scroll the existing data (just to be pretty, or as you write letters to one end)....

Above all else, keep a copy of what works, take small steps when you change the code, and remember to have fun - Paul



#28 vader7071

vader7071

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationDothan, AL

Posted 26 January 2014 - 12:02 AM

One aspect I have noticed working with the program, the more you add display wise (i.e. the more chips and longer message) you sacrifice speed.

 

The video link has 3 max7219 chips and a sleep timer in the code of only 3 ms.  Something to keep in mind.

 

 

BUT, that being said, it is still fun to play with.  Now that I am finding out the limitations, time to start trimming the fat like you suggested Paul.



#29 Paul Newton

Paul Newton

    Advanced Member

  • Members
  • PipPipPip
  • 724 posts
  • LocationBerkshire, UK

Posted 26 January 2014 - 07:32 PM

Looks good!

 

Unfortunate fact of life when bit bashing - the more bits the more bashing!

If you use the SPI hardware it should be a lot faster, hopefully so fast that you won't notice its taking time to send the serial data.

 

Paul



#30 vader7071

vader7071

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationDothan, AL

Posted 26 January 2014 - 09:06 PM

Yeah, looking over the code and comparing, I noticed that what I am using is not using SPI to full extent.  SPI offers 10 MHz data transfer and I don't think I am using that here.  That is my next step is figuring how to incorporate that in,



#31 vader7071

vader7071

    Advanced Member

  • Members
  • PipPipPip
  • 132 posts
  • LocationDothan, AL

Posted 28 January 2014 - 12:30 AM

OK Paul, time to try and pick your brain again.   Shifting from the bit-bang method to xSPI.  I think I have the broad strokes done right, but there are some initialization issues I think.   Here is the whole program:    
using System;using System.Threading;using Microsoft.SPOT;using Microsoft.SPOT.Hardware;using SecretLabs.NETMF.Hardware;using SecretLabs.NETMF.Hardware.Netduino; namespace Dome_Controller_3{    public class Program    {        public static void Main()        {            //Create necessary memory locations            byte[] chip123 = new byte[24];            SPI.Configuration xSPIConfig;                               // SPI configuration            SPI xspi;                                                   // The actual SPI object            //End Creations             // Setup the configuration                //Clock = D13                //Data = D11                //CS = D8            xSPIConfig = new SPI.Configuration(Pins.GPIO_PIN_D8,        //Chip Select (CS) pin                                false,                                  //Chip Select Active State                                0,                                      //Chip Select Setup Time                                0,                                      //Chip Select Hold Time                                false,                                  //Clock Idle State                                true,                                   //Clock Edge                                10000,                                  //Clock Rate (kHz)                                SPI.SPI_module.SPI1);                   //SPI Module             xspi = new SPI(xSPIConfig);                             // Create the SPI port            //End SPI creation             //Begin Chip Initialization            byte[] scan = new byte[]                                    //Scan Limit            { 0x0b, 0x07 };                                             //register, value; set scan limit            byte[] decode = new byte[]                                  //Decode Mode            { 0x09, 0x00 };                                             //register, value; using an led matrix mode (not digits)            byte[] shutdown = new byte[]                                //Shutdown            { 0x0c, 0x01 };                                             //register, value; not in shutdown mode            byte[] display = new byte[]                                 //Display Test            { 0x0f, 0x00 };                                             //register, value; no display test            byte[] intensity = new byte[]                               //Intensity            { 0x0a, 0x0f };                                             //register, value; set max intensity  (range 00-0f)             xspi.Write(scan);            xspi.Write(decode);            xspi.Write(shutdown);            xspi.Write(display);            xspi.Write(intensity);            //End Chip Initialize             //Begin "Pretty"                        Random rndGenMax7219 = new Random();                        //Random Generator             while (true)                                                //Function loop            {                rndGenMax7219.NextBytes(chip123);                       //Create random values in chip123                 xspi.Write(chip123);                                    //Write chip123 to all 3 chips                Thread.Sleep(100);                                      //Sleep            }            //End "Pretty"        }    }}
    By pulling apart the bit-bang code, I found the initialization code.  It is:    
 //Begin Chip Initialization            byte[] scan = new byte[]             //Scan Limit            { 0x0b, 0x07 };                      //register, value; set scan limit            byte[] decode = new byte[]           //Decode Mode            { 0x09, 0x00 };                      //register, value; using an led matrix mode (not digits)            byte[] shutdown = new byte[]         //Shutdown            { 0x0c, 0x01 };                      //register, value; not in shutdown mode            byte[] display = new byte[]          //Display Test            { 0x0f, 0x00 };                      //register, value; no display test            byte[] intensity = new byte[]        //Intensity            { 0x0a, 0x0f };                      //register, value; set max intensity  (range 00-0f)             xspi.Write(scan);            xspi.Write(decode);            xspi.Write(shutdown);            xspi.Write(display);            xspi.Write(intensity);            //End Chip Initialize
  What the old code did was used it's write code to write the scan location followed by the value to the chip.  I think I have it done the right way in the initialization section, but when I run the code, I get some WILD results.   Each chip lights all leds, then they all go out, then some come on in a random pattern, but extremely dim (random is good by the by) then all go out, then all leds come on, then one grid goes out, then another, then one may be totally dark, one is extremely light partially random, and one is full on.   Any ideas?

#32 Paul Newton

Paul Newton

    Advanced Member

  • Members
  • PipPipPip
  • 724 posts
  • LocationBerkshire, UK

Posted 28 January 2014 - 09:08 PM

You are not thinking in paraserialel (OK that's not a real word).

You have got a chain of Max chips, you need to be writing exactly the right number of bytes to fill them all up on every SPI operation.

I think you had three displays in the YouTube video, so I will assume three:

byte[] scan = new byte[]                                    //Scan Limit            { 0x0b, 0x07, 0x0b, 0x07, 0x0b, 0x07 };xspi.Write(scan);

If you write the above byte array, each display should get the scan limit command and a clock pulse to load it.

[color=#0000ff;]Repeat for the other commands[/color].

 

Note that I am not sure whether the bytes go out left to right or right to left - [color=#ff0000;]you may need to swap the above byte order[/color].

 

The code that you had, would have loaded

  • all the setup commands into the first display OK,
  • all but one command into the second,
  • all but two into the last display in the chain.

This is because each two byte write operation would have moved the previous command onto the next display as the next two bytes were written out. But the last commands will never reach the last displays.

 

Next, we need to write some display data. Again the byte array should only be 6 bytes - two per display.

You are going to need to write out at least 8 SPI operations to set all the columns.

(You may chose to use more operations to allow you to just write to one display at a time. This is what the No-Op command is for, it tells the other displays to ignore the operation.)

byte[] chip123 = new byte[6];

You need to load up the pairs of bytes so that each display gets a data load command. These could be to the same digit/column or to different ones:

chip123[0] = 0x00   // Do nothing to display Achip123[1] = 0x00   // not usedchip123[2] = 0x01   // Load column 1 display B with: chip123[3] = 0x99   //  *OO**OO*chip123[4] = 0x01   // Load column 1 display C with:chip123[5] = 0xAA   //  *O*O*O*Oxspi.Write(chip123);chip123[0] = 0x08   // Load column 8 display A with:chip123[1] = 0xA9   //  *O*O*OO* chip123[2] = 0x03   // Load column 3 display B with: chip123[3] = 0x99   //  *OO**OO*chip123[4] = 0x00   // Do nothing to display Cchip123[5] = 0xAA   // not used xspi.Write(chip123);

Or maybe in a loop:

			byte[] chip123 = new byte[6];			byte data = 0;			while (true)			{				for (byte col = 1; col < 9; col++)				{									    // Set all displays to load same column					chip123[0] = col;					chip123[2] = col;					chip123[4] = col;									    // Load different data to each display					chip123[1] = data;					chip123[3] = data + 8;					chip123[5] = data + 16;				    				    xspi.Write(chip123);				    				    data++;				}							    data = data + 16;				Thread.Sleep(1000);			}

Any better?






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.