├── LICENSE ├── README.md ├── other downloads ├── Animatronic_Head_template.pdf ├── Animatronic_Head_template.png ├── Animatronic_Head_template.svg ├── Project 5 - guitar.pdf ├── Project 5 - guitar.png ├── Project 5 - guitar.svg └── bitbot_enhanced_NP_dfu.hex └── python ├── Ch_05_Acceleration_Display.py ├── Experiment_01.py ├── Experiment_02.py ├── Experiment_04.py ├── Experiment_05.py ├── Experiment_06.py ├── Experiment_07.py ├── Experiment_08.py ├── Experiment_09.py ├── Experiment_10.py ├── Experiment_11.py ├── Experiment_12.py ├── Lie Detector.py ├── Reaction_Timer.py ├── TimeSpeakerTest.py ├── analog voltage plotter.py ├── ch_02_Doorbell.py ├── ch_02_Shoutometer.py ├── ch_02_tune.py ├── ch_03_Magic_Mirror.py ├── ch_04_Compass.py ├── ch_04_Magnetic_Alarm.py ├── ch_05_Toothbrush_Monitor.py ├── ch_06_Animatronic_Head.py ├── ch_07_Binary_Clock.py ├── ch_07_Talking_Clock.py ├── ch_08_Lie_Detector.py ├── ch_09_Logger.py ├── ch_09_Plant_Waterer.py ├── ch_10_Wireless_Doorbell.py ├── log_acceleration.py └── read_temperature_mm_sensor.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 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 | # micro:bit for the Mad Scientist 2 | 3 | Code for my book "micro:bit for the Mad Scientist" 4 | 5 | Some of the programs in this book get pretty long and complex, and typing them in is not something that the Mad Scientist in you is likely to be keen to do. 6 | 7 | All the Block code is published on the makecode website and shared by a short URL that will open your own copy of the Block code project in your browser. Here are the short URLs for the book's projects and experiments. Just click on them to open the project. Once the project is open, you can click on _Download_ to create the HEX file that then needs to be dragged onto your micro:bit. If you feel like editing the Block code to try your own ideas out, then click on the _Edit_ button. 8 | 9 | ## Projects 10 | 11 | ### Chapter 2 12 | [Musical Doorbell](https://makecode.microbit.org/_Rb6MsFdrUP92) 13 | 14 | [Shout-O-Meter](https://makecode.microbit.org/_0drcfrM7kUE6) 15 | 16 | 17 | 18 | ### Chapter 3 19 | [Automatic Night-Light](https://makecode.microbit.org/_9xwYd25hfVr7) 20 | 21 | [Light Guitar](https://makecode.microbit.org/_b0UHfudwXK3e) 22 | 23 | [Magic Mirror](https://makecode.microbit.org/_iDwD6ccdRe2x) 24 | 25 | 26 | ### Chapter 4 27 | 28 | [Compass](https://makecode.microbit.org/_f4M1s1bK4gre) 29 | 30 | [Magnetic Alarm](https://makecode.microbit.org/_P5DF8HMab6cA) 31 | 32 | 33 | ### Chapter 5 34 | 35 | [Toothbrushing Monitor](https://makecode.microbit.org/_Dh7VJw3Hz1Wx) 36 | 37 | [Acceleration Display](https://makecode.microbit.org/_Vu8cdtPzpbrq) 38 | 39 | ### Chapter 6 and 7 don't have any Blocks code 40 | 41 | ### Chapter 8 42 | 43 | [Lie Detector](https://makecode.microbit.org/_aM8WTLcEJ6qe) 44 | 45 | 46 | ### Chapter 9 47 | 48 | [Plant Waterer](https://makecode.microbit.org/_VrVemL7Kx2FP) 49 | 50 | 51 | ### Chapter 10 52 | 53 | [Wireless Doorbell](https://makecode.microbit.org/_hvLdHC5TqbXa) 54 | 55 | [Rover](https://makecode.microbit.org/_FTPcwRg3CPjV) 56 | 57 | [Rover Controller](https://makecode.microbit.org/_L69HYaPvU53t) 58 | 59 | 60 | 61 | ## Experiments 62 | 63 | ### Chapter 2 64 | 65 | [Experiment 1: Generating Sounds](https://makecode.microbit.org/_dk75wcLE263E) 66 | 67 | There is no block code for Experiment 2 68 | 69 | 70 | ### Chapter 3 71 | 72 | [Experiment 3: Sensing Light](https://makecode.microbit.org/_WzAc3vfXcKg1) 73 | 74 | 75 | ### Chapter 4 76 | 77 | [Experiment 4: Magnetic Fields](https://makecode.microbit.org/_5HhbF218K6j8) 78 | 79 | [Link for Google Sheet spreadsheet for Experiment 4)(https://docs.google.com/spreadsheets/d/1qSybk116Zv5qyFtHL0l5jVkicrFcodrefVTEGUbmIYk/edit?usp=sharing) 80 | 81 | 82 | ### Chapter 5 83 | 84 | [Experiment 5: Gestures](https://makecode.microbit.org/_hX3Cx5AFm2X7) 85 | 86 | There is no block code for Experiments 6 and 7 87 | 88 | 89 | ### Chapter 6 90 | 91 | [Experiment 8: Servomotors](https://makecode.microbit.org/_RsRRuvUH89kL) 92 | 93 | There is no block code for experiments 7 to 12. 94 | 95 | 96 | ### Chapter 10 97 | 98 | [Experiment 12: Radio Range](https://makecode.microbit.org/_DJFddiLyVHLq) 99 | 100 | 101 | 102 | 103 | ## Cloning and Downloading 104 | 105 | If you are an expert developer, used to using git, then you can clone the entire project into your computer. However, if you just want to get the Python code, you can download it as a ZIP file. To do this, click on the green _Clone or download_ button and select Download ZIP. 106 | 107 | 108 | ## Copying the Downloaded MicroPython Files 109 | 110 | Find the ZIP file (mbms-master.zip) in your downloads area and then extract all the files from it. This will create a directory called 'mbms-master'. Within this directory you will find another directory called 'python' and within this, you will find all of the MicroPython programs for the book as a separate file, each with the extension .py. 111 | 112 | Unfortunately Mu is not associated with the file type of .py, so to make it super easy to find the programs for the book when using Mu, I suggest that you copy all the MicroPython programs from the download into the directory where Mu normally expects to find its programs. By default this is a directory called mu_code within your home directory. 113 | 114 | 115 | ## Other Downloads 116 | 117 | You may also have noticed that there is a directory here called 'other downloads'. This directory contains other files for projects, such as drawing templates. 118 | -------------------------------------------------------------------------------- /other downloads/Animatronic_Head_template.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simonmonk/mbms/6763faa870d1a16f272b3eade70b433ed3df0e51/other downloads/Animatronic_Head_template.pdf -------------------------------------------------------------------------------- /other downloads/Animatronic_Head_template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simonmonk/mbms/6763faa870d1a16f272b3eade70b433ed3df0e51/other downloads/Animatronic_Head_template.png -------------------------------------------------------------------------------- /other downloads/Animatronic_Head_template.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 42 | 44 | 45 | 47 | image/svg+xml 48 | 50 | 51 | 52 | 53 | 54 | 59 | 66 | 72 | 76 | 82 | 88 | 94 | 100 | 106 | 107 | 111 | 117 | 123 | 129 | 135 | 141 | 142 | 146 | 153 | 157 | 163 | 169 | 170 | 171 | 177 | 180 | 187 | 194 | 201 | 208 | 215 | 222 | 223 | 226 | 232 | 238 | 239 | 247 | 252 | 257 | 262 | 267 | 268 | 269 | -------------------------------------------------------------------------------- /other downloads/Project 5 - guitar.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simonmonk/mbms/6763faa870d1a16f272b3eade70b433ed3df0e51/other downloads/Project 5 - guitar.pdf -------------------------------------------------------------------------------- /other downloads/Project 5 - guitar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simonmonk/mbms/6763faa870d1a16f272b3eade70b433ed3df0e51/other downloads/Project 5 - guitar.png -------------------------------------------------------------------------------- /other downloads/Project 5 - guitar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 39 | 41 | 42 | 44 | image/svg+xml 45 | 47 | 48 | 49 | 50 | 51 | 56 | 61 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /python/Ch_05_Acceleration_Display.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | from math import sqrt 3 | 4 | while True: 5 | x, y, z = accelerometer.get_values() 6 | acc = sqrt(x*x + y*y + z*z) 7 | y = int(2 + (acc - 1000) / 100) 8 | display.clear() 9 | if y < 0: 10 | y = 0 11 | if y > 4: 12 | y = 4 13 | for x in range(0, 5): 14 | display.set_pixel(x, y, 9) -------------------------------------------------------------------------------- /python/Experiment_01.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | import music 3 | 4 | while True: 5 | if button_a.was_pressed(): 6 | music.pitch(262, 1000) -------------------------------------------------------------------------------- /python/Experiment_02.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | import speech 3 | 4 | while True: 5 | if button_a.was_pressed(): 6 | speech.say("Mad Scientists love micro bits") -------------------------------------------------------------------------------- /python/Experiment_04.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | 3 | while True: 4 | display.scroll(str(int(compass.get_field_strength() / 1300))) -------------------------------------------------------------------------------- /python/Experiment_05.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | 3 | while True: 4 | if accelerometer.was_gesture('shake'): 5 | display.show(Image.HAPPY) 6 | sleep(500) 7 | display.clear() -------------------------------------------------------------------------------- /python/Experiment_06.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | from math import sqrt 3 | 4 | while True: 5 | x, y, z = accelerometer.get_values() 6 | net = sqrt(x*x + y*y + z*z) 7 | all = (x, y, z, net) 8 | print(all) 9 | sleep(100) 10 | 11 | 12 | 13 | 23 16.5 2 14 | 15 | -------------------------------------------------------------------------------- /python/Experiment_07.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | from math import sqrt 3 | import os 4 | 5 | filename = 'data.txt' 6 | 7 | recording = False 8 | display.show(Image.NO) 9 | 10 | while True: 11 | if button_a.was_pressed(): 12 | recording = not recording 13 | if recording: 14 | display.show(Image.YES) 15 | try: 16 | os.remove(filename) 17 | except: 18 | pass 19 | fs = open(filename, 'w') 20 | else: 21 | display.show(Image.NO) 22 | fs.close() 23 | if recording: 24 | x, y, z = accelerometer.get_values() 25 | net = sqrt(x*x + y*y + z*z) 26 | fs.write(str(net)) 27 | fs.write('\n') 28 | sleep(10) -------------------------------------------------------------------------------- /python/Experiment_08.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | 3 | def set_servo_angle(pin, angle): 4 | duty = 26 + (angle * 102) / 180 5 | pin.write_analog(duty) 6 | 7 | angle = 90 8 | set_servo_angle(pin2, angle) 9 | 10 | while True: 11 | if button_a.was_pressed() and angle >= 10: 12 | angle -= 10 13 | set_servo_angle(pin2, angle) 14 | if button_b.was_pressed() and angle <= 170: 15 | angle += 10 16 | set_servo_angle(pin2, angle) 17 | 18 | if button_a.is_pressed() and button_b.is_pressed(): 19 | display.scroll(str(angle)) -------------------------------------------------------------------------------- /python/Experiment_09.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | 3 | seconds = 0 4 | last_time = 0 5 | 6 | while True: 7 | now = running_time() 8 | elapsed_ms = now - last_time 9 | if elapsed_ms >= 1000: 10 | seconds += 1 11 | last_time = now 12 | if button_a.was_pressed(): 13 | display.scroll(str(seconds)) 14 | if button_b.was_pressed(): 15 | seconds = 0 16 | display.show("0") 17 | sleep(100) 18 | display.clear() -------------------------------------------------------------------------------- /python/Experiment_10.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | import random 3 | 4 | n = 5 5 | 6 | def run_full_test(): 7 | print("TEST 1 - USING your hand") 8 | t_hand = run_test() 9 | print("The average time using your hand was " + str(t_hand) + " ms") 10 | print("Now repeat the test for your foot") 11 | t_foot = run_test() 12 | print("The average time using your foot was " + str(t_foot) + " ms") 13 | d_hand = int(input("Enter the distance from the back of your neck to your fingers in cm: ")) 14 | d_foot = int(input("Enter the distance from the back of your neck to your toes in cm: ")) 15 | thinking_time = (d_hand * t_foot - d_foot * t_hand) / (d_hand - d_foot) 16 | transmission_speed = 10 * (t_foot - thinking_time) / d_foot 17 | print("Thinking time (ms): " + str(thinking_time)) 18 | print("Transmission speed (m/s): " + str(transmission_speed)) 19 | 20 | def run_test(): 21 | print("Hold the switch down while cross is showing.") 22 | print("Release momentarily when the display blanks.") 23 | print("Repeat " + str(n) + " times.") 24 | input("Press ENTER when ready to start the test") 25 | total = 0 26 | for i in range(0, n): 27 | t = get_reaction_time() 28 | if t > 10: 29 | print(t) 30 | total += t 31 | else: 32 | print("You let go too soon") 33 | return total / n 34 | 35 | def get_reaction_time(): 36 | display.show(Image.NO) 37 | sleep(random.randint(3000, 7000)) 38 | display.clear() 39 | t0 = running_time() 40 | while pin5.read_digital() == False: # Button A down 41 | pass 42 | t1 = running_time() 43 | t = t1 - t0 44 | return t 45 | 46 | run_full_test() 47 | 48 | -------------------------------------------------------------------------------- /python/Experiment_11.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | import radio 3 | 4 | busy = False 5 | last_busy_flip = 0 6 | busy_period = 600000 7 | last_log_time = 0 8 | log_period = 20000 9 | 10 | while True: 11 | if busy: 12 | display.on() 13 | radio.on() 14 | display.show("Busy") 15 | else: 16 | display.off() 17 | radio.off() 18 | now = running_time() 19 | if now > last_busy_flip + busy_period: 20 | busy = not busy 21 | last_busy_flip = now 22 | now = running_time() 23 | if now > last_log_time + log_period: 24 | print((temperature(), busy * 10)) 25 | last_log_time = now 26 | -------------------------------------------------------------------------------- /python/Experiment_12.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | import radio 3 | 4 | radio.on() 5 | radio.config(power=7, group=1) 6 | 7 | while True: 8 | if button_a.was_pressed(): 9 | radio.send("test") 10 | display.show(Image.ARROW_N) 11 | sleep(1000) 12 | display.clear() 13 | message = radio.receive() 14 | if message == 'test': 15 | display.show(Image.YES) 16 | sleep(1000) 17 | display.clear() -------------------------------------------------------------------------------- /python/Lie Detector.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | 3 | while True: 4 | print((pin0.read_analog(),)) 5 | sleep(200) -------------------------------------------------------------------------------- /python/Reaction_Timer.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | 3 | elapsed_seconds = 0 4 | seconds = 0 5 | last_time = 0 6 | 7 | while True: 8 | now = running_time() 9 | elapsed_ms = now - last_time 10 | if elapsed_ms >= 1000: 11 | seconds += 1 12 | last_time = now 13 | if button_a.was_pressed(): 14 | display.scroll(str(seconds)) 15 | if button_b.was_pressed(): 16 | seconds = 0 17 | display.show("0") 18 | sleep(100) 19 | display.clear() -------------------------------------------------------------------------------- /python/TimeSpeakerTest.py: -------------------------------------------------------------------------------- 1 | import speech 2 | 3 | digits = ["no", "1", "2", "3", "4", "5", "6", "7", "8", "9", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nienteen"] 4 | tens = ["no", "no", "twenty", "thirty", "forty", "fifty"] 5 | 6 | preamble = "The time is " 7 | am = "aye em" 8 | pm = "pee em" 9 | 10 | minutes = 21 11 | hours = 16 12 | 13 | def speak_the_time(): 14 | h = hours 15 | am_pm = am 16 | if h > 12: 17 | h = h - 12 18 | am_pm = pm 19 | if minutes == 0: 20 | speech.say(preamble + digits[h] + " " + am_pm + " exactly") 21 | else: 22 | if minutes < 20: 23 | speech.say(preamble + digits[h] + " " + digits[minutes] + " " + am_pm) 24 | else: 25 | mins_tens = int(minutes / 10) 26 | mins_units = minutes % 10 27 | speech.say(preamble + digits[h] + " " + tens[mins_tens] + " " + digits[mins_units] + " " + am_pm) 28 | speak_the_time() -------------------------------------------------------------------------------- /python/analog voltage plotter.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | 3 | while True: 4 | print((pin2.read_analog(),)) 5 | sleep(100) -------------------------------------------------------------------------------- /python/ch_02_Doorbell.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | import music 3 | 4 | while True: 5 | if button_a.was_pressed(): 6 | music.play(music.ENTERTAINER) 7 | elif button_b.was_pressed(): 8 | music.play(music.FUNERAL) -------------------------------------------------------------------------------- /python/ch_02_Shoutometer.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | 3 | def sound_level(): 4 | # find max of 10 readings 5 | max_level = 0 6 | for i in range(0, 10): 7 | level = (pin0.read_analog() - 511) / 100 8 | if level > max_level: 9 | max_level = level 10 | return max_level 11 | 12 | def bargraph(a): 13 | display.clear() 14 | for y in range(0, 5): 15 | if a > y: 16 | for x in range(0, 5): 17 | display.set_pixel(x, 4-y, 9) 18 | 19 | while True: 20 | bargraph(sound_level()) 21 | sleep(10) -------------------------------------------------------------------------------- /python/ch_02_tune.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | import music 3 | 4 | notes = ['A4:4', 'A', 'A', 'F:2', 'C5:2', 'A4:4', 'F:2', 'C5:2', 'A4:4'] 5 | 6 | while True: 7 | if button_a.was_pressed(): 8 | music.play(notes) -------------------------------------------------------------------------------- /python/ch_03_Magic_Mirror.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | import neopixel, random 3 | 4 | leds = neopixel.NeoPixel(pin0, 30) 5 | 6 | while True: 7 | led = random.randint(0, 29) 8 | color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) 9 | leds[led] = color 10 | leds.show() 11 | sleep(5) -------------------------------------------------------------------------------- /python/ch_04_Compass.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | 3 | while True: 4 | heading = compass.heading() 5 | if heading > 10 and heading < 180: 6 | display.show(Image.ARROW_W) 7 | elif heading >= 180 and heading < 350: 8 | display.show(Image.ARROW_E) 9 | else: 10 | display.show(Image.ARROW_N) 11 | 12 | if button_a.was_pressed(): 13 | compass.calibrate() 14 | -------------------------------------------------------------------------------- /python/ch_04_Magnetic_Alarm.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | import music 3 | 4 | while True: 5 | if compass.get_field_strength() < 160000: 6 | music.pitch(523, 1000) 7 | -------------------------------------------------------------------------------- /python/ch_05_Toothbrush_Monitor.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | from math import sqrt 3 | 4 | strokes_per_point = 50 5 | old_mg = 0 6 | count = 0 7 | change_in_mg = 0 8 | score = 0 9 | mg = 0 10 | display.show(str(score)) 11 | 12 | while True: 13 | x, y, z = accelerometer.get_values() 14 | mg = sqrt(x*x + y*y + z*z) 15 | change_in_mg = mg - old_mg 16 | old_mg = mg 17 | if change_in_mg > 800: 18 | count += 1 19 | if count > strokes_per_point: 20 | score += 1 21 | display.show(str(score)) 22 | count = 0 23 | if score > 9: 24 | display.show(Image.HAPPY) -------------------------------------------------------------------------------- /python/ch_06_Animatronic_Head.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | import random, speech, radio 3 | 4 | eye_angles = [50, 140, 60, 90, 140] 5 | 6 | radio.off() 7 | 8 | sentences = [ 9 | "Hello my name is Mike", 10 | "What is your name", 11 | "I am looking at you", 12 | "Exterminate exterminate exterminate", 13 | "Number Five is alive", 14 | "I cant do that Dave", 15 | "daisee daisee give me your answer do" 16 | ] 17 | 18 | lips0 = Image("00000:" 19 | "00000:" 20 | "99999:" 21 | "00000:" 22 | "00000") 23 | 24 | lips1 = Image("00000:" 25 | "00900:" 26 | "99099:" 27 | "00900:" 28 | "00000") 29 | 30 | lips2 = Image("00000:" 31 | "09990:" 32 | "99099:" 33 | "09990:" 34 | "00000") 35 | 36 | lips = [lips0, lips1, lips2] 37 | 38 | def set_servo_angle(pin, angle): 39 | duty = 26 + (angle * 51) / 90 40 | pin.write_analog(duty) 41 | 42 | def speak(sentence): 43 | words = sentence.split() 44 | for i in range(0, len(words)): 45 | display.show(random.choice(lips)) 46 | speech.say(words[i]) 47 | display.show(lips0) 48 | 49 | def act(): 50 | set_servo_angle(pin2, random.choice(eye_angles)) 51 | sleep(300) 52 | speak(random.choice(sentences)) 53 | set_servo_angle(pin2, 90) 54 | 55 | 56 | base_z = 0 57 | 58 | while True: 59 | new_z = abs(accelerometer.get_z()) 60 | if abs(new_z - base_z) > 20: 61 | base_z = new_z 62 | act() 63 | if random.randint(0, 1000) == 0: # say something 1 time in 1000 64 | act() 65 | sleep(200) 66 | -------------------------------------------------------------------------------- /python/ch_07_Binary_Clock.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | 3 | 4 | # hhhhh 5 | # m 6 | # mmmmm 7 | # s 8 | # sssss 9 | 10 | sec_leds = [[4, 4], [3, 4], [2, 4], [1, 4], [0, 4], [0, 3]] 11 | min_leds = [[4, 2], [3, 2], [2, 2], [1, 2], [0, 2], [0, 1]] 12 | hour_leds = [[4, 0], [3, 0], [2, 0], [1, 0], [0, 0]] 13 | 14 | hours = 16 15 | minutes = 46 16 | seconds = 0 17 | 18 | adjust = -10 19 | 20 | def display_binary(value, num_bits, leds): 21 | v = value 22 | for i in range(0, num_bits): 23 | v_bit = v % 2 24 | display.set_pixel(leds[i][0], leds[i][1], int(v_bit * 9)) 25 | v = int(v / 2) 26 | 27 | last_time = 0 28 | tick = 1000 + adjust 29 | 30 | def update_time(): 31 | global hours, minutes, seconds 32 | seconds += 1 33 | if seconds > 59: 34 | seconds = 0 35 | minutes += 1 36 | if minutes > 59: 37 | minutes = 0 38 | hours += 1 39 | if hours > 23: 40 | hours = 0 41 | 42 | def display_time(): 43 | display_binary(seconds, 6, sec_leds) 44 | display_binary(minutes, 6, min_leds) 45 | display_binary(hours, 5, hour_leds) 46 | 47 | while True: 48 | if button_a.is_pressed(): 49 | tick = 10 50 | else: 51 | tick = 1000 + adjust 52 | now = running_time() 53 | elapsed_ms = now - last_time 54 | if elapsed_ms >= tick: 55 | update_time() 56 | display_time() 57 | last_time = now -------------------------------------------------------------------------------- /python/ch_07_Talking_Clock.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | import speech 3 | 4 | digits = ["no", "1", "2", "3", "4", "5", "6", "7", "8", "9", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nienteen"] 5 | tens = ["no", "no", "twenty", "thirty", "forty", "fifty"] 6 | 7 | preamble = "The time is " 8 | am = "aye em" 9 | pm = "pee em" 10 | 11 | hours = 8 12 | minutes = 26 13 | seconds = 0 14 | adjust = -10 15 | 16 | last_time = 0 17 | tick = 1000 + adjust 18 | 19 | def update_time(elapsed_seconds): 20 | global hours, minutes, seconds 21 | seconds += elapsed_seconds 22 | if seconds > 59: 23 | seconds = elapsed_seconds - 1 24 | minutes += 1 25 | if minutes > 59: 26 | minutes = 0 27 | hours += 1 28 | speak_the_time() 29 | if hours > 23: 30 | hours = 0 31 | 32 | def speak_the_time(): 33 | h = hours 34 | am_pm = am 35 | if h >= 12: 36 | am_pm = pm 37 | if h > 12: 38 | h = h - 12 39 | if minutes == 0: 40 | # The time is twelve pm exactly 41 | speech.say(preamble + digits[h] + " " + am_pm + " exactly") 42 | else: 43 | if minutes < 10: 44 | # The time is twelve o four pm 45 | speech.say(preamble + digits[h] + " o " + digits[minutes] + " " + am_pm) 46 | elif minutes < 20: 47 | # The time is twelve eighteen pm 48 | speech.say(preamble + digits[h] + " " + digits[minutes] + " " + am_pm) 49 | else: 50 | mins_tens = int(minutes / 10) 51 | mins_units = minutes % 10 52 | if mins_units == 0: 53 | # The time is twelve twenty pm 54 | speech.say(preamble + digits[h] + " " + tens[mins_tens] + " " + am_pm) 55 | else: 56 | # The time is twelve twenty four pm 57 | speech.say(preamble + digits[h] + " " + tens[mins_tens] + " " + digits[mins_units] + " " + am_pm) 58 | 59 | def blink(): 60 | display.show(Image.HEART) 61 | sleep(100) 62 | display.clear() 63 | 64 | while True: 65 | if button_b.is_pressed(): 66 | speak_the_time() 67 | now = running_time() 68 | elapsed_ms = now - last_time 69 | if elapsed_ms >= tick: 70 | elapsed_seconds = int(elapsed_ms / tick) 71 | update_time(elapsed_seconds) 72 | blink() 73 | last_time = now 74 | 75 | -------------------------------------------------------------------------------- /python/ch_08_Lie_Detector.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | 3 | pin2.set_pull(pin2.PULL_UP) 4 | baseline = pin2.read_analog() 5 | 6 | while True: 7 | if button_a.was_pressed(): 8 | baseline = pin2.read_analog() 9 | reading = pin2.read_analog() 10 | change = int((reading - baseline) / 10) 11 | if (change > 2): 12 | change = 2 13 | if (change < -2): 14 | change = -2 15 | display.clear() 16 | display.set_pixel(2, 2 + change, 9) -------------------------------------------------------------------------------- /python/ch_09_Logger.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | from math import log 3 | import os 4 | 5 | sample_period = 60000 6 | filename = 'data.txt' 7 | temp_pin = pin1 8 | light_pin = pin2 9 | 10 | last_sample_time = 0 11 | recording = False 12 | display.show(Image.NO) 13 | 14 | def read_c(): 15 | r0 = 100000.0 16 | r2 = 100000.0 17 | b = 4250.0 18 | v33 = 3.3 # actually result is independent of this value 19 | V = temp_pin.read_analog() * v33 / 1023.0 20 | R = r2 * (v33 - V) / V 21 | t0 = 273.15 # 0 deg C in K 22 | t25 = t0 + 25.0 # 25 deg C in K 23 | # Steinhart-Hart equation - Google it 24 | inv_T = 1/t25 + 1/b * log(R/r0) 25 | T = (1/inv_T - t0) 26 | return round(T, 1) 27 | 28 | def read_f(self): 29 | return read_c() * 9/5 + 32 30 | 31 | while True: 32 | if button_a.was_pressed(): 33 | recording = not recording 34 | if recording: 35 | display.show(".") 36 | try: 37 | os.remove(filename) 38 | except: 39 | pass 40 | fs = open(filename, 'w') 41 | else: 42 | display.show(Image.NO) 43 | fs.close() 44 | now = running_time() 45 | if now > last_sample_time + sample_period: 46 | last_sample_time = now 47 | if recording: 48 | temp = read_c() 49 | light = light_pin.read_analog() 50 | fs.write(str(temp) + "," + str(light)) 51 | fs.write('\n') 52 | -------------------------------------------------------------------------------- /python/ch_09_Plant_Waterer.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | 3 | dryness = 0 4 | dry_threshold = 500 5 | on_time_ms = 10000 6 | check_period_ms = 3600000 7 | dont_check_until = 0 8 | 9 | def water_the_plant(): 10 | pin0.write_digital(1) 11 | display.show(Image.ARROW_S) 12 | sleep(on_time_ms) 13 | pin0.write_digital(0) 14 | 15 | def check_dryness(): 16 | global dryness 17 | pin1.write_digital(1) 18 | dryness = pin2.read_analog() 19 | pin1.write_digital(1) 20 | 21 | def bargraph(a): 22 | display.clear() 23 | for y in range(0, 5): 24 | if a > y: 25 | for x in range(0, 5): 26 | display.set_pixel(x, 4-y, 9) 27 | 28 | while True: 29 | if button_a.was_pressed(): 30 | check_dryness() 31 | display.scroll(str(dryness)) 32 | bargraph(dryness / 200) 33 | if button_b.was_pressed(): 34 | water_the_plant() 35 | check_dryness() 36 | bargraph(dryness / 200) 37 | if running_time() > dont_check_until: 38 | check_dryness() 39 | if dryness > dry_threshold: 40 | water_the_plant() 41 | dont_check_until = running_time() + check_period_ms 42 | bargraph(dryness / 200) -------------------------------------------------------------------------------- /python/ch_10_Wireless_Doorbell.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | import radio, music 3 | 4 | radio.on() 5 | radio.config(power=7, group=1) 6 | 7 | def send_message(message): 8 | radio.send(message) 9 | display.show(Image.ARROW_N) 10 | sleep(1000) 11 | display.clear() 12 | 13 | while True: 14 | if button_a.was_pressed(): 15 | send_message("db1") 16 | if button_b.was_pressed(): 17 | send_message("db2") 18 | message = radio.receive() 19 | if message == 'db1': 20 | music.play(music.ENTERTAINER) 21 | elif message == 'db2': 22 | music.play(music.FUNERAL) -------------------------------------------------------------------------------- /python/log_acceleration.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | from math import sqrt 3 | 4 | while True: 5 | x, y, z = accelerometer.get_values() 6 | net = sqrt(x*x + y*y + z*z) 7 | print((net,)) 8 | sleep(100) -------------------------------------------------------------------------------- /python/read_temperature_mm_sensor.py: -------------------------------------------------------------------------------- 1 | from microbit import * 2 | from math import log 3 | 4 | temp_pin = pin0 5 | 6 | def read_c(): 7 | r0 = 100000.0 8 | r2 = 100000.0 9 | b = 4250.0 10 | v33 = 3.3 # actually result is independent of this value 11 | V = temp_pin.read_analog() * v33 / 1023.0 12 | R = r2 * (v33 - V) / V 13 | t0 = 273.15 # 0 deg C in K 14 | t25 = t0 + 25.0 # 25 deg C in K 15 | # Steinhart-Hart equation - Google it 16 | inv_T = 1/t25 + 1/b * log(R/r0) 17 | T = (1/inv_T - t0) 18 | return T 19 | 20 | def read_f(self): 21 | return read_c() * 9/5 + 32 22 | 23 | while True: 24 | print(read_c()) 25 | sleep(1000) --------------------------------------------------------------------------------