├── .gitignore ├── 03_01_blink.py ├── 03_02_sos.py ├── 03_03_for_loop.py ├── 03_04_sos_for.py ├── 03_05_if_simple.py ├── 03_06_if_else.py ├── 04_01_print_polite.py ├── 04_02_sos_function.py ├── 04_03_sos_return.py ├── 04_04_dice.py ├── 04_05_dice_many.py ├── 05_01_sos_list.py ├── 05_02_morse_dict.py ├── 05_03_morse_send_morse.py ├── 05_04_morse_printing.py ├── 05_05_morse_complete.py ├── 06_01_name_conflict.py ├── 06_02_Pin_class.py ├── 06_03_file_write.py ├── 06_04_file_read.py ├── 06_05_try_except.py ├── 06_06_counter.py ├── 07_01_digital_input.py ├── 07_02_switch_led.py ├── 07_03_pwm.py ├── 07_04_pwm_percent.py ├── 07_05_analog_input.py ├── 07_06_voltmeter.py ├── 08_01_blink_led.py ├── 08_02_RGB.py ├── 08_04_servo.py ├── 09_01_interrupts.py ├── 09_02_blink_timer.py ├── 09_03_fast_pwm.py ├── 09_04_multicore.py ├── 10_01_thermometer.py ├── 10_02_light_meter.py ├── 11_01_oled.py ├── 11_02_neopixel.py ├── 11_03_oled_clock.py ├── 12_01_circuit_python_blink.py ├── LICENSE ├── README.md ├── bonus_material ├── oled_pot.py └── ssd1306.py └── ssd1306.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | -------------------------------------------------------------------------------- /03_01_blink.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | from utime import sleep 3 | 4 | led = Pin(16, Pin.OUT) 5 | 6 | while True: 7 | led.on() 8 | sleep(0.5) # pause 9 | led.off() 10 | sleep(0.5) 11 | -------------------------------------------------------------------------------- /03_02_sos.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | from utime import sleep 3 | 4 | led = Pin(25, Pin.OUT) # For Pico W change 25 to LED see https://forums.raspberrypi.com/viewtopic.php?t=336836 5 | 6 | while True: 7 | # S 8 | led.on() 9 | sleep(0.2) 10 | led.off() 11 | sleep(0.2) 12 | led.on() 13 | sleep(0.2) 14 | led.off() 15 | sleep(0.2) 16 | led.on() 17 | sleep(0.2) 18 | led.off() 19 | sleep(0.6) 20 | # O 21 | led.on() 22 | sleep(0.6) 23 | led.off() 24 | sleep(0.6) 25 | led.on() 26 | sleep(0.6) 27 | led.off() 28 | sleep(0.6) 29 | led.on() 30 | sleep(0.6) 31 | led.off() 32 | sleep(0.6) -------------------------------------------------------------------------------- /03_03_for_loop.py: -------------------------------------------------------------------------------- 1 | for x in range(1, 10): 2 | print(x) -------------------------------------------------------------------------------- /03_04_sos_for.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | from utime import sleep 3 | 4 | led = Pin(25, Pin.OUT) # For Pico W change 25 to LED see https://forums.raspberrypi.com/viewtopic.php?t=336836 5 | 6 | while True: 7 | # This loop does 3 dots (S) 8 | for x in range(1, 4): 9 | led.on() 10 | sleep(0.2) 11 | led.off() 12 | sleep(0.2) 13 | sleep(0.4) # Gap between S and O 14 | # This loop does 3 dashes (O) 15 | for x in range(1, 4): 16 | led.on() 17 | sleep(0.6) 18 | led.off() 19 | sleep(0.6) 20 | -------------------------------------------------------------------------------- /03_05_if_simple.py: -------------------------------------------------------------------------------- 1 | response = input("Enter a number: ") 2 | number = int(response) 3 | if number > 10: 4 | print("That's a big number") 5 | -------------------------------------------------------------------------------- /03_06_if_else.py: -------------------------------------------------------------------------------- 1 | response = input("Enter a number: ") 2 | number = int(response) 3 | if number > 10: 4 | print("That's a big number") 5 | else: 6 | print("That's a small number") -------------------------------------------------------------------------------- /04_01_print_polite.py: -------------------------------------------------------------------------------- 1 | def print_polite(text): 2 | print(text + " please") 3 | 4 | print_polite("Pass the salt") -------------------------------------------------------------------------------- /04_02_sos_function.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | from utime import sleep 3 | 4 | led = Pin(25, Pin.OUT) # For Pico W change 25 to LED see https://forums.raspberrypi.com/viewtopic.php?t=336836 5 | 6 | def blink(times, delay): 7 | for x in range(1, times+1): 8 | led.on() 9 | sleep(delay) 10 | led.off() 11 | sleep(delay) 12 | 13 | while True: 14 | blink(3, 0.2) 15 | sleep(0.4) 16 | blink(3, 0.6) -------------------------------------------------------------------------------- /04_03_sos_return.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | from utime import sleep 3 | 4 | led = Pin(25, Pin.OUT) # For Pico W change 25 to LED see https://forums.raspberrypi.com/viewtopic.php?t=336836 5 | 6 | def blink(times, delay): 7 | for x in range(1, times+1): 8 | led.on() 9 | sleep(delay) 10 | led.off() 11 | sleep(delay) 12 | return times * delay * 2 13 | 14 | while True: 15 | print(blink(3, 0.2)) 16 | sleep(0.4) 17 | print(blink(3, 0.6)) 18 | -------------------------------------------------------------------------------- /04_04_dice.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | from utime import sleep 3 | from random import randint 4 | 5 | led = Pin(25, Pin.OUT) # For Pico W change 25 to LED see https://forums.raspberrypi.com/viewtopic.php?t=336836 6 | 7 | def throw_dice(): 8 | return randint(1, 6) 9 | 10 | def blink(times, delay): 11 | for x in range(1, times+1): 12 | led.on() 13 | sleep(delay) 14 | led.off() 15 | sleep(delay) 16 | 17 | while True: 18 | input() 19 | dice_throw = throw_dice() 20 | print(dice_throw) 21 | blink(dice_throw, 0.2) 22 | 23 | 24 | -------------------------------------------------------------------------------- /04_05_dice_many.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | from utime import sleep 3 | from random import randint 4 | 5 | led = Pin(25, Pin.OUT) # For Pico W change 25 to LED see https://forums.raspberrypi.com/viewtopic.php?t=336836 6 | 7 | def throw_dice(num_dice=1): 8 | total = 0 9 | for x in range(1, num_dice+1): 10 | total += randint(1, 6) 11 | return total 12 | 13 | def blink(times, delay): 14 | for x in range(1, times+1): 15 | led.on() 16 | sleep(delay) 17 | led.off() 18 | sleep(delay) 19 | 20 | while True: 21 | input() 22 | dice_throw = throw_dice(num_dice=2) 23 | print(dice_throw) 24 | blink(dice_throw, 0.2) 25 | -------------------------------------------------------------------------------- /05_01_sos_list.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | from utime import sleep 3 | 4 | led = Pin(25, Pin.OUT) # For Pico W change 25 to LED see https://forums.raspberrypi.com/viewtopic.php?t=336836 5 | 6 | delays = [0.2, 0.2, 0.2, 0.6, 0.6, 0.6] 7 | 8 | while True: 9 | for delay in delays: 10 | led.on() 11 | sleep(delay) 12 | led.off() 13 | sleep(delay) 14 | -------------------------------------------------------------------------------- /05_02_morse_dict.py: -------------------------------------------------------------------------------- 1 | codes = { 2 | "a" : ".-", "b" : "-...", "c" : "-.-.", 3 | "d" : "-..", "e" : ".", "f" : "..-.", 4 | "g" : "--.", "h" : "....", "i" : "..", 5 | "j" : ".---", "k" : "-.-", "l" : ".-..", 6 | "m" : "--", "n" : "-.", "o" : "---", 7 | "p" : ".--.", "q" : "--.-", "r" : ".-.", 8 | "s" : "...", "t" : "-", "u" : "..-", 9 | "v" : "...-", "w" : ".--", "x" : "-..-", 10 | "y" : "-.--", "z" : "--.." 11 | } -------------------------------------------------------------------------------- /05_03_morse_send_morse.py: -------------------------------------------------------------------------------- 1 | codes = { 2 | "a" : ".-", "b" : "-...", "c" : "-.-.", 3 | "d" : "-..", "e" : ".", "f" : "..-.", 4 | "g" : "--.", "h" : "....", "i" : "..", 5 | "j" : ".---", "k" : "-.-", "l" : ".-..", 6 | "m" : "--", "n" : "-.", "o" : "---", 7 | "p" : ".--.", "q" : "--.-", "r" : ".-.", 8 | "s" : "...", "t" : "-", "u" : "..-", 9 | "v" : "...-", "w" : ".--", "x" : "-..-", 10 | "y" : "-.--", "z" : "--.." 11 | } 12 | 13 | def send_morse_for(character): 14 | if character == ' ': 15 | print("space") 16 | else: 17 | dots_n_dashes = codes.get(character.lower()) 18 | if dots_n_dashes: 19 | print(character + " " + dots_n_dashes) 20 | else: 21 | print("unknown character: " + character) -------------------------------------------------------------------------------- /05_04_morse_printing.py: -------------------------------------------------------------------------------- 1 | codes = { 2 | "a" : ".-", "b" : "-...", "c" : "-.-.", 3 | "d" : "-..", "e" : ".", "f" : "..-.", 4 | "g" : "--.", "h" : "....", "i" : "..", 5 | "j" : ".---", "k" : "-.-", "l" : ".-..", 6 | "m" : "--", "n" : "-.", "o" : "---", 7 | "p" : ".--.", "q" : "--.-", "r" : ".-.", 8 | "s" : "...", "t" : "-", "u" : "..-", 9 | "v" : "...-", "w" : ".--", "x" : "-..-", 10 | "y" : "-.--", "z" : "--.." 11 | } 12 | 13 | def send_morse_for(character): 14 | if character == ' ': 15 | print("space") 16 | else: 17 | dots_n_dashes = codes.get(character.lower()) 18 | if dots_n_dashes: 19 | print(character + " " + dots_n_dashes) 20 | else: 21 | print("unknown character: " + character) 22 | 23 | while True: 24 | text = input("Message: ") 25 | for character in text: 26 | send_morse_for(character) -------------------------------------------------------------------------------- /05_05_morse_complete.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | from utime import sleep 3 | 4 | led = Pin(25, Pin.OUT) # For Pico W change 25 to LED see https://forums.raspberrypi.com/viewtopic.php?t=336836 5 | 6 | dot_duration = 0.2 7 | dash_duration = dot_duration * 3 8 | word_gap = dot_duration * 7 9 | 10 | durations = {"." : dot_duration, "-" : dash_duration} 11 | 12 | codes = { 13 | "a" : ".-", "b" : "-...", "c" : "-.-.", 14 | "d" : "-..", "e" : ".", "f" : "..-.", 15 | "g" : "--.", "h" : "....", "i" : "..", 16 | "j" : ".---", "k" : "-.-", "l" : ".-..", 17 | "m" : "--", "n" : "-.", "o" : "---", 18 | "p" : ".--.", "q" : "--.-", "r" : ".-.", 19 | "s" : "...", "t" : "-", "u" : "..-", 20 | "v" : "...-", "w" : ".--", "x" : "-..-", 21 | "y" : "-.--", "z" : "--.." 22 | } 23 | 24 | def send_pulse(dot_or_dash): 25 | if dot_or_dash == '.': 26 | delay = dot_duration 27 | else: 28 | delay = dash_duration 29 | led.on() 30 | sleep(delay) 31 | led.off() 32 | sleep(delay) 33 | 34 | def send_morse_for(character): 35 | if character == ' ': 36 | sleep(word_gap) 37 | else: 38 | dots_n_dashes = codes.get(character.lower()) 39 | if dots_n_dashes: 40 | print(character + " " + dots_n_dashes) 41 | for pulse in dots_n_dashes: 42 | send_pulse(pulse) 43 | sleep(dash_duration) 44 | else: 45 | print("unknown character: " + character) 46 | 47 | 48 | while True: 49 | text = input("Message: ") 50 | for character in text: 51 | send_morse_for(character) -------------------------------------------------------------------------------- /06_01_name_conflict.py: -------------------------------------------------------------------------------- 1 | def print(): 2 | pass 3 | 4 | print() -------------------------------------------------------------------------------- /06_02_Pin_class.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | led = Pin(25, Pin.OUT) # For Pico W change 25 to LED see https://forums.raspberrypi.com/viewtopic.php?t=336836 3 | led.on() 4 | -------------------------------------------------------------------------------- /06_03_file_write.py: -------------------------------------------------------------------------------- 1 | f = open("test.txt", "w") 2 | f.write(str(1)) 3 | f.close() 4 | -------------------------------------------------------------------------------- /06_04_file_read.py: -------------------------------------------------------------------------------- 1 | f = open("test.txt", "r") 2 | print(f.read()) 3 | f.close() -------------------------------------------------------------------------------- /06_05_try_except.py: -------------------------------------------------------------------------------- 1 | file_name = "testXX.txt" 2 | try: 3 | f = open(file_name, "r") 4 | print(f.read()) 5 | f.close() 6 | except: 7 | print("File {} doesn't exist".format(file_name)) -------------------------------------------------------------------------------- /06_06_counter.py: -------------------------------------------------------------------------------- 1 | config_file = "config.txt" 2 | count = 0 3 | 4 | def read_config(): 5 | global count 6 | try: 7 | f = open(config_file, "r") 8 | count = int(f.read()) 9 | f.close() 10 | except: 11 | pass 12 | 13 | def write_config(): 14 | f = open(config_file, "w") 15 | f.write(str(count)) 16 | f.close() 17 | 18 | read_config() 19 | print(count) 20 | count += 1 21 | write_config() 22 | -------------------------------------------------------------------------------- /07_01_digital_input.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | from utime import sleep 3 | 4 | switch = Pin(10, Pin.IN, Pin.PULL_UP) 5 | 6 | while True: 7 | print(switch.value()) 8 | sleep(0.1) -------------------------------------------------------------------------------- /07_02_switch_led.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | from utime import sleep 3 | 4 | switch = Pin(10, Pin.IN, Pin.PULL_UP) 5 | led = Pin(25, Pin.OUT) # For Pico W change 25 to LED see https://forums.raspberrypi.com/viewtopic.php?t=336836 6 | 7 | while True: 8 | if switch.value() == 0: 9 | led.on() 10 | sleep(10) 11 | led.off() -------------------------------------------------------------------------------- /07_03_pwm.py: -------------------------------------------------------------------------------- 1 | from machine import Pin, PWM 2 | from utime import sleep 3 | 4 | led = PWM(Pin(15)) 5 | 6 | while True: 7 | brightness_str = input("brightness (0-65534):") 8 | brightness = int(brightness_str) 9 | led.duty_u16(brightness) 10 | -------------------------------------------------------------------------------- /07_04_pwm_percent.py: -------------------------------------------------------------------------------- 1 | from machine import Pin, PWM 2 | from utime import sleep 3 | 4 | led = PWM(Pin(25)) # For Pico W change 25 to LED see https://forums.raspberrypi.com/viewtopic.php?t=336836 5 | 6 | while True: 7 | brightness_str = input("brightness (0-100):") 8 | brightness = int(int(brightness_str) * 65534 / 100) 9 | led.duty_u16(brightness) -------------------------------------------------------------------------------- /07_05_analog_input.py: -------------------------------------------------------------------------------- 1 | from machine import ADC, Pin 2 | from utime import sleep 3 | 4 | analog = ADC(28) 5 | 6 | while True: 7 | reading = analog.read_u16() 8 | print(reading) 9 | sleep(0.5) -------------------------------------------------------------------------------- /07_06_voltmeter.py: -------------------------------------------------------------------------------- 1 | from machine import ADC, Pin 2 | from utime import sleep 3 | 4 | analog = ADC(28) 5 | 6 | def volts_from_reading(reading): 7 | min_reading = 336 8 | max_reading = 65534 9 | reading_span = max_reading - min_reading 10 | volts_per_reading = 3.3 / reading_span 11 | volts = (reading - min_reading) * volts_per_reading 12 | return volts 13 | 14 | while True: 15 | reading = analog.read_u16() 16 | print(volts_from_reading(reading)) 17 | sleep(0.5) -------------------------------------------------------------------------------- /08_01_blink_led.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | from utime import sleep 3 | 4 | led = Pin(16, Pin.OUT) 5 | 6 | while True: 7 | led.on() 8 | sleep(0.5) # pause 9 | led.off() 10 | sleep(0.5) 11 | 12 | -------------------------------------------------------------------------------- /08_02_RGB.py: -------------------------------------------------------------------------------- 1 | from machine import Pin, PWM 2 | from utime import sleep 3 | 4 | red_ch = PWM(Pin(16)) 5 | green_ch = PWM(Pin(17)) 6 | blue_ch = PWM(Pin(15)) 7 | 8 | button = Pin(12, Pin.IN, Pin.PULL_UP) 9 | colors = [[255, 0, 0], [127, 127, 0],[0, 255, 0], [0, 127, 127], [0, 0, 255], [127, 0, 127]] 10 | 11 | def set_color(rgb): 12 | red_ch.duty_u16(rgb[0] * 256) 13 | green_ch.duty_u16(rgb[1] * 256) 14 | blue_ch.duty_u16(rgb[2] * 256) 15 | 16 | index = 0 17 | set_color(colors[index]) 18 | while True: 19 | if button.value() == 0: 20 | index +=1 21 | if index >= len(colors): 22 | index = 0 23 | sleep(0.2) 24 | set_color(colors[index]) 25 | -------------------------------------------------------------------------------- /08_04_servo.py: -------------------------------------------------------------------------------- 1 | from machine import Pin, PWM 2 | from utime import sleep 3 | 4 | button_up = Pin(14, Pin.IN, Pin.PULL_UP) 5 | button_down = Pin(15, Pin.IN, Pin.PULL_UP) 6 | 7 | servo = PWM(Pin(16)) 8 | servo.freq(50) # pulse every 20ms 9 | 10 | def set_angle(angle, min_pulse_us=500, max_pulse_us=2500): 11 | us_per_degree = (max_pulse_us - min_pulse_us) / 180 12 | pulse_us = us_per_degree * angle + min_pulse_us 13 | # duty 0 to 1023. At 50Hz, each duty_point is 20000/65535 = 0.305 µs/duty_point 14 | duty = int(pulse_us / 0.305) 15 | # print("angle=" + str(angle) + " pulse_us=" + str(pulse_us) + " duty=" + str(duty)) 16 | print(angle) 17 | servo.duty_u16(duty) 18 | 19 | angle = 90 20 | set_angle(90) 21 | min_angle = 10 22 | max_angle = 160 23 | 24 | while True: 25 | if button_up.value() == 0 and angle <= max_angle: 26 | angle += 1 27 | set_angle(angle) 28 | #print(angle) 29 | sleep(0.01) 30 | elif button_down.value() == 0 and angle > min_angle: 31 | angle -= 1 32 | set_angle(angle) 33 | #print(angle) 34 | sleep(0.01) -------------------------------------------------------------------------------- /09_01_interrupts.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | from utime import sleep 3 | 4 | button = Pin(12, Pin.IN, Pin.PULL_UP) 5 | 6 | def handle_button(ignore): 7 | print("BUTTON PRESSED") 8 | 9 | button.irq(handle_button, Pin.IRQ_RISING) 10 | 11 | i = 0 12 | 13 | while True: 14 | i += 1 15 | print(i) 16 | sleep(0.2) 17 | -------------------------------------------------------------------------------- /09_02_blink_timer.py: -------------------------------------------------------------------------------- 1 | from machine import Pin, Timer 2 | from utime import sleep 3 | 4 | led = Pin(25, Pin.OUT) # For Pico W change 25 to LED see https://forums.raspberrypi.com/viewtopic.php?t=336836 5 | 6 | def tick(timer): 7 | global led 8 | led.toggle() 9 | 10 | Timer().init(freq=2, mode=Timer.PERIODIC, callback=tick) 11 | 12 | x = 0 13 | while True: 14 | print(x) 15 | x += 1 16 | sleep(1.2) -------------------------------------------------------------------------------- /09_03_fast_pwm.py: -------------------------------------------------------------------------------- 1 | from machine import Pin, PWM 2 | 3 | out_pin = PWM(Pin(16)) 4 | out_pin.freq(300) 5 | 6 | out_pin.duty_u16(32768) # 50% 7 | -------------------------------------------------------------------------------- /09_04_multicore.py: -------------------------------------------------------------------------------- 1 | from machine import Pin 2 | from utime import sleep 3 | import _thread 4 | 5 | switch = Pin(10, Pin.IN, Pin.PULL_UP) 6 | 7 | def core0(): 8 | x = 0 9 | while True: 10 | x += 1 11 | print(x) 12 | sleep(1) 13 | 14 | def core1(): 15 | while True: 16 | if switch.value() == 0: 17 | print("button pressed") 18 | sleep(0.1) 19 | 20 | _thread.start_new_thread(core1, ( )) 21 | core0() 22 | -------------------------------------------------------------------------------- /10_01_thermometer.py: -------------------------------------------------------------------------------- 1 | from machine import Pin, ADC 2 | from utime import sleep 3 | 4 | temp_sensor = ADC(4) 5 | points_per_volt = 3.3 / 65535 6 | 7 | def read_temp_c(): 8 | reading = temp_sensor.read_u16() * points_per_volt 9 | temp_c = 27 - (reading - 0.706)/0.001721 10 | return temp_c 11 | 12 | while True: 13 | temp_c = read_temp_c() 14 | print(temp_c) 15 | sleep(0.5) 16 | 17 | 18 | -------------------------------------------------------------------------------- /10_02_light_meter.py: -------------------------------------------------------------------------------- 1 | from machine import ADC, Pin 2 | from utime import sleep 3 | from math import sqrt 4 | 5 | light_sensor = ADC(28) 6 | dark_reading = 200 7 | scale_factor = 2.5 8 | 9 | def read_light(): 10 | reading = light_sensor.read_u16() 11 | # print(reading) 12 | percent = int(sqrt(reading - dark_reading) / scale_factor) 13 | if percent < 0: 14 | percent = 0 15 | elif percent > 100: 16 | percent = 100 17 | return (percent) 18 | 19 | while True: 20 | light_level = read_light() 21 | print(light_level) 22 | sleep(0.2) -------------------------------------------------------------------------------- /11_01_oled.py: -------------------------------------------------------------------------------- 1 | from machine import Pin, I2C 2 | from ssd1306 import SSD1306_I2C 3 | 4 | i2c = I2C(0, sda=Pin(4), scl=Pin(5)) 5 | oled = SSD1306_I2C(128, 32, i2c) 6 | 7 | oled.fill(0) 8 | oled.rect(0, 0, 127, 31, 1) 9 | oled.text("Programming the", 5, 2, 1) 10 | oled.text("Raspberry Pi", 5, 12, 1) 11 | oled.text("Pico", 5, 22, 1) 12 | 13 | oled.show() -------------------------------------------------------------------------------- /11_02_neopixel.py: -------------------------------------------------------------------------------- 1 | import array, time 2 | from machine import Pin 3 | import rp2 4 | from random import randint 5 | 6 | NUM_LEDS = 24 7 | 8 | # Start of Magic programmable IO code 9 | @rp2.asm_pio(sideset_init=rp2.PIO.OUT_LOW, out_shiftdir=rp2.PIO.SHIFT_LEFT, autopull=True, pull_thresh=24) 10 | def ws2812(): 11 | T1 = 2 12 | T2 = 5 13 | T3 = 3 14 | wrap_target() 15 | label("bitloop") 16 | out(x, 1) .side(0) [T3 - 1] 17 | jmp(not_x, "do_zero") .side(1) [T1 - 1] 18 | jmp("bitloop") .side(1) [T2 - 1] 19 | label("do_zero") 20 | nop() .side(0) [T2 - 1] 21 | wrap() 22 | 23 | sm = rp2.StateMachine(0, ws2812, freq=8_000_000, sideset_base=Pin(22)) 24 | sm.active(1) # Start the StateMachine 25 | pixels = array.array("I", [0 for _ in range(NUM_LEDS)]) 26 | # End of Magic programmable IO code 27 | 28 | def set_led(led, red, green, blue): 29 | pixels[led] = (red << 16) + (green << 8) + blue 30 | 31 | def show(): 32 | sm.put(pixels, 8) 33 | 34 | def clear(): 35 | for i in range(NUM_LEDS): 36 | set_led(i, 0, 0, 0) 37 | show() 38 | 39 | def randomize(): 40 | clear() 41 | for i in range(NUM_LEDS): 42 | set_led(i, randint(0, 50), randint(0, 50), randint(0, 50)) 43 | show() 44 | time.sleep(0.1) 45 | 46 | clear() 47 | 48 | print("Enter the LED's number to turn it on") 49 | print("or c-clear r-randomize") 50 | while True: 51 | led_str = input("command: ") 52 | if (led_str == 'c'): 53 | clear() 54 | elif (led_str == 'r'): 55 | randomize() 56 | else: 57 | led = int(led_str) 58 | set_led(led, 50, 50, 50) # white 59 | show() 60 | -------------------------------------------------------------------------------- /11_03_oled_clock.py: -------------------------------------------------------------------------------- 1 | from machine import Pin, I2C, Timer 2 | from ssd1306 import SSD1306_I2C 3 | 4 | i2c = I2C(0, sda=Pin(4), scl=Pin(5)) 5 | oled = SSD1306_I2C(128, 32, i2c) 6 | 7 | h, m, s = (12, 0, 0) 8 | 9 | def show_time(): 10 | oled.fill(0) 11 | time_str = "{:02d}:{:02d}:{:02d}".format(h, m, s) 12 | print(time_str) 13 | oled.text(time_str, 0, 0, 1) 14 | oled.show() 15 | 16 | def tick(timer): 17 | global h, m, s 18 | s += 1 19 | if s == 60: 20 | s = 0 21 | m += 1 22 | if m == 60: 23 | m = 0 24 | h += 1 25 | if h == 24: 26 | h = 0 27 | show_time() 28 | 29 | Timer().init(freq=1, mode=Timer.PERIODIC, callback=tick) -------------------------------------------------------------------------------- /12_01_circuit_python_blink.py: -------------------------------------------------------------------------------- 1 | import board 2 | import digitalio 3 | from time import sleep 4 | 5 | led = digitalio.DigitalInOut(board.LED) 6 | led.direction = digitalio.Direction.OUTPUT 7 | 8 | while True: 9 | led.value = True 10 | sleep(0.5) 11 | led.value = False 12 | sleep(0.5) 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Simon Monk 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 | # prog_pico_ed1 2 | Code examples for my book 'Programming the Raspberry Pi Pico'. 3 | -------------------------------------------------------------------------------- /bonus_material/oled_pot.py: -------------------------------------------------------------------------------- 1 | from machine import Pin, I2C, ADC 2 | from ssd1306 import SSD1306_I2C 3 | import time 4 | 5 | i2c = I2C(0, sda=Pin(4), scl=Pin(5)) 6 | oled = SSD1306_I2C(128, 32, i2c) 7 | 8 | pushButton = Pin(17, Pin.IN, Pin.PULL_UP) 9 | analog = ADC(28) 10 | 11 | oled.fill(0) 12 | oled.rect(0, 0, 127, 31, 1) 13 | 14 | oled.text("Pico", 5, 22, 1) 15 | 16 | oled.show() 17 | 18 | while True: 19 | if pushButton.value() == 0: 20 | oled.fill(1) 21 | oled.show() 22 | time.sleep(1) 23 | reading = analog.read_u16() # 0 to 65535 24 | w = int(reading / 512) 25 | n = int(reading / 6553.5) 26 | oled.fill(0) 27 | oled.fill_rect(0, 0, w, 31, 1) 28 | oled.text(str(n), 0, 10, 0) 29 | oled.show() 30 | -------------------------------------------------------------------------------- /bonus_material/ssd1306.py: -------------------------------------------------------------------------------- 1 | # MicroPython SSD1306 OLED driver, I2C and SPI interfaces 2 | 3 | from micropython import const 4 | import framebuf 5 | 6 | 7 | # register definitions 8 | SET_CONTRAST = const(0x81) 9 | SET_ENTIRE_ON = const(0xA4) 10 | SET_NORM_INV = const(0xA6) 11 | SET_DISP = const(0xAE) 12 | SET_MEM_ADDR = const(0x20) 13 | SET_COL_ADDR = const(0x21) 14 | SET_PAGE_ADDR = const(0x22) 15 | SET_DISP_START_LINE = const(0x40) 16 | SET_SEG_REMAP = const(0xA0) 17 | SET_MUX_RATIO = const(0xA8) 18 | SET_COM_OUT_DIR = const(0xC0) 19 | SET_DISP_OFFSET = const(0xD3) 20 | SET_COM_PIN_CFG = const(0xDA) 21 | SET_DISP_CLK_DIV = const(0xD5) 22 | SET_PRECHARGE = const(0xD9) 23 | SET_VCOM_DESEL = const(0xDB) 24 | SET_CHARGE_PUMP = const(0x8D) 25 | 26 | # Subclassing FrameBuffer provides support for graphics primitives 27 | # http://docs.micropython.org/en/latest/pyboard/library/framebuf.html 28 | class SSD1306(framebuf.FrameBuffer): 29 | def __init__(self, width, height, external_vcc): 30 | self.width = width 31 | self.height = height 32 | self.external_vcc = external_vcc 33 | self.pages = self.height // 8 34 | self.buffer = bytearray(self.pages * self.width) 35 | super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB) 36 | self.init_display() 37 | 38 | def init_display(self): 39 | for cmd in ( 40 | SET_DISP | 0x00, # off 41 | # address setting 42 | SET_MEM_ADDR, 43 | 0x00, # horizontal 44 | # resolution and layout 45 | SET_DISP_START_LINE | 0x00, 46 | SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0 47 | SET_MUX_RATIO, 48 | self.height - 1, 49 | SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0 50 | SET_DISP_OFFSET, 51 | 0x00, 52 | SET_COM_PIN_CFG, 53 | 0x02 if self.width > 2 * self.height else 0x12, 54 | # timing and driving scheme 55 | SET_DISP_CLK_DIV, 56 | 0x80, 57 | SET_PRECHARGE, 58 | 0x22 if self.external_vcc else 0xF1, 59 | SET_VCOM_DESEL, 60 | 0x30, # 0.83*Vcc 61 | # display 62 | SET_CONTRAST, 63 | 0xFF, # maximum 64 | SET_ENTIRE_ON, # output follows RAM contents 65 | SET_NORM_INV, # not inverted 66 | # charge pump 67 | SET_CHARGE_PUMP, 68 | 0x10 if self.external_vcc else 0x14, 69 | SET_DISP | 0x01, 70 | ): # on 71 | self.write_cmd(cmd) 72 | self.fill(0) 73 | self.show() 74 | 75 | def poweroff(self): 76 | self.write_cmd(SET_DISP | 0x00) 77 | 78 | def poweron(self): 79 | self.write_cmd(SET_DISP | 0x01) 80 | 81 | def contrast(self, contrast): 82 | self.write_cmd(SET_CONTRAST) 83 | self.write_cmd(contrast) 84 | 85 | def invert(self, invert): 86 | self.write_cmd(SET_NORM_INV | (invert & 1)) 87 | 88 | def show(self): 89 | x0 = 0 90 | x1 = self.width - 1 91 | if self.width == 64: 92 | # displays with width of 64 pixels are shifted by 32 93 | x0 += 32 94 | x1 += 32 95 | self.write_cmd(SET_COL_ADDR) 96 | self.write_cmd(x0) 97 | self.write_cmd(x1) 98 | self.write_cmd(SET_PAGE_ADDR) 99 | self.write_cmd(0) 100 | self.write_cmd(self.pages - 1) 101 | self.write_data(self.buffer) 102 | 103 | 104 | class SSD1306_I2C(SSD1306): 105 | def __init__(self, width, height, i2c, addr=0x3C, external_vcc=False): 106 | self.i2c = i2c 107 | self.addr = addr 108 | self.temp = bytearray(2) 109 | self.write_list = [b"\x40", None] # Co=0, D/C#=1 110 | super().__init__(width, height, external_vcc) 111 | 112 | def write_cmd(self, cmd): 113 | self.temp[0] = 0x80 # Co=1, D/C#=0 114 | self.temp[1] = cmd 115 | self.i2c.writeto(self.addr, self.temp) 116 | 117 | def write_data(self, buf): 118 | self.write_list[1] = buf 119 | self.i2c.writevto(self.addr, self.write_list) 120 | 121 | 122 | class SSD1306_SPI(SSD1306): 123 | def __init__(self, width, height, spi, dc, res, cs, external_vcc=False): 124 | self.rate = 10 * 1024 * 1024 125 | dc.init(dc.OUT, value=0) 126 | res.init(res.OUT, value=0) 127 | cs.init(cs.OUT, value=1) 128 | self.spi = spi 129 | self.dc = dc 130 | self.res = res 131 | self.cs = cs 132 | import time 133 | 134 | self.res(1) 135 | time.sleep_ms(1) 136 | self.res(0) 137 | time.sleep_ms(10) 138 | self.res(1) 139 | super().__init__(width, height, external_vcc) 140 | 141 | def write_cmd(self, cmd): 142 | self.spi.init(baudrate=self.rate, polarity=0, phase=0) 143 | self.cs(1) 144 | self.dc(0) 145 | self.cs(0) 146 | self.spi.write(bytearray([cmd])) 147 | self.cs(1) 148 | 149 | def write_data(self, buf): 150 | self.spi.init(baudrate=self.rate, polarity=0, phase=0) 151 | self.cs(1) 152 | self.dc(1) 153 | self.cs(0) 154 | self.spi.write(buf) 155 | self.cs(1) -------------------------------------------------------------------------------- /ssd1306.py: -------------------------------------------------------------------------------- 1 | # MicroPython SSD1306 OLED driver, I2C and SPI interfaces 2 | 3 | from micropython import const 4 | import framebuf 5 | 6 | 7 | # register definitions 8 | SET_CONTRAST = const(0x81) 9 | SET_ENTIRE_ON = const(0xA4) 10 | SET_NORM_INV = const(0xA6) 11 | SET_DISP = const(0xAE) 12 | SET_MEM_ADDR = const(0x20) 13 | SET_COL_ADDR = const(0x21) 14 | SET_PAGE_ADDR = const(0x22) 15 | SET_DISP_START_LINE = const(0x40) 16 | SET_SEG_REMAP = const(0xA0) 17 | SET_MUX_RATIO = const(0xA8) 18 | SET_COM_OUT_DIR = const(0xC0) 19 | SET_DISP_OFFSET = const(0xD3) 20 | SET_COM_PIN_CFG = const(0xDA) 21 | SET_DISP_CLK_DIV = const(0xD5) 22 | SET_PRECHARGE = const(0xD9) 23 | SET_VCOM_DESEL = const(0xDB) 24 | SET_CHARGE_PUMP = const(0x8D) 25 | 26 | # Subclassing FrameBuffer provides support for graphics primitives 27 | # http://docs.micropython.org/en/latest/pyboard/library/framebuf.html 28 | class SSD1306(framebuf.FrameBuffer): 29 | def __init__(self, width, height, external_vcc): 30 | self.width = width 31 | self.height = height 32 | self.external_vcc = external_vcc 33 | self.pages = self.height // 8 34 | self.buffer = bytearray(self.pages * self.width) 35 | super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB) 36 | self.init_display() 37 | 38 | def init_display(self): 39 | for cmd in ( 40 | SET_DISP | 0x00, # off 41 | # address setting 42 | SET_MEM_ADDR, 43 | 0x00, # horizontal 44 | # resolution and layout 45 | SET_DISP_START_LINE | 0x00, 46 | SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0 47 | SET_MUX_RATIO, 48 | self.height - 1, 49 | SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0 50 | SET_DISP_OFFSET, 51 | 0x00, 52 | SET_COM_PIN_CFG, 53 | 0x02 if self.width > 2 * self.height else 0x12, 54 | # timing and driving scheme 55 | SET_DISP_CLK_DIV, 56 | 0x80, 57 | SET_PRECHARGE, 58 | 0x22 if self.external_vcc else 0xF1, 59 | SET_VCOM_DESEL, 60 | 0x30, # 0.83*Vcc 61 | # display 62 | SET_CONTRAST, 63 | 0xFF, # maximum 64 | SET_ENTIRE_ON, # output follows RAM contents 65 | SET_NORM_INV, # not inverted 66 | # charge pump 67 | SET_CHARGE_PUMP, 68 | 0x10 if self.external_vcc else 0x14, 69 | SET_DISP | 0x01, 70 | ): # on 71 | self.write_cmd(cmd) 72 | self.fill(0) 73 | self.show() 74 | 75 | def poweroff(self): 76 | self.write_cmd(SET_DISP | 0x00) 77 | 78 | def poweron(self): 79 | self.write_cmd(SET_DISP | 0x01) 80 | 81 | def contrast(self, contrast): 82 | self.write_cmd(SET_CONTRAST) 83 | self.write_cmd(contrast) 84 | 85 | def invert(self, invert): 86 | self.write_cmd(SET_NORM_INV | (invert & 1)) 87 | 88 | def show(self): 89 | x0 = 0 90 | x1 = self.width - 1 91 | if self.width == 64: 92 | # displays with width of 64 pixels are shifted by 32 93 | x0 += 32 94 | x1 += 32 95 | self.write_cmd(SET_COL_ADDR) 96 | self.write_cmd(x0) 97 | self.write_cmd(x1) 98 | self.write_cmd(SET_PAGE_ADDR) 99 | self.write_cmd(0) 100 | self.write_cmd(self.pages - 1) 101 | self.write_data(self.buffer) 102 | 103 | 104 | class SSD1306_I2C(SSD1306): 105 | def __init__(self, width, height, i2c, addr=0x3C, external_vcc=False): 106 | self.i2c = i2c 107 | self.addr = addr 108 | self.temp = bytearray(2) 109 | self.write_list = [b"\x40", None] # Co=0, D/C#=1 110 | super().__init__(width, height, external_vcc) 111 | 112 | def write_cmd(self, cmd): 113 | self.temp[0] = 0x80 # Co=1, D/C#=0 114 | self.temp[1] = cmd 115 | self.i2c.writeto(self.addr, self.temp) 116 | 117 | def write_data(self, buf): 118 | self.write_list[1] = buf 119 | self.i2c.writevto(self.addr, self.write_list) 120 | 121 | 122 | class SSD1306_SPI(SSD1306): 123 | def __init__(self, width, height, spi, dc, res, cs, external_vcc=False): 124 | self.rate = 10 * 1024 * 1024 125 | dc.init(dc.OUT, value=0) 126 | res.init(res.OUT, value=0) 127 | cs.init(cs.OUT, value=1) 128 | self.spi = spi 129 | self.dc = dc 130 | self.res = res 131 | self.cs = cs 132 | import time 133 | 134 | self.res(1) 135 | time.sleep_ms(1) 136 | self.res(0) 137 | time.sleep_ms(10) 138 | self.res(1) 139 | super().__init__(width, height, external_vcc) 140 | 141 | def write_cmd(self, cmd): 142 | self.spi.init(baudrate=self.rate, polarity=0, phase=0) 143 | self.cs(1) 144 | self.dc(0) 145 | self.cs(0) 146 | self.spi.write(bytearray([cmd])) 147 | self.cs(1) 148 | 149 | def write_data(self, buf): 150 | self.spi.init(baudrate=self.rate, polarity=0, phase=0) 151 | self.cs(1) 152 | self.dc(1) 153 | self.cs(0) 154 | self.spi.write(buf) 155 | self.cs(1) --------------------------------------------------------------------------------