MicroPython-micro-bit
Create Python Module
This is an advanced tutorial for the official BBC micro:bit V2 where we create a custom interactive talking statecapital.py module and freeze this custom Python educational chatbot into the firmware where students interact with the bot in the Python REPL to help them learn the respective capitol to each of the 50 states.
Mission Statement
This tutorial is not targeted toward beginners so I want to be very clear about this to not discourage anyone who has a passion for the new micro:bit V2. If you are a beginner I am excited to help inspire and take you along the journey as I have a very detailed FREE step-by-step lesson series HERE.
This tutorial is designed for professional Python Developers who are looking to help others add functionality into their micro:bit V2 to ultimately be called by Python in an individual main.py file. This is a step-by-step tutorial for advanced developers who know Python to help educators build out their own custom firmware for educational purposes so that they can take advantage of the robust scalability of the Python language in their custom firmware such that their students can have these modules within the build to help accelerate their educational growth.
We will be using Vistual Studio Code IDE in this tutorial. If you are unfamiliar with Visual Studio Code please watch this video HERE.
I call upon all of YOU, leaders in the Python microcontroller domain, to help drive this project forward so that others can enter the field with Python so that we can expand the pool of microcontroller developers for the future generations. I ask that you take time to contribute to the micro:bit V2 effort and help educators develop their own custom firmware so that new makers can be inspired and ultimately inspire others as well!
Project Hypothetical
YOU are a History Teacher and are about to teach your students the 50 state capitals of the US. YOU now have a grant and with that grant a micro:bit V2 for each student and YOU get to build a custom Python module (library) to integrate into your curriculum!
YOU follow the steps below and very easily see how YOU can integrate this technology in a way NEVER done in history! YOU will be able to BRING TO LIFE a talking chat bot that can help the student learn the 50 state capitals as it makes facial animations and literally TALKS to the student!
With the micro:bit V2 we have created the concept of the micro:bit TED or talking educational database. You can make a micro:bit TED for ANY curriculum of your choice and you can have multiple micro:bit TED's on a single device.
You could have one for the state capital curriculum, you could have one for a custom music curriculum, biology curriculum, chemistry curriculum, ANYTHING!
Schematic
Parts
STEP 1: Download & Install Visual Studio Code IDE
STEP 2: Plug micro:bit Into Computer
PLUG IN USB CABLE TO COMPUTER AND DEVICE
STEP 3: Clone micropython-microbit-v2 REPO
git clone https://github.com/microbit-foundation/micropython-microbit-v2.gitSTEP 4: Prepare REPO For Development
cd micropython-microbit-v2
git submodule update --init
git clone https://github.com/lancaster-university/codal.git lib/codal
git clone --recurse-submodules https://github.com/lancaster-university/codal-core.git lib/codal/libraries/codal-core
git clone --recurse-submodules https://github.com/lancaster-university/codal-nrf52.git lib/codal/libraries/codal-nrf52
git clone --recurse-submodules https://github.com/microbit-foundation/codal-microbit-nrf5sdk.git lib/codal/libraries/codal-microbit-nrf5sdk
git clone --recurse-submodules https://github.com/lancaster-university/codal-microbit-v2.git lib/codal/libraries/codal-microbit-v2
STEP 5: Open Visual Studio Code IDE
STEP 6: Copy LATEST make-frozen.py Module
SOURCE
https://github.com/micropython/micropython/blob/master/tools/make-frozen.py
PLACE FILE IN THE ROOT DIRECTORY AS make-frozen.py
STEP 7: Create frozen Directory
mkdir frozen
cd frozen
STEP 8: Create statecapital.py
import gc
import time
from microbit import display, Image
from speech import say
def bot(question):
"""Bot function
Parameters
----------
question : str
Question to parse for trigger words
Returns
-------
None
"""
# Our Python dictionary which is a database
# and here is where we can type in new key/value
# pairs or in our case trigger word or words and
# then a response
db = {
'alabama': 'The capital of Alabama is Montgomery.',
'montgomery': 'Montgomery is the capital of Alabama.',
'alaska': 'The capital of Alaska is Juneau.',
'juneau': 'Juneau is the capital of Alaska.',
'arizona': 'The capital of Arizona is Phoenix.',
'phoenix': 'Phoenix is the capital of Arizona.',
'arkansas': 'The capital of Arkansas is Little Rock.',
'little rock': 'Little Rock is the capital of Arkansas.',
'california': 'The capital of California is Sacramento.',
'sacramento': 'Sacramento is the capital of California.',
'colorado': 'The capital of Colorado is Denver.',
'denver': 'Denver is the capital of Colorado.',
'connecticut': 'The capital of Connecticut is Hartford.',
'hartford': 'Hartford is the capital of Connecticut.',
'delaware': 'The capital of Delaware is Dover.',
'dover': 'Dover is the capital of Delaware.',
'florida': 'The capital of Florida is Tallahassee.',
'tallahassee': 'Tallahassee is the capital of Florida.',
'georgia': 'The capital of Georgia is Atlanta.',
'atlanta': 'Atlanta is the capital of Georgia.',
'hawaii': 'The capital of Hawaii is Honolulu.',
'honolulu': 'Honolulu is the capital of Hawaii.',
'idaho': 'The capital of Idaho is Boise.',
'boise': 'Boise is the capital of Idaho.',
'illinois': 'The capital of Illinois is Springfield.',
'springfield': 'Springfield is the capital of Illinois.',
'indiana': 'The capital of Indiana is Indianapolis.',
'indianapolis': 'Indianapolis is the capital of Indiana.',
'iowa': 'The capital of Iowa is Des Moines.',
'des moines': 'Des Moines is the capital of Iowa.',
'kansas': 'The capital of Kansas is Topeka.',
'topeka': 'Topeka is the capital of Kansas.',
'kentucky': 'The capital of Kentucky is Frankfort.',
'frankfort': 'Frankfort is the capital of Kentucky.',
'louisiana': 'The capital of Louisiana is Baton Rouge.',
'baton rouge': 'Baton Rouge is the capital of Louisiana.',
'maine': 'The capital of Maine is Augusta.',
'augusta': 'Augusta is the capital of Maine.',
'maryland': 'The capital of Maryland is Annapolis.',
'annapolis': 'Annapolis is the capital of Maryland.',
'massachusetts': 'The capital of Massachusetts is Boston.',
'boston': 'Boston is the capital of Massachusetts.',
'michigan': 'The capital of Michigan is Lansing.',
'lansing': 'Lansing is the capital of Michigan.',
'minnesota': 'The capital of Minnesota is Saint Paul.',
'saint paul': 'Saint Paul is the capital of Minnesota.',
'mississippi': 'The capital of Mississippi is Jackson.',
'jackson': 'Jackson is the capital of Mississippi.',
'missouri': 'The capital of Missouri is Jefferson City.',
'jefferson city': 'Jefferson City is the capital of Missouri.',
'montana': 'The capital of Montana is Helena.',
'helena': 'Helena is the capital of Montana.',
'nebraska': 'The capital of Nebraska is Lincoln.',
'lincoln': 'Lincoln is the capital of Nebraska.',
'nevada': 'The capital of Nevada is Carson City.',
'carson city': 'Carson City is the capital of Nevada.',
'new hampshire': 'The capital of New Hampshire is Concord.',
'concord': 'Concord is the capital of New Hampshire.',
'new jersey': 'The capital of New Jersey is Trenton.',
'trenton': 'Trenton is the capital of New Jersey.',
'new mexico': 'The capital of New Mexico is Santa Fe.',
'santa fe': 'Santa Fe is the capital of New Mexico.',
'new york': 'The capital of New York is Albany.',
'albany': 'Albany is the capital of New York.',
'north carolina': 'The capital of North Carolina is Raleigh.',
'raleigh': 'Raleigh is the capital of North Carolina.',
'north dakota': 'The capital of North Dakota is Bismarck.',
'bismarck': 'Bismarck is the capital of North Dakota.',
'ohio': 'The capital of Ohio is Columbus.',
'columbus': 'Columbus is the capital of Ohio.',
'oklahoma': 'The capital of Oklahoma is Oklahoma City.',
'oklahoma city': 'Oklahoma City is the capital of Oklahoma.',
'oregon': 'The capital of Oregon is Salem.',
'salem': 'Salem is the capital of Oregon.',
'pennsylvania': 'The capital of Pennsylvania is Harrisburg.',
'harrisburg': 'Harrisburg is the capital of Pennsylvania.',
'rhode island': 'The capital of Rhode Island is Providence.',
'providence': 'Providence is the capital of Rhode Island.',
'south carolina': 'The capital of South Carolina is Columbia.',
'columbia': 'Columbia is the capital of South Carolina.',
'south dakota': 'The capital of South Dakota is Pierre.',
'pierre': 'Pierre is the capital of South Dakota.',
'tennessee': 'The capital of Tennessee is Nashville.',
'nashville': 'Nashville is the capital of Tennessee.',
'texas': 'The capital of Texas is Austin.',
'austin': 'Austin is the capital of Texas.',
'utah': 'The capital of Utah is Salt Lake City.',
'salt lake city': 'Salt Lake City is the capital of Utah.',
'vermont': 'The capital of Vermont is Montpelier.',
'montpelier': 'Montpelier is the capital of Vermont.',
'virginia': 'The capital of Virginia is Richmond.',
'richmond': 'Richmond is the capital of Virginia.',
'washington': 'The capital of Washington is Olympia.',
'west virginia': 'The capital of West Virginia is Charleston.',
'charleston': 'Charleston is the capital of West Virginia.',
'wisconsin': 'The capital of Wisconsin is Madison.',
'madison': 'Madison is the capital of Wisconsin.',
'wyoming': 'The capital of Wyoming is Cheyenne.',
'cheyenne': 'Cheyenne is the capital of Wyoming.',
}
# Init LED happy image
display.show(Image.HAPPY)
# This is an advanced topic as well however this little function
# cleans out the unnecessary global objects or variables on what
# we call the heap area in memory
gc.collect()
# Init response object
response = ''
# We want to make sure that our dictionary database can
# find all values even if you use a capital letter
# so we convert everything to lowercase
question = question.lower()
# If you type something other than an empty string that means
# question has a value so the rest of the code will continue
# on
if question:
# This is a bit complicated do not worry about this for now
# all this is doing is looking through our dictionary database
# and seeing if our input value has the word or words which
# match an entry in the dictionary database and if it does
# put the value in the _response object
response = [val for key, val in db.items() if key in question]
gc.collect()
# If our bot got a response from us then make sure
# we trigger the speaking or suprised image so our bot
# can open its mouth to talk and then have our bot
# talk to us in our REPL and by hearing it speak as well
# and if the user types in a trigger work that is not
# recognized then provide a custom default response
if response:
display.show(Image.SURPRISED)
print('BOT: {0}'.format(response[0]))
say(str(response[0]))
display.show(Image.HAPPY)
else:
display.show(Image.SURPRISED)
print('BOT: That is not a state or state capital I am familiar with.')
say('That is not a state or state capital I am familiar with.')
display.show(Image.HAPPY)PLACE FILE IN THE frozen DIRECTORY AS statecapital.py
STEP 9: Freeze
python3 make-frozen.py frozen > frozen.cSTEP 10: Copy frozen.c
PLACE FILE IN THE source/codal_port DIRECTORY AS frozen.c
STEP 11: Add Custom Frozen Module Defines In src/codal_port/mpconfigport.h
PLACE TWO LINES AFTER LINE 31
...
// Add custom frozen module defines
#define MICROPY_MODULE_FROZEN (1)
#define MICROPY_MODULE_FROZEN_STR (1)
...STEP 12: Add Custom frozen.c SRC_C In src/codal_port/Makefile
PLACE TWO LINES AFTER LINE 54
...
frozen.c \
...STEP 13: Build Custom Firmware
cd src
make clean
make
STEP 14: Flash Custom Firmware
Drag and drop MICROBIT.hex into the MICROBIT drive.
STEP 15: Unplug & Re-Plug micro:bit
STEP 16: Enter REPL & Press micro:bit Reset Button
Use either the ALPHA Mu IDE or screen in Linux or MAC or putty in Windows and press the reset button on the back of the micro:bit to drop to a REPL.
STEP 17: Test Out New Integrated Talking statecapital TED Module In REPL
*** PLEASE MAKE SURE YOU INSTALL THE ALPHA VERSION OF MU IN ORDER FOR THE MICRO:BIT V2 TO WORK PROPERLY IF YOU ARE USING THE MU IDE ***
>>> import statecapital
>>> statecapital.bot('What is the capital of Pennsylvania?')
The capital of Pennsylvania is Harrisburg.
>>> statecapital.bot('What is Harrisburg the capital of?')
Harrisburg is the capital of Pennsylvania.
Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Please make sure to update tests as appropriate.

