I bought a 32×64 RGB LED Panel in May of 2018 just for the hell of it. No real plan or application. I tend to go on buying binges for electronics periodically. I think I might have powered it up with some Arduino code I found online just to make sure all the LEDs worked, but it really just sat in a drawer collecting dust for a year. Then in the summer of 2019 I decided to put it to use and make a personal project out of it. I chose to use the display for a simple weather app I could mount in my apartment. Instead of looking on my phone or a website for basic weather information of the day, I would have it hanging on my wall always updated with current information just waiting to be looked at. I didn’t even know what type of weather information I wanted or could display at this point, it was more of an exploratory project that I ended up being very happy with. It was a fun simple project that I use (look at) every single day; and it’s still running perfectly fine today (December 2020).
RGB LED Panel
My 32×64 Pixel RGB LED Panel was purchased off Amazon, iSparkLED brand, but who really knows. I think many companies make this product and they all more or less follow the same hardware and interface protocols.
After a little Googling, I found Adafruit’s tutorial on controlling LED panels with a Raspberry Pi to be extremely helpful (okay, crucial). Big shout out to their team, they have great content. Here are some other tutorial links I also found useful: another Adafruit tutorial, BigjBehr’s tutorial, and Ramin Sangesari’s tutorial.
The tutorials above go into much greater detail about the LED Panel’s operation. Keeping it brief, the panel is powered through a 5VDC connection. Each LED (ignoring PWM dimming) can either be set OFF, RED, GREEN, BLUE, or any combination of the 3. I ran some initial experiments to test the panel’s current consumption. The idle current draw with all LEDs OFF, but powered up via the 5V connection, was around 68mA. With all LEDs ON and WHITE (the most current-hungry RGB color selection) the total current draw was around 340mA. So to be safe, I power the LED Panel with a 5V AC-to-DC adapter with a maximum current rating of 2A, well above the 340mA maximum.
Again, each LED can be a combination of RED, GREEN, or BLUE. Representing each RGB color as a single bit (1), there is a total of 8 (0-7) 3-bit combinations you can make and mix to generate more colors. This ignores PWM dimming; each RGB color is either completely ON or completely OFF.
The pinout interface is this 16-pin (8×2) male pin header connection. The LED Panel’s hardware is not capable of “remembering” commands and keeping the LED state you send. You must continually send commands as fast as possible or the LED panel with flicker or go black. This concern will come up in the Raspberry Pi section. Basically, you must constantly send RGB bit values to each LED starting in the upper-left corner, going right column by column, and then moving on to the next row.
Besides the obvious shared GROUND connections, the remaining 13 control pins are all inputs (to the LED panel):
- R1 – Controls the RED LEDs on the top half of the panel
- R2 – Controls the RED LEDs on the bottom half of the panel
- G1 – Controls the GREEN LEDs on the top half of the panel
- G2 – Controls the GREEN LEDs on the bottom half of the panel
- B1 – Controls the BLUE LEDs on the top half of the panel
- B2 – Controls the BLUE LEDs on the bottom half of the panel
- A, B, C, D – Row addressing bits for the multiplexing circuitry of the panel (0-15, 0000-1111)
- CLK – Clock, high speed pin to clock-in RGB data to the panel
- LAT/STB – Latch or Strobe, used to latch data into the panel (0 to 1 to 0) for each row
- OE – Output Enable, controls whether all LEDs are allowed to turn on or not (1 = OFF, 0 = ON)
I originally thought of using a PIC microcontroller to drive the LED Panel, but I abandoned that early on because…
- I wanted to write the code in Python to get more practice in the language (I was using it heavily in grad school).
- Using a standalone microcontroller would require an additional WIFI IC to grab weather information which results in more circuitry and points of error. I wanted to keep this project light and simple.
- I don’t want to physically connect to the controller to re-program it every time I want to update or try something out. I wanted wireless remote access.
Therefore, I decided to use a Raspberry Pi to drive the LED Panel since I already had one sitting around, I needed more experience with a Pi, and most of the LED Panel examples I found online also used the Pi. So Raspberry Pi it is! FINE!
I originally wanted to use the cheaper, lightweight Raspberry Pi Zero W (kit) for this project. I envisioned slapping this small Pi directly on the back of the LED Panel so the only cables needed for the project was a single power connection. The Pi Zero was light enough to plug in directly to the back panel’s PCB (described below) and not cause issues. However, when implementing the Python code (described below) from scratch without the use of RGB LED Matrix libraries, I could not overcome constant LED Panel flickering. The code and weather app functionality worked perfectly fine, but the Pi Zero’s clocking speed could not keep up. So I had to put the Pi Zero back in the drawer. Damn.
Instead, I purchased the full-blown big boy Raspberry Pi 3 B+ (kit) off Amazon. Besides the beautiful and compact layout, it’s a full-blown single board computer running Linux with clocking speeds suitable for constantly driving the LED Panel without noticeable flickering. WIFI capability is built into the board so wireless file transfer and control is an ease.
Below is the final mapping of 13 GPIO Raspberry Pi pins to the LED Panel pins described earlier. All of the connections are Pi-outputs/LED-inputs, all one direction. The motivation of which GPIO pins were selected was arbitrary, just convenience when mapping out PCB traces. Note: in my Python code I use the relative GPIO# to map variables to the correct Pi pins, NOT the actual pin number (1-40).
However, there’s one BIG problem when using a Pi to drive this LED Panel directly. The logic of the Pi is 3.3V and the logic of the LED Panel is 5V. That’s where additional circuitry comes into play in the form of a “PI HAT” or as I call it “Pi-to-Panel PCB Adapter”.
Pi-to-Panel PCB Adapter
To overcome the voltage level difference between the Pi and Panel, Adafruit offers a PI HAT voltage level converter. Their circuit contains more than 3.3V-to-5V conversion; power protection and a real time clock. This felt like overkill for my application. I simply needed to convert the 3.3V Pi pins to 5V LED Panel pins, so I decided to design and solder my own PCB.
The schematic is very simple consisting of 4 logic level converters and female pin header connectors. I purchased the 3.3V-to-5V 4-channel converters off Amazon. All the materials used in this project are in my Bill of Materials files at the top of this page.
Each logic level converter IC has 4 channels, so to convert 16 total pins 4 ICs are required. I included 2 40-pin (2×20) pin header connections on the middle-man adapter circuit. All pins are directly mapped/connected to each other. This allows you to solder a male or female connector on the unused area if you wish to add more circuitry or pin connections to the Pi. Don’t want to waste all the unused Pi pins by covering them up with the ribbon cable connector. The EAGLE SCH and PCB files are at the top of this page.
Before getting into the LED interface design and which weather stats I included, the weather information API I used was the Dark Sky API. However, they are no longer accepting new users. BIG BUMMER! They allow existing user accounts to stay active, but it looks like no one new can use their great service. They offered free membership users 1000 weather information “pulls” per day. Which is plenty for my application. Their API documentation is pretty straightforward so I won’t go into detail here. If you’re interested compare their documentation to my final Python code. There are other Weather Info APIs out there that could be adapted to work with this project; just alter the weather-related portions of the Python code.
Python Code and Features
My initial set of desired features included:
- Top 3-cell display showing: LOW temperature of the day (blue), CURRENT temperature (green), and HIGH temperature of the day (red).
- Line graph showing temperatures for the day (midnight to midnight).
- Have pixel in line graph for the current time match the color of the CURRENT temperature displayed above.
- 1-D bar graph showing CURRENT rain percentage.
- 1-D bar graph showing CURRENT UV index.
- Refresh every 4 or 5 minutes automatically.
- Below is my original concept sketch adhering to the amount of pixels I can work with.
Throughout design and implementation I expanded to include the new features:
- A 2nd “screen” to display the rain percentages in a 2-D bar graph throughout the day.
- IR control to switch between the 2 screens and to turn off all the LEDs at night. Added an IR receiver that accepts any standard remote control IR signal. So any remote and any button can control the LED Panel by pressing and holding a button for a few seconds.
The photos and videos of the working LED Panel I took on my phone aren’t of the highest quality, the refresh rate of the LED Panel and the frame rate of my phone’s camera aren’t a perfect match. So I included some matplotlib images and animations to fully illustrate what the Weather App system is capable of. I altered the Raspberry Pi Python code to interface with traditional plots instead of the physical LED Panel.
Here are GIFs and images describing the weather stats shown on screen0 (general) and screen1 (rain):
The Python code running this weather program is just a single file, Weather_Display.py I did not use any RGB LED Matrix libraries, instead wrote everything bare bones and from scratch (with help from those tutorial sites). I think it is fairly well commented and self-explanatory. The code is ready to go but you have to change the weather API DarkSky’s “api key” and “location”, but like I mentioned above DarkSky no longer accepts new members. So you would have to rework some of the weather information pulling Python code anyway with a new API service. I hardcoded the numbers myself in 3-D lists with a pixel size of 6 wide by 13 tall for the large numbers used for temperatures on the main screen which can handle 3-digit temperatures. For the smaller numbers on the 2nd screen I hardcoded another list of numbers that are 3 wide by 5 tall.
The system/LED Panel updates or refreshes every 4 minutes which comes to 360 weather API pulls a day. Well under the free 1000 allowed by DarkSky. The main routine is constantly being executed in a while(TRUE) loop since the LED Panel needs constant communication to “stay on”. If you do it fast enough, it appears that it is truly static and on.
Due to the nature of this application and LED Panel interfacing requiring constant communication to stay on, threading is required for 2 things: 1 – getting weather information and preparing it for output (main_func()) and 2 – detecting IR communication to switch screens or shut off the LEDs (IR_decoder()). Running threads in the background to catch interrupts at any point in time is simple since the Pi runs Linux, easy as pie.
The MAIN FUNCTION also contains a while(TRUE) infinite loop that has the 4-minute delay at the bottom. It grabs the weather information with a little postprocessing of the numbers or data type formats, draws the basic outline frames, draws the temperature numbers, line graph, etc. The time.sleep(0.01) statements are not required, they just add a cool animation effect showing the graphs populating more slowly and noticable by the human eye.
The IR DECODE function reads input from the IR Receiver I added to the circuit. Simply connected it to the additional female pin headers of the Pi pins not being used by the LED Panel. The simple wiring diagram is below. This IR Receiver accepts standard TV/DVD/Blu-Ray remote IR signals of a certain frequency band (I think around 38KHz). So basically, I can use any button from any remote to toggle the LED Panel’s screens (screen0/normal –> screen1/rain –> All LEDs OFF –>…). But since this LED Panel is in the same room as my TV, I don’t want the screens toggling every time I press the volume button. So within this IR Decoding code, the IR signal has to persist for a few seconds to register. You must hold the remote button down, not just a normal press.
There are many more important functions within the Python file, but these are the most interesting in explaining the broad strokes. Check out my .py file for everything else. To automatically execute my Python file every time the Raspberry Pi boots up I added the line “sleep 20;sudo python /home/pi/Desktop/weather/Weather_Display.py” without quotes to the “/etc/rc.local” file learned from this site on Pi startup programs. Every once in a while my program threw an error or got caught in some weird loop, so like a bad programmer not fixing the ACTUAL problem, I decided to automatically restart the Pi everyday to “clear everything up”. I know, lazy. But hey, it works. To learn about the Linux “cron” capabilities on the Pi visit this site.I loved this project and use its weather information everyday. It helped me become more familiar with the Raspberry Pi and GPIO programming in Python. Python isn’t a language you usually associate with low-level pin manipulation. My code ended up being pretty lightweight with not much fat and I was proud of how the code’s structure turned out. I think it’s pretty readable for any software engineer out there. Anyway, here are some blurry photos and GIFs of the finished product. ENJOY!
Source: LED Panel Weather App Project