code.py
  1  # SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries
  2  #
  3  # SPDX-License-Identifier: MIT
  4  
  5  # Vertical Word Clock using the Adafruit Feather M4 and
  6  #   the Adafruit DS3231 real-time clock FeatherWing
  7  
  8  import time
  9  import board
 10  import busio as io
 11  import digitalio
 12  import adafruit_ds3231
 13  import neopixel
 14  
 15  i2c = io.I2C(board.SCL, board.SDA)
 16  
 17  # Create the RTC instance:
 18  rtc = adafruit_ds3231.DS3231(i2c)
 19  
 20  # Set up Feather M4 onboard LED for output
 21  LED13 = digitalio.DigitalInOut(board.D13)
 22  LED13.direction = digitalio.Direction.OUTPUT
 23  
 24  # Set digital 6 as an input for slide switch
 25  Slide_Switch = digitalio.DigitalInOut(board.D6)
 26  Slide_Switch.switch_to_input(pull=digitalio.Pull.UP)
 27  
 28  pixel_pin = board.D5
 29  num_pixels = 21
 30  pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=1.0,
 31                             auto_write=False)
 32  pixels.fill((0, 0, 0))  # Blanking Display
 33  COLOR = (0, 200, 0)     # Green for time later in code
 34  
 35  # Bitmap values for each value. These can be OR'ed together
 36  THREE = 1
 37  EIGHT = 1 << 1
 38  ELEVEN = 1 << 2
 39  TWO = 1 << 3
 40  SIX = 1 << 4
 41  FOUR = 1 << 5
 42  SEVEN = 1 << 6
 43  NOON = 1 << 7
 44  TEN = 1 << 8
 45  ONE = 1 << 9
 46  FIVE = 1 << 10
 47  MIDNIGHT = 1 << 11
 48  NINE = 1 << 12
 49  PAST = 1 << 13
 50  TO = 1 << 14
 51  FIVEMIN = 1 << 15
 52  QUARTER = 1 << 16
 53  TENMIN = 1 << 17
 54  HALF = 1 << 18
 55  TWENTY = 1 << 19
 56  
 57  # Pass in hour and minute, return LED bitmask
 58  # pylint: disable=too-many-branches
 59  # pylint: disable=too-many-statements
 60  def writetime(the_hr, the_min):
 61      value = 0  # Start with zero, which is no words
 62      if (the_hr == 24) and (the_min == 0):  # Special cases: Midnight and Noon
 63          return MIDNIGHT
 64      if (the_hr == 12) and (the_min == 0):
 65          return NOON
 66      # set minute
 67      if (the_min > 3) and (the_min < 8):
 68          value = value | FIVEMIN
 69      if (the_min > 7) and (the_min < 13):
 70          value = value | TENMIN
 71      if (the_min > 12) and (the_min < 18):
 72          value = value | QUARTER
 73      if (the_min > 17) and (the_min < 23):
 74          value = value | TWENTY
 75      if (the_min > 22) and (the_min < 28):
 76          value = value | TWENTY | FIVEMIN
 77      if (the_min > 27) and (the_min < 33):
 78          value = value | HALF
 79      if (the_min > 32) and (the_min < 38):
 80          value = value | TWENTY | FIVEMIN
 81      if (the_min > 37) and (the_min < 43):
 82          value = value | TWENTY
 83      if (the_min > 42) and (the_min < 48):
 84          value = value | QUARTER
 85      if (the_min > 47) and (the_min <= 53):
 86          value = value | TENMIN
 87      if the_min >= 54:
 88          value = value | FIVEMIN
 89      # before or after
 90      if (the_min > 3) and (the_min <= 32):
 91          value = value | PAST
 92      if the_min >= 33:
 93          the_hr = the_hr + 1  # for the TO case
 94          value = value | TO
 95      # set hour
 96      if the_hr > 12:
 97          the_hr = the_hr - 12  # Convert 24 hour format to 12 hour
 98      if the_hr == 1:
 99          value = value | ONE
100      if the_hr == 2:
101          value = value | TWO
102      if the_hr == 3:
103          value = value | THREE
104      if the_hr == 4:
105          value = value | FOUR
106      if the_hr == 5:
107          value = value | FIVE
108      if the_hr == 6:
109          value = value | SIX
110      if the_hr == 7:
111          value = value | SEVEN
112      if the_hr == 8:
113          value = value | EIGHT
114      if the_hr == 9:
115          value = value | NINE
116      if the_hr == 10:
117          value = value | TEN
118      if the_hr == 11:
119          value = value | ELEVEN
120      if the_hr == 0:
121          value = value | MIDNIGHT
122      if the_hr == 12:
123          value = value | NOON
124      return value
125  # end def
126  # pylint: enable=too-many-branches
127  # pylint: enable=too-many-statements
128  
129  # Main loop
130  LEDstate = 0
131  Write_Now = True
132  
133  while True:
134      t = rtc.datetime
135      # print("The date is {} {}/{}/{}".format(days[int(t.tm_wday)],
136      #        t.tm_mday, t.tm_mon, t.tm_year))
137      # print("The time is {}:{:02}:{:02}".format(t.tm_hour, t.tm_min, t.tm_sec))
138      hour = t.tm_hour
139      if not Slide_Switch.value:  # Slide switch activate = Daylight savings
140          # print("Switch detected for daylight savings")
141          if hour == 24:
142              hour = 1
143          else:
144              hour += 1
145          Write_Now = True  # Trigger a write
146      minute = t.tm_min
147      second = t.tm_sec
148      if second == 59 or Write_Now:
149          # print("The time is {}:{:02}".format(t.tm_hour, t.tm_min))
150          pixels.fill((0, 0, 0))       # blank all pixels for change
151          the_time = writetime(hour, minute)
152          for i in range(0, 21):       # Check all bits
153              if the_time & 1 << i:    # If the bit is true
154                  pixels[i+1] = COLOR  # set pixel on (shift up 2 for buried one)
155          pixels.show()
156      if LEDstate == 0:       # Flash the D13 LED every other second for activity
157          LED13.value = True
158          LEDstate = 1
159      else:
160          LED13.value = False
161          LEDstate = 0
162      Write_Now = False
163      time.sleep(1)  # wait a second