├── 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 |
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 |
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)
--------------------------------------------------------------------------------