code.py
  1  # SPDX-FileCopyrightText: 2020 Liz Clark for Adafruit Industries
  2  #
  3  # SPDX-License-Identifier: MIT
  4  
  5  import time
  6  import board
  7  import displayio
  8  from adafruit_clue import clue
  9  from simpleio import map_range
 10  from adafruit_bitmap_font import bitmap_font
 11  from adafruit_lsm6ds.lsm6ds33 import LSM6DS33
 12  from adafruit_lsm6ds import Rate, AccelRange
 13  from adafruit_progressbar.progressbar import ProgressBar
 14  from adafruit_display_text.label import Label
 15  
 16  #  turns off onboard NeoPixel to conserve battery
 17  clue.pixel.brightness = (0.0)
 18  
 19  #  accessing the Clue's accelerometer
 20  sensor = LSM6DS33(board.I2C())
 21  
 22  #  step goal
 23  step_goal = 10000
 24  
 25  #  onboard button states
 26  a_state = False
 27  b_state = False
 28  
 29  #  array to adjust screen brightness
 30  bright_level = [0, 0.5, 1]
 31  
 32  countdown = 0 #  variable for the step goal progress bar
 33  clock = 0 #  variable used to keep track of time for the steps per hour counter
 34  clock_count = 0 #  holds the number of hours that the step counter has been running
 35  clock_check = 0 #  holds the result of the clock divided by 3600 seconds (1 hour)
 36  last_step = 0 #  state used to properly counter steps
 37  mono = time.monotonic() #  time.monotonic() device
 38  mode = 1 #  state used to track screen brightness
 39  steps_log = 0 #  holds total steps to check for steps per hour
 40  steps_remaining = 0 #  holds the remaining steps needed to reach the step goal
 41  sph = 0 #  holds steps per hour
 42  
 43  #  variables to hold file locations for background and fonts
 44  clue_bgBMP = "/clue_bgBMP.bmp"
 45  small_font = "/fonts/Roboto-Medium-16.bdf"
 46  med_font = "/fonts/Roboto-Bold-24.bdf"
 47  big_font = "/fonts/Roboto-Black-48.bdf"
 48  
 49  #  glyphs for fonts
 50  glyphs = b'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-,.: '
 51  
 52  #  loading bitmap fonts
 53  small_font = bitmap_font.load_font(small_font)
 54  small_font.load_glyphs(glyphs)
 55  med_font = bitmap_font.load_font(med_font)
 56  med_font.load_glyphs(glyphs)
 57  big_font = bitmap_font.load_font(big_font)
 58  big_font.load_glyphs(glyphs)
 59  
 60  #  creating display and default brightness
 61  clue_display = board.DISPLAY
 62  clue_display.brightness = 0.5
 63  
 64  #  graphics group
 65  clueGroup = displayio.Group()
 66  
 67  #  loading bitmap background
 68  # CircuitPython 6 & 7 compatible
 69  clue_bg = displayio.OnDiskBitmap(open(clue_bgBMP, "rb"))
 70  clue_tilegrid = displayio.TileGrid(
 71      clue_bg, pixel_shader=getattr(clue_bg, 'pixel_shader', displayio.ColorConverter())
 72  )
 73  clueGroup.append(clue_tilegrid)
 74  
 75  # # CircuitPython 7+ compatible
 76  # clue_bg = displayio.OnDiskBitmap(clue_bgBMP)
 77  # clue_tilegrid = displayio.TileGrid(clue_bg, pixel_shader=clue_bg.pixel_shader)
 78  # clueGroup.append(clue_tilegrid)
 79  
 80  #  creating the ProgressBar object
 81  bar_group = displayio.Group()
 82  prog_bar = ProgressBar(1, 1, 239, 25, bar_color=0x652f8f)
 83  bar_group.append(prog_bar)
 84  
 85  clueGroup.append(bar_group)
 86  
 87  #  text for step goal
 88  steps_countdown = Label(small_font, text='%d Steps Remaining' % step_goal, color=clue.WHITE)
 89  steps_countdown.x = 55
 90  steps_countdown.y = 12
 91  
 92  #  text for steps
 93  text_steps = Label(big_font, text="0     ", color=0xe90e8b)
 94  text_steps.x = 45
 95  text_steps.y = 70
 96  
 97  #  text for steps per hour
 98  text_sph = Label(med_font, text=" -- ", color=0x29abe2)
 99  text_sph.x = 8
100  text_sph.y = 195
101  
102  #  adding all text to the display group
103  clueGroup.append(text_sph)
104  clueGroup.append(steps_countdown)
105  clueGroup.append(text_steps)
106  
107  #  sending display group to the display at startup
108  clue_display.show(clueGroup)
109  
110  #  setting up the accelerometer and pedometer
111  sensor.accelerometer_range = AccelRange.RANGE_2G
112  sensor.accelerometer_data_rate = Rate.RATE_26_HZ
113  sensor.gyro_data_rate = Rate.RATE_SHUTDOWN
114  sensor.pedometer_enable = True
115  
116  while True:
117  
118      #  button debouncing
119      if not clue.button_a and not a_state:
120          a_state = True
121      if not clue.button_b and not b_state:
122          b_state = True
123  
124      #  setting up steps to hold step count
125      steps = sensor.pedometer_steps
126  
127      #  creating the data for the ProgressBar
128      countdown = map_range(steps, 0, step_goal, 0.0, 1.0)
129  
130      #  actual counting of the steps
131      #  if a step is taken:
132      if abs(steps-last_step) > 1:
133          step_time = time.monotonic()
134          #  updates last_step
135          last_step = steps
136          #  updates the display
137          text_steps.text = '%d' % steps
138          clock = step_time - mono
139  
140          #  logging steps per hour
141          if clock > 3600:
142              #  gets number of hours to add to total
143              clock_check = clock / 3600
144              #  logs the step count as of that hour
145              steps_log = steps
146              #  adds the hours to get a new hours total
147              clock_count += round(clock_check)
148              #  divides steps by hours to get steps per hour
149              sph = steps_log / clock_count
150              #  adds the sph to the display
151              text_sph.text = '%d' % sph
152              #  resets clock to count to the next hour again
153              clock = 0
154              mono = time.monotonic()
155  
156          #  adjusting countdown to step goal
157          prog_bar.progress = float(countdown)
158  
159      #  displaying countdown to step goal
160      if step_goal - steps > 0:
161          steps_remaining = step_goal - steps
162          steps_countdown.text = '%d Steps Remaining' % steps_remaining
163      else:
164          steps_countdown.text = 'Steps Goal Met!'
165  
166      #  adjusting screen brightness, a button decreases brightness
167      if clue.button_a and a_state:
168          mode -= 1
169          a_state = False
170          if mode < 0:
171              mode = 0
172              clue_display.brightness = bright_level[mode]
173          else:
174              clue_display.brightness = bright_level[mode]
175      #  b button increases brightness
176      if clue.button_b and b_state:
177          mode += 1
178          b_state = False
179          if mode > 2:
180              mode = 2
181              clue_display.brightness = bright_level[mode]
182          else:
183              clue_display.brightness = bright_level[mode]
184  
185      time.sleep(0.001)