├── Chapter01 ├── 01_first.py └── 02_repl.py ├── Chapter02 ├── 01_pin_13.py ├── 02_brightness.py ├── 03_color.py ├── 04_hex.py ├── 05_color_by_name.py ├── 06_set_all.py ├── 07_set_range.py ├── 08_generating_random.py ├── 09_random_animation.py └── 10_rainbow_animation.py ├── Chapter03 ├── 01_beep_basic.py ├── 02_beep_loop.py ├── 03_note.py ├── 04_melody.py ├── 05_alarm.py ├── 06_wav.py ├── 07_convert.py ├── 08_tones.py └── hello.wav ├── Chapter04 ├── 01_push_button.py ├── 02_button_led.py ├── 03_slide_switch.py ├── 04_button_state_change.py ├── 05_moving_leds.py ├── 06_button_beep.py ├── 07_detect_touch.py ├── 08_touch_pad_raw.py └── 09_adjust_threshold.py ├── Chapter05 ├── 01_temperature.py ├── 02_light.py ├── 03_meter.py ├── 04_motion.py ├── 05_tap.py ├── 06_shake.py └── 07_beep_on_shake.py ├── Chapter06 ├── 01_detect_button.py ├── 02_button_module.py ├── 03_button_event_loop.py ├── 04_generator.py ├── 05_show_scores.py ├── 06_detect_winners.py ├── 07_score_event_loop.py └── game │ ├── button.py │ ├── colors.py │ ├── main.py │ ├── score.py │ ├── start.wav │ ├── win1.wav │ └── win2.wav ├── Chapter07 ├── 01_touch.py ├── 02_speaker.py ├── 03_play.py ├── 04_pixels.py ├── 05_handler_sounds.py ├── 06_handler_pixels.py ├── 07_event_loop.py └── fruity │ ├── hit.wav │ ├── main.py │ ├── piano.wav │ ├── tin.wav │ └── wood.wav ├── Chapter08 ├── 01_tuning.py ├── 02_actuation_range.py ├── 03_servo_angle.py ├── 04_servo_sweep.py ├── 05_servo_buttons.py ├── 06_multiple_servos.py ├── 07_dc_motor_on.py ├── 08_dc_motor_speed.py └── 09_dc_motor_buttons.py ├── Chapter09 ├── 01_mu_flash.py ├── 02_mu_repl.py ├── 03_display_character.py ├── 04_display_image.py ├── 05_display_scrolling.py ├── 06_show_button.py └── 07_countdown.py ├── Chapter10 ├── 01_repl.py ├── 02_scan.py ├── 03_ap.py ├── 04_station.py ├── 05_webrepl_web.py ├── 06_webrepl_cli.py └── 07_leds.py ├── Chapter11 ├── 01_remount.py ├── 02_list_files.py ├── 03_remove_files.py ├── 04_create_directories.py ├── 05_read_files.py ├── 06_write_files.py └── 07_disk_usage.py ├── Chapter12 ├── 01_dns.py ├── 02_check_network.py ├── 03_http_raw.py ├── 04_http_urequests.py ├── 05_fetch_json.py ├── 06_http_server.py ├── 07_web_handler.py ├── 08_web_leds.py ├── 09_api_leds.py └── extra │ ├── fix_urequests_warnings.py │ ├── netcheck.py │ └── web.py ├── Chapter13 ├── 01_buttons.py ├── 02_ssd1306.py ├── 03_fill.py ├── 04_pixels.py ├── 05_lines.py ├── 06_text.py ├── 07_invert.py └── extra │ └── fix_framebuf_import.py ├── Chapter14 ├── 01_get_weather_simple.py ├── 02_get_weather_func.py ├── 03_random_city.py ├── 04_screen.py ├── 05_show_weather.py ├── 06_visual_feedback.py ├── 07_show_random_weather.py ├── 08_button_event_loop.py └── extra │ └── screen.py ├── Chapter15 ├── 01_discover_i2c.py ├── 02_accelerometer.py ├── 03_flip.py ├── 04_brightness.py ├── 05_display_image.py ├── 06_list_images.py ├── 07_joke_machine.py └── images │ ├── joke_01_question.bmp │ ├── joke_01_response.bmp │ ├── joke_02_question.bmp │ ├── joke_02_response.bmp │ ├── joke_03_question.bmp │ ├── joke_03_response.bmp │ ├── joke_04_question.bmp │ └── joke_04_response.bmp ├── LICENSE └── README.md /Chapter01/01_first.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | import time 3 | 4 | cpx.pixels[0] = (255, 0, 0) # set first NeoPixel to the color red 5 | time.sleep(60) 6 | -------------------------------------------------------------------------------- /Chapter01/02_repl.py: -------------------------------------------------------------------------------- 1 | def add(a, b): 2 | return a + b 3 | 4 | 5 | add(2, 2) 6 | 7 | 8 | 2**100 + 2**101 9 | -------------------------------------------------------------------------------- /Chapter02/01_pin_13.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | cpx.red_led = True 3 | cpx.red_led = False 4 | -------------------------------------------------------------------------------- /Chapter02/02_brightness.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | 3 | cpx.pixels.brightness = 1.0 4 | cpx.pixels[0] = (255, 0, 0) 5 | 6 | cpx.pixels.brightness = 0.5 7 | cpx.pixels.brightness = 0.10 8 | -------------------------------------------------------------------------------- /Chapter02/03_color.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | 3 | cpx.pixels[0] = (255, 0, 0) 4 | 5 | cpx.pixels[0] = (0, 255, 0) 6 | 7 | cpx.pixels[0] = (0, 0, 255) 8 | 9 | cpx.pixels[0] = (0, 0, 0) 10 | 11 | cpx.pixels[1] = (255, 0, 0) 12 | -------------------------------------------------------------------------------- /Chapter02/04_hex.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | 3 | cpx.pixels[0] = 0xFF0000 4 | 5 | cpx.pixels[1] = 0x00FF00 6 | cpx.pixels[2] = 0x0000FF 7 | 8 | cpx.pixels[3] = 0xFFFF00 9 | 10 | cpx.pixels[4] = 255 11 | -------------------------------------------------------------------------------- /Chapter02/05_color_by_name.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | 3 | RGB = dict(black=0x000000, blue=0x0000FF, green=0x00FF00, cyan=0x00FFFF, 4 | red=0xFF0000, magenta=0xFF00FF, yellow=0xFFFF00, white=0xFFFFFF) 5 | cpx.pixels[0] = RGB['red'] 6 | 7 | for i, name in enumerate(sorted(RGB)): 8 | cpx.pixels[i] = RGB[name] 9 | -------------------------------------------------------------------------------- /Chapter02/06_set_all.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | cpx.pixels.fill(0x0000FF) 3 | 4 | cpx.pixels.fill(0x000000) 5 | -------------------------------------------------------------------------------- /Chapter02/07_set_range.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | cpx.pixels[0:2] = [0xFF0000, 0xFF0000] 3 | 4 | cpx.pixels[2:5] = [0x00FF00] * 3 5 | cpx.pixels[5:10] = [0x0000FF] * 5 6 | -------------------------------------------------------------------------------- /Chapter02/08_generating_random.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | from random import randint 3 | 4 | randint(0, 255) 5 | 6 | 7 | def get_random_color(): 8 | return (randint(0, 255), randint(0, 255), randint(0, 255)) 9 | 10 | 11 | get_random_color() 12 | 13 | 14 | cpx.pixels[0] = get_random_color() 15 | 16 | 17 | cpx.pixels.fill(get_random_color()) 18 | -------------------------------------------------------------------------------- /Chapter02/09_random_animation.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | from random import randint 3 | import time 4 | 5 | 6 | def get_random_color(): 7 | return (randint(0, 255), randint(0, 255), randint(0, 255)) 8 | 9 | 10 | for i in range(10): 11 | cpx.pixels[i] = get_random_color() 12 | time.sleep(1) 13 | 14 | 15 | cpx.pixels.fill(0x000000) 16 | for cycle in range(3): 17 | for i in range(10): 18 | cpx.pixels[i] = get_random_color() 19 | time.sleep(1) 20 | 21 | 22 | cpx.pixels.fill(0x000000) 23 | for i in range(5): 24 | cpx.pixels.fill(get_random_color()) 25 | time.sleep(1) 26 | -------------------------------------------------------------------------------- /Chapter02/10_rainbow_animation.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | import time 3 | 4 | RAINBOW = [ 5 | 0xFF0000, # red 6 | 0xFFA500, # orange 7 | 0xFFFF00, # yellow 8 | 0x00FF00, # green 9 | 0x0000FF, # blue 10 | 0x4b0082, # indigo 11 | 0xEE82EE, # violet 12 | ] 13 | 14 | cpx.pixels.brightness = 0.10 15 | cpx.pixels.fill(0x000000) 16 | while True: 17 | for i, color in enumerate(RAINBOW): 18 | cpx.pixels[i] = color 19 | time.sleep(0.2) 20 | for i in range(len(RAINBOW)): 21 | cpx.pixels[i] = 0x000000 22 | time.sleep(0.2) 23 | -------------------------------------------------------------------------------- /Chapter03/01_beep_basic.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | cpx.play_tone(900, 0.2) 3 | 4 | cpx.play_tone(500, 0.4) 5 | -------------------------------------------------------------------------------- /Chapter03/02_beep_loop.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | for i in range(500, 1000, 100): 3 | print(i) 4 | cpx.play_tone(i, 0.2) 5 | 6 | 7 | for i in range(200, 500, 100): 8 | print(i) 9 | cpx.play_tone(i, i / 1000) 10 | -------------------------------------------------------------------------------- /Chapter03/03_note.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | 3 | E5 = 659 4 | C5 = 523 5 | G5 = 784 6 | 7 | cpx.play_tone(E5, 0.15) 8 | -------------------------------------------------------------------------------- /Chapter03/04_melody.py: -------------------------------------------------------------------------------- 1 | import time 2 | from adafruit_circuitplayground.express import cpx 3 | 4 | E5 = 659 5 | C5 = 523 6 | G5 = 784 7 | 8 | MELODY = (E5, E5, 0, E5, 0, C5, E5, 0, G5) 9 | 10 | 11 | def play_note(note, duration=0.15): 12 | if note == 0: 13 | time.sleep(duration) 14 | else: 15 | cpx.play_tone(note, duration) 16 | 17 | for note in MELODY: 18 | play_note(note) 19 | -------------------------------------------------------------------------------- /Chapter03/05_alarm.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | 3 | BEEP_HIGH = 960 4 | BEEP_LOW = 800 5 | 6 | for i in range(3): 7 | cpx.play_tone(BEEP_HIGH, 0.5) 8 | cpx.play_tone(BEEP_LOW, 0.5) 9 | -------------------------------------------------------------------------------- /Chapter03/06_wav.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | cpx.play_file('hello.wav') 3 | -------------------------------------------------------------------------------- /Chapter03/07_convert.py: -------------------------------------------------------------------------------- 1 | # no python code for this recipe 2 | -------------------------------------------------------------------------------- /Chapter03/08_tones.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | import time 3 | 4 | BEEP_HIGH = 960 5 | BEEP_LOW = 800 6 | 7 | cpx.pixels.brightness = 0.10 8 | 9 | cpx.start_tone(BEEP_HIGH) 10 | for i in range(10): 11 | cpx.pixels[i] = 0xFF0000 12 | time.sleep(0.1) 13 | cpx.stop_tone() 14 | 15 | cpx.start_tone(BEEP_LOW) 16 | for i in range(10): 17 | cpx.pixels[i] = 0x000000 18 | time.sleep(0.1) 19 | cpx.stop_tone() 20 | -------------------------------------------------------------------------------- /Chapter03/hello.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/MicroPython-Cookbook/dd9b98fae1c44e807c565358fc126b6dc982f2ca/Chapter03/hello.wav -------------------------------------------------------------------------------- /Chapter04/01_push_button.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | import time 3 | 4 | while True: 5 | print(cpx.button_a) 6 | time.sleep(0.05) 7 | -------------------------------------------------------------------------------- /Chapter04/02_button_led.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | 3 | BLACK = 0x000000 4 | GREEN = 0x00FF00 5 | 6 | cpx.pixels.brightness = 0.10 7 | while True: 8 | cpx.pixels[2] = GREEN if cpx.button_a else BLACK 9 | cpx.pixels[7] = GREEN if cpx.button_b else BLACK 10 | -------------------------------------------------------------------------------- /Chapter04/03_slide_switch.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | import time 3 | 4 | while True: 5 | print(cpx.switch) 6 | time.sleep(0.05) 7 | -------------------------------------------------------------------------------- /Chapter04/04_button_state_change.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | 3 | 4 | def button_change(pressed): 5 | print('pressed:', pressed) 6 | 7 | 8 | last = cpx.button_a 9 | while True: 10 | if cpx.button_a != last: 11 | button_change(cpx.button_a) 12 | last = cpx.button_a 13 | -------------------------------------------------------------------------------- /Chapter04/05_moving_leds.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | import time 3 | 4 | BLACK = 0x000000 5 | BLUE = 0x0000FF 6 | 7 | cpx.pixels.brightness = 0.10 8 | i = 0 9 | direction = 1 10 | while True: 11 | if cpx.button_a: 12 | direction = 1 13 | if cpx.button_b: 14 | direction = -1 15 | i += direction 16 | i = i % 10 17 | cpx.pixels.fill(BLACK) 18 | cpx.pixels[i] = BLUE 19 | time.sleep(0.05) 20 | -------------------------------------------------------------------------------- /Chapter04/06_button_beep.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | 3 | while True: 4 | if cpx.button_a: 5 | cpx.play_tone(500, 0.2) 6 | if cpx.button_b: 7 | cpx.play_tone(900, 0.2) 8 | -------------------------------------------------------------------------------- /Chapter04/07_detect_touch.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | import time 3 | 4 | while True: 5 | if cpx.touch_A1: 6 | print('detected touch') 7 | time.sleep(0.05) 8 | -------------------------------------------------------------------------------- /Chapter04/08_touch_pad_raw.py: -------------------------------------------------------------------------------- 1 | import time 2 | import touchio 3 | import board 4 | 5 | a1 = touchio.TouchIn(board.A1) 6 | while True: 7 | touch = a1.raw_value > a1.threshold 8 | print('raw:', a1.raw_value, 'threshold:', a1.threshold, 'touch:', touch) 9 | time.sleep(0.5) 10 | -------------------------------------------------------------------------------- /Chapter04/09_adjust_threshold.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | import time 3 | 4 | cpx.adjust_touch_threshold(200) 5 | while True: 6 | if cpx.touch_A1: 7 | print('detected touch') 8 | time.sleep(0.5) 9 | -------------------------------------------------------------------------------- /Chapter05/01_temperature.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | import time 3 | 4 | start = time.monotonic() 5 | while True: 6 | elapsed = time.monotonic() - start 7 | temp = cpx.temperature 8 | print('{elapsed:.2f}\t{temp}'.format(**locals())) 9 | time.sleep(0.1) 10 | -------------------------------------------------------------------------------- /Chapter05/02_light.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | import time 3 | 4 | while True: 5 | print(cpx.light) 6 | time.sleep(0.1) 7 | -------------------------------------------------------------------------------- /Chapter05/03_meter.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | import time 3 | 4 | BLACK = 0x000000 5 | BLUE = 0x0000FF 6 | MAX_LUX = 330 7 | cpx.pixels.brightness = 0.10 8 | 9 | 10 | def gauge(level): 11 | cpx.pixels[0:level] = [BLUE] * level 12 | 13 | 14 | last = 0 15 | while True: 16 | level = int((cpx.light / MAX_LUX) * 10) 17 | if level != last: 18 | cpx.pixels.fill(BLACK) 19 | gauge(level) 20 | last = level 21 | time.sleep(0.05) 22 | -------------------------------------------------------------------------------- /Chapter05/04_motion.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | import time 3 | 4 | while True: 5 | x, y, z = cpx.acceleration 6 | print('x: {x:.2f} y: {y:.2f} z: {z:.2f}'.format(**locals())) 7 | time.sleep(0.1) 8 | -------------------------------------------------------------------------------- /Chapter05/05_tap.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | import time 3 | 4 | cpx.detect_taps = 1 5 | while True: 6 | print('tap detected:', cpx.tapped) 7 | time.sleep(0.1) 8 | -------------------------------------------------------------------------------- /Chapter05/06_shake.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | import time 3 | 4 | while True: 5 | print('shake detected:', cpx.shake()) 6 | time.sleep(0.1) 7 | -------------------------------------------------------------------------------- /Chapter05/07_beep_on_shake.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | import time 3 | 4 | while True: 5 | if cpx.shake(20): 6 | cpx.play_tone(900, 0.2) 7 | time.sleep(0.1) 8 | -------------------------------------------------------------------------------- /Chapter06/01_detect_button.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | 3 | 4 | class ButtonEvent: 5 | def __init__(self, name): 6 | self.name = name 7 | self.last = False 8 | 9 | def is_pressed(self): 10 | pressed = getattr(cpx, self.name) 11 | changed = (pressed != self.last) 12 | self.last = pressed 13 | return (pressed and changed) 14 | 15 | 16 | button = ButtonEvent('button_a') 17 | while True: 18 | if button.is_pressed(): 19 | print('button A pressed') 20 | -------------------------------------------------------------------------------- /Chapter06/02_button_module.py: -------------------------------------------------------------------------------- 1 | from button import ButtonEvent 2 | 3 | button = ButtonEvent('button_a') 4 | while True: 5 | if button.is_pressed(): 6 | print('button A pressed') 7 | -------------------------------------------------------------------------------- /Chapter06/03_button_event_loop.py: -------------------------------------------------------------------------------- 1 | from button import ButtonEvent 2 | 3 | 4 | def main(): 5 | buttons = {1: ButtonEvent('button_a'), 2: ButtonEvent('button_b')} 6 | while True: 7 | for player, button in buttons.items(): 8 | if button.is_pressed(): 9 | print('button pressed for player', player) 10 | 11 | 12 | main() 13 | -------------------------------------------------------------------------------- /Chapter06/04_generator.py: -------------------------------------------------------------------------------- 1 | BLACK = 0x000000 2 | SEQUENCE = [ 3 | 0xFFFF00, # Yellow 4 | 0xFF8C00, # DarkOrange 5 | 0xFF0000, # Red 6 | 0xFF00FF, # Magenta 7 | ] 8 | PLAYER_PIXELS1 = [0, 1, 2, 3, 4] 9 | PLAYER_PIXELS2 = [9, 8, 7, 6, 5] 10 | 11 | 12 | def generate_colors(positions): 13 | yield 0, BLACK 14 | for i in positions: 15 | for color in SEQUENCE: 16 | yield i, color 17 | 18 | 19 | COLORS = dict() 20 | COLORS[1] = list(generate_colors(PLAYER_PIXELS1)) 21 | COLORS[2] = list(generate_colors(PLAYER_PIXELS2)) 22 | -------------------------------------------------------------------------------- /Chapter06/05_show_scores.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | from colors import COLORS 3 | 4 | 5 | class ScoreBoard: 6 | def __init__(self): 7 | self.score = {1: 0, 2: 0} 8 | cpx.pixels.brightness = 0.02 9 | cpx.play_file('start.wav') 10 | 11 | def show(self, player): 12 | score = self.score[player] 13 | pos, color = COLORS[player][score] 14 | cpx.pixels[pos] = color 15 | -------------------------------------------------------------------------------- /Chapter06/06_detect_winners.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | from colors import COLORS 3 | 4 | 5 | class ScoreBoard: 6 | def __init__(self): 7 | self.score = {1: 0, 2: 0} 8 | cpx.pixels.brightness = 0.02 9 | cpx.play_file('start.wav') 10 | 11 | def scored(self, player): 12 | self.score[player] += 1 13 | self.show(player) 14 | if self.score[player] == 20: 15 | cpx.play_file('win%s.wav' % player) 16 | 17 | def show(self, player): 18 | score = self.score[player] 19 | pos, color = COLORS[player][score] 20 | cpx.pixels[pos] = color 21 | -------------------------------------------------------------------------------- /Chapter06/07_score_event_loop.py: -------------------------------------------------------------------------------- 1 | from button import ButtonEvent 2 | from score import ScoreBoard 3 | 4 | 5 | def main(): 6 | buttons = {1: ButtonEvent('button_a'), 2: ButtonEvent('button_b')} 7 | board = ScoreBoard() 8 | while True: 9 | for player, button in buttons.items(): 10 | if button.is_pressed(): 11 | board.scored(player) 12 | 13 | 14 | main() 15 | -------------------------------------------------------------------------------- /Chapter06/game/button.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | 3 | 4 | class ButtonEvent: 5 | def __init__(self, name): 6 | self.name = name 7 | self.last = False 8 | 9 | def is_pressed(self): 10 | pressed = getattr(cpx, self.name) 11 | changed = (pressed != self.last) 12 | self.last = pressed 13 | return (pressed and changed) 14 | -------------------------------------------------------------------------------- /Chapter06/game/colors.py: -------------------------------------------------------------------------------- 1 | BLACK = 0x000000 2 | SEQUENCE = [ 3 | 0xFFFF00, # Yellow 4 | 0xFF8C00, # DarkOrange 5 | 0xFF0000, # Red 6 | 0xFF00FF, # Magenta 7 | ] 8 | PLAYER_PIXELS1 = [0, 1, 2, 3, 4] 9 | PLAYER_PIXELS2 = [9, 8, 7, 6, 5] 10 | 11 | 12 | def generate_colors(positions): 13 | yield 0, BLACK 14 | for i in positions: 15 | for color in SEQUENCE: 16 | yield i, color 17 | 18 | 19 | COLORS = dict() 20 | COLORS[1] = list(generate_colors(PLAYER_PIXELS1)) 21 | COLORS[2] = list(generate_colors(PLAYER_PIXELS2)) 22 | -------------------------------------------------------------------------------- /Chapter06/game/main.py: -------------------------------------------------------------------------------- 1 | from button import ButtonEvent 2 | from score import ScoreBoard 3 | 4 | 5 | def main(): 6 | buttons = {1: ButtonEvent('button_a'), 2: ButtonEvent('button_b')} 7 | board = ScoreBoard() 8 | while True: 9 | for player, button in buttons.items(): 10 | if button.is_pressed(): 11 | board.scored(player) 12 | 13 | 14 | main() 15 | -------------------------------------------------------------------------------- /Chapter06/game/score.py: -------------------------------------------------------------------------------- 1 | from adafruit_circuitplayground.express import cpx 2 | from colors import COLORS 3 | 4 | 5 | class ScoreBoard: 6 | def __init__(self): 7 | self.score = {1: 0, 2: 0} 8 | cpx.pixels.brightness = 0.02 9 | cpx.play_file('start.wav') 10 | 11 | def scored(self, player): 12 | self.score[player] += 1 13 | self.show(player) 14 | if self.score[player] == 20: 15 | cpx.play_file('win%s.wav' % player) 16 | 17 | def show(self, player): 18 | score = self.score[player] 19 | pos, color = COLORS[player][score] 20 | cpx.pixels[pos] = color 21 | -------------------------------------------------------------------------------- /Chapter06/game/start.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/MicroPython-Cookbook/dd9b98fae1c44e807c565358fc126b6dc982f2ca/Chapter06/game/start.wav -------------------------------------------------------------------------------- /Chapter06/game/win1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/MicroPython-Cookbook/dd9b98fae1c44e807c565358fc126b6dc982f2ca/Chapter06/game/win1.wav -------------------------------------------------------------------------------- /Chapter06/game/win2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/MicroPython-Cookbook/dd9b98fae1c44e807c565358fc126b6dc982f2ca/Chapter06/game/win2.wav -------------------------------------------------------------------------------- /Chapter07/01_touch.py: -------------------------------------------------------------------------------- 1 | from touchio import TouchIn 2 | import board 3 | 4 | 5 | class TouchEvent: 6 | THRESHOLD_ADJUSTMENT = 400 7 | 8 | def __init__(self, name, onchange): 9 | self.name = name 10 | self.last = False 11 | self.onchange = onchange 12 | pin = getattr(board, name) 13 | self.touch = TouchIn(pin) 14 | self.touch.threshold += self.THRESHOLD_ADJUSTMENT 15 | 16 | def process(self): 17 | current = self.touch.value 18 | if current != self.last: 19 | self.onchange(self.name, current) 20 | self.last = current 21 | 22 | 23 | def handle(name, current): 24 | print(name, current) 25 | 26 | 27 | event = TouchEvent('A1', handle) 28 | while True: 29 | event.process() 30 | -------------------------------------------------------------------------------- /Chapter07/02_speaker.py: -------------------------------------------------------------------------------- 1 | from digitalio import DigitalInOut 2 | import board 3 | 4 | 5 | def enable_speakers(): 6 | speaker_control = DigitalInOut(board.SPEAKER_ENABLE) 7 | speaker_control.switch_to_output(value=True) 8 | 9 | 10 | enable_speakers() 11 | -------------------------------------------------------------------------------- /Chapter07/03_play.py: -------------------------------------------------------------------------------- 1 | from digitalio import DigitalInOut 2 | from audioio import WaveFile, AudioOut 3 | import board 4 | import time 5 | 6 | 7 | def play_file(speaker, path): 8 | file = open(path, "rb") 9 | audio = WaveFile(file) 10 | speaker.play(audio) 11 | 12 | 13 | def enable_speakers(): 14 | speaker_control = DigitalInOut(board.SPEAKER_ENABLE) 15 | speaker_control.switch_to_output(value=True) 16 | 17 | 18 | enable_speakers() 19 | speaker = AudioOut(board.SPEAKER) 20 | play_file(speaker, 'piano.wav') 21 | time.sleep(100) 22 | -------------------------------------------------------------------------------- /Chapter07/04_pixels.py: -------------------------------------------------------------------------------- 1 | from neopixel import NeoPixel 2 | import board 3 | 4 | PIXEL_COUNT = 10 5 | RGB = dict( 6 | black=0x000000, 7 | white=0xFFFFFF, 8 | green=0x00FF00, 9 | red=0xFF0000, 10 | yellow=0xFFFF00, 11 | ) 12 | 13 | pixels = NeoPixel(board.NEOPIXEL, PIXEL_COUNT) 14 | pixels.brightness = 0.05 15 | pixels[0] = RGB['red'] 16 | pixels[1] = RGB['green'] 17 | 18 | while True: 19 | pass 20 | -------------------------------------------------------------------------------- /Chapter07/05_handler_sounds.py: -------------------------------------------------------------------------------- 1 | from touchio import TouchIn 2 | from digitalio import DigitalInOut 3 | from audioio import WaveFile, AudioOut 4 | import board 5 | 6 | 7 | def enable_speakers(): 8 | speaker_control = DigitalInOut(board.SPEAKER_ENABLE) 9 | speaker_control.switch_to_output(value=True) 10 | 11 | 12 | def play_file(speaker, path): 13 | file = open(path, "rb") 14 | audio = WaveFile(file) 15 | speaker.play(audio) 16 | 17 | 18 | class Handler: 19 | def __init__(self, speaker): 20 | self.speaker = speaker 21 | 22 | def handle(self, name, state): 23 | if state: 24 | play_file(self.speaker, 'piano.wav') 25 | 26 | 27 | class TouchEvent: 28 | THRESHOLD_ADJUSTMENT = 400 29 | 30 | def __init__(self, name, onchange): 31 | self.name = name 32 | self.last = False 33 | self.onchange = onchange 34 | pin = getattr(board, name) 35 | self.touch = TouchIn(pin) 36 | self.touch.threshold += self.THRESHOLD_ADJUSTMENT 37 | 38 | def process(self): 39 | current = self.touch.value 40 | if current != self.last: 41 | self.onchange(self.name, current) 42 | self.last = current 43 | 44 | 45 | enable_speakers() 46 | speaker = AudioOut(board.SPEAKER) 47 | handler = Handler(speaker) 48 | event = TouchEvent('A1', handler.handle) 49 | while True: 50 | event.process() 51 | -------------------------------------------------------------------------------- /Chapter07/06_handler_pixels.py: -------------------------------------------------------------------------------- 1 | from touchio import TouchIn 2 | from digitalio import DigitalInOut 3 | from audioio import WaveFile, AudioOut 4 | from neopixel import NeoPixel 5 | import board 6 | 7 | PIXEL_COUNT = 10 8 | 9 | 10 | def enable_speakers(): 11 | speaker_control = DigitalInOut(board.SPEAKER_ENABLE) 12 | speaker_control.switch_to_output(value=True) 13 | 14 | 15 | def play_file(speaker, path): 16 | file = open(path, "rb") 17 | audio = WaveFile(file) 18 | speaker.play(audio) 19 | 20 | 21 | class Handler: 22 | def __init__(self, speaker, pixels): 23 | self.speaker = speaker 24 | self.pixels = pixels 25 | 26 | def handle(self, name, state): 27 | if state: 28 | play_file(self.speaker, 'piano.wav') 29 | self.pixels[0] = 0xFF0000 30 | else: 31 | self.pixels[0] = 0x000000 32 | 33 | 34 | class TouchEvent: 35 | THRESHOLD_ADJUSTMENT = 400 36 | 37 | def __init__(self, name, onchange): 38 | self.name = name 39 | self.last = False 40 | self.onchange = onchange 41 | pin = getattr(board, name) 42 | self.touch = TouchIn(pin) 43 | self.touch.threshold += self.THRESHOLD_ADJUSTMENT 44 | 45 | def process(self): 46 | current = self.touch.value 47 | if current != self.last: 48 | self.onchange(self.name, current) 49 | self.last = current 50 | 51 | 52 | enable_speakers() 53 | speaker = AudioOut(board.SPEAKER) 54 | pixels = NeoPixel(board.NEOPIXEL, PIXEL_COUNT) 55 | pixels.brightness = 0.05 56 | handler = Handler(speaker, pixels) 57 | event = TouchEvent('A1', handler.handle) 58 | while True: 59 | event.process() 60 | -------------------------------------------------------------------------------- /Chapter07/07_event_loop.py: -------------------------------------------------------------------------------- 1 | from touchio import TouchIn 2 | from digitalio import DigitalInOut 3 | from audioio import WaveFile, AudioOut 4 | from neopixel import NeoPixel 5 | import board 6 | 7 | PIXEL_COUNT = 10 8 | TOUCH_PADS = ['A1', 'A2', 'A5', 'A6'] 9 | SOUND = dict( 10 | A1='hit.wav', 11 | A2='piano.wav', 12 | A5='tin.wav', 13 | A6='wood.wav', 14 | ) 15 | RGB = dict( 16 | black=0x000000, 17 | white=0xFFFFFF, 18 | green=0x00FF00, 19 | red=0xFF0000, 20 | yellow=0xFFFF00, 21 | ) 22 | PIXELS = dict( 23 | A1=(6, RGB['white']), 24 | A2=(8, RGB['red']), 25 | A5=(1, RGB['yellow']), 26 | A6=(3, RGB['green']), 27 | ) 28 | 29 | 30 | def play_file(speaker, path): 31 | file = open(path, "rb") 32 | audio = WaveFile(file) 33 | speaker.play(audio) 34 | 35 | 36 | def enable_speakers(): 37 | speaker_control = DigitalInOut(board.SPEAKER_ENABLE) 38 | speaker_control.switch_to_output(value=True) 39 | 40 | 41 | class Handler: 42 | def __init__(self, speaker, pixels): 43 | self.speaker = speaker 44 | self.pixels = pixels 45 | 46 | def handle(self, name, state): 47 | pos, color = PIXELS[name] 48 | if state: 49 | play_file(self.speaker, SOUND[name]) 50 | self.pixels[pos] = color 51 | else: 52 | self.pixels[pos] = RGB['black'] 53 | 54 | 55 | class TouchEvent: 56 | THRESHOLD_ADJUSTMENT = 400 57 | 58 | def __init__(self, name, onchange): 59 | self.name = name 60 | self.last = False 61 | self.onchange = onchange 62 | pin = getattr(board, name) 63 | self.touch = TouchIn(pin) 64 | self.touch.threshold += self.THRESHOLD_ADJUSTMENT 65 | 66 | def process(self): 67 | current = self.touch.value 68 | if current != self.last: 69 | self.onchange(self.name, current) 70 | self.last = current 71 | 72 | 73 | def main(): 74 | enable_speakers() 75 | speaker = AudioOut(board.SPEAKER) 76 | pixels = NeoPixel(board.NEOPIXEL, PIXEL_COUNT) 77 | pixels.brightness = 0.05 78 | handler = Handler(speaker, pixels) 79 | events = [TouchEvent(i, handler.handle) for i in TOUCH_PADS] 80 | while True: 81 | for event in events: 82 | event.process() 83 | 84 | 85 | main() 86 | -------------------------------------------------------------------------------- /Chapter07/fruity/hit.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/MicroPython-Cookbook/dd9b98fae1c44e807c565358fc126b6dc982f2ca/Chapter07/fruity/hit.wav -------------------------------------------------------------------------------- /Chapter07/fruity/main.py: -------------------------------------------------------------------------------- 1 | from touchio import TouchIn 2 | from digitalio import DigitalInOut 3 | from audioio import WaveFile, AudioOut 4 | from neopixel import NeoPixel 5 | import board 6 | 7 | PIXEL_COUNT = 10 8 | TOUCH_PADS = ['A1', 'A2', 'A5', 'A6'] 9 | SOUND = dict( 10 | A1='hit.wav', 11 | A2='piano.wav', 12 | A5='tin.wav', 13 | A6='wood.wav', 14 | ) 15 | RGB = dict( 16 | black=0x000000, 17 | white=0xFFFFFF, 18 | green=0x00FF00, 19 | red=0xFF0000, 20 | yellow=0xFFFF00, 21 | ) 22 | PIXELS = dict( 23 | A1=(6, RGB['white']), 24 | A2=(8, RGB['red']), 25 | A5=(1, RGB['yellow']), 26 | A6=(3, RGB['green']), 27 | ) 28 | 29 | 30 | def play_file(speaker, path): 31 | file = open(path, "rb") 32 | audio = WaveFile(file) 33 | speaker.play(audio) 34 | 35 | 36 | def enable_speakers(): 37 | speaker_control = DigitalInOut(board.SPEAKER_ENABLE) 38 | speaker_control.switch_to_output(value=True) 39 | 40 | 41 | class Handler: 42 | def __init__(self, speaker, pixels): 43 | self.speaker = speaker 44 | self.pixels = pixels 45 | 46 | def handle(self, name, state): 47 | pos, color = PIXELS[name] 48 | if state: 49 | play_file(self.speaker, SOUND[name]) 50 | self.pixels[pos] = color 51 | else: 52 | self.pixels[pos] = RGB['black'] 53 | 54 | 55 | class TouchEvent: 56 | THRESHOLD_ADJUSTMENT = 400 57 | 58 | def __init__(self, name, onchange): 59 | self.name = name 60 | self.last = False 61 | self.onchange = onchange 62 | pin = getattr(board, name) 63 | self.touch = TouchIn(pin) 64 | self.touch.threshold += self.THRESHOLD_ADJUSTMENT 65 | 66 | def process(self): 67 | current = self.touch.value 68 | if current != self.last: 69 | self.onchange(self.name, current) 70 | self.last = current 71 | 72 | 73 | def main(): 74 | enable_speakers() 75 | speaker = AudioOut(board.SPEAKER) 76 | pixels = NeoPixel(board.NEOPIXEL, PIXEL_COUNT) 77 | pixels.brightness = 0.05 78 | handler = Handler(speaker, pixels) 79 | events = [TouchEvent(i, handler.handle) for i in TOUCH_PADS] 80 | while True: 81 | for event in events: 82 | event.process() 83 | 84 | 85 | main() 86 | -------------------------------------------------------------------------------- /Chapter07/fruity/piano.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/MicroPython-Cookbook/dd9b98fae1c44e807c565358fc126b6dc982f2ca/Chapter07/fruity/piano.wav -------------------------------------------------------------------------------- /Chapter07/fruity/tin.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/MicroPython-Cookbook/dd9b98fae1c44e807c565358fc126b6dc982f2ca/Chapter07/fruity/tin.wav -------------------------------------------------------------------------------- /Chapter07/fruity/wood.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/MicroPython-Cookbook/dd9b98fae1c44e807c565358fc126b6dc982f2ca/Chapter07/fruity/wood.wav -------------------------------------------------------------------------------- /Chapter08/01_tuning.py: -------------------------------------------------------------------------------- 1 | import time 2 | from adafruit_circuitplayground.express import cpx 3 | from adafruit_crickit import crickit 4 | 5 | MIN_PULSE = 750 6 | MAX_PULSE = 2250 7 | 8 | crickit.servo_1.set_pulse_width_range(MIN_PULSE, MAX_PULSE) 9 | crickit.servo_1.angle = 0 10 | time.sleep(3) 11 | crickit.servo_1.angle = 90 12 | time.sleep(60) 13 | -------------------------------------------------------------------------------- /Chapter08/02_actuation_range.py: -------------------------------------------------------------------------------- 1 | import time 2 | from adafruit_circuitplayground.express import cpx 3 | from adafruit_crickit import crickit 4 | 5 | MIN_PULSE = 750 6 | MAX_PULSE = 2250 7 | 8 | crickit.servo_1.set_pulse_width_range(MIN_PULSE, MAX_PULSE) 9 | crickit.servo_1.angle = 0 10 | time.sleep(3) 11 | crickit.servo_1.actuation_range = 160 12 | crickit.servo_1.angle = 160 13 | time.sleep(60) 14 | -------------------------------------------------------------------------------- /Chapter08/03_servo_angle.py: -------------------------------------------------------------------------------- 1 | import time 2 | from adafruit_circuitplayground.express import cpx 3 | from adafruit_crickit import crickit 4 | 5 | MIN_PULSE = 750 6 | MAX_PULSE = 2250 7 | 8 | crickit.servo_1.set_pulse_width_range(MIN_PULSE, MAX_PULSE) 9 | crickit.servo_1.angle = 0 10 | crickit.servo_1.actuation_range = 160 11 | 12 | crickit.servo_1.angle = 0 13 | time.sleep(3) 14 | 15 | crickit.servo_1.angle = 45 16 | time.sleep(3) 17 | 18 | crickit.servo_1.angle = 90 19 | time.sleep(3) 20 | 21 | crickit.servo_1.angle = 160 22 | time.sleep(3) 23 | -------------------------------------------------------------------------------- /Chapter08/04_servo_sweep.py: -------------------------------------------------------------------------------- 1 | import time 2 | from adafruit_circuitplayground.express import cpx 3 | from adafruit_crickit import crickit 4 | 5 | MIN_PULSE = 750 6 | MAX_PULSE = 2250 7 | MAX_ANGLE = 160 8 | STEP = 10 9 | DELAY = 0.1 10 | 11 | 12 | def init(servo): 13 | servo.set_pulse_width_range(MIN_PULSE, MAX_PULSE) 14 | servo.angle = 0 15 | servo.actuation_range = MAX_ANGLE 16 | 17 | 18 | def sweep(servo, direction): 19 | angle = int(servo.angle) 20 | while 0 <= angle <= MAX_ANGLE: 21 | print(angle) 22 | servo.angle = angle 23 | time.sleep(DELAY) 24 | angle += STEP * direction 25 | 26 | 27 | def main(): 28 | init(crickit.servo_1) 29 | while True: 30 | sweep(crickit.servo_1, 1) 31 | sweep(crickit.servo_1, -1) 32 | 33 | 34 | main() 35 | -------------------------------------------------------------------------------- /Chapter08/05_servo_buttons.py: -------------------------------------------------------------------------------- 1 | import time 2 | from adafruit_circuitplayground.express import cpx 3 | from adafruit_crickit import crickit 4 | 5 | MIN_PULSE = 750 6 | MAX_PULSE = 2250 7 | MAX_ANGLE = 160 8 | STEP = 10 9 | DELAY = 0.1 10 | 11 | 12 | def init(servo): 13 | servo.set_pulse_width_range(MIN_PULSE, MAX_PULSE) 14 | servo.angle = 0 15 | servo.actuation_range = MAX_ANGLE 16 | 17 | 18 | def move(servo, angle, direction): 19 | new = angle + STEP * direction 20 | if 0 <= new <= MAX_ANGLE: 21 | angle = new 22 | print(angle) 23 | servo.angle = angle 24 | return angle 25 | 26 | 27 | def main(): 28 | init(crickit.servo_1) 29 | angle = 0 30 | while True: 31 | if cpx.button_a: 32 | angle = move(crickit.servo_1, angle, 1) 33 | if cpx.button_b: 34 | angle = move(crickit.servo_1, angle, -1) 35 | time.sleep(DELAY) 36 | 37 | 38 | main() 39 | -------------------------------------------------------------------------------- /Chapter08/06_multiple_servos.py: -------------------------------------------------------------------------------- 1 | import time 2 | from adafruit_circuitplayground.express import cpx 3 | from adafruit_crickit import crickit 4 | 5 | MIN_PULSE = 750 6 | MAX_PULSE = 2250 7 | MAX_ANGLE = 160 8 | STEP = 10 9 | DELAY = 0.1 10 | 11 | 12 | def init(servo): 13 | servo.set_pulse_width_range(MIN_PULSE, MAX_PULSE) 14 | servo.angle = 0 15 | servo.actuation_range = MAX_ANGLE 16 | 17 | 18 | def move(servo, angle, direction): 19 | new = angle + STEP * direction 20 | if 0 <= new <= MAX_ANGLE: 21 | angle = new 22 | print(angle) 23 | servo.angle = angle 24 | return angle 25 | 26 | 27 | def main(): 28 | servos = [crickit.servo_1, crickit.servo_4] 29 | angles = [0, 0] 30 | init(servos[0]) 31 | init(servos[1]) 32 | while True: 33 | switch = int(cpx.switch) 34 | if cpx.button_a: 35 | angles[switch] = move(servos[switch], angles[switch], 1) 36 | if cpx.button_b: 37 | angles[switch] = move(servos[switch], angles[switch], -1) 38 | time.sleep(DELAY) 39 | 40 | 41 | main() 42 | -------------------------------------------------------------------------------- /Chapter08/07_dc_motor_on.py: -------------------------------------------------------------------------------- 1 | from adafruit_crickit import crickit 2 | import time 3 | 4 | while True: 5 | crickit.dc_motor_1.throttle = 1 6 | time.sleep(1) 7 | crickit.dc_motor_1.throttle = 0 8 | time.sleep(1) 9 | -------------------------------------------------------------------------------- /Chapter08/08_dc_motor_speed.py: -------------------------------------------------------------------------------- 1 | from adafruit_crickit import crickit 2 | import time 3 | 4 | DELAY = 0.1 5 | 6 | 7 | def change_throttle(motor, start, increment): 8 | throttle = start 9 | for i in range(21): 10 | print(throttle) 11 | motor.throttle = throttle 12 | throttle += increment 13 | throttle = round(throttle, 1) 14 | time.sleep(DELAY) 15 | 16 | 17 | def main(): 18 | while True: 19 | change_throttle(crickit.dc_motor_1, -1.0, 0.1) 20 | change_throttle(crickit.dc_motor_1, 1.0, -0.1) 21 | 22 | 23 | main() 24 | -------------------------------------------------------------------------------- /Chapter08/09_dc_motor_buttons.py: -------------------------------------------------------------------------------- 1 | from adafruit_crickit import crickit 2 | from adafruit_circuitplayground.express import cpx 3 | import time 4 | 5 | STEP = 0.1 6 | DELAY = 0.1 7 | MIN_THROTTLE = -1 8 | MAX_THROTTLE = 1 9 | 10 | 11 | def move(motor, throttle, direction): 12 | new = throttle + STEP * direction 13 | if MIN_THROTTLE <= new <= MAX_THROTTLE: 14 | throttle = round(new, 1) 15 | print(throttle) 16 | motor.throttle = throttle 17 | return throttle 18 | 19 | 20 | def main(): 21 | throttle = 0 22 | while True: 23 | if cpx.button_a: 24 | throttle = move(crickit.dc_motor_1, throttle, 1) 25 | if cpx.button_b: 26 | throttle = move(crickit.dc_motor_1, throttle, -1) 27 | time.sleep(DELAY) 28 | 29 | 30 | main() 31 | -------------------------------------------------------------------------------- /Chapter09/01_mu_flash.py: -------------------------------------------------------------------------------- 1 | from microbit import display 2 | display.show('x') 3 | -------------------------------------------------------------------------------- /Chapter09/02_mu_repl.py: -------------------------------------------------------------------------------- 1 | import microbit 2 | microbit 3 | -------------------------------------------------------------------------------- /Chapter09/03_display_character.py: -------------------------------------------------------------------------------- 1 | from microbit import display 2 | import time 3 | 4 | for i in range(3): 5 | display.show(i) 6 | time.sleep(1) 7 | -------------------------------------------------------------------------------- /Chapter09/04_display_image.py: -------------------------------------------------------------------------------- 1 | from microbit import display, Image 2 | import time 3 | 4 | CLOCK = [getattr(Image, 'CLOCK%s' % i) for i in range(1, 13)] 5 | while True: 6 | for image in CLOCK: 7 | display.show(image) 8 | time.sleep(0.1) 9 | -------------------------------------------------------------------------------- /Chapter09/05_display_scrolling.py: -------------------------------------------------------------------------------- 1 | from microbit import display 2 | 3 | TEXT = [ 4 | ('slow', 300), 5 | ('normal', 150), 6 | ('fast', 75), 7 | 8 | ] 9 | 10 | for text, delay in TEXT: 11 | display.scroll(text, delay=delay) 12 | -------------------------------------------------------------------------------- /Chapter09/06_show_button.py: -------------------------------------------------------------------------------- 1 | from microbit import display, button_a, button_b 2 | 3 | while True: 4 | if button_a.is_pressed(): 5 | display.show('a') 6 | elif button_b.is_pressed(): 7 | display.show('b') 8 | else: 9 | display.clear() 10 | -------------------------------------------------------------------------------- /Chapter09/07_countdown.py: -------------------------------------------------------------------------------- 1 | from microbit import display, button_a 2 | import time 3 | 4 | NUMBERS = list(range(9, 0, -1)) 5 | 6 | 7 | def countdown(): 8 | for i in NUMBERS: 9 | display.show(i) 10 | time.sleep(1) 11 | display.clear() 12 | 13 | 14 | while True: 15 | if button_a.is_pressed(): 16 | countdown() 17 | -------------------------------------------------------------------------------- /Chapter10/01_repl.py: -------------------------------------------------------------------------------- 1 | import math 2 | math.pow(8, 2) 3 | 4 | 8**2 5 | -------------------------------------------------------------------------------- /Chapter10/02_scan.py: -------------------------------------------------------------------------------- 1 | import network 2 | station = network.WLAN(network.STA_IF) 3 | 4 | station.active(True) 5 | 6 | networks = station.scan() 7 | 8 | len(networks) 9 | names = [i[0] for i in networks] 10 | -------------------------------------------------------------------------------- /Chapter10/03_ap.py: -------------------------------------------------------------------------------- 1 | import network 2 | ap = network.WLAN(network.AP_IF) 3 | ap.config(essid='PyWifi', password='12345678') 4 | ap.active(True) 5 | ap.ifconfig() 6 | -------------------------------------------------------------------------------- /Chapter10/04_station.py: -------------------------------------------------------------------------------- 1 | import network 2 | station = network.WLAN(network.STA_IF) 3 | station.active(True) 4 | networks = station.scan() 5 | names = [i[0] for i in networks] 6 | 7 | station.connect('MyAmazingWiFi', 'MyAmazingPassword') 8 | station.isconnected() 9 | station.ifconfig() 10 | station.active(False) 11 | -------------------------------------------------------------------------------- /Chapter10/05_webrepl_web.py: -------------------------------------------------------------------------------- 1 | import webrepl_setup 2 | -------------------------------------------------------------------------------- /Chapter10/06_webrepl_cli.py: -------------------------------------------------------------------------------- 1 | import machine 2 | machine.reset() 3 | -------------------------------------------------------------------------------- /Chapter10/07_leds.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | import time 3 | 4 | red = Pin(0, Pin.OUT) 5 | blue = Pin(2, Pin.OUT) 6 | while True: 7 | blue.value(0) 8 | red.value(1) 9 | time.sleep(1) 10 | blue.value(1) 11 | red.value(0) 12 | time.sleep(1) 13 | -------------------------------------------------------------------------------- /Chapter11/01_remount.py: -------------------------------------------------------------------------------- 1 | import storage 2 | storage.remount('/', False) 3 | -------------------------------------------------------------------------------- /Chapter11/02_list_files.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | FILE_CODE = 0x8000 4 | 5 | 6 | def isfile(path): 7 | return os.stat(path)[0] == FILE_CODE 8 | 9 | 10 | def main(): 11 | files = [i for i in sorted(os.listdir()) if isfile(i)] 12 | print('files:', files) 13 | dirs = [i for i in sorted(os.listdir()) if not isfile(i)] 14 | print('dirs:', dirs) 15 | 16 | 17 | main() 18 | -------------------------------------------------------------------------------- /Chapter11/03_remove_files.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | FILE_CODE = 0x8000 4 | 5 | 6 | def isfile(path): 7 | return os.stat(path)[0] == FILE_CODE 8 | 9 | 10 | def any_remove(path): 11 | func = os.remove if isfile(path) else os.rmdir 12 | func(path) 13 | -------------------------------------------------------------------------------- /Chapter11/04_create_directories.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | def exists(path): 5 | try: 6 | os.stat(path) 7 | except OSError: 8 | return False 9 | return True 10 | 11 | 12 | def mkdir_safe(path): 13 | if not exists(path): 14 | os.mkdir(path) 15 | 16 | 17 | def makedirs(path): 18 | items = path.strip('/').split('/') 19 | count = len(items) 20 | paths = ['/' + '/'.join(items[0:i + 1]) for i in range(count)] 21 | for path in paths: 22 | os.mkdir(path) 23 | -------------------------------------------------------------------------------- /Chapter11/05_read_files.py: -------------------------------------------------------------------------------- 1 | data = open('hi.txt').read() 2 | 3 | data = open('hi.txt', 'rb').read() 4 | -------------------------------------------------------------------------------- /Chapter11/06_write_files.py: -------------------------------------------------------------------------------- 1 | class Path: 2 | def __init__(self, path): 3 | self._path = path 4 | 5 | def __repr__(self): 6 | return "Path(%r)" % self._path 7 | 8 | def write_bytes(self, data): 9 | with open(self._path, 'wb') as f: 10 | return f.write(data) 11 | 12 | def write_text(self, data): 13 | with open(self._path, 'w') as f: 14 | return f.write(data) 15 | 16 | 17 | Path('hi.txt').write_text('hi there') 18 | -------------------------------------------------------------------------------- /Chapter11/07_disk_usage.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | def get_disk_stats(): 5 | stats = os.statvfs('/') 6 | block_size = stats[0] 7 | total_blocks = stats[2] 8 | free_blocks = stats[3] 9 | stats = dict() 10 | stats['free'] = block_size * free_blocks 11 | stats['total'] = block_size * total_blocks 12 | stats['used'] = stats['total'] - stats['free'] 13 | return stats 14 | 15 | 16 | def format_size(val): 17 | val = int(val / 1024) # convert bytes to KiB 18 | val = '{:,}'.format(val) # add thousand separator 19 | val = '{0: >6} KiB'.format(val) # right align amounts 20 | return val 21 | 22 | 23 | def print_stats(): 24 | stats = get_disk_stats() 25 | print('free space: ', format_size(stats['free'])) 26 | print('used space: ', format_size(stats['used'])) 27 | print('total space:', format_size(stats['total'])) 28 | 29 | 30 | print_stats() 31 | -------------------------------------------------------------------------------- /Chapter12/01_dns.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import time 3 | 4 | BOOTUP_WIFI_DELAY = 5 5 | 6 | 7 | def get_ip(host, port=80): 8 | addr_info = socket.getaddrinfo(host, port) 9 | return addr_info[0][-1][0] 10 | 11 | 12 | def main(): 13 | print('applying wifi delay...') 14 | time.sleep(BOOTUP_WIFI_DELAY) 15 | print('performing DNS lookup...') 16 | hosts = ['python.org', 'micropython.org', 'pypi.org'] 17 | for host in hosts: 18 | print(host, get_ip(host)) 19 | 20 | 21 | main() 22 | -------------------------------------------------------------------------------- /Chapter12/02_check_network.py: -------------------------------------------------------------------------------- 1 | from netcheck import wait_for_networking 2 | 3 | 4 | def main(): 5 | ip = wait_for_networking() 6 | print('main started') 7 | print('device ip:', ip) 8 | 9 | 10 | main() 11 | -------------------------------------------------------------------------------- /Chapter12/03_http_raw.py: -------------------------------------------------------------------------------- 1 | from netcheck import wait_for_networking 2 | import socket 3 | 4 | HTTP_REQUEST = 'GET /{path} HTTP/1.0\r\nHost: {host}\r\n\r\n' 5 | HTTP_PORT = 80 6 | BUFFER_SIZE = 1024 7 | 8 | 9 | def parse_url(url): 10 | return url.replace('http://', '').split('/', 1) 11 | 12 | 13 | def get_ip(host, port=HTTP_PORT): 14 | addr_info = socket.getaddrinfo(host, port) 15 | return addr_info[0][-1][0] 16 | 17 | 18 | def fetch(url): 19 | host, path = parse_url(url) 20 | ip = get_ip(host) 21 | sock = socket.socket() 22 | sock.connect((ip, 80)) 23 | request = HTTP_REQUEST.format(host=host, path=path) 24 | sock.send(bytes(request, 'utf8')) 25 | response = b'' 26 | while True: 27 | chunk = sock.recv(BUFFER_SIZE) 28 | if not chunk: 29 | break 30 | response += chunk 31 | sock.close() 32 | body = response.split(b'\r\n\r\n', 1)[1] 33 | return str(body, 'utf8') 34 | 35 | 36 | def main(): 37 | wait_for_networking() 38 | html = fetch('http://micropython.org/ks/test.html') 39 | print(html) 40 | 41 | 42 | main() 43 | -------------------------------------------------------------------------------- /Chapter12/04_http_urequests.py: -------------------------------------------------------------------------------- 1 | from netcheck import wait_for_networking 2 | import urequests 3 | 4 | 5 | def main(): 6 | wait_for_networking() 7 | url = 'http://micropython.org/ks/test.html' 8 | html = urequests.get(url).text 9 | print(html) 10 | 11 | 12 | main() 13 | -------------------------------------------------------------------------------- /Chapter12/05_fetch_json.py: -------------------------------------------------------------------------------- 1 | from netcheck import wait_for_networking 2 | import urequests 3 | import time 4 | 5 | ISS_API_URL = 'http://api.open-notify.org/iss-now.json' 6 | 7 | 8 | def track_space_station(): 9 | for i in range(10): 10 | data = urequests.get(ISS_API_URL).json() 11 | position = data['iss_position'] 12 | print(i, 'lat: {latitude} long: {longitude}'.format(**position)) 13 | time.sleep(1) 14 | 15 | 16 | def main(): 17 | wait_for_networking() 18 | track_space_station() 19 | 20 | main() 21 | -------------------------------------------------------------------------------- /Chapter12/06_http_server.py: -------------------------------------------------------------------------------- 1 | from netcheck import wait_for_networking 2 | import socket 3 | import time 4 | 5 | HTTP_PORT = 80 6 | TCP_BACKLOG = 0 7 | TEMPLATE = """\ 8 | 9 | 10 | 11 | ESP8266 12 | 13 | 14 | 15 | 16 | 17 |

ESP8266

18 | uptime: {uptime}s 19 | 20 | 21 | """ 22 | 23 | 24 | def socket_listen(): 25 | sock = socket.socket() 26 | sock.bind(('0.0.0.0', HTTP_PORT)) 27 | sock.listen(TCP_BACKLOG) 28 | return sock 29 | 30 | 31 | def serve_requests(sock, ip): 32 | print('webserver started on http://%s/' % ip) 33 | start = time.monotonic() 34 | while True: 35 | conn, address = sock.accept() 36 | print('request:', address) 37 | request = conn.makefile('rwb') 38 | while True: 39 | line = request.readline() 40 | if not line or line == b'\r\n': 41 | break 42 | uptime = time.monotonic() - start 43 | html = TEMPLATE.format(uptime=uptime) 44 | conn.send(html) 45 | conn.close() 46 | 47 | 48 | def main(): 49 | ip = wait_for_networking() 50 | sock = socket_listen() 51 | serve_requests(sock, ip) 52 | 53 | 54 | main() 55 | -------------------------------------------------------------------------------- /Chapter12/07_web_handler.py: -------------------------------------------------------------------------------- 1 | from web import BASE_TEMPLATE, run_server 2 | import random 3 | 4 | 5 | def handler(request, method, path): 6 | body = 'random: %s' % random.random() 7 | return BASE_TEMPLATE % body 8 | 9 | 10 | def main(): 11 | run_server(handler) 12 | 13 | 14 | main() 15 | -------------------------------------------------------------------------------- /Chapter12/08_web_leds.py: -------------------------------------------------------------------------------- 1 | from web import BASE_TEMPLATE, run_server 2 | from machine import Pin 3 | 4 | pins = dict(red=Pin(0, Pin.OUT), blue=Pin(2, Pin.OUT)) 5 | state = dict(red=True, blue=True) 6 | 7 | BODY = """ 8 | Red: {red}
9 | Blue: {blue}

10 | Toggle Colors:

11 |

12 |

13 | """ 14 | 15 | 16 | def format(value): 17 | return 'On' if value else 'Off' 18 | 19 | 20 | def gen_body(): 21 | data = {k: format(v) for k, v in state.items()} 22 | return BODY.format(**data) 23 | 24 | 25 | def toggle_color(color): 26 | state[color] = not state[color] 27 | pin_value = 0 if state[color] else 1 28 | pins[color].value(pin_value) 29 | 30 | 31 | def handler(request, method, path): 32 | if method == 'POST': 33 | color = path.replace('/', '') 34 | toggle_color(color) 35 | return BASE_TEMPLATE % gen_body() 36 | 37 | 38 | def main(): 39 | pins['red'].value(0) 40 | pins['blue'].value(0) 41 | run_server(handler) 42 | 43 | 44 | main() 45 | -------------------------------------------------------------------------------- /Chapter12/09_api_leds.py: -------------------------------------------------------------------------------- 1 | from web import BASE_TEMPLATE, run_server 2 | from machine import Pin 3 | import json 4 | 5 | pins = dict(red=Pin(0, Pin.OUT), blue=Pin(2, Pin.OUT)) 6 | state = dict(red=True, blue=True) 7 | JSON_HEADERS = '''\ 8 | HTTP/1.1 200 OK 9 | Content-Type: application/json 10 | 11 | ''' 12 | 13 | 14 | def toggle_color(color): 15 | state[color] = not state[color] 16 | pin_value = 0 if state[color] else 1 17 | pins[color].value(pin_value) 18 | 19 | 20 | def handler(request, method, path): 21 | if method == 'POST': 22 | color = path.replace('/', '') 23 | toggle_color(color) 24 | return JSON_HEADERS + json.dumps(state) + '\n' 25 | 26 | 27 | def main(): 28 | pins['red'].value(0) 29 | pins['blue'].value(0) 30 | run_server(handler) 31 | 32 | 33 | main() 34 | -------------------------------------------------------------------------------- /Chapter12/extra/fix_urequests_warnings.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | OLD_CODE = 'usocket.getaddrinfo(host, port, 0, usocket.SOCK_STREAM)' 5 | NEW_CODE = 'usocket.getaddrinfo(host, port)' 6 | 7 | 8 | def main(): 9 | assert sys.version_info.major >= 3, 'Python 3 or above required' 10 | os.rename('urequests.py', 'old_urequests.py') 11 | old = open('old_urequests.py').read() 12 | new = old.replace(OLD_CODE, NEW_CODE) 13 | with open('urequests.py', 'w') as f: 14 | f.write(new) 15 | 16 | main() 17 | -------------------------------------------------------------------------------- /Chapter12/extra/netcheck.py: -------------------------------------------------------------------------------- 1 | import network 2 | import time 3 | 4 | 5 | def wait_for_networking(): 6 | station = network.WLAN(network.STA_IF) 7 | while not station.isconnected(): 8 | print('waiting for network...') 9 | time.sleep(1) 10 | ip = station.ifconfig()[0] 11 | print('address on network:', ip) 12 | return ip 13 | -------------------------------------------------------------------------------- /Chapter12/extra/web.py: -------------------------------------------------------------------------------- 1 | from netcheck import wait_for_networking 2 | import socket 3 | 4 | HTTP_PORT = 80 5 | TCP_BACKLOG = 0 6 | BASE_TEMPLATE = """\ 7 | 8 | 9 | 10 | MicroPython 11 | 12 | 13 | 14 | 15 | 16 | %s 17 | 18 | 19 | """ 20 | 21 | 22 | def socket_listen(): 23 | sock = socket.socket() 24 | sock.bind(('0.0.0.0', HTTP_PORT)) 25 | sock.listen(TCP_BACKLOG) 26 | return sock 27 | 28 | 29 | def serve_requests(sock, ip, handler): 30 | print('webserver started on http://%s/' % ip) 31 | while True: 32 | conn, address = sock.accept() 33 | stream = conn.makefile('rwb') 34 | request = b'' 35 | while True: 36 | line = stream.readline() 37 | request += line 38 | if not line or line == b'\r\n': 39 | break 40 | request = str(request, 'utf8') 41 | method, path, _ = request.split(' ', 2) 42 | client_ip = address[0] 43 | print('request:', client_ip, method, path) 44 | html = handler(request, method, path) 45 | conn.send(html) 46 | conn.close() 47 | 48 | 49 | def run_server(handler): 50 | ip = wait_for_networking() 51 | sock = socket_listen() 52 | serve_requests(sock, ip, handler) 53 | -------------------------------------------------------------------------------- /Chapter13/01_buttons.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | import time 3 | 4 | PINS = dict(a=0, b=16, c=2) 5 | 6 | 7 | def format(name, buttons): 8 | pressed = not buttons[name].value() 9 | return '{name}: {pressed}'.format(name=name, pressed=pressed) 10 | 11 | 12 | def get_status(names, buttons): 13 | items = [format(i, buttons) for i in names] 14 | return ' '.join(items) 15 | 16 | 17 | def get_buttons(): 18 | return dict( 19 | a=Pin(PINS['a'], Pin.IN, Pin.PULL_UP), 20 | b=Pin(PINS['b']), 21 | c=Pin(PINS['c'], Pin.IN, Pin.PULL_UP), 22 | ) 23 | 24 | 25 | def main(): 26 | names = sorted(PINS.keys()) 27 | buttons = get_buttons() 28 | while True: 29 | status = get_status(names, buttons) 30 | print(status) 31 | time.sleep(0.1) 32 | 33 | 34 | main() 35 | -------------------------------------------------------------------------------- /Chapter13/02_ssd1306.py: -------------------------------------------------------------------------------- 1 | import adafruit_ssd1306 2 | import board 3 | import busio 4 | 5 | 6 | def main(): 7 | print('initialize I2C bus') 8 | i2c = busio.I2C(board.SCL, board.SDA) 9 | print('create SSD1306_I2C object') 10 | oled = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c) 11 | print('ALL DONE') 12 | 13 | 14 | main() 15 | -------------------------------------------------------------------------------- /Chapter13/03_fill.py: -------------------------------------------------------------------------------- 1 | import adafruit_ssd1306 2 | import board 3 | import busio 4 | 5 | 6 | def main(): 7 | i2c = busio.I2C(board.SCL, board.SDA) 8 | oled = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c) 9 | for i in range(10): 10 | oled.fill(1) 11 | oled.show() 12 | oled.fill(0) 13 | oled.show() 14 | 15 | 16 | main() 17 | -------------------------------------------------------------------------------- /Chapter13/04_pixels.py: -------------------------------------------------------------------------------- 1 | import adafruit_ssd1306 2 | import board 3 | import busio 4 | 5 | BLACK = 0 6 | WHITE = 1 7 | 8 | 9 | def animate_pixel(oled, x, y, step_x, step_y, count): 10 | for i in range(count): 11 | x += step_x 12 | y += step_y 13 | oled.pixel(x, y, WHITE) 14 | oled.show() 15 | 16 | 17 | def zig_zag(oled): 18 | animate_pixel(oled, x=0, y=0, step_x=1, step_y=1, count=30) 19 | animate_pixel(oled, x=30, y=30, step_x=1, step_y=-1, count=30) 20 | animate_pixel(oled, x=60, y=0, step_x=1, step_y=1, count=30) 21 | animate_pixel(oled, x=90, y=30, step_x=1, step_y=-1, count=30) 22 | 23 | 24 | def main(): 25 | i2c = busio.I2C(board.SCL, board.SDA) 26 | oled = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c) 27 | zig_zag(oled) 28 | 29 | 30 | main() 31 | -------------------------------------------------------------------------------- /Chapter13/05_lines.py: -------------------------------------------------------------------------------- 1 | import adafruit_ssd1306 2 | import board 3 | import busio 4 | 5 | BLACK = 0 6 | WHITE = 1 7 | 8 | 9 | def draw_hi(oled): 10 | print('drawing H') 11 | oled.vline(x=50, y=0, height=30, color=WHITE) 12 | oled.hline(x=50, y=15, width=30, color=WHITE) 13 | oled.vline(x=80, y=0, height=30, color=WHITE) 14 | oled.show() 15 | print('drawing I') 16 | oled.vline(x=100, y=0, height=30, color=WHITE) 17 | oled.show() 18 | 19 | 20 | def animate_boxes(oled, x, y, step_x, step_y, size, count): 21 | for i in range(count): 22 | oled.rect(x, y, width=size, height=size, color=WHITE) 23 | oled.show() 24 | x += step_x 25 | y += step_y 26 | 27 | 28 | def draw_x_boxes(oled): 29 | animate_boxes(oled, x=0, y=0, step_x=5, step_y=5, size=5, count=6) 30 | animate_boxes(oled, x=0, y=25, step_x=5, step_y=-5, size=5, count=6) 31 | 32 | 33 | def main(): 34 | i2c = busio.I2C(board.SCL, board.SDA) 35 | oled = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c) 36 | draw_x_boxes(oled) 37 | draw_hi(oled) 38 | 39 | 40 | main() 41 | -------------------------------------------------------------------------------- /Chapter13/06_text.py: -------------------------------------------------------------------------------- 1 | import adafruit_ssd1306 2 | import board 3 | import busio 4 | 5 | BLACK = 0 6 | WHITE = 1 7 | ALPHA_NUMERIC = [ 8 | 'abcdefghijklmnopqrstu', 9 | 'vwxyzABCDEFGHIJKLMNOP', 10 | 'QRSTUVWXYZ0123456789', 11 | ] 12 | 13 | 14 | def countdown(oled, start): 15 | for i in range(start, -1, -1): 16 | oled.fill(BLACK) 17 | oled.text(str(i), 0, 0, WHITE) 18 | oled.show() 19 | 20 | 21 | def show_alpha_numeric(oled): 22 | for i, text in enumerate(ALPHA_NUMERIC): 23 | oled.text(text, 0, 10 * i, WHITE) 24 | oled.show() 25 | 26 | 27 | def main(): 28 | i2c = busio.I2C(board.SCL, board.SDA) 29 | oled = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c) 30 | oled.fill(BLACK) 31 | countdown(oled, 10) 32 | oled.fill(BLACK) 33 | show_alpha_numeric(oled) 34 | 35 | 36 | main() 37 | -------------------------------------------------------------------------------- /Chapter13/07_invert.py: -------------------------------------------------------------------------------- 1 | import adafruit_ssd1306 2 | import board 3 | import busio 4 | import time 5 | 6 | BLACK = 0 7 | WHITE = 1 8 | 9 | 10 | def measure_time(label, func, args=(), count=3): 11 | for i in range(count): 12 | start = time.monotonic() 13 | func(*args) 14 | total = (time.monotonic() - start) * 1000 15 | print(label + ':', '%s ms' % total) 16 | 17 | 18 | def main(): 19 | i2c = busio.I2C(board.SCL, board.SDA) 20 | oled = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c) 21 | oled.fill(BLACK) 22 | oled.show() 23 | 24 | measure_time('fill', oled.fill, [BLACK]) 25 | measure_time('show', oled.show, []) 26 | measure_time('text', oled.text, ['hello', 0, 0, WHITE]) 27 | measure_time('invert', oled.invert, [True]) 28 | 29 | 30 | main() 31 | -------------------------------------------------------------------------------- /Chapter13/extra/fix_framebuf_import.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | OLD_CODE = 'import framebuf' 5 | NEW_CODE = 'import adafruit_framebuf as framebuf' 6 | 7 | 8 | def main(): 9 | assert sys.version_info.major >= 3, 'Python 3 or above required' 10 | os.rename('adafruit_ssd1306.py', 'old_adafruit_ssd1306.py') 11 | old = open('old_adafruit_ssd1306.py').read() 12 | new = old.replace(OLD_CODE, NEW_CODE) 13 | with open('adafruit_ssd1306.py', 'w') as f: 14 | f.write(new) 15 | 16 | main() 17 | -------------------------------------------------------------------------------- /Chapter14/01_get_weather_simple.py: -------------------------------------------------------------------------------- 1 | import urequests 2 | 3 | API_URL = 'http://api.openweathermap.org/data/2.5/weather' 4 | 5 | APPID = 'put-your-API-key(APPID)-here' 6 | city = 'Berlin' 7 | url = API_URL + '?units=metric&APPID=' + APPID + '&q=' + city 8 | 9 | response = urequests.get(url) 10 | response 11 | data = response.json() 12 | len(data) 13 | 14 | data['main'] 15 | data['main']['temp'] 16 | data['main']['humidity'] 17 | data['wind'] 18 | data['wind']['speed'] 19 | -------------------------------------------------------------------------------- /Chapter14/02_get_weather_func.py: -------------------------------------------------------------------------------- 1 | from netcheck import wait_for_networking 2 | import urequests 3 | import json 4 | 5 | CONF_PATH = 'conf.json' 6 | API_URL = 'http://api.openweathermap.org/data/2.5/weather' 7 | 8 | 9 | def get_conf(): 10 | content = open(CONF_PATH).read() 11 | return json.loads(content) 12 | 13 | 14 | def get_weather(APPID, city): 15 | url = API_URL + '?units=metric&APPID=' + APPID + '&q=' + city 16 | return urequests.get(url).json() 17 | 18 | 19 | def main(): 20 | wait_for_networking() 21 | conf = get_conf() 22 | APPID = conf['APPID'] 23 | data = get_weather(APPID, 'London') 24 | print('temp:', data['main']['temp']) 25 | print('wind:', data['wind']['speed']) 26 | print('name:', data['name']) 27 | print('country:', data['sys']['country']) 28 | 29 | 30 | main() 31 | -------------------------------------------------------------------------------- /Chapter14/03_random_city.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | CITIES = ['Berlin', 'London', 'Paris', 'Tokyo', 'Rome', 'Oslo', 'Bangkok'] 5 | 6 | 7 | def main(): 8 | for i in range(10): 9 | city = random.choice(CITIES) 10 | print('random selection', i, city) 11 | 12 | 13 | main() 14 | -------------------------------------------------------------------------------- /Chapter14/04_screen.py: -------------------------------------------------------------------------------- 1 | from screen import Screen, get_oled 2 | 3 | MESSAGE = """\ 4 | top line %s 5 | middle line 6 | last line 7 | """ 8 | 9 | 10 | def main(): 11 | oled = get_oled() 12 | screen = Screen(oled) 13 | screen.write('hello') 14 | 15 | for i in range(10): 16 | print(i) 17 | screen.write(MESSAGE % i) 18 | 19 | 20 | main() 21 | -------------------------------------------------------------------------------- /Chapter14/05_show_weather.py: -------------------------------------------------------------------------------- 1 | from screen import Screen, get_oled 2 | from netcheck import wait_for_networking 3 | import urequests 4 | import json 5 | 6 | CONF_PATH = 'conf.json' 7 | API_URL = 'http://api.openweathermap.org/data/2.5/weather' 8 | CITIES = ['Berlin', 'London', 'Paris', 'Tokyo', 'Rome', 'Oslo', 'Bangkok'] 9 | WEATHER = """\ 10 | City: {city} 11 | Temp: {temp} 12 | Wind: {wind} 13 | """ 14 | 15 | 16 | def get_conf(): 17 | content = open(CONF_PATH).read() 18 | return json.loads(content) 19 | 20 | 21 | def get_weather(APPID, city): 22 | url = API_URL + '?units=metric&APPID=' + APPID + '&q=' + city 23 | return urequests.get(url).json() 24 | 25 | 26 | def show_weather(screen, APPID, city): 27 | weather = get_weather(APPID, city) 28 | data = {} 29 | data['city'] = city 30 | data['temp'] = weather['main']['temp'] 31 | data['wind'] = weather['wind']['speed'] 32 | text = WEATHER.format(**data) 33 | print('-------- %s --------' % city) 34 | print(text) 35 | screen.write(text) 36 | 37 | 38 | def main(): 39 | oled = get_oled() 40 | screen = Screen(oled) 41 | wait_for_networking() 42 | conf = get_conf() 43 | APPID = conf['APPID'] 44 | for city in CITIES: 45 | show_weather(screen, APPID, city) 46 | 47 | 48 | main() 49 | -------------------------------------------------------------------------------- /Chapter14/06_visual_feedback.py: -------------------------------------------------------------------------------- 1 | from screen import Screen, get_oled 2 | from netcheck import wait_for_networking 3 | import urequests 4 | import json 5 | import time 6 | 7 | CONF_PATH = 'conf.json' 8 | API_URL = 'http://api.openweathermap.org/data/2.5/weather' 9 | CITIES = ['Berlin', 'London', 'Paris', 'Tokyo', 'Rome', 'Oslo', 'Bangkok'] 10 | WEATHER = """\ 11 | City: {city} 12 | Temp: {temp} 13 | Wind: {wind} 14 | """ 15 | 16 | 17 | def get_conf(): 18 | content = open(CONF_PATH).read() 19 | return json.loads(content) 20 | 21 | 22 | def get_weather(APPID, city): 23 | url = API_URL + '?units=metric&APPID=' + APPID + '&q=' + city 24 | return urequests.get(url).json() 25 | 26 | 27 | def show_weather(screen, APPID, city): 28 | screen.oled.invert(True) 29 | weather = get_weather(APPID, city) 30 | data = {} 31 | data['city'] = city 32 | data['temp'] = weather['main']['temp'] 33 | data['wind'] = weather['wind']['speed'] 34 | text = WEATHER.format(**data) 35 | print('-------- %s --------' % city) 36 | print(text) 37 | screen.write(text) 38 | screen.oled.invert(False) 39 | 40 | 41 | def main(): 42 | oled = get_oled() 43 | screen = Screen(oled) 44 | wait_for_networking() 45 | conf = get_conf() 46 | APPID = conf['APPID'] 47 | for city in CITIES: 48 | show_weather(screen, APPID, city) 49 | time.sleep(1) 50 | 51 | 52 | main() 53 | -------------------------------------------------------------------------------- /Chapter14/07_show_random_weather.py: -------------------------------------------------------------------------------- 1 | from screen import Screen, get_oled 2 | from netcheck import wait_for_networking 3 | import urequests 4 | import json 5 | import time 6 | import random 7 | 8 | CONF_PATH = 'conf.json' 9 | API_URL = 'http://api.openweathermap.org/data/2.5/weather' 10 | CITIES = ['Berlin', 'London', 'Paris', 'Tokyo', 'Rome', 'Oslo', 'Bangkok'] 11 | WEATHER = """\ 12 | City: {city} 13 | Temp: {temp} 14 | Wind: {wind} 15 | """ 16 | 17 | 18 | def get_conf(): 19 | content = open(CONF_PATH).read() 20 | return json.loads(content) 21 | 22 | 23 | def get_weather(APPID, city): 24 | url = API_URL + '?units=metric&APPID=' + APPID + '&q=' + city 25 | return urequests.get(url).json() 26 | 27 | 28 | def show_weather(screen, APPID, city): 29 | screen.oled.invert(True) 30 | weather = get_weather(APPID, city) 31 | data = {} 32 | data['city'] = city 33 | data['temp'] = weather['main']['temp'] 34 | data['wind'] = weather['wind']['speed'] 35 | text = WEATHER.format(**data) 36 | print('-------- %s --------' % city) 37 | print(text) 38 | screen.write(text) 39 | screen.oled.invert(False) 40 | 41 | 42 | def show_random_weather(screen, APPID): 43 | city = random.choice(CITIES) 44 | show_weather(screen, APPID, city) 45 | 46 | 47 | def main(): 48 | oled = get_oled() 49 | screen = Screen(oled) 50 | wait_for_networking() 51 | conf = get_conf() 52 | APPID = conf['APPID'] 53 | for i in range(3): 54 | show_random_weather(screen, APPID) 55 | 56 | 57 | main() 58 | -------------------------------------------------------------------------------- /Chapter14/08_button_event_loop.py: -------------------------------------------------------------------------------- 1 | from screen import Screen, get_oled 2 | from netcheck import wait_for_networking 3 | from machine import Pin 4 | import urequests 5 | import json 6 | import time 7 | import random 8 | 9 | BUTTON_A_PIN = 0 10 | CONF_PATH = 'conf.json' 11 | API_URL = 'http://api.openweathermap.org/data/2.5/weather' 12 | CITIES = ['Berlin', 'London', 'Paris', 'Tokyo', 'Rome', 'Oslo', 'Bangkok'] 13 | WEATHER = """\ 14 | City: {city} 15 | Temp: {temp} 16 | Wind: {wind} 17 | """ 18 | 19 | 20 | def get_conf(): 21 | content = open(CONF_PATH).read() 22 | return json.loads(content) 23 | 24 | 25 | def get_weather(APPID, city): 26 | url = API_URL + '?units=metric&APPID=' + APPID + '&q=' + city 27 | return urequests.get(url).json() 28 | 29 | 30 | def show_weather(screen, APPID, city): 31 | screen.oled.invert(True) 32 | weather = get_weather(APPID, city) 33 | data = {} 34 | data['city'] = city 35 | data['temp'] = weather['main']['temp'] 36 | data['wind'] = weather['wind']['speed'] 37 | text = WEATHER.format(**data) 38 | print('-------- %s --------' % city) 39 | print(text) 40 | screen.write(text) 41 | screen.oled.invert(False) 42 | 43 | 44 | def show_random_weather(screen, APPID): 45 | city = random.choice(CITIES) 46 | show_weather(screen, APPID, city) 47 | 48 | 49 | def main(): 50 | oled = get_oled() 51 | screen = Screen(oled) 52 | wait_for_networking() 53 | conf = get_conf() 54 | APPID = conf['APPID'] 55 | button = Pin(BUTTON_A_PIN, Pin.IN, Pin.PULL_UP) 56 | show_random_weather(screen, APPID) 57 | while True: 58 | if not button.value(): 59 | show_random_weather(screen, APPID) 60 | 61 | 62 | main() 63 | -------------------------------------------------------------------------------- /Chapter14/extra/screen.py: -------------------------------------------------------------------------------- 1 | import adafruit_ssd1306 2 | import board 3 | import busio 4 | 5 | BLACK = 0 6 | WHITE = 1 7 | 8 | 9 | class Screen: 10 | def __init__(self, oled): 11 | self.oled = oled 12 | self.oled.fill(BLACK) 13 | self.oled.show() 14 | 15 | def write(self, text): 16 | self.oled.fill(BLACK) 17 | lines = text.strip().split('\n') 18 | for row, line in enumerate(lines): 19 | self.oled.text(line, 0, 10 * row, WHITE) 20 | self.oled.show() 21 | 22 | 23 | def get_oled(): 24 | i2c = busio.I2C(board.SCL, board.SDA) 25 | return adafruit_ssd1306.SSD1306_I2C(128, 32, i2c) 26 | -------------------------------------------------------------------------------- /Chapter15/01_discover_i2c.py: -------------------------------------------------------------------------------- 1 | import board 2 | import busio 3 | 4 | 5 | def main(): 6 | i2c = busio.I2C(board.SCL, board.SDA) 7 | while not i2c.try_lock(): 8 | print('getting lock...') 9 | devices = [hex(x) for x in i2c.scan()] 10 | print('devices found:', devices) 11 | 12 | 13 | main() 14 | -------------------------------------------------------------------------------- /Chapter15/02_accelerometer.py: -------------------------------------------------------------------------------- 1 | from adafruit_lis3dh import LIS3DH_I2C 2 | import board 3 | import busio 4 | import time 5 | 6 | ACCEL_ADDRESS = 0x18 7 | 8 | 9 | def main(): 10 | i2c = busio.I2C(board.SCL, board.SDA) 11 | accel = LIS3DH_I2C(i2c, address=ACCEL_ADDRESS) 12 | while True: 13 | print(accel.acceleration) 14 | time.sleep(0.1) 15 | 16 | 17 | main() 18 | -------------------------------------------------------------------------------- /Chapter15/03_flip.py: -------------------------------------------------------------------------------- 1 | from adafruit_lis3dh import LIS3DH_I2C 2 | import board 3 | import busio 4 | import time 5 | 6 | ACCEL_ADDRESS = 0x18 7 | 8 | 9 | def main(): 10 | i2c = busio.I2C(board.SCL, board.SDA) 11 | accel = LIS3DH_I2C(i2c, address=ACCEL_ADDRESS) 12 | while True: 13 | face = 'up' if accel.acceleration.z < 0 else 'down' 14 | print('board is face', face) 15 | time.sleep(0.1) 16 | 17 | 18 | main() 19 | -------------------------------------------------------------------------------- /Chapter15/04_brightness.py: -------------------------------------------------------------------------------- 1 | import board 2 | import time 3 | 4 | 5 | def fade_in(): 6 | for i in range(0, 11): 7 | brightness = i / 10 8 | print('brightness:', brightness) 9 | board.DISPLAY.brightness = brightness 10 | time.sleep(0.1) 11 | 12 | 13 | def main(): 14 | while True: 15 | fade_in() 16 | 17 | 18 | main() 19 | -------------------------------------------------------------------------------- /Chapter15/05_display_image.py: -------------------------------------------------------------------------------- 1 | import board 2 | from displayio import OnDiskBitmap, ColorConverter, TileGrid, Group 3 | 4 | 5 | IMAGES = ['joke_01_question.bmp', 'joke_01_response.bmp'] 6 | 7 | 8 | def show_image(path): 9 | with open(path, 'rb') as f: 10 | bitmap = OnDiskBitmap(f) 11 | pixel_shader = ColorConverter() 12 | sprite = TileGrid(bitmap, pixel_shader=pixel_shader) 13 | group = Group() 14 | group.append(sprite) 15 | board.DISPLAY.show(group) 16 | board.DISPLAY.wait_for_frame() 17 | 18 | 19 | def main(): 20 | while True: 21 | for image in IMAGES: 22 | show_image(image) 23 | 24 | 25 | main() 26 | -------------------------------------------------------------------------------- /Chapter15/06_list_images.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | def get_questions(): 5 | paths = sorted(os.listdir()) 6 | return [i for i in paths if i.endswith('question.bmp')] 7 | 8 | 9 | def main(): 10 | questions = get_questions() 11 | for question in questions: 12 | response = question.replace('question.bmp', 'response.bmp') 13 | print(question, response) 14 | 15 | 16 | main() 17 | -------------------------------------------------------------------------------- /Chapter15/07_joke_machine.py: -------------------------------------------------------------------------------- 1 | from displayio import OnDiskBitmap, ColorConverter, TileGrid, Group 2 | import board 3 | import random 4 | import time 5 | import touchio 6 | import os 7 | 8 | 9 | def show_image(path): 10 | print('showing image', path) 11 | with open(path, 'rb') as f: 12 | bitmap = OnDiskBitmap(f) 13 | pixel_shader = ColorConverter() 14 | sprite = TileGrid(bitmap, pixel_shader=pixel_shader) 15 | group = Group() 16 | group.append(sprite) 17 | board.DISPLAY.show(group) 18 | board.DISPLAY.wait_for_frame() 19 | 20 | 21 | def wait_for_touch(touch): 22 | while not touch.value: 23 | print('waiting...') 24 | time.sleep(0.1) 25 | 26 | 27 | def get_questions(): 28 | paths = sorted(os.listdir()) 29 | return [i for i in paths if i.endswith('question.bmp')] 30 | 31 | 32 | def main(): 33 | touch = touchio.TouchIn(board.TOUCH1) 34 | questions = get_questions() 35 | while True: 36 | question = random.choice(questions) 37 | response = question.replace('question.bmp', 'response.bmp') 38 | show_image(question) 39 | wait_for_touch(touch) 40 | show_image(response) 41 | wait_for_touch(touch) 42 | 43 | 44 | main() 45 | -------------------------------------------------------------------------------- /Chapter15/images/joke_01_question.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/MicroPython-Cookbook/dd9b98fae1c44e807c565358fc126b6dc982f2ca/Chapter15/images/joke_01_question.bmp -------------------------------------------------------------------------------- /Chapter15/images/joke_01_response.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/MicroPython-Cookbook/dd9b98fae1c44e807c565358fc126b6dc982f2ca/Chapter15/images/joke_01_response.bmp -------------------------------------------------------------------------------- /Chapter15/images/joke_02_question.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/MicroPython-Cookbook/dd9b98fae1c44e807c565358fc126b6dc982f2ca/Chapter15/images/joke_02_question.bmp -------------------------------------------------------------------------------- /Chapter15/images/joke_02_response.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/MicroPython-Cookbook/dd9b98fae1c44e807c565358fc126b6dc982f2ca/Chapter15/images/joke_02_response.bmp -------------------------------------------------------------------------------- /Chapter15/images/joke_03_question.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/MicroPython-Cookbook/dd9b98fae1c44e807c565358fc126b6dc982f2ca/Chapter15/images/joke_03_question.bmp -------------------------------------------------------------------------------- /Chapter15/images/joke_03_response.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/MicroPython-Cookbook/dd9b98fae1c44e807c565358fc126b6dc982f2ca/Chapter15/images/joke_03_response.bmp -------------------------------------------------------------------------------- /Chapter15/images/joke_04_question.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/MicroPython-Cookbook/dd9b98fae1c44e807c565358fc126b6dc982f2ca/Chapter15/images/joke_04_question.bmp -------------------------------------------------------------------------------- /Chapter15/images/joke_04_response.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/MicroPython-Cookbook/dd9b98fae1c44e807c565358fc126b6dc982f2ca/Chapter15/images/joke_04_response.bmp -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # MicroPython Cookbook 5 | 6 | MicroPython Cookbook 7 | 8 | This is the code repository for [MicroPython Cookbook](https://www.packtpub.com/in/application-development/micropython-cookbook?utm_source=github&utm_medium=repository&utm_campaign=), published by Packt. 9 | 10 | **Build practical solutions to control LEDs, make music and read sensor data using popular microcontrollers such as Adafruit Circuit Playground, ESP8266, and the BBC Micro Bit** 11 | 12 | ## What is this book about? 13 | MicroPython is an open source implementation of Python 3 that runs in embedded environments. With MicroPython, you can write clean and simple Python code to control hardware instead of using complex low-level languages such as C and C++. This book guides you through all the major applications of the MicroPython platform to build and program projects that use microcontrollers. 14 | 15 | This book covers the following exciting features: 16 | * Execute code without any need for compiling or uploading using REPL (read-evaluate-print-loop) 17 | * Program and control LED matrix and NeoPixel drivers to display patterns and colors 18 | * Build projects that make use of light, temperature, and touch sensors 19 | * Configure devices to create Wi-Fi access points and use network modules to scan and connect to existing networks 20 | * Use Pulse Width Modulation to control DC motors and servos 21 | * Build an IoT device to display live weather data from the internet at the touch of a button 22 | 23 | If you feel this book is for you, get your [copy](https://www.amazon.com/dp/1838649956) today! 24 | 25 | https://www.packtpub.com/ 27 | 28 | ## Instructions and Navigations 29 | All of the code is organized into folders. For example, Chapter01. 30 | 31 | The code will look like the following: 32 | ``` 33 | from adafruit_circuitplayground.express import cpx 34 | import time 35 | 36 | cpx.pixels[0] = (255, 0, 0) # set first NeoPixel to the color red 37 | time.sleep(60) 38 | ``` 39 | 40 | **Following is what you need for this book:** 41 | This book aims to help people apply the power and ease of use of the Python language to the versatility of microcontrollers. Prior knowledge of Python is expected in order to understand this book. 42 | 43 | With the following software and hardware list you can run all code files present in the book (All chapters). 44 | ### Software and Hardware List 45 | | Chapter | Software required | OS required | 46 | | -------- | ------------------------------------ | ----------------------------------- | 47 | | All | Mu Text Editor 1.x | Windows, Linux, or macOS | 48 | | All | Screen terminal emulator | Windows, Linux, or macOS | 49 | 50 | We also provide a PDF file that has color images of the screenshots/diagrams used in this book. [Click here to download it](https://www.packtpub.com/sites/default/files/downloads/9781838649951_ColorImages.pdf). 51 | 52 | ### Related products 53 | * Artificial Intelligence for Robotics [[Packt]](https://www.packtpub.com/in/hardware-and-creative/artificial-intelligence-robotics?utm_source=github&utm_medium=repository&utm_campaign=) [[Amazon]](https://www.amazon.com/dp/1788835441) 54 | 55 | * Learn Robotics Programming [[Packt]](https://www.packtpub.com/hardware-and-creative/learn-robotics-programming?utm_source=github&utm_medium=repository&utm_campaign=) [[Amazon]](https://www.amazon.com/dp/1789340748) 56 | 57 | ## Get to Know the Author 58 | **Marwan Alsabbagh** 59 | has been coding in some form or other since before the web existed and has continued to develop software, with a particular passion for Python, his preferred programming language, for over a decade. He has been a speaker at a number of global Python conferences, where he has been known to present microcontroller projects with a healthy dose of humor and stage theatrics. The snow globe intruder alert system, which he created with his creative and curious daughters, was one of his favorite MicroPython projects. His research interests include software engineering, microcontrollers, and 3D printing. 60 | 61 | ### Suggestions and Feedback 62 | [Click here](https://docs.google.com/forms/d/e/1FAIpQLSdy7dATC6QmEL81FIUuymZ0Wy9vH1jHkvpY57OiMeKGqib_Ow/viewform) if you have any feedback or suggestions. 63 | ### Download a free PDF 64 | 65 | If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.
66 |

https://packt.link/free-ebook/9781838649951

--------------------------------------------------------------------------------