Share My Creation Birthday Card

Birthday card that plays happy birthday tune and display greetings on a TFT display. The speaker is a piezo buzzer and the TFT is 0.96", 80x160 pixels, ST7735 driver, SPI interface.
The name of the card receiver has to be changed in the code, the color of each letter can be set, name can be up to 6 letters, the letter number is the order it is in the array 'font'.

B4X:
'   TFT module with ST7735 driver
'   2 SCK   13
'   3 SDA   11
'   4 A0 Or DC  9
'   5 RESET   8
'   6 CS  10
'   7 GND   GND
'   8 VCC   5 V


Sub Process_Globals

    Public Serial1 As Serial
    Private AStream As AsyncStreams
    Public CS As Pin
    Public DC As Pin
    Public SDA As Pin
    Public SCK As Pin
    Public RST As Pin
    Public out As Pin
    Public out2 As Pin
    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=0x00
    Private yb=48 As Byte
    Private yp=28 As Byte
    Private yn=78 As Byte
    Private ya=27 As Byte
    Private spires, spidata As Byte
    Private note() As Byte = Array As Byte(239,239,213,239,179,189,239,239,213,239,159,179,239,239,119,142,179,189,213,134,134,142,179,159,179)
    Private dur() As Byte = Array As Byte(2,1,3,3,3,3,2,1,3,3,3,4,2,1,3,3,3,3,4,2,1,3,3,3,4)
    Private pause() As Byte = Array As Byte(0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,1)
    Private n As Byte
End Sub

Private Sub AppStart
    
    Serial1.Initialize(9600)
    AStream.Initialize(Serial1.Stream,Null , Null)    '"Astream_NewData"
    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)
    out.Initialize(4, out.MODE_OUTPUT)
    out2.Initialize(3, out2.MODE_OUTPUT)

    RunNative ("set_spi",Null)
    TFTinit
    display
End Sub

Sub display
    Dim LP=1 As Byte
    Do While LP=1
        rectan(1,25,160,105,bgr)
        happy
        Pname
            'play tune
        For n=0 To 24
            play(note(n),dur(n),pause(n))
        Next
    
        rectan(1,25,160,105,bgr)
        baloon2(31,ya,RED)
        draw(38,ya+7,27,CYAN,2)
        baloon2(67,ya,GREEN)
        draw(74,ya+7,27,MAGENTA,2)
        baloon2(103,ya,BLUE)
        draw(110,ya+7,27,WHITE,2)
        Delay(3000)
        rectan(1,25,160,105,bgr)
        cake2(46,47)
            'play tune
        For n=0 To 24
            play(note(n),dur(n),pause(n))
        Next
    
    Loop
End Sub

Sub play(freq As Byte, len As Byte, brk As Byte)
    Dim j,d,f As UInt
    f=freq*8
    d=8000/freq*len
    For j=0 To d
        out.DigitalWrite(True)
        out2.DigitalWrite(False)
        DelayMicroseconds(f)
        out.DigitalWrite(False)
        out2.DigitalWrite(True)
        DelayMicroseconds(f)
    Next
    Delay(100)
    If brk=1 Then Delay(400)
End Sub

Sub baloon2(x As Byte, y As Byte, hue As UInt)
{
    Dim i As Byte
    
    rectan(x+9,y,x+14,y+1,hue)
    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+18,hue)
    rectan(x+2,y+18,x+21,y+21,hue)
    For i=0 To 6
        rectan(x+i+3,y+i+21,x+20-i,y+i+22,hue)
    Next
    rectan(x+8,y+30,x+15,y+32,hue)
    rectan(x+13,y+30,x+13,y+54,WHITE)
    rectan(x+11,y+29,x+12,y+30,WHITE)
    
End Sub

Sub Pname()

    draw(4,yn,26,YELLOW,3) 
    draw(24,yn,13,RED,3)
    draw(44,yn,0,GREEN,3)
    draw(64,yn,12,YELLOW,3)
    draw(84,yn,4,BLUE,3)
    draw(104,yn,26,YELLOW,3)

End Sub

Sub happy()
    draw(40,yp,7,MAGENTA,2)
    draw(56,yp,0,MAGENTA,2)
    draw(72,yp,15,MAGENTA,2)
    draw(88,yp,15,MAGENTA,2)
    draw(104,yp,24,MAGENTA,2)
    
    draw(16,yb,1,YELLOW,2)
    draw(32,yb,8,YELLOW,2)
    draw(48,yb,17,YELLOW,2)
    draw(64,yb,19,YELLOW,2)
    draw(80,yb,7,YELLOW,2)
    draw(96,yb,3,YELLOW,2)
    draw(112,yb,0,YELLOW,2)
    draw(128,yb,24,YELLOW,2)

End Sub

Sub cake2(x As Byte, y As Byte)
    rectan(x+1,y+16,x+65,y+17,WHITE)
    rectan(x,y+17,x+66,y+25,WHITE)
    rectan(x+1,y+25,x+65,y+49,ORANGE)
    rectan(x+2,y+49,x+64,y+50,ORANGE)
    icing2(x,y+25)
    icing2(x+16,y+25)
    icing2(x+33,y+25)
    icing2(x+50,y+25)
    candle2(x+31,y)
    candle2(x+10,y)
    candle2(x+50,y)

End Sub

Sub icing2(x As Byte, y As Byte)
    rectan(x,y,x+5,y,WHITE)
    rectan(x+10,y,x+16,y,WHITE)
    rectan(x,y+1,x+2,y+2,WHITE)
    rectan(x+13,y+1,x+16,y+2,WHITE)
End Sub


Sub candle2(x As Byte, y As Byte)
    rectan(x+1,y+7,x+5,y+15,CYAN)
    rectan(x+2,y+1,x+3,y+6,YELLOW)
    rectan(x+1,y+3,x+4,y+5,YELLOW)
    'pixel(x+3,y,YELLOW)
    rectan(x+3,y,x+3,y,YELLOW)

End Sub

        'draw char
Sub draw(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( _
    0x7E, 0x11, 0x11, 0x11, 0x7E, _' A
    0x7F, 0x49, 0x49, 0x49, 0x36, _' B
    0x3E, 0x41, 0x41, 0x41, 0x22, _' C
    0x7F, 0x41, 0x41, 0x22, 0x1C, _' D
    0x7F, 0x49, 0x49, 0x49, 0x41, _' E
    0x7F, 0x09, 0x09, 0x01, 0x01, _' F
    0x3E, 0x41, 0x41, 0x51, 0x32, _' G
    0x7F, 0x08, 0x08, 0x08, 0x7F, _' H
    0x00, 0x41, 0x7F, 0x41, 0x00, _' I
    0x20, 0x40, 0x41, 0x3F, 0x01, _' J
    0x7F, 0x08, 0x14, 0x22, 0x41, _' K
    0x7F, 0x40, 0x40, 0x40, 0x40, _' L
    0x7F, 0x02, 0x04, 0x02, 0x7F, _' M
    0x7F, 0x04, 0x08, 0x10, 0x7F, _' N
    0x3E, 0x41, 0x41, 0x41, 0x3E, _' O
    0x7F, 0x09, 0x09, 0x09, 0x06, _' P
    0x3E, 0x41, 0x51, 0x21, 0x5E, _' Q
    0x7F, 0x09, 0x19, 0x29, 0x46, _' R
    0x46, 0x49, 0x49, 0x49, 0x31, _' S
    0x01, 0x01, 0x7F, 0x01, 0x01, _' T
    0x3F, 0x40, 0x40, 0x40, 0x3F, _' U
    0x1F, 0x20, 0x40, 0x20, 0x1F, _' V
    0x7F, 0x20, 0x18, 0x20, 0x7F, _' W
    0x63, 0x14, 0x08, 0x14, 0x63, _' X
    0x03, 0x04, 0x78, 0x04, 0x03, _' Y
    0x61, 0x51, 0x49, 0x45, 0x43, _' Z
    0x00, 0x00, 0x00, 0x00, 0x00, _' (space)26
    0x24, 0x2A, 0x7F, 0x2A, 0x12, _' $ 27
    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(0xA8)    '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
 

Attachments

  • bd_tft_405.jpg
    bd_tft_405.jpg
    35.8 KB · Views: 518
  • bd_tft_uno.gif
    bd_tft_uno.gif
    3.6 KB · Views: 85
  • birthday.zip
    3.5 KB · Views: 51
  • bd_tft_85.jpg
    bd_tft_85.jpg
    41.2 KB · Views: 83
Top