TM1638 Display Switchpad


Well-known member
View attachment 21983

This is a good combination module with the TM1638 driver. It works with SPI commands in the PICAXE really well. I've decoded some of the 'C' code from others to get an addressing scheme for the various 'digits' on the module.

The seven-segment digits and the LEDs are one sequential block of addresses starting at 0xC0 for the first seven-segment digit. The next address is for the first LED. The next address is for the second seven-segment digit and so on. The address alternates between digit and LED in the sequential method off addressing.

So, this means that each seven-segment digit is separated from the ones around it by adding / subtracting two from the address. This allows addressing sequential digits with a FOR/NEXT or DO/LOOP scheme. The same applies to the LEDs.

Now, if you set a particular digit or LED address into a constant or variable, there is a command to address a digit or LED individually. This is great for putting a number (battery voltage?) on the display starting at any digit including decimal points. So, again, a FOR/NEXT or DO/LOOP can be used to put a string of numbers (word/integer?) onto the display.

Here are a few MACROs that I've devised for the module. My goto PICAXE is the 20X2, so that's what I've designed and tested these MACROs for. Your mileage may vary, but I'm sure these can be adjusted for other processors. Need help? Ask!

UPDATE: 2018-MAR-22 Using version 3 already! :D
View attachment 22071 (NOTE: Remove the ".txt" extension of the filename after downloading.)
VERSION 3: Added leading zero blanking to DisplayWordTM1638
VERSION 2: Erased some errors
VERSION 1: Well, enough said! :D

Following is descriptive header:

[noparse]'------[ DESCRIPTION ]------[/noparse]
' This is the INCLUDE file that contains TM1638 display/keypad MACROs for PICAXE (20X2).
'  There are some modifications to make it easier to use other PICAXE processors.

[noparse]'------[ CALLING PROCEDURES ]------[/noparse]
' BlankDisplayTM1638 ; "2018-03-18 06:32:56"
'     clears all display elements and LEDs

' ResetDisplayTM1638 ; "2018-03-18 06:24:53"
'     clears all display elements and LEDs then writes character zero to seven-segment digits

' IssueCommandTM1638(command) ; "2018-03-18 06:22:30"
'     sends a command to the display
'     replace "command" with constants such as DISPLAYONFULL, DISPLAYONMED

' WritePosTM1638(address,value) ; "2018-03-18 06:18:51"
'     sends a single value to a single display address
'     replace "address" with constants DIG1-DIG8,LED1-LED8
'     replace "value" with seven-segment code for digits or logical 1(on) or zero(off) for LEDs

' ResetAllLEDTM1638 ; "2018-03-19 14:24:01"
'     each LED is turned OFF(0)

' SetAllLEDTM1638 ; "2018-03-18 06:13:50"
'     each LED is turned ON(1)

' SetResetLEDbitsTM1638(byte) ; "2018-03-18 06:11:02"
'     set/resets all LEDs
'     bits set to 1 in byte will turn on LED
'     bits set to 0 in byte will turn off LED
'     intended to set LED from switch closures

' DisplayLEDTM1638(address,level) ; "2018-03-18 06:31:37"
'     sets or resets individual LED at address
'     replace "address" with constants LED1-LED8
'     replace "level" with 0(off) or 1(on)

' BinToDigitsBptr(location,wordValue) ; "2018-03-18 06:39:17"
'     separates a wordValue into digits (not ASCII) and puts them into RAM location for later retrieval 
'     replace "location" with a MSD address in RAM where 5 sequential bytes will be transfered
'     replace "wordValue" with a 16 bit variable with the value to be converted
'     thanks to hippy BinToAsciiBPtr PICAXE forum 01-AUG-2017

' ConvertTo7Segment(character) ; "2018-03-18 06:41:09"
'     returns the seven-segment code for the number in character
'     enter with character set to the decimal number of the character to convert (0x00 thru 0x0F)
'     see also subroutine 

' DisplayWordTM1638(locFrom,locTo,digits,address,dpdigit) ; "2018-03-19 06:30:32"
[noparse]'     separates a 16 bit word in RAM (locFrom [LE format]) into number of digits for display (address)[/noparse]
'     replace "digits" with value of how many digits to fill (constant or variable)
'     replace "address" with starting digit to start displaying (DIG_1,2,3,4,5,6,7,or 8)
'     decimal point is added at the dpdigit

' ReadSwitchesTM1638(location) ; "2018-03-19 07:08:45"
'     read the module switch status (pushed/not pushed) and combine into one byte at location
'     location is where the read switch status bits (byte) will be located
'     replace "location" with a MSB address in RAM where 8 sequential bits will be transferred
'        suggest location is "0x00" for variable b0 where bit7-bit0 can address each bit separately (not required)[/color]


Well-known member
lbenson said:
Paul, I've implemented your include file and demo program, ... since it's a neat little device and your code makes it easy to use. I see one small issue in the demo program--S4 turns on LED3, S3->LED2, S2->LED1, and S1 does nothing.
Answering this note on the blog post so it is more public and might help others, also.

Check that you have Version 3, at least, of the include file. I was working on a Version 4 of the include file when I got distracted by PUSH/POP. So, the reason for the PUSH/POP diversion was that sometimes I was combining macros is such a way that the system variables that I use were being reused. That could be a problem for you, but it depends on how you are using the macros.

The whole idea is that the ReadSwitchesTM1638(location) macro is in the middle of a DO/LOOP and reads the current state of any switches pressed while it is executing. The routine combines the results into a byte starting at location in RAM. The LSBit is from "S1".

The TM1638 gets a "READ_IN" command which causes it to set up the four next bytes read to indicate the switch status in pairs. Each pair is in bit0 and bit4. The accumulator variable is shifted left by the READ_IN byte number to position the bit0 and bit4 into the proper position by ORing with the previous accumulator variable.

PS. There is considerable rubbish being published about which bits are set when a button is pressed in the TM1638, and I have found that example code doesn't always match the rhetoric at many web sites.