うごくものをつくる

個人的な学習ノート

基礎技術メモ

【メモ】SiPEED Maixマイコンボードのデジタル入出力

ブログ更新サボりすぎ問題……

仕事の忙しさと生来の怠け心のせいで、日々ブログに書くほど新たな知識を勉強してるわけではない……なんて言い訳をしてても仕方ないので、ちょっとしたことでも記事に残していく。

今回は、SiPEED Maixマイコンボードシリーズ(Maix BitとかMaix Dockとか)で、デジタル入出力を使う方法のメモ。

そんなもん公式ドキュメントを見れば一発なので需要があるかは分からないが、自分用のメモとして他にネタもないので書いていく。

1. GPIOの番号について(Arduinoとの違い)

デジタル入出力というと、マイコンボードの基本的機能である。

例えばArduinoなんかだと、LEDをデジタル2番ピン(D2)に繋いで、プログラム側でD2を1秒おきにオン・オフするようなプログラムを書いてやると、LEDが1秒おきに点滅するような作品が作れる。

ここで、ArduinoにおけるD2ピンというのは、たった一つに決まっている。それは基板上に「D2」という印(あるいは単に「2」とだけ書かれた印)で示されたピンのことであり、Arduino UNOの搭載マイコンであるATmega328Pについて言えば、D2とはマイコンICの4番ピンである。

他のピンをD2として使うこともできないし、D2のピン(すなわちICの4番ピン)を、D1やD3のような他の番号のデジタル出力として使うことも、通常できない。

しかし、SiPEED Maixシリーズのマイコンボードは(というか、それらのボードに使われているkendryte K210マイコンは)、GPIOのピン番号を自由に決めて使うことができる。

もちろん全く制約がないわけではないが、GPIOとして使うために用意されたピンであれば、そのどれを1番とし、どれを2番とするか……というのは、開発者各自が好きに選ぶことができる。

逆に言うと、デジタル入出力を使いたいのであれば、どのピンをデジタル何番として使用します、というのを、ちゃんとプログラム内で書いてマイコンに教えてあげなければならない。

2. GPIO ピン番号の設定

まずは、GPIO番号を設定するために必要な機能を、インポートしておく。

from Maix import GPIO, FPIOA
from fpioa_manager import fm

次に、GPIOに使いたいピン番号を選び、それをデジタル何番に設定するか記述する。

Fpioa = FPIOA()#Fpioa使う前のおまじない
Fpioa.set_function(35, fm.fpioa.GPIO1)#他に役割のない35番ピンをGPIO1に設定。

今回は、35番ピンをGPIOの1、すなわちデジタル1番の出力ピンとして使用することにした。ここで、35番ピンとは、ボード上に35と書かれているピンのこと。

これね。(写真はMaix Bit)

なお、コード内のコメントにある「他に役割のない……」とは、マイコン側が持つ特殊な役割のあるピン(カメラユニットやディスプレイの駆動に使われるようなピン)ではない、という意味。

たとえ特殊な役割を持っていても、その機能を使わない(カメラやディスプレイを繋がないで使う場合など)は、番号付きでボードに出されている時点でGPIOとして使用OKということなんだと思う。

ちなみに、Fpioaという機能でどのピンをGPIO何番とするか決めるわけだけど、この機能を使う前にはFpioa = FPIOA()と書いておかないといけない。なぜなのかはよくわからない。

3. デジタル出力

先程、35番ピンをGPIO1として設定したが、GPIO1は出力ピンなのか、それとも入力ピンなのかを設定しなければならない。

ここでは、出力として使う。その設定方法は以下の通り。

led_1=GPIO(GPIO.GPIO1,GPIO.OUT)#35番ピン(GPIO1)にLEDをつなぎ、出力設定

GPIO.OUTと書いてやれば、出力ピンとなる。今後このピンを使うための名前を、好きに決めておく。(ここでは、led_1という名前にした。)

これでデジタル出力ができるようになったので、試しに35番ピンにLEDをつなぎ、GPIO1の出力を0.5秒おきにハイとローを入れ替えるようなプログラムを組み、それを実行してみる。

実行したコードはこれ↓

# Untitled - By: K.Shj - 月 7 19 2021

import time

from Maix import GPIO, FPIOA
from fpioa_manager import fm

Fpioa = FPIOA()#Fpioa使う前のおまじない
Fpioa.set_function(35, fm.fpioa.GPIO1)#他に役割のない35番ピンをGPIO1に設定。
led_1=GPIO(GPIO.GPIO1,GPIO.OUT)#35番ピン(GPIO1)にLEDをつなぎ、出力ピンとして設定。今後はled_1という名前で使うことにする。

while(True):
    led_1.value(1)#値に1を入れると出力ハイになる
    time.sleep_ms(500)#500ミリ秒、すなわち0.5秒待つ
    led_1.value(0)#値に0を入れると出力ローになる
    time.sleep_ms(500)

これを実行したらこんな感じ。

ちゃんと0.5秒おきにLEDがオンオフの点滅をしている。

4. デジタル入力

上で実行したコード&回路の状態から、デジタル入力ピンを追加する。先程と同様にして、まずは33番ピンをGPIO2番として設定する。

そのGPIO2は入力ピンとして設定する。先程の出力のときのように、今後使うための名前を任意で設定する。ここではsw1という名前にした。

Fpioa.set_function(33, fm.fpioa.GPIO2)#33番ピンをGPIO2に設定。
sw1=GPIO(GPIO.GPIO2,GPIO.IN)#33番ピン(GPIO2)は入力ピンとして設定。

なお、ここではGPIO.INという記述で入力ピン設定したが、Arduinoで入力ピンを設定するときによく使われる「内部プルアップ」も使うことができる。

内部プルアップとは、入力ピンを内部的に抵抗を介して電源につなぐことで、ボタンが押されていないときのような何の入力もないとき、確実に「1」が入力されるためのものだ。

これをしなかったら、何の入力もないときには本来「0」が入力されるべきなのだが、周囲のノイズを拾ってしまい、何もしていないのに0や1がフラフラと入力されてしまうので、ボタンを押してもないのに押したときのような動作をするトラブルが起こる。

これを防ぐために、内部プルアップをするのだ。内部プルアップを使って入力ピンの設定をするには、先程の記述をGPIO.INではなく以下のように変える。

sw1=GPIO(GPIO.GPIO2,GPIO.PULL_UP)

これでプルアップされるので、スイッチの片側をGNDに繋いでやることで、「ボタンを押したときに入力0, ボタンを押していないときは入力1」といった状態になる。

なお、内部プルダウンも同様にして使うことができる。

sw1=GPIO(GPIO.GPIO2,GPIO.PULL_DOWN)

こうすると、プルアップのときとは逆に、 「ボタンを押したときに入力1, ボタンを押していないときは入力0」といった状態になる。 このときは、スイッチの片側はGNDではなく電源(3.3V)につなぐ。

プルアップとプルダウンのどっちが良いかは各々で好きに決めてほしい。

入力値を読む方法は、

sw_in = sw1.value()

とする。デジタル出力のときと書き方が似ているが、カッコの中には何も入れない。これで、GPIO2入力(sw1の状態)がハイならば変数sw_inに1が、ローなら0が代入される。変数の名前は何でもいい。

というわけで、ボタンを押していないときはLEDが消灯しているが、ボタンを押すと高速点滅をするプログラムを実行してみよう。以下のコードを実行する。今回はプルアップ設定としたので、ボタンはGNDに繋ぐ。ボタンが押されているときはGPIO2の入力値は0になっているはずだ。

# Untitled - By: K.Shj - 月 7 19 2021

import time

from Maix import GPIO, FPIOA
from fpioa_manager import fm

Fpioa = FPIOA()#Fpioa使う前のおまじない
Fpioa.set_function(35, fm.fpioa.GPIO1)#他に役割のない35番ピンをGPIO1に設定。
led_1=GPIO(GPIO.GPIO1,GPIO.OUT)#35番ピン(GPIO1)にLEDをつなぎ、出力ピンとして設定。今後はled_1という名前で使うことにする。

Fpioa.set_function(33, fm.fpioa.GPIO2)#33番ピンをGPIO2に設定。
sw1=GPIO(GPIO.GPIO2,GPIO.PULL_UP)#33番ピン(GPIO2)は入力ピンとして設定。今後はsw1という名前で使うことにする。

while(True):
    sw_in = sw1.value()#入力ピンの状態を取得し変数に代入
    if sw_in == 0:
        led_1.value(1)#値に1を入れると出力ハイになる
        time.sleep_ms(50)#50ミリ秒、すなわち0.05秒待つ
        led_1.value(0)#値に0を入れると出力ローになる
        time.sleep_ms(50)
    else:
        led_1.value(0)#LED消灯

実行している様子がこちら。

プログラム通り、ボタンを押したらLEDが高速点滅し、押していないときはLEDは消えている。

以上が、SiPEED MaixシリーズのGPIOをmicroPythonでコード書いて使うときのやり方である。

返信する

メールアドレスが公開されることはありません。 が付いている欄は必須項目です