7 ноября 2013 г.

LED матрица

Я захотел поиграть со светодиодной матрицей, но в интернете нашёл довольно мало информации и примеров именно с программной частью, есть описание матрицы,  немного про мультиплексирование и много туториалов для Arduino.


Светодиодная матрица это просто много светодиодов которые представляют таблицу.
Чтобы зажечь выделенный светодиод нужно подать + на R2 и - на C3. Таким образом можно зажечь любой светодиод или группу светодиодов в 1 столбце или ряду. Если попытаться зажечь светодиоды в разных рядах и колоннах одновременно, то загорятся и другие светодиоды. К примеру если вместе с нашим красным светодиодом зажечь тот что в левом нижнем углу R6 - C0 то загорятся еще 2 R6 C3 и R2 C0.

Но есть еще и другие схемы подключения где используется меньше ножек МК к примеру "Чарлиплексинг" "Charlieplexing" которую предложил Charlie Allen. Статья на вики

Как видно с 3 ногами можно зажечь 6 светодиодов, с 10 => 90. Используя N ног можно зажечь N^2 - N светодиодов. Есть еще и другие способы подключения.

Смысл работы матрицы такой, нужно быстро включать и выключать каждый столбец или строку последовательно зажигая там необходимые светодиоды, нашему глазу будет казаться что они не мигают а горят постоянно.



                               

Окей, теперь электроника. Ножка МК не выдерживает ток для питания нескольких светодиодов, пока я эксперементировал  сжёг PORTD у ATmega32. Для решения проблемы есть несколько решений, использовать транзисторы или регистры сдвига. Я лишь хотел заставить его работать, так что я решил что у меня будет гореть только 1 светодиод в такт.

Нужно пройти каждый светодиод отдельно и зажечь его если нужно на 0.3 мс, затем потушить. Получается что МК не зажигает больше чем 1 светодиод значит ничего не сгорит, но минус в том что программная часть сложнее и требуется больше памяти.

Вот что у меня получилось


#include <avr/io.h>
#include <util/delay.h>

int main()
{
 DDRD=0xFF; 
 DDRA=0xFF; 

 int fps = 8;
 int pic = 0;
 int frames = 0;

 PORTA = 0b11111011; // GND
 PORTD = 0b00000001;

 int matrix[8][60] = {
 {0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,1,1,1,1,1,0,1,1,0,0,0,1,1},
 {0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0,1,1,1,0,0,1,1,0,0,1,1,0},
 {0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,1,1,0,0,1,1,0,0,1,1,1,1,1,1,0,0,0,1,0,0,0,1,1,0,1,1,0,0},
 {0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,1,1,0,0,0,0,1,1,0,1,1,1,1,1,1,0,0,0,1,0,0,0,1,1,1,1,0,0,0},
 {0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,0,0,0,1,0,0,0,1,1,1,1,0,0,0},
 {0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,0,0,0,1,0,0,0,1,1,0,1,1,0,0},
 {0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,1,1,1,0,0,1,1,0,0,1,1,0},
 {0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,1,1,1,0,0,0,0,0,1,1,0,1,1,1,1,1,0,1,1,0,0,0,1,1},
 };

 int matrix2[8][60] = {
 {0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,1,1,1,1,1,0,1,1,0,0,0,1,1},
 {0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0,1,1,1,0,0,1,1,0,0,1,1,0},
 {0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,1,1,0,0,1,1,0,0,1,1,1,1,1,1,0,0,0,1,0,0,0,1,1,0,1,1,0,0},
 {0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,1,1,0,0,0,0,1,1,0,1,1,1,1,1,1,0,0,0,1,0,0,0,1,1,1,1,0,0,0},
 {0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,0,0,0,1,0,0,0,1,1,1,1,0,0,0},
 {0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,0,0,0,1,0,0,0,1,1,0,1,1,0,0},
 {0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,1,1,1,0,0,0,0,0,1,1,0,0,1,1,1,0,0,1,1,0,0,1,1,0},
 {0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,0,1,1,1,0,0,0,0,0,1,1,0,1,1,1,1,1,0,1,1,0,0,0,1,1},
 };

 while(1)
 {
  pic++;
  if(pic >= fps) 
  {
   pic = 0;
   frames++;
   
   for(int n = 0; n < 8; n++)
   {
    for(int k = 0; k < 59; k++)
    {
     if(k != 58) matrix[n][k] = matrix[n][k+1];
     else matrix[n][k] = 0;
    }
   }
  }

  if(frames >= 60)
  {
   for(int n = 0; n < 8; n++)
   {
    for(int k = 0; k < 59; k++)
    {
     matrix[n][k] = matrix2[n][k];
     frames = 0;
    }
   }
  }

  for(int row = 0; row < 8; row++)
  {
   PORTD = (1 << row); // so PORTC = 0,1,2,4 VCC

   for(int col = 0; col < 8; col++)
   {         
    PORTA ^= (matrix[row][col] << col);
    _delay_ms(0.3);
    PORTA = 0xFF;
   }
  }
 } 
}

Код не идеален, вообщем есть массив где храниться строка, через определённое время все столбцы строки сдвигаются влево, когда строка дойдет до конца, всё начнётся заново.

Информация отсюда:
easyelectronics.ru
poprobotics

Комментариев нет :

Отправить комментарий