Advertisement  

Tuesday, 19 March 2024
     
 
Main Menu
Home Home
Shop Shop
News News
BASCOM-AVR BASCOM-AVR
BASCOM-8051 BASCOM-8051
Products Products
Application Notes Application Notes
Publications Publications
Links Links
Support Center Support Center
Downloads Downloads
Forum Forum
Resellers Resellers
Contact Us Contact Us
Updates Updates
MCS Wiki MCS Wiki
Online Help
BASCOM-AVR Help BASCOM-AVR Help
BASCOM-8051 Help BASCOM-8051 Help
Contents in Cart
Show Cart
Your Cart is currently empty.
Search the Shop

Products Search

User Login
Username

Password

If you have problem after log in with disappeared login data, please press F5 in your browser

RSS News
 
     
 

 
   
     
 
AN #196 - DotMatrix display Print
BASCOM guru Ben Zijlstra wrote support for the neat matrix board based on some code he found on the net.
Paulvk (check out his forums blog projects) added a lot of functionality such as IR control as you can read in his blog. So a good moment to create an AN out if it.

This is for the 4 digit HT1632 driven 32 x 8 matrix display JY-MCU-3208.
A RX8025 real time clock and resistors have been soldered to the board also a MCP9700 analog temperature sensor has been used in place of an I2C  one as the RTC is on different pins and we can only have one I2C port in Bascom  with this board/AVR.
A TSOP31236 infra-red receiver is used but any suitable one that runs off 5 volts will do.
The 3 buttons on the board are not used as space in flash was needed and they are redundant with an IR remote.
It is necessary to load and run the infra-red timing and decode programs to determine the characteristics and codes for the remote used Demo version of Bascom can be used for this but the full is required for this code.











Schematic of added parts

Because size of schematic of main board it can be downloaded from here : icon jy-mcu_3208_schematic.pdf (34.10 KB)  

Datasheet for RX8025 : icon RX8025SA.pdf (444.62 KB)


Full commented source code: (can be downloaded with rest files from here : icon Matrix-Clock-Programs.zip )
( code is based on Ben Zijlstra’s code published on MCS Forum )



'---------------------------------------------------------------------------------------
'This is for the 4 digit HT1632 driven 32 x 8 matrix display JY-MCU-3208
' Note as the code takes almost all the flash some parts need
' to be commented out to use the debug prints
' A RX8025 real time clock and resistors have been soldered to the board
' also a MCP9700 analog temprature sensor has been used in place of an I2C
' one as the RTC is on diffrent pins and we can only have one I2C port in Bascom
' with this board/AVR
' A TSOP31236 infra-red reciver is used but any suitable one that runs off 5 volts will do
' The 3 buttons on the board are not used as space in flash was needed
' and they are redundant with an IR remote
' It is nessary to load and run the infra-red timing and decode programs
' to determin the characteristics and codes for the remote used Demo version of
' Bascom can be used for this but the full is required for this code'
'--------------------------------------------------------------------------
' I have left some replaced code in but commented out so that it can be seen
' how Sub programs can be used to reduce code & flash use
'
'
'
'--------------------------------------------------------------------------------------------------------------
'
'I used an old VCR remote control hence PLAY & EJECT just replace the codes received for the buttons
'in your remote at the constants and re-type the instructions with your button choices
'Note I wrote these instructions for myself as there are too many to remember!
'
'
'CLOCK OPERATING INSTRUCTIONS
'
'
'Constant              Button                      Function
'
'Pause                 PAUSE   This displays the temprature
'
'Irclock               CLOCK   This puts theclock into time set mode
'
'Play                  PLAY      This causes the date to be displayed
'
'Eject                 EJECT    This turns the display off
'
'Poweron               POWER ON  This turns the display on
'
'Square                SQUARE This sets the display to max brightness
'
'Arrowright            ARROWRIGHT This changes the brightnes in steps from low to high in a loop
'
'Rew                   REWIND   This stors the current brightness as the DUSK SETTING
'
'Ff                    FAST FORWARD This stors the current brightness as the DAYLIGHT SETTING
'
'Sstop                 STOP This stors the current brightness as the DARK SETTING
'
'Rec                   RECORD This turns the alarm on
'
'Tvvcr                 TVVCR This turns the alarm off & stops the display flashing
'
'TIME SET MODE-------------------AFTER PRESSING CLOCK
'
'Longp                  LONGPLAY    This selects - Set the time
'
'Av                     AV  This selects - Set the date
'
'Skip                   SKIP  This selects - Set the alarm time and days
'
'How to set Time & Date
'----------------------------
'
'Press CLOCK this puts us into setting mode at any time pressing CLEAR will abort the mode
'
'Press LONGPLAY  to set the time
'Enter hours and minutes via the number buttons then press OK to store them
'
'Press AV to set the date
'Enter month then day then two digits for the year the 20 is entered automatically (so it works for only 98 years)
'now press REC Record Day will be displayed then enter the day of the week starting at 0 for sunday
'when the correct day is shown press OK to store the date
'
'Press SKIP to set the alarm time and days
'Enter hours and minutes
'then press ARROW UP to move through the days of the week SUN MON TUE will display on the clock
'then press 1 or 0   1 will set that day for an alarm 0 with turn that day off any other number is a 1
'press OK to store the alarm setting
'
'---------------------------------------------------------------------------------------------------------------------




$regfile = "m8adef.dat"
$crystal = 8000000                                          'using internal RC
$hwstack = 128
$swstack = 256
$framesize = 256

$baud = 19200

'--fuse settings
'$PROG &HFF,&HC4,&HC7,&H00' generated. Take care that the chip supports all fuse bytes.


$lib "ds1307clock.lib" 'both chips are similar

Declare Sub Clrd                                            'clears display
Declare Sub Get_character
Declare Sub Show_text                                       'writes text data to display chip


Declare Sub Commandout                                      'sends commands to the HT1632 display driver
Declare Sub Rotate_chr                                      'rotates the eeprom data 90 deg
Declare Sub Get_chr                                         'caculates the position in eeprom of the character

Declare Sub Roll_over                                       'calls Roll_digit 8 times to roll the character in


Declare Sub Display_chr

Declare Sub Showtime                                        'gets the time from the RX8025 to be displayed

Declare Sub Roll_digit                                      'rolls the digit into the display on byte at a time

Declare Sub Bright_up                                       'changes the brightness of display

Declare Sub Add_kar

'--this sub for debug prints of RX8025 registers

'Declare Sub I2c_print

Declare Sub Set_tick

Declare Sub I2c_write                                       'writes to the RX8025


Declare Sub Dig1_2                                          'displays characters 1 & 2

Declare Sub Dig3_4                                          'displays characters 3 & 4

Declare Sub St_time                                         'looks up eeprom for character patern

Declare Sub I2c_read                                        'reads from RX8025

Declare Sub Add_chr                                         'add characters to be displayed

Declare Sub Handle_infrared                                 'decodes infra-red input


'address of rx8025
Const Rx8025w = &H64                                        ' Addresses of rx8025 clock
Const Rx8025r = &H65
Const 24hr = &HE0                                           'select 24 hour mode
Const 24hron = &H20
Const Alarmon = &HE3
Const Alarmoff = &H23




'--these are the control codes for the display chip
Const Senddata = &B0010100000000000
Const Sysen = &B100000000010
Const Ledon = &B100000000110

Const Ledoff = &B100000000100
Const Blinkon = &B100000010010

Const Mastermode = &B100000101110
Const Rc = &B100000110110
Const Commonsoption = &B100001000000                        'N-MOS open drain output
Const Pwmduty = &B100101111100
Const Pwm 1_16duty = &B100101000000
Const Pwm 2_16duty = &B100101000100
Const Blinkoff = &B100000010000



'--remote control constants need to test with chosen remote to get codes
'--using the infra-red debugging programs with a serial port on a pc
'--

Const Remoteid = 183
Const Arrowup = 24740
Const Arrowdown = 41572
Const Arrowright = 58404
Const Arrowleft = 8420
Const Square = 17828
Const Eject = 49188
Const Poweron = 50468
Const Ok = 25508
Const Klear = 2020
Const Numone = 33124
Const Numtwo = 16804
Const Numthree = 484
Const Numfour = 49956
Const Numfive = 33636
Const Numsix = 17316
Const Numseven = 996
Const Numeight = 50980
Const Numnine = 34660
Const Numzero = 49444
Const Irclock = 4068
Const Tvvcr = 34148
Const Skip = 46948
Const Av = 21924
Const Longp = 53796
Const Rec = 33380
Const Rew = 16548
Const Ff = 228
Const Sstop = 32868
Const Play = 49700
Const Pause = 740









Cs1 Alias Portb.3                                           'chip select for display driver
Clk Alias Portb.4                                           'chip clock for display driver
Dat Alias Portb.5                                           'chip data line for display driver
'--configure these as outputs
Config Dat = Output
Config Clk = Output
Config Cs1 = Output

'--Pins connected to push buttons
'redundant with infra-red remote
'Push1 Alias Pind.5
'Push2 Alias Pind.6
'Push3 Alias Pind.7
Ina Alias Pinb.0
Almin Alias Pinc.3
Buzz Alias Portc.0
Llevel Alias Pinc.4

'Config Push1 = Input
'Config Push2 = Input
'Config Push3 = Input
Config Almin = Input 'inerrupt B output from RX8025
Config Buzz = Output 'output for use as buzzer or to switch something on
Config Llevel = Input 'connected to light sensor


Config Ina = Input

'Set Portd.5
'Set Portd.6                                                 'Switch on the pullup for the buttons
'Set Portd.7

'Config Debounce = 1

Dim Chrrom(336) As Eram Byte 'the character fonts in eeprom

Dim Txt(51) As Eram String * 1                              'days of week & text in eeprom
Dim Ereg As Eram Byte
Dim Eereg As Byte

'---here we stor the alarm settings in eeprom in case of battery fail


Dim Bright As Eram Word 'stor brightness for night
Dim Dusk As Eram Word 'stor brightness for in the middle
Dim Daybright As Eram Word 'stor brightness for day light


Dim Alarmmins As Eram Byte 'this is the alarm settings for minutes
Dim Alarmhours As Eram Byte 'this is the alarm settings for hours
Dim Alarmdays As Eram Byte 'this is the alarm settings for days


Dim Alarmcodes(31) As Eram Word



Dim Seeprm As Byte 'start pointer in eeprom
Dim Steps As Byte 'number of eeprom bytes to get
Dim Days As Byte
Dim Daybit As Byte
Dim Daybyte As Byte
Dim Setday As Bit
Dim Dayweek As Byte
Dim Almison As Bit
Dim Mabcd As Byte

Dim B As Byte

Config Scl = Portb.1                                        ' we need to provide the SCL pin name
Config Sda = Portb.2                                        ' we need to provide the SDA pin name


Dim Weekday As Byte

Dim G As String * 32

'--infra red

Dim Length As Word
Dim Recvdata As Long
'--
'--Overlay is a good function here it enables me to
'--break the Recvdata Long (4 bytes) into two Datain words (2 bytes each)
'--and importantly uses no RAM
Dim Datain(2) As Word At Recvdata Overlay
Dim Bx As Byte
Dim Px As Bit
Dim Dotim As Byte
Dim Dodat As Bit
Dim Klk As Bit
Dim Timedate As Bit
Dim Digit As Byte
Dim Timeset As String * 8
Dim Dateset As String * 8
Dim Lmins As Byte
Dim Lhour As Byte



Dim I2caddress As Byte
Dim I2cdata As Byte
Dim X As Byte
Dim Y As Byte
Dim D As Byte
Dim E As Word
Dim F As Word
'Dim Fnt(8) As Byte


Dim Kar As String * 1
Dim Lt As String * 8                                        'changed from local to make use of a sub

Dim Shiftdat As Word
'Dim Shiftdodat As Word
Dim Pulswidth As Word
Dim Z As Byte
Dim W As Word
Dim K As Word
Dim B1 As Byte
Dim B2 As Byte
Dim Cd As Byte
Dim Col As Bit

 Dim Ana As Double

 '-- Ana is 8 bytes long
 '--the dim below uses the Overlay function
 '--this breakes Ana up into 8 one byte variables
 '--and importantly uses no RAM

 Dim Aa(8) As Byte At Ana Overlay


 Dim Bb(8) As Byte 'a place to stor the 8 bytes of the character
 'font from eeprom

 '--digits 1 to four with space for two digits the before and after
 '--so we can roll them in
 '--this holds each 8x8 digit in one variable
 Dim Dig1 As Double
 Dim Dig2 As Double
 Dim Dig3 As Double
 Dim Dig4 As Double

 Dim Dignew As Double
 Dim Digtemp As Double

 '--with the overlay we break up each double into 8 bytes which gives us each row 1 t 8
 '--and importantly uses no RAM

 Dim D1(8) As Byte At Dig1 Overlay
 Dim D2(8) As Byte At Dig2 Overlay
 Dim D3(8) As Byte At Dig3 Overlay
 Dim D4(8) As Byte At Dig4 Overlay
 Dim Ddnew(8) As Byte At Dignew Overlay
 Dim Ddtemp(8) As Byte At Digtemp Overlay
 Dim Lv As Byte

 Dim Dignum As Byte 'this is the number of the digit

 Dim Light As Word 'value from the ADC connected to the light sensor

 'used in deguging
 'Dim N As Byte

 'Dim M As Byte

 'Dim O As Byte

 'Dim P As Byte

 '
 'Set up the ADC part of the chip let the compliler handle Prescaler = Auto  set the Reference = Avcc this uses the voltage
 'fed to the micro, the board has a 1nF capacitor from AREF to ground already so no need to add it
 '

 Config Adc = Single , Prescaler = Auto , Reference = Avcc


 '---Here we are not using the timer but its interrupt function to trigger code
 '---this is a very usefull thing as with some chips if you use the other functions like
 '---two RS232 serial ports INT0 & INT1 are no longer avaliable
 '
 '===for 1 second tick
 Config Timer1 = Timer , Capture_edge = Rising , Noise_cancel = 0

 On Capture1 Sectic                                        'go to Sectic on interrupt

'------this is for the infra-red

 On Int1 Int_one                                           'go to Int_one on interrupt



 Dim Tim As String * 8                                     '8 characters for time and date

 Config Date = Dmy , Separator = Minus                     ' EG 22-10-12

 Dim Tick As Byte 'we use this to count up to 60

 Config Clock = User                                       'we do our own clock (User) not using the megaAVR timer and 32KHz crystal

'---
'--- NOTE You must enable the individual interrupts for them to work
'--- Enable Interrupts does not do this
'---

 Enable Capture1 'the one second pulse from RTC

 Enable Int1 'infra-red detector

 Enable Interrupts

 Reset Buzz                                                'turn buzzer off



 '---read control register E I2cdata will hold the contents



  I2caddress = &HE4
 Call I2c_read

 'debug prints

 'Print "I2c>" ; Bin(i2cdata)

  Eereg = Ereg

 'Print "EEP>" ; Bin(eereg)

 If I2cdata = Eereg Then 'if it does not match the stored value
 'this may be because the alarm is on
 nop

 Else 'or the RTC chip has just been powered up


  I2caddress = &HE0
  I2cdata = Eereg

 'Print "eeprom" ; Hex(i2cdata)

 Call I2c_write

 End If

 'Print "eeprom" ; Hex(i2cdata)

 '--debug prints


'----------------------------
'--this shows how to read the control registers of the RX8025


 'I2cstart                                                  ' Generate start code
 'I2cwbyte Rx8025w                                          ' send write address
 'I2cwbyte &H80                                             ' start address in rx8025 with read bit set
 ' we can read from this address

 '--read back the two control registers

 'I2crbyte N , Ack
 'I2crbyte M , Ack
 'I2crbyte O , Ack
 'I2crbyte P , Nack
 'I2cstop

 'Print "Reg MINS>" ; Bin(n)
 'Print "Reg HOURS>" ; Bin(m)
 'Print "Reg DAYS>" ; Bin(o)
 'Print "Reg E>" ; Bin(p)



 Daybit = 1




 D = 12

 Set Cs1

 Shiftdat = Sysen

 Call Commandout

 '--turn the display on

 Shiftdat = Ledon

 Call Commandout


 '--as we only have one display driver we set it as a master
 Shiftdat = Mastermode

 Call Commandout

 Shiftdat = Rc

 Call Commandout

'--set the type of led common anode or cathode

 Shiftdat = Commonsoption

 Call Commandout

'--set the display to maximum brightness

 Pulswidth = 2368

 Shiftdat = Pwmduty

 Call Commandout








'here we get the alarm time from eeprom to write to the RTC
'at default these will be all 0 but if we set alarm values and
'the back up battery is flat we will have not to reset the alarm data
'also as I intend to have a clock with a retrofited mega328 which will
'get its time from the internet via NTP so it does not even need back up


   Lmins = Alarmmins

   Lhour = Alarmhours

   Daybyte = Alarmdays
 'if the value is greater than 0
 If Lhour > 0 Then 'write alarm time to real time clock

 I2cstart ' Generate start code
 I2cwbyte Rx8025w                               ' send address
 I2cwbyte &H80                                  ' starting address in rx8025
 I2cwbyte Lmins
 I2cwbyte Lhour
 I2cwbyte Daybyte
 I2cstop


 End If


Dignum = 1


Call Clrd                                                   'clear Display


 Dotim = 0
 Dodat = 0

 Klk = 0
 Tick = 60


 Timedate = 1                                               'show date

 'Call Showtime

'--here we go around in a circle a do--loop
'--waiting to be sent to an interrup which comes
'--once every second from the RTC clock or from the
'--infra-red reciver

 Do

 If Klk = 0 Then 'if Klk 1 we are setting the time & date
 'so leave display alone
 If Tick >= 59 Then





       Light = Getadc(4) 'get the value for thelight sensor


 '--debug print
 'Print "Light" ; Light                                'this is so you can determin what is the dark, dusk, daylight value
 'comment out date$ print to use
 Select Case Light


 Case Is > 700                                        'it must be dark

       Pulswidth = Bright                                   'set it to what we stored in eeprom


 Case Is > 550                                        'it must be almost dark

       Pulswidth = Dusk                                     'set it to what we stored in eeprom



 Case Else

       Pulswidth = Daybright                                'set it to what we stored in eeprom



 End Select

       Shiftdat = Pulswidth

 Call Commandout


 Call Showtime

 Call Set_tick

'---So why send date and time to serial port?
'---well I intend to build slave clocks that
'---will recive this via a wireless link
'---thus every clock in my house will have
'---exactly the same time I only need set
'---the master clock, along comes daylight saving
'---the master will know this and update itself then
'---transmit time and date which all the slaves
'---will get and update their times

 Print Date; "<<<>>>" ; Time$



 End If

 End If

 If Almin = 0 And Almison = 0 Then 'we have an alarm

          Almison = 1                                       'stop the if-then running

          Shiftdat = Blinkon                                'flash display

 Call Commandout

 Set Buzz                                          'turn on buzzer

 End If


Loop 'go back to the DO

End


'--read a byte from the RTC
 Sub I2c_read

 I2cstart ' Generate start code
 I2cwbyte Rx8025w                                          ' send write address
 I2cwbyte I2caddress                                       ' control register two address in rx8025
 I2crbyte I2cdata , Nack ' read in byte

 I2cstop

 End Sub

'--write a byte to the RTC
 Sub I2c_write

 I2cstart ' Generate start code
 I2cwbyte Rx8025w                                          ' send write address
 I2cwbyte I2caddress                                       ' control register two address in rx8025
 I2cwbyte I2cdata

 I2cstop



 End Sub

'call three subs in turn
 Sub Display_chr

 Call Get_chr

 Call Rotate_chr

 Call Roll_over


 End Sub


'-display digit 1 & 2
 Sub Dig1_2

   Dignum = 1

  Kar = Left(lt , 1)




Call Display_chr


Dignum = 2

  Kar = Mid(lt , 2 , 1)



Call Display_chr



 End Sub


 '-display digit 3 & 4
 Sub Dig3_4

Dignum = 3

  Kar = Mid(lt , 4 , 1)



Call Display_chr

Dignum = 4

  Kar = Mid(lt , 5 , 1)



Call Display_chr


 End Sub

'--this will display the time or date depending
'--on the setting of the Timedate variable

 Sub Showtime

'--these local variables a temporary we release the RAM used by them
'--when we exit the sub and they are only avaliable in this sub
'--this makes best use of what can be a scarce resource

 Local Lm As String * 2
 Local Ln As String * 2
 Local Lo As String * 4

 Select Case Timedate

 Case 0

      Lt = Time$


 Case 1

      Lt = Date$

      Tick = 0

      Lm = Left(lt , 2) 'month
      Ln = Mid(lt , 4 , 2) 'day
      Lo = Right(lt , 2) 'year

      Lt = Ln + "-" + Lm + "-" + Lo                         'day month year

 Print Lt

       Seeprm = 26                                          'eeprom start point
       Steps = 4                                            'number of bytes from eeprom

 Call St_time                                         'now get the bytes from eeprom
 'these will put a character on the display

 Wait 2


 End Select

 '--debug print

 'Print "LT>>" ; Lt


 Call Dig1_2


 Call Dig3_4


 If Timedate = 1 Then

 Wait 5

    Seeprm = 34
    Steps = 2
 Call St_time






  Dignum = 3

  Kar = Mid(lt , 7 , 1)

 Call Display_chr


  Dignum = 4

  Kar = Mid(lt , 8 , 1)

 Call Display_chr

 Wait 5

  Timedate = 0

  Tick = 60

 Exit Sub

 Call Set_tick

 End If




End Sub

Sub Set_tick

Local Lk As String * 2


  Lt = Time$

  Lk = Right(lt , 2)

  Tick = Val(lk) - 2




End Sub



'--this gets the data from the infra-red

 Int_one:

 Pulsein Length , Pind , 3 , 1



'--the values in the case statements can be found with the infra-red debug programs

 Select Case Length

 Case Is < 60

     Recvdata.bx = 0

 Incr Bx

 'Waitms 1                                               'adjust this for timing if needed

 'Print "0" 'debug

 Case Is < 250

     Recvdata.bx = 1

 Incr Bx
 'Print "1" 'debug

 Case Is > 500                                           'we are at the end
 'this needs to be varied depending on
 Call Handle_infrared                                    'the remote used some do not have this


 Case Is > 400                                           'we are at the start
 'some do not have this
    Bx = 0





 End Select


 Return


'--this gets characters from the eeprom which have been placed in a particular
'--place and order there to make them simple to read this saves code space

 Sub St_time



 Local Lb As Byte


 For Lb = 1 To Steps                                        'now we get the text from eeprom to save some flash
 'the eeprom is now a character ROM
 Kar = Txt(seeprm) 'this saved 400 bytes of flash

 Dignum = Lb

 Call Display_chr

 Incr Seeprm

 Next Lb






 End Sub

 '--this reduced the code by over 100 bytes
 '--any task done a number of times can in most cases
 '--be done in a sub saving flash
 Sub Add_kar

   Timeset = Timeset + Kar


 Call Display_chr

 Incr Dignum


 End Sub


 Sub Add_chr

 Local Lkar As String * 1
 Local Lbit As Byte

 Select Case Dotim

 Case 1                                                'set time

 Select Case Dignum

 Case 1 To 2


 Call Add_kar


 Case 3

          Timeset = Timeset + ":"


 Call Add_kar


 Case 4

          Timeset = Timeset + Kar + ":" + "00"



 Call Display_chr

          Dignum = 1

 End Select


 Case 0                                                'set date



 Select Case Dignum

 Case 1 To 2


 Call Add_kar


 Case 3

          Timeset = Timeset + "-"


 Call Add_kar



 Case 4

          Kar = Kar + "-"

 Call Add_kar



 Case 5
            Lkar = Kar                                      'save character

            Seeprm = 34
           Steps = 2
 Call St_time

           Kar = Lkar                                       'replace character

 'debug print
 'Print "tset-mel>>" ; Kar

          Dignum = 3

 Call Add_kar


          Dignum = 6

 Case 6


          Dignum = 4

 Call Add_kar


          Digit = 1


 Case 7

          Dignum = 4

          Dayweek = Val(kar)

 Call Display_chr






 End Select

 Case 2

 Select Case Dignum                                  'set alarm

 Case 1 To 4                                        'hour and minutes

 Call Add_kar


 Case 5                                             'set days for the alarm

         Dignum = 4



 Call Display_chr

'--------here we are setting the bit for the day to 1 or 0

         Lbit = Val(kar)

 'debug
 'Print "Lbit" ; Lbit

 If Lbit > 1 Then 'so if you press a number higher than 1 we asume it to be 1

           Lbit = 1

 End If

         Daybyte.daybit = Lbit

 'DEBUG PRINT

 'Print "tset>>" ; Timeset
 'Print "YES" ; Bin(daybyte)

 Incr Daybit

 End Select



 End Select



 End Sub


'--here we use the decoded infra-red data as commands

Sub Handle_infrared                                         'infra-red command

'--again we use temporary ram variables

 Local Temp As Word
 Local Deg As Single
 Local Tval As String * 3
 Local Alm As String * 2
 Local Lday As Byte


 Shift Recvdata , Left , 6                                'line up the device ID and data to be in each variable


 Shift Datain(1) , Right , 7                              'move the device ID to the front of the variable


 'debug
 'Print Datain(1)                                         'these are to see the codes from remote
 'Print Datain(2)



 If Datain(1) = Remoteid Then 'Remoteid is an idetification code sent by
 'the infra-red remote to identify itself
 'it sends this before the data of the button
 'so that when you turn your TV off your CD player
 'knows its not its remote control and does not react

    Datain(1) = 0

 If Klk = 1 Then 'we are in set clock mode

 Select Case Datain(2)



 Case Longp                                           'set time

         Dotim = 1

         Dodat = 0

         Timeset = ""


         Seeprm = 22
         Steps = 4                                          'number of bytes from eeprom

 Call St_time

         Dignum = 1



 Case Av                                              'set date
 'when we get to the year the 20 is automatically
 'inserted before you put in the two year digits
 'so yes its only good for 98 years



         Dotim = 0

         Timeset = ""

         Seeprm = 26
         Steps = 4                                          'number of bytes from eeprom

 Call St_time

         Dignum = 1


 Case Skip                                            'set alarm

         Dotim = 2

         Timeset = ""

         Seeprm = 45
         Steps = 4
         Days = 1
         Daybit = 0                                         'number of bytes from eeprom

 Call St_time

         Dignum = 1



 'Case 0



 Case Numone                                          'number 1

          Kar = "1"


 Call Add_chr

 Case Numtwo                                          'number 2

          Kar = "2"

 Call Add_chr


 Case Numthree                                        'number 3

          Kar = "3"

 Call Add_chr


 Case Numfour                                         'number 4

          Kar = "4"

 Call Add_chr


 Case Numfive                                         'number 5

          Kar = "5"

 Call Add_chr


 Case Numsix                                          'number 6

          Kar = "6"

 Call Add_chr


 Case Numseven                                        'number 7

          Kar = "7"

 Call Add_chr


 Case Numeight                                        'number 8

          Kar = "8"

 Call Add_chr


 Case Numnine                                         'number 9

          Kar = "9"

 Call Add_chr


 Case Numzero                                         'number 0

          Kar = "0"

 Call Add_chr




 Case Arrowup                                         'move through days for alarm
 'eg SUN , MON ,TUE
         Seeprm = Days
         Steps = 3

         Dotim = 2

 Call St_time

         Days = Days + 3                                    'move to the position of the next day in eeprom



          Dignum = 5

 'Wait 1

 Case Rec                                             'set day of week
 'here we start at 0 for sunday
 'and go up to 6 for saturday
 'as this is how the RX8025 RTC works
         Seeprm = 49
         Steps = 3

 Call St_time

         Dignum = 7




 Case Ok



 Select Case Dotim

 Case 0                                           'date

 Date= Timeset                                 'set the date in the RTC


            Tick = 0

            Klk = 0


 Case 1                                           'time

 Time= Timeset                                 'set the time in the RTC

            Tick = 0

            Klk = 0

 Case 2                                           'alarm set

           Alm = Left(timeset , 2)

           Lhour = Val(alm)

           Lhour = Makebcd(lhour)

           Alm = Mid(timeset , 3 , 2)

           Lmins = Val(alm)

           Lmins = Makebcd(lmins)

          Alarmmins = Lmins                                 'write the values to eeprom
 'to use to set if power fails
          Alarmhours = Lhour                                'Note not yet implimented
 'due to flash space
          Alarmdays = Daybyte


          I2caddress = &HE0                                 'first turn alarm off
          I2cdata = Alarmoff                                'reccomended in spec documents
 Call I2c_write

 I2cstart ' Generate start code
 I2cwbyte Rx8025w                               ' send address
 I2cwbyte &H80                                  ' starting address in rx8025
 I2cwbyte Lmins                                 'write minutes to RX8025
 I2cwbyte Lhour                                 'write hours to RX8025
 I2cwbyte Daybyte                               'write day settings to RX8025
 I2cstop



            Tick = 58

            Klk = 0




 End Select


 Call Showtime


 Case Klear                                           'abort the present operation

           Klk = 0
           Dignum = 1

 Call Showtime



 End Select

     Recvdata = 0

 Else

 Select Case Datain(2)

 Case Pause                                           'get temprature
 'using an MCP9700

         Seeprm = 30
         Steps = 4                                          'number of bytes from eeprom
 'to display the word TEMP
 Call St_time

         Dignum = 1

 Wait 2

         Temp = Getadc(2)

         Deg = Temp * .00497                                'refrence volts 4.97
 'this needs to be adjusted to suit
 'the value your analog reference is!
 'measured at the AREF pin

         Deg = Deg - .5                                     '0/C at 500 mili volts

         Deg = Deg / .01                                    '10 mili volts per Deg/C

 Print "Deg C/>" ; Deg
         Tval = Fusing(deg , "##.#") 'only print 3 digits two before one after the decimal point

         Lt = Tval + ":" 'the ":" character has been replaced by a deg C one in the eeprom
 Call Dig1_2
 Call Dig3_4


 Case Irclock                                         'we will set clock

        Klk = 1                                             'hold all events that change the display


 Case Play                                            'show date


        Timedate = 1

 Call Showtime

'--not really needed alarm turns on blink
 ' Case Klear

 ' Shiftdat = Blinkon

 'Call Commandout

'--need this to turn blink off after alarm turns it on
'--or we can include it in alarm off as I have done
'--it depends if you want the alarm to go off again
'       Case Ok

'          Shiftdat = Blinkoff

'          Call Commandout




 Case Eject

          Shiftdat = Ledoff                                 'turn off the display

 Call Commandout


 Case Poweron

          Shiftdat = Ledon                                  'turn on the display

 Call Commandout



 Case Square

          Shiftdat = Pwmduty                                'maximum brightness

 Call Commandout

 Case Arrowright

 Call Bright_up


'---------debug prints to get value of alarm registers in RX8025


 'Case Ff

 'I2caddress = &H34

 'Call I2c_read
 'Print ">>>>" ; Bin(i2cdata)


 'I2caddress = &H70
 'I2cdata = 0

 'Call I2c_write
 'Print ">>>>" ; Bin(i2cdata)

 ' I2caddress = &H84

 ' Call I2c_read
 ' Print ">>>>" ; Bin(i2cdata)

 '
 'I2caddress = &H94

 'Call I2c_read
 'Print ">>>>" ; Bin(i2cdata)

 'I2caddress = &HA4

 'Call I2c_read
 'Print ">>>>" ; Bin(i2cdata)

 ' I2caddress = &HE4

 ' Call I2c_read
 'Print ">>>>" ; Bin(i2cdata)

 'I2caddress = &HF4

 'Call I2c_read
 'Print ">>>>" ; Bin(i2cdata)


 'Call I2c_print

 'Case Rew

 'I2caddress = &H94

 'Call I2c_print


'-------------------------------------------------

 Case Rew

            Dusk = Pulswidth                                'stor current brightness for dusk setting


 Case Ff

            Daybright = Pulswidth                           'stor current brightness for daylight setting

 Case Sstop

            Bright = Pulswidth                              'stor current brightness for darkness setting



 Case Rec                                             'turn alarm on

          Almison = 0

          I2caddress = &HE0
          I2cdata = Alarmon

 Call I2c_write

 Case Tvvcr                                           'turn alarm off

 Reset Buzz                                        'turn buzzer off

          I2caddress = &HE0
          I2cdata = Alarmoff

 Call I2c_write

          I2caddress = &HF0                                 'reset the bits to 0 in this register
          I2cdata = 0                                       'as is reccomended in the data sheet

 Call I2c_write

          Shiftdat = Blinkoff                               'stop display flashing

 Call Commandout





 End Select

    Recvdata = 0

 End If

 End If



End Sub



'--for debug prints
'Sub I2c_print

 'Call I2c_read
 'Print ">>>>" ; Bin(i2cdata)



'End Sub




Sub Bright_up                                               'increase brightness then loop back to
 'lowest value then up again

 If Pulswidth > 2428 Then

          Pulswidth = 2368

 End If

       Shiftdat = Pulswidth

 Call Commandout

       Pulswidth = Pulswidth + 4



End Sub



'--This ISR gets called once every second using the 1Hz from the RTC chip

Sectic:

 '--this If > Then flashes the leds in the center for a clock display
 '--once every second
 If Klk = 0 Then
 Tick = Tick + 1


 If Col = 0 Then
 'D2(1).7 = 0
   D2(2).= 1                                              '*
   D2(3).= 1                                              '*
   D2(4).= 0                                              '
   D2(5).= 1                                              '*
   D2(6).= 1                                              '*
   D2(7).= 0                                              '
 'D2(8).7 = 0

'   Ana = Dig2
'
'   W = 16
'   Cd = 1
'
'   Call Show_text

   Col = 1

 Else

 'D2(1).7 = 0
   D2(2).= 0                                              '
   D2(3).= 1                                              '*
   D2(4).= 1                                              '*
   D2(5).= 0                                              '
   D2(6).= 1                                              '*
   D2(7).= 1                                              '*
 'D2(8).7 = 0

'   Ana = Dig2
'
'   W = 16
'   Cd = 1
'
'   Call Show_text

   Col = 0

 End If

    D2(8).= 0

    Ana = Dig2

   W = 16
   Cd = 1

 Call Show_text



End If

Return





'--this sends the text to the display chip

Sub Show_text

'--use local variables as we have only 1K of ram
Local Ldat As Word
Local Lz As Byte


'W = 0                                                       'address "0"





Ldat = &B0000001010000000                                   'write data command with space for address



Ldat = Ldat + W                                             'add address "W" to command (Shiftdodat)

 Shift Ldat , Left , 6                                      'move the first bit to the front of the word

 Reset Cs1                                                  'select HT1632
Waitus 100                                                  'wait for it to stabilise

Shiftout Dat , Clk , Ldat , 1 , 10                          'clock out command and address



For Lz = 1 To Cd                                            'Cd alows us to clock out more than one character


Shiftout Dat , Clk , Ana , 3 , 64                           'clock out data 64 bits= one character
 'or 8 for one line,


Next Lz

 Set Cs1

End Sub

'--This gets a character from the font data
'--that is now in eeprom

Sub Get_chr

'--use local variables as we have only 1K of ram

Local Le As Word
Local Lf As Word
Local Lz As Byte

Le = Asc(kar) 'get the ASCII value of the character


 Le = Le - 48
 'If Le = 0 Then
 'Le = 1
 'End If

 Shift Le , Left , 3                                        'move up 8 bytes  as there is 8 per character
 'Le = Le * 8
 'Le = Le + 1

'Restore Shrunk8x8  moved into eeprom

For Lz = 1 To 8                                             'get 8 the bytes from eeprom

 Lf = Le + Lz

Bb(lz) = Chrrom(lf)


Next Lz


End Sub





'--This rotates the character 90deg to the left each time it is called

Sub Rotate_chr

'--use local variables as we have only 1K of ram

Local Lj As Byte
Local Lx As Byte
Local Ln As Byte
Local Lp As Byte

For Lj = 1 To 8

   Ln = Lj - 1


 For Lx = 1 To 8

    Lp = Lx - 1

       Aa(lj).lp = Bb(lx).ln



 Next Lx



 Next Lj



End Sub

'-this loads the data into the double word
'-Dignew is the new character Dig1 is character one, Dig2 is character two
'-Dig3 is character three, Dig4 is character four

Sub Roll_over

'--use local variables as we have only 1K of ram

'Local Lv As Byte
'--changed Lv to global to use Sub Roll_digit
'--removing 3 repeates of similar code saving 166 bytes of flash!


 Cd = 1                                                     ' only one characyer at a time


Dignew = Ana                                                ' move character into temp buffer


For Lv = 8 To 1 Step -1                                     'move character in one byte at a time


 Select Case Dignum

 Case 1

        Digtemp = Dig1

 Call Roll_digit

         Dig1 = Digtemp

         Ana = Dig1

         W = 0                                              'start of digit 1


 Case 2

        Digtemp = Dig2

 Call Roll_digit

         Dig2 = Digtemp

         Ana = Dig2

         W = 16                                             'start of digit 2


 Case 3

        Digtemp = Dig3

 Call Roll_digit

         Dig3 = Digtemp

         Ana = Dig3

         W = 32                                             'start of digit 3


 Case 4

        Digtemp = Dig4

 Call Roll_digit

         Dig4 = Digtemp

         Ana = Dig4

         W = 48                                             'start of digit 4




 End Select





'-----Roll_digit sub replaced all this
'
'  Select Case Dignum                                        'select character to change
'
'      Case 1
'
'        D1(8) = D1(7)
'        D1(7) = D1(6)
'        D1(6) = D1(5)
'        D1(5) = D1(4)
'        D1(4) = D1(3)
'        D1(3) = D1(2)
'        D1(2) = D1(1)
'        D1(1) = Ddnew(lv)
'
'         Ana = Dig1
'
'         W = 0                                              'start of digit 1
'
'      Case 2
 '
'
'        D2(8) = D2(7)
'        D2(7) = D2(6)
'        D2(6) = D2(5)
'        D2(5) = D2(4)
'        D2(4) = D2(3)
'        D2(3) = D2(2)
'        D2(2) = D2(1)
'        D2(1) = Ddnew(lv)
'
'         Ana = Dig2
'
'         W = 16                                             'start of digit 2
'
'      Case 3
'
'
'        D3(8) = D3(7)
'        D3(7) = D3(6)
'        D3(6) = D3(5)
'        D3(5) = D3(4)
'        D3(4) = D3(3)
'        D3(3) = D3(2)
'        D3(2) = D3(1)
'        D3(1) = Ddnew(lv)
'
'         Ana = Dig3
'
'         W = 32                                             'start of digit 3
'
'
'      Case 4
'
'
'        D4(8) = D4(7)
'        D4(7) = D4(6)
'        D4(6) = D4(5)
'        D4(5) = D4(4)
'        D4(4) = D4(3)
'        D4(3) = D4(2)
'        D4(2) = D4(1)
'        D4(1) = Ddnew(lv)
'
'         Ana = Dig4
'
'         W = 48                                             'start of digit 4
'
'
'  End Select


 Call Show_text


 Waitms 50                                                  'adjust for speed of roll over

Next Lv


End Sub

'--replaced the multiple code in the sub above
Sub Roll_digit


        Ddtemp(8) = Ddtemp(7)
        Ddtemp(7) = Ddtemp(6)
        Ddtemp(6) = Ddtemp(5)
        Ddtemp(5) = Ddtemp(4)
        Ddtemp(4) = Ddtemp(3)
        Ddtemp(3) = Ddtemp(2)
        Ddtemp(2) = Ddtemp(1)
        Ddtemp(1) = Ddnew(lv)


End Sub



'---My clear display, all bits at once

'--this writes all of the leds at a time

'__this writes "0" to all leds clearing display

Sub Clrd

  Dig1 = 0                                                  'clear the digit variables
  Dig2 = 0
  Dig3 = 0
  Dig4 = 0


  Ana = 0                                                   'set the value to "0"
  Cd = 4                                                    'send 64 bits 4 times & write to all bytes
 Call Show_text


End Sub





'--this sends the command bytes to the display

Sub Commandout


Reset Cs1
Waitus 100

Shift Shiftdat , Left , 4

Shiftout Dat , Clk , Shiftdat , 1 , 12

Set Cs1

End Sub




'called from ds1307clock.lib so a DS1307 could be used as they both are similar but
'the RX8025 has its own internal crystal which has been calibrated at the factory
'so it has a higher accuracy
Getdatetime:
 I2cstart ' Generate start code
 I2cwbyte Rx8025w                                          ' send address
 I2cwbyte &H04                                             ' start address in rx8025
 I2crbyte _sec , Ack
 I2crbyte _min , Ack ' MINUTES
 I2crbyte _hour , Ack ' Hours
 I2crbyte Weekday , Ack ' Day of Week
 I2crbyte _day , Ack ' Day of Month
 I2crbyte _month , Ack ' Month of Year
 I2crbyte _year , Nack ' Year
 I2cstop
  _sec = Makedec(_sec) : _min = Makedec(_min) : _hour = Makedec(_hour)
  _day = Makedec(_day) : _month = Makedec(_month) : _year = Makedec(_year)



Return

Setdate:
  _day = Makebcd(_day) : _month = Makebcd(_month) : _year = Makebcd(_year)



 I2cstart ' Generate start code
 I2cwbyte Rx8025w                                          ' send address
 I2cwbyte &H30                                             ' starting address in rx8025
 I2cwbyte Dayweek
 I2cwbyte _day                                             ' Send Date
 I2cwbyte _month                                           ' MINUTES
 I2cwbyte _year                                            ' Hours
 I2cstop
Return

Settime:


  _sec = Makebcd(_sec) : _min = Makebcd(_min) : _hour = Makebcd(_hour)


 I2cstart ' Generate start code
 I2cwbyte Rx8025w                                          ' send address
 I2cwbyte 0                                                ' starting address in rx8025
 I2cwbyte _sec                                             ' Send Data to SECONDS
 I2cwbyte _min                                             ' MINUTES
 I2cwbyte _hour                                            ' Hours

 I2cstop
Return




'Moved into eeprom
'$include "shrunk8x8.font"



'--------------------------------------
'--Here we stor text in eeprom to save on flash space

$eeprom 'start of eeprom data


Data 0 , 62 , 81 , 73 , 69 , 62 , 0 , 0                     ' 0
Data 0 , 0 , 66 , 127 , 64 , 0 , 0 , 0                      ' 1
Data 0 , 98 , 81 , 73 , 73 , 70 , 0 , 0                     ' 2
Data 0 , 34 , 73 , 73 , 73 , 54 , 0 , 0                     ' 3
Data 0 , 24 , 20 , 18 , 127 , 16 , 0 , 0                    ' 4
Data 0 , 47 , 73 , 73 , 73 , 49 , 0 , 0                     ' 5
Data 0 , 60 , 74 , 73 , 73 , 48 , 0 , 0                     ' 6
Data 0 , 1 , 113 , 9 , 5 , 3 , 0 , 0                        ' 7
Data 0 , 54 , 73 , 73 , 73 , 54 , 0 , 0                     ' 8
Data 0 , 6 , 73 , 73 , 41 , 30 , 0 , 0                      ' 9
Data 7 , 5 , 7 , 0 , 60 , 66 , 66 , 66                      ' : DEG C
Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0                          ' ;
Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0                          ' <
Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0                          ' =
Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0                          ' >
Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0                          ' ?
Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0                          ' @
Data 0 , 126 , 17 , 17 , 17 , 126 , 0 , 0                   ' A
Data 0 , 127 , 73 , 73 , 73 , 54 , 0 , 0                    ' B
Data 0 , 62 , 65 , 65 , 65 , 34 , 0 , 0                     ' C
Data 0 , 127 , 65 , 65 , 65 , 62 , 0 , 0                    ' D
Data 0 , 127 , 73 , 73 , 73 , 65 , 0 , 0                    ' E
Data 0 , 127 , 9 , 9 , 9 , 1 , 0 , 0                        ' F
Data 0 , 62 , 65 , 73 , 73 , 122 , 0 , 0                    ' G
Data 0 , 127 , 8 , 8 , 8 , 127 , 0 , 0                      ' H
Data 0 , 0 , 65 , 127 , 65 , 0 , 0 , 0                      ' I
Data 0 , 48 , 64 , 64 , 64 , 63 , 0 , 0                     ' J
Data 0 , 127 , 8 , 20 , 34 , 65 , 0 , 0                     ' K
Data 0 , 127 , 64 , 64 , 64 , 64 , 0 , 0                    ' L
Data 0 , 127 , 2 , 4 , 2 , 127 , 0 , 0                      ' M
Data 0 , 127 , 2 , 4 , 8 , 127 , 0 , 0                      ' N
Data 0 , 62 , 65 , 65 , 65 , 62 , 0 , 0                     ' O
Data 0 , 127 , 9 , 9 , 9 , 6 , 0 , 0                        ' P
Data 0 , 62 , 65 , 81 , 33 , 94 , 0 , 0                     ' Q
Data 0 , 127 , 9 , 9 , 25 , 102 , 0 , 0                     ' R
Data 0 , 38 , 73 , 73 , 73 , 50 , 0 , 0                     ' S
Data 0 , 1 , 1 , 127 , 1 , 1 , 0 , 0                        ' T
Data 0 , 63 , 64 , 64 , 64 , 63 , 0 , 0                     ' U
Data 0 , 31 , 32 , 64 , 32 , 31 , 0 , 0                     ' V
Data 0 , 63 , 64 , 60 , 64 , 63 , 0 , 0                     ' W
Data 0 , 99 , 20 , 8 , 20 , 99 , 0 , 0                      ' X
Data 0 , 7 , 8 , 112 , 8 , 7 , 0 , 0                        ' Y
'data 0 , 113 , 73 , 69 , 67 , 0 , 0 , 0                    ' Z
'Data 7 , 5 , 7 , 0 , 60 , 66 , 66 , 66                      ' !

'-------------prompts

Data "S" , "U" , "N" , "M" , "O" , "N" , "T" , "U" , "E" , "W" , "E" , "D"
Data "T" , "H" , "R" , "F" , "R" , "I" , "S" , "A" , "T"
Data "T" , "I" , "M" , "E" , "D" , "A" , "T" , "E" , "T" , "E" , "M" , "P"
Data "2"
Data "0" , "1" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9",
Data "A" , "L" , "A" , "M" , "D" , "A" , "Y" ', "M" , "A" , "L" , "A" , "M"
'Data "A" , "L" , "A" , "M"
Data &H23                                                   'this is the register E control byte
 '&H23 is the default with alarm off
 '&HA3 is alarm on this is the
 'eram variable Ereg


Data 2428 , 2428 , 2428                                     'default values for brightness

Data 0 , 0 , 0 , 0 , 0 , 0                                  'default alarm values

$data 'end of eeprom data