micro:bit

2021年5月 6日 (木)

microbit-v2にMicropythonをインストールする

2021/5/10
LCD表示スクリプトを追加した。

2021/5/6
初版

microbit-v2 MicroPython Install

microbit-v2 MicroPython Install

概要

microbit-v2にMicropythonをインストールする方法について記載する
webブラウザーから「micro:bit python editor」にアクセスしてプログラムを作成する方法があるが、ここではmicrobit-v2のボードにmicropythonインタープリタを書き込んで使用する。
(ホストPCとしてはubuntuを想定している)

注意:
microbit-v1のmicropythonの書き込み/実行には以下のエディタを使用すること。
micro:bit python editor

事前準備

(1)Thonny(pythonエディタ)
以下の手順でインストールする:

bash <(wget -O - https://thonny.org/installer-for-linux)

(2)picocom(通信ソフト)
以下の手順でインストールする:

sudo apt-get install picocom

ビルド手順

以下の手順でmicrobit-v2用のmicropythonをビルドする:

mkdir mb2_mp cd mb2_mp git clone https://github.com/microbit-foundation/micropython-microbit-v2.git cd micropython-microbit-v2 git submodule update --init make -C lib/micropython/mpy-cross cd src gedit Makefile # Makefileを自分のビルド環境にあわせて変更する

Makefile
以下の部分を自分の実行パスに合わせて変更する:
(実行パスは、which rm,which mkdirなどを実行すると分かる)

<省略> RM = /usr/bin/rm MKDIR = /usr/bin/mkdir PYTHON3 ?= python3 <省略>

続き:

make # makeが完了すると以下のようにMICROBIT.hexが生成される: ls MICROBIT.hex addlayouttable.py codal.patch codal_port Makefile build codal_app # miicrobit-v2ボードを接続してファームウェアを描き込む cp MICROBIT.hex /media/USER/MICROBIT/

以上でfirmwareがボードに書き込まれる。
・USERは環境依存なので、自分の環境に合わせること。

動作確認

picocomを使いボードとシリアルで通信する。
以下、通信例:

$ picocom /dev/ttyACM0 -b115200 MPY: soft reboot MicroPython v1.15-64-g1e2f0d280 on 2021-05-06; micro:bit v2.0.0-beta.5 with nRF52833 Type "help()" for more information. >>> import os >>> os.uname() (sysname='microbit', nodename='microbit', release='2.0.0-beta.5', version='micro:bit v2.0.0-beta.5+c28e6bd-dirty on 2021-05-06; MicroPython v1.15-64-g1e2f0d280 on 2021-05-06', machine='micro:bit with nRF52833') >>> import gc >>> gc.collect() >>> gc.mem_free() 62272 >>> list(5 * x + y for x in range(10) for y in [4, 2, 1]) [4, 2, 1, 9, 7, 6, 14, 12, 11, 19, 17, 16, 24, 22, 21, 29, 27, 26, 34, 32, 31, 39, 37, 36, 44, 42, 41, 49, 47, 46] >>> >>> dir() ['pin_logo', 'panic', 'pin2', 'pin3', 'pin0', 'pin1', 'pin6', 'compass', 'pin4', 'pin5', 'pin7', 'sleep', 'temperature', 'pin9', 'pin8', 'ws2812_write', 'SoundEvent', 'pin13', 'pin12', 'pin11', 'pin10', 'running_time', 'spi', 'pin15', 'pin14', 'display', 'accelerometer', 'pin16', 'pin19', '__thonny_helper', 'audio', '__thonny_relevant', 'button_a', 'button_b', 'Sound', 'os', 'speaker', 'pin_speaker', 'pin20', 'i2c', '__name__', 'uart', 'set_volume', 'Image', 'microphone', 'gc', 'reset'] >>> help('modules') __main__ machine os uerrno antigravity math radio urandom audio microbit speech ustruct builtins micropython this usys gc music uarray utime love neopixel ucollections Plus any modules on the filesystem >>> #オンライン・ヘルプ >>> help() Welcome to MicroPython on the micro:bit! Try these commands: display.scroll('Hello') running_time() sleep(1000) button_a.is_pressed() What do these commands do? Can you improve them? HINT: use the up and down arrow keys to get your command history. Press the TAB key to auto-complete unfinished words (so 'di' becomes 'display' after you press TAB). These tricks save a lot of typing and look cool! Explore: Type 'help(something)' to find out about it. Type 'dir(something)' to see what it can do. Type 'dir()' to see what stuff is available. For goodness sake, don't type 'import this'. Control commands: CTRL-C -- stop a running program CTRL-D -- on a blank line, do a soft reset of the micro:bit CTRL-E -- enter paste mode, turning off auto-indent For a list of available modules, type help('modules') For more information about Python, visit: http://python.org/ To find out about MicroPython, visit: http://micropython.org/ Python/micro:bit documentation is here: https://microbit-micropython.readthedocs.io/ >>>

サンプルスクリプト

helloWorld.py

from microbit import * while True: display.scroll('Hello, World!') display.show(Image.HEART) sleep(2000)

blink.py

from microbit import * while True: pin0.write_digital(0) sleep(500) pin0.write_digital(1) sleep(500)

・接続しているLED(pin0)が点滅する。

dimmer.py

from microbit import * min_power = 50 max_power = 1023 power_step = (max_power - min_power) / 9 brightness = 0 def set_power(brightness): display.show(str(brightness)) if brightness == 0: pin0.write_analog(0) else: pin0.write_analog(brightness * power_step + min_power) set_power(brightness) while True: if button_a.was_pressed(): brightness -= 1 if brightness < 0: brightness = 0 set_power(brightness) elif button_b.was_pressed(): brightness += 1 if brightness > 9: brightness = 9 set_power(brightness) sleep(100)

・ボタンBを押すと接続しているLEC(pin0)の光量が増す。
・ボタンAを押すと接続しているLEC(pin0)の光量が減る。

linghtsensor.py

from microbit import * while True: if display.read_light_level() < 100: display.show(Image.HEART) else: display.clear() sleep(2000)

・光をLED-Matrixに当てると表示されているLEDのハートマークが消える。
 (強い光を当てないと光センサーが動作しないようだ)

conway.py

''' Conway's Game Of Life for the micro:bit Press button A or tap the micro:bit to generate a fresh layout. ''' import microbit import random arena1 = bytearray(7 * 7) arena2 = bytearray(7 * 7) def show(): img = microbit.Image(5,5) for y in range(5): for x in range(5): img.set_pixel(x, y, arena1[8 + y * 7 + x]*9) microbit.display.show(img) # do 1 iteration of Conway's Game of Life def conway_step(): global arena1, arena2 for i in range(5 * 5): # loop over pixels i = 8 + (i // 5) * 7 + i % 5 # count number of neighbours num_neighbours = (arena1[i - 8] + arena1[i - 7] + arena1[i - 6] + arena1[i - 1] + arena1[i + 1] + arena1[i + 6] + arena1[i + 7] + arena1[i + 8]) # check if the centre cell is alive or not self = arena1[i] # apply the rules of life if self and not (2 <= num_neighbours <= 3): arena2[i] = 0 # not enough, or too many neighbours: cell dies elif not self and num_neighbours == 3: arena2[i] = 1 # exactly 3 neighbours around an empty cell: cell is born else: arena2[i] = self # stay as-is # swap the buffers (arena1 is now the new one to display) arena1, arena2 = arena2, arena1 while True: # randomise the start for i in range(5 * 5): # loop over pixels i = 8 + (i // 5) * 7 + i % 5 arena1[i] = random.randrange(2) # set the pixel randomly show() microbit.sleep(1) # need to yield to update accelerometer (not ideal...) # loop while button a is not pressed while not microbit.button_a.is_pressed() and microbit.accelerometer.get_z() < -800: conway_step() show() microbit.sleep(150)

neopixel_random.py

""" neopixel_random.py Repeatedly displays random colours onto the LED strip. This example requires a strip of 8 Neopixels (WS2812) connected to pin0. """ from microbit import * import neopixel from random import randint # Setup the Neopixel strip on pin0 with a length of 8 pixels #np = neopixel.NeoPixel(pin0, 8) np = neopixel.NeoPixel(pin0, 64) while True: #Iterate over each LED in the strip for pixel_id in range(0, len(np)): red = randint(0, 60) green = randint(0, 60) blue = randint(0, 60) # Assign the current LED a random red, green and blue value between 0 and 60 np[pixel_id] = (red, green, blue) # Display the current pixel data on the Neopixel strip np.show() #sleep(100)

・使用するneopixelの数に応じてsleep時間は調整すること。

firefly.py

# A micro:bit Firefly. # By Nicholas H.Tollervey. Released to the public domain. import radio import random from microbit import display, Image, button_a, sleep # Create the "flash" animation frames. Can you work out how it's done? flash = [Image().invert()*(i/9) for i in range(9, -1, -1)] # The radio won't work unless it's switched on. radio.on() # Event loop. while True: # Button A sends a "flash" message. if button_a.was_pressed(): radio.send('flash') # a-ha # Read any incoming messages. incoming = radio.receive() if incoming == 'flash': # If there's an incoming "flash" message display # the firefly flash animation after a random short # pause. sleep(random.randint(50, 350)) display.show(flash, delay=100, wait=False) # Randomly re-broadcast the flash message after a # slight delay. if random.randint(0, 9) == 0: sleep(500) radio.send('flash') # a-ha

・2つのmicrobitを用意して上のプログラムを描き込み実行する。
・Aボタンを押すとbluetooth経由で信号を受信して対向のmicrobitのLEDが光る。
(対向のmicrobitはv2でなくても良い)

performanceTest.py

import time def performanceTest(): msec = time.ticks_ms endTime = msec() + 10000 count = 0 while msec() < endTime: count += 1 print("Count: ", count) performanceTest()

以下が出力される:(出力例)

Count: 669283

LCD表示スクリプト(2021/5/10)

以下は 「DEPRECATED LIBRARY micropython-adafruit-rgb-display」のソースをmicrobit-v2のmicropythonに合わせて修正したものになる:
(使用しているLCDは以下のもの)
1.8inch colorful display module for micro:bit, 160x128

rgb.py

import utime import ustruct def color565(r, g, b): return (r & 0xf8) << 8 | (g & 0xfc) << 3 | b >> 3 class DummyPin: """A fake gpio pin for when you want to skip pins.""" OUT = 0 IN = 0 PULL_UP = 0 PULL_DOWN = 0 OPEN_DRAIN = 0 ALT = 0 ALT_OPEN_DRAIN = 0 LOW_POWER = 0 MED_POWER = 0 HIGH_PWER = 0 IRQ_FALLING = 0 IRQ_RISING = 0 IRQ_LOW_LEVEL = 0 IRQ_HIGH_LEVEL = 0 def __call__(self, *args, **kwargs): return False init = __call__ value = __call__ out_value = __call__ toggle = __call__ high = __call__ low = __call__ on = __call__ off = __call__ mode = __call__ pull = __call__ drive = __call__ irq = __call__ class Display: _PAGE_SET = None _COLUMN_SET = None _RAM_WRITE = None _RAM_READ = None _INIT = () _ENCODE_PIXEL = ">H" _ENCODE_POS = ">HH" _DECODE_PIXEL = ">BBB" def __init__(self, width, height): self.width = width self.height = height self.init() def init(self): """Run the initialization commands.""" for command, data in self._INIT: self._write(command, data) def _block(self, x0, y0, x1, y1, data=None): """Read or write a block of data.""" self._write(self._COLUMN_SET, self._encode_pos(x0, x1)) self._write(self._PAGE_SET, self._encode_pos(y0, y1)) if data is None: size = ustruct.calcsize(self._DECODE_PIXEL) return self._read(self._RAM_READ, (x1 - x0 + 1) * (y1 - y0 + 1) * size) self._write(self._RAM_WRITE, data) def _encode_pos(self, a, b): """Encode a postion into bytes.""" return ustruct.pack(self._ENCODE_POS, a, b) def _encode_pixel(self, color): """Encode a pixel color into bytes.""" return ustruct.pack(self._ENCODE_PIXEL, color) def _decode_pixel(self, data): """Decode bytes into a pixel color.""" return color565(*ustruct.unpack(self._DECODE_PIXEL, data)) def pixel(self, x, y, color=None): """Read or write a pixel.""" if color is None: return self._decode_pixel(self._block(x, y, x, y)) if not 0 <= x < self.width or not 0 <= y < self.height: return self._block(x, y, x, y, self._encode_pixel(color)) def fill_rectangle(self, x, y, width, height, color): """Draw a filled rectangle.""" x = min(self.width - 1, max(0, x)) y = min(self.height - 1, max(0, y)) w = min(self.width - x, max(1, width)) h = min(self.height - y, max(1, height)) self._block(x, y, x + w - 1, y + h - 1, b'') chunks, rest = divmod(w * h, 512) pixel = self._encode_pixel(color) if chunks: data = pixel * 512 for count in range(chunks): self._write(None, data) if rest: self._write(None, pixel * rest) def fill(self, color=0): """Fill whole screen.""" self.fill_rectangle(0, 0, self.width, self.height, color) def hline(self, x, y, width, color): """Draw a horizontal line.""" self.fill_rectangle(x, y, width, 1, color) def vline(self, x, y, height, color): """Draw a vertical line.""" self.fill_rectangle(x, y, 1, height, color) def blit_buffer(self, buffer, x, y, width, height): """Copy pixels from a buffer.""" if (not 0 <= x < self.width or not 0 <= y < self.height or not 0 < x + width <= self.width or not 0 < y + height <= self.height): raise ValueError("out of bounds") self._block(x, y, x + width - 1, y + height - 1, buffer) class DisplaySPI(Display): def __init__(self, spi, dc, cs=None, rst=None, width=1, height=1): self.spi = spi self.cs = cs self.dc = dc self.rst = rst if self.rst is None: self.rst = DummyPin() if self.cs is None: self.cs = DummyPin() #self.cs.init(self.cs.OUT, value=1) #self.dc.init(self.dc.OUT, value=0) #self.rst.init(self.rst.OUT, value=1) self.cs.write_digital(1) self.dc.write_digital(0) self.rst.write_digital(1) self.reset() super().__init__(width, height) def reset(self): #self.rst(0) self.rst.write_digital(0) utime.sleep_ms(50) #self.rst(1) self.rst.write_digital(1) utime.sleep_ms(50) def _write(self, command=None, data=None): if command is not None: #self.dc(0) #self.cs(0) self.dc.write_digital(0) self.cs.write_digital(0) self.spi.write(bytearray([command])) #self.cs(1) self.cs.write_digital(1) if data is not None: #self.dc(1) #self.cs(0) self.dc.write_digital(1) self.cs.write_digital(0) self.spi.write(data) #self.cs(1) self.cs.write_digital(1) def _read(self, command=None, count=0): #self.dc(0) #self.cs(0) self.dc.write_digital(0) self.cs.write_digital(0) if command is not None: self.spi.write(bytearray([command])) if count: data = self.spi.read(count) #self.cs(1) self.cs.write_digital(1) return data

・ピン制御の部分をmicrobitのmicropythonに合わせて修正した。

st7735.py

from rgb import DisplaySPI, color565 import ustruct _NOP=const(0x00) _SWRESET=const(0x01) _RDDID=const(0x04) _RDDST=const(0x09) _SLPIN=const(0x10) _SLPOUT=const(0x11) _PTLON=const(0x12) _NORON=const(0x13) _INVOFF=const(0x20) _INVON=const(0x21) _DISPOFF=const(0x28) _DISPON=const(0x29) _CASET=const(0x2A) _RASET=const(0x2B) _RAMWR=const(0x2C) _RAMRD=const(0x2E) _PTLAR=const(0x30) _COLMOD=const(0x3A) _MADCTL=const(0x36) _FRMCTR1=const(0xB1) _FRMCTR2=const(0xB2) _FRMCTR3=const(0xB3) _INVCTR=const(0xB4) _DISSET5=const(0xB6) _PWCTR1=const(0xC0) _PWCTR2=const(0xC1) _PWCTR3=const(0xC2) _PWCTR4=const(0xC3) _PWCTR5=const(0xC4) _VMCTR1=const(0xC5) _RDID1=const(0xDA) _RDID2=const(0xDB) _RDID3=const(0xDC) _RDID4=const(0xDD) _PWCTR6=const(0xFC) _GMCTRP1=const(0xE0) _GMCTRN1=const(0xE1) class ST7735(DisplaySPI): """ A simple driver for the ST7735-based displays. >>> from machine import Pin, SPI >>> import st7735 >>> display = st7735.ST7735(SPI(1), dc=Pin(12), cs=Pin(15), rst=Pin(16)) >>> display = st7735.ST7735R(SPI(1, baudrate=40000000), dc=Pin(12), cs=Pin(15), rst=Pin(16)) >>> display.fill(0x7521) >>> display.pixel(64, 64, 0) """ _COLUMN_SET = _CASET _PAGE_SET = _RASET _RAM_WRITE = _RAMWR _RAM_READ = _RAMRD _INIT = ( (_SWRESET, None), (_SLPOUT, None), (_MADCTL, b'\x08'), # bottom to top refresh (_COLMOD, b'\x05'), # 16bit color (_INVCTR, b'0x00'), # line inversion # 1 clk cycle nonoverlap, 2 cycle gate rise, 3 sycle osc equalie, # fix on VTL (_DISSET5, b'\x15\x02'), # fastest refresh, 6 lines front porch, 3 line back porch (_FRMCTR1, b'\x00\x06\x03'), (_PWCTR1, b'\x02\x70'), # GVDD = 4.7V, 1.0uA (_PWCTR2, b'\x05'), # VGH=14.7V, VGL=-7.35V (_PWCTR3, b'\x01\x02'), # Opamp current small, Boost frequency (_PWCTR6, b'\x11\x15'), (_VMCTR1, b'\x3c\x38'), # VCOMH = 4V, VOML = -1.1V (_GMCTRP1, b'\x09\x16\x09\x20\x21\x1b\x13\x19' b'\x17\x15\x1e\x2b\x04\x05\x02\x0e'), # Gamma (_GMCTRN1, b'\x08\x14\x08\x1e\x22\x1d\x18\x1e' b'\x18\x1a\x24\x2b\x06\x06\x02\x0f'), (_CASET, b'\x00\x02\x00\x81'), # XSTART = 2, XEND = 129 (_RASET, b'\x00\x02\x00\x81'), # YSTART = 2, YEND = 129 (_NORON, None), (_DISPON, None), ) _ENCODE_PIXEL = ">H" _ENCODE_POS = ">HH" def __init__(self, spi, dc, cs, rst=None, width=128, height=128): super().__init__(spi, dc, cs, rst, width, height) class ST7735R(ST7735): _INIT = ( (_SWRESET, None), (_SLPOUT, None), (_MADCTL, b'\xc8'), (_COLMOD, b'\x05'), # 16bit color (_INVCTR, b'\x07'), (_FRMCTR1, b'\x01\x2c\x2d'), (_FRMCTR2, b'\x01\x2c\x2d'), (_FRMCTR3, b'\x01\x2c\x2d\x01\x2c\x2d'), (_PWCTR1, b'\x02\x02\x84'), (_PWCTR2, b'\xc5'), (_PWCTR3, b'\x0a\x00'), (_PWCTR4, b'\x8a\x2a'), (_PWCTR5, b'\x8a\xee'), (_VMCTR1, b'\x0e'), (_INVOFF, None), (_GMCTRP1, b'\x02\x1c\x07\x12\x37\x32\x29\x2d' b'\x29\x25\x2B\x39\x00\x01\x03\x10'), # Gamma (_GMCTRN1, b'\x03\x1d\x07\x06\x2E\x2C\x29\x2D' b'\x2E\x2E\x37\x3F\x00\x00\x02\x10'), ) def __init__(self, spi, dc, cs, rst=None, width=128, height=160): super().__init__(spi, dc, cs, rst, width, height) def init(self): super().init() cols = ustruct.pack('>HH', 0, self.width - 1) rows = ustruct.pack('>HH', 0, self.height - 1) for command, data in ( (_CASET, cols), (_RASET, rows), (_NORON, None), (_DISPON, None), ): self._write(command, data)

・特に修正はない。

displayLCD.py

from microbit import * from st7735 import ST7735, ST7735R from rgb import color565 spi.init(mode=3, baudrate=300000000, sclk=pin13, mosi=pin15, miso=pin14) #spi.init(0) lcd = ST7735R(spi, dc=pin12, cs=pin16, rst=pin8) lcd.fill(0) for x in range(128): for y in range(160): lcd.pixel(x,y,color565(x*2, y*3//2, 255-x-y*3//4))

・転送速度が遅いようで描画速度が遅い。
 (設定の問題だと思うが画面端にゴミが表示される)
・他のmicropythonと異なり最初からSPIのインスタンスが用意されているので、コーディング時は、そこに注意する必要がある。(メモリの制約と推測する)

main.py

電源オン時に自動的にmain.pyが実行されるので、直接実行したいプログラムをmain.pyに置くことができる。
直接実行したいプログラムがxxxx.pyの場合は、
main.pyを以下のようにしても良い。

main.py

# main.py import xxxx

参照URL

micro:bit-v2_MicroPython関連:
MicroPython on the micro:bit via CODAL
Hello, World! (v2-doc)日本語版
micro:bit v2 用 MicroPython で新機能を試してみる
Hello, World! (v2-doc)
Out of box experience(factory reset)
Python guide(examples)
micropython/examples

Thonny関連:
Thonny (Python IDE for beginners)
Thonnyインストール方法(PicoボードにMicropython/CircuitPythonをインストールする)

(別の)MicroPython関連:
TFT LCD(ST7735R)をMicroPythonで動かしてみた
DEPRECATED LIBRARY micropython-adafruit-rgb-display

MakeCode(python)関連:(参考)
(the difference between) MakeCode Python and MicroPython
micro:bit v2(マイクロビット)に関する技術情報を集約

以上

続きを読む "microbit-v2にMicropythonをインストールする"

| | コメント (0)

2021年4月30日 (金)

LCDをmicrobit_arduinoで動かす

2021/5/3
スケッチをハードウェアSPIに切り替えた。

2021/4/30
初版

pio Microbit Arduino ST7735S

pio Microbit Arduino ST7735S

概要

以下のLCDをmicrobit_arduinoで動かす
1.8inch colorful display module for micro:bit, 160x128 (ST7735S)
(ホストはubuntu20.04を想定している)
platformioが既にインストールされている前提で説明する。

platformioのインストールについては以下などを参照のこと:
arduinoフレームワーク用platformio.ini集

platformio.ini

以下のplatformio.iniを利用する:

; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:bbcmicrobit] platform = nordicnrf51 board = bbcmicrobit framework = arduino build_flags = -DMICROBIT -DNRF51_S110 monitor_speed = 115200 lib_ldf_mode = deep+ #upload_port = /media/USER/MICROBIT #upload_protocol = mbed upload_protocol = cmsis-dap lib_deps = https://github.com/adafruit/Adafruit_BusIO/archive/master.zip https://github.com/sparkfun/SparkFun_MAG3110_Breakout_Board_Arduino_Library/archive/master.zip https://cdn-learn.adafruit.com/assets/assets/000/046/217/original/MMA8653.zip https://github.com/stm32duino/LSM303AGR/archive/master.zip https://github.com/adafruit/Adafruit-GFX-Library/archive/master.zip # https://github.com/sandeepmistry/arduino-BLEPeripheral/archive/master.zip https://github.com/adafruit/Adafruit_Microbit/archive/master.zip # https://github.com/ht-deko/microbit_Screen/archive/master.zip # adafruit/Adafruit ST7735 and ST7789 Library @ ^1.7.2

graphicstest.ino

テスト用プログラムを以下のように作成する:
src/graphicstest.ino

// modified for Waveshare 1.8inch LCD for micro:bit, controler:ST7735S (2021/4/30) /************************************************************************** This is a library for several Adafruit displays based on ST77* drivers. Works with the Adafruit 1.8" TFT Breakout w/SD card ----> http://www.adafruit.com/products/358 The 1.8" TFT shield ----> https://www.adafruit.com/product/802 The 1.44" TFT breakout ----> https://www.adafruit.com/product/2088 The 1.14" TFT breakout ----> https://www.adafruit.com/product/4383 The 1.3" TFT breakout ----> https://www.adafruit.com/product/4313 The 1.54" TFT breakout ----> https://www.adafruit.com/product/3787 The 2.0" TFT breakout ----> https://www.adafruit.com/product/4311 as well as Adafruit raw 1.8" TFT display ----> http://www.adafruit.com/products/618 Check out the links above for our tutorials and wiring diagrams. These displays use SPI to communicate, 4 or 5 pins are required to interface (RST is optional). Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Limor Fried/Ladyada for Adafruit Industries. MIT license, all text above must be included in any redistribution **************************************************************************/ #include <Adafruit_GFX.h> // Core graphics library #include <Adafruit_ST7735.h> // Hardware-specific library for ST7735 #include <Adafruit_ST7789.h> // Hardware-specific library for ST7789 #include <SPI.h> #ifndef MICROBIT #if defined(ARDUINO_FEATHER_ESP32) // Feather Huzzah32 #define TFT_CS 14 #define TFT_RST 15 #define TFT_DC 32 #elif defined(ESP8266) #define TFT_CS 4 #define TFT_RST 16 #define TFT_DC 5 #else // For the breakout board, you can use any 2 or 3 pins. // These pins will also work for the 1.8" TFT shield. #define TFT_CS 10 #define TFT_RST 9 // Or set to -1 and connect to Arduino RESET pin #define TFT_DC 8 #endif // OPTION 1 (recommended) is to use the HARDWARE SPI pins, which are unique // to each board and not reassignable. For Arduino Uno: MOSI = pin 11 and // SCLK = pin 13. This is the fastest mode of operation and is required if // using the breakout board's microSD card. // For 1.44" and 1.8" TFT with ST7735 use: Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); // For 1.14", 1.3", 1.54", and 2.0" TFT with ST7789: //Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST); // OPTION 2 lets you interface the display using ANY TWO or THREE PINS, // tradeoff being that performance is not as fast as hardware SPI above. //#define TFT_MOSI 11 // Data out //#define TFT_SCLK 13 // Clock out // For ST7735-based displays, we will use this call //Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST); // OR for the ST7789-based displays, we will use this call //Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST); #endif #ifdef MICROBIT // setup for Waveshare LCD #define TFT_CS 16 #define TFT_RST 8 #define TFT_DC 12 #define TFT_MOSI 15 // Data out #define TFT_SCLK 13 // Clock out #define BL_EN 1 // backlit enable //Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST); Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); // use Hardware SPI #endif float p = 3.1415926; void setup(void) { //pinMode(BL_EN, OUTPUT); //digitalWrite(BL_EN, HIGH); //Serial.begin(9600); Serial.begin(115200); Serial.print(F("Hello! ST77xx TFT Test")); #ifndef MICROBIT // Use this initializer if using a 1.8" TFT screen: tft.initR(INITR_BLACKTAB); // Init ST7735S chip, black tab // OR use this initializer if using a 1.8" TFT screen with offset such as WaveShare: // tft.initR(INITR_GREENTAB); // Init ST7735S chip, green tab // OR use this initializer (uncomment) if using a 1.44" TFT: //tft.initR(INITR_144GREENTAB); // Init ST7735R chip, green tab // OR use this initializer (uncomment) if using a 0.96" 160x80 TFT: //tft.initR(INITR_MINI160x80); // Init ST7735S mini display // OR use this initializer (uncomment) if using a 1.3" or 1.54" 240x240 TFT: //tft.init(240, 240); // Init ST7789 240x240 // OR use this initializer (uncomment) if using a 2.0" 320x240 TFT: //tft.init(240, 320); // Init ST7789 320x240 // OR use this initializer (uncomment) if using a 1.14" 240x135 TFT: //tft.init(135, 240); // Init ST7789 240x135 // SPI speed defaults to SPI_DEFAULT_FREQ defined in the library, you can override it here // Note that speed allowable depends on chip and quality of wiring, if you go too fast, you // may end up with a black screen some times, or all the time. //tft.setSPISpeed(40000000); #endif #ifdef MICROBIT tft.initR(INITR_GREENTAB); // Init ST7735S chip, green tab for WaveShare //tft.setRotation(1); // landscape (microbit board upside) tft.setRotation(2); // portrait (microbit board leftside) tft.setSPISpeed(40000000); #endif Serial.println(F("Initialized")); uint16_t time = millis(); tft.fillScreen(ST77XX_BLACK); time = millis() - time; Serial.println(time, DEC); delay(500); // large block of text tft.fillScreen(ST77XX_BLACK); testdrawtext("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur adipiscing ante sed nibh tincidunt feugiat. Maecenas enim massa, fringilla sed malesuada et, malesuada sit amet turpis. Sed porttitor neque ut ante pretium vitae malesuada nunc bibendum. Nullam aliquet ultrices massa eu hendrerit. Ut sed nisi lorem. In vestibulum purus a tortor imperdiet posuere. ", ST77XX_WHITE); delay(1000); // tft print function! tftPrintTest(); delay(4000); // a single pixel tft.drawPixel(tft.width()/2, tft.height()/2, ST77XX_GREEN); delay(500); // line draw test testlines(ST77XX_YELLOW); delay(500); // optimized lines testfastlines(ST77XX_RED, ST77XX_BLUE); delay(500); testdrawrects(ST77XX_GREEN); delay(500); testfillrects(ST77XX_YELLOW, ST77XX_MAGENTA); delay(500); tft.fillScreen(ST77XX_BLACK); testfillcircles(10, ST77XX_BLUE); testdrawcircles(10, ST77XX_WHITE); delay(500); testroundrects(); delay(500); testtriangles(); delay(500); mediabuttons(); delay(500); Serial.println("done"); delay(1000); } void loop() { tft.invertDisplay(true); delay(500); tft.invertDisplay(false); delay(500); } void testlines(uint16_t color) { tft.fillScreen(ST77XX_BLACK); for (int16_t x=0; x < tft.width(); x+=6) { tft.drawLine(0, 0, x, tft.height()-1, color); delay(0); } for (int16_t y=0; y < tft.height(); y+=6) { tft.drawLine(0, 0, tft.width()-1, y, color); delay(0); } tft.fillScreen(ST77XX_BLACK); for (int16_t x=0; x < tft.width(); x+=6) { tft.drawLine(tft.width()-1, 0, x, tft.height()-1, color); delay(0); } for (int16_t y=0; y < tft.height(); y+=6) { tft.drawLine(tft.width()-1, 0, 0, y, color); delay(0); } tft.fillScreen(ST77XX_BLACK); for (int16_t x=0; x < tft.width(); x+=6) { tft.drawLine(0, tft.height()-1, x, 0, color); delay(0); } for (int16_t y=0; y < tft.height(); y+=6) { tft.drawLine(0, tft.height()-1, tft.width()-1, y, color); delay(0); } tft.fillScreen(ST77XX_BLACK); for (int16_t x=0; x < tft.width(); x+=6) { tft.drawLine(tft.width()-1, tft.height()-1, x, 0, color); delay(0); } for (int16_t y=0; y < tft.height(); y+=6) { tft.drawLine(tft.width()-1, tft.height()-1, 0, y, color); delay(0); } } void testdrawtext(char *text, uint16_t color) { tft.setCursor(0, 0); tft.setTextColor(color); tft.setTextWrap(true); tft.print(text); } void testfastlines(uint16_t color1, uint16_t color2) { tft.fillScreen(ST77XX_BLACK); for (int16_t y=0; y < tft.height(); y+=5) { tft.drawFastHLine(0, y, tft.width(), color1); } for (int16_t x=0; x < tft.width(); x+=5) { tft.drawFastVLine(x, 0, tft.height(), color2); } } void testdrawrects(uint16_t color) { tft.fillScreen(ST77XX_BLACK); for (int16_t x=0; x < tft.width(); x+=6) { tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color); } } void testfillrects(uint16_t color1, uint16_t color2) { tft.fillScreen(ST77XX_BLACK); for (int16_t x=tft.width()-1; x > 6; x-=6) { tft.fillRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color1); tft.drawRect(tft.width()/2 -x/2, tft.height()/2 -x/2 , x, x, color2); } } void testfillcircles(uint8_t radius, uint16_t color) { for (int16_t x=radius; x < tft.width(); x+=radius*2) { for (int16_t y=radius; y < tft.height(); y+=radius*2) { tft.fillCircle(x, y, radius, color); } } } void testdrawcircles(uint8_t radius, uint16_t color) { for (int16_t x=0; x < tft.width()+radius; x+=radius*2) { for (int16_t y=0; y < tft.height()+radius; y+=radius*2) { tft.drawCircle(x, y, radius, color); } } } void testtriangles() { tft.fillScreen(ST77XX_BLACK); uint16_t color = 0xF800; int t; int w = tft.width()/2; int x = tft.height()-1; int y = 0; int z = tft.width(); for(t = 0 ; t <= 15; t++) { tft.drawTriangle(w, y, y, x, z, x, color); x-=4; y+=4; z-=4; color+=100; } } void testroundrects() { tft.fillScreen(ST77XX_BLACK); uint16_t color = 100; int i; int t; for(t = 0 ; t <= 4; t+=1) { int x = 0; int y = 0; int w = tft.width()-2; int h = tft.height()-2; for(i = 0 ; i <= 16; i+=1) { tft.drawRoundRect(x, y, w, h, 5, color); x+=2; y+=3; w-=4; h-=6; color+=1100; } color+=100; } } void tftPrintTest() { tft.setTextWrap(false); tft.fillScreen(ST77XX_BLACK); tft.setCursor(0, 30); tft.setTextColor(ST77XX_RED); tft.setTextSize(1); tft.println("Hello World!"); tft.setTextColor(ST77XX_YELLOW); tft.setTextSize(2); tft.println("Hello World!"); tft.setTextColor(ST77XX_GREEN); tft.setTextSize(3); tft.println("Hello World!"); tft.setTextColor(ST77XX_BLUE); tft.setTextSize(4); tft.print(1234.567); delay(1500); tft.setCursor(0, 0); tft.fillScreen(ST77XX_BLACK); tft.setTextColor(ST77XX_WHITE); tft.setTextSize(0); tft.println("Hello World!"); tft.setTextSize(1); tft.setTextColor(ST77XX_GREEN); tft.print(p, 6); tft.println(" Want pi?"); tft.println(" "); tft.print(8675309, HEX); // print 8,675,309 out in HEX! tft.println(" Print HEX!"); tft.println(" "); tft.setTextColor(ST77XX_WHITE); tft.println("Sketch has been"); tft.println("running for: "); tft.setTextColor(ST77XX_MAGENTA); tft.print(millis() / 1000); tft.setTextColor(ST77XX_WHITE); tft.print(" seconds."); } void mediabuttons() { // play tft.fillScreen(ST77XX_BLACK); tft.fillRoundRect(25, 10, 78, 60, 8, ST77XX_WHITE); tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_RED); delay(500); // pause tft.fillRoundRect(25, 90, 78, 60, 8, ST77XX_WHITE); tft.fillRoundRect(39, 98, 20, 45, 5, ST77XX_GREEN); tft.fillRoundRect(69, 98, 20, 45, 5, ST77XX_GREEN); delay(500); // play color tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_BLUE); delay(50); // pause color tft.fillRoundRect(39, 98, 20, 45, 5, ST77XX_RED); tft.fillRoundRect(69, 98, 20, 45, 5, ST77XX_RED); // play color tft.fillTriangle(42, 20, 42, 60, 90, 40, ST77XX_GREEN); }

・「Adafruit ST7735 and ST7789 Library 」にあるExamplesを修正したもの。
・「#ifdef MICROBIT ... #endif」などで囲まれた部分が修正部分になる。

ビルド&書き込み

以下の手順でビルトと書き込みができる:

cd pico_proj # ツールなどのインストール(最初の1回のみ) pio run -t clean # ビルド&書き込み pio run -t upload # この時点で書き込みが完了する

書き込みが上手く行かない場合は、platformio.iniを以下のように変更すると正常に動作するようだ。
いったん、書き込みが正常動作した跡は、元に戻しても書き込みが正常動作するようだ。

#upload_port = /media/USER/MICROBIT #upload_protocol = mbed upload_protocol = cmsis-dap → upload_port = /media/USER/MICROBIT upload_protocol = mbed #upload_protocol = cmsis-dap

・USERは環境依存なので、実際の環境に合わせて変更する。

micro:bit-V2対応

以下のplatformio.iniでmicrobit-v2でビルド&書き込みができるが、正常動作しないようだ。
(原因不明)

platformio.ini

[env:bbcmicrobit_v2] platform = nordicnrf52 board = bbcmicrobit_v2 framework = arduino ;build_flags = -DMICROBIT_V2 build_flags = -DMICROBIT monitor_speed = 115200 lib_ldf_mode = deep+ #upload_port = /media/USER/MICROBIT #upload_protocol = mbed upload_protocol = cmsis-dap lib_deps = https://github.com/adafruit/Adafruit_BusIO/archive/master.zip https://github.com/sparkfun/SparkFun_MAG3110_Breakout_Board_Arduino_Library/archive/master.zip https://cdn-learn.adafruit.com/assets/assets/000/046/217/original/MMA8653.zip https://github.com/stm32duino/LSM303AGR/archive/master.zip https://github.com/adafruit/Adafruit-GFX-Library/archive/master.zip # adafruit/Adafruit ST7735 and ST7789 Library @ ^1.7.2

参考情報

LCD関連:
1.8inch LCD for micro:bit
1.8inch colorful display module for micro:bit, 160x128

Microbit_Arduino関連:
micro:bit Arduino/MBED開発ツール(v2)(micro:bit-v2対応,linux版)
micro:bitでmicrobit_screenライブラリを利用する(micro:bit-v2対応,linux版)
arduinoフレームワーク用platformio.ini集

platformio関連:
PlatformIO Core (CLI)
Arduino-IDEとPlatformioのコンパイラーの挙動の違いについて
arduinoフレームワーク用platformio.ini集
ubuntu20.04をインストールする

以上

続きを読む "LCDをmicrobit_arduinoで動かす"

| | コメント (0)

2021年1月11日 (月)

micro:bitでmicrobit_screenライブラリを利用する(micro:bit-v2対応,linux版)

2021/1/11
初版

pio microbit_screen lib

pio microbit_screen lib

概要

micro:bitで以下のmicrobit_screenライブラリを利用する(micro:bit-v2対応,linux版)

https://github.com/ht-deko/microbit_Screen

開発ツールとしてはplatformioを使用するが、そのインストールについては以下を参照のこと:

micro:bit Arduino/MBED開発ツール(v2)(micro:bit-v2対応,linux版)

該当ライブラリーのインストール方法

cd demo_sketch cd src wget https://raw.githubusercontent.com/ht-deko/microbit_Screen/master/microbit_Screen.cpp wget https://raw.githubusercontent.com/ht-deko/microbit_Screen/master/microbit_Screen.h

オリジナルは、microbit-v1対応なので、 microbit_Screen.hを以下のように修正して microbit-v1/v2両方対応にする。 src/microbit_Screen.h

<修正無しなので省略> #ifndef microbit_Screen_h #define microbit_Screen_h #include <Arduino.h> #ifdef MICROBIT const uint8_t max_cols PROGMEM = 9; const uint8_t max_rows PROGMEM = 3; const uint8_t colCount PROGMEM = 5; const uint8_t rowCount PROGMEM = 5; const uint8_t cols[max_cols] PROGMEM = {3, 4, 10, 23, 24, 25, 9, 7, 6}; const uint8_t rows[max_rows] PROGMEM = {26, 27, 28}; #endif #ifdef MICROBIT_V2 const uint8_t max_cols PROGMEM = 5; const uint8_t max_rows PROGMEM = 5; const uint8_t colCount PROGMEM = 5; const uint8_t rowCount PROGMEM = 5; const int cols[5] = {4, 7, 3, 6, 10}; const int rows[5] = {21, 22, 23, 24, 25}; #endif const uint32_t darknessValue = 493; const uint32_t brightnessValue = 20; typedef struct TPoint { uint8_t x; uint8_t y; } LED_POINT; #ifdef MICROBIT const LED_POINT LED_POS[rowCount][colCount] PROGMEM = { {{0, 0}, {3, 1}, {1, 0}, {4, 1}, {2, 0}}, {{3, 2}, {4, 2}, {5, 2}, {6, 2}, {7, 2}}, {{1, 1}, {8, 0}, {2, 1}, {8, 2}, {0, 1}}, {{7, 0}, {6, 0}, {5, 0}, {4, 0}, {3, 0}}, {{2, 2}, {6, 1}, {0, 2}, {5, 1}, {1, 2}} }; #endif #ifdef MICROBIT_V2 const LED_POINT LED_POS[rowCount][colCount] PROGMEM = { {{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}}, {{0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1}}, {{0, 2}, {1, 2}, {2, 2}, {3, 2}, {4, 2}}, {{0, 3}, {1, 3}, {2, 3}, {3, 3}, {4, 3}}, {{0, 4}, {1, 4}, {2, 4}, {3, 4}, {4, 4}} }; #endif const uint8_t LED_FONT[96][colCount] PROGMEM = <修正無しなので省略>

arduino用のplatformio.ini

microbit-v1用

; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:bbcmicrobit] platform = nordicnrf51 board = bbcmicrobit framework = arduino build_flags = -DMICROBIT -DNRF51_S110 monitor_speed = 115200 lib_ldf_mode = deep+ upload_protocol = cmsis-dap lib_deps = https://github.com/adafruit/Adafruit_BusIO/archive/master.zip https://github.com/sparkfun/SparkFun_MAG3110_Breakout_Board_Arduino_Library/archive/master.zip https://cdn-learn.adafruit.com/assets/assets/000/046/217/original/MMA8653.zip https://github.com/stm32duino/LSM303AGR/archive/master.zip https://github.com/adafruit/Adafruit-GFX-Library/archive/master.zip # https://github.com/sandeepmistry/arduino-BLEPeripheral/archive/master.zip https://github.com/adafruit/Adafruit_Microbit/archive/master.zip

microbit-v2用

; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:bbcmicrobit_v2] platform = nordicnrf52 board = bbcmicrobit_v2 framework = arduino build_flags = -DMICROBIT_V2 monitor_speed = 115200 lib_ldf_mode = deep+ upload_protocol = cmsis-dap lib_deps = https://github.com/adafruit/Adafruit_BusIO/archive/master.zip https://github.com/sparkfun/SparkFun_MAG3110_Breakout_Board_Arduino_Library/archive/master.zip https://cdn-learn.adafruit.com/assets/assets/000/046/217/original/MMA8653.zip https://github.com/stm32duino/LSM303AGR/archive/master.zip https://github.com/adafruit/Adafruit-GFX-Library/archive/master.zip # #https://github.com/sandeepmistry/arduino-BLEPeripheral/archive/master.zip #https://github.com/adafruit/Adafruit_Microbit/archive/master.zip

デモ・スケッチ

以下はv1/v2の両方で動作する:

src/demo.ino

#include "microbit_Screen.h" void setup() { SCREEN.begin(); } void loop() { //SCREEN.showString("HELLO,WORLD."); //SCREEN.showString("micro:bit!"); // patched pattern for MB2 SCREEN.showAnimation((String) ". # . . . # # # . . # # # . ." + "# # . . . . . # . . . . # . ." + ". # . . . . # . . . # # # . ." + ". # . . . # . . . . . . # . ." + ". # . . . # # # . . # # # . ." ); // SCREEN.showIcon(IconNames::Heart); }

microbit-V2では該当ライブラリの修正変更にバグがあり右側から2番目の列のLEDが光らないので 数字の1,2,3を表示した後、欠けたハートマークが表示される。 (今のところ原因不明)
当然のことながらV1では正常に動作する。

参考情報

BBC micro:bit/Arduino化に特化した話

PlatformIO Core (CLI)

以上

続きを読む "micro:bitでmicrobit_screenライブラリを利用する(micro:bit-v2対応,linux版)"

| | コメント (0)

2021年1月 9日 (土)

micro:bit Yotta開発ツール(linux版)

2021/1/9
初版

yotta micro:bit MBED tool

yotta micro:bit MBED tool

概要

micro:bit Yotta開発ツール(linux版)
なお、本ツールは、microbit-v1用である。

インストール手順

mkdir microbit_ws cd microbit_ws # 必要なライブラリやツールをインストールする sudo apt-get update && sudo apt-get install python-setuptools cmake build-essential ninja-build python-dev libffi-dev libssl-dev && sudo easy_install pip # yotta をインストールする sudo pip install yotta # micoribt-samples をダウンロードする git clone https://github.com/lancaster-university/microbit-samples cd microbit-samples # yottaの設定 yt target bbc-microbit-classic-gcc # src/main.cppがターゲットソースになる yt build # ビルド結果(hex)をmicrobitに転送する # <USER>は実際の環境に合わせる cp build/bbc-microbit-classic-gcc/source/microbit-samples-combined.hex /media/<USER>/MICROBIT/

なお、source/examples に他のサンプルがある。

参考情報

Yotta/Installation on Linux

yotta Documentation
yotta: Build Software with Reusable Components

https://os.mbed.com/users/MACRUM/notebook/microbit/
micro:bit の使い方

https://github.com/toyowata/microbit_web_bluetooth/blob/master/README.md
Web Bluetooth(micro:bitとbluetooth接続してブラウザから制御する)

以上

続きを読む "micro:bit Yotta開発ツール(linux版)"

| | コメント (0)

2021年1月 2日 (土)

micro:bit Arduino/MBED開発ツール(v2)(micro:bit-v2対応,linux版)

2021/1/9+
・BLE関連ライブラリでビルドできなかったが platformio.iniを変更してビルド可能にした。
・SoftDevice書き込みツールの インストール方法を追加した。

2021/1/5
SoftDevice(bleファームウェア)の再書き込みについて記載した。

2021/1/2
初版

cli micro:bit Arduino/MBED tool

cli micro:bit Arduino/MBED tool

概要

micro:bit Arduino/MBED開発ツール(v2)(micro:bit-v2対応,linux版)

この記事は「 micro:bit MBED開発ツール(VScode+PlatformIO) 」の続編にあたり、arduinoプラットフォームでの設定やmicro:bit-v2の対応方法についても記述している。
(ホストはubuntuを想定している)

PlatformIOのインストール

python3 -m venv pio_env source pio_env/bin/activate pip3 install platformio インストール後も、本ツールを使用する場合 同じディレクトリで以下を実行する: source pio_env/bin/activate # 「source」は、「.」でも良い

準備

以下を実行して、udevのrulesを登録する:

curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core/master/scripts/99-platformio-udev.rules | sudo tee /etc/udev/rules.d/99-platformio-udev.rules sudo udevadm control --reload-rules sudo usermod -a -G dialout $USER sudo usermod -a -G plugdev $USER

microbit-v2対応

microbit-v2の対応がまだ未完了のようなので、以下を行なう必要がある。

cd ~/.platformio/boards # boardsがなければmkdirで作成する wget https://raw.githubusercontent.com/platformio/platform-nordicnrf52/master/boards/bbcmicrobit_v2.json

bbcmicrobit_v2.jsonの内容にミスがあるので 以下のように修正する:

"name": "BBC micro:bit V2", "upload": { "maximum_ram_size": 65536, "maximum_size": 524288, "protocol": "cmsis-dap", "protocols": [ "jlink", 上を以下のように修正する: "name": "BBC micro:bit V2", "upload": { "maximum_ram_size": 131072, "maximum_size": 524288, "protocol": "cmsis-dap", "protocols": [ "jlink",

RAMサイズが間違っていた。(64KB→128KB)

コンパイル時(pio run)で以下のようなメッセージになればOK.

-------------------------------------------------------------------------------- Verbose mode can be enabled via `-v, --verbose` option CONFIGURATION: https://docs.platformio.org/page/boards/nordicnrf52/bbcmicrobit_v2.html PLATFORM: Nordic nRF52 (6.0.0) > BBC micro:bit V2 HARDWARE: NRF52833 64MHz, 128KB RAM, 512KB Flash DEBUG: Current (cmsis-dap) On-board (cmsis-dap) External (blackmagic, jlink, stlink) PACKAGES: - framework-arduinonordicnrf5 1.700.201209 (7.0) - tool-bossac-nordicnrf52 1.10901.201022 (1.9.1)

ちなみにv1の場合は以下のようになる:

-------------------------------------------------------------------------------- Verbose mode can be enabled via `-v, --verbose` option CONFIGURATION: https://docs.platformio.org/page/boards/nordicnrf51/bbcmicrobit.html PLATFORM: Nordic nRF51 (6.1.0) > BBC micro:bit HARDWARE: NRF51822 16MHz, 16KB RAM, 256KB Flash DEBUG: Current (cmsis-dap) On-board (cmsis-dap) External (jlink) PACKAGES: - framework-arduinonordicnrf5 1.700.201209 (7.0) - tool-nrfjprog 1.90702.1 (9.7.2)

arduino用のplatformio.ini

microbit-v1用

; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:bbcmicrobit] platform = nordicnrf51 board = bbcmicrobit framework = arduino build_flags = -DMICROBIT monitor_speed = 115200 lib_ldf_mode = deep+ #upload_port = /media/USER/MICROBIT #upload_protocol = mbed upload_protocol = cmsis-dap lib_deps = https://github.com/adafruit/Adafruit_BusIO/archive/master.zip https://github.com/sparkfun/SparkFun_MAG3110_Breakout_Board_Arduino_Library/archive/master.zip https://cdn-learn.adafruit.com/assets/assets/000/046/217/original/MMA8653.zip https://github.com/stm32duino/LSM303AGR/archive/master.zip https://github.com/adafruit/Adafruit-GFX-Library/archive/master.zip # #https://github.com/sandeepmistry/arduino-BLEPeripheral/archive/master.zip #https://github.com/adafruit/Adafruit_Microbit/archive/master.zip

BLE関連を含むライブラリはコンパイルエラーになるのでコメントアウトしている。 コンパイルエラーになる原因は不明(今後、調査予定)(2021/1/9時点で解決)

microbit-v2用

; PlatformIO Project Configuration File ; ; Build options: build flags, source filter ; Upload options: custom upload port, speed and extra flags ; Library options: dependencies, extra library storages ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html [env:bbcmicrobit_v2] platform = nordicnrf52 board = bbcmicrobit_v2 framework = arduino build_flags = -DMICROBIT_V2 monitor_speed = 115200 lib_ldf_mode = deep+ #upload_port = /media/USER/MICROBIT #upload_protocol = mbed upload_protocol = cmsis-dap lib_deps = https://github.com/adafruit/Adafruit_BusIO/archive/master.zip https://github.com/sparkfun/SparkFun_MAG3110_Breakout_Board_Arduino_Library/archive/master.zip https://cdn-learn.adafruit.com/assets/assets/000/046/217/original/MMA8653.zip https://github.com/stm32duino/LSM303AGR/archive/master.zip https://github.com/adafruit/ Adafruit-GFX-Library/archive/master.zip # #https://github.com/sandeepmistry/arduino-BLEPeripheral/archive/master.zip #https://github.com/adafruit/Adafruit_Microbit/archive/master.zip

BLE関連を含むライブラリはコンパイルエラーになるのでコメントアウトしている。 コンパイルエラーになるのはmicrobit-v2のプロセッサ対応が未完のせいが考えられる。

テスト用スケッチ

以下はv1/v2の両方で動作する:

src/ASCIItable.ino

/* ASCII table Prints out byte values in all possible formats: - as raw binary values - as ASCII-encoded decimal, hex, octal, and binary values For more on ASCII, see http://www.asciitable.com and http://en.wikipedia.org/wiki/ASCII The circuit: No external hardware needed. created 2006 by Nicholas Zambetti <http://www.zambetti.com> modified 9 Apr 2012 by Tom Igoe This example code is in the public domain. http://www.arduino.cc/en/Tutorial/ASCIITable */ void setup() { //Initialize serial and wait for port to open: Serial.begin(115200); while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only } // prints title with ending line break Serial.println("ASCII Table ~ Character Map"); } // first visible ASCIIcharacter '!' is number 33: int thisByte = 33; // you can also write ASCII characters in single quotes. // for example, '!' is the same as 33, so you could also use this: // int thisByte = '!'; void loop() { // prints value unaltered, i.e. the raw binary version of the byte. // The Serial Monitor interprets all bytes as ASCII, so 33, the first number, // will show up as '!' Serial.write(thisByte); Serial.print(", dec: "); // prints value as string as an ASCII-encoded decimal (base 10). // Decimal is the default format for Serial.print() and Serial.println(), // so no modifier is needed: Serial.print(thisByte); // But you can declare the modifier for decimal if you want to. // this also works if you uncomment it: // Serial.print(thisByte, DEC); Serial.print(", hex: "); // prints value as string in hexadecimal (base 16): Serial.print(thisByte, HEX); Serial.print(", oct: "); // prints value as string in octal (base 8); Serial.print(thisByte, OCT); Serial.print(", bin: "); // prints value as string in binary (base 2) also prints ending line break: Serial.println(thisByte, BIN); // if printed last visible character '~' or 126, stop: if (thisByte == 126) { // you could also use if (thisByte == '~') { // This loop loops forever and does nothing while (true) { continue; } } // go on to the next character thisByte++; }

arduinoのサンプルそのもの(bpsのみ変更)

src/microbit_blink.ino

#ifdef MICROBIT const int COL1 = 3; // Column #1 control const int LED = 26; // 'row 1' led #endif #ifdef MICROBIT_V2 const int COL1 = 4; const int LED = 21; #endif void setup() { Serial.begin(115200); Serial.println("microbit is ready!"); // because the LEDs are multiplexed, we must ground the opposite side of the LED pinMode(COL1, OUTPUT); digitalWrite(COL1, LOW); pinMode(LED, OUTPUT); } void loop(){ Serial.println("blink!"); digitalWrite(LED, HIGH); delay(100); digitalWrite(LED, LOW); delay(100); }

MatrixLEDの仕様が変更になったので#ifdefで切り替えている。

テスト用スケッチ(ビルドエラーが起きるもの)

以下は、platformioでライブラリがBLEに関係がありエラーになった例である:

src/matrixdemo.ino

// This is a demo of the matrix driver code // works with Adafruit GFX commands - its just // a really small screen! // https://learn.adafruit.com/adafruit-gfx-graphics-library #include <Adafruit_Microbit.h> Adafruit_Microbit_Matrix microbit; const uint8_t smile_bmp[] = { B00000, B01010, B00000, B10001, B01110, }; void setup() { Serial.begin(9600); Serial.println("microbit matrix demo is ready!"); microbit.begin(); } void loop(){ // Fill screen microbit.fillScreen(LED_ON); delay(1000); // draw a heart microbit.show(microbit.HEART); delay(1000); // draw a no cross microbit.show(microbit.NO); delay(1000); // draw a yes check microbit.show(microbit.YES); delay(1000); // draw a custom made bitmap face microbit.show(smile_bmp); delay(1000); microbit.clear(); // Draw a line 'by hand' microbit.drawPixel(0, 0, LED_ON); microbit.drawPixel(1, 1, LED_ON); microbit.drawPixel(2, 2, LED_ON); microbit.drawPixel(3, 3, LED_ON); microbit.drawPixel(4, 4, LED_ON); // draw the 'opposite' line with drawline (easier!) microbit.drawLine(0, 4, 4, 0, LED_ON); delay(1000); // erase screen, draw a square microbit.clear(); microbit.drawRect(0,0, 5, 5, LED_ON); // top left corner @ (0,0), 5 by 5 pixels size delay(1000); // erase screen, draw a circle microbit.clear(); microbit.drawCircle(2,2, 2, LED_ON); // center on 2, 2, radius 2 delay(1000); // erase screen, draw a filled triangle microbit.clear(); microbit.fillTriangle(0,4, 2,0, 4,4, LED_ON); delay(1000); // scroll some text the 'easy' way microbit.print("HELLO WORLD"); // count up! for (int i=0; i<10; i++) { microbit.print(i); delay(500); } microbit.print(3.1415, 4); // pi time, 4 digits of precision!! }

本家のArduino-IDEではコンパイルができて実行もできた。(だだしv1のみ)

動作しない場合、SoftDevice(BLEファームウェア)が消されている可能性があるので
以下でダウンロードしたhexファイルをMICROBITフォルダにドラッグ&ドロップ後、
書き込みを行なう。(Softdevice:"S110"にすることを忘れずに!)

wget https://cdn-learn.adafruit.com/assets/assets/000/046/777/original/microbit-adv.hex

上の方法は、簡易的な方法になる。正式な書き込みツールのインストール方法については参考情報のリンクを参照のこと。

src/ble_uartdemo.ino

/* * Serial Port over BLE * Create UART service compatible with Nordic's *nRF Toolbox* and Adafruit's *Bluefruit LE* iOS/Android apps. * * Copyright (c) Sandeep Mistry. All rights reserved. * Licensed under the MIT license. See LICENSE file in the project root for full license information. * BLESerial class implements same protocols as Arduino's built-in Serial class and can be used as it's wireless * replacement. Data transfers are routed through a BLE service with TX and RX characteristics. To make the * service discoverable all UUIDs are NUS (Nordic UART Service) compatible. * * Please note that TX and RX characteristics use Notify and WriteWithoutResponse, so there's no guarantee * that the data will make it to the other end. However, under normal circumstances and reasonable signal * strengths everything works well. */ #include <Adafruit_Microbit.h> Adafruit_Microbit microbit; void setup() { Serial.begin(115200); Serial.println("Microbit ready!"); // custom services and characteristics can be added as well microbit.BTLESerial.begin(); microbit.BTLESerial.setLocalName("microbit"); // Start LED matrix driver after radio (required) microbit.begin(); } void loop() { microbit.BTLESerial.poll(); forward(); //loopback(); spam(); } // forward received from Serial to microbit.BTLESerial and vice versa void forward() { if (microbit.BTLESerial && Serial) { int byte; if (microbit.BTLESerial.available()) { Serial.write(microbit.BTLESerial.read()); } char buffer[10]; memset(buffer, 0x0, 10); int idx = 0; while (Serial.available() && idx != 10) { buffer[idx] = Serial.read(); idx++; } if (idx) { microbit.BTLESerial.write(buffer, idx); } } delay(1); } // echo all received data back void loopback() { if (microbit.BTLESerial) { int byte; while ((byte = microbit.BTLESerial.read()) > 0) { microbit.BTLESerial.write(byte); } } } // periodically sent time stamps void spam() {  if (microbit.BTLESerial) { microbit.BTLESerial.print(millis()); microbit.BTLESerial.println(" tick-tacks!"); delay(1000); } }

本家のArduino-IDEではコンパイルができて実行もできた。(だだしv1のみ)

動作しない場合、SoftDevide(BLEファームウェア)が消されている可能性があるので
以下でダウンロードしたhexファイルをMICROBITフォルダにドラッグ&ドロップ後、
書き込みを行なう。(Softdevice:"S110"にすることを忘れずに!)

wget https://cdn-learn.adafruit.com/assets/assets/000/046/777/original/microbit-adv.hex

上の方法は、簡易的な方法になる。正式な書き込みツールのインストール方法については参考情報のリンクを参照のこと。

対向するフマフォ・アプリは以下になる:
Bluefruit Connect/iPhone
Bluefruit Connect/Android

スマフォ・アプリ使用時、デバイスのMACアドレスだけでデバイス名がないので
「Uart Capable」と付記があるアドレスのデバイスを選択すること。

Arduino-IDEを使用する際の設定

(1)IDEを起動して[ファイル/環境設定(Preferences)]に入り 以下のurlを[追加のボードマネージャーのURL]のテキストボックスに以下を入力する。 https://sandeepmistry.github.io/arduino-nRF5/package_nRF5_boards_index.json (2)[ツール/ボード/ボードマネージャ(Tools>Board>Boards Manager)]で「nRF5」で検索して "Nordic Semiconductor nRF5 Boards" by Sandeep Mistry をインストールする (3)platformio.iniに登録されているzipのurlにアクセスしてzipファイルをダウンロードする (4)[スケッチ/ライブラリをインクルード/.ZIP形式でインストール]でダウンロードしたzipファイルを指定してインストールする

注意:
ボードとして [BBC micro:bit](v1)を選択した場合、Softdeviceは"S110"に設定すること。
v2の場合、不要(設定できない)

ショートカット:

上の(3)(4)は以下の方法でも良い: cd ~/Arduino/libraries wget https://xxxxx/archive/master.zip unzip master.zip rm master.zip # 以上をファイルの数だけ繰り返す

mbed対応

上で述べたplatformio.iniのplatformのところを以下のように変更するとmbed対応になる。

framework = arduino 以下のように変更する: framework = mbed

ただし、v2は、まだ、mbed対応になっていなのでエラーになる。 また、当然のことながら、arduino用ライブラリでなくmbed用ライブラリを使うこと。

また、microbit-v1用開発ツールとして以下のものを使用する選択肢もある:
micro:bit Yotta開発ツール(linux版)

platformioでBLE関連ライブラリがビルドできなかった問題の解決(2021/1/9)

microbit-v1用のplatformio.iniを以下のように変更する:
(変更箇所のみ記載)

<省略> build_flags = -DMICROBIT -DNRF51_S110 <省略> # https://github.com/sandeepmistry/arduino-BLEPeripheral/archive/master.zip https://github.com/adafruit/Adafruit_Microbit/archive/master.zip <省略>

具体的には、ビルドできなかった以下のスケッチがビルド&実行可能になる。

src/matrixdemo.ino src/ble_uartdemo.ino

ただし、ble_uartdemo.ino は参照エラーになるので
ソースの先頭に以下のプロトタイプ宣言を追加すること:

// prototype definitions void forward(); void spam(); void loopback();

参考情報

SoftDevice書き込みツールのインストール方法
https://github.com/sandeepmistry/arduino-nRF5#flashing-a-softdevice

Flashing a SoftDevice cd <SKETCHBOOK>, where <SKETCHBOOK> is your Arduino Sketch folder: OS X: ~/Documents/Arduino Linux: ~/Arduino Windows: ~/Documents/Arduino Create the following directories: tools/nRF5FlashSoftDevice/tool/ Download nRF5FlashSoftDevice.jar to <SKETCHBOOK>/tools/nRF5FlashSoftDevice/tool/ wget https://github.com/sandeepmistry/arduino-nRF5/releases/download/tools/nRF5FlashSoftDevice.jar Restart the Arduino IDE Select your nRF board from the Tools -> Board menu Select a SoftDevice from the Tools -> "SoftDevice: " menu Select a Programmer (J-Link, ST-Link V2, or CMSIS-DAP) from the Tools -> "Programmer: " menu Select Tools -> nRF5 Flash SoftDevice Read license agreement Click "Accept" to accept license and continue, or "Decline" to decline and abort If accepted, SoftDevice binary will be flashed to the board

micro:bit v2 で遊ぶ

platformio関連:

https://docs.platformio.org/en/latest/boards/nordicnrf52/bbcmicrobit_v2.html https://docs.platformio.org/en/latest/platforms/creating_board.html Installation 1.Create boards directory in core_dir if it doesn’t exist. 2.Create myboard.json file in this boards directory. 3.Search available boards via pio boards command. You should see myboard board.

PlatformIO Core (CLI)

以上

続きを読む "micro:bit Arduino/MBED開発ツール(v2)(micro:bit-v2対応,linux版)"

| | コメント (0)

2020年5月10日 (日)

プログラミング言語Rustをmicro:bitボードで動かす

2020/5/10

Rust micro:bit

Rust micro:bit

概要

プログラミング言語Rustを以下のmicro:bitボードで動かす。 (ホストPCとしてはubuntuを想定している)

micro:bit

関連ツールのインストール

以下で必要なツールをインスールする:
(0)rustツールのインストール

curl https://sh.rustup.rs -sSf | sh

(1)Cコンパイラのバージョンアップ
binを作成するのに、これに含まれるツールを使用するのでインストールする

以下でインストールしたコンパイラが古くてビルドエラーが出たのでバージョンアップする。 sudo apt-get install gcc-arm-none-eabi (1)以下のurlから最新版をダウンロードする: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads 解凍したものを以下のフォルダに置く: $HOME/Downloads/gcc-arm-none-eabi-8-2019-q3-update (2)パス設定 #古いコンパイラを削除する sudo apt-get remove gcc-arm-none-eabi #パスを設定する export PATH=$PATH:$HOME/Downloads/gcc-arm-none-eabi-8-2019-q3-update/bin

exportは、.bashrcに登録する

(2)その他の必要ツールのインストール

sudo apt-get install openocd sudo apt-get install picocom

事前準備

openocdとgdbを使用してビルドしたelfを自動的に書き込むので 以下のように起動時の.gdbinitを用意する:

(1)~/.gdbinit
以下の内容に編集する:

add-auto-load-safe-path /home/user/rust_ws/mb_work/microbit/.gdbinit

上の「/home/user/rust_ws/mb_work/microbit/」は、gdb実行時のカレント・ディレクトリになるので、自分の環境に合わせる。

(2)~/rust_ws/mb_work/microbit/.gdbinit
以下の内容に編集する:

target remote :3333 monitor arm semihosting enable load continue

(3)別の端末でopenocdを起動しておく。
micro:bitをホストPCと接続して 以下を実行する。
(gdbの接続待ちになる)

openocd -f interface/cmsis-dap.cfg -f target/nrf51.cfg

シリアルを利用したサンプルを実行する場合、 さらに別端末でシリアル通信を起動しておく。

picocom /dev/ttyACM0 -b115200

samplesを実行する

以下を実行する:

rustup update rustup target add thumbv6m-none-eabi #サンプルをgitでダウンロードする git clone https://github.com/therealprof/microbit.git cd microbit #たとえば、以下のうち一つを実行すると #gdbが自動的に起動しプログラムを書き込んで実行される cargo run --example gpio_hal_blinky cargo run --example serial_direct_helloworld cargo run --example gpio_hal_ledbutton cargo run --example gpio_hal_printbuttons cargo run --example led_rtfm cargo run --example serial_hal_blocking_echo #以下、gdbの出力例: .. semihosting is enabled Loading section .vector_table, size 0xa8 lma 0x0 Loading section .text, size 0x486c lma 0xa8 Loading section .rodata, size 0xc14 lma 0x4920 Start address 0x4768, load size 21800 #この時点で、書き込んだプログラムが実行される

なお、gdbから抜ける場合は、quitを実行する。

実行結果

1.gpio_hal_blinky
micro:bitのLEDの一つが点滅する。

2.gpio_hal_ledbutton
ボタンを押すとLEDが光る。

3.led_rtfm
LEDがハートマークに光る。

4.serial_direct_helloworld
シリアル出力で'hello world'が出力される。

5.serial_hal_blocking_echo
エコープログラムになっており シリアル通信の画面で入力すると 入力した文字が返ってくる。

6.gpio_hal_printbuttons
ボタンを押すと、その状態を示す テキストがシリアル出力される。

なお、上のものは、色々あるサンプルのうちの一部である。

参照情報

micro:bit

The Embedded Rust Book
The Embedded Rust Book - Semihosting

UbuntuにRustをインストールする

以上

続きを読む "プログラミング言語Rustをmicro:bitボードで動かす"

| | コメント (0)