TLC5940 представляет собой интегральную схему с 16 выходами ШИМ. ШИМ-генератор микросхемы имеет разрешение 12 бит или 4096 степеней заполнения. Одним из основных преимуществ этой микросхемы является возможность подключения светодиодов напрямую к ее выводам (без резисторов). Выводы TLC5940 могут выдерживать нагрузку до 120 мА.
Выводы микросхемы TLC5940
- OUT0..OUT15 — 16 выводов ШИМ схемы генераторов. Выводы могут быть загружены максимум от 5 до 120 мА. Ток выводов регулируется ведущим IREF и/или специальными «DC» регистрами системы.
- VPRG — ввод режима системного программирования — подключается к GND в Arduino.
Низкое состояние — программирование регистров заполнения ШИМ (GS), высокое состояние — программирование регистров коррекции выходного тока (DC). - SIN — последовательный ввод — вы подключаетесь к цифровому выводу 11 в Arduino UNO.
- SCLK — последовательный ввод битов данных — вы подключаетесь к цифровому выводу 13 в Arduino UNO.
- XLAT — ввод, подтверждающий отправленные данные — подключается к цифровому выводу 9 в Arduino UNO.
- BLANK — ввод для отключения выводов и сброса счетчиков ШИМ-генератора — подключается к цифровому пину 10 в Arduino UNO.
- GND — заземление ввода питания — подключите к GND в Arduino.
- VCC — ввод питания +5 В — подключаете к контакту питания 5 В в Arduino.
- IREF — ввод для определения тока на выходах OUT. Вы подключаете резистор к вводу с сопротивлением, настроенным на выходной ток, где другая нога резистора подключена к GND.
Rref = номинал резистора, подключенного между IREF и GND.
Предполагая, что для светодиодов требуется ток 20 мА, резистор должен быть 2 кОм.
DCPRG — Ввод выбора данных для точной регулировки выходного тока — подключаете к + 5В.
GSCLK — Тактовый ввод, импульсы которого заставляют счетчики ШИМ-генераторов системы считать — вы подключаете его к цифровому выводу 3 в Arduino UNO.
SOUT — последовательный вывод данных с микросхемы. В конфигурации с последовательным подключением этот вывод подключается к SIN следующей микросхемы.
XERR — вывод системной ошибки. При перегреве системы или перегорании любого светодиода, подключенного к выходам ШИМ-генератора, на выходе появятся низкие импульсы. Выход представляет собой открытый сток, из-за чего он либо низкий, либо переходный.
Подключение TLC5940 к Arduino Uno
На схеме выше показано, как подключить микросхему TLC5940 к Arduino. Соединение занимает 5 цифровых контактов Arduino. Светодиоды можно подключать напрямую к выходам от OUT0 до OUT15, катодом к OUT, анодом до 5В (при условии использования подходящего резистора IREF). В этом примере мы подключили светодиод к выходу OUT1.
Подключение к Arduino Mega
Поскольку у Arduino MEGA выход SPI находится немного в другом месте, для подключения к нему TLC5940 требуется другая схема подключения.
Программирование микросхемы TLC5940
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <Tlc5940.h> void setup() { Tlc.init(); Tlc.set(1, 2048); while (Tlc.update()); } void loop() { } |
У Arduino также есть библиотека для чипа TLC5940. В нашем примере, светодиод, подключенный к выходу OUT1, загорается на половину яркости.
Системное программирование начинается с загрузки соответствующей библиотеки через #include <Tlc5940.h> . Затем, в функции setup , библиотеку необходимо инициализировать с помощью метода Tlc.init(); . Мы поместили метод Tlc.update() в цикл while . Этот метод отвечает за отправку данных в систему и обновление ее регистров. Вы должны продолжать вызывать его, пока он не вернет 0. Если это не критично, вы можете поместить этот метод и в функцию цикла.
Метод Tlc.set отвечает за настройку отдельных выходов ШИМ TLC5940. Его первый параметр — номер вывода от 0 до 15, а второй параметр — значение заполнения ШИМ-генератора от 0 до 4095.
Библиотека использует для своей работы системы Timer1 и Timer2 и SPI контроллера Arduino, поэтому будьте внимательны, не конфликтует ли она с другой библиотекой в вашем проекте.
Методы объекта TLC:
Tlc.init() разрешает работу библиотеки и инициирует связь с микросхемой TLC5940. У него есть необязательный аргумент, представляющий собой число от 0 до 4095. Аргумент устанавливает начальное
значение заполнения для всех выводных данных макета. Вызов метода без аргумента приводит к установке выводных данных в 0.
Tlc.clear () устанавливает все выходы в 0.
Tlc.setAll(value) устанавливает для всех выходов значение заполнения, указанное в аргументе (от 0 до 4095).
Tlc.set (out, value) устанавливает выход, указанный в аргументе «out» (от 0 до 15), равным значению,
указанному в аргументе «value» (от 0 до 4095).
Tlc.get (out) возвращает значение заполнения для вывода, указанного в аргументе «out» (от 0 до 15).
Tlc.update() отправляет данные на чип. Возвращает 0, если данные зафиксированы, или 1,
если еще не зафиксированы.
Продолжим…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
#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(); } |
В качестве примера использования библиотеки, мы использовали идею индикатора типа «LED bar» (светодиодная панель). Предполагается, что все контакты OUT TLC5940 подключены к светодиодам. Работу индикатора можно описать так, что чем выше напряжение на выводе Arduino Analog 0, тем больше светодиодов будет гореть на следующих выводах. Все светодиоды горят при напряжении 5В. Дополнительным преимуществом использования ШИМ является то, что последний индикаторный диод загорается постепенно по мере увеличения напряжения на входе.
Наиболее важной функцией программы является tlc_progress . Он управляет освещением светодиодов, подключенных к системе. Его первый аргумент — значение от 0 до 65535. Чем больше число, тем плавнее загораются следующие светодиоды индикатора. Другим аргументом функции является аргумент яркости диодов, предшествующих последней. Если вы установите его на 0, одновременно будет гореть только один светодиод.
Если поставить туда максимальное значение, т.е. 4095, то следующие светодиоды будут гореть до максимальной яркости.
В функции цикла программа считывает значение с вывода Analog 0. Так как функция AnalogRead считывает значения от 0 до 1023, их необходимо масштабировать с помощью функции map до значений диапазона функции tlc_progress , т.е. от 0 до 65535.
Светодиодный индикатор используется там, где не важна точность, но важно быстро узнать об уровне того или иного сигнала. Вы можете легко превратить программу в крутой «аналоговый» термометр, тахометр или индикатор уровня звука на вашей аудиосистеме.
Другие примеры из библиотеки
В дополнение к основному заголовку Tlc5940.h ,в библиотеке есть несколько других заголовков с дополнительными функциями, которые помогут в решении некоторых ваших идей:
Затухание светодиода
Заголовок tlc_fades.h позволяет легко создавать эффекты плавного свечения и постепенного затухания.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <Tlc5940.h> #include <tlc_fades.h> void setup() { Tlc.init(); tlc_addFade(1, 0, 4095, 5000, 10000); } void loop() { tlc_updateFades(); } |
Чтобы начать использовать библиотеку, добавьте заголовок #include <tlc_fades.h> . После добавления заголовка #include <tlc_fades.h> система должна нормально инициализироваться в функции setup . В функции loop должна быть функция tlc_updateFades(); она отвечает за синхронизацию работы всей библиотеки.
Функция tlc_addFade отвечает за подготовку свечения/угасания, назовем все это анимацией. Ее первый аргумент — номер вывода микросхемы TLC5940, на которой должна происходить анимация. Следующим аргументом является начальное значение яркости анимации (от 0 до 4095). А третий аргумент — конечное значение яркости анимации с теми же параметрами, что и у предыдущего аргумента.
Последние два аргумента — это время в миллисекундах с момента включения Arduino. Предпоследний говорит о миллисекунде, через которую должна начаться анимация, а следующий, через который она должна закончиться.
Функция в примере создает анимацию светодиода на выходе «OUT1», загорающегося от значения 0 до значения 4095. Свечение должно произойти в течение 5-10 секунд после включения Arduino.
Вы можете сделать до 24 анимаций одновременно (вызовы функции tlc_addFade). Затем вам нужно дождаться окончания одной из анимаций. В этом поможет функция tlc_isFading . Ее аргументом является выходной номер, и он возвращает 1, если на данном выходе ожидается какая-то анимация, или 0, если не ожидается.
Также есть функция tlc_removeFades . Ее аргументом является начальный номер. Он удаляет все анимации для данного вывода.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#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(); } |
В этом примере мы реализовали анимацию мигания светодиода на выходе OUT1. Условие if проверяет, есть ли в данный момент анимация, и если нет, то создает другую.
Анимация создана так, что текущее время загружается в переменную time . Через одну секунду после этого времени ссвечение длится 250 мс. Через 1,5 с начинается задержка длительностью 500 мс. Это придает светодиоду приятный плавный эффект мерцания.
Функция tlc_updateFades имеет необязательный аргумент текущих миллисекунд. Если в анимации вас не устраивает время от включения Arduino, вы можете указать в аргументе свое текущее значение времени, выраженное в миллисекундах.
Смещение
Библиотека tlc_shifts.h отвечает за эффект смещения значений яркости с одного светодиода на другой светодиод.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#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); } |
В примере создается эффект «световой змейки», заключающийся в иллюзии того, что свет в линейке светодиодов ползет.
Функция «tlc_shiftUp» записывает новое значение заполнения, указанное в аргументе, на выход OUT0, в то время как остальная часть значения сдвигается на последовательные выходы (OUT0 на OUT1, OUT1 на OUT2 и т. д.). Эта функция возвращает последнее значение, которое было в регистре заполнения OUT15 (это облегчает зацикливание).
Существует также обратная функция, называемая tlc_shiftDown , аргумент которой записывает значение заполнения в OUT15 и сдвигает значения регистра вниз (OUT15 в OUT14, OUT14 в OUT13 и т. д.). Затем возвращает значение регистра OUT0 перед сдвигом.
Данные из памяти программ
Иногда возникает необходимость передать некоторые данные из памяти на выходы ШИМ. Контроллер AVR в Arduino имеет несколько видов памяти, самая объемная из которых — Flash-память, где хранится программа. Оперативная память в несколько раз менее емкая, поэтому в ней лучше всего хранить текущие переменные, а не массивы с постоянными данными. Поэтому авторы системной библиотеки TLC5940 позаботились о возможности разной работы с памятью программ:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#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() { } |
Библиотека tlc_progmem_utils.h содержит инструменты для обработки данных из памяти программ.
Чтобы подготовить массив значений заполнения для ШИМ-регистров схемы, его необходимо объявить соответствующим образом. Помимо стандартного определения типа byte, имени массива pwm_data и его размера, необходимо также добавить соответствующую директиву, информирующую о том, что таблица должна храниться в памяти программы, а не в оперативной памяти. Эта директива PROGMEM. Размер массива определяется объемом данных, необходимых для программирования системы. Это связано с тем, что чипу требуется шестнадцать 12-битных значений. В языке C нет типа, который может содержать 12-битные значения. Имеется либо 16-битный word, либо 8-битный byte. Во избежание ненужной потери данных в библиотеке используется 8-битный byte. 24 элемента байтового массива являются результатом того, что 16 × 12 бит/8 (тип byte) = 24. Массив сортируется от последнего регистра GS OUT15 до первого GS OUT0.
Чтобы это упростить, в библиотеке есть макрос GS_DUO, который имеет два аргумента для представления следующих 2 выходов ШИМ (OUT15, OUT14 до OUT1, OUT0).
За отправку данных из таблицы отвечает функция tlc_setGSfromProgmem. Его аргументом является имя массива с данными для отображения.
Анимации из памяти программы
Если вы хотите отправлять последовательности данных на TLC5940, например, в виде анимации или данных на спектральный дисплей, вы можете использовать библиотеку tlc_animations.h, которая работает аналогично предыдущей:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#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); } } |
На этот раз, размер массива pwm_data нужно умножить на количество кадров анимации. В этом примере мы создали 2 кадра анимации. Первый кадр — это максимальное свечение нечетных выходных светодиодов, а второй — максимальное свечение четных светодиодов.
За запуск анимации отвечает функция tlc_playAnimation. Ее первый аргумент — это массив с данными анимации, второй — количество кадров анимации, а последний аргумент — время, через которое должен отображаться каждый кадр анимации. Время выражается в циклах счетчика ШИМ, один цикл равен 1,024 мс. Итак, 500 означает, что кадры будут появляться примерно каждые полсекунды.
Поскольку tlc_playAnimation не зацикливает анимацию, ее необходимо перезапустить после отображения последнего кадра анимации. Tlc_onUpdateFinished возвращает 0, если анимация закончилась, и 1, если она все еще выполняется. Вот почему мы использовали его для зацикливания анимации.
Коррекция выходного тока TLC5940
Если к выходам TLC5940 подключить светодиоды разного цвета, то их свечение часто бывает неодинаково ярким. Это можно установить, создав сложные формулы, которые преобразуют значение регистра заполнения и ограничивают разрешение каналов ШИМ. Однако этот чип имеет дополнительное оборудование, которое поможет вам настроить яркость.
Регистры DC (Dot Correct) отвечают за более точную регулировку тока на выходах ШИМ. Их разрешение 6 бит, поэтому они принимают значения от 0 до 63. Они делят значение максимального выходного тока, определяемого резистором на входе IREF.
Чтобы выбрать регистры постоянного тока, необходимо внести небольшое изменение в электрическую систему и программную библиотеку.
На схеме добавлен еще один провод к цифровому выводу Arduino. Провод проходит от входа VPRG (ножка 27 микросхемы TLC5940) к цифровому выводу 8 в Arduino. В Arduino MEGA этот сигнал должен быть подключен к цифровому выводу 50.
Затем в каталоге библиотеки найдите файл tlc_config.h, отвечающий за установку параметров библиотеки и найдите в нем определение #define VPRG_ENABLED 0 и измените его на #define VPRG_ENABLED 1. Это активирует дополнительные элементы библиотеки, отвечающие за регистры постоянного тока.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#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() { } |
Самый простой способ обработки регистров — использование библиотеки tlc_progmem_utils.h.
Настройка регистров постоянного тока аналогична ранее описанной функции установки регистров заполнения из флэш-памяти. В этом случае вам нужен массив в памяти программы с 12- байтовыми элементами. Для легкой настройки отдельных регистров нужны макросы DC_QUARTET, имеющие по 4 аргумента, представляющие каждый выход в обратном порядке. Для настройки всех регистров требуется четыре макроса.
За запись данных из таблицы в TLC5940 отвечает функция tlc_setDCfromProgmem, единственным аргументом которой является имя таблицы с данными регистра DC.
В нашем примере, к выходам OUT0 — OUT7 были подключены зеленые светодиоды, а к выходам OUT8 — OUT15 — красные светодиоды. Красные светодиоды были очень яркими и намного ярче зеленых, поэтому они получили значение 3, а зеленые светодиоды, менее яркие, значение 14.
Сервоуправление
Как вы уже знаете, а если не помните, загляните в эту статью, угол поворота сервопривода зависит от ширины импульса ШИМ. Вы также можете подключить 16 сервоприводов к TLC5940.
Выходы TLC 5940 имеют открытый коллектор и сообщают только о низком или переходном уровне. Следовательно, необходимо подключить резистор PullUp (подтягивающий резистор), чтобы активировать управляющий вход. Этот резистор согласно библиотечная документация должна иметь сопротивление от 2 кОм до 5 кОм.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#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(); } |
Для использования сервоприводов системой, используется специальная библиотека tlc_servos.h. Так как в библиотеке установлены вполне безопасные минимальные и максимальные значения времени импульса сервопривода, перед загрузкой библиотеки необходимо определить собственное время в макросах SERVO_MIN_WIDTH и SERVO_MAX_WIDTH. Эти значения выражаются количеством раз заполнения в регистре ШИМ, то есть от 0 до 4095. Первое значение для заполнения соответствует сервоприводу, установленному на 0 градусов, а второе — на 180 градусов. Время заполнения для 1000 микросекунд равно 204. Наши сервоприводы (HTX900) находятся в диапазоне от 870 до 2800 микросекунд, поэтому мы дали им значения заполнения от 177 до 571. Эти значения можно рассчитать по формуле:
1 |
GSvalue = czas_impulsu_us * 204 / 1000 |
В функции setup библиотеки требуется вызов tlc_initServos(); необязательным аргументом которого является угол поворота сервоприводов, подключенных к выходам.
Сервоприводы задаются с помощью функции tlc_setServo, первый аргумент которой — номер выхода, к которому подключен сервопривод, а второй аргумент — угол поворота его оси.
В конце, разумеется, необходимо подтвердить отправку данных на чип с помощью метода Tlc.update();
Данные на сервопривод также можно передать методом Tlc.set, не забывая при этом не превышать минимальный и максимальный импульс. Прежде чем указать параметр заполнения для этого метода, его необходимо вычесть из 4095 ( Tlc.set (4095-imp_width); ).
С помощью сервобиблиотеки к выходам можно подключить и другие элементы, имея в виду, что теперь они генерируют импульсы с частотой 50 Гц.
Программа, в примере, считывает значение с аналогового входа и после масштабирования устанавливает сервоось пропорционально напряжению на входе.
Будьте осторожны: библиотека нуждается в небольшой доработке, так как диапазон импульсов нашего сервопривода вызывал в ней ошибку. В директории библиотеки в файле tlc_servos.h функция tlc_angleToVal должна выглядеть так:
1 2 3 4 5 6 7 8 |
/** 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); } |
Контроль двигателя
Электродвигатель управляется, как и в предыдущей записи, MOSFET-транзистором. Конечно, не забывая предусмотреть резистор PullUp на выходе TLC5940.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#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(); } |
Данный пример не отличается от предыдущих, и не требует специальной библиотеки. Управляет скоростью двигателя на основе напряжения на аналоговом входе 0 на Arduino, масштабируя значение до уровня диапазона значений регистра заполнения GS.
Соединение нескольких микросхем TLC5940
Чтобы получить больше выходов ШИМ, подключите еще один чип TLC5940. Для этого вам не нужно использовать какие-либо дополнительные контакты Arduino. Последующие цепи подключаются так же, как и первая, передавая те же самые сигналы следующим, за одним исключением. Вы соединяете сигнал SIN (вывод 26) следующей микросхемы с сигналом SOUT (вывод 17) предыдущей. Таким образом, вы получаете еще 16 выходов ШИМ. Вы можете комбинировать таким образом любое количество систем, имея в виду, что чрезмерное количество требует дополнительных модификаций в библиотеке управления.
Чтобы программа использовала дополнительные системы, откройте файл из каталога библиотеки с именем tlc_config.h. В нем определен макрос #define NUM_TLCS 1. Число после названия соответствует количеству подключенных микросхем TLC5940. В нашем случае это будет #define NUM_TLCS 2.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include <Tlc5940.h> void setup() { Tlc.init(); Tlc.set(1, 2048); Tlc.set(17, 2048); while (Tlc.update()); } void loop() { } |
В программе управления цепями почти ничего не меняется. Единственное отличие состоит в том, что последовательные выходы имеют последовательные номера. Таким образом, красный светодиод, подключенный к OUT1 первой микросхемы, имеет номер 1, а зеленый светодиод, подключенный к OUT1 второй микросхемы, имеет номер 17. Это очень простое решение.
Количество выходов увеличивается на кратное количество систем в каждом. Библиотеки, использующие флэш-память, должны иметь массивы, увеличенные до числа выходов микросхемы.
Итог
TLC5940 — очень интересная интегральная схема. Ее возможности в сочетании с Arduino очень велики. Благодаря TLC5940 можно делать шагающих роботов, используя для этого несколько сервоприводов, или удивительные световые эффекты для новогодней елки. Придумайте свой проект, в котором будет использоваться микросхема TLC5940, и поделитесь им с нами. Удачи вам в ваших проектах!
С Уважением, МониторБанк