Thursday, March 6, 2014

Arduino library for TM1637 Display Module

Update: A new version has been released, includes control of the colon/decimal points.

I needed a small numerical display for a project I'm working on. I found this one on Dealextream. It looks great - a 4 digit module, with a driver and a serial interface - perfect match for my requirements. The product page mentioned that it is driven by a chip called TM1637. A quick search at Google lead me to an Arduino library, made by SeeedStudio that is capable of communicating with the module.

Three weeks later, I have the module at hand. I'm connecting it to an Arduino board, installing the library and uploading one of the example files. Nothing. Total blackness. On the hardware side, with only two digital pins, it's pretty hard to mess things up, so the suspicion falls on the software. The next step is trying to get the datasheet of the TM1637. The chip is made by a company called Titan Microelectronics, which holds a product page for it. Sadly, the link to the datasheet is broken. Searching again, filtering all the "" etc., I find this datasheet, in plain Chinese. With the help of Google Translate, and SeeedStudio's library, the communication protocol gets revealed. The chip uses the I2C protocol, and the sequence required to write display data is as follows (ST - start condition; SP - stop condition):

  • ST - COMM1 (0x40) - SP
  • ST - COMM2 (0xC0) + the first digit to be written
  • digit1 - digit2 - ... - digit4 - SP
  • ST - COMM3 (0x80) + the display brightness - SP

Having all that at hand, I wrote a new library, implementing this protocol. The library is available at GITHUB, including a sample sketch demonstrating its capabilities. The repository also includes a README file explaining how the library should be used and how the module should be connected to the Arduino.

Why did SeeedStudio's library fail?

Browsing through SeeedStudio's code, I found two problems that might cause it to malfunction.
The first one is this:

  digitalWrite(Clkpin,LOW); //wait for the ACK  

The digital output pins are bit-banged to create the I2C signal, but there's no delay. This gives a toggling rate much beyond the specified 400KHz. It's possible that Seeed were testing their module with an 8MHz Arduino, while my module was 16MHz, raising the toggle rate even further away from the specification.

The second problem also arises from the code snippet above. I2C is wired-and bus, meaning it should never be driven high.When a logic '1' is desirable, the output of the Arduino should be put in high-impedance state allowing the pull-up resistor to pull the line to its high level. This is unlikely to cause an immediate problem, but in the long term it may cause the reliability of the components to degrade.