Monday, May 16, 2011

Silent Radio LED Sign Part 4

There are at least three solutions for the brightness problem.

One solution lays in the cathode drivers.  There are brown resistor arrays consisting of 100 ohm resistors in series with the cathodes of the LED arrays.  They can be bypassed with 10 ohm resistors.  The arrays go every other pin so the replacement resistors can be jumpered in on the back side of the board from pin 1 to 2 then next resistor goes from pin 3 to pin 4 , etc.  You would need to do this like 90 times to fix the brightness problem that way.

Another solution lays in the Anode drivers.  If you add a ULN2003, then a PNP driver like the TIP125 you can then deliver much more voltage to the anodes.  With the Tip120's there is 5 volts on the collectors, 5 volts to the base but only 4 volts is delivered to the anodes of the LED arrays because of the Base-Emitter voltage drop.  Even if you increase the power supply to 8 volts the NPN drives still only send 4 volts on the the LED arrays.  I tried using a PNP driver and i tried using FET's to no avail as long as the power supply is still at 5 volts.  So you need to change the driver configuration to a ULN2003 to a 1 k resistor to a TIP125 driver.  The emitter goes to a 8 or 9 volt at 2 amps power supply and the collector goes to the LED arrays.  That also means that the driver transistors cannot be on a common heat sink.

Then I came up with what might be the best solution, a 4017!  It runs off 9 volts and can connect to the Arduino for reset and clock. By not using output 1 of the 4017 a reset can be used to blank the display then we clock the 4017 to the row that you want to light up.  I have wired it up and am working on the necessary software changes.

Here is the schematic:


Here is a picture of the controller with the 4017 added.  So far the maximum operating voltage is 6 volts at 7 volts it stops working for some reason? Problem solved, it was a bad AC adapter, it runs fine on 9 volts at 2 amps.  If you try 10 volts the shift registers stop because the clock and data levels are too low.
To get it to fit back into the aluminum cabinet I had to move the Arduino down below the brown circuit board.  Otherwise it scrapes the top of the aluminum and shorts out.

Here is a video of it running.


Here is the code to make it work with the 4017.  Note that I turned the sign upside down so the greeen arrays are on the left for this version of the code.

//**************************************************************//
//  Name    : Silent Radio Driver with 4017                    //
//  Author  : Bob Davis                                         //
//  Date    : 20 June, 2011                                    //
//  Version : 1.0                                               //
//  Based on work of Hari Wiguna - http://g33k.blogspot.com/    //
//****************************************************************
// Pins for the 4017 Row select
int RowReset = 3;
int RowClock = 2;
// Pins for the Column shift registers
int clockPin = 4;
int dataPin = 5;

// Set the pins to output to the circuit
void setup() {
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(RowReset, OUTPUT);
  pinMode(RowClock, OUTPUT);
}

//=== B I T M A P ===
//Bits in this array represents one LED of the matrix
// 8 is # of rows, 7 is # of LED matrix we have
byte bitmap[8][12]; // Change the 12 to however many matrices you want to use.
int numZones = sizeof(bitmap) / 8;
// I will refer to each group of 8 columns (represented by one matrix) as a Zone.
int maxZoneIndex = numZones-1;
int numCols = numZones * 8;

//=== F O N T ===
// Font courtesy of aspro648
// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1203747843/22
// The @ will display as space character.
byte alphabets[][5] = {
  {0,0,0,0,0},
  {31, 40, 72, 40, 31},
  {127, 73, 73, 73, 54},
  {62, 65, 65, 65, 34},
  {127, 65, 65, 34, 28},
  {127, 73, 73, 65, 65},
  {127, 72, 72, 72, 64},
  {62, 65, 65, 69, 38},
  {127, 8, 8, 8, 127},
  {0, 65, 127, 65, 0},
  {2, 1, 1, 1, 126},
  {127, 8, 20, 34, 65},
  {127, 1, 1, 1, 1},
  {127, 32, 16, 32, 127},
  {127, 48, 24, 12, 127},
  {62, 65, 65, 65, 62},
  {127, 72, 72, 72, 48},
  {62, 65, 69, 66, 61},
  {127, 72, 76, 74, 49},
  {50, 73, 73, 73, 38},
  {64, 64, 127, 64, 64},
  {126, 1, 1, 1, 126},
  {124, 2, 1, 2, 124},
  {126, 1, 6, 1, 126},
  {99, 20, 8, 20, 99},
  {96, 16, 15, 16, 96},
  {67, 69, 73, 81, 97},
};

//=== F U N C T I O N S ===
// This routine takes whats in the array and display it on the matrix
void RefreshDisplay()
{
  for (int row = 0; row < 8; row++) {
    //-- turn off the display --
//    if (row==1) {
      digitalWrite (RowReset, HIGH);
      digitalWrite (RowReset, LOW);
//    }
    //-- Shift out to each matrix (zone is 8 columns represented by one matrix)
    for (int zone = maxZoneIndex; zone >= 0; zone--) {
      shiftOut(dataPin, clockPin, MSBFIRST, bitmap[row][zone]);
    }
    //-- turn the current row on --
    for (int rowclk = row; rowclk > 0; rowclk--) {
      digitalWrite (RowClock, LOW);
      digitalWrite (RowClock, HIGH);
    }
    //-- Wait a little bit to get more brightness --
    delayMicroseconds(1000);
  }
}

// Converts row and colum to actual bitmap bit and turn it off/on
void Plot(int col, int row, bool isOn)
{
  int zone = col / 8;
  int colBitIndex = col % 8;
  byte colBit = 1 << colBitIndex;
  if (isOn)
    bitmap[row][zone] =  bitmap[row][zone] | colBit;
  else
    bitmap[row][zone] =  bitmap[row][zone] & (~colBit);
}

// Plot each character of the message one column at a time, updated the display, shift bitmap left.
void AlphabetSoup()
{
  char msg[] = " ARDUINO LED SIGN ";
  for (int charIndex=0; charIndex < (sizeof(msg)-1); charIndex++)
  {
    int alphabetIndex = msg[charIndex] - '@';
    if (alphabetIndex < 0) alphabetIndex=0;
    //-- Draw one character of the message --
    for (int col = 0; col < 6; col++)
    {
      for (int row = 0; row < 8; row++)
      {
        // Set the pixel to the alphabet for columns 0 thru 4
        bool isOn = 0;
        if (col<5) isOn = bitRead( alphabets[alphabetIndex][col], 7-row ) == 1;
        Plot( numCols-1, row, isOn);
      }
      //-- The more times you repeat this loop, the slower we would scroll --
      for (int refreshCount=0; refreshCount < 20; refreshCount++)
        RefreshDisplay();
      //-- Shift the bitmap one column to left --
      for (int row=0; row<8; row++)
      {
        for (int zone=0; zone < numZones; zone++)
        {
          // This right shift would show a left scroll on display.
          bitmap[row][zone] = bitmap[row][zone] >> 1;
          // Roll over lowest bit from the next zone as highest bit of this zone.
          if (zone < maxZoneIndex) bitWrite(bitmap[row][zone], 7, bitRead(bitmap[row][zone+1],0));
        }
      }
    }
  }
}
//=== L O O P ===
void loop() {
  AlphabetSoup();
}
Post a Comment