Bag Of Cows

RoboCadets

Back

Microbit files

This is the code for the BBC microbit, which needs to be flashed to the Microbit. It was done using the 'Mu' program and seemed to work well when it was done from an Ubuntu system, but only sometimes when from anything else...(?!)



from microbit import *

validImages = [
     "HEART", "HEART_SMALL", "HAPPY", "SMILE", "SAD", 
     "CONFUSED", "ANGRY", "ASLEEP", "SURPRISED", "SILLY", 
     "FABULOUS", "MEH", "YES", "NO", "CLOCK12" , "CLOCK11" , 
     "CLOCK10" , "CLOCK9" , "CLOCK8" , "CLOCK7" , "CLOCK6" , 
     "CLOCK5" , "CLOCK4" , "CLOCK3" , "CLOCK2" , "CLOCK1", 
     "ARROW_N" , "ARROW_NE" , "ARROW_E" , "ARROW_SE" , 
     "ARROW_S" , "ARROW_SW" , "ARROW_W" , "ARROW_NW", 
     "TRIANGLE", "TRIANGLE_LEFT", "CHESSBOARD", "DIAMOND", 
     "DIAMOND_SMALL", "SQUARE", "SQUARE_SMALL", "RABBIT", 
     "COW", "MUSIC_CROTCHET", "MUSIC_QUAVER", "MUSIC_QUAVERS", 
     "PITCHFORK", "XMAS", "PACMAN", "TARGET", "TSHIRT", 
     "ROLLERSKATE", "DUCK", "HOUSE", "TORTOISE", "BUTTERFLY", 
     "STICKFIGURE", "GHOST", "SWORD", "GIRAFFE", "SKULL", 
     "UMBRELLA", "SNAKE"]
validPatterhChars = ['0','1','2','3','4','5','6','7','8','9',':']

uart.init(115200)
display.show(Image.HAPPY)


while True:
    # wait for a signal on the usb line to start
    while uart.any() == 0:
        pass
    # wait a short time to allow it all to be received
    sleep(10)
    # read it into an array of binary values
    binary = uart.readline()
    
    # convert from binary values into an ASCII string
    # there is probably a much nicer way to do this...
    text = ""
    for i in range(len(binary)):
        text += chr(binary[i])
    text = text.strip()
    # the protocol is that the first character will tell the microbit
    # what to do with the rest of the informatiom
    # In all cases the microbit will respond with 
    # the current state of the sensors
    if len(text) > 0:
        response = ""
        # always send a status response
        if button_a.is_pressed():
            response += "A:1;"
        else:
            response += "A:0;"
        if button_b.is_pressed():
            response += "B:1;"
        else:
            response += "B:0;"
        print(response)
        # decide what to do based on the first character
        if text[0].lower() == 's':
            # this means scroll the message
            message = text[1:]
            display.scroll(message)
        elif text[0].lower() == 'i':
            # this means use a standard image - check it is a valin name first
            if text[1:].upper() in validImages:
                eval("display.show(Image." + text[1:].upper() + ")")
        elif text[0].lower() == 'c':
            # clear the screen    
            display.clear()
        elif text[0].lower() == 'p':
            display.clear()
            # make an image from the patterns, if they look ok
            pattern = text[1:]
            if len(pattern) == 29:
                ok = True
                # check for only valid characters
                for letter in pattern:
                    if not letter in validPatterhChars:
                        ok = False
                        break
                # check the : characters are in the right place
                # positions 5,11,17,23
                for i in range(5,24,6):
                    if pattern[i]!= ':':
                        ok = False
                        break
                if ok:
                    im = Image( pattern)
                    display.show(im)
        else:
            # ignore anything unexpected
            pass
        
        


And this is the code for the robot, which is in the 'lib' folder (called microbit_comms.py)and is imported as 'mbt' into the program.



from __future__ import absolute_import, division, print_function
import serial
import time
import threading

ser = serial.Serial('/dev/ttyACM0', 115200, timeout=1)
cmd = "?"
status = ["0","0"]
run = True

# function for the buttons so that 
# they have a callback assigned
def DoNothing():
	pass
# default buttons to do nothing
buttonA = DoNothing
buttonB = DoNothing

def SetButtonCallback(button, func):
	global buttonA
	global buttonB
	if button=="A":
		buttonA = func
	if button=="B":
		buttonB = func
def Close():
	global run 
	run = False

def SendAndReceive():
    global ser
    global cmd
    global buttonA
    global buttonB
    global run
    lastCmd = "none"
    while run:
	thisCmd = "?"
    	if cmd != lastCmd:
		lastCmd = cmd
		thisCmd = cmd
		ser.write(cmd.encode("utf-8"))
	else:
		ser.write("?".encode("utf-8"))
	rcvd = ser.readline()
    	text = rcvd.strip().decode("utf-8")
	#print(text)
	new_status = text.split(';')
	#print(new_status)
	try:
		A = new_status[0][2]
		B = new_status[1][2]
		if A == "1" and status[0] == "0":
			# fire the procedure
			buttonA()
		if B == "1" and status[1] == "0":
			# fire the procedure
			buttonB()
		status[0] = A
		status[1] = B
	except:
		print("Can't process response from microbit:" ,text)
	time.sleep(0.1)
#	print(status)
    ser.close()

def ShowImage(name):
	global cmd
	cmd = 'i'+name
#	SendAndReceive(cmd,ser)
def ShowPattern(img):
	global cmd
	temp = img.split(':')
	res = ""
	if len(temp) == 5 and len(img) == 29:
		res = img
	else:
		res = "00000:00000:00900:00000:00000"
	cmd = 'p'+res
	#SendAndReceive(cmd,ser)
def ScrollText(text):		
	global cmd
	cmd = 's'+text
	#SendAndReceive(cmd,ser)
def GetButtons():
	cmd = '?'
	#text = SendAndReceive(cmd,ser)
	#return text
def Interactive():
	global cmd
	while True:
		print("""Enter options:
s = scroll text
i = display standard image
p = display image pattern (5 blocks of 0-9, separated by :)
c = clear microbiy display
? = read button state
@ = monitor button state for 4 secs
q = quit
""")
		choice = raw_input().lower()
		if choice == 's':
			text = raw_input("Enter text to scroll: ")
			cmd = 's'+text
		elif choice == 'i':
			text = raw_input("Enter image name: ")
			cmd = 'i'+text
		elif choice =='c':
			cmd = 'c'
		elif choice == 'p':
			text = raw_input("Enter pattern: ")
			if len(text) == 0:
				text = "90909:09090:90909:09090:90909"
			cmd = 'p'+text
		elif choice == '@':
			start = time.time()
			cmd = '?'
			#while time.time() <= start + 4:
			#	SendAndReceive(cmd,ser)
		elif choice == 'q':
			print("Quitting interactive mode")
			break
		else:
			cmd = '?'
		#SendAndReceive(cmd,ser)

    
mainloop = threading.Thread(target=SendAndReceive)
mainloop.daemon=True
mainloop.start()