Где можно скачать библиотеку для "4-Bit LED Digital Tube Module"?

ExtreMe83
Offline
Зарегистрирован: 15.11.2014

http://ru.aliexpress.com/item/High-Quality-4-Bits-Digital-Tube-LED-Displ...

дисплей сделан на 2 сдвиговых регистрах TM74HC595

что то как то не хочется самому перебирать биты для сдвигового регистра, мош кто знает где есть библиотека для этой штуки?

verhmax
Offline
Зарегистрирован: 21.12.2014

https://github.com/reeedstudio/libraries/blob/master/DigitalTube/TM1637.h

#include <TM1637.h>
#define CLK 12
#define DIO 13
TM1637 disp(CLK,DIO);

void setup()
{
disp.set(5);//BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7; яркость дисплея
disp.init(D4056A);
disp.display("1.234"); // выводит на дисплей
}

 

verhmax
Offline
Зарегистрирован: 21.12.2014

код привел для другого модуля (не заметил с первого раза)

http://ru.aliexpress.com/item/Free-shipping-4-digital-display-with-adjus...

ExtreMe83
Offline
Зарегистрирован: 15.11.2014

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

ExtreMe83
Offline
Зарегистрирован: 15.11.2014

вот, мош кому интересно будет
http://forum.arduino.cc/index.php?topic=235453.0

valerik88
Offline
Зарегистрирован: 23.02.2016

Короче пришли мне 2 индикатора из китая, покопался я по форумам, разобрался в принципе работы, нашёл пару работающих кусков кода и написал библиотеку для ардуинки.

"4-Bit LED Digital Tube Module" на двух чипах TM74HC595

Качаем.

https://github.com/kostarev/TM74HC595-4dig-display/archive/master.zip

 

daVaska
Offline
Зарегистрирован: 20.03.2016

А можно пожайлуйста по подробней))) как пользоваться новичку? Что куда подключать и какая функция выводит на дисплей?

daVaska
Offline
Зарегистрирован: 20.03.2016

Разобрался! Спасибо valerik88

valerik88
Offline
Зарегистрирован: 23.02.2016

Написал по этому модулю небольшую статью

http://www.catincoat.ru/2016/03/arduino-atmega328-4-bit-led-digital.html

dhog1
Offline
Зарегистрирован: 01.03.2016

Разрешите немного поработать капитаном очевидность, прежде всего для valerk88.

1.  Приведенные по ссылке 7-ми сегментные сборки действительно разные. Одни подключаются через пару сдвиговых регистров 74HC595 (где два чипа на обороте платы модуля, маркируются <что-то там>595) и подразумевают _динамическую_  индикацию, т.е. непрерывное обновление со стороны микроконтроллера, чтобы там что-то светилось (выводилось).

2.  Другие (сборки 7-ми сегментных индикаторов) подключаются через микросхему TM1637, которая сама может поддерживать динамическую индикацию, т.е. не требует вмешательства микроконтроллера для отображения данных. Это там, где на обороте модуля виден один чип (маркируется TM1637), а на индикаторах (модуля, обычно) присутствует двоеточие.

3. Соответственно софт различается. Там, где присутствует TM1637, обычно используют библиотеку, которую можно найти в поисковике как "TM1637.h". По моему IMHO не самая удачная библиотека, но она работает. Кому было нужно, написали свой софт. В случае двух 74HC595 используют софт для динамической индикации (который проще написать, чем найти, IMHO).

4. В случае приведенной valerik88 "библиотеке" для 7-ми сегментной сборки на сдвиговых регистрах 74HC595 динамической индикации обнаружить не удалось.

valerik88
Offline
Зарегистрирован: 23.02.2016

dhog1 пишет:

4. В случае приведенной valerik88 "библиотеке" для 7-ми сегментной сборки на сдвиговых регистрах 74HC595 динамической индикации обнаружить не удалось.

Вот этот пункт не очень понял.  Сможете перефразировать?

dhog1
Offline
Зарегистрирован: 01.03.2016

Вопрос понял. Перефразирую.

В случае приведенной valerik88 "библиотеке" для 7-ми сегментной сборки на сдвиговых регистрах 74HC595 динамическая индикация отсутствует от слова совсем. Автор не разобрался в вопросе и путает других.

Объясняю, если проще прочитать здесь, а не найти в Инете кучу толковых статей по запросу "динамическая индикация".

Принцип ДИ - гарантированное высвечивание разряда (в поразрядной индикации, есть и посегментная, для большого количества разрядов) втечение определенного времени. Нижней границей инерции человеческого зрения принято считать 50 Гц, допустим у нас 4 разряда. Следовательно, характерная частота обновления разряда 200 Гц (4 х 50) или 5 мс. Один раз в 5 мс нужно зажечь разряд, через 5 мс погасить его и зажечь следующий и т.д. Делать это нужно тупо и регулярно.

Если вы поместите выполняющую такую работу функцию в loop, добиться регулярности будет трудно. Кроме мигания разрядами еще температуру померить хочется или клешню роботу поднять, кнопку в титановом велосипеде прокрутить.

Второе и более досадное. Вот чем занимается ваша функция digit4? Она зачем-то с энтузиазмом параметра replay крутит все разряды индикатора (replay раз) и потом сдыхает. Вместо того, чтобы сдохнуть сразу, предварительно высветив нужный разряд. И не дожидаться пинка где-то в loop'е, а быть регулярно вызываемой, гарантированно раз в 5 мс., например.

Управление ДИ семисегментников на паре сдвиговых регистров отработано до блеска и в прямом смысле сводится к программистскому жаргону - "как два байта переслать". Первый для сегментов, второй для разрядов сборки индикаторов. В пару сдвиговых регистров переслать. По прерыванию таймера. И это все, что надо.

Перефразирование закончил.

valerik88
Offline
Зарегистрирован: 23.02.2016

Ну, я не такой уж и программист, сделал как смог.

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

dhog1
Offline
Зарегистрирован: 01.03.2016

Ну не обиделись (или не показали этого), и хорошо. Тут код не критикуют, ворчат на неправильное понимание. Чтобы закрыть тему, коротко.

1. Настраиваете любой таймер на прерывание по переполнению. Характерное время счета - не более 5 мс. Ну это время регенерации разряда индикатора.

2. В теле прерывания таймера по переполнению пишете очень короткий код, те самые два байта переслать. Вы уже делаете это в своем коде. Один байт - уже протранслированный по таблице сегментов код цифры, второй - номер разряда. Обычно объявляют глобальный массив из 8-ми байт (4 разряда х 2 байта) (в примере _data[]), и глобальный указатель на текущую позицию этого массива (_idx). Код в теле прерывания выглядит как-то так:

ISR <таймера по переполнению> {

    _RELOAD_TIMER;                  // загрузить таймер начальным значением, если считает не с нуля

    _idx %= sizeof(_data);           // индекс крутится по кругу

    SEND(_data[_idx++]);
    SEND(_data[_idx++]);
    
}

Теперь все что в буфере _data[] будет отправляться куда надо само по себе.

3. Пишете функцию вроде indicator_write(int nbr), которая принимает то, что нужно вывести, разбирает число на десятичные цифры, транслирует каждую в сегментный код и пишет в буфер _data[], два байта на одну цифру.

void indicator_write(int num) {    // это демо. Учет знака, всякие ведущие нули
                                   // или пробелы - опущено, чтобы не загромождать
unsigned char i, j = 0;            // Смысл - поместить число в пригодном для вывода на индикатор виде
unsigned char digs[4];             // в буфер, откуда самим выводом занимается код прерывания таймера

    if (num < 0) { j = 1; num *= -1; };   // знак, если нужно
    i = 0;
    do {
        digs[i++] = num % 10; num /= 10;    // разобрали по цифрам и сложили в
    } while (num);                          // массив digs[] в обратном порядке; i - кол-во цифр
                                            // где-то глобально таблица кодов сегментов digitToSegment
                                            // транслируем
    for (j = 0; j < i; j++) digs[j] = *(digitToSegment+digs[j]);

#asm("cli")
    _STOP_TIMER;
#asm("sei")                   
                                        // тонкое место - перенос результатов в буфер. Порядок переноса
                                        // зависит от порядка подключения 74HC595 (кто сегментный, кто разрядный)
                                        // и логики - общий катод индикаторов или общий анод
    for (j = 0; j < i; j++) {           // переносим в буфер, откуда код прерывания по переполнению          
        _data[2*j] = ~digs[j];          // таймера будет отправлять эти данные на индикатор
        _data[2*j+1] = (1 << j);        // это схема для китайского индикатора с общим анодом, поэтому инверсия
    };
    _START_TIMER;
}

4. Как бы это все с динамической индикацией. Тему можно закрыть.

5. Если кто это читает. Приобретая недорогие сборки 7-ми сегментников, которые китайские товарищи называют digital tube, следует выбирать common catode (общий катод) версии. В этом случае драйверы вроде MAX7219 (max 8 разрядов) или TM1637 (max 6 разрядов) позволят обходиться без всякой ДИ в своих кодах, сами все сделают. Что делать счастливым обладателям сборок с общим анодом - не знаю (кроме ДИ). Понятно, что ДИ не очень дружит с измерениями и некоторыми протоколами.

valerik88
Offline
Зарегистрирован: 23.02.2016

Обновил библиотеку с учётом замечаний. Скачать можно тут https://sites.google.com/site/fajlydlablogakotavpalto/123/TM74HC595-4dig-display.zip?attredirects=0&d=1

Drambynik
Drambynik аватар
Offline
Зарегистрирован: 14.05.2016

valerik88 пишет:

Обновил библиотеку с учётом замечаний. Скачать можно тут https://sites.google.com/site/fajlydlablogakotavpalto/123/TM74HC595-4dig-display.zip?attredirects=0&d=1

А как точки зажигать?

valerik88
Offline
Зарегистрирован: 23.02.2016

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

Например ты хочешь вывести такой символ:

Смотришь какие сегменты тебе нужно зажечь, и сооветвствующий бит выставляешь в 0, те сегменты, которые не должны гореть, выставляешь в 1.(Тут могу напутать, возможно наоборот, но принцип тот же)

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

dhog1 пишет:

Если вы поместите выполняющую такую работу функцию в loop, добиться регулярности будет трудно. Кроме мигания разрядами еще температуру померить хочется или клешню роботу поднять, кнопку в титановом велосипеде прокрутить.

Вот пример регулятора температуры с выводом на семисигментный индикатор посредством ДИ. В регуляторе задействован детектор перехода сетевого напряжения через 0 (повешен на прерывание), ведется расчет температуры по сопротивлению датчика температуры, ПИ регулирования и воздействия на нагрузку по алгоритму брезенхема. На глаз мерцание не заметно (на видео это эффект от камеры телефона). Если найду код выложу (давно это было). Ни каких прямых записей в порты не применял, всё на стандартных функциях.

Полностью код не нашел, только секция индикации


//выводы сегментов
int A=4,B=3,C=6,D=8,E=11,F=5,G=7;//int A=4,B=3,C=5,D=6,E=7,F=8,G=12;
const int segs[7] = { 
  A, B, C, D, E, F, G };
//выводы знакомест
int CA1=9, CA2=10;
//цифры в двоичном коде
const byte numbers[10] = { 
  0b1000000, 0b1111001, 0b0100100, 0b0110000, 0b0011001, 0b0010010,
  0b0000010, 0b1111000, 0b0000000, 0b0010000 };
int l_main = 20, l_set=100;//яркость символов
//Переменные датчика температуры
double temp=0;
double pre_temp=0;
//double pre_temp=0, k_temp=0.7;
//
double err, ust=20, Kp=20;
int m=0;//экраны 1-текущая темп 2-уставка 3-аварии
boolean FB=0;//флаг кнопки
int aR=0;//флаг потенциометра
int but=19;//кнопка
int ten=13;//семистр
boolean out=0;
int reg,er,zad;
unsigned long PIDMillis;//таймер расчета регулятора
unsigned long tempMillis;//таймер для замера темп
unsigned long scrMillis;//таймер для возврат на главный экран


void setup() {
  pinMode(A, OUTPUT);
  pinMode(B, OUTPUT);
  pinMode(C, OUTPUT);
  pinMode(D, OUTPUT);
  pinMode(E, OUTPUT);
  pinMode(F, OUTPUT);
  pinMode(G, OUTPUT);
  pinMode(CA1, OUTPUT);
  pinMode(CA2, OUTPUT);
  pinMode(ten,OUTPUT);//ывход на тен (симистр)
  pinMode(19,INPUT);//вход кнопки
  pinMode(12,OUTPUT);//точка
  //aR= val (0,1023,1,l_set);
  temp=12;
  //attachInterrupt(0, zero_crosss_int, RISING);//внешнее прерывание
  //test();
 // Serial.begin(9600);
  //настройка потенциометра если не настроен
  //автонастройка регулятора
}

void loop() {
 // unsigned long currentMillis = millis();
  //каждую секунду мерим температуру
 Digit(temp);
 /* if (currentMillis-tempMillis>=1000){
    digitalWrite(12,0);
    
    digitalWrite(12,1);
    tempMillis=currentMillis;
  }*/

}

//разбор на цифры
void Digit(int x){
  int dig1=x/10;
  int dig2=(x-dig1*10);
  scr(dig1,dig2);
}
void scr (int x,int y){
for (int i = 0; i < 7; i++) {//прорисовка символа
  if (bitRead(numbers[y], i)<1){analogWrite(CA1,l);}
  if (bitRead(numbers[x], i)<1){analogWrite(CA2,l);}
    delay(2);
    digitalWrite(segs[i],0);
    delay(2);
    analogWrite(CA1,0);
    analogWrite(CA2,0);
    digitalWrite(segs[i], 1);
}
 
}

Не стал чистить, как есть.

dhog1
Offline
Зарегистрирован: 01.03.2016

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

Не тот ли это yul-i-an, которого на потеху всему форуму учат "классу переключения пина"? И, судя по времени, пока не научили.

Или, освоив пины, yul-i-an решил поучить (меня в том числе) динамической индикации семисегментников? Он, правда, не стал "чистить", а оставил "как есть".

Ну можно прикупить поп-корна, если yul-i-an захочет феерического продолжения "на нагрузку по алгоритму брезенхема".

Gena_
Offline
Зарегистрирован: 14.10.2012

Как регулируется яркость индикаторов ? У меня один блок ярче трех других.

valerik88
Offline
Зарегистрирован: 23.02.2016

Попробуй задать другое значение в таймере прерываний

Timer1.initialize(1500); // set a timer of length 1500

Поэкспериментируй с разными задержками

Gena_
Offline
Зарегистрирован: 14.10.2012

При задержке (1000) яркость стала одинаковая. Респект ! 

uragan
Offline
Зарегистрирован: 23.02.2015

А для 3 -х разрядного индикатора можно использовать?

valerik88
Offline
Зарегистрирован: 23.02.2016

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

valerik88
Offline
Зарегистрирован: 23.02.2016

Обновил библиотеку. Скачать можно тут https://sites.google.com/site/fajlydlablogakotavpalto/123/TM74HC595-4dig-display.zip?attredirects=0&d=1

Добавил функцию dispFloat(float f) для вывода чисел с точкой и отрицательных чисел с минусом.

saftik
Offline
Зарегистрирован: 08.04.2015

за ранее извиняюсь что немного не по теме .
хочу похвастаться моей поделкой на базе такого дисплея.
все исходники прилагаються
https://www.youtube.com/watch?v=APHAS2nvHLw

valerik88
Offline
Зарегистрирован: 23.02.2016

Не по теме в первую очередь потому, что дисплей не тот, который в этой теме обсуждается, просто очень похожий, но управляется другим драйвером

Dallyla
Offline
Зарегистрирован: 23.04.2016

почитайте вот эту статью - http://www.catincoat.ru/2016/03/arduino-atmega328-4-bit-led-digital.html

ИМХО

Yuva
Offline
Зарегистрирован: 14.10.2016

Dallyla пишет:

почитайте вот эту статью - http://www.catincoat.ru/2016/03/arduino-atmega328-4-bit-led-digital.html

ИМХО

 

Пришлось зарегистрироваться, чтоб процитировать Dallyla. Та статья, на которую Вы, Dallyla, ссылаетесь, написана пользователем valerik88. Он сам об этом пишет в начале дискусии. Забавно)))

astroHABT
Offline
Зарегистрирован: 27.03.2017

Сударь, библиотека супер! но! с отображение всех выводимых данных растянуто по времени оооочень сильно. на float отдельное спасибо. появилась необходимость отображать точки не пользуя float. как это организовать на данном дисплее?

 
access777
Offline
Зарегистрирован: 23.05.2017

Копаю аналогичную тему, но для STM32. Нашел вот такую статью

http://narodstream.ru/stm-urok-25-hal-spi-led-dinamicheskaya-indikaciya/

По сути - это дискретно разбросанный тот же модуль с 595-ми сдвиговыми регистрами.  Возможно, будет полезно...

Alexscandal
Offline
Зарегистрирован: 24.05.2017

Вопрос для тех, кто курил библиотеку TM1637.h

Описания не нашел. Только отрывки кода.

Есть функции как, например, writeByte и coding. Что они должны выполнять?

.init(D4056A) вызывает ошибку, без параметра работает.

.display("1.234") не работает. Работает .display(номер разряда, значение) или .display(массив).

Вообщем может есть у кого наводки на описание всего этого?

Плата Leonardo, если нужно.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Alexscandal пишет:
Вообщем может есть у кого наводки на описание всего этого?

А самому прочитать код слабоTM1637.h

#ifndef TM1637_h
#define TM1637_h
#include <inttypes.h>
#include <Arduino.h>

//************definitions for TM1637*********************
#define ADDR_AUTO  0x40
#define ADDR_FIXED 0x44

#define STARTADDR  0xc0
/**** definitions for the clock point of the 4-Digit Display *******/
#define POINT_ON   1
#define POINT_OFF  0
/**************definitions for brightness***********************/
#define  BRIGHT_DARKEST 0
#define  BRIGHT_TYPICAL 2
#define  BRIGHTEST      7
//--------------------------------------------------------//
//Special characters index of tube table
#define INDEX_NEGATIVE_SIGN	16
#define INDEX_BLANK			17
/************definitions for type of the 4-Digit Display*********************/
#define D4036B 0
#define D4056A 1

class TM1637 {
    uint8_t Clkpin;
    uint8_t Datapin;
    uint8_t DecPoint;
    boolean BlankingFlag;
  public:
    uint8_t Cmd_SetData;
    uint8_t Cmd_SetAddr;
    uint8_t Cmd_DispCtrl;
    boolean _PointFlag; 	//_PointFlag=1:the clock point on
    uint8_t _DispType;
    // конструктор
    TM1637(uint8_t, uint8_t);
    void init(uint8_t = D4036B);
    void writeByte(int8_t wr_data);//write 8bit data to tm1637
    void start(void);//send start bits
    void stop(void); //send stop bits
    void display(int8_t DispData[]);
    void display(uint8_t BitAddr, int8_t DispData);
    void display(double Decimal);
    void display(int16_t Decimal);
    void clearDisplay(void);
    void set(uint8_t = BRIGHT_TYPICAL, uint8_t = 0x40, uint8_t = 0xc0); //To take effect the next time it displays.
    void point(boolean PointFlag);//whether to light the clock point ":".To take effect the next time it displays.
    void coding(int8_t DispData[]);
    int8_t coding(int8_t DispData);
};
#endif

TM1637.cpp


/*******************************************************************************/
#include "TM1637.h"
#include <Arduino.h>
static int8_t TubeTab[] = {0x3f, 0x06, 0x5b, 0x4f, //'0','1','2','3'
                           0x66, 0x6d, 0x7d, 0x07, //'4','5','6','7'
                           0x7f, 0x6f, 0x77, 0x7c, //'8','9','A','b'
                           0x39, 0x5e, 0x79, 0x71, //'C','d','E','F'
                           0x40, 0x00
                          };         //"-"," "

// конструктор
TM1637::TM1637(uint8_t Clk, uint8_t Data) {
  Clkpin = Clk;
  Datapin = Data;
  pinMode(Clkpin, OUTPUT);
  pinMode(Datapin, OUTPUT);
}
// инициализация
void TM1637::init(uint8_t DispType) {
  _DispType = DispType;
  BlankingFlag = 1;
  DecPoint = 3;
  clearDisplay();
}
// записать байт
void i2c_write_8(uint8_t dev, uint8_t reg, uint8_t data) {
  //Put Start Condition on TWI Bus
  TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
  //Poll Till Done
  while (!(TWCR & (1 << TWINT)));
  TWDR = dev;
  TWCR = (1 << TWINT) | (1 << TWEN);
  while (!(TWCR & (1 << TWINT)));
  TWDR = reg;
  TWCR = (1 << TWINT) | (1 << TWEN);
  while (!(TWCR & (1 << TWINT)));
  TWDR = data;
  TWCR = (1 << TWINT) | (1 << TWEN);
  while (!(TWCR & (1 << TWINT)));
  TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
  //Wait for STOP to finish
  while (TWCR & (1 << TWSTO));
}
// ......
void TM1637::writeByte(int8_t wr_data) {
  uint8_t i, count1;
  for (i = 0; i < 8; i++) //sent 8bit data
  {
    digitalWrite(Clkpin, LOW);
    if (wr_data & 0x01)digitalWrite(Datapin, HIGH); //LSB first
    else digitalWrite(Datapin, LOW);
    delayMicroseconds(3);
    wr_data >>= 1;
    digitalWrite(Clkpin, HIGH);
    delayMicroseconds(3);

  }
  digitalWrite(Clkpin, LOW); //wait for the ACK
  digitalWrite(Datapin, HIGH);
  digitalWrite(Clkpin, HIGH);
  pinMode(Datapin, INPUT);
  while (digitalRead(Datapin))
  {
    count1 += 1;
    if (count1 == 200) //
    {
      pinMode(Datapin, OUTPUT);
      digitalWrite(Datapin, LOW);
      count1 = 0;
    }
    pinMode(Datapin, INPUT);
  }
  pinMode(Datapin, OUTPUT);

}
//send start signal to TM1637
void TM1637::start(void) {
  // digitalWrite(Clkpin,HIGH);//send start signal to TM1637
  digitalWrite(Datapin, HIGH);
  // delayMicroseconds(2);
  digitalWrite(Datapin, LOW);
  digitalWrite(Clkpin, LOW);
}
//End of transmission
void TM1637::stop(void) {
  digitalWrite(Clkpin, LOW);
  // delayMicroseconds(2);
  digitalWrite(Datapin, LOW);
  //  delayMicroseconds(2);
  digitalWrite(Clkpin, HIGH);
  // delayMicroseconds(2);
  digitalWrite(Datapin, HIGH);
}
//display function.Write to full-screen.
void TM1637::display(int8_t DispData[]) {
  int8_t SegData[4];
  uint8_t i;
  for (i = 0; i < 4; i ++)
    SegData[i] = DispData[i];
  coding(SegData);
  start();          //start signal sent to TM1637 from MCU
  writeByte(ADDR_AUTO);//
  stop();           //
  start();          //
  writeByte(Cmd_SetAddr);//
  for (i = 0; i < 4; i ++)
    writeByte(SegData[i]);        //
  stop();           //
  start();          //
  writeByte(Cmd_DispCtrl);//
  stop();           //
}
//******************************************
void TM1637::display(uint8_t BitAddr, int8_t DispData)
{
  int8_t SegData;
  SegData = coding(DispData);
  start();          //start signal sent to TM1637 from MCU
  writeByte(ADDR_FIXED);//
  stop();           //
  start();          //
  writeByte(BitAddr | 0xc0); //
  writeByte(SegData);//
  stop();            //
  start();          //
  writeByte(Cmd_DispCtrl);//
  stop();           //
}

void TM1637::display(double Decimal) {
  int16_t temp;
  if (Decimal > 9999)return;
  else if (Decimal < -999)return;
  uint8_t i = 3;
  if (Decimal > 0)
  {
    for ( ; i > 0; i --)
    {
      if (Decimal < 1000)Decimal *= 10;
      else break;
    }
    temp = (int)Decimal;
    if ((Decimal - temp) > 0.5)temp++;
  }
  else
  {
    for ( ; i > 1; i --)
    {
      if (Decimal > -100)Decimal *= 10;
      else break;
    }
    temp = (int)Decimal;
    if ((temp - Decimal) > 0.5)temp--;
  }
  DecPoint = i;

  Serial.println(Decimal);
  BlankingFlag = 0;
  display(temp);

}
// вывод десятичного числа
void TM1637::display(int16_t Decimal) {
  int8_t temp[4];
  if ((Decimal > 9999) || (Decimal < -999))return;
  if (Decimal < 0) {
    temp[0] = INDEX_NEGATIVE_SIGN;
    Decimal = abs(Decimal);
    temp[1] = Decimal / 100;
    Decimal %= 100;
    temp[2] = Decimal / 10;
    temp[3] = Decimal % 10;
    if (BlankingFlag)
    {
      if (temp[1] == 0)
      {
        temp[1] = INDEX_BLANK;
        if (temp[2] == 0) temp[2] = INDEX_BLANK;
      }
    }
  }
  else
  {
    temp[0] = Decimal / 1000;
    Decimal %= 1000;
    temp[1] = Decimal / 100;
    Decimal %= 100;
    temp[2] = Decimal / 10;
    temp[3] = Decimal % 10;
    if (BlankingFlag)
    {
      if (temp[0] == 0)
      {
        temp[0] = INDEX_BLANK;
        if (temp[1] == 0)
        {
          temp[1] = INDEX_BLANK;
          if (temp[2] == 0) temp[2] = INDEX_BLANK;
        }
      }
    }
  }
  BlankingFlag = 1;
  display(temp);

}
// очистка экрана
void TM1637::clearDisplay(void) {
  display(0x00, 0x7f);
  display(0x01, 0x7f);
  display(0x02, 0x7f);
  display(0x03, 0x7f);
}
//To take effect the next time it displays.
void TM1637::set(uint8_t brightness, uint8_t SetData, uint8_t SetAddr) {
  Cmd_SetData = SetData;
  Cmd_SetAddr = SetAddr;
  Cmd_DispCtrl = 0x88 + brightness;//Set the brightness and it takes effect the next time it displays.
}

//Whether to light the clock point ":".
//To take effect the next time it displays.
void TM1637::point(boolean PointFlag) {
  if (_DispType == D4036B) _PointFlag = PointFlag;
}
// ......
void TM1637::coding(int8_t DispData[]) {
  uint8_t PointData;
  if (_PointFlag == POINT_ON)PointData = 0x80;
  else PointData = 0;
  for (uint8_t i = 0; i < 4; i ++) {
    if (DispData[i] == 0x7f)DispData[i] = 0x00;
    else DispData[i] = TubeTab[DispData[i]] + PointData;
  }
  if ((_DispType == D4056A) && (DecPoint != 3)) {
    DispData[DecPoint] += 0x80;
    DecPoint = 3;
  }
}
// .....
int8_t TM1637::coding(int8_t DispData) {
  uint8_t PointData;
  if (_PointFlag == POINT_ON)PointData = 0x80;
  else PointData = 0;
  if (DispData == 0x7f) DispData = 0x00 + PointData; //The bit digital tube off
  else DispData = TubeTab[DispData] + PointData;
  return DispData;
}
/*void TM1637::coding(float Decimal,DispData[])
  {
  uint16_t int_part;
  if(Decimal > 9999)return;
  else if(Decimal < -999)return;
  if(Decimal > 0)
  {
	uint8_t i = 0;
	for(i < 3; i ++)
	{
	  if(Decimal < 1000)Decimal *= 10;
	  else break;
	}

  }
  }*/

ПС: Скоро будут спрашивать , а кто нибудь читал учебник русского языка, вместо того что бы самому прочитать.

Для тех кому нужна библиотека то она тут https://yadi.sk/d/Ci5aiYzsqo7qk

Alexscandal
Offline
Зарегистрирован: 24.05.2017

qwone пишет:

А самому прочитать код слабоTM1637.h

Умничать я и сам могу.

Код прочитал.

Снова задам вопрос: что делают функции writeByte и coding.

Не хотите отвечать? Не надо.

Ответят другие.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Alexscandal пишет:
Снова задам вопрос: что делают функции writeByte и coding.
Там же понятным , для умеющего читать на Си, написано- запись байта (уже сформированого в ТМ1637) и перекодирование из значения в нужную форму знака.  Что бы умничать надо знать, а вы даже обижаетесь, когда вам эти знания дают, даже скорее впихивают, так как через пять минут вы все забудете.  А вот вам даташит на понятном языке https://lib.chipdip.ru/110/DOC001110878.pdf . Разумеется на английском, так только на этом языке эти даташиты и пишут.  Но если вы знаете язык Поднебесной, которая эти чипы производит, то вам сюда http://www.haoyuelectronics.com/Attachment/Digitron-Modules-A/TM1637_V2[1].1.pdf

ExtreMe83
Offline
Зарегистрирован: 15.11.2014

Alexscandal пишет:

Вопрос для тех, кто курил библиотеку TM1637.h

эта ветка форума для сдвигового регистра TM74HC595

вопрос для тех кто курил такую библиотеку для TM1637 нужно задавать в соответствующей ветке форума, и тогда будешь получать адекватные ответы. учись пользоваться поиском по форуму

http://arduino.ru/forum/programmirovanie/problema-novichok-4-digit-led-d...

Alexscandal
Offline
Зарегистрирован: 24.05.2017

За наводки спасибо. Данного pdf не находил.

Попробую разобраться.

access777
Offline
Зарегистрирован: 23.05.2017

Как считаете, при использовании RTOS нужна ли динамическая индикация? Или подойдет и первый вариант библиотеки?

access777
Offline
Зарегистрирован: 23.05.2017

Как считаете, при использовании RTOS нужна ли динамическая индикация? Или подойдет и первый вариант библиотеки?

ExtreMe83
Offline
Зарегистрирован: 15.11.2014

удали дублированное сообщение.

тебе что нужно сделать с динамической индикацией?

access777
Offline
Зарегистрирован: 23.05.2017

@Moderator

Прошу удалить это и предыдущее мое сообщение. Спасибо

dim3740
dim3740 аватар
Offline
Зарегистрирован: 25.03.2015

Уважаемые форумчане, знающие TM1637. У меня библиотека, как бы, "вешает" скетч...

http://arduino.ru/forum/obshchii/rabotaet-pri-ide-sam-ne-zapuskaetsyaне

В чем может быть причина? 

tribo
Offline
Зарегистрирован: 23.12.2016

Вот здесь рабочий скетч под модуль 74HC595 https://robojax.com/learn/arduino/?vid=robojax_74HC595_2_digits

 

tribo
Offline
Зарегистрирован: 23.12.2016

Залил скетч и все заработало как надо, удачи всем

 

tribo
Offline
Зарегистрирован: 23.12.2016

xfvlad пишет:

tribo пишет:

Залил скетч и все заработало как надо, удачи всем

 

 

Спасибо. Сохраню себе в архив. Еще отлично работает пример https://alexgyver.ru/tm74hc595_display/

пробовал, именно на этих индикаторах по моей ссылке--не работают!!"

xfvlad
Offline
Зарегистрирован: 06.02.2021

Значит есть отличия в схемотехнике. Должны были работать.

vasilii48
vasilii48 аватар
Offline
Зарегистрирован: 27.01.2018

Уважаемые участники форума пожалуйста подскажите дисплей четырёхразрядный индикатор Quad Display с 74НС595 это аналогичен дисплею 4-Bit LED Digital Module c 74HC595 и можно заменить индикатор Quad Display на 4-Bit LED Digital Module не внося изменения в скетч ардуино подключил на соответствующие пины.

Дисплея  Quad Display с 74НС595 нет, а 4-Bit LED Digital Module c 74HC595.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Купи лучше ТМ1637 и не парь мосх присуцтвующим.