Skip to content

Instantly share code, notes, and snippets.

@pwillard
Created July 15, 2022 13:53
Show Gist options
  • Save pwillard/6f64e637b4a251cbd59e21701e5a185c to your computer and use it in GitHub Desktop.
Save pwillard/6f64e637b4a251cbd59e21701e5a185c to your computer and use it in GitHub Desktop.
Simple LED CLOCK using Raspberry Pi PICO
'==============================================================================
=
' TTTTT M M 1 666 3333 77777 BBBB AAA SSSS
' T MM MM 11 6 3 7 B B A A S
' T M M M 1 6666 333 7 BBBB AAAAA SSS
' T M M M 1 6 6 3 7 .. B B A A S
' T M M 111 666 3333 7 .. BBBB A A SSSS
'==============================================================================
=
'==============================================================================
=
' Program: TM1637.BAS
' Author: Pete Willard
' Version: 1.0
' Target: PICOMITE
' Date: 2022/06/07
' Time: 17:27:30
' Notes: Much help from Pete Maher
'
' Reference: TM1637 DATASHEET IN WONDERFUL CHINGLISH.
' It kind of wants to be true SPI and then it doesn't feel like it so much.
' It's really just simpler "shift register" stuff. The TM1637 treats these
' as open collector, to pullups resistors are used to pull the pins to Vcc.
' The board has the following pins:
' CLK, DIO, GND AND 5V
' Pull DIO low before CLK transition to create a START condition
' Pull CLK high before DIO after and 8 bit data transfer to signal
' END condition
' There are 3 basic command modes:
' DISPLAY ON/OFF &H8F/&H80
' DATA WRITE &H40/&H44
' WRITE TO REGISTER &HC0/&HC1...
'
'==============================================================================
' MMBASIC CLOCK
'--------------
'OPTION SYSTEM SPI GP18,GP19,GP16
'OPTION SYSTEM I2C GP0,GP1
'OPTION AUTORUN 1
'OPTION COLOURCODE ON
'OPTION SDCARD GP22
-----------------------------
'=====[ CONFIGURATION ]========================================================
Option explicit
Option default none
'=====[ VARIABLES ]============================================================
Dim digittosegment%(15)=(&H3F,&H06,&H5B,&H4F,&H66,&H6D,&H7D,&H07,&H7F,&H6F,&H7
PRESS ANY KEY ... 7,&H7C,&H39,&H47,&H79,&H71)
Dim integer m_brightness ' 0-15
Dim integer displaydata(3)=(0,0,0,0) ' Holds segment data for digits
Const false=0
Const true=1
Const colon=1
Const nocolon=0
Const noleadingzeros=1
Const leadingzeros=0
Const TM1637_I2C_COMM1 = &H40
Const TM1637_I2C_COMM2 = &HC0
Const TM1637_I2C_COMM3 = &H80
'
Dim mytime$ length 8
'=====[ PINS ]=================================================================
Dim INTEGER DIO = 17 ' GPIO 12
Dim INTEGER CLK = 16 ' GPIO 13
'=====[ SUBROUTINES ]==========================================================
Sub TM1637Init(pinClk As integer, pinDIO As integer)
Dim integer m_pinClk,m_pinDIO
PRESS ANY KEY ... ' Copy the pin numbers
m_pinClk = pinClk
m_pinDIO = pinDIO
' Set the pin direction and default value.
' Both pins are set as inputs, allowing the pull-up resistors to pull them up
Pin(m_pinDIO)=0
Pin(m_pinClk)=0
SetPin m_pinDIO,DIN
SetPin m_pinClk,DIN
End Sub
'=============================================
Sub setBrightness(brightness As integer)
m_brightness = brightness
End Sub
'=============================================
Sub setSegments(segments() As integer)
Local integer k
' Write COMM1
sendstart
writeByte(TM1637_I2C_COMM1)
sendstop
' Write COMM2 + first digit address
sendstart
writeByte(TM1637_I2C_COMM2)
' Write the data bytes
For k=0 To 3
writeByte(segments(k))
Next k
sendstop
' Write COMM3 + brightness
sendstart
writeByte(TM1637_I2C_COMM3 + (m_brightness And &H0f))
sendstop
End Sub
'=============================================
Sub sendstart
SetPin m_pinDIO, DOUT
' bitDelay
Pause 0.01
End Sub
'=============================================
Sub sendstop
SetPin m_pinDIO, dout
SetPin m_pinClk, DIN
SetPin m_pinDIO, DIN
' bitDelay
Pause 0.01
End Sub
'=============================================
Sub writeByte(b As integer) As integer
Local integer i,ack,odata = b
' 8 Data Bits
For i=0 To 7
' CLK low
SetPin m_pinClk,dout
' Set data bit
If (odata And 1) Then
SetPin m_pinDIO,DIN
Else
SetPin m_pinDIO,DOUT
EndIf
'Pause 0.01
' CLK high
SetPin m_pinClk, DIN
odata = odata >> 1
Next i
'Pause 0.01
' Wait for acknowledge
' CLK to zero
SetPin m_pinClk, dout
SetPin m_pinDIO, DIN
' CLK to high
SetPin m_pinClk, din
ack = Pin(m_pinDIO)
If (ack = 0) Then
SetPin m_pinDIO, dout
EndIf
SetPin m_pinClk, dout
Pause 0.01
End Sub
'=============================================
Function encodeDigit(digit As integer) As integer
encodeDigit=digitToSegment%(digit And &H0f)
End Function
'=============================================
Sub convertnumber(dd() As integer,n As integer, nolead As integer)
Local integer d(2),m
m=Abs(n Mod 10000)
PRESS ANY KEY ... If n<0 Then m=Abs(n Mod 1000)
d(0)=(m - (m Mod 1000))
d(1)=(m - d(0) - (m Mod 100))
d(2)=(m - d(0) - d(1) - (m Mod 10))
dd(3)=encodeDigit(m - d(0) -d(1)- d(2))
dd(0)=encodeDigit(d(0)\1000)
dd(1)=encodeDigit(d(1)\100)
dd(2)=encodeDigit(d(2)\10)
If nolead Then
If d(0)=0 Then
dd(0)=0
If d(1)=0 Then
dd(1)=0
If d(2)=0 Then
dd(2)=0
EndIf
EndIf
EndIf
If n<0 Then
If dd(2)=0 Then
dd(2)=64
Else
If (dd(1)=0) Then
dd(1)=64
Else
dd(0)=64
EndIf
EndIf
EndIf
Else
If n<0 Then dd(0)= 64
EndIf
End Sub
'=============================================
Sub converttime(dd() As integer,displaycolon As integer,nolead As integer) As i
nteger
Local integer i=Val(Left$(Time$,2))*100+Val(Mid$(Time$,4,2))
convertnumber(dd(),i,nolead)
If displaycolon Then dd(1)=dd(1) Or &H80
End Sub
'=====[ MAIN CODE ]============================================================
TM1637Init(CLK,DIO)' initialise the display
setbrightness(15)' load the brightness into the global variable
setsegments(displaydata()) 'displaydata is set to zeroes so clear the display
PRESS ANY KEY ...
mytime$=Time$
Pause 1000
Do
If mytime$<>Time$ Then 'the clock seconds have changed
If Val(Right$(Time$,1)) Mod 2 Then 'flash the colon each second
converttime(displaydata(),colon,noleadingzeros) 'set the time into the di
splay array including the colon but no leading zeroes
Else
converttime(displaydata(),nocolon,noleadingzeros)'set the time into the d
isplay array without the colon or leading zeroes
EndIf
setsegments(displaydata()) 'update the display
mytime$=Time$
EndIf
Pause 500
Loop
'==============================================================================
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment