Interrupt/Kill SmartMatrix for a defined amount of time without retaining image

Interrupt/Kill SmartMatrix for a defined amount of time without retaining image

Hello

First a big thank to you, Louis, for developing and sharing this excellent library. In my project I am using 32x64 LED matrixes to stimulate living cells with optogenetic receptors and a custom PCB based on the ESP32 (teensylc branch, soon the project code will be published on GitHub as it will be opensource).

During the cell stimulation process, the LED matrix is not always powered on, for 10s of stimulation we have a pause of 5 minutes in which the matrix remains dark. As these experiments can go on for up to a week and as cells do not like temperature changes, it is important to reduce the heating up of the LED matrix.

Therefore, I have included a MOSFET circuit which supplies the matrix only with power if needed (+5V line is cut off as GND of the power connector and the GND of the data lines are interconnected in the matrixes). This reduced the heating up of the LED driver chips. However, I still have a problem with an extreme overheating of one of the shift registers located on the Matrix (see FLIR picture, it is one of the ICN74HC chips, the matrix is not used on this picture, it is only connected but no image is displayed).

IR_0801

Exists there a solution to temporally power down the matrix when no image is displayed to avoid a heating up of the matrix (preferably without reinitialising the matrix the next time when an image is sent, as every time it initialises itself it flickers randomly for 0.5s)?

I’ve tried to set all Matrix data pins to GPIO mode INPUT_PULLDOWN, however I still measure 1.6V on them (however only on ABCD, CLK and 0.6V on OE) and the matrix stills heat up. Another thing that I have tried is to reduce the refresh rate (I do not need fancy things only some pixels that illuminate with full brightness at a specific color), it seems that this helped a little bit (however I could not test it with the thermal imaging camera up to now, as I currently don’t have access to it anymore).

Here some additional information on my setup.

Used Library: SmartMatrix Tensylc branch with custom Pin out:

#define CLKS_DURING_LATCH 0
#define MATRIX_I2S_MODE I2S_PARALLEL_BITS_16
#define MATRIX_DATA_STORAGE_TYPE uint16_t
#define R1_PIN 22
#define G1_PIN 32
#define B1_PIN 21
#define R2_PIN 19
#define G2_PIN 33
#define B2_PIN 17
#define A_PIN 16
#define B_PIN 25
#define C_PIN 27
#define D_PIN 26
#define E_PIN -1
#define LAT_PIN 14
#define OE_PIN 13
#define CLK_PIN 12
#define GPIO_PWM0A_OUT GPIO_NUM_32
#define GPIO_SYNC0_IN GPIO_NUM_34

Used MCU: ESP32-WROOM 32D
Used Matrix: 32x64 (multiple, however always one of the three shift registers heats up extremely)

If you need additional information, please contact me.

Thanks for every answer in advance

Very interesting use case I never expected SmartMatrix Library to be used for.

Few thoughts

  • You want to keep OE as an output and keep it high so no LEDs are driven
  • The easiest thing to do might be disconnecting the I2S peripheral signals from driving the GPIO, then connecting them back up when you’re ready to refresh the panel (maybe keep OE driven manually high for a little bit of time and connect that signal last so you don’t get random flashing)
  • Look at the gpio_setup_out() function calls, you want to repeat those to reconnect the panel, and do something else to disable them
  • gpio_setup_out()in turn calls gpio_matrix_out(), which has this option which seems like a quick way to disconnect I2S from the GPIO, which you can then follow with a normal call to setup GPIO as a manually driven output:
    • signal_idx == 0x100, cancel output put to the gpio

Hope that helps!

I reread your issue, and think that setting all outputs to output 0V is probably best, but do try driving OE high if you’re seeing pixels light up, or try driving OE manually high when you reconnect I2S to drive the matrix

It’s possible that chip is heating up because as you’ve disconnected the power supply to the panel, the panel circuit is drawing power out of the HUB75 signals, which are the only thing that is supplying power now. Hopefully setting all signals to low fixes that.

Note the potentially inverted CLK signal, I can’t remember if that’s inverted by default, but it can be different than the rest of the signals.

I guess another way to fix this in hardware if the software proves too difficult is to put a circuit between the ESP32 and HUB75 that drives all the signals low controlled by a separate GPIO. Hopefully the software solution works

Thank you very much for your fast reply. Your hint with setting signal to 0x100 in gpio_matrix_out() worked perfectly. Now I have 0V on all data lines when the matrix is not use. Thanks to the MOSFET circuit I have also 0V on the power line. When touching the chip, it seems to not get hot anymore when the matrix does not display an image. As information for the other forum members, I will share the definitive results (temperature measurements) as soon as I have again access to the FLIR camera (probably towards the end of next week).

If anybody is interested in the code, here are my modifications:
Creation of two new files in the library.
Custom.h

#ifndef CUSTOM_H
#define CUSTOM_H
#include "esp32_i2s_parallel.h"
extern int sig_data_base_stored;
extern int sig_clk_stored;
extern i2s_parallel_config_t cfg_stored;
void reset_matrix_after_sleep();
void sleep_matrix();
#endif

Custom.cpp

#include "custom.h"
#include "esp32_i2s_parallel.h"
int sig_data_base_stored;
int sig_clk_stored;
i2s_parallel_config_t cfg_stored;
void sleep_matrix()
{
    for (int x = 0; x < cfg_stored.bits; x++)
    {
        gpio_setup_out(cfg_stored.gpio_bus[x], 0x100);
    }
    gpio_setup_out(cfg_stored.gpio_clk, 0x100);
}
void reset_matrix_after_sleep()
{
    for (int x = 0; x < cfg_stored.bits; x++)
    {
        gpio_setup_out(cfg_stored.gpio_bus[x], sig_data_base_stored + x);
    }
    gpio_setup_out_invert(cfg_stored.gpio_clk, sig_clk_stored);
}

The header file is then included in esp32_i2s_parallel.c and SmartMatrixMultiplexedRefreshEsp32_Impl.h at the beginning.
Change of gpio_setup_out and gpio_setup_out_invert to void instead of void static in esp32_i2s_parallel.c and addition of the following two lines in esp32_i2s_parallel.h

void gpio_setup_out(int gpio, int sig);
void gpio_setup_out_invert(int gpio, int sig);

Assign (=) cfg to cfg_stored in SmartMatrixMultiplexedRefreshEsp32_Impl.h and sig_data_base, sig_clk to sig_data_base_stored and sig_clk_stored in void i2s_parallel_setup_without_malloc of esp32_i2s_parallel.c

sig_data_base_stored = sig_data_base;
sig_clk_stored = sig_clk

cfg_stored = cfg;

sleep_matrix() and reset_matrix_after_sleep() can then be called in the main part of program to sleep or wake up the matrix.
I know that these modifications are far from genius and probably violate a lot of C++ good coding practice. To my defence, I am not a professional developer, only a mere biochemist. However, I would like to improve my code, especially the part where I copy cfg to cfg_stored. Would it be possible to do this already in the function i2s_parallel_setup_without_malloc? When I understand your code correctly, we have a pointer to cfg in this function. Now I should probably make a deep copy of cfg to cfg_stored (as it does not exist during the whole runtime of the program). I’ve tried it with multiple variants, however never arrived. Could maybe somebody give me a hint how I can create this copy of cfg to cfg_stored already ini2s_parallel_setup_without_malloc? Thanks a lot for any help.

1 Like