Pulsin display on 4 7-segment LED displays


hi everyone,
I would like to display the result of a pulsin measurement with an 08M2 picaxe (0.8 to 2.2 msec) on a 4-digit 7-segment red led display.
The display would therefore be 800 to 2200 (the first zero from 800 to 999 not lighting up).
Which driver for 4 7-segment led displays would you recommend?
Incidentally, would such a program have already been presented on this forum?
Thanks already.


Senior Member
It's possible that this thread may be helpful:

and this related blog post:


I remember that I had used a Motorola MC14489P driven with successive SHIFTOUT commands with a Basic Stamp.
Circuit capable of driving up to 5 digits and requiring only three inputs: Data_in, Clock, \Enable.
I will also research in this direction and see if an adaptation is possible with a picaxe.
There might also be the MAX7219?
I also see the TM1637 ...
>>>To see which one is the easiest to use ...
An advice ?
If you have other proposals, I am interested ;)
Last edited:


Thank you for your interventions.
An interesting post had been published for the TM1637 with an optimized program:



I am therefore analyzing the TM1637 driver.
I understand the control protocol.
In fact, in series, we send the status of each segment of each display.
The decimal point is obtained by adding 128 to the code of the search character.

How to light up the two vertical dots used in the case of time display, for example.
Indeed, adding 128 to the code of the second character will light its small decimal point but not the two aforementioned points.




Here is my optimised code inspired from various sources from which I have kept the most compact routines and comments from the Picaxe FR and GB forum specialists.

But I'm waiting for a TM1637 module to test it...

If you see an anomaly or an improvement (or if you are able to test it on a TM1637 module) I thank you already.

However, I have a question waiting to be tested:
Is it necessary to specify again at the beginning of each frame the address of the first digit ($C0) and the brightness level ?
I use the default data command setting= $40 (Write data to display register + Automatic address adding + Normal Mode).
For information, I summarize a maximum of information about this driver on my page http://www.alpmn.byethost32.com/4digitled.htm.

Thank you for your collaboration.

;Pulsin TM1637.bas
;Roger LEGAT 18/09/2020
;Display Pulsin value on 4 LED Digit
;(1msec=1000 to 2msec=2000)
;Picaxe 08M2
            #Picaxe 08M2
;              _ _
;       Vcc  o| U |o  Gnd
;       C.5  x|   |x  C.0
; Pulse C.4  >|   |>  C.1  DIO (Pullup actived)
;       C.3  x|___|>  C.2  CLK (Pullup actived)

;Setfreq m16
 Setfreq m4  ; Default : Pulsin in msec

;Pins I/O ***************
 Symbol Clk   = C.2 : input C.2
 Symbol Dio   = C.1 : Output C.1
 Symbol Pulse = C.4 : Input C.4
;Pullup %01100    ;Active R_Pullup sur C.1,C.2
; Real R.pullup on board recommanded !

;Bytes **********************
 Symbol Pack  = b0  ; Byte to send -> bit0 to bit7
 Symbol i     = b4  ; work variable
 Symbol DIGIT1 = b6
 Symbol DIGIT2 = b7
 Symbol DIGIT3 = b8
 Symbol DIGIT4 = b9
;Words *****************************
 Symbol Value = w1 ; Value to display on 4 digit

;EEPROM( 0  1   2  3  4   5  6   7  8  9  10 )'Pos 10 = Blank
DATA 0, ($3F,$06,$5B,$4F,$66,$6D,$7D,$07,$7F,$6F,$00)

;**** Initialisation TM1637 *********************************   
;Symbol TypeAdr=$40 ; auto increment addressing (Default)
 Symbol AdrOrigin=$C0 ; Address of 1er digit
 Symbol Brighness=$8C ; Brighness 69% 

High Clk: High Dio: Low Dio  ; I2CStart
 Pack=Brighness        ;Send Brighness level
 Gosub I2CSendPack
Low Clk: Low Dio : High Clk : High Dio ;I2CStop

;==  MAIN LOOP  ===================================================
 Pulsin 1,Pulse,Value
 Gosub SetDigit
;***  Sub-Routines ***************************************


  bintoascii Value,b5,b6,b7,b8,b9 ; b5 not used (only 4 digit)
  ;Convert Ascii code to Nombre
  b6=b6-48  ; Code Ascii of 0=48, of 1=49, of 2=50 ...

;Ready to send packs :))
;Adressing first digit
High Clk: High Dio: Low Dio    ; I2CStart

Pack = AdrOrigin : Gosub I2CSendPack ; b0 (=AdrOrigin) is the first PACK to send

; ??? is it necessary to re-specify the brighness in the series ????

   Read b6,b0 ; b0(now=b6 =DIGIT1) is the new PACK to send
     If Pack = 0 then
      Pack = 10 ; Blank only first digit if equal to zero
   Gosub I2CSendPack

   Read b7,b0 :  Gosub I2CSendPack  ; DIGIT2 b0(=b7) is the new PACK to send
   Read b8,b0 :  Gosub I2CSendPack  ; DIGIT3 b0(=b8) is the new PACK to send
   Read b9,b0 :  Gosub I2CSendPack  ; DIGIT4 b0(=b9) is the new PACK to send

Low Clk: Low Dio : High Clk : High Dio ;I2CStop

;*** Sending Pack bit by bit, bit0 LSB first  (Shiftout not supported by 08M2 !)
 For i=1 to 8
  Low Clk
  OutpinC.1 = bit0  ; DIO = bit0 of PACK
  Pack = Pack/2    ;>>> shift right >>> bit1 becomes bit0
  High Clk
 Next i


New Member
The only comment I would make is that it's probably inefficient to use bintoascii and then convert the ascii back to integer. Given that you don't need to keep Value, this code does the same thing, and will be faster, as well as using less code space:
    b9 = Value // 10
    Value = Value / 10
    b8 = Value // 10
    Value = Value / 10
    b7 = Value // 10
    Value = Value / 10
    b6 = Value // 10


Hi Aries,
I read your comment and wonder.
I previously used a calculation routine similar to the one you present.
Namely: successive divisions based on the remains of the division.
This routine consumes a lot of lines of code compared to a simple Bintoascii.
So I'm not really sure that you are faster.
To be tested ...
Finally, notes that Bintoascii gives an integer result and that there is therefore no need to "convert" it, other than to remove the "offset value" of 38.
Thank you for your intervention.
To be continued ...


Senior Member

BINTOASCII is an "Internal Macro" generated by the Program Editor, so it is generally less efficient than a "Roll your Own" block of program code. For example you must declare 5 result bytes when only 4 are needed and it cannot re-use the individual bytes within the input Word. This can be shown by doing a Syntax Check in the PE, both with and without the BINTOASCII, which shows that it consumes around 44 bytes of Program Memory. Actually, it's possible to do even a little better than Aries, the following uses only about 22 bytes (i.e. half the number of bytes and probably about twice as fast as BINTOASCII).
   b9 = Value // 10
   b8 = Value / 10 // 10
   b7 = Value / 100 // 10
   b6 = Value / 1000
That's basically what the PE creates, but it has a 5th line (for the 10,000 digit) and must add "0" (48) to each line to create the ASCII values.

Cheers, Alan.


Hi AllyCat,
Thank you for your intervention.
In fact, I relied on a post found on the Picaxe Forum FR on which Beusquet, Senior member, advised to "replace the 4-byte number decomposition loop by the bintoascii command, much faster"!
But as I am waiting to receive a TM1637 module, I haven't been able to compare yet.
#Post6 at https://picaxeforum.co.uk/threads/recherche-afficheur-7-segments-série-svp.31541/

Do you have an opinion on my question about whether or not it is necessary to repeat the Brighness command and the address of the first digit at the beginning of each frame.

Thank you.


New Member
I have used TM1637s for a couple of radio-controlled clocks. My displays don't seem to have decimal points - the HH:MM colon is the only one that is active. However, to answer your questions from my own experience:
The brightness command is only necessary once at the beginning, or when you want to change the brightness setting.
You do need to set the starting position for the first digit each time (in principle, I think you can set any digit individually).


Hi Aries,
I am very impatient to receive my module to be able to test all this and finalize my web page on this driver.
thanks very much.