Максимално опростен Ардуино проект за управление на 16 светодиода с ATmega8

(базирано на Arduino ISP и ATmega8)

След успеха ми с програмирането на ATmega8 с помощта на Arduino Nano като ISP се зачудих за бърз и лесен проект, който да опитам да направя с негова помощ. В резултат се получи описания в този туториал.

Описание.

Използва се Arduino Nano като ISP и с него се програмира ATmega8, който управлява 16 светодиода чрез мултиплексиране. Добавени са и 2 потенциометъра - с единия се избира светлинния ефект (в програмта са реализирани до 8) а с другия се настройва неговата скорост.

Ръководство.

Схемата е пределно опростена както се вижда на приложената картинка.

(цъкни за по-голям размер)

Светодиодите са свързани директно като дори нямат токоограничаващи резистори. Чрез мултиплексиране само с 8 пина се управляват 16 светодиода. Управляващата програма по подобие на схемата също е елементарна.

/*
диодите са свързани директно към микроконтролера без токоограничаващи резистори
свързването е кръстосано 4х4 за общо 16 диода
програмата е за 8 режима като максималния общ брой стъпки зависи от наличната памет
избор на режим и задаване на скорост се извършва чрез 2 съответстващи потенциометъра
*/

#include <avr/pgmspace.h>

const byte LEDpin [] =
{
  0, 1, 2, 3,
  5, 6, 7, 8
};
// пинове свързани към светодиодите мултиплексирано 4 анода към 4 катода

const byte speedPin = 4;
const byte modePin = 5;
// 2 линейни потенциометъра от 1k до 100k всеки - не е необходимо да са еднакви само за предпочитане е да са линейни

byte ml [] PROGMEM =
{
  40, 40, 34, 2, 32, 137, 32, 21,

  B00000000, B00000000, B10000000, B00000001, B01000000, B00000010, B00100000, B00000100,
  B00010000, B00001000, B00001000, B00010000, B00000100, B00100000, B00000010, B01000000,
  B00000001, B10000000, B10000001, B10000001, B01000001, B10000010, B00100001, B10000100,
  B00010001, B10001000, B00001001, B10010000, B00000101, B10100000, B00000011, B11000000,
  B10000011, B11000001, B01000011, B11000010, B00100011, B11000100, B00010011, B11001000,
  B00001011, B11010000, B00000111, B11100000, B10000111, B11100001, B01000111, B11100010,
  B00100111, B11100100, B00010111, B11101000, B00001111, B11110000, B10001111, B11110001,
  B01001111, B11110010, B00101111, B11110100, B00011111, B11111000, B00011111, B11111000,
  B10011111, B11111001, B01011111, B11111010, B00111111, B11111100, B10111111, B11111101,
  B01111111, B11111110, B11111111, B11111111, B00000000, B00000000, B11111111, B11111111,

  B00000000, B00000000, B10000000, B00000000, B11000000, B00000000, B11100000, B00000000,
  B11110000, B00000000, B01111000, B00000000, B00111100, B00000000, B00011110, B00000000,
  B00001111, B00000000, B00000111, B10000000, B00000011, B11000000, B00000001, B11100000,
  B00000000, B11110000, B00000000, B01111000, B00000000, B00111100, B00000000, B00011110,
  B00000000, B00001111, B00000000, B00000111, B00000000, B00000011, B00000000, B00000001,
  B00000000, B00000000, B00000000, B00000001, B00000000, B00000011, B00000000, B00000111,
  B00000000, B00001111, B00000000, B00011110, B00000000, B00111100, B00000000, B01111000,
  B00000000, B11110000, B00000001, B11100000, B00000011, B11000000, B00000111, B10000000,
  B00001111, B00000000, B00011110, B00000000, B00111100, B00000000, B01111000, B00000000,
  B11110000, B00000000, B11100000, B00000000, B11000000, B00000000, B10000000, B00000000,

  B00000000, B00000000, B10000000, B00000000, B01000000, B00000000, B00100000, B00000000,
  B00010000, B00000000, B00001000, B00000000, B00000100, B00000000, B00000010, B00000000,
  B00000001, B00000000, B00000000, B10000000, B00000000, B01000000, B00000000, B00100000,
  B00000000, B00010000, B00000000, B00001000, B00000000, B00000100, B00000000, B00000010,
  B00000000, B00000001, B00000000, B00000000, B00000000, B00000001, B00000000, B00000010,
  B00000000, B00000100, B00000000, B00001000, B00000000, B00010000, B00000000, B00100000,
  B00000000, B01000000, B00000000, B10000000, B00000001, B00000000, B00000010, B00000000,
  B00000100, B00000000, B00001000, B00000000, B00010000, B00000000, B00100000, B00000000,
  B01000000, B00000000, B10000000, B00000000,

  B10101010, B01010101, B01010101, B10101010,

  B00000000, B00000000, B00000000, B00000001, B00000000, B00000000, B10000000, B00000000,
  B00000000, B00000000, B00000000, B00000010, B00000000, B00000000, B01000000, B00000000,
  B00000000, B00000000, B00000000, B00000100, B00000000, B00000000, B00100000, B00000000,
  B00000000, B00000000, B00000000, B00001000, B00000000, B00000000, B00010000, B00000000,
  B00000000, B00000000, B00000000, B00010000, B00000000, B00000000, B00001000, B00000000,
  B00000000, B00000000, B00000000, B00100000, B00000000, B00000000, B00000100, B00000000,
  B00000000, B00000000, B00000000, B01000000, B00000000, B00000000, B00000010, B00000000,
  B00000000, B00000000, B00000000, B10000000, B00000000, B00000000, B00000001, B00000000,

  B00000000, B00000000, B10000000, B00000000, B01000000, B00000000, B00100000, B00000000,
  B00010000, B00000000, B00001000, B00000000, B00000100, B00000000, B00000010, B00000000,
  B00000001, B00000000, B00000000, B10000000, B00000000, B01000000, B00000000, B00100000,
  B00000000, B00010000, B00000000, B00001000, B00000000, B00000100, B00000000, B00000010,
  B00000000, B00000001, B00000000, B00000011, B00000000, B00000110, B00000000, B00001100,
  B00000000, B00011000, B00000000, B00110000, B00000000, B01100000, B00000000, B11000000,
  B00000001, B10000000, B00000011, B00000000, B00000110, B00000000, B00001100, B00000000,
  B00011000, B00000000, B00110000, B00000000, B01100000, B00000000, B11000000, B00000000,
  B11100000, B00000000, B01110000, B00000000, B00111000, B00000000, B00011100, B00000000,
  B00001110, B00000000, B00000111, B00000000, B00000011, B10000000, B00000001, B11000000,
  B00000000, B11100000, B00000000, B01110000, B00000000, B00111000, B00000000, B00011100,
  B00000000, B00001110, B00000000, B00000111, B00000000, B00001111, B00000000, B00011110,
  B00000000, B00111100, B00000000, B01111000, B00000000, B11110000, B00000001, B11100000,
  B00000011, B11000000, B00000111, B10000000, B00001111, B00000000, B00011110, B00000000,
  B00111100, B00000000, B01111000, B00000000, B11110000, B00000000, B11111000, B00000000,
  B01111100, B00000000, B00111110, B00000000, B00011111, B00000000, B00001111, B10000000,
  B00000111, B11000000, B00000011, B11100000, B00000001, B11110000, B00000000, B11111000,
  B00000000, B01111100, B00000000, B00111110, B00000000, B00011111, B00000000, B00111111,
  B00000000, B01111110, B00000000, B11111100, B00000001, B11111000, B00000011, B11110000,
  B00000111, B11100000, B00001111, B11000000, B00011111, B10000000, B00111111, B00000000,
  B01111110, B00000000, B11111100, B00000000, B11111110, B00000000, B01111111, B00000000,
  B00111111, B10000000, B00011111, B11000000, B00001111, B11100000, B00000111, B11110000,
  B00000011, B11111000, B00000001, B11111100, B00000000, B11111110, B00000000, B01111111,
  B00000000, B11111111, B00000001, B11111110, B00000011, B11111100, B00000111, B11111000,
  B00001111, B11110000, B00011111, B11100000, B00111111, B11000000, B01111111, B10000000,
  B11111111, B00000000, B11111111, B10000000, B01111111, B11000000, B00111111, B11100000,
  B00011111, B11110000, B00001111, B11111000, B00000111, B11111100, B00000011, B11111110,
  B00000001, B11111111, B00000011, B11111111, B00000111, B11111110, B00001111, B11111100,
  B00011111, B11111000, B00111111, B11110000, B01111111, B11100000, B11111111, B11000000,
  B11111111, B11100000, B01111111, B11110000, B00111111, B11111000, B00011111, B11111100,
  B00001111, B11111110, B00000111, B11111111, B00001111, B11111111, B00011111, B11111110,
  B00111111, B11111100, B01111111, B11111000, B11111111, B11110000, B11111111, B11111000,
  B01111111, B11111100, B00111111, B11111110, B00011111, B11111111, B00111111, B11111111,
  B01111111, B11111110, B11111111, B11111100, B11111111, B11111110, B01111111, B11111111,
  B11111111, B11111111,

  B00000000, B00000000, B10000000, B00000001, B11000000, B00000011, B11100000, B00000111,
  B11110000, B00001111, B11111000, B00011111, B11111100, B00111111, B11111110, B01111111,
  B11111111, B11111111, B01111111, B11111110, B00111111, B11111100, B00011111, B11111000,
  B00001111, B11110000, B00000111, B11100000, B00000011, B11000000, B00000001, B10000000,
  B00000000, B00000000, B00000001, B10000000, B00000011, B11000000, B00000111, B11100000,
  B00001111, B11110000, B00011111, B11111000, B00111111, B11111100, B01111111, B11111110,
  B11111111, B11111111, B11111110, B01111111, B11111100, B00111111, B11111000, B00011111,
  B11110000, B00001111, B11100000, B00000111, B11000000, B00000011, B10000000, B00000001,

  B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000,
  B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000,
  B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000,
  B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000,
  B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000, B00000000,
  B11111111, B11111111
};

byte A;
byte C;

void setup ()
{
  for ( byte n = 0; n < 8; n ++ )
  {
    pinMode ( LEDpin [ n ], OUTPUT );
  }
}

void loop ()
{
  byte mode = modeRead ();
  byte L = pgm_read_byte ( & ( ml [ mode ] ) );
  word S = 8;
  if ( mode )
  {
    for ( byte n = 0; n < mode; n ++ ) // изчислява началното отместване за избрания режим
    {
      S += 2 * pgm_read_byte ( & ( ml [ n ] ) );
    }
  }
  for ( byte n = 0; n < L; n ++ ) // изрежда всички елементи на избрания режим
  {
    word spd = 2 + analogRead ( speedPin ); // минимална скорост около 1 стъпка за над 1 секунда
    if ( mode - modeRead () ) break; // проверява за промяна на режима
    word matrix = pgm_read_byte ( & ( ml [ S + 2 * n ] ) ) << 8 | pgm_read_byte ( & ( ml [ S + 2 * n + 1 ] ) );
    for ( word frame = 0; frame < spd; frame ++ ) // брой обхождания в зависимост от избраната скорост
    {
      for ( byte LED = 0; LED < 16; LED ++ ) // изреждане на светодиодите
      {
        boolean RC = bitRead ( matrix, LED );
        A = LED / 4;
        C = 4 + LED % 4;
        digitalWrite ( LEDpin [ A ], RC );
        digitalWrite ( LEDpin [ C ], !RC );
        delayMicroseconds ( 32 );
        digitalWrite ( LEDpin [ A ], LOW );
        digitalWrite ( LEDpin [ C ], HIGH );
      }
    }
  }
}

byte modeRead ()
{
  return analogRead ( modePin ) / 128; // 8 режима
}

Програмата е голяма но причината са описаните светлинни ефекти като самия изпълним код е малко. Използването на PGMSPACE позволява масива описващ светлинните ефекти да е доста голям защото се използва свободната програмна памет. Примерен резултат може да се види на приложения клип.

http://www.youtube.com/watch?v=7Lfu1XZ8VA8

Share