DS3231 RTC with TFT display and DF-Player to make the cuckoo sound. Every 15 minutes it sounds once and on the hour it sounds the hour.
The RTC is 2 ppm accuracy so you are going to miss your next birthday by about a minute.
The code in C is for the SPI drive of the TFT. The images are also generated by the code.
The RTC is 2 ppm accuracy so you are going to miss your next birthday by about a minute.
The code in C is for the SPI drive of the TFT. The images are also generated by the code.
B4X:
Sub Process_Globals
Public Serial1 As Serial
Private AStream As AsyncStreams
Private wire As WireMaster
Dim adr As Byte= 0x68
Private tmr As Timer
Public CS As Pin
Public DC As Pin
Public SDA As Pin
Public SCK As Pin
Public RST As Pin
Public minutePB As Pin
Public hourPB As Pin
Public busy As Pin
Public test As Pin
Private minL, minH, minS, hourL, hourH, hourS As Byte
Public yh=4, yc=yh+40 As Int
Public BLACK As UInt=0x00
Public BLUE As UInt=0x01F
Public RED As UInt=0xF800
Public GREEN As UInt=0x07E0
Public CYAN As UInt=0x07FF
Public MAGENTA As UInt=0xF81F
Public YELLOW As UInt=0xFFE0
Public WHITE As UInt=0xFFFF
Public PINK As UInt=0xFC58
Public ORANGE As UInt=0xFC00
Public BROWN As UInt=0x8208
Public bgr As UInt=0xFFFF
Private spires, spidata As Byte
End Sub
Private Sub AppStart
Serial1.Initialize(9600)
AStream.Initialize(Serial1.Stream,Null , Null) '"Astream_NewData"
wire.Initialize
tmr.Initialize("tmr_Tick", 500)
tmr.Enabled = True
CS.Initialize(10, CS.MODE_OUTPUT)
DC.Initialize(9, DC.MODE_OUTPUT)
SCK.Initialize(13, SCK.MODE_OUTPUT)
RST.Initialize(8, RST.MODE_OUTPUT)
SDA.Initialize(11, SDA.MODE_OUTPUT)
minutePB.Initialize(minutePB.A0, minutePB.MODE_INPUT_PULLUP)
hourPB.Initialize(hourPB.A1, hourPB.MODE_INPUT_PULLUP)
test.Initialize(test.A2, test.MODE_INPUT_PULLUP)
'hourPB.AddListener("hourPB_StateChanged")
RunNative ("set_spi",Null)
TFTinit
rectan(0,0,127,159,CYAN) 'clear screen
house
door
End Sub
Sub tmr_Tick
If minutePB.DigitalRead=True And hourPB.DigitalRead=True Then
get_time
End If
If minutePB.DigitalRead=False Then
minL=minL+1
If minL>9 Then
minL=0
minH=minH+1
End If
If minH>5 Then minH=0
drawC(50,yc,minH,BLUE,2) 'minutes
drawC(63,yc,minL,BLUE,2)
minS=Bit.ShiftLeft(minH,4) + minL
setTime(1,minS)
End If
If hourPB.DigitalRead=False Then
hourL=hourL+1
If hourL>9 Then
hourL=0
hourH=hourH+1
End If
If (hourH*10 + hourL)>23 Then
hourH=0
hourL=0
End If
drawC(11,yc,hourH,BLUE,2) 'hourS
drawC(24,yc,hourL,BLUE,2)
hourS=Bit.ShiftLeft(hourH,4) + hourL
setTime(2,hourS)
End If
End Sub
Sub door
Dim x=51, y=yh+74 As Byte
rectan(x-20,y-6,x+44,y+46,ORANGE) 'erase
rectan(x-4,y-6,x+28,y+46,BROWN) 'door
End Sub
Sub bird
Dim i, x=51, y=yh+74 As Byte
Dim hue=YELLOW As Int
rectan(x-20,y-6,x+44,y+46,ORANGE) 'erase
rectan(x-4,y-4,x+28,y+44,BLACK) 'opening
rectan(x-20,y-6,x-4,y+46,BROWN) 'door
rectan(x+28,y-6,x+44,y+46,BROWN) 'door
'body
For i=0 To 4
rectan(x+6-i,y+i+23,x+17+i,y+i+24,ORANGE)
Next
rectan(x+2,y+28,x+21,y+32,ORANGE)
For i=0 To 4
rectan(x+2+i,y+i+32,x+21-i,y+i+33,ORANGE)
Next
rectan(x,y+28,x+2,y+34,YELLOW) 'wing
rectan(x+21,y+28,x+23,y+34,YELLOW) 'wing
rectan(x+8,y+38,x+9,y+44,RED) 'leg
rectan(x+14,y+38,x+15,y+44,RED) 'leg
'head
rectan(x+9,y,x+14,y+1,hue) 'top
For i=0 To 4
rectan(x+6-i,y+i+1,x+i+17,y+i+2,hue)
Next
rectan(x+1,y+6,x+22,y+9,hue)
rectan(x,y+9,x+23,y+15,hue)
rectan(x+1,y+15,x+22,y+17,hue)
For i=0 To 4
rectan(x+i+2,y+i+17,x+21-i,y+i+18,hue)
Next
rectan(x+9,y+23,x+14,y+24,hue)
'eye
For i=0 To 2
rectan(x+5-i,y+i+6,x+7+i,y+i+7,WHITE)
Next
For i=0 To 2
rectan(x+5-i,y+i+9,x+7+i,y+i+10,BLACK)
Next
For i=0 To 2
rectan(x+3+i,y+i+13,x+9-i,y+i+14,BLACK)
Next
For i=0 To 2
rectan(x+16-i,y+i+6,x+18+i,y+i+7,WHITE)
Next
For i=0 To 2
rectan(x+16-i,y+i+9,x+18+i,y+i+10,BLACK)
Next
For i=0 To 2
rectan(x+14+i,y+i+13,x+20-i,y+i+14,BLACK)
Next
'BIC
rectan(x+10,y+20,x+14,y+21,MAGENTA)
rectan(x+11,y+21,x+13,y+22,MAGENTA)
For i=0 To 3
rectan(x+9,y+i,x+10+i,y+i+1,ORANGE)
Next
End Sub
Sub bic_closed
Dim i, x=51, y=yh+74 As Byte
rectan(x+9,y+16,x+15,y+19,PINK) 'erase
For i=0 To 2
rectan(x+11-i,y+i+16,x+13+i,y+i+17,MAGENTA)
Next
End Sub
Sub bic_open
Dim x=51, y=yh+74 As Byte
rectan(x+9,y+16,x+15,y+19,PINK)
rectan(x+11,y+16,x+13,y+17,MAGENTA)
rectan(x+9,y+17,x+15,y+18,MAGENTA)
End Sub
Sub house
Dim i As Byte
For i=0 To 6 'roof
rectan(59-i*8,yh+i*4,67+i*8,yh+i*4+4,RED)
Next
rectan(0,yh+27,127,yh+31,RED)
rectan(35,yh,39,yh+12,BLACK) 'chemny
For i=0 To 7 'board
rectan(15-i*2,yh+120+i*3,111+i*2,yh+i*3+124,GREEN)
Next
For i=0 To 5 'house
rectan(4+i*2,yh+32+i*16,123-i*2,yh+i*16+48,ORANGE)
Next
rectan(9,yc-2,118,yc+16,bgr) '//
drawC(37,yc,10,MAGENTA,2) ':
drawC(76,yc,10,MAGENTA,2) ':
End Sub
Sub setTime (reg As Byte, setting As Byte)
Dim data(2) As Byte
data(0)=reg
data(1)= setting
wire.WriteTo(adr, data)
End Sub
Sub get_time
Dim sh, sl, dong, i As Byte 'hh, hl, mh, ml,
Dim data(1) As Byte
data(0) = 0
wire.WriteTo(adr,data)
Dim res() As Byte = wire.RequestFrom(adr,7) 'request time
If res.Length>=6 Then
hourH=Bit.And(Bit.ShiftRight(res(2),4),3) 'res(2)>>4 & 3
hourL=Bit.And(res(2),15)
minH=Bit.And(Bit.ShiftRight(res(1),4),7) 'res[1]>>4 & 7
minL=Bit.And(res(1),15)'res[1] & 15
sh=Bit.And(Bit.ShiftRight(res(0),4),7)
sl=Bit.And(res(0),15)
End If
drawC(11,yc,hourH,BLUE,2) 'hourS
drawC(24,yc,hourL,BLUE,2)'
drawC(50,yc,minH,BLUE,2) 'minutes
drawC(63,yc,minL,BLUE,2)'
drawC(89,yc,sh,BLUE,2) 'seconds
drawC(102,yc,sl,BLUE,2)
dong = hourH*10 + hourL 'total hourS
If res(1)=0 And res(0)=0 Then 'If 00 minutes And 00 seconds
bird
Delay(1000)
For i=1 To dong
play_df
Next
Delay(1000)
door
else if (minH*10+minL) Mod 15=0 And res(0)=0 Then '((mh*10+ml)%15==0 && res[0]==0) '15,30,45 minutes
bird
Delay(1000)
play_df
Delay(1000)
door
End If
End Sub
Sub play_df
Dim ps() As Byte = Array As Byte(0x7E,0xff,0x06,0x03,0x00,0x00,1,0xEF)
Do While busy.DigitalRead=False 'wait For prev track To complete, !busy
Delay(10)
Loop
bic_open
AStream.Write(ps)
Delay(1400)
bic_closed
End Sub
'draw char
Sub drawC(x As Byte, y As Byte, c As Byte, color As UInt, size As Byte)
Dim i, j, line As Byte
Private font() As Byte = Array As Byte( _
0x3E, 0x41, 0x41, 0x41, 0x3E, _ '0
0x00, 0x42, 0x7F, 0x40, 0x00, _ '1
0x72, 0x49, 0x49, 0x49, 0x46, _
0x21, 0x41, 0x49, 0x4D, 0x33, _
0x18, 0x14, 0x12, 0x7F, 0x10, _
0x27, 0x45, 0x45, 0x45, 0x39, _ '5
0x3C, 0x4A, 0x49, 0x49, 0x31, _
0x41, 0x21, 0x11, 0x09, 0x07, _
0x36, 0x49, 0x49, 0x49, 0x36, _
0x46, 0x49, 0x49, 0x29, 0x1E, _ '9
0x00, 0x00, 0x14, 0x00, 0x00) ':
For i=0 To 5
If i = 5 Then
line = 0
Else
line = font((c*5)+i)
End If
For j = 0 To 7
If Bit.And(line,0x1)=1 Then
rectan(x+(i*size), y+(j*size), x+(i*size)+size, y+(j*size)+size, color)
Else
rectan(x+(i*size), y+(j*size), x+(i*size)+size, y+(j*size)+size, bgr)
End If
line=Bit.ShiftRight(line,1)
Next
Next
End Sub
Sub spi(data As Byte) 'send byte over spi
spidata=data
RunNative ("spi",Null)
Return
End Sub
Sub command(cmd As Byte)
DC.DigitalWrite(False) 'command Mode
CS.DigitalWrite(False) 'Select the LCD (active low)
spi(cmd)'set up data on bus
CS.DigitalWrite(True) 'Deselect LCD (active low)
End Sub
Sub send_data(data As Byte)
DC.DigitalWrite(True) 'data mode
CS.DigitalWrite(False) 'Select the LCD (active low)
spi(data) 'set up data on bus
CS.DigitalWrite(True) 'Deselect LCD (active low)
End Sub
Sub TFTinit
Dim i As Byte
RST.DigitalWrite(True) 'hardware reset
Delay(200)
RST.DigitalWrite(False)
Delay(10)
RST.DigitalWrite(True)
Delay(10)
command(0x01) 'sw reset
Delay(200)
command(0x11) ' Sleep out
Delay(200)
command(0x3A) 'color mode
send_data(0x05) '16 bits
'send_data(0x06) '18 bits
command(0x36) 'Memory access ctrl (directions)
send_data(0x10) '0x10=ver, 0B1100000=0x60=hor
'send_data(0x08) '0x48=left to right,BRG,horizontal 0x40=vertical,RGB
'command(0x21) 'color inversion on
command(0x2D) 'color look up table
send_data(0)
For i = 1 To 31
send_data(i * 2)
Next
For i = 0 To 63
send_data(i)
Next
send_data(0)
For i = 1 To 31
send_data(i * 2)
Next
command(0x13) 'Normal display on
command(0x29) 'Main screen turn on
End Sub
Sub area(x0 As Byte, y0 As Byte, x1 As Byte, y1 As Byte)
command(0x2A) 'Column addr set
send_data(0x00)
send_data(x0) ' XSTART
send_data(0x00)
send_data(x1) ' XEND
command(0x2B) 'Row addr set
send_data(0x00)
send_data(y0) ' YSTART
send_data(0x00)
send_data(y1) ' YEND
command(0x2C) 'write To RAM
End Sub
Sub rectan(x0 As Byte, y0 As Byte, x1 As Byte, y1 As Byte, color As UInt)
Dim i As Int
area(x0,y0,x1,y1)
For i=(y1 - y0 + 1) * (x1 - x0 + 1) To 0 Step -1
DC.DigitalWrite(True) ' data mode
CS.DigitalWrite(False)
spi(color / 256)
spi(color Mod 256)
CS.DigitalWrite(True)
Next
End Sub
#if C
void spi(B4R::Object* o)
{
SPDR = b4r_main::_spidata; // Start transmission
while (!(SPSR & _BV(SPIF))); // Wait For transmission To complete
b4r_main::_spires = SPDR; // received byte
}
void set_spi(B4R::Object* o)
{
SPCR = 0B1011100; // Enable SPI, Master, mode3, set clock rate fck/4 = 4MHz
//SPSR = 1; //set clock rate fck/2=8MHz
}
#End if