Created
October 11, 2017 23:59
-
-
Save dvsseed/a43388b9b904af82f2abf2d4ad34b061 to your computer and use it in GitHub Desktop.
Scratch Extension helper for micro:bit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/local/bin/python | |
# -*- coding: utf-8 -*- | |
""" | |
Created on Tue Oct 10 12:49:59 2017 | |
@author: Davis, Tseng @Taiwan | |
Copyright (c) 2017-18 Davis Tseng All right reserved. | |
This program is free software; | |
you can redistribute it and/or modify it under the terms of the GNU | |
Lesser General Public License as published by the Free Software Foundation; | |
either version 2.1 of the License, or (at your option) any later version. | |
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; | |
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
See the GNU Lesser General Public License for more details. | |
You should have received a copy of the GNU Lesser General Public License along with this library; | |
if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
""" | |
from __future__ import unicode_literals | |
import os | |
import sys | |
import time | |
import serial | |
import serial.tools.list_ports | |
import thread | |
from blockext import * | |
acc_x = 0 | |
acc_y = 0 | |
acc_z = 0 | |
comp_x = 0 | |
comp_y = 0 | |
comp_z = 0 | |
btn_a = False | |
btn_b = False | |
pins = '' | |
melodys = '' | |
temp_t = 0 | |
show_led = '' | |
clear_led = False | |
clear_music = False | |
clear_mb = False | |
class BBCmicrobit: | |
def __init__(self): | |
self.led = '' | |
self.cls = False | |
self.sm = False | |
self.rst = False | |
def _is_connected(self): | |
return | |
def _problem(self): | |
if time.time() % 8 > 4: | |
return "The Scratch Sensor board is not connected. Foo." | |
def _on_reset(self): | |
global show_led | |
show_led = '' | |
global pins | |
pins = '' | |
global melodys | |
melodys = '' | |
print(""" | |
Reset! The red stop button has been clicked, | |
And now everything is how it was. | |
If you want to stop this shell scripting, | |
please use <Ctrl-C> to exit. | |
""") | |
@reporter("acc_x") | |
def acc_x(self): | |
return acc_x | |
@reporter("acc_y") | |
def acc_y(self): | |
return acc_y | |
@reporter("acc_z") | |
def acc_z(self): | |
return acc_z | |
@reporter("comp_x") | |
def comp_x(self): | |
return comp_x | |
@reporter("comp_y") | |
def comp_y(self): | |
return comp_y | |
@reporter("comp_z") | |
def comp_z(self): | |
return comp_z | |
@reporter("btn_a") | |
def btn_a(self): | |
return str(btn_a).lower() | |
@reporter("btn_b") | |
def btn_b(self): | |
return str(btn_b).lower() | |
@command("%m.status : Write on %m.inputs digital value %m.high_low", defaults=["off", "P0", "0"]) | |
def show_pin(self, status, inputs, high_low): | |
global pins | |
if status == 'on': | |
pins = inputs + '.' + high_low | |
else: | |
pins = '' | |
return pins | |
@command("%m.status : Play built-in melody %m.musics Loop %m.bools", defaults=["off", "music.BIRTHDAY", "false"]) | |
def play_music(self, status, musics, bools): | |
global melodys | |
if status == 'on': | |
melodys = musics + '.' + bools | |
else: | |
melodys = '' | |
return melodys | |
@command("Stop music") | |
def stop_music(self): | |
global clear_music | |
self.sm = True | |
clear_music = self.sm | |
@reporter("stop") | |
def get_stop(self): | |
return self.sm | |
@reporter("temp_t") | |
def temp_t(self): | |
return temp_t | |
@reporter("Image of %m.imgs", defaults=["Image.HAPPY"]) | |
def show_image(self, imgs): | |
return imgs | |
@command("%m.status : Set LED to %s", defaults=["off", ""]) | |
def set_led(self, status, value): | |
global show_led | |
if status == 'on': | |
self.led = value | |
show_led = value | |
else: | |
show_led = '' | |
return show_led | |
@reporter("led") | |
def get_led(self): | |
return self.led | |
@command("Clear display") | |
def off_led(self): | |
global clear_led | |
self.cls = True | |
clear_led = self.cls | |
@reporter("clear") | |
def get_clear(self): | |
return self.cls | |
@command("Reset microbit") | |
def reset_mb(self): | |
global clear_mb | |
self.rst = True | |
clear_mb = self.rst | |
@reporter("reset") | |
def get_reset(self): | |
return self.rst | |
def serial_proc(): | |
global acc_x | |
global acc_y | |
global acc_z | |
global comp_x | |
global comp_y | |
global comp_z | |
global btn_a | |
global btn_b | |
global pins | |
global melodys | |
global temp_t | |
global show_led | |
global clear_mb | |
global clear_music | |
global clear_led | |
# the port will depend on your computer | |
# for a raspberry pi it will probably be /dev/ttyACM0 | |
# for windows it will be COM(something) | |
PORT = None | |
if len(sys.argv) == 2: | |
PORT = str(sys.argv[1]) | |
else: | |
ports = list(serial.tools.list_ports.comports()) | |
for p in ports: | |
sp = str(p) | |
if sp.find('COM') != -1 and sp.find('mbed') != -1 and os.name == "nt": | |
lslice = sp.find('(') + 1 | |
rslice = sp.find(')') | |
PORT = sp[lslice:rslice] | |
# PORT = "COM14" | |
elif sp.find('usb') != -1 and os.name == "posix": | |
PORT = sp[0:sp.find(' ')] | |
# PORT = "/dev/cu.usbmodem1412" | |
# PORT = "/dev/cu.usbmodem1422" | |
else: | |
PORT = "/dev/ttyACM0" | |
if PORT is None: | |
print('The micro:bit should be plugged into a USB socket, please.') | |
# to exit the entire thread | |
os._exit(1) | |
# | |
BAUD = 115200 | |
s = serial.Serial(PORT) | |
s.baudrate = BAUD | |
s.parity = serial.PARITY_NONE | |
s.databits = serial.EIGHTBITS | |
s.stopbits = serial.STOPBITS_ONE | |
# s.flushInput() # flush input buffer, discarding all its contents | |
# s.flushOutput() # flush output buffer, aborting current output | |
play_time = None | |
try: | |
while True: | |
# Serial Communication (Receiving) | |
# read a line from the microbit, decode it and | |
# strip the whitespace at the end | |
data = s.readline().decode('utf-8') | |
# split the accelerometer data into ax, ay, az... | |
data_list = data.rstrip().split(' ') | |
ax, ay, az, cx, cy, cz, ba, bb, tp = data_list | |
acc_x = ax.replace('\x00', '') | |
acc_y = ay | |
acc_z = az | |
comp_x = cx | |
comp_y = cy | |
comp_z = cz | |
btn_a = ba | |
btn_b = bb | |
temp_t = tp | |
#print(acc_x, acc_y, acc_z, comp_x, comp_y, comp_z, btn_a, btn_b, temp_t) | |
# time.sleep(0.2) | |
# Serial Communication (Sending) | |
# Writing Data | |
send_to_mb = '' | |
if clear_led: | |
send_to_mb = send_to_mb + 'OFF:' | |
clear_led = False | |
else: | |
send_to_mb = send_to_mb + 'none:' | |
if clear_mb: | |
send_to_mb = send_to_mb + 'OFFRESET:' | |
clear_mb = False | |
else: | |
send_to_mb = send_to_mb + 'none:' | |
if clear_music: | |
send_to_mb = send_to_mb + 'OFFMUSIC:' | |
clear_music = False | |
else: | |
send_to_mb = send_to_mb + 'none:' | |
if show_led != '': | |
send_to_mb = send_to_mb + show_led + ':' | |
else: | |
send_to_mb = send_to_mb + 'none:' | |
if pins != '': | |
send_to_mb = send_to_mb + pins + ':' | |
else: | |
send_to_mb = send_to_mb + 'none:' | |
if melodys != '': | |
# replay music must be limited for 15 seconds | |
if play_time == None or int(time.time() - play_time) > 15: | |
play_time = time.time() | |
send_to_mb = send_to_mb + melodys | |
else: | |
send_to_mb = send_to_mb + 'none' | |
else: | |
send_to_mb = send_to_mb + 'none' | |
s.write(send_to_mb.encode('utf-8')) | |
# print(send_to_mb) | |
# time.sleep(0.2) | |
finally: | |
# Close serial port | |
s.close() | |
def run_server(): | |
print 'Starting HTTPServer, use <Ctrl-C> to stop.' | |
extension.run_forever(debug=True) | |
def get_decorated_blocks_from_class(cls, selectors=None): | |
if selectors: | |
cls_vars = vars(cls) | |
values = map(cls_vars.get, selectors) | |
else: | |
values = vars(cls).values() | |
functions = [] | |
for value in values: | |
if callable(value) and hasattr(value, '_block'): | |
functions.append(value) | |
functions.sort(key=lambda func: func._block_id) | |
return [f._block for f in functions] | |
descriptor = Descriptor( | |
name = "BBC micro:bit Extension", | |
port = 54321, | |
blocks = get_decorated_blocks_from_class(BBCmicrobit), | |
menus = dict( | |
status = ["on", "off"], | |
inputs = ["P0", "P1", "P2"], | |
high_low = ["0", "1"], | |
bools = ["true", "false"], | |
musics = ["music.DADADADUM", "music.ENTERTAINER", "music.PRELUDE", "music.ODE", "music.NYAN", "music.RINGTONE", "music.FUNK", "music.BLUES", "music.BIRTHDAY", "music.WEDDING", "music.FUNERAL", "music.PUNCHLINE", "music.PYTHON", "music.BADDY", "music.JUMP_UP", "music.JUMP_DOWN", "music.POWER_UP", "music.POWER_DOWN"], | |
imgs = ["Image.HEART", "Image.HAPPY", "Image.SMILE", "Image.ANGRY", "Image.YES", "Image.NO", "Image.CLOCK12", "Image.CLOCK11", "Image.CLOCK10", "Image.CLOCK9", "Image.CLOCK8", "Image.CLOCK7", "Image.CLOCK6", "Image.CLOCK5", "Image.CLOCK4", "Image.CLOCK3", "Image.CLOCK2", "Image.CLOCK1", "Image.ALL_CLOCKS", "Image.ARROW_N", "Image.ARROW_NE", "Image.ARROW_E", "Image.ARROW_SE", "Image.ARROW_S", "Image.ARROW_SW", "Image.ARROW_W", "Image.ARROW_NW", "Image.ALL_ARROWS"], | |
), | |
) | |
extension = Extension(BBCmicrobit, descriptor) | |
if __name__ == "__main__": | |
try: | |
thread.start_new_thread(serial_proc, ()) | |
thread.start_new_thread(run_server, ()) | |
except: | |
pass | |
while 1: | |
pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment