Go Down

Topic: TM1638 display library (Read 17008 times) previous topic - next topic

int2str

Attached is a new "library" for the 7-segment/LED displays based on the TM1638 controller.
These displays can be had for cheap on eBay etc.

The attachment is not a "library" in the usual sense. To make it work you'll have to edit the TM1638.h header file and configure which pins to use in that file. No run-time pin configuration is available to keep the library compact and fast.

The library uses direct port access to dramatically speed up the display/button access and to keep the compiled size small. It also uses a font stored in PROGMEM to keep SRAM usage down.

There is an existing library for the TM16xx based displays, that is easier to use, available here:
http://code.google.com/p/tm1638-library/

Then why use the attached library?

Take this very simple program, counting up to 65534 and reading the button states, as an example:
Code: [Select]
void setup()
{
    TM1638 disp(2, 1, 0); 
    for (uint16_t  j = 0; j != 0xffff; ++j)
    {
        disp.setDisplayToDecNumber(j, 0);
        disp.setLEDs(disp.getButtons());
    }
}

void loop() {}


Using the TM16xx library for code.google.com, the compiled binary has the following size (note the 88 bytes of SRAM used as well):
Code: [Select]
text    data     bss     dec     hex filename
2814      88       9    2911     b5f obj/tm1638_org.elf


With the new, attached library, the binary size is:
Code: [Select]
text    data     bss     dec     hex filename
1178       0       0    1178     49a obj/tm1638.elf


Running on a Digispark (ATTiny85), the program takes this long to count from 0-65534 while checking the buttons and setting the LEDs accordingly:

"Old" library:
5min, 40s or 340s.

"New" library:
39s (!!!!)

So the old library allows about 120 refreshes per second while the new one achieves >1600.
And that's on an ATTiny85...

While you rarely want/need 1600 updates per second, speeding up the screen updates and button checks frees up your controller to do other things.

robtillaart

#1
Sep 28, 2013, 05:01 pm Last Edit: Sep 28, 2013, 05:11 pm by robtillaart Reason: 1
Thanks for sharing,

A quick look at the lib showed some well engineered code but also some /= 10 (3x) and %10 (2x) which are both quite expensive operations

you might check the divmod10 discussion to speed up the lib even further - http://forum.arduino.cc/index.php?topic=167414.0 -
Should speed up your lib too. Esp when using the highly optimized asm version - http://forum.arduino.cc/index.php?topic=167414.msg1291081#msg1291081 -
Could you please check what numbers you get as I do not have such device?

alternatively
Code: [Select]

    while (number && offset != 0xFF)
    {
        setDigit(offset--, number % 10);
        number /= 10;
    }


could also be made quite faster by using one additional var

Code: [Select]

    while (number && offset != 0xFF)
    {
        uint16_t x = number / 10;
        setDigit(offset--, number - x*10);
        number = x;
    }

(this code snippet appears twice)

2) Please add some example sketches to the library to show how to use it. This might include your performance test.

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

int2str

A quick look at the lib showed some well engineered code but also some /= 10 (3x) and %10 (2x) which are both quite expensive operations

you might check the divmod10 discussion to speed up the lib even further - http://forum.arduino.cc/index.php?topic=167414.0


Thanks for the tips!
I did incorporate divmod10_asm() and it indeed made quite a difference.
While I was performance tweaking, I un-rolled the send loop and did some other tweaks - hopefully without compromising the code readability too much.

As it stands now, it can count to 65534 while checking all the buttons and setting the LEDs in <27s! Over 2400 screen updates per second!

The code has increased in size a bit with the example program now clocking in at 1944 bytes. Still acceptable in my book....

robtillaart

#3
Sep 30, 2013, 01:15 pm Last Edit: Sep 30, 2013, 01:24 pm by robtillaart Reason: 1
Quote
The code has increased in size a bit with the example program now clocking in at 1944 bytes. Still acceptable in my book....


you should make it conditional, something like

in .h file
#define TM1638_HIGHSPEED

in .cpp file
#ifdef TM1638_HIGHSPEED
 divmod10(x,y,z);
#elseif
  x = y/10;
  z = y%10;
#endif
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

gigislab

Hi,
Thanks for your very good work.

As you know those 7 segments modules can be put in daisy chain to have up to 6 displays driven by 6 different Strobo pins.
Your fast library is very important due to the bigger data throughput it can provide without so much latence and delay. It is more important to be fast as the displays are more.

I'm absolutely not familiar with CPP, so I'm messing around a way to have separates instances of the same library being referred from the main c by adding the strobe pin value, so to drive those 6 displays with no hassle.

Can you help providing a modified library where the strobe pin can be provided for each TM1638 command routine?

Thanks so much

Gigislab

soraz

can explain me a simple code to use this fast-tm1638 library with arduino code ?

-->>> code sample <<<--
#include <TM1638.h>
#include <TM1638Font.h>

void setup()
{
    TM1638 disp(); 
    for (uint16_t  j = 0; j != 0xffff; ++j)
    {
        disp.setDisplayToDecNumber(j, 0);
        disp.setLEDs(disp.getButtons());
    }
}

void loop() {}
---------------------------------------------

-->>> errors <<<--
sketch_jul09a.ino: In function 'void setup()':
sketch_jul09a:9: error: request for member 'setDisplayToDecNumber' in 'disp', which is of non-class type 'TM1638 ()()'
sketch_jul09a:10: error: request for member 'setLEDs' in 'disp', which is of non-class type 'TM1638 ()()'
sketch_jul09a:10: error: request for member 'getButtons' in 'disp', which is of non-class type 'TM1638 ()()'

thanks for any advance


int2str

Something like this (can't test it right now):

Code: [Select]
#include <TM1638.h>

void setup()
{
    TM1638 disp;
    for (uint16_t j = 0; j != 0xFFFF; ++j)
    {
        disp.setNumber(j);
        disp.setLEDs(disp.getButtons(), 0);
        delay(100);
    }
}

void loop()
{
}

soraz

#7
Jul 09, 2014, 10:44 pm Last Edit: Aug 19, 2014, 03:40 pm by soraz Reason: 1
this work, thanks.
i have modified in TM1638.cpp from uint16_t number to uint32_t number the three sub-routine of setNumber (line 185, 197 and 209)
and added in TM1683.h this lines
// PORTC
// PC0 A0
// PC1 A1
// PC2 A2
// PC3 A3
// PC4 A4
// PC5 A5
//
// PORTD
// PD0 D0/RX
// PD1 D1/TX
// PD2 D2
// PD3 D3
// PD4 D4
// PD5 D5
// PD6 D6
// PD7 D7
//
// PORTB
// PB0 D8
// PB1 D9
// PB2 D10
// PB3 D11/MOSI
// PB4 D12/MISO
// PB5 D13/SCK
//
#define PB4     4 //D12/MISO
#define PB3     3 //D11/MOSI
#define PB2     2 //D10
//

attached modified library with display connected in D3 (STB0),D4 (CLK), D5 (DIO).

int2str

#8
Mar 26, 2015, 05:43 am Last Edit: Mar 26, 2015, 01:40 pm by robtillaart Reason: url
It's been a while, but the "library" is now available on GitHub:
https://github.com/int2str/TM1638

Also added a simple example to demonstrate the usage.

robtillaart

you might add meta info to the header file like
Code: [Select]

//
//    FILE: tm1638.h
//  AUTHOR: int2str
// VERSION: 0.1.02
// PURPOSE: lib for 7 seg display
//     URL: https://github.com/int2str/TM1638
//
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

maphf60

Hello to everyone, I would like to know how to modify the library TM1638 v 1.02 for driver 2 modules TM1638.
Thanks in advance and greetings

kolaha

topik need to be deleted. the library is now changed

jlsilicon

#12
Jul 01, 2018, 01:57 am Last Edit: Jul 05, 2018, 04:46 pm by jlsilicon
Has anybody had trouble with these EBay Tm1638 Modules ?

- I ordered (3) of them - and none seemed to work.
All that works is the Left Power LED.
I am connecting with an Arduino Mini Pro.

I followed the Pinout:
 VCC - 5v from Arduino
 Gnd - GND from Arduino
 STB - strobe pin -> D6
 CLK - clock pin -> D7
 DIO -  data pin -> D8

TM1638 module(8, 7, 6);

I also tried:
TM1638 module(8, 9, 10);


I tried assortment of examples from the github Lib :
 https://github.com/rjbatista/tm1638-library

Also tried this example, still does not work :

Code: [Select]


#include <TM1638.h>

// /// define a module on : DIO data pin 8 , CLK clock pin 9 , STB strobe pin 10
// TM1638 module(8, 9, 10);
/// DIO data, CLK clock , STB strobe connected to pins 8, 7, 6
TM1638 module(8, 7, 6);

unsigned long a = 1;

byte keys;

void setup()
{
 Serial.begin(9600);
 Serial.println("Starting...");
}

void loop()
{
 for (a=1; a<=100; a++)
 {
   Serial.println(a);
   module.setDisplayToDecNumber(a,0,false);
   //module.setLEDs(0xE007);
   module.setLEDs(a);
   delay(100);
 }
 
 module.setDisplayToString("Complete");
 delay(300);

 for(a=1; a<=20; a++)
 {
   keys = module.getButtons();
   if(keys != 0  &&  keys != 255)
     Serial.println(keys);

   // light the first 4 red LEDs and the last 4 green LEDs as the buttons are pressed
   module.setLEDs(((keys & 0xF0) << 8 ) | (keys & 0xF));

   delay(100);
 }
}



Serial just returns :
- "Starting..."
- counting from 1 to 100
- 255 for the keys - pressed or not

None of the Tutorials seem to specify Resistors or Pullups needed.

Does the Mini Pro have enough power to drive the Tm1638 ?

Does this Library / Tm1638 work on the Arduino Mini Pro ??

jlsilicon

#13
Jul 06, 2018, 02:51 am Last Edit: Jul 09, 2018, 06:47 pm by jlsilicon
-
I found out that the Tm1638 Lib/Code works on the UNO.

Tried on a second Arduino mini Pro.
Works on this one.

* Must be a Bad Arduino Mini Pro Brd.
Programs, Blink works, but Tm1638 does not work - not with Pins 7,8,9 nor Pins 10,11,12.
* Some of the Arduino Outputs must be damaged.

-

Go Up