Grove / Catalex 4 digit 7 segment displays (TM1637)

Memran

Member
Hello everyone :)

I've recently acquired one of the TM1637-based Grove / Catalex 4 digit 7 segment display modules from ebay. The ebay listing said it was I2C, but it does not appear to be at all like any other I2C module!

With the aid of a post by GM39 in the French forum (here: http://www.picaxeforum.co.uk/showthread.php?24564-PICAXE-et-Modules-GROVE&highlight=grove) I was able to get it working via some bit banging. The problem was the complexity of the code and the monopolisation of some general purpose variables, so I tried to simplify as best I could and also free up as many of the variables as I was able.

Hopefully someone will have use of this code, so here it is:
Code:
'################################################################################################
'## Utility Library for the TM1637-based 4 digit 7 segment display modules, such as from Grove 
'## or Catalex.
'##
'## It utilises RAM locations $50-$54 and bytes b26 and b27.
'##
'## It was written this way so that the remaining general purpose variables would be available
'## for the general logic of the user's program.
'## The focus here is on ease of use, not efficiency!
'################################################################################################
#no_data

symbol clk=C.1	'Configure the clock pin
symbol dio=C.2	'Configure the data pin

poke $50,1,2,3,4	'Store the values to display on each digit in RAM locations $50-$53
gosub display	'Call the display subroutine

end
'################################################################################################
'## DO NOT MODIFY ANYTHING BELOW THIS LINE - TREAT IT AS A LIBRARY!
'################################################################################################

i2CStart:
	high clk
	high dio
	low dio
	low clk
	return
	
i2CStop:
	low clk
	low dio
	high clk
	high dio
	return

'Send a byte
i2CWrByte:	
	peek $54,b27:b27 = b27 & %00000001:if b27>0 then high dio else low dio endif:pulsout clk, 1
	peek $54,b27:b27 = b27 & %00000010:if b27>0 then high dio else low dio endif:pulsout clk, 1
	peek $54,b27:b27 = b27 & %00000100:if b27>0 then high dio else low dio endif:pulsout clk, 1
	peek $54,b27:b27 = b27 & %00001000:if b27>0 then high dio else low dio endif:pulsout clk, 1
	peek $54,b27:b27 = b27 & %00010000:if b27>0 then high dio else low dio endif:pulsout clk, 1
	peek $54,b27:b27 = b27 & %00100000:if b27>0 then high dio else low dio endif:pulsout clk, 1
	peek $54,b27:b27 = b27 & %01000000:if b27>0 then high dio else low dio endif:pulsout clk, 1
	peek $54,b27:b27 = b27 & %10000000:if b27>0 then high dio else low dio endif:pulsout clk, 1
	pulsout clk, 1
	return

'Converts the value into the data which the driver understands
decTo7Seg:
	select case b26
		case 0 poke $54,$3f
		case 1 poke $54,$06
		case 2 poke $54,$5b
		case 3 poke $54,$4f
		case 4 poke $54,$66
		case 5 poke $54,$6d
		case 6 poke $54,$7d
		case 7 poke $54,$07
		case 8 poke $54,$7f
		case 9 poke $54,$6f
		case 10 poke $54,$77 'A
		case 11 poke $54,$7c 'B
		case 12 poke $54,$39 'C
		case 13 poke $54,$5e 'D
		case 14 poke $54,$79 'E
		case 15 poke $54,$71 'F	
		case 255 poke $54,$00'BLANK
		'Add other numbers/characters here if required
	endselect
	return

'Read the values from RAM and output to the display
display:
	gosub brightness
	
	'Enable sequential movement (from one digit to next)
	gosub i2CStart
	poke $54,$40
	gosub i2CWrByte
	gosub i2CStop
	
	'Move to first digit
	gosub i2CStart	
	poke $54,$c0
	gosub i2CWrByte

	'First value
	peek $50,b26
	gosub decTo7Seg
	gosub i2CWrByte
	
	'Second value
	peek $51,b26
	gosub decTo7Seg
	gosub i2CWrByte

	'Third value
	peek $52,b26
	gosub decTo7Seg
	gosub i2CWrByte

	'Fourth value
	peek $53,b26
	gosub decTo7Seg
	gosub i2CWrByte
	
	gosub i2CStop
	return

'Set the maximum brightness ($88 = on, $88 to $8F are the brightness levels)
brightness:
	gosub i2CStart
	poke $54,$8f
	gosub i2CWrByte
	gosub i2CStop
	return
Now if someone could help me figure out how to make the ":" in the middle of the digits work, I'd be very grateful! :D
 

techElder

Well-known member
Do you mean to imply that this code will work on any processor at any frequency? Just checking ...
 

Memran

Member
Do you mean to imply that this code will work on any processor at any frequency? Just checking ...
Any processor? Yes, I don't see why not. :)
Any frequency? Maybe. You may need to increase the duration of the pulsout commands to compensate for the faster clock. Just guessing! :)
 

hippy

Technical Support
Staff member
The TM1637 seems to be a multiplexed 6-digit x 8-segment driver so basically it expect six bytes of bit-pattern data, one byte per digit.

The first step in lighting the colon would require determining which segment(s) of which digit(s) map to that colon.

Assuming any do you will need a flag in your PICAXE to indicate if the colon should be lit or not, and then will need to set the appropriate bits in the data being sent to light the colon. You might have to send extra bytes if it maps into the fifth or sixth currently unsent digit bit patterns.

There is a less than easily comprehensible TM1637 datasheet here -

https://github.com/Tinkerforge/segment-display-4x7-bricklet/raw/master/datasheets/TM1637.pdf
 

Memran

Member
Thanks Hippy!
I've figured it out :)
The data which gets sent in the i2CWrite sub, is actually 1 bit for each segment of the 7 segment displays. In the case of digit #2, adding 128 to the data also turns on the ":".
 

pxgator

Senior Member
Thank you Memran ,

This works great on a 14M2 with no changes running at 32 MHZ...:)
Here is a modified snippet to turn on the colon:

Code:
[color=Green];Second value
  [/color][color=Blue]peek [/color][color=Navy]$51[/color][color=Black],[/color][color=Purple]b26
  [/color][color=Blue]call [/color][color=Black]decTo7Seg
  [/color][color=Blue]peek [/color][color=Navy]$54[/color][color=Black],[/color][color=Purple]b25                            [/color][color=Green];1 these 3 lines needed to turn on colon
  [/color][color=Purple]b25 [/color][color=DarkCyan]= [/color][color=Purple]b25 [/color][color=DarkCyan]+ [/color][color=Navy]128                         [/color][color=Green];2
  [/color][color=Blue]poke [/color][color=Navy]$54[/color][color=Black],[/color][color=Purple]b25                            [/color][color=Green];3
  [/color][color=Blue]call [/color][color=Black]i2CWrByte    [/color]
Or:

Code:
[color=Green];Second value
  [/color][color=Blue]peek [/color][color=Navy]$51[/color][color=Black],[/color][color=Purple]b26
  [/color][color=Blue]call [/color][color=Black]decTo7Seg
  [/color][color=Purple]bptr [/color][color=DarkCyan]= [/color][color=Navy]$54                              [/color][color=Green];1 these 2 lines needed to turn on colon                
  [/color][color=Purple]@bptr [/color][color=DarkCyan]= [/color][color=Purple]@bptr [/color][color=DarkCyan]+ [/color][color=Navy]128                     [/color][color=Green];2                                                
  [/color][color=Blue]call [/color][color=Black]i2CWrByte  [/color]
 
Last edited:

Memran

Member
Wow I'd completely forgotten about this! I'm glad someone has found it useful! :)
Thanks for updating the code.
 
Top