TLC5940 czyli co najmniej 16 dodatkowych pinów PWM w Arduino

TLC5940 to układ scalony zawierający 16 wyjść PWM. Generator PWM układu ma rozdzielczość 12 bitów czyli 4096 stopni wypełnienia. Jedną z głównych zalet tego chipu jest możliwość podłączenia do jego wyjść bezpośrednio diod LED (bez rezystorów). Jego wyjścia mogą wytrzymać do 120 mA obciążenia.

Wyprowadzenia układu TLC5940

OUT0..OUT15 – 16 wyjść PWM generatorów układu. Wyjścia są typu “otwarty kolektor” czyli przewodzą albo stan niski, albo stan nieustalony. Wyjścia można obciążać maksymalnie od 5 do 120 mA. Prąd wyjść reguluje się za pomocą wyprowadzenia IREF i/lub specjalnych rejestrów “DC” układu.

VPRG – Wejście trybu programowania układu – podłączasz do GND w Arduino.
Stan niski to programowanie rejestrów wypełnienia PWM (GS), stan wysoki to programowanie rejestrów korekcji prądu wyjść (DC).

SIN – Wejście szeregowe  – podłączasz do pinu cyfrowego 11 w Arduino UNO

SCLK – Wejście szeregowe zegara zatwierdzającego bity danych – podłączasz do pinu cyfrowego 13 w Arduino UNO

XLAT – Wejście zatwierdzające wysłane dane – podłączasz do pinu cyfrowego 9 w Arduino UNO

BLANK – Wejście wyłączania wyjść i resetowania liczników generatora PWM – podłączasz do pinu cyfrowego 10 w Arduino UNO

GND – Wejście zasilania masa – podłączasz do GND w Arduino

VCC – Wejście zasilania +5 V – podłączasz do pinu zasilania 5V w Arduino

IREF – Wejście ustalania prądu na wyjściach OUT. Do wejścia podłączasz rezystor o oporze dostosowanym do prądu wyjścia, gdzie druga noga rezystora jest podłączona do GND.

Prąd wyjścia oblicza się ze wzoru:

Imax = (Vref / Rref) * 31,5 = (1.24 / Rref) * 31,5

Rref = Wartość oporu rezystora podłączonego między IREF i GND.

Przyjmując, że diody LED wymagają prądu 20 mA, to rezystor powinien mieć wartość 2 KOhm.

DCPRG – Wejście wybierania danych dokładnej regulacji prądu wyjścia – podłączasz do +5V

GSCLK – Wejście zegara, którego impulsy powodują zliczanie przez liczniki generatorów PWM układu – podłączasz do pinu cyfrowego 3 w Arduino UNO

SOUT – Szeregowe wyjście danych z układu. W konfiguracji wielu układów złączonych szeregowo to wyjście jest podłączone do SIN następnego układu.

XERR  – Wyjście błędów układu. Jeśli układ się przegrzeje, lub jakaś dioda LED podłączona do wyjść generatora PWM się przepali, na wyjściu pojawią się impulsy stanu niskiego. Wyjście jest typu “otwarty dren”, co powoduje, że ma albo stan niski, albo nieustalony.

Podłączenie układu TLC5940 do Arduino

Schemat przedstawia sposób podłączenia układu do Arduino. Połączenie zabiera 5 cyfrowych pinów Arduino. Do wyjść od OUT0 do OUT15 można podłączyć bezpośrednio diody LED, katodą do OUT, anodą do 5V (pod warunkiem zastosowania odpowiedniego rezystora IREF). W przykładzie podłączyłem diodę LED do wyjścia OUT1.

Noga TLC5940

Pin Arduino

Nazwa sygnału

Checklista

27

GND

VPRG

26

Digital 11

SIN

25

Digital 13

SCLK

24

Digital 9

XLAT

23

Digital 10

BLANK

22

GND

GND

21

5V

VCC

20

–Rezystor–GND

IREF

19

5V

DCPRG

18

Digital 3

GSCLK

17

do drugiego TLC5940

SOUT

16

XERR

 

 

Podłączenie do Arduino MEGA

Ponieważ Arduino MEGA ma wyjście SPI w nieco innym miejscu, podłączenie do niego TLC5940 wymaga innego schematu elektrycznego.

Noga TLC5940

Pin Arduino MEGA

Nazwa sygnału

Checklista

27

GND

VPRG

26

Digital 51

SIN

25

Digital 52

SCLK

24

Digital 11

XLAT

23

Digital 12

BLANK

22

GND

GND

21

5V

VCC

20

–Rezystor–GND

IREF

19

5V

DCPRG

18

Digital 9

GSCLK

17

do drugiego TLC5940

SOUT

16

XERR

 

 

Programowanie układu TLC5940

 

#include <Tlc5940.h>

void setup()
{
  Tlc.init();

  Tlc.set(1, 2048);

  while (Tlc.update());
}

void loop()
{
}

 

Społeczność Arduino napisała również dla układu TLC5940 odpowiednią bibliotekę. Przykład zapala diodę LED podłączoną do wyjścia OUT1 na połowę jasności.

 

Programowanie układu rozpoczyna się od załadowania odpowiedniej biblioteki poprzez “#include <Tlc5940.h>”. Następnie w funkcji “setup” biblioteka musi zostać zainicjowana za pomocą metody “Tlc.init();”. Metodę “Tlc.update()” umieściłem w pętli “while”. Metoda ta odpowiada za wysłanie danych do do układu i zaktualizowanie jego rejestrów. Trzeba wywoływać ja tak długo aż zwróci wartość 0. Jeśli nie jest to krytyczne, możesz umieścić też tą metodę w funkcji “loop”.

 

Za ustawianie poszczególnych wyjść PWM układu TLC5940 odpowiada metoda “Tlc.set”. Jej pierwszym parametrem jest numer wyjścia od 0 do 15, a drugim wartość wypełnienia generatora PWM od 0 do 4095.

 

Bibioteka wykorzystuje do swojej pracy układy Timer1 i Timer2 oraz SPI kontrolera Arduino, dlatego warto uważać, czy nie koliduje to z inną biblioteką w twoim projekcie.

 

Metody obiektu Tlc:

  • Tlc.init() Uaktywnia działanie biblioteki i inicjuje komunikacje z układem TLC5940. Ma opcjonalny argument, który jest liczbą od 0 do 4095. Argument ustawia początkową wartość wypełnienia na wszystkich wyjściach układu. Wywołanie metody bez argumentu sprawia, że wyjścia ustawiają się na 0.
  • Tlc.clear() Ustawia wszystkie wyjścia na wartość 0.
  • Tlc.setAll(value) Ustawia wszystkie wyjścia na wartość wypełnienia podaną w argumencie (od 0 do 4095).

     

  • Tlc.set(out, value) Ustawia wyjście określone w argumencie “out” (od 0 do 15) na wartość określoną w argumencie “value” (od 0 do 4095).
  • Tlc.get(out) Zwraca wartość wypełnienia dla wyjścia podanego w argumencie “out” (od 0 do 15).
  • Tlc.update() Wysyła dane do układu. Zwraca 0 jeśli dane zostaną zatwierdzone lub 1 jeśli jeszcze nie.

 

Wskaźnik diodowy

#include <Tlc5940.h>

void tlc_progress(word value, word prefix)
{
  byte out_num = value / 4096;
  word out_brg = value % 4096;

  for (byte out=0; out<16; out++)
  {
    if (out < out_num)
    {
      Tlc.set(out, prefix);
    }

    else if (out == out_num)
    {
      Tlc.set(out, out_brg);
    }

    else
    {
      Tlc.set(out, 0);
    }
  }
}

void setup()
{
  Tlc.init();
}

void loop()
{
  int value = analogRead(0);
  value = map(value, 0, 1023, 0, 65535);
  tlc_progress(value, 4095);
  Tlc.update();
}

Jako temat przykładu użycia biblioteki wykorzystałem pomysł na wskaźnik typu “linijka diodowa”. Zakłada on podłączenie do wszystkich pinów OUT układu TLC5940 diod LED. Działanie wskaźnika można opisać w ten sposób, że im program dostanie większe napięcie na pin Arduino Analog 0 tym więcej diod na kolejnych wyjściach się będzie świeciło. Przy napięciu 5V świecą się wszystkie diody. Dodatkową zaletą wykorzystania PWM jest to, że ostatnia zapalona dioda wskaźnika zapala się stopniowo wraz ze wzrostem napięcia na wejściu.


Najważniejszą funkcją programu jest “tlc_progress”. Steruje ona zapalaniem diod podłączonych do układu. Jej pierwszy arguement to wartość od 0 do 65535. Im większa liczba tym kolejne diody wskaźnika się płynnie zapalają. Kolejnym argumentem funkcji jest argument jasności świecenia lampek poprzedzających ostatnią zapaloną. Jeśli ustawisz mu wartość 0, to będzie paliła się na raz tylko jedna dioda – imitując wskazówkę.

 

Jeśli wstawisz tam wartość maksymalną, czyli 4095, to będą zapalały się kolejne diody aż do maksymalnej jasności.

 

W funkcji “loop” program odczytuje wartość z pinu Analog 0. Ponieważ funkcja “analogRead” odczytuje wartości z zakresu od 0 do 1023, to trzeba je przeskalować za pomocą funkcji “map” na wartości zakresu funkcji “tlc_progress”, czyli od 0 do 65535.


Wskaźnik diodowy ma zastosowanie tam, gdzie nie liczy się zbytnia dokładność, ale ważne jest szybkie zorientowanie się co do poziomu jakiegoś sygnału. Program możesz łatwo przerobić na fajny “analogowy” termometr, obrotomierz lub wskaźnik poziomu głośności w zestawie audio.

W nagraniu do wejścia analogowego 0 podłączyłem potencjometr.

Inne przykłady z biblioteki układu

Oprócz podstawowego nagłówka “Tlc5940.h”, biblioteka posiada jeszcze kilka ciekawych nagłówków z dodatkowymi funkcjami pomagającymi szybko rozwiązać pewne pomysły.

Fades

Pierwszym z nich jest “tlc_fades.h”, ułatwiający tworzenie płynnie zapalających się i gasnących efektów świetlnych.

#include <Tlc5940.h>
#include <tlc_fades.h>

void setup()
{
  Tlc.init();

  tlc_addFade(1, 0, 4095, 5000, 10000);
}

void loop()
{
  tlc_updateFades();
}

Użycie biblioteki rozpoczynasz od dodania nagłówka “#include <tlc_fades.h>”. Potem należy normalnie zainicjować układ w funkcji “setup”. W funkcji “loop” powinna być funkcja “tlc_updateFades();” odpowiedzialna za synchronizowanie działania całej biblioteki.

Za przygotowanie zapalania/gaśnięcia odpowiada funkcja “tlc_addFade”. Jej pierwszym argumentem jest numer wyjścia układu TLC5940 na którym ma się odbyć animacja. Kolejnym jest wartość początkowa jasności animacji (od 0 do 4095). Trzecim argumentem jest wartość końcowa jasności animacji o parametrach jak poprzednia.

Dwa ostatnie argumenty to czas w milisekundach liczony od chwili włączenia Arduino. Przedostatni mówi o tym w jakiej milisekundzie ma się rozpocząć animacja, a kolejny w jakiej ma się skończyć.

Funkcja w przykładzie tworzy animacje zapalenia się diody na wyjściu “OUT1” od wartości 0 do wartości 4095. Rozświetlenie ma się odbyć w czasie od 5 do 10 sekundy od chwili włączenia Arduino.

Można wykonać do 24 animacji na raz (wywołań funkcji “tlc_addFade”). Potem trzeba poczekać, aż któraś animacja się skończy. Pomocną przy tym funkcją jest “tlc_isFading”. Jej argumentem jest numer wyjścia, a zwraca 1 jeśli na danym wyjściu jest przewidziana jakaś animacja lub 0 jeśli nie jest.

Jest jeszcze funkcja “tlc_removeFades”. Jej argumentem jest numer wyjścia. Usuwa ona wszystkie animacje dla danego wyjścia.

#include <Tlc5940.h>
#include <tlc_fades.h>

void setup()
{
  Tlc.init();
}

void loop()
{
  if (!tlc_isFading(1))
  {
    unsigned long time = millis();
    tlc_addFade(1, 0, 4095, time+1000, time+1250);
    tlc_addFade(1, 4095, 0, time+1500, time+2000);
  }
  tlc_updateFades();
}

W tym przykładzie zrealizowałem animację mrugania diody LED na wyjściu OUT1. Warunek “if” sprawdza czy jest tam aktualnie animacja i jeśli nie ma to tworzy kolejną.

Animacja powstaje tak, że pobierany jest aktualny czas do zmiennej “time”. Sekundę po tym czasie rozpoczyna się rozświetlanie trwające 250 ms. Po 1.5 s zaczyna się gaśnięcie trwające 500 ms. Daje to ładny efekt płynnego mrugania.


Funkcja “tlc_updateFades” ma opcjonalny argument, którym są aktualne milisekundy. Jeśli nie odpowiada ci w animacji czas od chwili włączenia Arduino, możesz w argumencie dostarczyć swoją aktualną wartość czasu wyrażoną w milisekundach.

Shifts

Biblioteka “tlc_shifts.h” odpowiada za efekt przesuwania wartości wypełnienia z jednego wyjścia na kolejne.

#include <Tlc5940.h>
#include <tlc_shifts.h>

void setup()
{
  Tlc.init();
}

void loop()
{
  static byte counter = 0;
  if (counter % 4)
    tlc_shiftUp(0);

  else
    tlc_shiftUp(4095);

  counter++;
  Tlc.update();
  delay(100);
}

Przykład tworzy efekt “wąż świetlny”, który polega na złudzeniu, że światło w diodach ustawionych w linię pełza.


Funkcja “tlc_shiftUp” powoduje zapisanie do wyjścia OUT0 nowej wartości wypełnienia, podanej w argumencie, podczas gdy reszta wartości jest przesuwana do kolejnych wyjść (z OUT0 do OUT1, z OUT1 do OUT2 itp.). Ostatnia wartość, która była w rejestrze wypełnienia OUT15 jest zwracana przez tą funkcję (ułatwia to zapętlanie).


Jest też odwrotnie działająca funkcja o nazwie “tlc_shiftDown”, której argument zapisuje wartość wypełnienia do OUT15 i przesuwa wartości rejestrów w dół (z OUT15 do OUT14, z OUT14 do OUT13 itp.). Zwraca ona wartość rejestru OUT0 przed przesunięciem.


Dane z pamięci programu

Czasem zachodzi potrzeba przeniesienia na wyjścia PWM jakiś danych z pamięci. Kontroler AVR w Arduino ma kilka pamięci z których najbardziej pojemna jest pamięć Flash, gdzie przechowywany jest program. Pamięć RAM jest kilka razy mniej pojemna, dlatego najlepiej przechowuje się w niej aktualne zmienne, a nie tablice ze stałymi danymi. Dlatego autorzy biblioteki układu TLC5940 zadbali o możliwość współpracy z pamięcią programu.

#include <Tlc5940.h>
#include <tlc_progmem_utils.h>

byte pwm_data[24] PROGMEM = {
  GS_DUO(4095, 3839), GS_DUO(3583, 3327), GS_DUO(3071, 2815), GS_DUO(2559, 2303), 
  GS_DUO(2047, 1791), GS_DUO(1535, 1279), GS_DUO(1023, 767), GS_DUO(511, 255)
};

void setup()
{
  Tlc.init();

  tlc_setGSfromProgmem(pwm_data);

  while (Tlc.update());
}

void loop()
{
}

Biblioteka “tlc_progmem_utils.h” zawiera narzędzia do obsługi danych z pamięci programu.

Aby przygotować tablice wartości wypełnienia dla rejestrów PWM układu, trzeba ją zadeklarować w odpowiedni sposób. oprócz standardowego określenia typu “byte”, nazwy tablicy “pwm_data” i jej rozmiaru, trzeba jeszcze dodać odpowiednią dyrektywę informującą, że tablica ma być przechowywana w pamięci programu a nie w normalnej pamięci RAM. Ta dyrektywa to “PROGMEM”. Rozmiar tablicy określony jest przez ilość danych potrzebnych do zaprogramowania układu. Wynika on z tego, że układ potrzebuje szesnastu 12 bitowych wartości. W języku C nie ma typu, który by przechowywał dokładnie 12 bitowe wartości. Jest albo 16 bitowy “word”, albo 8 bitowy “byte”. Aby nie było niepotrzebnych strat danych biblioteka używa 8 bitowego “byte”. 24 elementy tablicy typu “byte” wynikają z tego, że 16×12 bitów /  8 (typ byte) = 24. Tablica jest poukładana od ostatniego rejestru GS OUT15 do pierwszego GS OUT0.

Aby było łatwiej układać dane, w bibliotece jest makro o nazwie GS_DUO, które ma dwa argumenty reprezentujące kolejne 2 wyjścia PWM (OUT15, OUT14 aż do OUT1, OUT0).

Wysłaniem danych z tablicy zajmuje się funkcja “tlc_setGSfromProgmem”. Jej argumentem jest nazwa tablicy z danymi do wyświetlenia.

Animacje z pamięci programu

Jeśli chciałbyś wysyłać do układu TLC5940 sekwencje danych np. w postaci animacji lub danych do wyświetlacza widmowego, możesz skorzystać z biblioteki “tlc_animations.h”, która działa podobnie do poprzedniej.

#include <Tlc5940.h>
#include <tlc_animations.h>

byte pwm_data[24*2] PROGMEM = {
  GS_DUO(4095, 0), GS_DUO(4095, 0), GS_DUO(4095, 0), GS_DUO(4095, 0), 
  GS_DUO(4095, 0), GS_DUO(4095, 0), GS_DUO(4095, 0), GS_DUO(4095, 0), 

  GS_DUO(0, 4095), GS_DUO(0, 4095), GS_DUO(0, 4095), GS_DUO(0, 4095), 
  GS_DUO(0, 4095), GS_DUO(0, 4095), GS_DUO(0, 4095), GS_DUO(0, 4095)
};

void setup()
{
  Tlc.init();
}

void loop()
{
  if (!tlc_onUpdateFinished)
  {
    tlc_playAnimation(pwm_data, 2, 500);
  }
}

Tym razem wielkość tablicy “pwm_data” musi być pomnożona o liczbę klatek animacji. W tym przykładzie stworzyłem 2 klatki animacji. Pierwsza klatka to maksymalne świecenie diod wyjść nieparzystych, a druga to maksymalne świecenie diod parzystych. Klatki rozdzieliłem pustą linia.


Za uruchomienie animacji odpowiada funkcja “tlc_playAnimation”. Jej pierwszy argument to tablica z danymi animacji, drugi to liczba klatek animacji, a ostatni to czas po jakim mają się wyświetlać kolejne klatki animacji. Czas jest wyrażony w cyklach licznika PWM, a jeden cykl trwa 1,024 ms. Zatem 500 oznacza, że klatki będą pojawiać się co około pół sekundy.


Ponieważ funkcja “tlc_playAnimation” nie zapętla animacji, dlatego po wyświetleniu ostatniej klatki animacji trzeba ją uruchamiać ponownie. Zmienna “tlc_onUpdateFinished” zwraca 0 jeśli animacja się skończyła i 1 jeśli wciąż trwa. Dlatego zastosowałem ją w “if” do zapętlania animacji.

Korekcja prądu wyjść układu TLC5940

Jeśli podłączasz do wyjść układu TLC5940 różnokolorowe diody LED, często ich światło nie jest jednakowo jasne. Można to ustawić tworząc skomplikowane wzory przeliczające wartość rejestru wypełnienia i ograniczając rozdzielczość kanałów PWM. Ten układ ma jednak dodatkowy sprzęt, który pomoże dokonać korekty jasność.

Rejestry DC (Dot Correct) odpowiadają za dokładniejszą regulację prądu na wyjściach PWM. Ich rozdzielczość jest 6 bitowa, czyli przyjmują wartości od 0 do 63. Dzielą one wartość maksymalnego prądu na wyjściu ustalanego przez rezystor na wejściu IREF.

Aby dobrać się do rejestrów DC należy dokonać drobnej zmiany w układzie elektrycznym i bibliotece programu.


Na schemacie dodałem kolejny przewód do cyfrowego pinu Arduino. Przewód prowadzi od wejścia VPRG (noga 27 układu TLC5940) do pinu cyfrowego 8 w Arduino. W Arduino MEGA należy podłączyć ten sygnał do cyfrowego pinu 50.


Potem w katalogu biblioteki układu znajdź plik “tlc_config.h”, który odpowiada za ustawianie parametrów biblioteki i znajdz w nim definicję “#define VPRG_ENABLED 0” i zmień na “#define VPRG_ENABLED 1”. Uaktywni to dodatkowe elementy biblioteki odpowiedzialne za rejestry DC.

#include <Tlc5940.h>
#include <tlc_progmem_utils.h>

byte DC_data[12] PROGMEM = {
  DC_QUARTET(3, 3, 3, 3), DC_QUARTET(3, 3, 3, 3), 
  DC_QUARTET(14, 14, 14, 14), DC_QUARTET(14, 14, 14, 14)
};

void setup()
{
  Tlc.init(4095);

  tlc_setDCfromProgmem(DC_data);

  while (Tlc.update());
}

void loop()
{
}

Rejestry najłatwiej obsługiwać za pomocą biblioteki “tlc_progmem_utils.h”.

Ustawianie rejestrów DC wygląda podobnie do opisywanej wcześniej funkcji ustawiania rejestrów wypełnienia z pamięci programu Flash. W tym przypadku potrzebna jest tablica w pamięci programu zawierająca 12 elementów typu “byte”. Do łatwego ustawiania poszczególnych rejestrów potrzebne są makra “DC_QUARTET”, które mają po 4 argumenty, reprezentujące poszczególne wyjścia w odwrotnej kolejności. Do ustawienia wszystkich rejestrów potrzeba czterech makr.

Za zapisanie danych z tablicy do układu TLC5940 odpowiada funkcja “tlc_setDCfromProgmem”, której jedynym argumentem jest nazwa tablicy z danymi rejestrów DC.

W przykładzie miałem do wyjść OUT0 – OUT7 podłączone diody zielone i do wyjść OUT8 – OUT15 diody czerwone. Diody czerwone były bardzo jaskrawe i dużo jaśniejsze od zielonych, dlatego dostały wartość 3, a diody zielone, mniej jaskrawe wartość 14.

Wszystko dlatego ma tak niskie wartości, aby nie raziło, a jednocześnie świeciło na tyle jasno by widzieć dokładnie które diody świecą.

Sterowanie serwomechanizmem

Jak dowidziałeś się z poprzedniego wpisu, kąt obrotu serwomechanizmu zależy od szerokości impulsu PWM. Do układu TLC5940 możesz też podłączyć 16 serwomechanizmów.


Wyjścia układu TLC 5940 są typu “otwarty kolektor” i przekazują tylko albo stan niski, albo nieustalony. Dlatego aby wysterować wejście sterujące sewomechanizmu, trzeba podłączyć rezystor PullUp. Rezystor ten wg. dokumentacji biblioteki powinien mieć od 2k do 5k Ohm.

#include <Tlc5940.h>

#define SERVO_MIN_WIDTH 177
#define SERVO_MAX_WIDTH 571

#include <tlc_servos.h>

void setup()
{
  tlc_initServos();
}

void loop()
{
  int value = analogRead(0);
  value = map(value, 0, 1023, 0, 180);

  tlc_setServo(1, value);
  Tlc.update();
}

Do używania serwomechanizmów przez układ służy specjalna biblioteka “tlc_servos.h”. Ponieważ biblioteka ma ustawione dość bezpieczne czasy minimalnego i maksymalnego impulsu serwomechanizmu, dlatego przed załadowaniem biblioteki trzeba zdefiniować własne ich czasy w makrach “SERVO_MIN_WIDTH” i “SERVO_MAX_WIDTH”. Wartości te są wyrażone w liczbie czasu wypełnienia w rejestrze PWM czyli od 0 do 4095. Pierwsza wartość wypełnienia jest przy serwie ustawionym na 0 stopni, a druga na 180 stopni. Czas wypełnienia dla 1000 mikrosekund to 204. Moje serwomechanizmy (HTX900) mają zakres od 870 do 2800 mikrosekund, dlatego dałem im wartości wypełnienia od 177 do 571. Wartości te można obliczyć ze wzoru:

GSvalue = czas_impulsu_us * 204 / 1000

W funkcji “setup” biblioteka wymaga wywołania funkcji “tlc_initServos();”, której opcjonalny argument to kąt obrotu serw podłączonych do wyjść.

Serwomechanizmy ustawia się za pomocą funkcji “tlc_setServo”, której pierwszym argumentem jest numer wyjścia, do którego podłączone jest serwo, a drugim kąt obrotu jego osi.

Na końcu należy oczywiście zatwierdzić wysłanie danych do układu za pomocą metody “Tlc.update();”

Dane do serwomechanizmu można też przekazywać za pomocą metody “Tlc.set”, pamiętając by nie przekraczać minimalnego i maksymalnego impulsu. Zanim poda się parametr wypełnienia dla tej metody, trzeba go odjąć od liczby 4095 (“Tlc.set(4095-imp_width);”).

Korzystając z biblioteki serwomechanizmów, do można do wyjść podłączyć też inne elementy, pamiętając o tym, że teraz generują impulsy z częstotliwością 50 Hz.

Program w przykładzie odczytuje wartość z wejścia analogowego i po przeskalowaniu ustawia oś serwomechanizmu proporcjonalnie do napięcia na wejściu.

UWAGA:

Biblioteka wymaga drobnej poprawki, gdyż wynik zakresu impulsu moich serwomechanizmów wywołał w niej błąd. W katalogu biblioteki w pliku “tlc_servos.h” funkcja “tlc_angleToVal” powinna wyglądać tak:

/** Converts and angle (0 - SERVO_MAX_ANGLE) to the inverted tlc channel value
    (4095 - 0). */
uint16_t tlc_angleToVal(uint8_t angle)
{
    return 4095 - SERVO_MIN_WIDTH - (
            ((uint32_t) (angle) * (uint16_t)(SERVO_MAX_WIDTH - SERVO_MIN_WIDTH))
            / SERVO_MAX_ANGLE);
}

Sterowanie silnikiem


Silnikiem elektrycznym steruje się jak w poprzednim wpisie za pomocą tranzystora MOSFET. Pamiętając oczywiście o zapewnieniu rezystora PullUp na wyjściu układu TLC5940.

#include <Tlc5940.h>

void setup()
{
  Tlc.init();
}

void loop()
{
  int value = analogRead(0);
  value = map(value, 0, 1023, 0, 4095);

  Tlc.set(1, value);
  Tlc.update();
}

Przykład nie różni się od poprzednich, nie wymaga specjalnej biblioteki. Steruje prędkością silnika w zależności od napięcia na analogowym wejściu 0 w Arduino, skalując wartość do poziomu zakresu wartości rejestru wypełnienia GS.

Łączenie wielu układów TLC5940


Aby zyskać kolejne wyjścia PWM należy podłączyć kolejny układ TLC5940. Nie trzeba do tego wykorzystywać żadnych dodatkowych pinów Arduino. Kolejne układy podłączamy tak samo jak ten pierwszy, przekazując kolejnym te same sygnały z jednym wyjątkiem. Sygnał SIN (noga 26) następnego układu łączysz z sygnałem SOUT (noga 17) poprzedniego. W ten sposób zyskujesz kolejne 16 wyjść PWM. Układów możesz tak łączyć dowolną ilość pamiętając, że przesadne ilości wymagają więcej modyfikacji w bibliotece sterującej.


Aby program mógł skorzystać z dodatkowych układów należy otworzyć plik z katalogu biblioteki o nazwie “tlc_config.h”. Jest w nim zdefiniowane makro “#define NUM_TLCS 1”. Liczba za nazwą odpowiada liczbie podłączonych układów TLC5940. W moim przypadku będzie to “#define NUM_TLCS 2”.

#include <Tlc5940.h>

void setup()
{
  Tlc.init();

  Tlc.set(1, 2048);
  Tlc.set(17, 2048);

  while (Tlc.update());
}

void loop()
{
}

W programie sterującym układami prawie nic się nie zmienia. Różnica polega tylko na tym, że kolejne wyjścia mają kolejne numery. Zatem czerwona dioda LED podłączona do OUT1 pierwszego układu ma numer 1, a zielona dioda LED podłączona do wyjścia OUT1 drugiego układu ma numer 17. Jest to bardzo proste rozwiązanie.


Podobnie jest z innymi elementami biblioteki układu. W każdej ilość wyjść zwiększa się o wielokrotność układów. Biblioteki korzystające z pamięci Flash muszą mieć powiększone tablice do ilości wyjść układów.

Zakończenie

TLC5940 to bardzo ciekawy układ scalony. Jego możliwości w połączeniu z Arduino są bardzo duże. Dzięki niemu możesz robić kroczące roboty, na których mięśnie składa się kilkanaście serwomechanizmów, lub zaskakujące efekty świetlne na przyszłoroczną choinkę. Zdecydowanie najciekawszym efektem jaki można zrobić przy pomocy tych układów jest wyświetlacz widmowy. Nie chciałem odbierać ci tej przygody i dlatego postaraj się zrealizować go sam :-). Tylko pamiętaj o solidnym przymocowaniu LED-ów najlepiej na płytce uniwersalnej.


Linki