не могу програмно настроить пины на лед драйвере АТ1628

alexey3
Offline
Зарегистрирован: 25.11.2017

В общем есть плата с 7ми сегментными дисплеями. Хочу настроить управление, но вот загвоздка там стоят лед драйвера AT1628 я использовал библиотеку от ТМ1628 но вот беда выводится не на те пины как изменить ? Вернее вопрос даже такой как на драйверах настраивать значение выводов ?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Какая используется библиотека - ХЗ!

Что написано в скетче - ХЗ!

Как светодиоды распаяны на ноги микросхемы - ХЗ!

Ответ на вопрос: ХЗ х ХЗ х ХЗ = ХЗ3

alexey3
Offline
Зарегистрирован: 25.11.2017

библиотека tm1628_Master, смысл прилагать текст скетча не вижу, семисегментные модули припаяны wt4031asr, и извините что так мало инфы дал на форумах почти не был

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Вообще-то, я хотел Вам рассказать как можно настроиться на незнакомую плату (я как раз недавно это делал для TM1668), но ...

alexey3 пишет:

библиотека tm1628_Master

Вы предлагаете мне самому её гуглить, а если их несколько версий, то пытаться угадать какая именно у Вас? Ссылка, видимо, секретная?

alexey3 пишет:

смысл прилагать текст скетча не вижу

Смысла пытаться угадать как именно Вы формируете сегменты не вижу. Раз Вам лень привести скетч, то мне, тем более, лень угадывать что у Вас там написано.

alexey3 пишет:

извините что так мало инфы дал

Да, не извиняйтесь, мне Ваша инфа и не нужна вовсе, у меня-то нет проблемы. Я думал, что это нужно Вам, но, похоже, ошибся.

 

alexey3
Offline
Зарегистрирован: 25.11.2017

Нет вы не ошиблись и мне правдо очень нужно! Вы можете помочь ! Я ето понял Скажите что нужно я всё выложу

Ну вот скетчь но не мой он просто зажигает 2 сегмента

// Testing sketch for DVD LED module with TM1628 IC
// Written by Vasyl Yudin, oct 2012, public domain
// www.blockduino.org

#include <TM1628.h>
// define - data pin D9, clock pin D8 and strobe pin D7
// обьявление портов: DIO - порт D9, CLK - D8, STB - D7
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();  
    }
 /*   
    for(int i=0; i <= 255; i++)
    {
      dvdLED.setLEDoff(i);
      Serial.println();
      Serial.print("  I: ");
      Serial.print(i);
      delay(25);
      dvdLED.clear();    
    }
  */
}
/* sequence of LEDs:
   порядок светодиодов:
    LED_SE0 0x00
    LED_SE1 0x01
    LED_SE2 0x02
    LED_SE3 0x03
    LED_SE4 0x04
    LED_SE5 0x05
    LED_SE6 0x06
    LED_SE7 0x07
    LED_DVD 0x08
    LED_VCD 0x09
    LED_MP3 0x0A
    LED_PLY 0x0B
    LED_PAU 0x0C
    LED_PBC 0x0D
    LED_RET 0x0E
    LED_DTS 0x0F
    LED_DDD 0x10
    LED_CL1 0x11
    LED_CL2 0x12
*/

Если можно както наладить диалог с вами был бы рад

А библиотеку я нашёл наобум и уже не помню где ссылки не осталось ((( Как прикрепить сюда не знаю

Вот на всякий случай фото моего мучения

сегменты называются wt4031asr

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Пока перевставьте вот так, а я через полчаса вернусь и посмотрю.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Я пока смотрю на вот эту библиотеку. Сверьте, у Вас такая или другая?

alexey3
Offline
Зарегистрирован: 25.11.2017

Она самая

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, в таком случае у меня для Вас плохая новость - её писал непрофессионал, а потому менять придётся много.

Для начала я обясню Вам суть проблемы, чтобы Вы понимали главную идею, так Вам будет легче вносить правки - всегда лучше, когда понимаешь, что делаешь.

У 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. Но цифры заданы не через сегменты! Они заданы прямо битами. Поэтому, если Выам придётся менять соответсвие пинам сегментам, то менять придётся сразу в двух (как минимум) местах, что доставит гораздоб больше головной боли. Вот почему я сказал. что писал непрофессионал.

Теперь начнём наш квест.
 
Для начала в файле TM1628.h найдите строку
void setSeg(byte addr, byte num);

у меня она 47. И после неё вставьте строку

void setRaw(byte addr, byte num);

Затем в файле 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));
    }
}

Пока я буду писать, что делать дальше, сделайте это и убедитесь, что программа нормально компилируется (там это называется "проверка", кажется). 

Убедитесь. А я пока пишу дальше.

 

alexey3
Offline
Зарегистрирован: 25.11.2017

скомпилировалось

 

alexey3
Offline
Зарегистрирован: 25.11.2017

Я видно не понял вообще ничего я закоментировал ети строки , но несколько сегментов таки загораются

#define LED_SE0 0x00
#define LED_SE1 0x01
#define LED_SE2 0x02
#define LED_SE3 0x03
#define LED_SE4 0x04
#define LED_SE5 0x05
#define LED_SE6 0x06
#define LED_SE7 0x07
#define LED_DVD 0x08
#define LED_VCD 0x09
#define LED_MP3 0x0A
#define LED_PLY 0x0B
#define LED_PAU 0x0C
#define LED_PBC 0x0D
#define LED_RET 0x0E
#define LED_DTS 0x0F
#define LED_DDD 0x10
#define LED_CL1 0x11
#define LED_CL2 0x12

хотя как я понял не должны совсем

 

alexey3
Offline
Зарегистрирован: 25.11.2017

совсем забыл работаю на ардуине МЕГА 2560

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

alexey3 пишет:

Я видно не понял вообще ничего я закоментировал ети строки , но несколько сегментов таки загораются

В том-то и дело!

У меня аналогичные строки являются основой для всего остального! Именно потому, для Вашей задачи хватило бы только их поменять.

А у автора библиотеки это строки не пришей кобыле хвост - всё остальное сделано само по себе, без них.

Сравниете мои строки 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-ой цифры.

Попробуйте первую, втроую и т.д. цифры (там в комментария написано что менять).

Расскажите, что получилось.

 

alexey3
Offline
Зарегистрирован: 25.11.2017

'class TM1628' has no member named 'setRaw' ошибка компиляции

а теперь так:

'TM1628' does not name a type

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

В прошлом посте я просил Вас вставить в файлы библиотеки setRaw. Вы вставили? В те самые файлы, откуда берётся бибилиотека? Нормально сохранили? Боюсь, что нет. Вставьте как следует, сохраните. Попробуйте перезапустить IDE. И скажите, что получается.

alexey3
Offline
Зарегистрирован: 25.11.2017

всё как вы сказали всё на месте не работает ошибка

 

alexey3
Offline
Зарегистрирован: 25.11.2017

вот кусок из h

	void clear();
	void setSeg(byte addr, byte num);
	void setRaw(byte addr, byte num);
	void setChar(byte _curpos, byte chr);
	void setCursor(byte pos);
	virtual size_t write(byte chr);

а вот из 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();
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так не бывает. Что-то не так.

1. Убедитесь, что Вы правите именно те файлы, которые берёт IDE, а не например, копию библиотеки в том месте, куда Вы её скачали. Скажите где они у Вас расположены. Вы знаете, где установлены библиотеки? Вы именно там правите?

2. Выкладывайте сюда файлы библиотеки которые правили - оба.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Всё правильно.

Значит, см. п.1 в предыдущем посте.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

То, что старый скетч (без setRaw) у Вас компилировался говорит о том, что Вы поправили где-то в другом месте, а рабочая библиотека - не поправлена.

alexey3
Offline
Зарегистрирован: 25.11.2017

C:\Program Files (x86)\Arduino\libraries\TM1628-master это путь к библиотеке именно их правлю

Как прикрепть файлы тут ?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Прикреплять не надо, Вы дали куски пока хватит.

Правите в неправильном месте.

Посмотрите, если ли там рядом папка C:\Program Files (x86)\Arduino\libraries\TM1628

Есть?

alexey3
Offline
Зарегистрирован: 25.11.2017

нету

alexey3
Offline
Зарегистрирован: 25.11.2017

У меня есть скайп и майл если есть возможность через микрофон говорить ето бы упростило задачу )))

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Если нет, ищите папку в которой лежат Ваши скетчи. Все скетчи. Её легко найти. В IDE нажмите "Файл"|"Настройки" И в самом верху увидите "Расположение папки скетчей.

Вот в папке скетчей и лежит подпапка libraries, а в ней должна быть подпапка TM1628. Есть? Вот там надо править.

alexey3
Offline
Зарегистрирован: 25.11.2017

нету там папки библиотек

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Так, ну хорошо, но то место неправильное.

Давайте так.

1. В скетче закомментируйте строку с setRaw

2. Убедитесь, что компилируется.

3. Уберите ту папку TM1628-maste (скопируйте куда-нибудь и удалите нафиг.

4. запустите компиляцию и посмотрите. Скопилировалось?

Кстати, давайте скайп, я позвоню (не удивляйтесь женскому имени - это скайп жены)

alexey3
Offline
Зарегистрирован: 25.11.2017

alexey3148 - скайп

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015
#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();  
    }
 }

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015
#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();  
//    }
 }

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015
#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() {}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

#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() {}
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015
#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() {}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015
#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() {}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015
#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() {}

 

alexey3
Offline
Зарегистрирован: 25.11.2017

ссылка на даташит микросхемы тм1628 http://www.datasheet13.com/tm1628-%D0%B4%D0%B0%D1%82%D0%B0%D1%88%D0%B8%D...

 

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

В этом даташите не описаны команды и регистры памяти. Вот более подробный даташит - 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-ой), план такой. Нафиг любые бибилотеки, гораздо проще всё сделать простым кодом, на основе того, что у меня был. Когда разберёмся, обернуть его в "библиотеку" - как два пальца.

Сначала дожмём дисплей, потом займёмся кнопками, с ними проще (сколько их там у Вас физически, кстати?).

По времени, будь Ваш девайс у меня, я бы дожал его за три-четрые часа, но так, как мы работали сегодня, думаю несколько вечеров потратим. К сожалению, наступающая неделя у меня сумасшедшая (см., а я там руковожу конторой, которая собственно проводит мероприятие). Но посмотрим. Если Вам не горит это прямо "вчера", то за несколько вечеров, пусть не каждый день, без проблем всё сделаем.

Постараюсь завтра заранее уже выложить сектч для начала исследования.

alexey3
Offline
Зарегистрирован: 25.11.2017

Ну в общем у меня кое что получилось

Есть несколько вопросов, Я похоже не использовал библиотеку совсем или я неправильно чтото понял

Ну да ето ладно вот код



#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ти экранчиков

потом в первом пишет по порядку циферки а дальше сбой

С адресацией я так и не понял как она сформирована

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Только 6-ти? Т.е. самые левые таки не работают.

Алексей, пока суд да дело, Вы бы не посмотрели на эти две самые левые цифры, которые мы вчера засветить не смогли, как и куда они подключены. Может они вообще как-то отлельно (мимо этой микросхемы), а если к ней, то к каким пинами. Возьмите мультиметр, посмотрите. А то, легально-то 8 цифр к микросхеме подключить нельзя, значит есть там какая-то хитрость в подключении.

Мы сегодня сделаем всё без библиотеки вовсе, там всё будет в наших руках, так что, прорвёмся.

alexey3
Offline
Зарегистрирован: 25.11.2017

я же говорю все заработали

они по три цифры

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Знаете непонимание оттого, что мы говорим на разных языках.

Давайте, чтобы понимать друг друга, договоримся о терминоголии.

1. Индиатор или цифра - это 7-сегментный индиктор. Их у Вас 8. Давайте пока договоримся об их нумерации справа налево. Самый правый - нулевой, самый левый - седьмой.

2. сегмент - один из восьми сегментов индикатора A, B, ... G, Dp

3. Дополнительный светодиод - отдельно стоящий светодиод, который загорается при включении какого-нибудь неиспользуемого для цифр семента того или иного индикатора.

Как я Вас понял, у Вас светились 7 индикаторов из 8-ми (светились с 0 по 6-ой, а седьмой не светился). Правильно?

То, что при значении 48 светилось два сразу - правильно. Очевидно светились те, которые светилдись при 16 и 32. так ведь? Попрбуйте там не 48, а 64.

Но, по любому, управление этой микросхемой очень простое и мы сегодня просто поуправляем ею "в лоб". Безо всякой библиотеки. Это будет проще потому, что не надло угадывать что там в библиотеке куда выведено.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Сейчас у емня дергание туда сюда, но в 6 я точно свободен и мы этим займёмся.

alexey3
Offline
Зарегистрирован: 25.11.2017

у меня светились 6 семисегментных индикаторов они по три в блоке а не по 4ре как вам кажется ))

Тоесть полностью работали оба модуля по три 7ми сегментных блока

Ну как то так

 

alexey3
Offline
Зарегистрирован: 25.11.2017

По поводу адресов нашёл адреса отдельных светодиодов 2.64-зелёный , 0.64-второй зелёный, 7.64 - первый красный, 6.64 - второй красный

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Не теряйте времени на адреса

#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. Работает установка яркости?

alexey3
Offline
Зарегистрирован: 25.11.2017

вы абсолютно правы загорелось всё

Яркость регулируется

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Отличная новость!

Значит, мы всё без проблем сделаем безо всякого траха с чужой библиотекой (как видите, мы её не используем вовсе).

Кстати, мы договоаривались на 6, но я могу начать сейчас (правда в 5 будет перерыв на полчаса). Если Вы тоже можете, так давайте начнём.

alexey3
Offline
Зарегистрирован: 25.11.2017

Естественно могу

скайп ?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015
//
//	Подключение пинов
// 	разъём отверстиями кверху и синей стороной шлейфа к себе, тогда рсапиновка:
//		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(); // Обновляем экран, если нужно
}

///// Всё! Веселье закончилось!

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015
//
//	Подключение пинов
// 	разъём отверстиями кверху и синей стороной шлейфа к себе, тогда рсапиновка:
//		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) {}

///// Всё! Веселье закончилось!

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015
#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);

}

///// Всё! Веселье закончилось!