SureElectronics 3216 Led Matrix

If you buy a P4 32X16 RG Bicolor LED Dot Matrix Unit Board SPI Like from sureelectronics, you'll note that it does not work with any existing arduino code.

In this thread we'll discuss and try to make a working library and all hardware connections.

westfw said in http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1225239439/354:

This board uses the same HT3216 driver chip as the other boards that have been under discussion here, so it is no more "true SPI" that those (and no less. When I wrote the first sample code, the main reason for avoiding existing SPI libraries is that the chip commands were of unusual lengths (not a multiple of 8 bits.) (The "sample" code in Sure's documentation only seems to use the HW SPI support for some of the early initialization of the display.)

The 32x16 has FOUR of the HT3216 controllers, with each one driving the LEDs (red and green) in only two of the 8x8 arrays, so the mapping to dots is going to be significantly different. And you have to figure out which one to write to, and how. And deal with the multiple colors somehow. The existing code between the "draw a dot" logic and above the "send a command to an HT1632" is probably pretty useless.

Also their 5 mm LED "P7" 3216 RG display uses the same code as the smaller 3 mm LED "P4" 3216 RG display.

these use the new HT1632C not the older HT1632 Led Driver chips. The RC Master command ($18) is used differently now

How so? The wording in the datasheet has been changed slightly, but it looks like the actual functionality is identical...

That's right about the datasheet. A couple of the commands were combined into one with a new name. The user just needs to be aware that the code is not the same as the obsolete HT1632C. It also provides more output LED current. I will try to post my SX/B code (still in development) later tonight.

See the Parallax forum for the latest link to my software:

http://forums.parallax.com/showthread.php?128037-Sure-Electronics-new-32x16-bi-color-display-3216-RG

You can open the *.sxb file with any text editor such as Notepad.

See the Parallax forum for the latest link to my software:

http://forums.parallax.com/showthread.php?128037-Sure-Electronics-new-32x16-bi-c...

You can open the *.sxb file with any text editor such as Notepad.

I'll try to make an arduino code from this.

Thank you!

I think I found the trick in http://forums.parallax.com/showthread.php?117423-Electronics-I-O-(outputs-to-common-anode-RGB-LED-matrix)-question/page4:

The HT1632_CMD_MSTMD in HT1632 sets the IC to master mode. But in the new HT1632C it sets it to slave, so to set master mode on the new HT1632C you have to change HT1632_CMD_MSTMD to HT1632_CMD_RCCLK in initialization code of all this 0832, 2416 arduino codes/libraries already available.

I'm without my arduino stuff here(I'm traveling) so I can't test it. I'll try it tomorrow.

Yes. To be a little more specific with the differences between the HT1632 (used in the 2416 and 0832) and the new HT1632C (4 used in the 3216 RG) as far as coding goes is:

The MSTMD command is used ($14) but all that is needed is now the RC MasterMode (which has the same value as the HT1632 RCCLK command of $18).

One obvious difference is that 32x16 display requires an extra signal (CLK, pin2), compared to 24x16 display.

Its actually worse that just a just the extra CLK pin 2.

There is a CS pin 1 and CLK pin 2. The CS and CLK pins use pins from the micro-controller so that when CS is an active LOW (/CS) and the CLK pin is clocked by the micro-controller, 1 of 4 active low CS pins are cycled out of the 74HC164 shift register on the 3216 RG display. These 1 of 4 active low CS pins are fed into each of the 4 quadrant HT1632C active low CS inputs as /CS1, /CS2, /CS3, and /CS4.

The hard part is getting the clock cycling correct on the CLK pin and then applying the CS pin to enable to the correct HT1632C on the 3216 RG display. I haven't quite got this part working correctly yet.

I am having problems with selecting the chip that is supposed to receive the data/command. Basically, all commands/data I send go to all chips at once.

I am having problems with selecting the chip that is supposed to receive the data/command. Basically, all commands/data I send go to all chips at once.

I'm with the same problem here.

I didn't understand the datasheet. If I have more than one HT1632C how do I select the chip I want to control? Cycle the CLK pin? I tried to do this then I went to this problem(all commands/data goes to all chips).

I got it working.
I use the ChipSelect() from Sure's datasheet.
Most of the functions from the original code need to be enclosed between ChipSelect(chipNo) and ChipSelect(0). ChipSelect(0) would be equivalent to the old ht1632_chipfree().
I will put together a demo (with code).
Currently, I am just filling the memory with bits, using this piece of code:

void plot2 (int chipNo, byte addr, byte val)
{
   ht1632_shadowram[addr] = val;
   // Now copy the new memory value to the display
   ht1632_senddata(chipNo, addr, ht1632_shadowram[addr]);
}


static void ht1632_senddata (byte chipNo, byte address, byte data)
{
  ChipSelect(chipNo);
  ht1632_writebits(HT1632_ID_WR, 1<<2);  // send ID: WRITE to RAM
  ht1632_writebits(address, 1<<6); // Send address
  ht1632_writebits(data, 1<<3); // send 4 bits of data
  ChipSelect(0);
}


void loop ()
{
 for (int k=1; k<5; k++)
 {
   for (byte addr=0; addr<64; addr++)
   {
     for (int val=0; val<16; val++)
     {
       plot2 (k, addr, val);
       delay(20);
     }
   }
 }
  cls();
}

I'll appreciate the code! ;D

I tried to rewrite the chipselect function too but without success.

Here are the modified Sure functions I am using:

//**************************************************************************************************
//Function Name: OutputA_74164
//Function Feature: enable pin A of 74164 to output 0 or 1
//Input Argument: x: if x=1, 74164 outputs high. If x?1, 74164 outputs low.
//Output Argument: void
//**************************************************************************************************
void OutputA_74164(unsigned char x) //Input a digital level to 74164
{
  // chip select;
  if(x==1)
  {
    digitalWrite(ht1632_cs, 1);
  }
  else
  {
    digitalWrite(ht1632_cs, 0);
  }
}


//**************************************************************************************************
//Function Name: OutputA_74164
//Function Feature: enable pin A of 74164 to output 0 or 1
//Input Argument: x: if x=1, 74164 outputs high. If x?1, 74164 outputs low.
//Output Argument: void
//**************************************************************************************************
void OutputA_74164(unsigned char x) //Input a digital level to 74164
{
  // chip select;
  if(x==1)
  {
    digitalWrite(ht1632_cs, 1);
  }
  else
  {
    digitalWrite(ht1632_cs, 0);
  }
}


//**************************************************************************************************
//Function Name: ChipSelect
//Function Feature: enable HT1632C
//Input Argument: select: HT1632C to be selected
// If select=0, select none.
// If s<0, select all.
//Output Argument: void
//**************************************************************************************************
void ChipSelect(int select)
{
  unsigned char tmp = 0;
  if(select<0) //Enable all HT1632Cs
  {
    OutputA_74164(0);
    CLK_DELAY;
    for(tmp=0; tmp<CHIP_MAX; tmp++)
    {
      OutputCLK_Pulse();
    }
  }
  else if(select==0) //Disable all HT1632Cs
  {
    OutputA_74164(1);
    CLK_DELAY;
    for(tmp=0; tmp<CHIP_MAX; tmp++)
    {
      OutputCLK_Pulse();
    }
  }
  else
  {
    OutputA_74164(1);
    CLK_DELAY;
    for(tmp=0; tmp<CHIP_MAX; tmp++)
    {
      OutputCLK_Pulse();
    }
    OutputA_74164(0);
    CLK_DELAY;
    OutputCLK_Pulse();
    CLK_DELAY;
    OutputA_74164(1);
    CLK_DELAY;
    tmp = 1;
    for( ; tmp<select; tmp++)
    {
      OutputCLK_Pulse();
    }
  }
}

And here the definitions for pins (etc):

static const byte ht1632_data = 6;  // Data pin (pin 7 of display connector)
static const byte ht1632_wrclk = 7; // Write clock pin (pin 5 of display connector)
static const byte ht1632_cs = 8;    // Chip Select (pin 1 of display connnector)
static const byte ht1632_clk = 9; // clock pin (pin 2 of display connector)


void ht1632_setup()
{
  pinMode(ht1632_cs, OUTPUT);
  digitalWrite(ht1632_cs, HIGH);
  pinMode(ht1632_wrclk, OUTPUT);
  pinMode(ht1632_data, OUTPUT);
  pinMode(ht1632_clk, OUTPUT);

  ht1632_sendcmd(0, HT1632_CMD_SYSDIS);  // Disable system
  ht1632_sendcmd(0, HT1632_CMD_COMS00);
  ht1632_sendcmd(0, HT1632_CMD_MSTMD);       /* Master Mode */
  ht1632_sendcmd(0, HT1632_CMD_RCCLK);
  ht1632_sendcmd(0, HT1632_CMD_SYSON);       /* System on */
  ht1632_sendcmd(0, HT1632_CMD_LEDON);       /* LEDs on */
  for (byte i=0; i<96; i++)
  {
    ht1632_senddata(1, i, 0);  // clear the display!
    ht1632_senddata(2, i, 0);  // clear the display!
    ht1632_senddata(3, i, 0);  // clear the display!
    ht1632_senddata(4, i, 0);  // clear the display!
  }
}

On the hardware side, make sure you use 4 signals from Arduino to the display. In used pins 6-9 in my setup (see the above source code, with the comments).
Also, make sure you plug in the ribbon cable into BR1 connector (inputs) and NOT BR2 (outputs).
As I said earlier, there is an extra cable from Arduino to the display (compared to the 24x16 display, which had CS hardcoded through the switch).

It works! Thanks.

Now I'll try to rewrite the plot function to select the correct chip. After this I have 2 3216 so I'll connect both and try to control 8 HT1632C.

Beautiful!
It would be nice to see westfw's original demo ported.

Great work guys! I will try the Arduino code tomorrow.

Here is my latest for the Parallax SX-48 micro-controller with the 3216 RG and SX/B (Basic like language). There is a picture and SX/B code. I had so many problems selecting the individual HT1632C chips like others did. This works but needs a lot of refinement. Perhaps it will help one of you Arduino developers.

http://forums.parallax.com/showthread.php?128037-Sure-Electronics-new-32x16-bi-color-display-3216-RG&p=962127#post962127

I'm very bad dealing with hex, bit in C.

I made an address, value mapping to help:

                                // x,y
  ht1632_senddata(1, 0x0, 0x8); // 0,0
  ht1632_senddata(1, 0x2, 0x8); // 1,0
  ht1632_senddata(1, 0x4, 0x8); // 2,0
  ht1632_senddata(1, 0x6, 0x8); // 3,0
  ht1632_senddata(1, 0x8, 0x8); // 4,0
  ht1632_senddata(1, 0xa, 0x8); // 5,0
  ht1632_senddata(1, 0xc, 0x8); // 6,0
  ht1632_senddata(1, 0xe, 0x8); // 7,0
  
  ht1632_senddata(1, 0x0, 0x8+0x4); // 0,1
  ht1632_senddata(1, 0x0, 0x8+0x4+0x2); // 0,2
  ht1632_senddata(1, 0x0, 0x8+0x4+0x2+0x1); // 0,3
  ht1632_senddata(1, 0x1, 0x8); // 0,4
  ht1632_senddata(1, 0x1, 0x8+0x4); // 0,5
  ht1632_senddata(1, 0x1, 0x8+0x4+0x2); // 0,6
  ht1632_senddata(1, 0x1, 0x8+0x4+0x2+0x1); // 0,7
  
  ht1632_senddata(1, 0x3+0x20, 0x1); // 1,7 RED
  ht1632_senddata(1, 0x5+0x20, 0x1); // 2,7 RED
  ht1632_senddata(1, 0x7+0x20, 0x1); // 3,7 RED
  ht1632_senddata(1, 0x9+0x20, 0x1); // 4,7 RED
  ht1632_senddata(1, 0xb+0x20, 0x1); // 5,7 RED
  ht1632_senddata(1, 0xd+0x20, 0x1); // 6,7 RED
  ht1632_senddata(1, 0xf+0x20, 0x1); // 7,7 RED

I didn't know how to write the plot function :frowning:

Also, we can make this function like this:

void plot2(char x, char y, char val, char color)