基礎 · 読了まで13分

ブロックプログラミングからArduino C++へ:MicroPythonつき対応表

ブロックプログラミングからArduino C++への対応表です。34行のブロックとC++・MicroPythonのコード、よくある間違い、4ステップの方法、3通りで書いた1つのプログラムを紹介します。

ブロックプログラミングからArduino C++へ移るいちばんの近道は、各ブロックが実際のコードのどの行になるかを示す1ページの対応表を手元に置くことです。結論から言うと、ブロックは新しい言語ではなく、Arduino C++の行を目に見える形にしたものです。「ピン 13 を 出力 に設定」ブロックはpinMode(13, OUTPUT);の行、「1000 ms待つ」ブロックはdelay(1000);、「もし … 実行」ブロックはif文です。下の表では、BlueGraysアプリのブロックに表示される実際のラベルを、Arduino C++のコード、Raspberry Pi PicoでのMicroPythonのコードと並べています。

このページは授業ではなく、参照用のシートです。表を印刷して机のそばに置き、プロジェクトを見ながら、どの行がどのブロックに対応するかを確認できます。表のあとには、移行するときに多い間違い、ブロックから卒業するための4ステップの方法、同じプログラムをブロック、C++、MicroPythonで書いた例があります。例のプログラムはArduino IDEでコンパイルでき、PicoではThonnyで実行できます。

ブロックを1ステップずつ学びたい場合は、ブロックからコードへシリーズがあります:ブロックプログラミングとは?、ブロックプログラミングでLEDを点滅させる、ifブロックとボタン、ループと変数、ブロックでセンサーを読む、そしてMicroPythonへ。この記事は、それらの授業の内容を1つの表にまとめたものです。
「ブザーの周波数を調整」プロジェクトのブロック:グローバル変数、セットアップで入力に設定する4つのボタンピン、「ずっと繰り返す」の中の「もし」ブロック、範囲の制限と音を鳴らすブロック
「ブザーの周波数を調整」プロジェクトのブロックです。表に出てくる宣言、入力に設定、ピンを読み取る、代入、範囲の制限、音を鳴らす、音を止めるのブロックが、すべてこの1つのプログラムに入っています。

表を読む前に:3つの書き方の4つの違い

ブロック、C++、MicroPythonは同じ考え方を表しますが、書き方のルールが違います。特につまずきやすいのは次の4つの違いです。1つ目は構造です。Arduino C++のプログラムはsetup()とloop()という2つの部分からなり、ブロックでは「セットアップ(1回だけ実行)」と「ずっと繰り返す」として表示されます。MicroPythonには独立したsetupがなく、ファイルが上から下へ1回実行され、繰り返す部分はwhile True:ループの中に書きます。2つ目は型です。C++ではすべての変数に型を書き(int、float、bool)、ブロックでは「宣言:整数(int)」の選択肢がそれにあたります。Pythonでは型をまったく書きません。

3つ目は数値の範囲です。Arduino Unoではアナログの読み取り値が0〜1023、PWMが0〜255です。ESP32ではアナログの読み取り値が0〜4095まで広がり、PicoのMicroPythonでは読み取り値もPWMのデューティ比も0〜65535の範囲になります。そのため、しきい値をボードからボードへそのまま移すことはできません。4つ目は時間の単位です。delay()はミリ秒、time.sleep()は秒で指定します。0.5秒はC++ではdelay(500)、MicroPythonではtime.sleep(0.5)です。この4つのルールを覚えておけば、表のほとんどの行は自然に理解できます。

  • 表の数値は例です。ブロックで13となっている場所が、プロジェクトによっては7のこともあり、その場合はコードの行の数値も同じように変わります。
  • MicroPythonの列のピンはPicoのGP番号(GP14、GP15、GP26)です。Unoのピン番号と一致する必要はありません。回路図を確認してください。
  • 「Picoのブロックなし」と書かれた行は、そのブロックがPicoのプロジェクトでは使われないことを表します。それでも、同じ働きをするMicroPythonのコードを載せています。
  • ESP32もArduino C++でプログラムします。C++の列はESP32にもそのまま当てはまり、違うのはアナログの範囲と一部のピン番号だけです。

ブロック、Arduino C++、MicroPythonの対応表

表は12のグループに分かれています:プログラムの構造、ピン、時間、条件、ループ、変数、演算、シリアルポート、アナログとPWM、音、サーボ、センサー。ブロックの列の文字は、アプリのブロックに表示されているラベルです。「…」と「?」は、別のブロックをはめ込む場所を表します。1つの行に複数のブロックがある場合は、点(·)で区切っています。

グループブロック(アプリのラベル)Arduino C++MicroPython(Pico)
構造セットアップ(1回だけ実行)void setup() { … }while True:より前の行
構造ずっと繰り返すvoid loop() { … }while True:(中身は4スペースのインデント)
構造グローバル変数(最初に宣言)ファイルの先頭、setup()より前importの行のすぐ後の行
構造関数 blinkTwicevoid blinkTwice() { … } · 呼び出し:blinkTwice();def blinkTwice(): · 呼び出し:blinkTwice()
ピンピン 13 を 出力 に設定pinMode(13, OUTPUT);led = Pin(15, Pin.OUT)
ピンピン 2 を 入力(PULLUP) に設定pinMode(2, INPUT_PULLUP);btn = Pin(14, Pin.IN, Pin.PULL_UP)
ピンピン 13 に HIGH を書き込む · ピン 13 に LOW を書き込むdigitalWrite(13, HIGH); · digitalWrite(13, LOW);led.value(1) · led.value(0)(1でオン、0でオフ)
ピンピン 2 を読み取るdigitalRead(2) → HIGH(1)またはLOW(0)btn.value() → 1または0
ピン(Picoのみ)ピン led : GP 14 , 出力 · ピン led を オンにする(on) / オフにする(off)pinMode() + digitalWrite()と同じled = Pin(14, Pin.OUT) · led.on() / led.off()(オン/オフ)
時間1000 ms待つ · 0.5 秒待つ(Pico)delay(1000); · delay(500);time.sleep_ms(1000) · time.sleep(0.5)(ミリ秒・秒)
時間10 µs待つdelayMicroseconds(10);time.sleep_us(10)
時間起動からの経過ミリ秒millis()(unsigned long型)time.ticks_ms()
条件もし … 実行 … そうでなくもし … そうでなければ …if (…) { … } else if (…) { … } else { … }if …: · elif …: · else:
条件? = ?(≠、<、≤、>、≥)== != < <= > >=== != < <= > >=
条件? かつ ? · ? または ? · ?ではない&& · || · !xand · or · not x
ループ3 回繰り返す 実行for (int i = 0; i < 3; i++) { … }for i in range(3):
ループi を 0 から 5 まで 1 ずつ変えて数えるfor (i = 0; i <= 5; i++)(5を含み、6周)for i in range(0, 6):(6は含まない)
ループ条件が真の間繰り返すwhile (…) { … }while …:
ループループから抜け出すbreak;break
変数宣言:整数(int) delayTime = 60int delayTime = 60;delayTime = 60(型は書かない)
変数宣言:小数(float) voltage = 0.0float voltage = 0.0;voltage = 0.0
変数x に 0 を代入 · x を 1 増やすx = 0; · x += 1;(またはx++;)x = 0 · x += 1(x++はない)
変数配列 2 3 4 · ledPins の 0 番目の要素int ledPins[] = {2, 3, 4}; · ledPins[0]ledPins = [2, 3, 4] · ledPins[0]
演算1 + 1(−、×、÷も)+ - * / · int同士なら7 / 2 = 3+ - * / · 7 / 2 = 3.5、整数の割り算は7 // 2 = 3
演算10÷3の余り10 % 310 % 3
演算x の範囲を変換:0 – 1023 → 0 – 255map(x, 0, 1023, 0, 255)組み込みではないため、arduino_map()関数を書く
演算50 を 0 以上 100 以下の範囲に制限constrain(50, 0, 100)min(max(50, 0), 100)
シリアルポートシリアル通信を 9600 ボーで開始Serial.begin(9600);不要(print()はUSB経由で送られます)
シリアルポートシリアル出力 … 改行あり · 改行なしSerial.println(x); · Serial.print(x);print(x) · print(x, end="")(改行あり・改行なし)
アナログとPWMA0 をアナログ読み取りanalogRead(A0) → 0〜1023(ESP32では0〜4095)ADC(26).read_u16() → 0〜65535
アナログとPWMピン 9 にPWM 128 を書き込む · PWM led : GP 14 , 周波数 1000 Hz(Pico)analogWrite(9, 128);(0〜255)led = PWM(Pin(14)) · led.freq(1000) · led.duty_u16(32768)(0〜65535)
音ピン 8 で 440 Hzの音を鳴らす · ピン 8 の音を止めるtone(8, 440); · noTone(8);Picoのブロックなし:bz = PWM(Pin(16)) · bz.freq(440) · bz.duty_u16(32768) · 停止:bz.duty_u16(0)
サーボサーボ myServo をピン 9 に接続 · サーボ myServo を 90 度に回す#include <Servo.h> · Servo myServo; · myServo.attach(9); · myServo.write(90);(読み込み、宣言、接続、角度の設定)Picoのブロックなし:s = PWM(Pin(16)) · s.freq(50) · s.duty_ns(1500000)(約90°)
センサーピン 12 の HIGH パルス幅(µs)pulseIn(12, HIGH)machine.time_pulse_us(Pin(12, Pin.IN), 1)

一見1対1に見えても、注意が必要な行があります。「i を 0 から 5 まで 1 ずつ変えて数える」では5も含まれ、ループは6回実行されます。そのためC++では<ではなく<=を使い、Pythonではrange(0, 6)が必要です。rangeは終わりの数を含まないからです。割り算のブロックも落とし穴です。整数同士を割るとC++は余りを切り捨て、7 / 2は3になりますが、Pythonでは3.5になります。PythonでC++と同じ整数の割り算をするには//を使います。「範囲を変換」ブロックの元になっているmap()関数は、MicroPythonには組み込まれていません。下の例では、2行のarduino_map()関数で同じ計算をしています。

ArduinoからPicoに移るときは、しきい値と電圧を計算し直してください。Unoで400の光のしきい値は、Picoでは約25600になります(400 × 65535 / 1023)。Picoは3.3 Vで動作します。センサーの分圧回路は3V3(OUT)ピンから電源をとり、GPIOやADCのピンには決して5 Vを入れないでください。

入れ子のブロックはどうコードになりますか?

1つずつのブロックを知っているだけでは足りません。本当に大事なのは、入れ子になったブロックを1行のコードに直せることです。そのためには、2つの形を見分けてください。縁に出っ張りがあり、上下に積み重ねるブロックは命令で、それぞれがコードの1行になります。ほかのブロックのくぼみにはめ込む、楕円形やとがった形のブロックは値で、コードではかっこの中、イコールの右側、条件の中に入ります。下の行は、無料のブザーの周波数を調整プロジェクトのものです。4つのボタンで音のオン・オフを切り替え、周波数を上げ下げします。周波数は50〜5000 Hzの範囲に保たれます。

ブロック(ブザーの周波数を調整)C++の行読み方のルール
state に 1 を代入state = 1;上下に積み重ねた命令ブロックは、どれも1行になり、セミコロンで終わります。
もし(ピン btnOn を読み取る = HIGH)実行 …if (digitalRead(btnOn) == HIGH) { … }楕円形の値ブロックはかっこの中に入ります。ブロックの=による比較は、コードでは==になります。
frequency に(frequency + 50)を代入frequency = frequency + 50;内側のブロックが先に計算され、その結果が外側のブロックに渡されます。
frequency に(frequency を 50 以上 5000 以下の範囲に制限)を代入frequency = constrain(frequency, 50, 5000);(範囲を制限して代入)ブロックの空いたくぼみは、コードではカンマで区切った引数になります。
ピン buzzerPin で frequency Hzの音を鳴らすtone(buzzerPin, frequency);コードでは順番が決まっています。先にピン、次に値です。ブロックの語順は言語によって変わることがあります。
もし(state = 1)実行 … そうでなければ …if (state == 1) { … } else { … }「実行」の口にあるブロックは最初の{ }の中に、「そうでなければ」の口にあるブロックはelse { }の中に入ります。

この表を読むときは、1つの習慣を身につけてください。いちばん内側のブロックから先に訳し、外側に向かって進めます。「frequency に(frequency を 50 以上 5000 以下の範囲に制限)を代入」では、いちばん内側がconstrain(frequency, 50, 5000)で、外側の代入ブロックがそれをfrequency = …の形に包みます。値ブロックは単独では1行になれません。セミコロンをつけてそのまま置いてもコンパイラはエラーを出さないことがありますが、結果はどこにも保存されません。

ブロックからコードに移るときによくある間違い

ブロックエディターでは、こうした間違いのほとんどは起こりません。部品の形が、間違った場所にはまるのを防いでくれるからです。コードではこの保護がなくなるため、最初の数週間はほぼ全員が次の間違いに出会います。エラーメッセージは英語ですが、パターンは少なく、何回か見ればわかるようになります。

間違い症状直し方
行末にセミコロンがない「expected ';' before …」(;が必要)。コンパイラはよく1行下を示しますすべての文を;で終えます。if、for、whileの行の後には;をつけません。
波かっこが足りない、または多い「expected '}' at end of input」(最後に}が必要)、またはコードが思わぬ場所で実行される{にはそれぞれ}が必要です。Arduino IDEのCtrl+T(自動整形)でインデントが直り、足りないかっこを見つけやすくなります。
条件に=を書くif (state = 1)は常に真になり、stateも1になります。PythonではSyntaxErrorです比較は==、代入は=です。ブロックの=による比較は、コードでは必ず==になります。
intに小数を入れるint volt = 3.7;では3が保存され、5 / 2は2になります小数にはfloatを使い、割り算では一方の数を5.0と書きます。
digitalReadに間違った値を期待するif (digitalRead(2) == 5)は決して実行されません。プルアップのボタンでは論理が逆になりますdigitalReadが返すのはHIGH(1)かLOW(0)だけです。INPUT_PULLUPでは、押したボタンはLOWになります。
大文字と小文字を間違える「'digitalwrite' was not declared in this scope」(宣言されていない)、PythonではNameErrordigitalWrite、pinMode、Serialは一字一句そのとおりに書きます。PythonのTrueとFalseは大文字で始まります。
数えるループを1回少なく訳すブロックでは6回のループが、コードでは5回になり、最後のLEDが点灯しません「0 から 5 まで」は終わりの数を含みます。C++ではi <= 5、Pythonではrange(0, 6)です。
PythonのインデントがずれるIndentationError、またはループの外に出てしまう行whileやifの下の行は、すべて同じ4スペースで始めます。タブとスペースを混ぜないでください。
Pythonの時間をミリ秒だと思うtime.sleep(500)は8分以上待ってしまいますtime.sleep(0.5)またはtime.sleep_ms(500)と書きます。
C++の習慣をPythonに持ち込むx++、&&、行末の;が原因でSyntaxErrorPythonではx += 1、and、orを使います。行末の記号はありません。
コンパイラがある行を示したら、必ずその1行上も見てください。セミコロンの抜けや閉じていないかっこは、本当の問題より1行下で見つかることがよくあります。一度に複数のエラーが表示されたら、最初の1つだけを直して、もう一度コンパイルします。残りは最初のエラーの影響であることが多いからです。

ブロックから卒業する:4ステップの方法

一度に切り替えようとすると疲れてしまいます。次の4つのステップでは、読むことから書くことへ少しずつ進みます。各ステップに1つか2つのプロジェクトで十分です。表を見ずに今のステップができるようになったら、次のステップに進みましょう。

  1. 並べて読む。プロジェクトのブロックとコードを同時に開き、各ブロックがコードのどの行にあたるかを指でたどって対応させます。このステップでは表を手元に置いておきます。目標:コードのすべての行をブロックと結びつけられること。
  2. ブロックを隠して予想する。まずブロックを見て、次にブロックの表示をオフにし、コードを見ずにそのブロックのC++を紙に書きます。そのあと実際のコードと比べます。逆の方向も試してみてください:コードを読んで、ブロックを予想します。
  3. コードの値を変える。コードをパソコンに取り込み、数値を1つだけ変えます:待ち時間を100から500に、またはしきい値を400から600に上げます。書き込んで、違いを自分の目で確かめます。コンパイルエラーが出たら、上の間違いの表に戻ります。
  4. 新しい行を書く。ブロックにない行を自分で追加します:値をシリアルモニタに表示するSerial.println()、2つ目のLED、ボタンで動くifなどです。ここまで来れば、もうブロックを訳しているのではなく、直接コードを書いています。

それぞれのステップには、シリーズの中に対応する授業があります。1つ目のステップには、ブロックプログラミングでLEDを点滅させるにあるブロックと行の対応表から始めるのがおすすめです。2つ目と3つ目のステップで条件とループを扱うときは、ifブロックとボタンとループと変数を見てください。PicoでMicroPythonに移る場合は、ブロックからMicroPythonへの記事でThonnyのセットアップも説明しています。クラスで移行を数週間に分けて進めたいなら、8週間のロボットプログラミング授業計画が、そのまま使える順番を示してくれます。

BlueGraysアプリでブロックとコードを並べて開く

この表がいちばん役立つのは、実際のプロジェクトのブロックとコードを行き来するときです。BlueGraysアプリでは100件を超えるプロジェクトにブロック表示があります。30件を超える無料プロジェクトではブロックも公開されていて、プレミアムのプロジェクトのブロックはプレミアムでロック解除されます。ブロックは読むためのものです。アプリでブロックを編集することはできず、ブロックがボードに書き込まれることもありません。ボードに送られるのは常に実際のコードです。コピーで、またはパソコンで開くならリンクをコピーでコードを取り出し、Arduino IDE、PicoならThonnyに貼り付けます。

  • ブロックで表示:プロジェクトページのソースコードの横にあるこのスイッチをオンにすると、同じプログラムがアプリの言語のブロック画像で表示されます。画像をタップすると全画面で開きます。スイッチをオフ・オンすることが、そのまま1つ目と2つ目のステップの練習になります。
  • ブロック解説:ブロック表示をオンにすると、「コードを理解」タブがこの名前に変わります。プログラムがステップに分かれ、各ステップで対象の部分と説明が表示されます。最後の「自分で試す」の課題は、4つ目のステップにそのまま使える練習です。
  • コードガイド:「学ぶ」にある36枚のカード(Arduino C++が18枚、MicroPythonが18枚)は、どれもブロック、Arduino、MicroPythonのタブで例を3通りに表示します。表のある行をもっと詳しく見たいときは、対応するカードを開いてください。
  • ブロック対応のプロジェクト:「発見」>「プロジェクト」の「絞り込み」にあるこの選択肢を使うと、ブロック表示のあるプロジェクトだけが一覧に表示されるので、移行の練習に使うプロジェクトを選びやすくなります。

コードガイドの使い方はコードガイドの記事で、「コードを理解」と「自分で試す」は「コードを理解」のガイドで詳しく説明しました。命令を1つずつ解説したものとしては、例つきのArduino命令一覧もこの表と一緒に使うと便利です。

1つのプログラムを3通りで:周りの明るさに合わせて明るさが変わる常夜灯

表の内容をまとめて確かめるために、小さなプログラムを作ってみましょう。LDRが光を測り、部屋が明るい間はLEDが消えたままで、暗くなるにつれてLEDが少しずつ明るくなります。このプログラムは変数、アナログ読み取り、条件、範囲の変換、PWM、シリアル、待機のブロックを使うので、表の半分以上が1つの例に登場します。アイデアは無料のLDRで作る常夜灯プロジェクトがもとになっています。そちらではLEDが点灯か消灯のどちらかですが、ここではPWMで明るさを絞ります。LDRの配線は、LDRで光の強さを測定プロジェクトの回路図も参考になります。

接続Arduino UnoRaspberry Pi Pico
LDRの1本目の足5V3V3(OUT)、物理ピン36
LDRの2本目の足 + 10 kΩの抵抗の一端(中点)A0GP26 / ADC0、物理ピン31
10 kΩの抵抗のもう一端GNDGND、物理ピン38
LEDの長い足(220 Ωの抵抗を通して)D9(PWMピン)GP15、物理ピン20
LEDの短い足GNDGND、物理ピン18
光の読み取り値 / PWMの範囲0〜1023 / 0〜2550〜65535 / 0〜65535

まずはブロック版です。アプリのラベルで書くと、プログラムは次のブロックでできています。各項目は、このあとのC++コードの1行または数行に対応します:

  1. 「グローバル変数(最初に宣言)」:「宣言:整数(int) lightValue = 0」と「宣言:整数(int) brightness = 0」
  2. 「セットアップ(1回だけ実行)」:「シリアル通信を 9600 ボーで開始」、次に「ピン 9 を 出力 に設定」
  3. 「ずっと繰り返す」:「lightValue に(A0 をアナログ読み取り)を代入」
  4. 「もし(lightValue < 400)実行」:「brightness に(lightValue の範囲を変換:0 – 400 → 255 – 0)を代入」、「そうでなければ」:「brightness に 0 を代入」
  5. 「ピン 9 にPWM brightness を書き込む」
  6. 「シリアル出力 "Light: " 改行なし」、「シリアル出力 lightValue 改行なし」、「シリアル出力 " PWM: " 改行なし」、「シリアル出力 brightness 改行あり」
  7. 「200 ms待つ」
C++ (Arduino IDE)
1// ─────────────────────────────────────────
2//   BlueGrays · bluegrays.com
3//   Işığa göre kısılan gece lambası / Dimming night light
4// ─────────────────────────────────────────
5
6int lightValue = 0;   // LDR okuması / LDR reading (0-1023)
7int brightness = 0;   // LED parlaklığı / LED brightness (0-255)
8
9void setup() {
10  Serial.begin(9600);   // Seri port 9600 baud / Serial at 9600 baud
11  pinMode(9, OUTPUT);   // LED, PWM pini D9 / LED on PWM pin D9
12}
13
14void loop() {
15  lightValue = analogRead(A0);   // Az ışık = küçük değer / Little light = small value
16
17  if (lightValue < 400) {
18    // Karanlık arttıkça LED parlar / The darker it gets, the brighter the LED
19    brightness = map(lightValue, 0, 400, 255, 0);
20  } else {
21    brightness = 0;   // Oda aydınlık, LED kapalı / Room is bright, LED off
22  }
23
24  analogWrite(9, brightness);   // PWM 0-255 / PWM 0-255
25
26  Serial.print("Light: ");
27  Serial.print(lightValue);
28  Serial.print("  PWM: ");
29  Serial.println(brightness);
30
31  delay(200);   // 0,2 sn bekle / Wait 0.2 s
32}
33
MicroPython
1# ─────────────────────────────────────────
2#   BlueGrays · bluegrays.com
3#   Işığa göre kısılan gece lambası / Dimming night light
4# ─────────────────────────────────────────
5from machine import Pin, ADC, PWM
6import time
7
8ldr = ADC(26)                # GP26 = ADC0 / GP26 = ADC0
9led = PWM(Pin(15))           # LED, GP15 / LED on GP15
10led.freq(1000)               # PWM frekansı 1000 Hz / PWM frequency 1000 Hz
11
12THRESHOLD = 25600            # Uno'daki 400'ün karşılığı / Same as 400 on the Uno
13
14
15def arduino_map(x, in_min, in_max, out_min, out_max):
16    # Arduino map() ile aynı hesap / Same math as Arduino map()
17    return (x - in_min) * (out_max - out_min) // (in_max - in_min) + out_min
18
19
20while True:
21    light_value = ldr.read_u16()          # 0-65535 / 0-65535
22
23    if light_value < THRESHOLD:
24        # Karanlık arttıkça LED parlar / The darker it gets, the brighter the LED
25        brightness = arduino_map(light_value, 0, THRESHOLD, 65535, 0)
26    else:
27        brightness = 0                    # Oda aydınlık, LED kapalı / Room is bright, LED off
28
29    led.duty_u16(brightness)              # PWM 0-65535 / PWM 0-65535
30
31    print("Light:", light_value, " PWM:", brightness)
32
33    time.sleep(0.2)                       # 0,2 sn bekle / Wait 0.2 s
34

2つのプログラムを1行ずつ比べると、表にあった違いがすべて見えてきます。C++のsetup()はPythonではwhile Trueより前の行になり、Serial.begin()はなくなります。analogRead(A0)はADC(26).read_u16()になり、範囲が0〜1023から0〜65535に広がるので、しきい値は400ではなく25600です。analogWrite(9, …)の代わりに、まずPWMオブジェクトを作り、duty_u16()で明るさを0〜65535の範囲で設定します。map()が組み込まれていないため、arduino_map()関数を書きます。その中の//による整数の割り算は、C++の整数同士の割り算と同じ結果になります。4つのSerial.print()の代わりにprint()が1つで済み、delay(200)はtime.sleep(0.2)になります。

この例で、さっそく3つ目のステップを試してみましょう。Unoではしきい値を400から600に上げると、LEDが早めに光り始めます。Picoで同じ変更をするには、THRESHOLDを約38400にします。シリアルモニタ(9600ボー)かThonnyのシェルでLightの値を見ながら、部屋に合ったしきい値を見つけてください。

ブロックプログラミングからArduino C++への移行は、新しいことを暗記するよりも、すでに知っているブロックが文字でどう書かれるかに気づくことが中心です。この表を手元に置き、どのプロジェクトでもまず並べて読み、次にブロックを隠して自分で書いてみてください。表の行を実際のプロジェクトで見たいときは、BlueGraysアプリでブロック表示のあるプロジェクトを開き、ブロックで表示で同じプログラムの2つの形を切り替えてみましょう。

よくある質問

ブロックプログラミングの次に学ぶのは、C++とPythonのどちらがいいですか?

持っているボードで選びましょう。Arduino UnoやESP32のプロジェクトの多くはArduino C++で書かれ、Raspberry Pi PicoではMicroPythonがよく使われます。ブロックの考え方はどちらも同じなので、一方を覚えれば、もう一方に移るのにかかる時間はずっと短くなります。

ブロックプログラミングからArduinoのコードに移るには、どのくらいかかりますか?

人によって違いますが、週にいくつかのプロジェクトに取り組む人なら、たいてい数週間で短いプログラムを読み、小さな変更ができるようになります。まずブロックの横でコードを読み、次に値を1つだけ変え、最後に新しい行を追加すると、移行が楽になります。

Arduino UnoをPythonでプログラムできますか?

Arduino UnoではMicroPythonは動きません。UnoはArduino IDEを使ってC++でプログラムします。MicroPythonを使うには、Raspberry Pi Picoのような性能の高いボードが必要です。ただし、パソコンで動くPythonのプログラムから、シリアルポート経由でUnoに命令を送ることはできます。

BlueGraysでブロックを編集して、ボードに書き込めますか?

いいえ。BlueGraysのブロックは、コードを読んで理解するためのものです。アプリでブロックを編集することはできず、ブロックがボードに書き込まれることもありません。書き込むのは常にプロジェクトの実際のコードで、Arduino IDEまたはThonnyを使います。

ブロックのプログラムは本物のコードですか?

ブロックは本物のコードを目に見える形にしたもので、各ブロックがコードの1行または数行に対応します。BlueGraysのブロック表示があるプロジェクトでは、ブロックと、書き込むArduino C++またはMicroPythonのコードは同じプログラムを表しています。

digitalReadが1か0を返すのはなぜですか?HIGHは1と同じですか?

はい。ArduinoではHIGHは1、LOWは0と同じで、digitalReadはこの2つの値のどちらかだけを返します。INPUT_PULLUPで配線したボタンは、押している間はLOW、離すとHIGHになります。MicroPythonでもpin.value()は1か0を返します。

全プロジェクトを見る
ブザーの周波数を調整
#14中級

ブザーの周波数を調整

4つのボタンでブザーの音を操作します。1つは音を鳴らし、1つは音を止め、残りの2つは音を高くしたり低くしたりします。音を高くするボタンや低くするボタンを押し続けると、音程が段階的に変化し、サイレンのように聞こえます。音の高低が生まれる理由を、自分の耳で確かめられます。

4.6(69)
118
LDRで作る常夜灯
#12初級

LDRで作る常夜灯

暗くなると自動で点灯し、朝になると消灯する小さな常夜灯です。光センサーが部屋の明るさを測定し、Arduinoが十分に暗くなったらLEDを点灯させ、明るくなったら消灯させます。街灯が夕方になると自動で点灯する仕組みも理解できます。

4.8(102)
205
LDRで光の強さを測定
#11初級

LDRで光の強さを測定

部屋の明るさを数値で見てみませんか?光に反応する小さな部品、LDRで周囲の光を測定し、Arduinoが0.5秒ごとにその値をコンピューターの画面に表示します。手で覆うと数値が変わる様子を確認できます。自動で点灯する常夜灯などのプロジェクトへの第一歩です。

4.6(81)
139
ボタンでLEDを点灯(押している間のみ)
#9初級

ボタンでLEDを点灯(押している間のみ)

呼び鈴のように、押している間は点灯し、離すと消灯します。Arduinoはボタンの状態を常に読み取り、押されている間はLEDを点灯させ、指を離した瞬間に消灯させます。このシンプルな回路で、ボードが外部からの操作を検知する仕組みを学べます。

4.8(113)
229
ボタンでLEDの点灯・消灯を切り替え
#10初級

ボタンでLEDの点灯・消灯を切り替え

部屋の照明スイッチのように、ボタンを1回押すと点灯し、もう1回押すと消灯します。Arduinoはボタンが押されるたびにLEDの状態を反転させます。ボタン内部の小さな接点の振動で誤動作しないよう、短い待ち時間も設けます。1つのボタンでオン・オフを切り替える、シンプルな仕組みです。

4.8(100)
167
速度調整できる流れるLED
#7中級

速度調整できる流れるLED

6個のLEDが順番に点滅し、光が端から端へ走るように見えます。ポテンショメーターのつまみを回すと、その速さがすぐに変わります。一方に回すと光が素早く進み、反対に回すと各LEDが1秒近く点灯します。つまみで動きの速さを調整する仕組みを目で確かめられます。

4.6(72)
146
HC-SR04で距離を測定(シリアルモニタ表示)
#27初級

HC-SR04で距離を測定(シリアルモニタ表示)

HC-SR04センサーは、コウモリが暗闇で道を見つけるのと同じ仕組みで動作します。人には聞こえない音を出し、その反響を捉えて前方の物体までの距離を測ります。Arduinoは0.5秒ごとに距離をセンチメートル単位でコンピューターの画面に表示し、3〜100センチメートルの測定値を示します。駐車センサーや障害物を避けるロボットなどのプロジェクトの基礎になります。

4.6(46)
71
Raspberry Pi Picoで外付けLEDを点灯(ブレッドボード)
#148初級

Raspberry Pi Picoで外付けLEDを点灯(ブレッドボード)

Picoの内蔵LEDの次は、ブレッドボードに外付けLEDを接続し、GP14ピンで制御します。このプロジェクトでは、Picoの汎用GPIOピンを出力として使う方法、LEDの極性(長い足=アノード/+、短い足=カソード/−)、電流制限抵抗(220Ω)が必要な理由を学びます。抵抗を入れないと、LEDに過大な電流が流れて壊れることがあります。回路はとても簡単です。Pico GP14 → 220Ω抵抗 → LED(+)→ LED(−)→ Pico GND。Wokwiでシミュレーションできます。

4.5(2)
7