# ————__ Hacking STEM – PartyCircuits_MicroBit.py – micro:bit __———–
# For use with the Party Circuits lesson plan for electricity basics
# available from Microsoft Education Workshop at
# http://aka.ms/hackingSTEM
#
# Overview: This project uses the Micro:Bit to control lights. It
# reads in commands from Excel via Serial and uses the commands to flash LEDs.
#
# This project uses a BBC Micro:Bit microcontroller, information at:
# https://microbit.org/
#
# Comments, contributions, suggestions, bug reports, and feature
# requests are welcome! For source code and bug reports see:
# http://github.com/[TODO github path to Hacking STEM]
#
# Copyright 2018, Jen Fox (AKA jenfoxbot)
# Microsoft EDU Workshop – HackingSTEM
# MIT License terms detailed in LICENSE.txt
# ===—————————————————————===
#Import all of the Micro:Bit Library
from microbit import *
testArray = [1,1,1,1] #For testing purposes only
# Setup & Config
display.off() # Turns off LEDs to free up additional input pins
uart.init(baudrate=9600) # Sets serial baud rate
DATA_RATE = 10 # Frequency of code looping
EOL = ‘\n’ # End of Line Character
# These constants are the pins used on the micro:bit for the sensors
ledPinList = [pin0, pin1, pin2, pin3, pin4, pin10] #10 is last analog input pin
#Set constants
LED_TIME_OFF = 50
#Set variables for intensity and speed
LED_FLASH_SPEED = 10
LED_BRIGHT = 1023
LED_MID_BRIGHT = 1023*0.75
LED_DIM = 1023*0.5
LED_FAST_SPEED = 250
LED_MED_SPEED = 500
LED_SLOW_SPEED = 1000
#Set variables for Excel Commands
# LED status: 0 = off, 1 = on
ledCommandList = [0]*6
commandArrayRaw = [0]*10
commandArray = [0]*10
got_data = False
play_infinitely = False
is_paused = False
print(‘Variables set’)
#Functions to translate the Excel Hex command sequence
# Convert hex number into base 10 integer then into binary
def hexToBinary(hexNum):
binNum = “”
# if hexNum != “”:
if hexNum:
print(hexNum)
binNum = bin(int(hexNum, 16))[2:] # Convert hexNum to binary
# binNum = bin(int(hexNum, 16))[2:] # Convert hexNum to an integer and then to binary
# binNum = bin(int(hexNum, 16))[2:].str()
# binNum = bin(int(hexNum,16))
# binNum = format(int(hexNum, 16), ‘b’) # Convert hexNum to an integer and then to binary string
print(binNum)
return binNum
#Split the binary string into command sequence
def splitBinary(binNum):
binString = str(binNum)
while len(binString) < 12:
binString = ‘0’ +binString
print(binString)
# binString = binString.zfill(12) # Pad the binary string with leading zeros to make it 12 characters long
# if len(binString) < 12:
# binString = ‘0b0{}’.format(binString[2:])
# binString = ‘0b’ + ‘0’ * (12 – len(binString)) + binString[2:]
intensityBin = binString[2:4]
ledFlashSpeedBin = binString[4:6]
ledStatusArrayBin = binString[6:]
return intensityBin, ledFlashSpeedBin, ledStatusArrayBin
#Determine LED intensity
def ledIntensity(intensityBin):
intensity = 0
if intensityBin == “01”:
intensity = LED_DIM
elif intensityBin == “10”:
intensity = LED_MID_BRIGHT
elif intensityBin == “11”:
intensity = LED_BRIGHT
return intensity
#Determine LED flash speed
def ledFlashSpeed(flashSpeedBin):
flashSpeed = 0
if flashSpeedBin == “01”:
flashSpeed = LED_SLOW_SPEED
elif flashSpeedBin == “10”:
flashSpeed = LED_MED_SPEED
elif flashSpeedBin == “11”:
flashSpeed = LED_FAST_SPEED
return flashSpeed
# Turn LEDs on based on Excel commands
def turnOnLeds(intensity, ledStatus):
for i in range(len(ledStatus)):
if ledStatus[i] == “1”:
ledPinList[i].write_analog(intensity)
# Turn all LEDs off
def turnOffLeds():
for i in range(0,len(ledPinList)):
ledPinList[i].write_analog(0)
#Function to flash appropriate LEDs based on Excel commands
def ledFlashSequence(intensity, flashSpeed, ledCommandArray):
turnOnLeds(intensity, ledCommandArray)
sleep(flashSpeed)
turnOffLeds()
sleep(LED_TIME_OFF)
#=============================================================================#
#—————The Code Below Here is for Excel Communication—————-#
#=============================================================================#
# Array to hold the serial data (8 = number of commands)
parsedData = [0] * 8
def getData():
# This function gets data from serial and builds it into a string
global parsedData, builtString
builtString = “”
while uart.any() is True:
byteIn = uart.read(1)
if byteIn == b’\n’:
continue
byteIn = str(byteIn)
splitByte = byteIn.split(“‘”)
builtString += splitByte[1]
parseData(builtString)
return (builtString != “”)
def parseData(s):
# This function seperates the string into an array
global parsedData
if s != “”:
parsedData = s.split(“,”)
def update_control_state():
global got_data, is_paused, play_infinitely, commandArrayRaw
got_data = getData()
if got_data and len(parsedData) >= 3: # Check if parsedData has at least 3 elements:
print(“Got Data”)
is_paused = parsedData[0] == “#pause”
play_infinitely = parsedData[1] == “1”
commandArrayRaw = parsedData[2:]
#=============================================================================#
#——————————Main Program Loop——————————#
#=============================================================================#
while (True):
update_control_state()
print(“got_data:”, got_data)
print(“parsedData:”, parsedData)
if got_data or play_infinitely:
for command_index in range(len(commandArrayRaw)-1):
print(“command_index:”, command_index)
# Leave for loop if we’re paused
if is_paused:
break
command = commandArrayRaw[command_index]
print(“command:”, command)
intensity, flashSpeed, ledCommandList = splitBinary(hexToBinary(command))
intensity = ledIntensity(intensity)
flashSpeed = ledFlashSpeed(flashSpeed)
#uart is the micro:bit command for serial
try:
uart.write(‘{}{}’.format(command_index + 1, EOL))
except:
pass
#LED Flash Sequence
ledFlashSequence(intensity, flashSpeed, ledCommandList)
sleep(DATA_RATE)
update_control_state()