Почему светодиоды заметно мерцают?

Цель проекта состояла в том, чтобы продемонстрировать два «вида» светодиодов в одноцветной светодиодной матрице 8x8. Я использовал чип MAX7219 для управления светодиодами с помощью моего Arduino UNO R3. как драйвер (с обычным подключением).

Несмотря на то, что частота функции blackupdate() близка к 100 Гц, почему я вижу мерцание светодиодов, соответствующих currentblack()? 100Гц это намного больше разрешения глаза, как я понимаю. частота мультиплексирования чипа MAX7219 также намного превышает разрешение (800 Гц). Почему "белые" светодиоды не мерцают?

Вот код с Serial.println(), добавленным для отладки:

int DataPin = 2; // Контакт 1 на MAX
int LoadPin = 3; // Контакт 12 на МАКС.
int ClockPin = 4; // Контакт 13 на МАКС.
int currentwhite[8]={B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};
int currentblack[8]={B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};

#define SCAN_LIMIT_REG 0x0B
#define DECODE_MODE_REG 0x09
#define SHUTDOWN_REG 0x0C
#define INTENSITY_REG 0x0A
#define DISPLAY_CHECK_REG 0x0F

void setup() {
  pinMode(DataPin, OUTPUT);
  pinMode(LoadPin, OUTPUT);
  pinMode(ClockPin, OUTPUT);
  digitalWrite(LoadPin, LOW);
  shiftOut(DataPin, ClockPin, MSBFIRST, SCAN_LIMIT_REG); // предел сканирования установлен на 0:7
  shiftOut(DataPin, ClockPin, MSBFIRST, B00000111);
  digitalWrite(LoadPin, HIGH);
  digitalWrite(LoadPin, LOW);
  shiftOut(DataPin, ClockPin, MSBFIRST, DECODE_MODE_REG);
  shiftOut(DataPin, ClockPin, MSBFIRST, B00000000);
  digitalWrite(LoadPin, HIGH);
  digitalWrite(LoadPin, LOW);
  shiftOut(DataPin, ClockPin, MSBFIRST, SHUTDOWN_REG);
  shiftOut(DataPin, ClockPin, MSBFIRST,  B00000001);
  digitalWrite(LoadPin, HIGH);
  digitalWrite(LoadPin, LOW);
  shiftOut(DataPin, ClockPin, MSBFIRST, DISPLAY_CHECK_REG);
  shiftOut(DataPin, ClockPin, MSBFIRST, B00000000);
  digitalWrite(LoadPin, HIGH);
  digitalWrite(LoadPin, LOW);
  shiftOut(DataPin, ClockPin, MSBFIRST, INTENSITY_REG);
  shiftOut(DataPin, ClockPin, MSBFIRST, 0);
  digitalWrite(LoadPin, HIGH);
  Serial.begin(9600);

  currentblack[3]=B00001000;
  currentblack[4]=B00010000;
  currentwhite[3]=B00010000;
  currentwhite[4]=B00001000; 
}

void blackupdate() {
  digitalWrite(LoadPin, LOW);
    shiftOut(DataPin, ClockPin, MSBFIRST, INTENSITY_REG);
    shiftOut(DataPin, ClockPin, MSBFIRST, 0);
    digitalWrite(LoadPin, HIGH);
  for (byte row=0; row<8; row++){
    digitalWrite(LoadPin, LOW);
    shiftOut(DataPin, ClockPin, MSBFIRST, row+1);
    shiftOut(DataPin, ClockPin, MSBFIRST, (currentblack[row]));
    digitalWrite(LoadPin, HIGH);
  }
}

void whiteupdate() {
  digitalWrite(LoadPin, LOW);
    shiftOut(DataPin, ClockPin, MSBFIRST, INTENSITY_REG);
    shiftOut(DataPin, ClockPin, MSBFIRST, 15);
    digitalWrite(LoadPin, HIGH);
  for (byte row=0; row<8; row++){
    digitalWrite(LoadPin, LOW);
    shiftOut(DataPin, ClockPin, MSBFIRST, row+1);
    shiftOut(DataPin, ClockPin, MSBFIRST, (currentwhite[row]));
    digitalWrite(LoadPin, HIGH);
  }
}

void loop() {
  Serial.print("A");
  Serial.println(millis());
  blackupdate();
  Serial.print("B");
  Serial.println(millis());
  whiteupdate();
  delay(5);
  Serial.print("C");
  Serial.println(millis());  
} 

И последовательный вывод был следующим:

A1
B3
C10
A10
B12
C19
A19
B21
C28
A28
B30
C37
A37
B39
C47
A47
B49
C56
A56
B59
C65
A66
B68
C75
A75
B77
C84
A84
B87
C94
A94
B96
C105
A105
B112
C123
A123
B131
C142
A143
B150
C161
A161
B168
C180
A180
B187
C198
A198
B205
C217
A218
B225
C236
A236
B243
C254
A254
B262
C273
A274
B281
C292
A292
B300
C311
A311
B318
C329
A329
B336
C348
A349
B356
C367
A367
B374
C386
A386
B393
C404
A404
B412
C422
A423
B431
C442
A442
B449
C460
A460
B467
C479
A480
B487
C498
A498
B505
C517
A517
B524
C535
A535
B542
C553
A555
B562
C573
A573
B580
C591
A591
B599
C610
A611
B618
C629
A629
B636
C648
A648
B655
C666
A666
B673
C685
A686
B693
C704
A704
B711
C722
A722
B730
C741

, 👍-1

Обсуждение

Вы пытаетесь реализовать две разные яркости для каждого светодиода. Я думаю, проблема в том, что частота обновления MAX7219 и частота обновления вашего кода Arduino не синхронизированы, что вызывает некоторые различия в яркости. Кроме того, вы устанавливаете максимальную яркость MAX7219 перед обновлением данных пикселей, что на короткое время приведет к тому, что «черные» пиксели станут намного ярче. Я бы переместил первые 4 строки в whiteupdate в конец функции. PS вам нужно выполнить digitalWrite(LoadPin, LOW);...;digitalWrite(LoadPin, HIGH); один раз для каждой функции. Не нужно делать это 9x., @Gerben

Я попытался поставить функцию интенсивности в конце функции, но это ничего не изменило. Даже если черные светодиоды какое-то время горят ярко, для выполнения всей функции требуется всего 2 миллисекунды, поэтому они не должны быть видны. Не могли бы вы пояснить, что вы имеете в виду, говоря, что два устройства не синхронизированы?, @stochastic13

Разве нам не нужно было бы фиксировать данные, каждый раз устанавливая нагрузочный контакт на высокий уровень? В противном случае данные просто выводились бы через вывод Dout?, @stochastic13

Max7219 обновляет дисплей с частотой около 800 Гц. Ваш код обновляет данные дисплея около 100 Гц. Но не совсем. Таким образом, в идеале максимум должен мультиплексировать каждый столбец 8 раз между каждым обновлением. Но если он немного медленнее, он мог бы сделать последний столбец только 7 раз. Что сделало бы его менее ярким., @Gerben

Но тогда весь черный набор неизменно мерцает независимо от положения., @stochastic13


3 ответа


0

Настройка оборудования непонятна. Например, у вас две матрицы или одна? В любом случае эффект черного обновления() остается намного короче, чем эффект белого обновления() из-за задержки, вставленной в основной цикл.

,

Одна матрица. И я согласен, но функции по-прежнему работают с очень высокой частотой и должны быть неразличимы на глаз. Только среднее должно быть видно, верно?, @stochastic13

Паттерн белого обновления ненадолго прерывается паттерном черного цвета. Это мерцание, которое вы видите. Вы можете проверить это, закомментировав один из шаблонов. MCU ISS делает то, что хочет ваш код. Что вы хотите, чтобы ваш код делал?, @dannyf

Вижу мерцают только блэкобновленные светодиоды. Если прерывания были проблемой, обновленные белые светодиоды должны мигать, верно?, @stochastic13

Белые светодиоды, вероятно, слишком яркие, чтобы увидеть их мерцание., @Gerben


0

Вы правы, обновление происходит с частотой около 100 Гц. Подсказка находится в последовательном выводе:

A1
B3  <<
C10 <<
A10
B12 <<
C19 <<
A19
B21 <<
C28 <<
A28
B30 <<
C37 <<
A37

Всегда существует большой разрыв между чтением ms между B и C. Это связано с задержкой после whiteupdate().

void loop() {
    Serial.print("A");
    Serial.println(millis());
    blackupdate();
    Serial.print("B");
    Serial.println(millis());
    whiteupdate();
    delay(5);    // <-- DELAY HERE
    Serial.print("C");
    Serial.println(millis());  
} 

Между blackupdate() и whiteupdate() нет обновления, поэтому даже если 5 мс — это граница того, что могут определить ваши глаза, из-за повторяющийся узор и постоянство зрения, ваши глаза это замечают.

Вы обнаружите, что ваше мерцание исчезнет, если вы разделите задержку, чтобы у вас была равная задержка между вашими blackupdate()->whiteupdate() и whiteupdate()->blackupdate().

void loop() {
    Serial.print("A");
    Serial.println(millis());
    blackupdate();
    delay(2);    // <-- DELAY HERE
    Serial.print("B");
    Serial.println(millis());
    whiteupdate();
    delay(2);    // <-- DELAY HERE
    Serial.print("C");
    Serial.println(millis());  
} 

Удаление последовательных строк отладки дает вам:

void loop() {
    blackupdate();
    delay(2);
    whiteupdate();
    delay(2);
} 
,

Я пытался это сделать. Я все еще обнаружил, что светодиоды мерцают. Я установил обе задержки на задержку (10)., @stochastic13


0

Возможно, здесь работает еще и физиология. Замечали ли вы мерцание, когда пристально смотрели на один светодиод или осматривали область проекта («сканируя» глазами)? Если вы просканируете свое зрение мимо мерцающего светодиода, даже если он мерцает со скоростью, превышающей наше восприятие, вы увидите полосу точек, пересекающую ваше зрение, в то время как постоянно горящий светодиод образовал бы сплошную полосу. Я заметил его, когда ехал ночью, когда светодиодные задние фонари были еще новыми и необычными. Эти автомобили выделялись тем, что их задние фонари оставляли в моем поле зрения один и тот же след из точек (хотя некоторые люди говорили мне, что не видят этого явления или не знают о нем...).

,