HDD Clock V1

16. May 2010 16:50

Inspired by Strobeshnik (http://sensi.org/~svo/strobeshnik/)

But, used different Hardware & Language

Used Hardware:

 


Firmware:

  • Written in MikroBASIC (source code is on bottom of page)

 

 

 more than 100k views on youtube, thanks!

 

Source Code (mikroBasic)

 

program hdd_clock

structure PreCalcStruct
  dim p1 as integer
  dim p2 as integer
  dim p3 as integer
  dim p4 as integer
  dim p5 as integer
end structure

dim RpS as float
dim TMR0_PreSet, Deg, Rates as word
dim TMR1_1000, T_MM, T_HH, T_LastMM, LED_Eff, LED_En, RpS_Cycle, LED_CCnt as byte
dim TMR1_100, T_IsNew as boolean
dim PreCalc as PreCalcStruct

Const HH_1 as word = 118
Const HH_2 as word = 151
Const MM_1 as word = 210
Const MM_2 as word = 241    '0  1   2   3   4   5   6   7   8   9   :  -
Const NumPos as word[12] = (50,80,110,140,171,200,232,261,290,320,350,18)

sub procedure rot_left (dim byref abyte as byte)
dim CF as byte
  If abyte.7 then CF = 1
  else CF = 0
  end if
  abyte = abyte<<1
  If CF then abyte.0 = 1
  else abyte.0 = 0
  end if
end sub

sub procedure CalcPosition()
  if LED_Eff.0 = 0 then
    PreCalc.p1 = HH_1-NumPos[11]
  else
    PreCalc.p1 = HH_1-NumPos[(T_HH and 0xF0)>>4]
  end if

  if LED_Eff.1 = 0 then
    PreCalc.p2 = HH_2-NumPos[11]
  else
    PreCalc.p2 = HH_2-NumPos[T_HH and 0x0F]
  end if

  if LED_Eff.2 = 0 then
    PreCalc.p4 = MM_1-NumPos[11]
  else
    PreCalc.p4 = MM_1-NumPos[(T_LastMM and 0xF0)>>4]
  end if

 if LED_Eff.3 = 0 then
    PreCalc.p5 = MM_2-NumPos[11]
  else
    PreCalc.p5 = MM_2-NumPos[T_LastMM and 0x0F]
  end if

  if PreCalc.p1 < 0 then
     PreCalc.p1 = PreCalc.p1+360
  end if
  if PreCalc.p2 < 0 then
     PreCalc.p2 = PreCalc.p2+360
  end if
  if PreCalc.p4 < 0 then
     PreCalc.p4 = PreCalc.p4+360
  end if
  if PreCalc.p5 < 0 then
     PreCalc.p5 = PreCalc.p5+360
  end if
end sub

sub procedure Interrupt()         'Interrupt routine
  if (INTCON.INT0IF <> 0) then
    inc(Rates)
    Deg = 0                       'zero position, reset degrees
    INTCON.INT0IF = 0
    INTCON.TMR0IF = 1
  end if
  if (INTCON.TMR0IF <> 0) then
    TMR0H = Hi(TMR0_PreSet)
    TMR0L = Lo(TMR0_PreSet)
    
    LATA = 0x00
    if (Deg = PreCalc.p1) then
      LATA.0 = LED_En.0
    end if
    if (Deg = PreCalc.p2) then
      LATA.1 = LED_En.1
    end if
    if (Deg = PreCalc.p4) then
      LATA.3 = LED_En.2
    end if
    if (Deg = PreCalc.p5) then
      LATA.4 = LED_En.3
    end if
    if (Deg = PreCalc.p3) then
      LATA.2 = LED_En.4
    end if
    
    inc(Deg)                      'counting degrees
    INTCON.TMR0IF = 0
    exit
  end if
  if (PIR1.TMR1IF <> 0) then
    TMR1H = 0x0B
    TMR1L = 0xDC
    inc(TMR1_1000)
    TMR1_100 = 1
    PIR1.TMR1IF = 0
    exit
  end if
end sub

sub procedure Read_RTC()  'Read from RTC
    I2C1_Start()
    I2C1_Wr(0xD0)
    I2C1_Wr(0)
    I2C1_Repeated_Start()
    I2C1_Wr(0xD1)
    I2C1_Rd(1) 'sec
    T_MM=I2C1_Rd(1)
    T_HH=I2C1_Rd(0)
    I2C1_Stop()
 end sub
 
 sub procedure Write_RTC()
  I2C1_Start()
  I2C1_Wr(0xD0)
  I2C1_Wr(0)
  I2C1_Wr(0x80)
  I2C1_Wr(T_MM)
  I2C1_Wr(T_HH)
  I2C1_Wr(0x01)
  I2C1_Wr(0x01)
  I2C1_Wr(0x01)
  I2C1_Wr(0x10)
  I2C1_Stop()

  I2C1_Start()
  I2C1_Wr(0xD0)
  I2C1_Wr(0)
  I2C1_Wr(0)
  I2C1_Stop()
end sub

main:
  ADCON0 = 0x00       'Disable A/D
  ADCON1 = 0x0F       'All Digital
  CMCON  = 0x07       'Comparators Off

  TRISB  = 0xC7       'B0-2,6,7 input / B3-5 output
  TRISA  = 0x00       'All Output
  LATA   = 0x00       'Clear

  TMR0H  = 0xFE       'Hi
  TMR0L  = 0xEA       'INT0 overflow every ___

  TMR1H  = 0x0B       'Hi
  TMR1L  = 0xDC       'INT0 overflow every 100ms

  INTCON2 = 0x45      'Enable pull-up's, set edge

  T0CON  = 0x88       ' Set TMR0 in 16bit mode, no prescaler
  T1CON  = 0x31       ' Timer1 settings, prescaler 1:8

  Deg = 0             '
  TMR1_100 = 0        '
  TMR1_1000 = 0       '
  TMR0_PreSet = 0     '
  Rates = 0           '
  RpS = 0             '
  T_IsNEw = 0         '
  RpS_Cycle = 0       '
  LED_CCnt = 0        '
  LED_En = 0x1F       '
  LED_Eff = 0x0F      'Reset variables
  precalc.p3 = 188    'set dot's position

  I2C1_Init(400000)   'Initialize I2C (400_kHz)
  delay_ms(4000)      'wait for speed

  Read_RTC()          'Read Time from RTC
  CalcPosition()      'Calculate positions
  T_LastMM = T_MM     'set Last Minute

  INTCON.INT0IF = 0
  INTCON.TMR0IF = 0
  PIR1.TMR1IF   = 0

  INTCON.PEIE   = 1   'Enable Unmasked int's
  INTCON.TMR0IE = 1   'Enable TMR0
  INTCON.INT0IE = 1   'Enable INT0
  PIE1.TMR1IE   = 1   'Enable TMR1
  INTCON.GIE    = 1   'Enable Global int's
  
  while TRUE                     'Loop
    if (TMR1_100 = 1) then       'do every 100ms
      TMR1_100 = 0
      if T_IsNew = 1 then        'replace "-" with time
        rot_left(LED_Eff)
        if LED_Eff = 0x0F then
           T_IsNew = 0
        end if
      else
        if T_LastMM <> T_MM then  'if T_MM changed
          LED_Eff = LED_Eff<<1    'replace time with "-"
          if LED_Eff = 0xF0 then
            T_LastMM = T_MM
            T_IsNew = 1           'done, do it backwards
          end if
        end if
      end if
      CalcPosition()              'calculate position

      if (LED_CCnt = 5) then      ':
        LED_En.4 = (not LED_En.4)
        LED_CCnt = 0
      end if
      inc(LED_CCnt)
    end if

    if (TMR1_1000 = 10) then     'do every 1s
      TMR1_1000 = 0
      inc(RpS_Cycle)
      if (RpS_Cycle = 5) then    '5s
        RpS = (Rates/5)
        Rates = 0
        RpS_Cycle = 0
        TMR0_PreSet = 65536-ceil((((1000/RpS)*1000)/360)/0.218) 'calculate PreSet of TMR0
      end if
      Read_RTC()                 'Read time from RTC
    end if

    If (PORTB.1 = 0) then        'AddHour pressed
      delay_ms(100)
      If (PORTB.1 = 0) then
      T_HH = ((T_HH and 0xF0) >> 4)*10 + (T_HH and 0x0F)
      T_HH = T_HH+1
      if T_HH > 23 then
        T_HH = 0
      end if
      T_HH = (((T_HH div 10) << 4) and 0xF0) + ((T_HH-(T_HH div 10) * 10) and 0x0F) 'dec to hex
      Write_RTC()
      end if
    end if

    If (PORTB.2 = 0) then        'AddMin pressed
      delay_ms(100)
      If (PORTB.2 = 0) then
      T_MM = ((T_MM and 0xF0) >> 4)*10 + (T_MM and 0x0F)
      T_MM = T_MM+1
      if T_MM > 59 then
        T_MM = 0
      end if
      T_MM = (((T_MM div 10) << 4) and 0xF0) + ((T_MM-(T_MM div 10) * 10) and 0x0F) 'dec to hex
      Write_RTC()
      end if
    end if
  wend
end.

Add comment

biuquote
  • Comment
  • Preview
Loading

About

Weex

 

Czech Republic :Country
Technician :Occupation
IT, XVS650, Geocaching :Hobby
Doom/Gothic/Symphonic
:Most listening music
Falling Down :Favorite Movie

Month List

Recent Comments

None

Where I am