не могу програмно настроить пины на лед драйвере АТ1628
- Войдите на сайт для отправки комментариев
Сб, 25/11/2017 - 10:39
В общем есть плата с 7ми сегментными дисплеями. Хочу настроить управление, но вот загвоздка там стоят лед драйвера AT1628 я использовал библиотеку от ТМ1628 но вот беда выводится не на те пины как изменить ? Вернее вопрос даже такой как на драйверах настраивать значение выводов ?
Какая используется библиотека - ХЗ!
Что написано в скетче - ХЗ!
Как светодиоды распаяны на ноги микросхемы - ХЗ!
Ответ на вопрос: ХЗ х ХЗ х ХЗ = ХЗ3
библиотека tm1628_Master, смысл прилагать текст скетча не вижу, семисегментные модули припаяны wt4031asr, и извините что так мало инфы дал на форумах почти не был
Вообще-то, я хотел Вам рассказать как можно настроиться на незнакомую плату (я как раз недавно это делал для TM1668), но ...
библиотека tm1628_Master
Вы предлагаете мне самому её гуглить, а если их несколько версий, то пытаться угадать какая именно у Вас? Ссылка, видимо, секретная?
смысл прилагать текст скетча не вижу
Смысла пытаться угадать как именно Вы формируете сегменты не вижу. Раз Вам лень привести скетч, то мне, тем более, лень угадывать что у Вас там написано.
извините что так мало инфы дал
Да, не извиняйтесь, мне Ваша инфа и не нужна вовсе, у меня-то нет проблемы. Я думал, что это нужно Вам, но, похоже, ошибся.
Нет вы не ошиблись и мне правдо очень нужно! Вы можете помочь ! Я ето понял Скажите что нужно я всё выложу
Ну вот скетчь но не мой он просто зажигает 2 сегмента
Если можно както наладить диалог с вами был бы рад
А библиотеку я нашёл наобум и уже не помню где ссылки не осталось ((( Как прикрепить сюда не знаю
Вот на всякий случай фото моего мучения
сегменты называются wt4031asr
Пока перевставьте вот так, а я через полчаса вернусь и посмотрю.
Я пока смотрю на вот эту библиотеку. Сверьте, у Вас такая или другая?
Она самая
Ну, в таком случае у меня для Вас плохая новость - её писал непрофессионал, а потому менять придётся много.
Для начала я обясню Вам суть проблемы, чтобы Вы понимали главную идею, так Вам будет легче вносить правки - всегда лучше, когда понимаешь, что делаешь.
У 7-мисегментного индикатора есть 8 сегментов (да, я тоже вспомнил "Сказку о Тройке"). Они обозначаются буквами а-g и dp вот так
Автор библиотеки зачем-то ввёл нестандартное обозначение цифрами, но это не важно.
Поехали дальше.
В микросхемах типа Вашей обычно пишут какой сегмент индикатора к какой ноге микросхемы подводить. Но при разводке платы это часто бывает неудобно и люди подводят так, как удобно, чтобы поменьше перемычек делать, а потом отрабатывают это программно.
Обычно это (настройка соответствия ног сегментам) делает в одном месте. И, если что, то и менять надо в одном месте.
Вот посмотрите, как это сделано у меня в примере кода для TM1668. В строках 40-46 я задаю соответствие ног сегментам. А в строках 61-83 я задаю собственно цифры, буквы и прочие смиволы. Причеём цифры и буквы я задаю через сегменты, т.е. цифра 0 - это сегменты A, B, C, D, E и F, цифра 1 - это сегменты B и С. Там именно это и написано. Строки 61-83 всегда одинаковые -= они не зависят от того на каких сегментах сидят ноги микросхему, т.к., например, 1 всегда будет B и C, так ведь! При таком задании, если мне надо поменять соответсвие ног сегментам, я меняю только строки 40-46. Ничего другого менять не надо. В строках 61-83 поменяется всё само и цифры останутся правильными.
теперь посмотрите как это сделано у автора библиотеки. Сегменты заданы в строках 17-24 файла TM1628.h, а цифры заданы в строках 35-50 файла TM16XXFonts.h. Но цифры заданы не через сегменты! Они заданы прямо битами. Поэтому, если Выам придётся менять соответсвие пинам сегментам, то менять придётся сразу в двух (как минимум) местах, что доставит гораздоб больше головной боли. Вот почему я сказал. что писал непрофессионал.
у меня она 47. И после неё вставьте строку
Затем в файле TM1628.cpp найдите функцию
void TM1628::setSeg(byte addr, byte num) { for(int i=0; i<7; i++){ bitWrite(buffer[i*2], seg_addr[addr], bitRead(NUMBER_FONT[num],i)); } }у меня это строки 129-133. И после неё вставьте функцию
void TM1628::setRaw(byte addr, byte num) { for(int i=0; i<7; i++){ bitWrite(buffer[i*2], seg_addr[addr], bitRead(num,i)); } }Пока я буду писать, что делать дальше, сделайте это и убедитесь, что программа нормально компилируется (там это называется "проверка", кажется).
Убедитесь. А я пока пишу дальше.
скомпилировалось
Я видно не понял вообще ничего я закоментировал ети строки , но несколько сегментов таки загораются
хотя как я понял не должны совсем
совсем забыл работаю на ардуине МЕГА 2560
Я видно не понял вообще ничего я закоментировал ети строки , но несколько сегментов таки загораются
В том-то и дело!
У меня аналогичные строки являются основой для всего остального! Именно потому, для Вашей задачи хватило бы только их поменять.
А у автора библиотеки это строки не пришей кобыле хвост - всё остальное сделано само по себе, без них.
Сравниете мои строки 61-83 со строками 35-50 файла TM16XXFonts.h. Мои определения цифр сделаны через ранее определённые сегменты. А у автора бибилиотеки онс сделаны через голимые биты, а на определения сегментов (те строки. что Вы закомментировали) плевать.
Вот именно это и говорит о непрофессионализме, и именно это нам сейчас создаст массу головной боли.
Значит так, берите вот такой скетч
#include <TM1628.h> TM1628 dvdLED(9, 8, 7); void setup() { dvdLED.begin(ON, 7); Serial.begin(9600); dvdLED.setRaw(0, 0xff); // попробуйте тут вместо 0 поставить 1-6 } void loop() {}и скажите мне загорелись ли ВСЕ сегменты 0-ой цифры.
Попробуйте первую, втроую и т.д. цифры (там в комментария написано что менять).
Расскажите, что получилось.
'class TM1628' has no member named 'setRaw' ошибка компиляции
а теперь так:
'TM1628' does not name a type
В прошлом посте я просил Вас вставить в файлы библиотеки setRaw. Вы вставили? В те самые файлы, откуда берётся бибилиотека? Нормально сохранили? Боюсь, что нет. Вставьте как следует, сохраните. Попробуйте перезапустить IDE. И скажите, что получается.
всё как вы сказали всё на месте не работает ошибка
вот кусок из h
а вот из cpp
void TM1628::sendCommand(byte data) { digitalWrite(_stb_pin, LOW); send(data); digitalWrite(_stb_pin, HIGH); } void TM1628::setSeg(byte addr, byte num) { for(int i=0; i<7; i++){ bitWrite(buffer[i*2], seg_addr[addr], bitRead(NUMBER_FONT[num],i)); } } void TM1628::setRaw(byte addr, byte num) { for(int i=0; i<7; i++){ bitWrite(buffer[i*2], seg_addr[addr], bitRead(num,i)); } } void TM1628::setChar(byte addr, byte chr) { for(int i=0; i<7; i++){ bitWrite(buffer[i*2], seg_addr[addr], bitRead(FONT_DEFAULT[chr - 0x20],i)); } update(); }Так не бывает. Что-то не так.
1. Убедитесь, что Вы правите именно те файлы, которые берёт IDE, а не например, копию библиотеки в том месте, куда Вы её скачали. Скажите где они у Вас расположены. Вы знаете, где установлены библиотеки? Вы именно там правите?
2. Выкладывайте сюда файлы библиотеки которые правили - оба.
Всё правильно.
Значит, см. п.1 в предыдущем посте.
То, что старый скетч (без setRaw) у Вас компилировался говорит о том, что Вы поправили где-то в другом месте, а рабочая библиотека - не поправлена.
C:\Program Files (x86)\Arduino\libraries\TM1628-master это путь к библиотеке именно их правлю
Как прикрепть файлы тут ?
Прикреплять не надо, Вы дали куски пока хватит.
Правите в неправильном месте.
Посмотрите, если ли там рядом папка C:\Program Files (x86)\Arduino\libraries\TM1628
Есть?
нету
У меня есть скайп и майл если есть возможность через микрофон говорить ето бы упростило задачу )))
Если нет, ищите папку в которой лежат Ваши скетчи. Все скетчи. Её легко найти. В IDE нажмите "Файл"|"Настройки" И в самом верху увидите "Расположение папки скетчей.
Вот в папке скетчей и лежит подпапка libraries, а в ней должна быть подпапка TM1628. Есть? Вот там надо править.
нету там папки библиотек
Так, ну хорошо, но то место неправильное.
Давайте так.
1. В скетче закомментируйте строку с setRaw
2. Убедитесь, что компилируется.
3. Уберите ту папку TM1628-maste (скопируйте куда-нибудь и удалите нафиг.
4. запустите компиляцию и посмотрите. Скопилировалось?
Кстати, давайте скайп, я позвоню (не удивляйтесь женскому имени - это скайп жены)
alexey3148 - скайп
#include <TM1628.h> TM1628 dvdLED(9, 8, 7); void setup() { dvdLED.begin(ON, 7); Serial.begin(9600); } void loop() { for(int i=0; i <= 255 ;i++) { dvdLED.setLEDon(i); Serial.println(); Serial.print(" I: "); Serial.print(i); delay(250); dvdLED.clear(); } }#include <TM1628.h> TM1628 dvdLED(9, 8, 7); void setup() { dvdLED.begin(ON, 7); Serial.begin(9600); dvdLED.setTime(11,25,32); } void loop() { // for(int i=0; i <= 255 ;i++) // { // dvdLED.setLEDon(i); // Serial.println(); // Serial.print(" I: "); // Serial.print(i); // delay(250); // dvdLED.clear(); // } }#include <TM1628.h> TM1628 dvdLED(9, 8, 7); void setup() { dvdLED.begin(ON, 7); dvdLED.setRaw(0, 0b00000001); update(); // Здесь // надо попробовать все 8 вариантов // 0b00000001, 0b00000010, 0b00000100, ... 0b10000000 // и тщательно записать какой сегмент загорается // желательно записывать в файл сразу в виде // #define SEG_A 0b???????? // #define SEG_B 0b???????? // #define SEG_C 0b???????? // #define SEG_D 0b???????? // #define SEG_E 0b???????? // #define SEG_F 0b???????? // #define SEG_G 0b???????? // #define SEG_DP 0b???????? } void loop() {}#include <TM1628.h> TM1628 dvdLED(9, 8, 7); void setup() { dvdLED.begin(ON, 7); dvdLED.setRaw(0, 0); dvdLED.update(); // Здесь // надо попробовать все 8 вариантов // 0b00000001, 0b00000010, 0b00000100, ... 0b10000000 // и тщательно записать какой сегмент загорается // желательно записывать в файл сразу в виде // #define SEG_A 0b???????? // #define SEG_B 0b???????? // #define SEG_C 0b???????? // #define SEG_D 0b???????? // #define SEG_E 0b???????? // #define SEG_F 0b???????? // #define SEG_G 0b???????? // #define SEG_DP 0b???????? } void loop() {}#include <TM1628.h> TM1628 dvdLED(9, 8, 7); void setup() { dvdLED.begin(ON, 7); dvdLED.setRaw(0xff, 0); dvdLED.update(); // Здесь // надо попробовать все 8 вариантов // 0b00000001, 0b00000010, 0b00000100, ... 0b10000000 // и тщательно записать какой сегмент загорается // желательно записывать в файл сразу в виде // #define SEG_A 0b???????? // #define SEG_B 0b???????? // #define SEG_C 0b???????? // #define SEG_D 0b???????? // #define SEG_E 0b???????? // #define SEG_F 0b???????? // #define SEG_G 0b???????? // #define SEG_DP 0b???????? } void loop() {}#include <TM1628.h> TM1628 dvdLED(9, 8, 7); void setup() { dvdLED.begin(ON, 7); for (int i = 0; i < 7; i++) { dvdLED.setRaw(i, 15); dvdLED.update(); delay(2000); } } void loop() {}#include <TM1628.h> TM1628 dvdLED(9, 8, 7); void setup() { dvdLED.begin(ON, 7); // dvdLED.setRaw(0, 8); //a dvdLED.setRaw(1, 8); //f dvdLED.setRaw(2, 8); //e dvdLED.setRaw(3, 8); //b dvdLED.setRaw(5, 8); //c dvdLED.update(); // dvdLED.setRaw(0, 4); //a dvdLED.setRaw(1, 4); //f dvdLED.setRaw(2, 4); //e dvdLED.setRaw(3, 4); //b dvdLED.setRaw(5, 4); //c dvdLED.setRaw(7, 4); //c dvdLED.update(); // dvdLED.setRaw(0, 2); //a dvdLED.setRaw(1, 2); //f dvdLED.setRaw(2, 2); //e dvdLED.setRaw(3, 2); //b dvdLED.setRaw(5, 2); //c dvdLED.update(); // dvdLED.setRaw(0, 1); //a dvdLED.setRaw(1, 1); //f dvdLED.setRaw(2, 1); //e dvdLED.setRaw(3, 1); //b dvdLED.setRaw(5, 1); //c dvdLED.setRaw(4, 1); //c dvdLED.update(); //a, f, e, b, g, c, ., d 0 1 2 3 4 5 6 7 // for (int i = 0; i < 8; i++) { // dvdLED.setRaw(i, 15); // dvdLED.update(); // delay(2000); // } } void loop() {}ссылка на даташит микросхемы тм1628 http://www.datasheet13.com/tm1628-%D0%B4%D0%B0%D1%82%D0%B0%D1%88%D0%B8%D...
В этом даташите не описаны команды и регистры памяти. Вот более подробный даташит - http://aitendo3.sakura.ne.jp/aitendo_data/product_img/ic/LED-driver/TM1628english.pdf
Изучил даташиит. Есть две новости.
1. (хорошая)
Эта микросхема почти ничем не отличается от TM1668, которую я мучил в посте, на который ссылался выше. мы можем в хвост и в гриву использовать те наработки.
2. (так себе)
Подключение у Вас явно нестандартное. У Вас на панели 8 цифр, а микросхема поддерживает до 7-ми (либо 6 при 12 сегментах, либо 7 при 11-ти сегментах). Значит либо одна, либо 2 цифры подключены как-то "через зад", с этим надо будет разбираться. (Похоже, подключено 6х12 - помните мы с шестью легко работали, а две левые - ни в какую).
Исходя из этих новостей (особенно из 2-ой), план такой. Нафиг любые бибилотеки, гораздо проще всё сделать простым кодом, на основе того, что у меня был. Когда разберёмся, обернуть его в "библиотеку" - как два пальца.
Сначала дожмём дисплей, потом займёмся кнопками, с ними проще (сколько их там у Вас физически, кстати?).
По времени, будь Ваш девайс у меня, я бы дожал его за три-четрые часа, но так, как мы работали сегодня, думаю несколько вечеров потратим. К сожалению, наступающая неделя у меня сумасшедшая (см., а я там руковожу конторой, которая собственно проводит мероприятие). Но посмотрим. Если Вам не горит это прямо "вчера", то за несколько вечеров, пусть не каждый день, без проблем всё сделаем.
Постараюсь завтра заранее уже выложить сектч для начала исследования.
Ну в общем у меня кое что получилось
Есть несколько вопросов, Я похоже не использовал библиотеку совсем или я неправильно чтото понял
Ну да ето ладно вот код
#include <TM1628.h> TM1628 dvdLED(9, 8, 7); void setup() { dvdLED.begin(ON, 7); /* // dvdLED.setRaw(0, 8); //a dvdLED.setRaw(1, 8); //f dvdLED.setRaw(2, 8); //e dvdLED.setRaw(3, 8); //b dvdLED.setRaw(5, 8); //c dvdLED.update(); delay(100); // dvdLED.setRaw(0, 4); //a dvdLED.setRaw(1, 4); //f dvdLED.setRaw(2, 4); //e dvdLED.setRaw(3, 4); //b dvdLED.setRaw(5, 4); //c dvdLED.setRaw(7, 4); //c dvdLED.update(); delay(100); // dvdLED.setRaw(0, 2); //a dvdLED.setRaw(1, 2); //f dvdLED.setRaw(2, 2); //e dvdLED.setRaw(3, 2); //b dvdLED.setRaw(5, 2); //c dvdLED.update(); delay(100); // dvdLED.setRaw(0, 1); //a dvdLED.setRaw(1, 1); //f dvdLED.setRaw(2, 1); //e dvdLED.setRaw(3, 1); //b dvdLED.setRaw(5, 1); //c dvdLED.setRaw(4, 1); //c dvdLED.update(); delay(100); --- 0 --- | (a) | 1(f) 3(b) | | --- 4 --- | (g) | 2(e) 5(c) | | --- 7 --- . 6(.) (d) */ // a, f, e, b, g, c, ., d // 0 1 2 3 4 5 6 7 // for (int i = 0; i < 8; i++) { // dvdLED.setRaw(i, 15); // dvdLED.update(); // delay(100); // } Serial.begin(9600); } void loop() { dvdLED.clear();delay(100); //// первый дисплей //верхняя ГОРИЗОНТАЛЬНАЯ ПАЛОЧКА dvdLED.setRaw(0, 32); dvdLED.update();delay(100); dvdLED.setRaw(0, 48); dvdLED.update();delay(100); dvdLED.setRaw(0, 56); dvdLED.update();delay(100); //ЛЕВАЯ ВЕРХНЯЯ ВЕРТИКАЛЬНАЯ ПАЛОЧКА dvdLED.setRaw(1, 32); dvdLED.update();delay(100); dvdLED.setRaw(1, 48); dvdLED.update();delay(100); dvdLED.setRaw(1, 56); dvdLED.update();delay(100); //ЛЕВАЯ НИЖНЯЯ ВЕРТИКАЛЬНАЯ ПАЛОЧКА dvdLED.setRaw(2, 32); dvdLED.update();delay(100); dvdLED.setRaw(2, 48); dvdLED.update();delay(100); dvdLED.setRaw(2, 56); dvdLED.update();delay(100); //ПРАВАЯ ВЕРХНЯЯ ВЕРТИКАЛЬНАЯ ПАЛОЧКА dvdLED.setRaw(3, 32); dvdLED.update();delay(100); dvdLED.setRaw(3, 48); dvdLED.update();delay(100); dvdLED.setRaw(3, 56); dvdLED.update();delay(100); //СРЕДНЯЯ ГОРИЗОНТАЛЬНАЯ ПАЛОЧКА dvdLED.setRaw(4, 32); dvdLED.update();delay(100); dvdLED.setRaw(4, 48); dvdLED.update();delay(100); dvdLED.setRaw(4, 56); dvdLED.update();delay(100); //ЛЕВАЯ НИЖНЯЯ ВЕРТИКАЛЬНАЯ ПАЛОЧКА dvdLED.setRaw(5, 32); dvdLED.update();delay(100); dvdLED.setRaw(5, 48); dvdLED.update();delay(100); dvdLED.setRaw(5, 56); dvdLED.update();delay(100); //НИЖНЯЯ ГОРИЗОНТАЛЬНАЯ ПАЛОЧКА dvdLED.setRaw(7, 32); dvdLED.update();delay(100); dvdLED.setRaw(7, 48); dvdLED.update();delay(100); dvdLED.setRaw(7, 56); dvdLED.update();delay(100); //ТОЧКА dvdLED.setRaw(6, 32); dvdLED.update();delay(100); dvdLED.setRaw(6, 48); dvdLED.update();delay(100); dvdLED.setRaw(6, 56); dvdLED.update();delay(100); ///////ВТОРОЙ ДИСПЛЕЙ ///ВЕРХНЯЯ ГОРИЗОНТАЛЬНАЯ ПАЛОЧКА dvdLED.setRaw(0, 60); dvdLED.update();delay(100); dvdLED.setRaw(0, 62); dvdLED.update();delay(100); dvdLED.setRaw(0, 63); dvdLED.update();delay(100); //ЛЕВАЯ ВЕРХНЯЯ ВЕРТИКАЛЬНАЯ ПАЛОЧКА dvdLED.setRaw(1, 60); dvdLED.update();delay(100); dvdLED.setRaw(1, 62); dvdLED.update();delay(100); dvdLED.setRaw(1, 63); dvdLED.update();delay(100); //ЛЕВАЯ НИЖНЯЯ ВЕРТИКАЛЬНАЯ ПАЛОЧКА dvdLED.setRaw(2, 60); dvdLED.update();delay(100); dvdLED.setRaw(2, 62); dvdLED.update();delay(100); dvdLED.setRaw(2, 63); dvdLED.update();delay(100); //ПРАВАЯ ВЕРХНЯЯ ВЕРТИКАЛЬНАЯ ПАЛОЧКА dvdLED.setRaw(3, 60); dvdLED.update();delay(100); dvdLED.setRaw(3, 62); dvdLED.update();delay(100); dvdLED.setRaw(3, 63); dvdLED.update();delay(100); //СРЕДНЯЯ ГОРИЗОНТАЛЬНАЯ ПАЛОЧКА dvdLED.setRaw(4, 60); dvdLED.update();delay(100); dvdLED.setRaw(4, 62); dvdLED.update();delay(100); dvdLED.setRaw(4, 63); dvdLED.update();delay(100); //ЛЕВАЯ НИЖНЯЯ ВЕРТИКАЛЬНАЯ ПАЛОЧКА dvdLED.setRaw(5, 60); dvdLED.update();delay(100); dvdLED.setRaw(5, 62); dvdLED.update();delay(100); dvdLED.setRaw(5, 63); dvdLED.update();delay(100); //НИЖНЯЯ ГОРИЗОНТАЛЬНАЯ ПАЛОЧКА dvdLED.setRaw(7, 60); dvdLED.update();delay(100); dvdLED.setRaw(7, 62); dvdLED.update();delay(100); dvdLED.setRaw(7, 63); dvdLED.update();delay(100); //ТОЧКА dvdLED.setRaw(6, 60); dvdLED.update();delay(100); dvdLED.setRaw(6, 62); dvdLED.update();delay(100); dvdLED.setRaw(6, 63); dvdLED.update();delay(1000); dvdLED.clear();delay(100); // рисуем 0 в первом сегменте первого дисплея dvdLED.setRaw(1, 32); dvdLED.update(); dvdLED.setRaw(2, 32); dvdLED.update(); dvdLED.setRaw(3, 32); dvdLED.update(); dvdLED.setRaw(5, 32); dvdLED.update(); dvdLED.setRaw(0, 32); dvdLED.update(); dvdLED.setRaw(7, 32); dvdLED.update();delay(2000); dvdLED.clear();delay(100); // рисуем 1 в первом сегменте dvdLED.setRaw(3, 32); dvdLED.update(); dvdLED.setRaw(5, 32); dvdLED.update();delay(2000); dvdLED.clear();delay(100); // рисуем 2 в первом сегменте dvdLED.setRaw(0, 32); dvdLED.update(); dvdLED.setRaw(3, 32); dvdLED.update(); dvdLED.setRaw(4, 32); dvdLED.update(); dvdLED.setRaw(2, 32); dvdLED.update(); dvdLED.setRaw(7, 32); dvdLED.update();delay(2000); dvdLED.clear();delay(100); // рисуем 3 в первом сегменте dvdLED.setRaw(0, 32); dvdLED.update(); dvdLED.setRaw(3, 32); dvdLED.update(); dvdLED.setRaw(4, 32); dvdLED.update(); dvdLED.setRaw(5, 32); dvdLED.update(); dvdLED.setRaw(7, 32); dvdLED.update();delay(2000); dvdLED.clear();delay(100); // рисуем 4 в первом сегменте dvdLED.setRaw(3, 32); dvdLED.update(); dvdLED.setRaw(4, 32); dvdLED.update(); dvdLED.setRaw(5, 32); dvdLED.update(); dvdLED.setRaw(1, 32); dvdLED.update();delay(2000); dvdLED.clear();delay(100); // рисуем 5 в первом сегменте dvdLED.setRaw(0, 32); dvdLED.update(); dvdLED.setRaw(7, 32); dvdLED.update(); dvdLED.setRaw(4, 32); dvdLED.update(); dvdLED.setRaw(5, 32); dvdLED.update(); dvdLED.setRaw(1, 32); dvdLED.update();delay(2000); dvdLED.clear();delay(100); // рисуем 6 в первом сегменте dvdLED.setRaw(0, 32); dvdLED.update(); dvdLED.setRaw(7, 32); dvdLED.update(); dvdLED.setRaw(4, 32); dvdLED.update(); dvdLED.setRaw(5, 32); dvdLED.update(); dvdLED.setRaw(2, 32); dvdLED.update(); dvdLED.setRaw(1, 32); dvdLED.update();delay(2000); dvdLED.clear();delay(100); // рисуем 7 в первом сегменте dvdLED.setRaw(5, 32); dvdLED.update(); dvdLED.setRaw(3, 32); dvdLED.update(); dvdLED.setRaw(0, 32); dvdLED.update();delay(2000); dvdLED.clear();delay(100); // рисуем 8 в первом сегменте dvdLED.setRaw(0, 32); dvdLED.update(); dvdLED.setRaw(7, 32); dvdLED.update(); dvdLED.setRaw(4, 32); dvdLED.update(); dvdLED.setRaw(5, 32); dvdLED.update(); dvdLED.setRaw(2, 32); dvdLED.update(); dvdLED.setRaw(3, 32); dvdLED.update(); dvdLED.setRaw(1, 32); dvdLED.update();delay(2000); dvdLED.clear();delay(100); // рисуем 9 в первом сегменте dvdLED.setRaw(0, 32); dvdLED.update(); dvdLED.setRaw(7, 32); dvdLED.update(); dvdLED.setRaw(4, 32); dvdLED.update(); dvdLED.setRaw(5, 32); dvdLED.update(); dvdLED.setRaw(3, 32); dvdLED.update(); dvdLED.setRaw(1, 32); dvdLED.update();delay(2000); dvdLED.clear();delay(100); dvdLED.clear(); dvdLED.clear();delay(5000); // Рисуем цифры во втором сегменте первого дисплея (и вот тут начинается зажигание 2х сегментов сразу) // рисуем 0 в первом сегменте dvdLED.setRaw(1, 48); dvdLED.update(); dvdLED.setRaw(2, 48); dvdLED.update(); dvdLED.setRaw(3, 48); dvdLED.update(); //dvdLED.setRaw(4, 32); //dvdLED.update();delay(100); dvdLED.setRaw(5, 48); dvdLED.update(); dvdLED.setRaw(0, 48); dvdLED.update(); dvdLED.setRaw(7, 48); dvdLED.update();delay(2000); dvdLED.clear();delay(100); // рисуем 1 во втором сегменте dvdLED.setRaw(3, 48); dvdLED.update(); dvdLED.setRaw(5, 48); dvdLED.update();delay(2000); dvdLED.clear();delay(100); // рисуем 2 во втором сегменте dvdLED.setRaw(0, 48); dvdLED.update(); dvdLED.setRaw(3, 48); dvdLED.update(); dvdLED.setRaw(4, 48); dvdLED.update(); dvdLED.setRaw(2, 48); dvdLED.update(); dvdLED.setRaw(7, 48); dvdLED.update();delay(2000); dvdLED.clear();delay(100); // рисуем 3 во втором сегменте dvdLED.setRaw(0, 48); dvdLED.update(); dvdLED.setRaw(3, 48); dvdLED.update(); dvdLED.setRaw(4, 48); dvdLED.update(); dvdLED.setRaw(5, 48); dvdLED.update(); dvdLED.setRaw(7, 48); dvdLED.update();delay(2000); dvdLED.clear();delay(100); // рисуем 4 во втором сегменте dvdLED.setRaw(3, 48); dvdLED.update(); dvdLED.setRaw(4, 48); dvdLED.update(); dvdLED.setRaw(5, 48); dvdLED.update(); dvdLED.setRaw(1, 48); dvdLED.update();delay(2000); dvdLED.clear();delay(100); // рисуем 5 во втором сегменте dvdLED.setRaw(0, 48); dvdLED.update(); dvdLED.setRaw(7, 48); dvdLED.update(); dvdLED.setRaw(4, 48); dvdLED.update(); dvdLED.setRaw(5, 48); dvdLED.update(); dvdLED.setRaw(1, 48); dvdLED.update();delay(2000); dvdLED.clear();delay(100); // рисуем 6 во втором сегменте dvdLED.setRaw(0, 48); dvdLED.update(); dvdLED.setRaw(7, 48); dvdLED.update(); dvdLED.setRaw(4, 48); dvdLED.update(); dvdLED.setRaw(5, 48); dvdLED.update(); dvdLED.setRaw(2, 48); dvdLED.update(); dvdLED.setRaw(1, 48); dvdLED.update();delay(2000); dvdLED.clear();delay(100); // рисуем 7 во втором сегменте dvdLED.setRaw(5, 48); dvdLED.update(); dvdLED.setRaw(3, 48); dvdLED.update(); dvdLED.setRaw(0, 48); dvdLED.update();delay(2000); dvdLED.clear();delay(100); // рисуем 8 во втором сегменте dvdLED.setRaw(0, 48); dvdLED.update(); dvdLED.setRaw(7, 48); dvdLED.update(); dvdLED.setRaw(4, 48); dvdLED.update(); dvdLED.setRaw(5, 48); dvdLED.update(); dvdLED.setRaw(2, 48); dvdLED.update(); dvdLED.setRaw(3, 48); dvdLED.update(); dvdLED.setRaw(1, 48); dvdLED.update();delay(2000); dvdLED.clear();delay(100); // рисуем 9 во втором сегменте dvdLED.setRaw(0, 48); dvdLED.update(); dvdLED.setRaw(7, 48); dvdLED.update(); dvdLED.setRaw(4, 48); dvdLED.update(); dvdLED.setRaw(5, 48); dvdLED.update(); dvdLED.setRaw(3, 48); dvdLED.update(); dvdLED.setRaw(1, 48); dvdLED.update();delay(2000); dvdLED.clear();delay(100); //for (int x=0; x < 128; x++) // { //int x=0; // for (int i=32; i < 64; i++) // { // dvdLED.update(); // Serial.println(); // Serial.print("x: - "); // Serial.print(x); // Serial.print(" I: - "); // Serial.print(i); // } // } }Циклы не вставлял с ними не работает при прогоне в циклах до 255 обоих значений загораются и светодиоды зелёные и красные
Ну в общем етот код прорисовывает полностью все кластеры 6ти экранчиков
потом в первом пишет по порядку циферки а дальше сбой
С адресацией я так и не понял как она сформирована
Только 6-ти? Т.е. самые левые таки не работают.
Алексей, пока суд да дело, Вы бы не посмотрели на эти две самые левые цифры, которые мы вчера засветить не смогли, как и куда они подключены. Может они вообще как-то отлельно (мимо этой микросхемы), а если к ней, то к каким пинами. Возьмите мультиметр, посмотрите. А то, легально-то 8 цифр к микросхеме подключить нельзя, значит есть там какая-то хитрость в подключении.
Мы сегодня сделаем всё без библиотеки вовсе, там всё будет в наших руках, так что, прорвёмся.
я же говорю все заработали
они по три цифры
Знаете непонимание оттого, что мы говорим на разных языках.
Давайте, чтобы понимать друг друга, договоримся о терминоголии.
1. Индиатор или цифра - это 7-сегментный индиктор. Их у Вас 8. Давайте пока договоримся об их нумерации справа налево. Самый правый - нулевой, самый левый - седьмой.
2. сегмент - один из восьми сегментов индикатора A, B, ... G, Dp
3. Дополнительный светодиод - отдельно стоящий светодиод, который загорается при включении какого-нибудь неиспользуемого для цифр семента того или иного индикатора.
Как я Вас понял, у Вас светились 7 индикаторов из 8-ми (светились с 0 по 6-ой, а седьмой не светился). Правильно?
То, что при значении 48 светилось два сразу - правильно. Очевидно светились те, которые светилдись при 16 и 32. так ведь? Попрбуйте там не 48, а 64.
Но, по любому, управление этой микросхемой очень простое и мы сегодня просто поуправляем ею "в лоб". Безо всякой библиотеки. Это будет проще потому, что не надло угадывать что там в библиотеке куда выведено.
Сейчас у емня дергание туда сюда, но в 6 я точно свободен и мы этим займёмся.
у меня светились 6 семисегментных индикаторов они по три в блоке а не по 4ре как вам кажется ))
Тоесть полностью работали оба модуля по три 7ми сегментных блока
Ну как то так
По поводу адресов нашёл адреса отдельных светодиодов 2.64-зелёный , 0.64-второй зелёный, 7.64 - первый красный, 6.64 - второй красный
Не теряйте времени на адреса
#include <stdio.h> static int serial_fputchar(const char ch, FILE *stream) { ((void*)stream); Serial.write(ch); return ch; } static FILE *serial_stream = fdevopen(serial_fputchar, NULL); #define PIN_DIO 9 #define PIN_CLK 8 #define PIN_STB 7 #define INIT_6x12 2 #define INIT_7x11 3 #define LED_DATA_LENGTH 14 // // Глобальные переменные // #define ALL_LEDS 0xf0ff static uint16_t ledGRID[LED_DATA_LENGTH / 2] = {// текущее состояние экрана ALL_LEDS, ALL_LEDS, ALL_LEDS, ALL_LEDS, ALL_LEDS, ALL_LEDS, ALL_LEDS }; static uint8_t currentBrightness = 1; // текущая яркость // // Запись одиночной команды в TM1628 // void writeSingleCommand(const uint8_t command) { digitalWrite(PIN_STB, LOW); shiftOut(PIN_DIO, PIN_CLK, LSBFIRST, command); digitalWrite(PIN_STB, HIGH); delayMicroseconds(1); // Пауза до следующей команды } // // Запись состояния дисплея в TM1628 // void updateDisplay(void) { writeSingleCommand(0x40); // запись данных, автоматический адрес digitalWrite(PIN_STB, LOW); shiftOut(PIN_DIO, PIN_CLK, LSBFIRST, 0xC0); // Установка адреса в 0 uint8_t * p = (uint8_t *) ledGRID; for (int8_t i = 0; i < LED_DATA_LENGTH; i++, p++) shiftOut(PIN_DIO, PIN_CLK, LSBFIRST, *p); // запись данных digitalWrite(PIN_STB, HIGH); delayMicroseconds(1); // Пауза до следующей команды } // // Установить яркость от 0 (выключено) до 8 // (возвращает старую яркость) // static inline uint8_t setBrightness(const uint8_t newBrighness) { const uint8_t res = currentBrightness; currentBrightness = (newBrighness > 8) ? 8 : newBrighness; if (currentBrightness == 0) writeSingleCommand(0x80); // Выключить дисплей else writeSingleCommand(0x88 + (currentBrightness - 1)); // Установить яркость return res; } void setup(void) { stdout = serial_stream; // эта строка первая в setup Serial.begin(115200); // // Инициализация пинов pinMode(PIN_CLK, OUTPUT); pinMode(PIN_DIO, OUTPUT); pinMode(PIN_STB, OUTPUT); digitalWrite(PIN_STB, HIGH); digitalWrite(PIN_CLK, HIGH); // // Инициализация экрана writeSingleCommand(INIT_6x12); // Режим отображения setBrightness(currentBrightness); // // Выводим содержимое регистров updateDisplay(); uint8_t *p = (uint8_t *)(&(ledGRID[0])); for (int i = 0; i < 14; i++, p++) { printf("0x%02X%c", *p, i % 2 ? '\n' : ' '); } } void loop(void) {}Запустите вот этот скетч и скажите мне что засветлисось. Я ожидаю, что засветится ВСЕ, ЧТО МОЖЕТ. Так ли это?
Если всё засветилось хорошо, то поэкспериментируйте со строк 77. Там можно писать
setBrightness(0); // ничего не светится
до
setBrightness(8); // максимальная яроксть
Ну и средние значения между 0 и 8. Работает установка яркости?
вы абсолютно правы загорелось всё
Яркость регулируется
Отличная новость!
Значит, мы всё без проблем сделаем безо всякого траха с чужой библиотекой (как видите, мы её не используем вовсе).
Кстати, мы договоаривались на 6, но я могу начать сейчас (правда в 5 будет перерыв на полчаса). Если Вы тоже можете, так давайте начнём.
Естественно могу
скайп ?
// // Подключение пинов // разъём отверстиями кверху и синей стороной шлейфа к себе, тогда рсапиновка: // GND 3,3V CLK DIO STB OUT-IR 5V // #define PIN_DIO 9 #define PIN_CLK 8 #define PIN_STB 7 #define INIT_6x12 2 #define INIT_7x11 3 ///////////////////////////////////////////////////////////// ///////////// ТИПА "библиотека" ДЛЯ TM1668 //////////// ///////////////////////////////////////////////////////////// // // при том подключении, что есть // достаточно 10 байтов на светодиоды и 2 на кнопки // #define LED_DATA_LENGTH 14 #define KEY_DATA_LENGTH 2 // // Маски нажатых кнопок (слева направо) // #define KEY_1 0x0800 #define KEY_2 0x0100 #define KEY_3 0x0008 #define KEY_4 0x0001 // // Подключено 5 "цифр". // 0-ая - это двоеточие, залействовано только два младших бита // 1-4 - собственно цифры слева направо. // В цифрах задействовано 7 битов под сегменты (с 0-го по 6-ой) // и 7-ой бит под доплнительный символ (питание, конверт и т.п.) // #define LE6 0x0001 #define LE5 0x0020 #define LE7 0x0040 #define LE8 0x0040 #define SEG_A 0x0001 #define SEG_F 0x0002 #define SEG_B 0x0004 #define SEG_G 0x0008 #define SEG_C 0x0010 #define SEG_DP 0x0020 #define SEG_D 0x0040 #define SEG_E 0x0080 // // Символы (цифры / буквы, можно ещё добавить всяких) // #define SYMBOL_0 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F) #define SYMBOL_1 (SEG_B | SEG_C) #define SYMBOL_2 (SEG_A | SEG_B | SEG_D | SEG_E | SEG_G) #define SYMBOL_3 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_G) #define SYMBOL_4 (SEG_B | SEG_C | SEG_F | SEG_G) #define SYMBOL_5 (SEG_A | SEG_C | SEG_D | SEG_F | SEG_G) #define SYMBOL_6 (SEG_A | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G) #define SYMBOL_7 (SEG_A | SEG_B | SEG_C) #define SYMBOL_8 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G) #define SYMBOL_9 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G) #define SYMBOL_MINUS (SEG_G) #define SYMBOL_A (SEG_A | SEG_B | SEG_C | SEG_E | SEG_F | SEG_G) #define SYMBOL_C (SEG_A | SEG_E | SEG_F | SEG_D) #define SYMBOL_E (SEG_A | SEG_D | SEG_E | SEG_F | SEG_G) #define SYMBOL_H (SEG_B | SEG_C | SEG_E | SEG_F | SEG_G) #define SYMBOL_P (SEG_A | SEG_B | SEG_E | SEG_F | SEG_G) #define SYMBOL_G (SEG_A | SEG_E | SEG_F) #define SYMBOL_L (SEG_D | SEG_E | SEG_F) #define SYMBOL_F (SEG_A | SEG_E | SEG_F | SEG_G) #define SYMBOL_d (SEG_B | SEG_C | SEG_D | SEG_E | SEG_G) #define SYMBOL_b (SEG_C | SEG_D | SEG_E | SEG_F | SEG_G) #define SYMBOL_rP (SEG_A | SEG_B | SEG_C | SEG_E | SEG_F) // // Глобальные переменные // static uint16_t ledGRID[LED_DATA_LENGTH / 2]; // текущее состояние экрана static uint8_t currentBrightness = 1; // текущая яркость static uint8_t digits[] = { SYMBOL_0, SYMBOL_1, SYMBOL_2, SYMBOL_3, SYMBOL_4, SYMBOL_5, SYMBOL_6, SYMBOL_7, SYMBOL_8, SYMBOL_9 }; // static uint16_t saveGRID[LED_DATA_LENGTH / 2]; // нужно для сохранения состояния экрана на время теста static uint8_t saveBrightness; // нужно для сохранения яркости на время теста // // // Запись одиночной команды в TM1668 // void writeSingleCommand(const uint8_t command) { digitalWrite(PIN_STB, LOW); shiftOut(PIN_DIO, PIN_CLK, LSBFIRST, command); digitalWrite(PIN_STB, HIGH); delayMicroseconds(1); // Пауза до следующей команды } // // Запись состояния дисплея в TM1668 // void updateDisplay(void) { writeSingleCommand(0x40); // запись данных, автоматический адрес digitalWrite(PIN_STB, LOW); shiftOut(PIN_DIO, PIN_CLK, LSBFIRST, 0xC0); // Установка адреса в 0 uint8_t * p = (uint8_t *) ledGRID; for (int8_t i = 0; i < LED_DATA_LENGTH; i++, p++) shiftOut(PIN_DIO, PIN_CLK, LSBFIRST, *p); // запись данных digitalWrite(PIN_STB, HIGH); delayMicroseconds(1); // Пауза до следующей команды } // // Чтение состояния кнопок с TM1668 // void readKeyData(uint16_t * data) { digitalWrite(PIN_STB, LOW); shiftOut(PIN_DIO, PIN_CLK, LSBFIRST, 0x42); // чтение данных pinMode(PIN_DIO, INPUT_PULLUP); delayMicroseconds(1); * data = shiftIn(PIN_DIO, PIN_CLK, LSBFIRST) + (shiftIn(PIN_DIO, PIN_CLK, LSBFIRST) << 8); pinMode(PIN_DIO, OUTPUT); digitalWrite(PIN_STB, HIGH); } // // Установить яркость от 0 (выключено) до 8 // (возвращает старую яркость) // static inline uint8_t setBrightness(const uint8_t newBrighness) { const uint8_t res = currentBrightness; currentBrightness = (newBrighness > 8) ? 8 : newBrighness; if (currentBrightness == 0) writeSingleCommand(0x80); // Выключить дисплей else writeSingleCommand(0x88 + (currentBrightness - 1)); // Установить яркость return res; } // // Увеличить яркость на 1 (возвращает старую яркость) // static inline uint8_t increaseBrightness(void) { const uint8_t res = currentBrightness; if (currentBrightness < 8) setBrightness(currentBrightness + 1); return res; } // // Уменьшить яркость на 1 (возвращает старую яркость) // static inline uint8_t decreaseBrightness(void) { const uint8_t res = currentBrightness; if (currentBrightness > 0) setBrightness(currentBrightness - 1); return res; } // // Показать тест экрана // (все символы включены на максимальной яркости) // void showTest(void) { memcpy(saveGRID, ledGRID, sizeof(saveGRID)); ledGRID[0] = 3; ledGRID[1] = 0xFF; ledGRID[2] = 0xFF; ledGRID[3] = 0xFF; ledGRID[4] = 0xFF; updateDisplay(); saveBrightness = setBrightness(8); } // // Восстановить экран после теста // void hideTest(void) { memcpy(ledGRID, saveGRID, sizeof(saveGRID)); updateDisplay(); setBrightness(saveBrightness); } // // Показать цифру value (0-9) в позиции digit (1-4) // при этом, если у цифры горит дополнительный символ, сохраняем его // static inline void setDigit(const int8_t digit, const uint8_t value) { if (digit < 0 || digit > 6) return; // цифры у нас с 1-ой по 4-ую слева направо ledGRID[digit] = value; // не обижать дополнительный символ, если есть } // // Показать число m в двух правых цифрах (типа минуты или там секунды) // static inline void showMinutes(const int8_t m) { setDigit(0, digits[m % 10]); setDigit(1, digits[m / 10]); } // // Показать число h в двух левых цифрах (типа часы или там минуты) // static inline void showHours(const int8_t h) { setDigit(2, digits[h % 10]); setDigit(3, digits[h / 10]); } // // Показать и часы, и минуты // static inline void showClock(const int8_t h, const int8_t m) { showHours(h); showMinutes(m); } ///////////////////////////////////////////////////////////// //////////// КОНЕЦ "библиотеки" ДЛЯ TM1668 //////////// ///////////////////////////////////////////////////////////// void setup(void) { // // Инициализация пинов pinMode(PIN_CLK, OUTPUT); pinMode(PIN_DIO, OUTPUT); pinMode(PIN_STB, OUTPUT); digitalWrite(PIN_STB, HIGH); digitalWrite(PIN_CLK, HIGH); // // Инициализация экрана writeSingleCommand(INIT_7x11); // Режим отображения (1 и 2 - ничего не меняется) setBrightness(currentBrightness); // // Пишем на экране слово ПОПА setDigit(3, SYMBOL_rP); setDigit(2, SYMBOL_0); setDigit(1, SYMBOL_rP); setDigit(0, SYMBOL_A); updateDisplay(); // // Даём 5 секунд полюбоваться delay(5000); // // Рисуем нулевое время showClock(0, 0); updateDisplay(); } void loop(void) { static int8_t m = 0, s = 0; // минуты и секунды для показа static uint32_t oldMillis = 0; // запомненное состояние счётчика миллисекунд bool haveToUpdate = false; // Если true, то в конце нужно обновить экран const uint32_t currMillis = millis(); const uint32_t diffMillis = currMillis - oldMillis; // // Пришла пора сменить цифру // if (diffMillis >= 1000) { s++; if (s == 60) { s = 0; m = (m + 1) % 60; } showClock(m, s); haveToUpdate = true; oldMillis = currMillis; } if (haveToUpdate) updateDisplay(); // Обновляем экран, если нужно } ///// Всё! Веселье закончилось!// // Подключение пинов // разъём отверстиями кверху и синей стороной шлейфа к себе, тогда рсапиновка: // GND 3,3V CLK DIO STB OUT-IR 5V // #define PIN_DIO 9 #define PIN_CLK 8 #define PIN_STB 7 #define INIT_6x12 2 #define INIT_7x11 3 ///////////////////////////////////////////////////////////// ///////////// ТИПА "библиотека" ДЛЯ TM1668 //////////// ///////////////////////////////////////////////////////////// // // при том подключении, что есть // достаточно 10 байтов на светодиоды и 2 на кнопки // #define LED_DATA_LENGTH 14 #define KEY_DATA_LENGTH 2 // // Маски нажатых кнопок (слева направо) // #define KEY_1 0x0800 #define KEY_2 0x0100 #define KEY_3 0x0008 #define KEY_4 0x0001 // // Подключено 5 "цифр". // 0-ая - это двоеточие, залействовано только два младших бита // 1-4 - собственно цифры слева направо. // В цифрах задействовано 7 битов под сегменты (с 0-го по 6-ой) // и 7-ой бит под доплнительный символ (питание, конверт и т.п.) // #define LE6 0x0001 #define LE5 0x0020 #define LE7 0x0040 #define LE8 0x0040 #define SEG_A 0x0001 #define SEG_F 0x0002 #define SEG_B 0x0004 #define SEG_G 0x0008 #define SEG_C 0x0010 #define SEG_DP 0x0020 #define SEG_D 0x0040 #define SEG_E 0x0080 // // Символы (цифры / буквы, можно ещё добавить всяких) // #define SYMBOL_0 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F) #define SYMBOL_1 (SEG_B | SEG_C) #define SYMBOL_2 (SEG_A | SEG_B | SEG_D | SEG_E | SEG_G) #define SYMBOL_3 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_G) #define SYMBOL_4 (SEG_B | SEG_C | SEG_F | SEG_G) #define SYMBOL_5 (SEG_A | SEG_C | SEG_D | SEG_F | SEG_G) #define SYMBOL_6 (SEG_A | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G) #define SYMBOL_7 (SEG_A | SEG_B | SEG_C) #define SYMBOL_8 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G) #define SYMBOL_9 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G) #define SYMBOL_MINUS (SEG_G) #define SYMBOL_A (SEG_A | SEG_B | SEG_C | SEG_E | SEG_F | SEG_G) #define SYMBOL_C (SEG_A | SEG_E | SEG_F | SEG_D) #define SYMBOL_E (SEG_A | SEG_D | SEG_E | SEG_F | SEG_G) #define SYMBOL_H (SEG_B | SEG_C | SEG_E | SEG_F | SEG_G) #define SYMBOL_P (SEG_A | SEG_B | SEG_E | SEG_F | SEG_G) #define SYMBOL_G (SEG_A | SEG_E | SEG_F) #define SYMBOL_L (SEG_D | SEG_E | SEG_F) #define SYMBOL_F (SEG_A | SEG_E | SEG_F | SEG_G) #define SYMBOL_d (SEG_B | SEG_C | SEG_D | SEG_E | SEG_G) #define SYMBOL_b (SEG_C | SEG_D | SEG_E | SEG_F | SEG_G) #define SYMBOL_rP (SEG_A | SEG_B | SEG_C | SEG_E | SEG_F) // // Глобальные переменные // static uint16_t ledGRID[LED_DATA_LENGTH / 2]; // текущее состояние экрана static uint8_t currentBrightness = 1; // текущая яркость static uint8_t digits[] = { SYMBOL_0, SYMBOL_1, SYMBOL_2, SYMBOL_3, SYMBOL_4, SYMBOL_5, SYMBOL_6, SYMBOL_7, SYMBOL_8, SYMBOL_9 }; // static uint16_t saveGRID[LED_DATA_LENGTH / 2]; // нужно для сохранения состояния экрана на время теста static uint8_t saveBrightness; // нужно для сохранения яркости на время теста // // // Запись одиночной команды в TM1668 // void writeSingleCommand(const uint8_t command) { digitalWrite(PIN_STB, LOW); shiftOut(PIN_DIO, PIN_CLK, LSBFIRST, command); digitalWrite(PIN_STB, HIGH); delayMicroseconds(1); // Пауза до следующей команды } // // Запись состояния дисплея в TM1668 // void updateDisplay(void) { writeSingleCommand(0x40); // запись данных, автоматический адрес digitalWrite(PIN_STB, LOW); shiftOut(PIN_DIO, PIN_CLK, LSBFIRST, 0xC0); // Установка адреса в 0 uint8_t * p = (uint8_t *) ledGRID; for (int8_t i = 0; i < LED_DATA_LENGTH; i++, p++) shiftOut(PIN_DIO, PIN_CLK, LSBFIRST, *p); // запись данных digitalWrite(PIN_STB, HIGH); delayMicroseconds(1); // Пауза до следующей команды } // // Чтение состояния кнопок с TM1668 // void readKeyData(uint16_t * data) { digitalWrite(PIN_STB, LOW); shiftOut(PIN_DIO, PIN_CLK, LSBFIRST, 0x42); // чтение данных pinMode(PIN_DIO, INPUT_PULLUP); delayMicroseconds(1); * data = shiftIn(PIN_DIO, PIN_CLK, LSBFIRST) + (shiftIn(PIN_DIO, PIN_CLK, LSBFIRST) << 8); pinMode(PIN_DIO, OUTPUT); digitalWrite(PIN_STB, HIGH); } // // Установить яркость от 0 (выключено) до 8 // (возвращает старую яркость) // static inline uint8_t setBrightness(const uint8_t newBrighness) { const uint8_t res = currentBrightness; currentBrightness = (newBrighness > 8) ? 8 : newBrighness; if (currentBrightness == 0) writeSingleCommand(0x80); // Выключить дисплей else writeSingleCommand(0x88 + (currentBrightness - 1)); // Установить яркость return res; } // // Увеличить яркость на 1 (возвращает старую яркость) // static inline uint8_t increaseBrightness(void) { const uint8_t res = currentBrightness; if (currentBrightness < 8) setBrightness(currentBrightness + 1); return res; } // // Уменьшить яркость на 1 (возвращает старую яркость) // static inline uint8_t decreaseBrightness(void) { const uint8_t res = currentBrightness; if (currentBrightness > 0) setBrightness(currentBrightness - 1); return res; } // // Показать тест экрана // (все символы включены на максимальной яркости) // void showTest(void) { memcpy(saveGRID, ledGRID, sizeof(saveGRID)); ledGRID[0] = 3; ledGRID[1] = 0xFF; ledGRID[2] = 0xFF; ledGRID[3] = 0xFF; ledGRID[4] = 0xFF; updateDisplay(); saveBrightness = setBrightness(8); } // // Восстановить экран после теста // void hideTest(void) { memcpy(ledGRID, saveGRID, sizeof(saveGRID)); updateDisplay(); setBrightness(saveBrightness); } // // Показать цифру value (0-9) в позиции digit (1-4) // при этом, если у цифры горит дополнительный символ, сохраняем его // static inline void setDigit(const int8_t digit, const uint8_t value) { if (digit < 0 || digit > 6) return; // цифры у нас с 1-ой по 4-ую слева направо ledGRID[digit] = value; // не обижать дополнительный символ, если есть } // // Показать число m в двух правых цифрах (типа минуты или там секунды) // static inline void showMinutes(const int8_t m) { setDigit(0, digits[m % 10]); setDigit(1, digits[m / 10]); } // // Показать число h в двух левых цифрах (типа часы или там минуты) // static inline void showHours(const int8_t h) { setDigit(2, digits[h % 10]); setDigit(3, digits[h / 10]); } // // Показать и часы, и минуты // static inline void showClock(const int8_t h, const int8_t m) { showHours(h); showMinutes(m); } ///////////////////////////////////////////////////////////// //////////// КОНЕЦ "библиотеки" ДЛЯ TM1668 //////////// ///////////////////////////////////////////////////////////// void setup(void) { // // Инициализация пинов pinMode(PIN_CLK, OUTPUT); pinMode(PIN_DIO, OUTPUT); pinMode(PIN_STB, OUTPUT); digitalWrite(PIN_STB, HIGH); digitalWrite(PIN_CLK, HIGH); // // Инициализация экрана writeSingleCommand(INIT_7x11); // Режим отображения (1 и 2 - ничего не меняется) setBrightness(currentBrightness); // // Пишем на экране слово ПОПА setDigit(3, SYMBOL_rP); setDigit(2, SYMBOL_0); setDigit(1, SYMBOL_rP); setDigit(0, SYMBOL_A); updateDisplay(); // // Даём 5 секунд полюбоваться delay(5000); // // Рисуем нулевое время showClock(0, 0); updateDisplay(); setDigit(0, SYMBOL_0); setDigit(1, SYMBOL_1); setDigit(2, SYMBOL_2); setDigit(3, SYMBOL_3); setDigit(4, SYMBOL_4); setDigit(5, SYMBOL_5); updateDisplay(); } void loop(void) {} ///// Всё! Веселье закончилось!#include <stdio.h> static int serial_fputchar(const char ch, FILE *stream) { ((void*)stream); Serial.write(ch); return ch; } static FILE *serial_stream = fdevopen(serial_fputchar, NULL); // // Подключение пинов // разъём отверстиями кверху и синей стороной шлейфа к себе, тогда рсапиновка: // GND 3,3V CLK DIO STB OUT-IR 5V // #define PIN_DIO 9 #define PIN_CLK 8 #define PIN_STB 7 #define INIT_6x12 2 #define INIT_7x11 3 ///////////////////////////////////////////////////////////// ///////////// ТИПА "библиотека" ДЛЯ TM1668 //////////// ///////////////////////////////////////////////////////////// // // при том подключении, что есть // достаточно 10 байтов на светодиоды и 2 на кнопки // #define LED_DATA_LENGTH 14 #define KEY_DATA_LENGTH 2 // // Маски нажатых кнопок (слева направо) // #define KEY_1 0x0800 #define KEY_2 0x0100 #define KEY_3 0x0008 #define KEY_4 0x0001 // // Подключено 5 "цифр". // 0-ая - это двоеточие, залействовано только два младших бита // 1-4 - собственно цифры слева направо. // В цифрах задействовано 7 битов под сегменты (с 0-го по 6-ой) // и 7-ой бит под доплнительный символ (питание, конверт и т.п.) // #define LE6 0x0001 #define LE5 0x0020 #define LE7 0x0040 #define LE8 0x0040 #define SEG_A 0x0001 #define SEG_F 0x0002 #define SEG_B 0x0004 #define SEG_G 0x0008 #define SEG_C 0x0010 #define SEG_DP 0x0020 #define SEG_D 0x0040 #define SEG_E 0x0080 // // Символы (цифры / буквы, можно ещё добавить всяких) // #define SYMBOL_0 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F) #define SYMBOL_1 (SEG_B | SEG_C) #define SYMBOL_2 (SEG_A | SEG_B | SEG_D | SEG_E | SEG_G) #define SYMBOL_3 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_G) #define SYMBOL_4 (SEG_B | SEG_C | SEG_F | SEG_G) #define SYMBOL_5 (SEG_A | SEG_C | SEG_D | SEG_F | SEG_G) #define SYMBOL_6 (SEG_A | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G) #define SYMBOL_7 (SEG_A | SEG_B | SEG_C) #define SYMBOL_8 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G) #define SYMBOL_9 (SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G) #define SYMBOL_MINUS (SEG_G) #define SYMBOL_A (SEG_A | SEG_B | SEG_C | SEG_E | SEG_F | SEG_G) #define SYMBOL_C (SEG_A | SEG_E | SEG_F | SEG_D) #define SYMBOL_E (SEG_A | SEG_D | SEG_E | SEG_F | SEG_G) #define SYMBOL_H (SEG_B | SEG_C | SEG_E | SEG_F | SEG_G) #define SYMBOL_P (SEG_A | SEG_B | SEG_E | SEG_F | SEG_G) #define SYMBOL_G (SEG_A | SEG_E | SEG_F) #define SYMBOL_L (SEG_D | SEG_E | SEG_F) #define SYMBOL_F (SEG_A | SEG_E | SEG_F | SEG_G) #define SYMBOL_d (SEG_B | SEG_C | SEG_D | SEG_E | SEG_G) #define SYMBOL_b (SEG_C | SEG_D | SEG_E | SEG_F | SEG_G) #define SYMBOL_rP (SEG_A | SEG_B | SEG_C | SEG_E | SEG_F) // // Глобальные переменные // static uint16_t ledGRID[LED_DATA_LENGTH / 2]; // текущее состояние экрана static uint8_t currentBrightness = 1; // текущая яркость static uint8_t digits[] = { SYMBOL_0, SYMBOL_1, SYMBOL_2, SYMBOL_3, SYMBOL_4, SYMBOL_5, SYMBOL_6, SYMBOL_7, SYMBOL_8, SYMBOL_9 }; // static uint16_t saveGRID[LED_DATA_LENGTH / 2]; // нужно для сохранения состояния экрана на время теста static uint8_t saveBrightness; // нужно для сохранения яркости на время теста // // // Запись одиночной команды в TM1668 // void writeSingleCommand(const uint8_t command) { digitalWrite(PIN_STB, LOW); shiftOut(PIN_DIO, PIN_CLK, LSBFIRST, command); digitalWrite(PIN_STB, HIGH); delayMicroseconds(1); // Пауза до следующей команды } // // Запись состояния дисплея в TM1668 // void updateDisplay(void) { writeSingleCommand(0x40); // запись данных, автоматический адрес digitalWrite(PIN_STB, LOW); shiftOut(PIN_DIO, PIN_CLK, LSBFIRST, 0xC0); // Установка адреса в 0 uint8_t * p = (uint8_t *) ledGRID; for (int8_t i = 0; i < LED_DATA_LENGTH; i++, p++) shiftOut(PIN_DIO, PIN_CLK, LSBFIRST, *p); // запись данных digitalWrite(PIN_STB, HIGH); delayMicroseconds(1); // Пауза до следующей команды } // // Чтение состояния кнопок с TM1668 // void readKeyData(uint16_t * data) { digitalWrite(PIN_STB, LOW); shiftOut(PIN_DIO, PIN_CLK, LSBFIRST, 0x42); // чтение данных pinMode(PIN_DIO, INPUT_PULLUP); delayMicroseconds(1); * data = shiftIn(PIN_DIO, PIN_CLK, LSBFIRST) + (shiftIn(PIN_DIO, PIN_CLK, LSBFIRST) << 8); pinMode(PIN_DIO, OUTPUT); digitalWrite(PIN_STB, HIGH); } // // Установить яркость от 0 (выключено) до 8 // (возвращает старую яркость) // static inline uint8_t setBrightness(const uint8_t newBrighness) { const uint8_t res = currentBrightness; currentBrightness = (newBrighness > 8) ? 8 : newBrighness; if (currentBrightness == 0) writeSingleCommand(0x80); // Выключить дисплей else writeSingleCommand(0x88 + (currentBrightness - 1)); // Установить яркость return res; } // // Увеличить яркость на 1 (возвращает старую яркость) // static inline uint8_t increaseBrightness(void) { const uint8_t res = currentBrightness; if (currentBrightness < 8) setBrightness(currentBrightness + 1); return res; } // // Уменьшить яркость на 1 (возвращает старую яркость) // static inline uint8_t decreaseBrightness(void) { const uint8_t res = currentBrightness; if (currentBrightness > 0) setBrightness(currentBrightness - 1); return res; } // // Показать тест экрана // (все символы включены на максимальной яркости) // void showTest(void) { memcpy(saveGRID, ledGRID, sizeof(saveGRID)); ledGRID[0] = 3; ledGRID[1] = 0xFF; ledGRID[2] = 0xFF; ledGRID[3] = 0xFF; ledGRID[4] = 0xFF; updateDisplay(); saveBrightness = setBrightness(8); } // // Восстановить экран после теста // void hideTest(void) { memcpy(ledGRID, saveGRID, sizeof(saveGRID)); updateDisplay(); setBrightness(saveBrightness); } // // Показать цифру value (0-9) в позиции digit (1-4) // при этом, если у цифры горит дополнительный символ, сохраняем его // static inline void setDigit(const int8_t digit, const uint8_t value) { if (digit < 0 || digit > 6) return; // цифры у нас с 1-ой по 4-ую слева направо ledGRID[digit] = value; // не обижать дополнительный символ, если есть } // // Показать число m в двух правых цифрах (типа минуты или там секунды) // static inline void showMinutes(const int8_t m) { setDigit(0, digits[m % 10]); setDigit(1, digits[m / 10]); } // // Показать число h в двух левых цифрах (типа часы или там минуты) // static inline void showHours(const int8_t h) { setDigit(2, digits[h % 10]); setDigit(3, digits[h / 10]); } // // Показать и часы, и минуты // static inline void showClock(const int8_t h, const int8_t m) { showHours(h); showMinutes(m); } ///////////////////////////////////////////////////////////// //////////// КОНЕЦ "библиотеки" ДЛЯ TM1668 //////////// ///////////////////////////////////////////////////////////// void setup(void) { stdout = serial_stream; // эта строка первая в setup Serial.begin(115200); // // Инициализация пинов pinMode(PIN_CLK, OUTPUT); pinMode(PIN_DIO, OUTPUT); pinMode(PIN_STB, OUTPUT); digitalWrite(PIN_STB, HIGH); digitalWrite(PIN_CLK, HIGH); // // Инициализация экрана writeSingleCommand(INIT_7x11); // Режим отображения (1 и 2 - ничего не меняется) setBrightness(currentBrightness); // // Пишем на экране слово ПОПА setDigit(3, SYMBOL_rP); setDigit(2, SYMBOL_0); setDigit(1, SYMBOL_rP); setDigit(0, SYMBOL_A); updateDisplay(); // // Даём 5 секунд полюбоваться delay(5000); // // Рисуем нулевое время showClock(0, 0); updateDisplay(); setDigit(0, SYMBOL_0); setDigit(1, SYMBOL_1); setDigit(2, SYMBOL_2); setDigit(3, SYMBOL_3); setDigit(4, SYMBOL_4); setDigit(5, SYMBOL_5); updateDisplay(); printf("Press key\n"); } void loop(void) { uint16_t newKeys; readKeyData(& newKeys); printf("0x%02X\n", newKeys); } ///// Всё! Веселье закончилось!