📖

seeed xiao nRF52840の開発基礎(Mu editorでcircuitPython)

2023/06/10に公開

本当はmicropythonで書きたいところですが、ファームウェアの関係でESP32やラズパイPicoのように書けません(ubluetoothが使えないのが致命的)

公式ガイドやネット上に転がっている情報の多さではC言語で書くのが良さそうですが、私はあまりC言語を使えないのと、Arduino IDEは使いにくいので、Mu editorを使ってcircuitPythonで書きました。

circuitPythonは教育を目的として、microPythonを初心者でも使いやすくしたものらしいのですが、ぶっちゃけmicropythonの方がシンプルに書けますので使い勝手は良いです。

circuitPythonのドキュメント

https://docs.circuitpython.org/en/latest/docs/index.html

Mu editorの基本

コメントアウトのショートカットキーはコマンド+K

ボードLチカ

そもそもLチカの部分からcircuitPythonは書き方が違います。

xiaoには3色のLEDが付いており、これらはLED、LED_GREEN、LED_BLUEという名前で指定できます

気をつけなければならないのが、digitalioはFalseでオン、Trueでオフというようにvalueとオンオフが逆なことです。

import time
import board
import digitalio

led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT

green_led = digitalio.DigitalInOut(board.LED_GREEN)
green_led.direction = digitalio.Direction.OUTPUT

blue_led = digitalio.DigitalInOut(board.LED_BLUE)
blue_led.direction = digitalio.Direction.OUTPUT

while True:
    print('青色のみ点灯')
    led.value = True
    green_led.value = True
    blue_led.value = False
    time.sleep(1)
    print('赤色のみ点灯')
    led.value = False
    green_led.value = True
    blue_led.value = True
    time.sleep(1)
    print('緑色のみ点灯')
    led.value = True
    green_led.value = False
    blue_led.value = True
    time.sleep(1)

ちなみにmicropythonだとこんな書き方です。Pinはサポートされていません。

# main.py
from board import LED
from machine import RTCounter, Temp

greenLed = LED(2)

greenLed.on()

使いやすくするために、クラスにしました

from led import LED

led = LED()
blue_led = LED('LED_BLUE')
green_led = LED('LED_GREEN')


while True:
    led.on()
    time.sleep(1)
    led.off()
    time.sleep(1)
import board
from digitalio import DigitalInOut, Direction

class LED():
    led: DigitalInOut
    
    def __init__(self, color='LED'): # colorは'LED', 'LED_GREEN', 'LED_BLUE'
        self.led = DigitalInOut(getattr(board, color))
        self.led.direction = Direction.OUTPUT
        self.led.value = True
        
    def on(self):
        self.led.value = False
        
    def off(self):
        self.led.value = True

ディープスリープ

nRF52480の特徴は何と言っても消費電力が少ないこと。ディープスリープ自体はESP32にもありますが、ESP32のディープスリープ中の消費電力は0.1mA程度であるのに対して、nRFは5μA程度と桁違いに消費電力が少ないです。

ディープスリープの解除は、タイマー、ピン状態、タッチセンサーの3種類あります。

まずはタイマーで5秒おきにディープスリープに入るプログラムです。
ディープスリープに入ると、変数に入れた値は消えてしまうのですが、alarm.sleep_memoryに保存しておくことでデータを保持することができます。
ちなみにtime.monotonic()とはnRFを電源に繋いでからの時間(秒 float型)です。

import time
from led import LED
import board
import alarm

led = LED()

count = 0

while True:
    led.on()
    time.sleep(1)
    count = alarm.sleep_memory[0]
    count = count+1
    print(count)
    
    # スリープ前にメモリにデータを保存
    alarm.sleep_memory[0] = count
    time_alarm = alarm.time.TimeAlarm(monotonic_time = time.monotonic()+5)
    alarm.exit_and_deep_sleep_until_alarms(time_alarm)

ピンでディープスリープを解除したい場合は、ピンにPinAlarmを割り当てます

import time
from led import LED
import board
import alarm

led = LED()

count = 0
pin_alarm = alarm.pin.PinAlarm(board.D10, value=False) # 追加

while True:
    led.on()
    time.sleep(1)
    count = alarm.sleep_memory[0]
    count = count+1
    print(count)
    
    # スリープ前にメモリにデータを保存
    alarm.sleep_memory[0] = count
    time_alarm = alarm.time.TimeAlarm(monotonic_time = time.monotonic()+5)
    alarm.exit_and_deep_sleep_until_alarms(time_alarm,pin_alarm) # 追加

Discussion