Library to work with displays based on TM1637 (Oshonsoft Pic Basic Compiler).

DogFlu66

Member
I am attaching the library to work with the TM1637 based on the library written in C from the datasheets.
I have had several problems because the displays with TM1637 do not all work at the same speed and this is not taken into account in the examples in the datasheets. There is also a big problem with the datasheet example and that is that it does not configure the DIO line as an open collector, if this is not corrected it will be impossible to read the keyboard. After all these adventures I have been able to create a functional library. I just need to perform the keyboard reading test because I do not have any module with a keyboard until I receive the one I ordered.
Another important problem that I have had to implement is that in the "While" loop of the "I2CAskTM1637()" function (in the original I2CAsk) an exit had not been implemented due to lack of response from the DIO line, if this is not available Take into account that in the case of a breakdown or lack of response from the module, an infinite loop would be generated in the function.

Notice: Finish the library to work with a 4-digit display and a 6-digit display with a keyboard. So update to the new files (2024/04/10).
 

Attachments

  • _TM1637Library.bas
    10.1 KB · Views: 1,498
  • _Pic18F26K22Library.bas
    43.2 KB · Views: 182
  • _SetUpAmicus18.bas
    2.9 KB · Views: 1,528
  • Test LM1637_Keys.bas
    3.9 KB · Views: 1,466
Last edited:
That device presents unusual coding problems,(C) One project i started I had two 6 digit seven segment modules both with TM1637 drivers,Seem to remember I could not use I2C for various reasons (3 other I2C devices complained about the common data stream), and bit bang took up too many IO. What worked for me was using an MCP23017 (I2C) to control the TM1637 by bit banging. Eventually worked well.
 
That's because it's not an I2C chip, it's more like an SPI chip, and thus requires a separate chip-select line for each chip on the bus. I2C has specific addresses for each device on a 2 wire bus, SPI doesn't, and neither does the TM1637. Sticking an SPI(ish) chip on an I2C bus is going to completely mess the bus up.
 
Sticking an SPI(ish) chip on an I2C bus is going to completely mess the bus up.

I have successfully shared clock and data pins with I2C and SPI devices. It works a treat. I2C devices ignore data sent to an SPI device because the message doesn't have the right address format, and the SPI device ignores I2C data because its CS pin isn't asserted.

Not the best practice, and there is the possibility the SPI data could be interpreted as an I2C address, but in a pinch with short SPI messages, it can work.
 
Except it's not an SPI chip, only an SPI(ish) chip - and the TM1637 is VERY likely to upset the I2C bus.

However, even with a proper SPI chip, it's fairly likely to cause false messages on the I2C bus, not something you really want to be doing.
 
Except it's not an SPI chip, only an SPI(ish) chip - and the TM1637 is VERY likely to upset the I2C bus.

However, even with a proper SPI chip, it's fairly likely to cause false messages on the I2C bus, not something you really want to be doing.
Exactly, but some people just like to be cute for the sake of being cute. It's the difference between being a dilettante and an engineer.
 
Except it's not an SPI chip, only an SPI(ish) chip - and the TM1637 is VERY likely to upset the I2C bus.

And whether it's SPI or only SPI-like, it has a chip select pin, so my comments still apply. The chip will ignore everything on the clock and data lines while chip select is not asserted, and it's highly unlikely in the limited range of data sent to it or by it that I2C chips will care. But what do I know? I've only actually done it where I had to add a board where I didn't have an option otherwise.

I clearly stated the caveats. Would I parallel I2C and an SPI LCD? No, because that datastream could contain any combination of bytes.

And thank you very much! I've never been called a cute dilettante before!
 
Last edited:

Are you talking about the TM1637?, or an actual SPI chip.

Because for the TM1637 you send a considerable amount of data for latching the individual bits - not a particularly limited range at all.
 
The TM1637 is neither I2C nor SPI, but of the two I'd say it's more "I2C-like" but with no address byte, so they can't be bussed together easily like a normal I2C device might be.

The CLK can be push-pull, but the DIO line should be open-collector/open-drain since the TM1637 sends an ACK (low) back to the master during the 9th clock. If the master is actively driving this line high that would be a problem. Another reason it's OD is to read the key data.
 
I am using the already tested library.
Turning the module on and off and selecting the display brightness works well.
But it only shows me all the illuminated segments.
No matter how much I review the functions of the library, I cannot find any flaws.

'TM1637 commands
'Mode command setting.
Const MODE_TM1637 = 0x40 '01000000, write mode, address auto increment
'Address command setting.
Const ADDRESS_TM1637 = 0xC0 '11000000, first digit address
'Display control command setting.
Const CONTROL_OFF_TM1637 = 0x80 '10000000, display off
Const CONTROL_ON_TM1637 = 0x88 '10001000, display on at minimum (the last three brightness).

 
Last edited:
In your other thread you've said you removed the caps and it still didn't work... to me that sounds like there's a problem with the code.

Here's a driver I wrote for Swordfish BASIC based on the original arduino C code.
Perhaps you can compare it to yours. The TM1637 module I had required almost 100us delays (like the arduino code) because of the "incorrect" cap values on the CLK and DIO pins.

The Swordfish "#option" statement works similar to a "#define"... other than that if anything's unclear let me know.
 

Attachments

  • TM1637.bas
    9.6 KB · Views: 167
After comparing the functions you left with mine I found the error.
The strange thing is that all the other 4-digit TM1637s work well with my library without modifying it and I have several different ones.

I only had to add one line to a single function:
"CLK = 0 'I had to add only this line **************"

'Write byte
Function I2CWrByte(oneByte As Byte) As Bit
Dim i As Byte
CFor (i = 0; i < 8; i++)
CLK = 0
If (oneByte & 0x01) Then 'low front
DIO_HIGH()
Else
DIO_LOW()
Endif
WaitUsDelay1_IO
oneByte = oneByte >> 1
CLK = 1
WaitUsDelay1_IO
CNext
CLK = 0 'I had to add only this line **************
End Function

I have verified that it reads the keyboard well.
I only have to adapt my library from 4 digits to 6 digits.
 
Now that I know that it works with all TM1637 variants, and since I have to modify it so that it works with 6 digits, I will rename the names of the functions and remove all of them where it says "I2C", because the functions are based on the ones in the example of datasheet that names them that way.
 
Glad you got it working.

This module is one of the fast ones because it works with 1uSec delays.
Once I removed the caps on the CLK and DIO lines, all the modules I had worked ok with short delays too. Since the DIO line is driven in OD mode there's always going to be a rise-time issue that you have to account for anyway.

Personally, I don't see the need for them (the caps that is).
 
I agree with what you say. Here you can see the delay line that I incorporated to give time to the rising edge of the DIO signal, working at 64Mhz/4. Works with both slow and fast TM1637s.

'Set the DIO pin as open-drain.
Function DIO_HIGH() As Bit
DIO_IO = 1 'Select DIO as input.
'Open collector needs to wait for the line to change state, it is slower than using I/O.
'Tested with fast and slow displays and it has worked with the same value.
ASM: NOP
ASM: NOP
ASM: NOP
ASM: NOP
ASM: NOP
ASM: NOP
ASM: NOP
ASM: NOP
End Function
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…