Summary of One-chip 11×10 LED matrix. using pic microcontroller
This project demonstrates driving a 11x10 LED matrix using only a single 8-bit PIC microcontroller via charlieplexing. The author utilized 110 LEDs and an 11-pin controller to achieve the maximum theoretical limit of N*(N-1) LEDs. To maintain consistent brightness, the system scans all 110 positions at approximately 30Hz using Timer0 interrupts, ensuring every LED receives a uniform duty cycle regardless of how many are illuminated.
Parts used in the One-chip 11x10 LED matrix:
- 110 LEDs (from original 120)
- PIC16F688 microcontroller
- PIC16F1823 microcontroller
- Timer0 module
This project is pretty cool for a few reasons, and driving a huge LED matrix with a single 8-bit controller is just one of them. The idea was born when I bought 120 LEDs of the wrong type, and decided to do something with them. With that many LEDs, there are only a few things you can do, and a matrix is the natural first-place-winner in the competition of those ideas. One of the LEDs did not work, so a 12×10 matrix was out, so I settled for an 11×10 matrix. This meant I had to drive 110 LEDs. The only controller I had free was a PIC16F688 with 11 pins that can be used for output.After deciding not to use any other chips, charlieplexing was the way to go. The maximum number of LEDs one can charlieplex using N pins is N * (N – 1), so for 11 pins that number is 110. What a coincidence! 🙂
The problem with charlieplexing is that for any two arbitrary LEDs, only one may be lit at a time. While it is true that some combinations of LEDs can be lit simultaneously. Not all are possible. Thus to use this matrix to show an image, one has to scan trough it rather quickly and turn each LED that needs to be on in succession. A slight nit: If one only scans through LEDs that need to be on, the more LEDs are lit, the dimmer they will be. This is annoying, so always scan through them all, but do not turn some on. This way timing is preserved and all lit LEDs always have the same duty cycle (1/110) regardless of how many of them are actually lit. How fast do you need to scan? Well, you’ll be relying on persistence-of-vision to make them appear solidly lit. For human eye to have this illusion, each LED needs to turn on at least 25 times a second. I chose about 30 times a second as a good value. This means that given the fact that we have 25 LEDs total, we need to switch which LED is on 30×110 = 3300 times a second. That’s a lot! I do not want to write my code with that constraint in mind, so interrupts are used. On PIC16F688 (8 MHz = 2 MIPS) this actually means that interrupts will be happening quite often. Timer0 is used with no prescaler (so it increments once per instruction), and only 32 instructions are allowed to go by between the end of one interrupt handler and the beginning of the next. So in technical terms: timer0 overflow interrupt updated which LED is on, and at the end reloads timer0 with 0xD0, causing it to overflow 0x20 instructions later. On PIC16F1823 this is simpler since it runs at 32MHz ( = 8 MIPS). Here timer0 uses a 1/8 prescaler and is reloaded with 0x60.
For more detail: One-chip 11×10 LED matrix.
- How was the decision made for the matrix size?
The author started with 120 LEDs but one failed, reducing the count to 119; since a 12x10 grid required 120, an 11x10 grid using 110 LEDs was selected. - Why was charlieplexing chosen for this project?
Charlieplexing was selected because it allows driving up to 110 LEDs using exactly 11 output pins on the available PIC16F688 controller. - How is consistent brightness maintained across all LEDs?
The system scans through all 110 positions regardless of whether they need to be lit, preserving timing so every active LED has the same 1/110 duty cycle. - What scan rate was determined to be sufficient for persistence of vision?
A scan rate of approximately 30 times per second was chosen to ensure each LED turns on at least 25 times a second as required by human vision. - How does the code handle the high switching frequency requirement?
Interrupts are used to manage the 3300 switches per second, specifically utilizing Timer0 overflow interrupts to update which LED is active. - What specific configuration is used for Timer0 on the PIC16F688?
Timer0 runs with no prescaler at 8 MHz, allowing only 32 instructions between interrupts before reloading the timer with 0xD0. - How does the implementation differ when using a PIC16F1823?
The PIC16F1823 runs faster at 32 MHz, allowing the use of a 1/8 prescaler and a reload value of 0x60 for simpler timing management.