1- # AUTOCHEER DEVICE
2- # code by Andy Doro
3- #
4- # plays an MP3 at a specific time.
5- #
6- # uses native CircuitPython mp3 playback
7- #
8- # REQUIREMENTS:
9- # should use M4 (or higher)
10- # use CircuitPython 5.3.0+
11- #
12- #
13- # HARDWARE:
14- # Feather M4 Express https://www.adafruit.com/product/3857
15- # Adalogger https://www.adafruit.com/product/2922
16- #
17- #
18- # TO DO
19- # ---
20- # - daylight saving time
21- # - use built-in NeoPixel as indicator
22- #
23-
24- import os
25- import time
26- import board
27- import audiomp3
28- import audioio
29- import digitalio
30-
31-
32- # For hardware I2C (M0 boards) use this line:
33- import busio as io
34-
35- # Or for software I2C (ESP8266) use this line instead:
36- # import bitbangio as io
37-
38- #import adafruit_ds3231
39- import adafruit_pcf8523
40-
41- # SD card
42- import adafruit_sdcard
43- import storage
44-
45- # NeoPixel
46- #import neopixel
47-
48-
49- # Use any pin that is not taken by SPI
50- # For Adalogger FeatherWing: https://learn.adafruit.com/adafruit-adalogger-featherwing/pinouts
51- # The SDCS pin is the chip select line:
52- # On ESP8266, the SD CS pin is on GPIO 15
53- # On ESP32 it's GPIO 33
54- # On WICED it's GPIO PB5
55- # On the nRF52832 it's GPIO 11
56- # On Atmel M0, M4, 328p or 32u4 it's on GPIO 10
57- # On Teensy 3.x it's on GPIO 10
58-
59- SD_CS = board .D10 # for M4
60-
61- # Connect to the card and mount the filesystem.
62- spi = io .SPI (board .SCK , board .MOSI , board .MISO )
63- cs = digitalio .DigitalInOut (SD_CS )
64- sdcard = adafruit_sdcard .SDCard (spi , cs )
65- vfs = storage .VfsFat (sdcard )
66- storage .mount (vfs , "/sd" )
67-
68-
69- # Use the filesystem as normal! Our files are under /sd
70- # This helper function will print the contents of the SD
71-
72- def print_directory (path , tabs = 0 ):
73- for file in os .listdir (path ):
74- stats = os .stat (path + "/" + file )
75- filesize = stats [6 ]
76- isdir = stats [0 ] & 0x4000
77-
78- if filesize < 1000 :
79- sizestr = str (filesize ) + " by"
80- elif filesize < 1000000 :
81- sizestr = "%0.1f KB" % (filesize / 1000 )
82- else :
83- sizestr = "%0.1f MB" % (filesize / 1000000 )
84-
85- prettyprintname = ""
86- for _ in range (tabs ):
87- prettyprintname += " "
88- prettyprintname += file
89- if isdir :
90- prettyprintname += "/"
91- print ('{0:<40} Size: {1:>10}' .format (prettyprintname , sizestr ))
92-
93- # recursively print directory contents
94- if isdir :
95- print_directory (path + "/" + file , tabs + 1 )
96-
97-
98- print ("Files on filesystem:" )
99- print ("====================" )
100- print_directory ("/sd" )
101-
102-
103- data = open ("/sd/cheer.mp3" , "rb" )
104- mp3 = audiomp3 .MP3Decoder (data )
105- #a = audioio.AudioOut(board.A0) # mono
106- a = audioio .AudioOut (board .A0 , right_channel = board .A1 ) # stereo sound through A0 & A1
107-
108-
109- i2c = io .I2C (board .SCL , board .SDA ) # Change to the appropriate I2C clock & data
110- # pins here!
111-
112- # Create the RTC instance:
113- #rtc = adafruit_ds3231.DS3231(i2c)
114- rtc = adafruit_pcf8523 .PCF8523 (i2c )
115-
116- # Lookup table for names of days (nicer printing).
117- days = ("Sunday" , "Monday" , "Tuesday" , "Wednesday" , "Thursday" , "Friday" , "Saturday" )
118-
119-
120- # selected time
121- # 24 hour time
122- playhour = 19
123- playmin = 0
124-
125- # pylint: disable-msg=bad-whitespace
126- # pylint: disable-msg=using-constant-test
127- # no DST adjustment yet!
128- if False : # change to True if you want to set the time!
129- # year, mon, date, hour, min, sec, wday, yday, isdst
130- t = time .struct_time ((2020 , 5 , 13 , 15 , 15 , 15 , 0 , - 1 , - 1 ))
131- # you must set year, mon, date, hour, min, sec and weekday
132- # yearday is not supported, isdst can be set but we don't do anything with it at this time
133- print ("Setting time to:" , t ) # uncomment for debugging
134- rtc .datetime = t
135- print ()
136- # pylint: enable-msg=using-constant-test
137- # pylint: enable-msg=bad-whitespace
138-
139- # setup NeoPixel
140- #pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)
141-
142-
143- # Main loop:
144- while True :
145- t = rtc .datetime
146-
147- # print(t) # uncomment for debugging
148- print (
149- "The date is {} {}/{}/{}" .format (
150- days [int (t .tm_wday )], t .tm_mday , t .tm_mon , t .tm_year
151- )
152- )
153- print ("The time is {}:{:02}:{:02}" .format (t .tm_hour , t .tm_min , t .tm_sec ))
154-
155- if t .tm_hour == playhour and t .tm_min == playmin :
156- print ("it is time!" )
157- # turn NeoPixel green
158- #pixel[0] = (0, 255, 0)
159- # play the file
160- print ("playing" )
161- a .play (mp3 )
162- while a .playing :
163- pass
164- print ("stopped" )
165- # turn NeoPixel off
166- #pixel[0] = (0, 0, 0)
167-
1+ # AUTOCHEER DEVICE
2+ # code by Andy Doro
3+ #
4+ # plays an MP3 at a specific time.
5+ #
6+ # uses native CircuitPython mp3 playback
7+ #
8+ # REQUIREMENTS:
9+ # should use M4 (or higher)
10+ # use CircuitPython 5.3.0+
11+ #
12+ #
13+ # HARDWARE:
14+ # Feather M4 Express https://www.adafruit.com/product/3857
15+ # Adalogger https://www.adafruit.com/product/2922
16+ #
17+ #
18+ # TO DO
19+ # ---
20+ # - daylight saving time
21+ # - use built-in NeoPixel as indicator
22+ #
23+
24+ import os
25+ import time
26+ import board
27+ import audiomp3
28+ import audioio
29+ import digitalio
30+
31+
32+ # For hardware I2C (M0 boards) use this line:
33+ import busio as io
34+
35+ # Or for software I2C (ESP8266) use this line instead:
36+ # import bitbangio as io
37+
38+ #import adafruit_ds3231
39+ import adafruit_pcf8523
40+
41+ # SD card
42+ import adafruit_sdcard
43+ import storage
44+
45+ # NeoPixel
46+ #import neopixel
47+
48+
49+ # Use any pin that is not taken by SPI
50+ # For Adalogger FeatherWing: https://learn.adafruit.com/adafruit-adalogger-featherwing/pinouts
51+ # The SDCS pin is the chip select line:
52+ # On ESP8266, the SD CS pin is on GPIO 15
53+ # On ESP32 it's GPIO 33
54+ # On WICED it's GPIO PB5
55+ # On the nRF52832 it's GPIO 11
56+ # On Atmel M0, M4, 328p or 32u4 it's on GPIO 10
57+ # On Teensy 3.x it's on GPIO 10
58+
59+ SD_CS = board .D10 # for M4
60+
61+ # Connect to the card and mount the filesystem.
62+ spi = io .SPI (board .SCK , board .MOSI , board .MISO )
63+ cs = digitalio .DigitalInOut (SD_CS )
64+ sdcard = adafruit_sdcard .SDCard (spi , cs )
65+ vfs = storage .VfsFat (sdcard )
66+ storage .mount (vfs , "/sd" )
67+
68+
69+ # Use the filesystem as normal! Our files are under /sd
70+ # This helper function will print the contents of the SD
71+
72+ def print_directory (path , tabs = 0 ):
73+ for file in os .listdir (path ):
74+ stats = os .stat (path + "/" + file )
75+ filesize = stats [6 ]
76+ isdir = stats [0 ] & 0x4000
77+
78+ if filesize < 1000 :
79+ sizestr = str (filesize ) + " by"
80+ elif filesize < 1000000 :
81+ sizestr = "%0.1f KB" % (filesize / 1000 )
82+ else :
83+ sizestr = "%0.1f MB" % (filesize / 1000000 )
84+
85+ prettyprintname = ""
86+ for _ in range (tabs ):
87+ prettyprintname += " "
88+ prettyprintname += file
89+ if isdir :
90+ prettyprintname += "/"
91+ print ('{0:<40} Size: {1:>10}' .format (prettyprintname , sizestr ))
92+
93+ # recursively print directory contents
94+ if isdir :
95+ print_directory (path + "/" + file , tabs + 1 )
96+
97+
98+ print ("Files on filesystem:" )
99+ print ("====================" )
100+ print_directory ("/sd" )
101+
102+
103+ data = open ("/sd/cheer.mp3" , "rb" )
104+ mp3 = audiomp3 .MP3Decoder (data )
105+ #a = audioio.AudioOut(board.A0) # mono
106+ a = audioio .AudioOut (board .A0 , right_channel = board .A1 ) # stereo sound through A0 & A1
107+
108+
109+ i2c = io .I2C (board .SCL , board .SDA ) # Change to the appropriate I2C clock & data
110+ # pins here!
111+
112+ # Create the RTC instance:
113+ #rtc = adafruit_ds3231.DS3231(i2c)
114+ rtc = adafruit_pcf8523 .PCF8523 (i2c )
115+
116+ # Lookup table for names of days (nicer printing).
117+ days = ("Sunday" , "Monday" , "Tuesday" , "Wednesday" , "Thursday" , "Friday" , "Saturday" )
118+
119+
120+ # selected time
121+ # 24 hour time
122+ playhour = 19
123+ playmin = 0
124+
125+ # pylint: disable-msg=bad-whitespace
126+ # pylint: disable-msg=using-constant-test
127+ # no DST adjustment yet!
128+ if False : # change to True if you want to set the time!
129+ # year, mon, date, hour, min, sec, wday, yday, isdst
130+ t = time .struct_time ((2020 , 5 , 13 , 15 , 15 , 15 , 0 , - 1 , - 1 ))
131+ # you must set year, mon, date, hour, min, sec and weekday
132+ # yearday is not supported, isdst can be set but we don't do anything with it at this time
133+ print ("Setting time to:" , t ) # uncomment for debugging
134+ rtc .datetime = t
135+ print ()
136+ # pylint: enable-msg=using-constant-test
137+ # pylint: enable-msg=bad-whitespace
138+
139+ # setup NeoPixel
140+ #pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)
141+
142+
143+ # Main loop:
144+ while True :
145+ t = rtc .datetime
146+
147+ # print(t) # uncomment for debugging
148+ print (
149+ "The date is {} {}/{}/{}" .format (
150+ days [int (t .tm_wday )], t .tm_mday , t .tm_mon , t .tm_year
151+ )
152+ )
153+ print ("The time is {}:{:02}:{:02}" .format (t .tm_hour , t .tm_min , t .tm_sec ))
154+
155+ if t .tm_hour == playhour and t .tm_min == playmin :
156+ print ("it is time!" )
157+ # turn NeoPixel green
158+ #pixel[0] = (0, 255, 0)
159+ # play the file
160+ print ("playing" )
161+ a .play (mp3 )
162+ while a .playing :
163+ pass
164+ print ("stopped" )
165+ # turn NeoPixel off
166+ #pixel[0] = (0, 0, 0)
167+
168168 time .sleep (1 ) # wait a second
0 commit comments