Модуль 4 LED на драйвер чипе ТМ1637
- Войдите на сайт для отправки комментариев
Ср, 08/10/2014 - 15:19
Здравствуйте.
Имеется такой индикатор.

Подключаю к ARDUINO - всё вроде работает. При работе использую библиотеку: http://yadi.sk/d/qBMFhwjl8khMh.
#include "TM1637.h"
#include <Arduino.h>
static int8_t TubeTab[] = {0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};//0~9,A,b,C,d,E,F
TM1637::TM1637(uint8_t Clk, uint8_t Data)
{
Clkpin = Clk;
Datapin = Data;
pinMode(Clkpin,OUTPUT);
pinMode(Datapin,OUTPUT);
}
void TM1637::init(void)
{
clearDisplay();
}
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);
wr_data >>= 1;
digitalWrite(Clkpin,HIGH);
}
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);
digitalWrite(Datapin,LOW);
digitalWrite(Clkpin,LOW);
}
//End of transmission
void TM1637::stop(void)
{
digitalWrite(Clkpin,LOW);
digitalWrite(Datapin,LOW);
digitalWrite(Clkpin,HIGH);
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::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)
{
_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;
}
}
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;
}
Как я понимаю при помощи данной библиотеки можно подключить только один индикатор. Посмотрел альтернативные решения – тоже одно устройство.
Вопрос, есть или библиотека для работы с несколькими индикаторами?
Похоже я тормознул - всё можно, нужно пробовать.
Прикольно, перерыл весь инет на предмет бага в библиотеке TM1637.cpp которая может вешать контроллер, и не где этого не нашел, такое впечатление что только у меня вылезло это! В общем от лирики к делу: валялся у меня контроллер ATiny2313A решил на нем сделать часы(так поиграться) столкнулся с проблемой нехватки памяти в МК, прикупил 4313 вроде пока хватает памяти(4к), но вот была бида что МК, хаотично постоянно зависал, уже думал что бракованный МК купил, да вот оказалось что нет, потратив 2 дня на поиски проблемы пришел к выводу что 2313 тоже иногда виснит но реже, начал копать и выяснил что вешает контроллер вызов tm1637.display(TimeDisp), начал копаться в библиотеке и нашел баг,
отрывок кода(оригинал):
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); wr_data >>= 1; digitalWrite(Clkpin,HIGH); } 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); }отрывок кода(Исправленный):
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); wr_data >>= 1; digitalWrite(Clkpin,HIGH); } 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; break; } pinMode(Datapin,INPUT); } pinMode(Datapin,OUTPUT); }Что характерно на UNO не чего не висло, а вот на других МК проявлялось, думаю данная информация будет полезна не только мне, если кто то захочет поиграться с дисплеями часов на основе TM1637
Эта библиотека - один большой баг, она написана без понимания работы линий с подтяжкой. Зависание неизбежно при вхождении в цикл while. Войти в него можно, пропустив ACK от TM1637. Выйти из него неможно (почти по-польски).
"если кто то захочет поиграться с дисплеями часов на основе TM1637" тому следует не использовать данную библиотеку, а разобраться с 1637.
Просто в UNO сигнал ACK стабильно приходил. А на дургом контроллере - не всегда) Наверное, тайминги надо подправить. А отсутствие аварийного выхода из цикла - это, конечно, беда.
Прикольно, перерыл весь инет на предмет бага в библиотеке TM1637.cpp которая может вешать контроллер, и не где этого не нашел, такое впечатление что только у меня вылезло это!
Ай, спасибо тебе, добрый человек!
Очень похоже на мою ситуацию: часы, которые прекрасно отпахали все лето у меня на подоконнике на Леонарде в виде клубка проводов, после того, как я перевоплотил их на Про-Микро и без клубка проводов стали подвисать ежедневно в районе 8 утра. Я башку чуть не сломал - сначала грешил на модуль реал-тайм на 3231 - думал там какие-нибудь будильники срабатывают, потом на Про-Микро... Стал осциллографом тыкаться - вроде что-то есть на выводах от МК к индикатору - значит, думаю, не виснет контроллер. А на код как-то и не думал совсем: вроде он работал, и работал стабильно. Уже подумал, что дело в индикаторе, и вот набрел на этот тред и это сообщение. Очень похоже все получается: когда индикация "замерзает" осциллом видно, что на SCK высокий уровень постоянный, а на Дате коротенькие инверсные импульсы - пару десятков микросекунд и с периодом порядка 4мс. Учитывая, что и Дата и ЦЛК подтянуты к плюсу, прям напоминает результат вот этого:
//begin TM1637.cpp fragment 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); } //end TM1637.cpp fragmentУже залил было поправленный код с брейком, как потом обнаружил, что та библиотечка, которой мы пользуемся (DigitalTube ?) образца 2012-го года - это уже история и довольно дремучая. Есть гораздо свежее.
Вот ссыль:
https://github.com/Seeed-Studio/Seeed_Grove_4Digital_Display_g
В частности, процедура ожидания ACK там капитально другая - без вечности, а лишь с задержками. Попробую. О результатах отпишу. Очень надеюсь, что дело в этом.
Итак, вчера пробовал вручную установку разного времени на часах, в частности, 8 часов и около этого. Сегодня первый день с момента сборки часов, когда я с утра не наблюдаю "замороженный" на 8 часах индикатор. То-есть, видимо, установка кода со свежей версией библиотеки решила проблему.
Если вдруг что-то вылезет позже, дам знать.
Итак, вчера пробовал вручную установку разного времени на часах, в частности, 8 часов и около этого. Сегодня первый день с момента сборки часов, когда я с утра не наблюдаю "замороженный" на 8 часах индикатор. То-есть, видимо, установка кода со свежей версией библиотеки решила проблему.
Если вдруг что-то вылезет позже, дам знать.
Спасибо. У меня такая же ситуация с TM1637 была. Тормозила бегущая строка вместе с ним в 8:00 и далее. Поменял библиотеку и всё работает(пока работает) думаю что будет нормально. Я не программист-поэтому ещё раз большое спасибо-иначе я бы не разобрался бы.
Там, в этой библиотеке есть еще один прикол (TM1637.cpp). Когда выводите данные на дисплей, они дублируются в серийный монитор. По началу вообще понять не мог почему идет задвоение.
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)Встречается не во всех библиотеках, у меня было. Может кому поможет.
Прикольно, перерыл весь инет на предмет бага в библиотеке TM1637.cpp которая может вешать контроллер, и не где этого не нашел, такое впечатление что только у меня вылезло это!
Благодарствую, спас. Всё висло насмерть при передергивании питания, только break; и помог. Теперь всё нормально. Другие библтотеки не помогали.
Прикольно, перерыл весь инет на предмет бага в библиотеке TM1637.cpp которая может вешать контроллер, и не где этого не нашел, такое впечатление что только у меня вылезло это!
Спасибо тебе мил человек - тоже весь мозг сломал откуда у глюка ноги растут. причем что странно - на готовом модуле robodyn проблемы не было, а когда то же самое пытался воспроизвести на рассыпухе - вешалось колом в момент обращения к библиотеке. Поставил break - и все заработало!