Created
July 15, 2022 13:53
-
-
Save pwillard/6f64e637b4a251cbd59e21701e5a185c to your computer and use it in GitHub Desktop.
Simple LED CLOCK using Raspberry Pi PICO
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'============================================================================== | |
= | |
' 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