MM2(+): TM1637 7-segment clock display


Author Message
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 3210
Posted: 02:01pm 08 Aug 2019      

  Quote  Should this run on the MM(28 pin) after the appropriate pin changes ?


Yes, but no

Recent releases of MMbasic releases have tightened up on using reserved words as variable names and my programs used some. Try the attached

option explicit
option default none
dim digittosegment%(15)=(&H3F,&H06,&H5B,&H4F,&H66,&H6D,&H7D,&H07,&H7F,&H6F,&H77,&H7C,&H39,&H47,&H79,&H71)
dim integer m_brightness 'holds the brightness value for the display 0-15 are valid
DIM INTEGER displaydata(3)=(0,0,0,0) 'holds the bit values of the segments to be lit, ordered left to right
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
'*************************************************************************************************
'
' Test /demo program
'
dim mytime$ length 8
DIM integer j
TM1637Init(18,17)' initialise the display using pin 44 for the clock and pin 1 for the data
setbrightness(15)' load the brightness into the global variable
setsegments(displaydata()) 'displaydata is set to zeroes so clear the display
j=ds18b20(4)*10
convertnumber(displaydata(),j,noleadingzeros)
displaydata(3)=&B01011000
setsegments(displaydata()) 'displaydata is set to zeroes so clear the display
mytime$=time$
pause 1000
timer=0
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 display array including the colon but no leading zeroes
else
converttime(displaydata(),nocolon,noleadingzeros)'set the time into the display array without the colon or leading zeroes
endif
setsegments(displaydata()) 'update the display
mytime$=time$
endif
loop while timer <60000 'update the time over a minute
'
for j=-999 to 1999 step 17 'demo positive and negative numbers without leading zeroes
convertnumber(displaydata(),j,noleadingzeros)
setsegments(displaydata())
next j
for j=-999 to 1999 step 17 'demo positive and negative numbers with leading zeroes
convertnumber(displaydata(),j,leadingzeros)
setsegments(displaydata())
next j
end

'************************************************************************************************

sub TM1637Init(pinClk as integer, pinDIO as integer)
dim integer m_pinClk,m_pinDIO
' 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
end sub

sub sendstop

setpin m_pinDIO, dout
setpin m_pinClk, DIN
setpin m_pinDIO, DIN
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
' CLK high
setpin m_pinClk, DIN
odata = odata >> 1
next i

' 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
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)
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 integer
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

Edited 2019-08-09 00:03 by matherp