принцип динамической индикации

whoim
Offline
Зарегистрирован: 03.11.2011

Сел писать программу под атмегу + 8 штук 74hc595 и не могу вдуплить алгоритм.

Вот что накидал, но это неправильно: 

 //переменные состояния сдвиговых регистров
  byte anode_1 = B00000000; //переменная для регистра 1
  byte anode_2 = B00000000; //переменная для регистра 2
  byte cathode_3 = B00000000; //переменная для регистра 3
  byte cathode_4 = B00000000; //переменная для регистра 4
  byte cathode_5 = B00000000; //переменная для регистра 5
  byte cathode_6 = B00000000; //переменная для регистра 6
  byte cathode_7 = B00000000; //переменная для регистра 7
  byte cathode_8 = B00000000; //переменная для регистра 8

  for (byte x=0; x < _ROWS; x++) { //цикл по строкам
    for (byte y=0; y < _COLUMNS; y++) { //цикл по столбцам
      if (data[x][y] != 0) {//если элемент массива "включен"
          //задаем аноды
          if (x < 8) //определяем какой регистр анодов использовать
            anode_1 |= (1<<x);
          else
            anode_2 |= (1<<x-8);
          //задаем катоды
          if (y < 8)
            cathode_3 |= (1<<x);
          else if (y >= 8 && y < 16)
            cathode_4 |= (1<<x-8);
          else if (y >= 16 && y < 24)
            cathode_5 |= (1<<x-16);
          else if (y >= 24 && y < 32)
            cathode_6 |= (1<<x-24);
          else if (y >= 32 && y < 40)
            cathode_7 |= (1<<x-32);
          else if (y >= 40 && y < 48)
            cathode_8 |= (1<<x-40);
          }
    }
  }
  PORTB=|= (1<<0); //ставим LATCH pin_8 HIGH
  //shiftOut
  shiftOut2(cathode_8);
  shiftOut2(cathode_7);
  shiftOut2(cathode_6);
  shiftOut2(cathode_5);
  shiftOut2(cathode_4);
  shiftOut2(cathode_3);
  shiftOut2(anode_2);
  shiftOut2(anode_1);
  PORTB=|= (1<<0); //ставим LATCH pin_8 LOW
}

void shiftOut2(byte _byte) {
   for (byte i=0; i<8; i++) { //цикл по байту
    if (_byte & (1<<i)) {   //если бит 1
      PORTB |= (1<<3);  }   //ставим DATA pin_11 HIGH
    else {                  //если бит 0
      PORTB &= ~(1<<3); }    //ставим DATA pin_11 LOW
    PORTB |= (1<<4); //ставим CLOCK pin_12 HIGH
    PORTB &= ~(1<<4); //ставим CLOCK pin_12 LOW
   }
}

Когда говорят "частота развертки 500гц", имеют ввиду что ОДИН из множества светодиодов горит (в порядке очереди) 500 раз в секунду, то есть все светодиоды выстраиваются в очередь и зажигаются по одному в каждом цикле таймера, или за один вызов таймера должен протететь цикл по всем светодиодам и потрогать их?

Если последнее - то почему в примераз задержку не рисуют?

Дайте в опщем простой примерчик, разберем вместе подетально?

whoim
Offline
Зарегистрирован: 03.11.2011

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

whoim
Offline
Зарегистрирован: 03.11.2011

 Так будет правильно? Внутри всех циклов:

1) обнуляем все биты регистров
2) если в текущей позиции светодиод горит, составляем содержимое этих битов для отсылки в регистры, при этом "горит" только этот элемент (определяем катод и анод)

//процедура динамической индикации
void timer2() {
  for (byte x=0; x < _ROWS; x++) { //цикл по строкам
    for (byte y=0; y < _COLUMNS; y++) { //цикл по столбцам
    
      //переменные состояния сдвиговых регистров
      byte anode_1 = B00000000; //переменная для регистра 1
      byte anode_2 = B00000000; //переменная для регистра 2
      byte cathode_3 = B00000000; //переменная для регистра 3
      byte cathode_4 = B00000000; //переменная для регистра 4
      byte cathode_5 = B00000000; //переменная для регистра 5
      byte cathode_6 = B00000000; //переменная для регистра 6
      byte cathode_7 = B00000000; //переменная для регистра 7
      byte cathode_8 = B00000000; //переменная для регистра 8
    
      if (data[x][y] != 0) {//если элемент массива "включен"
    
          //задаем аноды
          if (x < 8) //определяем какой регистр анодов использовать
            anode_1 |= (1<<x);
          else
            anode_2 |= (1<<x-8);
          //задаем катоды
          if (y < 8)
            cathode_3 |= (1<<x);
          else if (y >= 8 && y < 16)
            cathode_4 |= (1<<x-8);
          else if (y >= 16 && y < 24)
            cathode_5 |= (1<<x-16);
          else if (y >= 24 && y < 32)
            cathode_6 |= (1<<x-24);
          else if (y >= 32 && y < 40)
            cathode_7 |= (1<<x-32);
          else if (y >= 40 && y < 48)
            cathode_8 |= (1<<x-40);
        }
         PORTB=|= (1<<0); //ставим LATCH pin_8 HIGH
        //зажигаем
        shiftOut2(cathode_8);
        shiftOut2(cathode_7);
        shiftOut2(cathode_6);
        shiftOut2(cathode_5);
        shiftOut2(cathode_4);
        shiftOut2(cathode_3);
        shiftOut2(anode_2);
        shiftOut2(anode_1);
        PORTB=|= (1<<0); //ставим LATCH pin_8 LOW
    }
  }
}

вопрос:  нужна ли задержка горения? умпеет ли МК обработать эти два цикла и вывод в регистры 500 раз в секунду?
Может, нужно пойти другим путем - завести глобальные переменные, текущая позиция в массиве, увеличивать их по мере нужды и обнулять, то есть добиться того что при вызове таймера обработается только один цикл (и один светодиод) - короче загорится следующий в очереди?

whoim
Offline
Зарегистрирован: 03.11.2011

 В общем то, натаскался я прилично. Вопрос решил, но.. низка яркость. У меня 16 строк, скважность 16 к одному - низкая. Хреново, через пару недель выставка в марселе.. блеать..

Немного помогает ликвидация резисторов с ленты. Как еще можно увеличить ток на светодиоды? Напряжение же тут как я понимаю не при чем..

Пока без таймера, ибо нах он нужен

/***************************
* LED RGB controller       *
* atmega328 & 8pcs 74hc595 *
* by whoim@mail.ru         *
****************************/

//74hc595 wiring
//Pin connected to ST_CP of 74HC595
#define _latch 8
#define _latchPORTB _latch - 8
//Pin connected to SH_CP of 74HC595
#define _clock 12
#define _clockPORTB _clock - 8
//Pin connected to DS of 74HC595
#define _data 11
#define _dataPORTB _data - 8

//прочее
#define _ROWS 16 //число строк в матрице (аноды)
#define _COLUMNS 48 //число столбцов в матрице (катоды)
byte data[_ROWS][_COLUMNS]; //массив состояния светодиодов для вывода

//настройки при запуске
void setup() { 
  //установка портов
  pinMode(_latch, OUTPUT);
  digitalWrite(_latch, LOW);
  pinMode(_clock, OUTPUT);
  digitalWrite(_clock, LOW);
  pinMode(_data, OUTPUT);
  digitalWrite(_data, LOW);
  //
  data[0][0] = 0x01;
  data[0][1] = 0x01;
}

//цикл главной программы
void loop() {

  //цикл по строкам (аноды)
  for (int x=0; x<_ROWS; x++) {
    byte registers[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //обнуляем регистры
    //задаем нужный анод
    if(x < 8) bitSet(registers[0], x);
    else bitSet(registers[1], x-8);
    //цикл по столбцам (катоды)
    for (int y=0; y < _COLUMNS; y++) {
        if (data[x][y] == 0x01) {
          //задаем катоды  
          if (y < 8) bitSet(registers[2], y);
          else if (y>=8 && y<16) bitSet(registers[3], y-8);
          else if (y>=16 && y<24) bitSet(registers[4], y-16);
          else if (y>=24 && y<32) bitSet(registers[5], y-24);
          else if (y>=32 && y<40) bitSet(registers[6], y-32);
          else if (y>=40 && y<48) bitSet(registers[7], y-40);
        }
    }

        //shiftOut
        bitClear(PORTB,_latchPORTB);
        shiftOutFast(_data,_clock,registers[7]);
        shiftOutFast(_data,_clock,registers[6]);
        shiftOutFast(_data,_clock,registers[5]);
        shiftOutFast(_data,_clock,registers[4]);
        shiftOutFast(_data,_clock,registers[3]);
        shiftOutFast(_data,_clock,registers[2]);
        shiftOutFast(_data,_clock,registers[0]);
        shiftOutFast(_data,_clock,registers[1]);
        bitSet(PORTB,_latchPORTB);
   }
}

void shiftOutFast(int my_data, int my_clock, byte myDataOut) {
  bitClear(PORTB,_dataPORTB);
  for (int i=7; i>=0; i--)  {
    bitClear(PORTB,_clockPORTB);
    if ( bitRead(myDataOut,i) == 1)
      bitSet(PORTB,_dataPORTB);
    else
      bitClear(PORTB,_dataPORTB);
    bitSet(PORTB,_clockPORTB);
    bitClear(PORTB,_clockPORTB);
  }
  digitalWrite(my_clock, 0);
}

 

Zaliv
Offline
Зарегистрирован: 05.03.2011

 Код впечатляющий. Я только не пойму это подключается 500 поштучных светодиодов или какая-то светодиодная панель? или это продолжение темы про подсветку макета, кстати, очень интересная тема. Зачитываюсь. :)

whoim
Offline
Зарегистрирован: 03.11.2011

 да, в продолжение.. или в окончание..

Светодиоды - липкие ленты, по три RGB диода в каждой (секции). Логически выглядит как один светодиод.. Секций может быть несколько объединено в одну, но суть не меняется - на схеме один светодиод..

Таких секций больше 250.

Впечатляющего в коде мало. Слабо горят сцуко, что же делать... повесится чтоли.. что ж я раньше то не почитал про скважность?

Volumetr
Offline
Зарегистрирован: 09.01.2012

whoim пишет:

 Немного помогает ликвидация резисторов с ленты. Как еще можно увеличить ток на светодиоды? Напряжение же тут как я понимаю не при чем..

Думаю придётся на каждый выход микросхемы ставить по транзисторному ключу и в зависимости от мощьности транзистора управлять нагрузкой более чем может позволить себе микросхема 74hc595. Да, на каждую микросхему нужно 8 транзисторов. 5 микросхем. Ну думаю как-то так возможно...

whoim
Offline
Зарегистрирован: 03.11.2011

 Да ключи то стоят, хоть 100 вольт 5 ампер гони. Мосфеты.

Вольтаж поднял до 18в, резисторы десантировал. Поприятнее но думаю еще придется.

Косяк в том что пока софт без таймера. А без таймера в момент например Serial.read может чутка программый шим подзависнуть, и попрут все вольты через мосфет на светодиод, а ему и резистора то даже не дали, прикрыться то..

whoim
Offline
Зарегистрирован: 03.11.2011

 8 микросхем кстати. Думаете отчего я шифтаут и латч так жестко дергаю?)

whoim
Offline
Зарегистрирован: 03.11.2011

24 вольта ей в задницу, резисторы нелльзя снимать - можно парралелить уменьшим до 50-60 ом, но и все..
В поисках БП в общем.

whoim
Offline
Зарегистрирован: 03.11.2011

Электролиты на мосфетах решили проблему с яркостью. Одну ногу на выход мосфета, вторую на питание (плюс или минус - зависит от мосфета, P или N) 

whoim
Offline
Зарегистрирован: 03.11.2011

Электролиты в задницу - из за них горят другие светодиоды )))

24 вольта и не снимая резисторов с лент - работает вполне.

barada
Offline
Зарегистрирован: 25.11.2013

интересная ветка, мне тоже предстоит подобный проект.