Как получить стабильное светодиодное освещение без сцинтилляции по шине I2C

led i2c led-matrix io-expander latency

Я построил светодиодную матрицу 8x8, используя белые светодиоды 5 мм. Я управляю светодиодами с помощью MCP23017, подключенного к Arduino по шине I2C. Схема подключения светодиодов в матрице такова, что ряд состоит из 8 светодиодов, катоды которых соединены вместе, а столбец состоит из 8 светодиодов, аноды которых соединены вместе. Конец каждой строки и каждого столбца соединен с выводом GPIO MCP23017. Размер пикселя составляет 4cmx4cm, что означает, что строка имеет длину 32 см (то же самое для столбца).

Я не могу заставить свет быть "стабильным", он продолжает мерцать. Я увеличил тактовую частоту шины I2C со 100 кГц до 400 кГц, теперь свет более стабилен, но недостаточно, так как сцинтилляция сохраняется. Перед этим я установил тактовую частоту I2C на 1700kH, и освещение стало еще медленнее..., я попытался увеличить значения импульсных резисторов выводов GPIO MCP23017, чтобы иметь более быстрый отклик на его выводах GPIO, но это не имело никаких эффектов.

Я думаю о 2 потенциальных причинах:

  • Провода слишком длинные для протокола I2C (сторона светодиодной матрицы длиной 32 см).
  • ток, достигающий каждого столбца (аноды), недостаточно, так как есть так много светодиодов, чтобы загораться.

Как вы думаете, что вызывает это плохое освещение? должен ли я изменить MCP23017 с другим типом расширителя/протокола?

Вот код:

#include <Wire.h>
#include <Adafruit_MCP23017.h>

bool four[3][5] = {{1, 1, 1, 0, 0}, {0, 0, 1, 0, 0}, {1, 1, 1, 1, 1}};
Adafruit_MCP23017 mcp;

void setup() {
  mcp.begin();
  for(int i=0; i<16; i++){
    mcp.pinMode(i, OUTPUT);
    }
}

void set_column(uint8_t col_idx, bool pixels[]){

  for(uint8_t i=0; i<8; i++)
    mcp.digitalWrite(i, HIGH);

  for(uint8_t i=8; i<16; i++) //Anodes are connected to Bank B of the MCP23O17
    if(i!=col_idx+8)
      mcp.digitalWrite(i, LOW);
    else
      mcp.digitalWrite(i, HIGH);

  for(uint8_t i=0; i<8; i++) //Cathodes are connected to Bank A of the MCP23O17
    if(pixels[i])
      mcp.digitalWrite(i, LOW);
}

void display_character(bool character[3][5]){
  bool pixels[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  for(int col=0; col<3; col++){
    for(int i=0; i<5; i++){
      pixels[i+3] = character[col][i];
      }
    set_column(7-col, pixels);
    }
}

void loop() {
 
  uint32_t time = millis();
  while(millis() - time < 1000)
    display_character(four);
}

, 👍1

Обсуждение

Проблема в том, что вы используете I2C. Это просто недостаточно быстро., @Majenko

Какой библиотекой вы пользуетесь? Кажется, что он делает одну передачу, чтобы установить один контакт. Это привело бы к 24 передачам. Кроме того, вы записываете контакты от 0 до 7 дважды, что не является необходимым. Вместо этого должна быть возможность записать все 16 контактов с помощью одной передачи. Это было бы намного быстрее, @chrisl

MAX7219 был бы гораздо лучшим драйвером для матрицы 8x8, чем bitbandig over extender. И, как уже отмечалось, вы должны написать весь колум сразу. Однако рядные выходы могут управлять только около 30 мА, поэтому я надеюсь, что у вас нет резисторов для колумб слишком маленьких, @KIIV

@Majenko, Даже 400k Hz в качестве тактовой частоты I2C недостаточно? почему это?, @S.E.K.

@chrisl Я использую библиотеку Adafruit_MCP23017 (я обновил фрагмент кода в вопросе). Да, каждый вывод настройки MCP23017 принимает передачу... Я понимаю, что могу установить им гораздо меньше передач. Спасибо за предложение., @S.E.K.

@KIIV Я поставил резистор 20 Ом для каждой колонки, я выбрал это значение, чтобы получить как можно более яркий свет. Я ошибаюсь в этом вопросе?, @S.E.K.

@S. E. K. "Абсолютный максимальный" ток приемника или источника составляет 25 мА на вывод и 150 мА для Vss / 125mA Vdd. Если прямое напряжение светодиодов составляет около 3 В, а Vcc для MCP 5 В, то у вас есть 2 В на резисторе 20R -> 100 мА (теоретически) для одного светодиода. В принципе он скоро сгорит или позже, @KIIV

@KIIV если ток на вывод составляет 25 мА, то напряжение через резистор 20R по закону Ома составляет 20*0,025=0,5 В, как вы обнаружили, что у меня есть 2 В на 20R? (Мои знания в области электроники довольно шаткие...), @S.E.K.

Светодиод имеет, например, нелинейную характеристику, где при 3,1 В будет 20 мА (зависит от цвета и других параметров. После этой точки напряжение медленно повышается, но ток быстро растет. 3,5 В может быть легко больше 100 мА., @KIIV

Лично я бы либо использовал специальный чип светодиодного матричного привода, либо специальный Arduino для непосредственного управления матрицей дисплея., @Majenko