I'm working on a research project in computational microscopy with the goal of doing large field-of-view, live cell imaging. We're using an Adafruit 32 x 32 RGB LED matrix panel (product id 607) to illuminate the sample with different patterns. The patterns are arrangements of individual LEDs where the blue LEDs in each matrix element only are either full on or off. All others are off.
We've noticed that using a CMOS camera with a rolling shutter and single LED illumination will produce bands across the camera's images regardless of the LED. The bands change thickness as we change exposure time, and they move slowly across the image when viewing the live stream. Our exposure times are usually between 10 and 100 ms.
All of this suggests there's an aliasing effect between the camera snapping an image and a LED possibly changing brightness or being switched on and off during the camera's exposure. It might also be due to the camera's rolling shutter reading out rows at different LED outputs over time. We're using the Adafruit Protomatter library on an Adafruit Metro Express M0 and are not explicitly doing any PWM.
I assume the LEDs have some sort of refresh rate that's causing this. Is this normal behavior for a LED matrix? Is there anyway to turn on a single LED in a LED matrix and keep its output constant? If not, why not? Can we somehow adjust the refresh rate to be many times faster than our exposure time, i.e. around 1 / 1000 s?
Absolutely. The LED matrix is using a something like dynamical indication - that is, only part of the matrix is lit at any time. By quickly switching parts, the entire screen is illuminated. Switching frequency is between 50 and 1000 Hz, typical is 200-400 Hz.
It is possible to light up only one pixel (or one line) on the matrix and not switch it - but for this you will have to change the library code.
The ability to raise the frequency above 1000 Hz depends on the microcontroller, the type of matrix and the library code. Most likely the standard library will not be able to do this, again, you need to change the code.
By the way, if you use pixels of only one base color (red, green or blue), it might make sense to choose a monochrome matrix of the corresponding color. On them, the scanning speed can be made higher.
What arduino controller are you using? I have been working with RGB and monochrome matrices in the Arduino environment for several years. For convenience, I wrote my own library for them. Please explain your problem in more detail, maybe I can help you
Thanks for your response, especially confirming that there is refresh of the board that's occurring.
For the moment I'm actually using an Adafruit knock-off, the Metro Express M0, because it plays nicely with the LED matrix and allowed me to get up and running quickly. I'm open to switching to another board if necessary.
For the moment, I'm actually just using serial communication with the M0 to illuminate one LED at a time according to its (column, row) coordinates in the matrix. Essentially, I have a script running on the PC that:
Sends a serial message to clear the LED board
Sends a command to illuminate the target LED at coordinates (col, row)
Snaps an image with the camera
Goes back to step 1 for the next LED in the matrix
Eventually I'll move to triggering the camera with the board so that the loop can run on the M0, but this will come later.
Even with only one LED on, I see the aliasing effects in the image. Any advice you have on how to keep a single LED illuminated with constant output would be great.
The Adafruit website says that this board is designed for use with the python language. Are you using it in python or in C? Are you programmed it in Arduino IDE? What library do you use to work with LED matrix?
I can't share the full repo that houses the code that I'm using since it's in a monorepo with some private stuff to our lab, but here's a snippet of the matrix control code where we illuminate a single LED:
We more-or-less parse the serial message into a custom Message type, then call the drawPixel method from Protomatter, which takes the LED coordinates and the color. In this case, MAX_BRIGHTNESS is 31, which is maximum blue in RGB565.
Not exactly.
It declared in Adafruit GFX, right, but as clearly virtual method.
The complete definition of the function is in the Protomatrix library code.
I am familiar with Adafruit GFX and old RGBMatrixPanel library, but not with Protomatrix. This library is quite complex, I need to understand its structure
The all these matrices works uses a common principles. They are driven with at least two types a microchips - the first is a led driver (one for each 8, 16,24... pixels) and the second is a address line multiplexor. There are many types of the drivers and multiplexors, but the fact that the OP uses the Protomatrix library speaks in favor of the fact that these are the most common ones.
That's not sufficient for the specific matrix. A dedicated controller chip has to be handled differently from discrete logic. Lack of answering my questions indicates lack of knowledge about the resulting problems and fixes.
Thanks to everyone who replied so far. I'm an optical engineer by training, so this stuff is relatively new to me. At least knowing that what I want is in principle possible with some LED matrix is a huge help.
@b707 I appreciate you taking a look. I'll also poke around a bit inside Protomatter to see whether I can make any sense of it.
Depends what you mean by "matrix".
Addressable LEDs are always PWMing (blinking) regardless how often they're 'updated'.
If it's a 'matrix' that runs like a line scan television, basically, there's only one on at a time - there's still blinking.
Sorry for saying that, but I am sure that there is NO dedicated controller chip in this case. The fact that the matrix works with the library unambiguously determines on which fundamental elements it is assembled.
Please read this disclaimer:
There are a few peculiar RGB LED matrices that have the same physical connection but work a bit differently -- they might have only have three shift register chains rather than six, or might use a shift register for the row selection rather than a set of address lines. The code presented here DOES NOT support these matrix variants.
Yes, it possible, and even relatively simple.
As I already wrote, only part of the matrix lits at any given moment. In the simplest case, these are two horizontal rows. The element that controls which rows of the whole matrix are switched on is called the address multiplexer. It is controlled by pins A B C D E on the hub75 connector. All you need to switch only the desired pixel is to find in the library code a function that switches rows and turn on only the desired row. I know how to do this in the RGBMatrixPanel library or in my code, but not in Protomatrix
As @DrDiettrich correctly said, there may be problems with brightness and cooling. Each pixel of the matrix is designed to work only 1/8 or 1/16 of a period, and the rest of the time it is off. If you turn it on all the time, then the brightness of the pixel will increase, respectively, by 8-16 times and it may overheat.
Thank you to all who replied. I think I have a basic handle on how these things work now, but I need to do some more research to better understand them. They're more complicated than I had anticipated.