Scratch1.4をBSDで使ってみるために

2017年02月11日(土) 関西*BSDユーザ会 第1回研究会

ScratchCat-mini.png http://retrobsd.org/styles/subsilver2/imageset/retrobsd_daemon_shad.png../BSD_squeak2013.files/kbug-bug-mini.png

むとうたけし@関西*BSDユーザ会 (@610t)

この発表はここから!!

QR-ScratchBSD.gif

Why Scratch 1.4?

理由: 大事なものから

などなど

UNIX(Linux)用のScratch 1.4

利用手順

4つのSqueak VMプラグイン

BSDに未対応

Scratch 1.4 @ OpenBSD !!

なんかおかしい…

原因を調査 by BSD technology

  9448 squeakvm NAMI  "/usr/share/scratch/locale"
  9448 squeakvm RET   mkdir -1 errno 2 No such file or directory
/usr/share/scratch
ScratchFileChooserDialog class
004B9B60  40 0B 00 00 0B B8 84 1D 48 65 6C 70 1F B9 38 01↓
           @.......Help..8.
004B9B70  2F 75 73 72 2F 73 68 61 72 65 2F 73 63 72 61 74↓
           /usr/share/scrat
004B9B80  63 68 2F 48 65 6C 70 00 0B BA 72 1C 65 6E 00 00↓
           ch/Help...r.en..

原因を調査 by Squeak Smalltalk technology

ScratchDebug.png
Smalltalk.png

Scratch.imageでの /usr/share/scratch ハードコーディング(4箇所)

↑ Smalltalk is Unix
  ifTrue: [FileDirectory on: '/usr/share/scratch']
  ifFalse: [FileDirectory default]
  Smalltalk is Unix
    ifTrue: [(FileDirectory default directoryExists: '/usr/share/scratch/Help')
      ifTrue: [helpDir ← FileDirectory on: '/usr/share/scratch/Help']].
  dir ← FileDirectory default.
  Smalltalk is Unix ifTrue: [dir ← FileDirectory on: '/usr/share/scratch'] 

「適切な場所」問題の解決方法

で、ましそうな解決策: リンク張る(ようにメッセージを出す)

% sudo ln -s /usr/local/share/scratch /usr/share/scratch

Scratch 1.4 @ FreeBSD

/usr/share/scratch 問題に関して本家に報告

Remove hard-coded /usr/share/scratch directory expectation

Scratch 1.4 @ その他のBSD

% squeak-vm -plugins /usr/local/share/scratch/Plugins/:\
                        /usr/local/lib/squeak/4.10.2-2614/

Scratch Remote Sensor Protocol

<size: 4 bytes><msg: size bytes>

デモ: Scratch Remote Sensor (Android)

PhysicalSensor4Scratch.png

デモ: Scratch Remote Sensor (ESP8266)

ESP8266-Scratch.png

デモ: Scratch 1.4@FreeBSD と chibi:bit (micro:bit)

microbit-Scratch.png

FreeBSDから見たmicro:bit

ugen4.2: <ARM> at usbus4
umass0: <USBMSC> on usbus4
umass0:  SCSI over Bulk-Only; quirks = 0x8100
umass0:2:0:-1: Attached to scbus2
da0 at umass-sim0 bus 0 scbus2 target 0 lun 0
da0: <MBED VFS 0.1> Removable Direct Access SCSI-2 device
da0: Serial Number 1021000017e0f38800000000000000000000000097969902
da0: 1.000MB/s transfers
da0: 64MB (131200 512 byte sectors)
da0: quirks=0x2<NO_6_BYTE>
uhid0: <CMSIS-DAP> on usbus4
umodem0: <mbed Serial Port> on usbus4
umodem0: data interface 2, has CM over data, has break

micro:bitってBLEあるので…

ugen4.2: <Bluegiga> at usbus4
umodem0: <CDC control> on usbus4
umodem0: data interface 1, has CM over data, has no break

micro:bitのソース

from microbit import *

def get_sensor_data():
    x, y, z = accelerometer.get_x(), accelerometer.get_y(), accelerometer.get_z()
    a, b = button_a.is_pressed(), button_b.is_pressed()
    print(x, y, z, a, b)

uart.init(115200)

while True:
    sleep(100)
    get_sensor_data()
    if uart.any():
        str=uart.readline()
        display.scroll(str,wait=False,loop=True)

microbit-scratch.py: メッセージ受信時のコールバック関数

import serial
from time import sleep
import scratch

class ScratchReceiver(object):
  @staticmethod
  def broadcast_handler(message):
    print('[receive] broadcast:', message)
    s.write(message.encode('utf-8'))
  @staticmethod
  def sensor_update_handler(**sensor_data):
    for name, value in sensor_data.items():
      print('[receive] sensor-update:', name, value)

microbit-scratch.py: シリアルの初期設定

PORT = "/dev/cuaU0"
BAUD = 115200

s = serial.Serial(PORT)
s.baudrate = BAUD
s.parity   = serial.PARITY_NONE
s.databits = serial.EIGHTBITS
s.stopbits = serial.STOPBITS_ONE

microbit-scratch.py: Scratch Remote Sensorとしての動作

# Setup Scratch remote sensor
rsc = scratch.RemoteSensorConnection(ScratchReceiver.broadcast_handler, ScratchReceiver.sensor_update_handler)  
rsc.connect()  
while True:
    data = s.readline().decode('UTF-8')
    data_list = data.rstrip().split(' ')
    try:
        x, y, z, a, b = data_list
        print(x,y,z,a,b)
        rsc.send_sensor_update(x=int(x))
        rsc.send_sensor_update(y=int(y))
        rsc.send_sensor_update(z=int(z))
        rsc.send_sensor_update(a=str(a))
        rsc.send_sensor_update(b=str(b))
    except:
        pass
rsc.disconnect()  

まとめ

Future works

絵のソース