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.
Artykuły są coraz lepsze, gratulacje za dogłębne przedstawienie tematu.
Oczywiście będę dociekliwy:
1. Jak rozumiem z lakonicznej wzmianki na Playground, maksymalna liczba wyjść przy połączeniu układów to 640?
2. Jaka jest maksymalna bezpieczna ilość diod możliwych do sterowania przez ten sterownik z zasilaniem bezpośrednio z Arduino, bez konieczności dodawania osobnego źródła napięcia i/lub tranzystorów etc.?
Odpowiem w formie FAQ
Q: Od czego zależy maksymalna ilość wyjść?
A: Układ tlc5940 bez hackowania działa tak, że wysyłasz mu 4096 impulsów przez wejście GSCLK. Taktują one liczniki generatorów PWM.
Po wysłaniu tylu impusów trzeba zresetować liczniki przez impuls na wejście BLANK.
To co opisałem wyżej nazywam cyklem generatorów PWM.
Układ tlc5940 pobiera dane przez synchroniczną magistralę szeregową na wejściach SIN i SCLK. Do zaprogramowania układu trzeba przez nią wysłać 192 bity. Po ich wysłaniu zatwierdza się dane przez impuls na wejściu XLAT.
Te dwie rzeczy działają tak, że jeśli chcesz zmienić wypełnienie na wyjściach, to na raz działa taktowanie liczników PWM i wysyłane są dane.
Gdy cykl licznika dobiegnie końca na raz generowane są impulsy BLANK i XLAT. Robi się to w ten sposób, że najpierw narasta zbocze sygnału BLANK, potem narasta XLAT, potem opada zbocze XLAT i po tym opada dopiero zbocze BLANK.
Gdy podłączasz więcej układów TLC, to trzeba wysłać im w cyklu generatora PWM odpowiednio więcej danych zanim się je zatwierdzi przez XLAT. 2 układy to już 384 bity.
Ograniczeniem liczby wyjść jest to, aby zmieścić się z wysłaniem danych do wszystkich układów, zanim skończy się cykl PWM.
Aby znieść to ograniczenie, można spowolnić cykl PWM (zmniejszyć taktowanie GSCLK), lub przyspieszyć wysyłanie danych przez magistrale szeregową.
Magistrala szeregowa SPI w Arduino ustawiona jest przez bibliotekę TLC na maksa czyli na CLK/2. CLK to szybkośc zegara taktującego AVR w Arduino czyli 16 MHz. Czyli wysyła 8 Mbitów/s.
W pliku „tlc_config.h” są zdefiniowane makra regulujące szybkośc taktowania liczników PWM.
TLC_PWM_PERIOD ustawia dzielnik taktowania ze wzoru
czestotliwosc_pwm = CLK / (2 * TLC_PWM_PERIOD)
gdzie CLK to częstotliwośc zegara Arduino.
Co dla domyślnej wartości (8192) daje 976.5625 Hz.
Czas trwania cyklu PWM dla takiej częstotliwości to
1 / czestotliwosc_pwm = 1 / 976,5625 = 0,001024 s
W takim czasie można przesłać
8 Mb/s * 0,001024 = 8192 bity
Co teoretycznie daje
8192 bity / 192 bity = 42 układy
42 uklady * 16 wyjść = 672 wyjscia
Czyli wynik podawany w dokumentacji biblioteki na stronie Arduino.
Jak widzisz możesz spowolnić generatory PWM zwiększając wartośc TLC_PWM_PERIOD i podłączać więcej układów.
Jeśli sterujesz silnikami to częstotliwośc generatorów musi być dość duża, żeby nie szarpały. Natomiast jeśli sterujesz diodami, to częstotliwośc musi być na tyle duża, żeby człowiek nie zauważał mrugania (minimum 25 Hz) i zeby poświata którą widać podczas ruchu urządzenia lub obserwatora nie była zbyt uciążliwa.
Od wartości TLC_PWM_PERIOD, zależy też druga wartość TLC_GSCLK_PERIOD
Oblicza się ją ze wzoru
TLC_GSCLK_PERIOD = (2 * TLC_PWM_PERIOD) / 4096 – 1
Domyślnie 3
Maksymalne częstotliwości dla układu TLC to 30 MHz.
Opis tych makr jest tu http://alex.kathack.com/codes/tlc5940arduino/html_r014/tlc__config_8h.html#bb206b2da1542dfeb3e0387869b1d8b7
Q: Jaka jest maksymalna bezpieczna ilość diod możliwych do sterowania przez ten
sterownik z zasilaniem bezpośrednio z Arduino?
A: Wyjście 5V w Arduino wytrzymuje do 500 mA. Każda dioda to 20 mA. Co daje teoretycznie 25 ledów. Ta wartość zależy od portu USB i jest raczej maksymalna. W każdym razie u mnie podłączenie 16 (320 mA) nie powodowało przeciążeń (komputer stacjonarny, Arduino podłączone przez HUB w klawiaturze).
Jeśli zasilasz Arduino z zasilacza, to ograniczeniem wyjścia 5V jest stabilizator na płytce Arduino – nie może się przegrzać (podobno max to 800 mA).
Podłączyłem wszystko jak trzeba, jednak diody zapalają się tylko do OUT11, kombinowałem na różne sposoby jednak nie udało się uruchomić nic podpiętego pod OUT{12,13,14,15}. Jakieś pomysły?
Prześlij więcej informacji, źródło programu i fotkę układu to chętnie zobaczę czy wszystko jest OK :).
Bo teraz to co przychodzi mi do głowy to sprawdzenie polaryzacji LED-ów.
@sprae: dzięki za odpowiedź, przepraszam, że tak późno. Z szybkości reakcji i obszerności Twoich wypowiedzi wnioskuję, że opanowałeś zaawansowany multitasking i nie sypiasz, tylko czasem na krótki okres czasu przestajesz obsługiwać przerwania… :)
Haha. Dzięki.
Powiem tak. Mam dobrego zarządce procesów. Na szczęście jest w pełni software-owy ;-).
Mój zarządca procesów (i zasobów) kupił mi Arduino na imieniny, ale ostatnio – od momentu powiększenia rodziny o małe ATTiny – żadne z nas nie ma wolnego czasu procesora na zabawę uC :)
A z innej beczki, zastanawiam się, jak wyjść poza zakres 40 LEDów (800mA) z PWM. Nic poza osobnymi kontrolerami na SPI/I2C nie przychodzi mi do głowy… Ewentualnie kilka sztuk Arduino połączonych magistralą, każde z własnym zasilaniem i zestawem kilku TLC5940?
Jak używasz TLC to chyba wystarczy dodać lepszy zasilacz 5V do zasilania LEDów.
Witam. Mam pytanie dotyczace schematow polaczenia arduino z roznymi podzespolami. Moglbym sie dowiedziec w jakim programie mozna utworzyc taki schemat poniewaz potrzebuje ladna graficzna prezentacje schematu podlaczenia do prezentacji.
Fritzing:
http://fritzing.org/
W czym może leżeć problem: podłączyłem zgodnie z opisem serwo Tower Pro 995R i w trakcie ruchu szarpie (drga) ? Zasilam z osobnego zasilacza servo – domyślnie ma ich być 13(połączone masy zasilacz i arduino).
By trzeba zobaczyć jakimś oscyloskopem gdzie są zakłócenia. Mógłbyś powiedzieć jaką zasilacz ma moc? Może wystarczy podłączyć kondensator.
Zasilacz 200W firmy Fusion, 15A ograniczenie na max więc prądu nie ograniczam, ogólnie na arduino 2560 na sprzętowych PWM sterowanie przebiega bezproblemowo i szarpania nie ma (albo nagłych losowych delikatnych wychyleń)
U niego wydają się działać stabilnie http://bildr.org/2012/03/servos-tlc5940-arduino/
Może skorzystaj z jego programu źródłowego do testów. Ale wygląda na to, że opiera się na tej samej bibliotece.
Witam. Nie rozumiem do końca jakie maksymalne obciążenie prądowe jest w stanie znieść ten scalak. W artykule przeczytałem, że nie powinno być to więcej niż 120mA. Jednak na filmiku podłączone było 16 diod przy Iref=20mA. Daje to razem 320mA(zostało to wspomniane kilka postów wyżej). Czy w takim razie scalak był przeciążony? Czy może te 120mA to maksymalne natężenie prądu na jedno wyjście, i teoretycznie scalak może wytrzymać prawie 2A (120*16)?!
Pytam, bo wygląda na to, że spaliłem trzy połączone ze sobą scalaki. Nie reagują. I się mocno grzeją.
Robię matrycę RGB na wzór tego projektu:
http://solderlab.de/index.php/hardware/matrix-controller-board
z tą różnicą, że inne tranzystory użyłem
(http://www.irf.com/product-info/datasheets/data/irf9z24npbf.pdf)
ale koncepcję projektu zachowałem (zrobiłem jeszcze na płytce zasilanie ze stabilizatorem 7805).
Wydaje się wszystko ładnie działać, oprócz tych scalaków (czyli de facto matryca nie działa). Iref ustalone było na 40mA, czyli obciążyłem każdy scalak prądem 640mA (za dużo?).
Zasilam płytkę osobno, 7,5V 2A przerobione na 5V. Z Arduino jedynie steruję tymi scalakami i demultiplexerem.
120 mA dotyczy maksymalnego obciążenia jednego z wyjść. Zasilanie diod LED to maksymalnie 17 V.
I tu pojawia się problem. Bo ciepło bierze się z mocy [Watt]. Moc liczy się przez P = U * I czyli napięcie razy prąd.
Układ przy temperaturze otoczenia mniejszej niż 25 stopni Celsjusza może wytrzymać 2,456 W.
Moc wydzielana przez układ to suma mocy diod na wyjściach z mocą elementów wewnętrznych układu.
Układ pobiera normalnie 0,9 mA. Podczas transmisji danych prąd układu zwiększa się do 60 mA. Zatem sama logika w maksymalnym momencie wydziela:
P = U * I = 5 * 0.06 = 0.3 W
Do tego dochodzi moc zasilanych diod LED
P = U * I * ilość = 5 * 0.02 * 16 = 1.6 W
Co razem daje:
0.3 + 1.6 = 1.9 W
Czyli w moim układzie nie przekroczyłem pełnej mocy w szczytowym poborze prądu (wszystkie diody świecą z maksymalną jasnością i trwa transmisja).
Wydaje mi się, że ten układ trudno zepsuć. Ma on zabezpieczenie i gdy się przegrzeje (160 stopni) to wyłącza wyjścia LED i ustawia wyjście XERR w stan niski.
Powodzenia!
Dziękuję za wyczerpującą odpowiedź;)
Wygląda na to, że moc wydzielana na scalakach u mnie wyniosła 3,5 W. Trochę przegiąłem.
Scalaki niestety nie wytrzymały, ale już zamówiłem nowe, więc myślę, że niedługo matryca będzie działać.
Pozdrawiam ;)
Witam,
Mam pytanie, chciałbym wykorzystać ten układ do zrobienia sterownika schodów opartego na arduino.
W tym celu będę potrzebował podpiąć do niego 16 około metrowych taśm led zasilanych napięciem 12V.
Takie obciążenie przekracza wytrzymałość układu. W związku z tym prawdopodobnie będę musiał skorzystać z tranzystorów mosfet. Tylko pytanie jak je podłączyć? Bezpośrednie podłączenie bramki tranzystora do wyjścia układu niestety nie zadziała…
aogorek: Hej. W arcie jest przykład jak podłączyć silnik przez mosfet. Dla taśmy powinno być podobnie.
Układ ma wyjścia typu open collector/drain czyli musisz dać rezystor pullup o wartości prawdopodobnie 10 kOHm (chyba, że tranzystory będą za wolno reagować przez pojemność bramki – wtedy jakiś mniejszy).
Pozdrawiam i życzę udanego projektu :)
Dziękuję bardzo! Pierwsza próba udana :) muszę tylko jeszcze dobrze dobrać wartości rezystorów
Witam, próbuję uruchomić TLC5940 w języku BASCOM na ATmega32 i robię to według postu nr 1 na tej stronie: http://www.ledstyles.de/ftopic3773.html. Czy ta wersja będzie działał tak samo jak wersja z Arduino? A jeżeli nie, to co należałoby w niej (w wersji bascom) poprawić?
Za wszelką pomoc będę wdzięczny.
PS. Na marginesie dodam, że zaprogramowałem procek wersją z tego niemieckojęzycznego forum i mam bardzo duże spadki napięcia, dioda nie jest zasilana z 5V, tylko z 3,5V.
Z tym napięciem to chyba dobrze biorąc pod uwagę, że diody podłączasz bezpośrednio do wyjść układu :)
Co do programu to najważniejsze, żeby co 4096 taktów zegara na GSCLK zrobić impuls na BLANK, żeby zresetować liczniki PWM.
No tylko, że jak na diodzie jest 3,5V zamiast 5V no to nie świeci pełną mocą. Dodam, że podłączam też LED’a 12V poprzez tranzystor NPN i na LED’zie mam tylko 9V – dość duży spadek napięcia.
Co do taktów zegara GSCLK to jak szybko je generować – jaki ustawić prescaler licznika ATmegi?
No to zwróć uwagę na regulację prądu w rezystorze i rejestra CV h.
Co do częstotliwości to, żeby nie było widać mrugania, generator musi działać w okresie przynajmniej 25 Hz. Czyli traktowanie licznika generatora to przynajmniej 25 * 4096. Licznik wytrzymuje do 30 MHz.
O regulacji prądu w rezystorze czytałem, wzór znam, potrafię wykorzystać go (tak mi się przynajmniej wydaje). A czy mógłbyś mi powiedzieć coś więcej na temat tych rejestrów?
Rejestry opisałem w rozdziale „Korekcja prądu wyjść układu TLC5940”
Ich programowanie polega na tym, że noga VPRG scalaka kiedy jest w stanie niskim to, gdy wysyłasz dane idą one do rejestrów PWM. Gdy jest w stanie wysokim, dane które wysyłasz idą do rejestrów korekcji prądu. Trzeba pamiętać, że te rejestry mają 6 bitów.
Noga o nazwie DCPRG wybiera źródło wg którego ustawiony jest prąd wyjściowy. W stanie wysokim źródłem są rejestry korekcji prądu (domyślnie chyba ustawione są na maksymalny prąd jaki daje rezystor).
Rejestry opisałem w rozdziale „Korekcja prądu wyjść układu TLC5940”
Ich programowanie polega na tym, że noga VPRG scalaka kiedy jest w stanie niskim to, gdy wysyłasz dane idą one do rejestrów PWM. Gdy jest w stanie wysokim, dane które wysyłasz idą do rejestrów korekcji prądu. Trzeba pamiętać, że te rejestry mają 6 bitów.
Noga o nazwie DCPRG wybiera źródło wg którego ustawiony jest prąd wyjściowy. W stanie wysokim źródłem są rejestry korekcji prądu (domyślnie chyba ustawione są na maksymalny prąd jaki daje rezystor).
Ok, wszystko się powoli zaczyna układać w całość. Ale ciągle mam problem z uzyskaniem maksymalnego prądu. Tzn. podłączam moduł taśmy LED (3 diody z rezystorem) bezpośrednio do 12V to mierząc prąd wynosi on ok 17mA. Zasilając ten sam pasek LED z układu TLC5940 (przez tranzystor npn), to prąd mam na poziomie 14mA? Co się dzieje z tymi 3mA? Dodam, że z korekcji prądu nie korzystam i rezystor IREF ma wartość 2kohm, czyli dobraną na 20mA.
To może być kwestia prądu bazy i doboru rezystora, żeby maksymalnie wykorzystał stan nasycenia tranzystora.
Witam, chciałem zapytać w jaki sposób zmienić czas zapalania pojedynczej diody? Co i gdzie należy wpisać do programu, aby dioda rozświetlała się (od zera do pełnej mocy) np. w ciągu 15s?
Pozdrawiam
Jest to opisane w rozdziale Fades. Jednak jeśli go nie ogarniasz masz tu prosty przykład:
#include
void setup()
{
Tlc.init();
}
void loop()
{
for (word value=0; value<4095; value++)
{
Tlc.set(0, value);
Tlc.update();
delay(4);
}
}
Tu czas reguluje się za pomocą funkcji delay.
Opóźnienie oblicza się dzieląc czas w sekundach przez ilość kroków rozjaśniania czyli 4096.
15 / 4096 = 0,003662
Co daje w przybliżeniu 3,662 milisekundy, a po zaokrągleniu 4.
Przepraszam, brzydko się wkleiło.
Masz tu link do programu: https://gist.github.com/sprae/5291808
Ok, a jaki może być maksymalny czas rozjaśniania LED’a? Może to być np. 5 min? Czy drastyczne zwiększanie tego czasu nie wpłynie na częstotliwość PWM i czy nie będzie widoczne mruganie LED’a?
możesz rozjaśniać do 40 dni i nie ma to żadnego wpływu.
Domyślna częstotliwość PWM to około 900 Hz.
Z resztą jak chcesz rozjaśniać jednego LED-a, to możesz użyć wbudowanego PWM w Arduino.
Witam,
zaczynam zabawę z Arduino i chciałbym dowiedzieć się czy układ TLC5940 będzie dobrze współpracował z shield ethernet?
W końcu oba potrzebują sygnału SIN, SCLK i BLANK.
Można połączyć SIN od ethernet z SOUT na TLC5940, a SCLK i BLANK równolegle, jak tak to co należałoby zmienić w bibliotece?
SIN i SCLK mogą współpracować. Bo układ odbierze dane wysłane do niego dopiero po zatwierdzeniu przez XLAT.
Gorzej jest z sygnałem BLANK. On musi mieć impuls co 4096 taktów generatora. Biblioteka wykorzystuje do tego prawdopodobnie wyjście generatora 16 bitowego (automatycznie liczy do 4096 i puszcza impuls), które koliduje z Ethenret.
Jeśli mógłbym coś zaproponować łatwiejszego, to jest gotowa płytka adaptera z bardziej niezależnym generatorem PWM, który wymaga tylko podłączenia zasilania i sygnałów I2C.
http://nettigo.pl/products/380
czesc,
podlaczylem 6xTLC5940 (SPI) do sterowania przekaznikami (96sztuk).
Generalnie przekazniki sa LOW aktywne wiec aktywuja sie gdy dren otwarty ma maxa. Do rozwiazania jeszcze sprawa zasilania ale….
Do sterowania chcialem uzyc klawiatury poprzez MCP23017 (I2C) i prawie sukces ale…
przekazniki strasznie warcza bo przerywaja,
Czy zatem urzadzenia SPI oraz I2c moga pracowac razem?
Czy da sie ten problem rozwiazac jakimis kondensatorami?
dzieki.
Wydaje mi się, że tyle przekaźników nadmiernie obciąża zasilacz/przewody zasilające i dlatego warczą bo jest spadek napięcia. Przy takiej ilości przekaźników trzeba się mocno starać by gdzieś czegoś nie przeciążyć.
juz dziala. ale tylko do 5x tlc5940 przy szostym ulkad wariuje szczegolnie w polaczeniu z e sterowaniem z I2C oraz serial.monitor gdzie wyswielam stan przekaznikow. czy moze rozeiazaniem byloby dolozenie jakiegos kondensatora ale ja mysle ze moze pokombinowac z tlc.gsclk.period oraz tlc.pwm.period. czy moze to miec zwiazek z przeciazeniem zegara pracujecego jednoczesnie dla twi + I2C + serial.monitor????
Witam. Czy układ TLC5940 można podłączyć do każdego arduino? Mam Pro Micro i nie potrafię podpiąć do niej TLC. Może miał ktoś do czynienia z taką konfiguracją?
@Cane – a gdzie (które piny) podpinasz TLC do Micro? Micro ma procesor ATmega32u4, a opis jest dla UNO. Komunikacja Arduino <-> TLC jest tak naprawdę po SPI, a SPI jest na innych numerach pinów na Leonardo/Pro Micro.
Może to jest przyczyna?
Dzięki, wszystko działa. Jakby ktoś potrzebował podłączyć TLC5940 do Pro Micro (ATmega32u4)
Pro Micro TLC5940
sck (pin 15) – sclk (pin 25)
mosi (pin 16) – sin (pin 26)
D9 – xlat (pin 24)
D10 – blank (pin 23)
D5 – gsclk (pin 18)
Witam,
Potrzebuje 20 PWM. Niestety podłączenie do arduino zabiera piny 11,10,3,9 na których są pwm. Czy jest sposób aby wykorzystać 16 pwm tlc5940 i 4 z atmegi 328? Z góry dzięki.
Możesz w zamian użyć dwóch takich.
https://nettigo.pl/products/sto-kanalowy-sterownik-serwomechanizmow-z-interfejsem-i2c
Zabierają tylko 2 piny interfejsu I2C/TWI + zasilanie.
Witam. Czy ktoś wie jak powinien wyglądać taki program na mikrokontrolerze C8051F020 ? wystawiłem sobie już na porcie 0 SCK, MISO, MOSI i dodatkowy timer T1 do GSCLK.
witam, błagam pomózcie..
przy zaprogramowaniu TL5940NT wyskakuje mi ten blad :
Arduino:1.8.1 (Windows 10), Płytka:”Arduino/Genuino Uno”
C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\Przemek\Documents\Arduino\libraries -fqbn=arduino:avr:uno -ide-version=10801 -build-path C:\Users\Przemek\AppData\Local\Temp\arduino_build_17046 -warnings=none -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avrdude.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.arduinoOTA.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -verbose C:\Users\Przemek\Documents\Arduino\pojedynca_dioda_pwm\pojedynca_dioda_pwm.ino
C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\Przemek\Documents\Arduino\libraries -fqbn=arduino:avr:uno -ide-version=10801 -build-path C:\Users\Przemek\AppData\Local\Temp\arduino_build_17046 -warnings=none -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.avrdude.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -prefs=runtime.tools.arduinoOTA.path=C:\Program Files (x86)\Arduino\hardware\tools\avr -verbose C:\Users\Przemek\Documents\Arduino\pojedynca_dioda_pwm\pojedynca_dioda_pwm.ino
Using board 'uno’ from platform in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr
Using core 'arduino’ from platform in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr
Detecting libraries used…
„C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++” -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10801 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR „-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino” „-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard” „C:\Users\Przemek\AppData\Local\Temp\arduino_build_17046\sketch\pojedynca_dioda_pwm.ino.cpp” -o „nul”
„C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avr-g++” -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10801 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR „-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino” „-IC:\Program Files (x86)\Arduino\hardware\arduino\avr\variants\standard” „C:\Users\Przemek\AppData\Local\Temp\arduino_build_17046\sketch\pojedynca_dioda_pwm.ino.cpp” -o „C:\Users\Przemek\AppData\Local\Temp\arduino_build_17046\preproc\ctags_target_for_gcc_minus_e.cpp”
C:\Users\Przemek\Documents\Arduino\pojedynca_dioda_pwm\pojedynca_dioda_pwm.ino:1:21: fatal error: Tlc5940.h: No such file or directory
#include
^
compilation terminated.
exit status 1
Błąd kompilacji dla płytki Arduino/Genuino Uno.
(to byla wersja rozszezona)
teraz wersja bardziej czytelna :
Arduino:1.8.1 (Windows 10), Płytka:”Arduino/Genuino Uno”
C:\Users\Przemek\Documents\Arduino\pojedynca_dioda_pwm\pojedynca_dioda_pwm.ino:1:21: fatal error: Tlc5940.h: No such file or directory
#include
^
compilation terminated.
exit status 1
Błąd kompilacji dla płytki Arduino/Genuino Uno.
Ten raport powinien zawierać więcej informacji jeśli w
File -> Preferencje zostanie włączona opcja „Pokaż
szczegółowe informacje podczas kompilacji”.
jestem jeszcze stosunkowo zielony, dopiero sie uczę, ale kod byl skopiowany, powinien wejsc.
prosze o pomoc.
PS alternatywny kontakt to przemek.czarlin@wp.pl
Drodzy,
sam doszedłem do rozwiązania:) brakowało bibliotek TAK nie brałem pod uwagę, że trzeba dogrywać :) a jednak:)
pozdrawiam:)
Gratuluję :-)
Odnosnie przelozenia pinu BLANK (w Uno D10) na inny to trzeba dokonac zmian w bibliotece:
-w zaleznosci od nowego pina ustawic odpowiedni Timer, np D10 jest na innym Timerze niz np D5 (Timer0 zamiast Timer1)
-// skomentowac 'enable_XLAT_pulses()’ w TLC5940.h
-przeniesc reszte z linii #define set_XLAT_interrupt (): TIFR1 (te z timerem 1) bezposrednio do kodu pod Tlc.init();
-w plitku Tlc5940.cpp zrobisc softwerowy BLANK/XLAT w handlerze interrupt 'ISR(TIMER1_OVF_vect)’;
wykasowac linie ponizej komendy wysylajacej 4096 impulsow przez GSCLK, ktore aktywuja oryginalny BLANK puls i zastapic np.:
digital.write(5,HIGH);
digital.write(5,LOW);
D5 bedzie wtdy twoim nowym BLANK
pozdrawiam
Witam, czy ktoś próbował podłączyć ten scalak do ESP8266 ? Chciałbym poszerzyć ilość wyjść PWM właśnie tym scalakiem jednak biblioteki przeznaczone do arduino nie działają na wemos esp8266 mini pro.
Uważam, że łatwiej byłoby użyć któregoś z tych modułów:
https://nettigo.pl/products/sto-kanalowy-sterownik-serwomechanizmow-z-interfejsem-i2c
https://nettigo.pl/products/sterownik-serwomechanizmow-16-kanalow-i2c
Wymagają do podłączenia tylko 2 przewodów sterujących i zasilania.
Witam
Mam pytanie o IREF jaki prąd ustawić (i dlaczego akurat taki :) ) gdy do wyjścia podłączam n-mosfet IRL2203N.
Pozdrawiam.
Witam
Mam pytanko, do wyjść podłączam tranzystory n-mosfet IRL2203N . Jaki ustawić prąd (i dlaczego akurat taki :-) ).
Pozdrawiam.
Ten układ ma już wbudowane tranzystory w wyjścia. Można je obciążyć prądem do 120 mA lub napięciem do 17 V. Maksymalny prąd można regulować 6-bitowym rejestrem.
Rozumiem, że chciałbyś obciążyć układ bardziej, stąd chcesz zastosować własne tranzystory, większej mocy.
Wyjścia OUT0-OUT15 tego układu przypominają wyjście typu „open-drain”. W stanie niskim są podłączone do GND (przez ogranicznik prądu). W stanie wysokim nie są podłączone do niczego (tak jakbyś odciął zasilanie od przewodu).
Żeby sterować bramką (Gate) tranzystora IRL2203n musisz podłączyć do wyjść OUT układu PWM, rezystory w układzie PULLUP. Sprawią one, że w stanie wysokim na wyjściu będzie napięcie.
Użyłbym rezystora o wartości 1 kOhm. Napięcie jakie podłączysz do tego rezystora zależy od tego jakim prądem chcesz obciążyć twój tranzystor. Maksymalne napięcie między wyprowadzeniami bramki (Gate) i źródła (Source) to 16 V. Z wykresu obciążenia[A]/napięcia [Vgs] w dokumentacji tranzystora wynika, że tranzystor przepuszcza ponad 100 A już przy napięciu bramki ponad 3,5 V (o ile dobrze rozumiem ;-)).
Drugim elementem, który trzeba brać pod uwagę jest pojemność bramki tranzystora. Element sterujący tranzystorem, ma działanie przypominające kondensator. Czyli, żeby tranzystor zaczął przewodzić odpowiedni prąd, ten kondensator w nim musi się naładować. Powoduje to opóźnienia we włączaniu i wyłączaniu urządzenia, którym tranzystor ma sterować.
W przypadku szybkich sygnałów, takich jak PWM, pojemność tranzystora może wygładzić taki sygnał i sprawić, że urządzenie nie będzie dobrze reagowało na regulacje wypełnienia fali.
Radzimy sobie z tym, zwiększając prąd, którym sterujemy bramką tranzystora. Czyli zmniejszasz wartość rezystora PULLUP do takiej, by bramka tranzystora możliwie szybko się ładowała, ale jednocześnie prąd nie przeciążał wyjścia OUT układu ponad rozsądną wartość.
Innym sposobem jest zmniejszenie częstotliwości generatora PWM, do takiej by zasilanie bramki „nadążało” się ładować i rozładowywać. Jest to jednak gorsze wyjście, ponieważ powoduje charakterystyczne buczenie (silników)/mruganie (żarówek/LED) elementów sterowanych tranzystorem.
Zawsze trzeba znaleźć jakiś kompromis.
Dziękuje za wyczerpującą odpowiedź,rozwiałeś wszystkie moje wątpliwości.
Pozdrawiam