Arduboyでブロック崩し

arduboy07.jpg
Arduboyのプログラムは基本的にはArduinoと同じです。
Arduboyのハードウェアにあわせたライブラリが提供されていますので、それを使います。
Arduboyに依存した処理はArduboyクラスで定義されています。

ライブラリの解説は正式なものはまだ内容ですが、Arduino用TFTライブラリなどを使ったことがあれば、それほど難しくはありません。
ヘッダファイルを見ればなんとなく使い方は分かります。

グラフィックス関連のヘッダファイルはこちら。

Arduboy/Arduboy.h at master · Arduboy/Arduboy

サウンド関連のヘッダファイルはこちらです。

Arduboy/audio.h at master · Arduboy/Arduboy

とりあえず何か作ってみようということで、まずは以前作ったブロック崩しを移植してみました。
ゲームの基本的な処理は変わっていませんが、ゲームとして完結するよう、ミス5回でゲームオーバーとし、スコア表示も追加しています。
また、隠しコマンドとしてゲーム開始時(AまたはBボタン)に左ボタンを押しているとデモモード、右ボタンを押していると高速モードになるようにしています。

Arduboyでの基本的なプログラムは以下のようになります。

#include "Arduboy.h"

Arduboy arduboy;

void setup() {
arduboy.begin();
arduboy.setFrameRate(30);
}

void loop() {
if (!(arduboy.nextFrame()))
return;

// いろいろな処理や描画命令など

arduboy.display();
}

Arduboyでは、描画命令は画面に対してではなく仮想スクリーンに対して行い、仮想スクリーンの内容を

 arduboy.display();

で一気にOLEDに転送しているようです。

それは結構重い処理なのではないかと思ったのですが、考えてみると白黒で128×64ピクセルしかないので、1024バイトの転送で済みます。毎秒60回処理しても60KBの転送量ですから、まあなんとかなりそうです。
カラーLCDだと1ピクセルで2バイトのデータですので、ピクセルあたり1/16のデータ量しかありません。

ただ、少ないArduinoのRAMの半分を仮想スクリーンに使ってしまいますので、メモリの使い方には注意が必要かもしれません。

移植するブロック崩しは、内部的には30×40ピクセルのマップ内で処理を行っており、使用するLCDの解像度に合わせて描画時に拡大することを想定しています。
今回は、Arduboyのスクリーンを90度回転し、マップを縦横2倍に拡大することにしました。
また、スクリーンの縦横比が1:2と大きいので、内部のマップを30×50ピクセルに引き伸ばしました。

128×64ドットのスクリーンの内側の100×60ドットをゲーム画面に使い、残りを枠やスコアなどの表示に使います。

Arduboy特有の命令で今回使ったのは、以下のものです。

・入力関係

arduboy.pressed(A_BUTTON) // ボタンが押されていればtrue
arduboy.notPressed(A_BUTTON) // ボタンが押されていなければtrue
// 他のボタンは、B_BUTTON、UP_BUTTON、DOWN_BUTTON、LEFT_BUTTON、RIGHT_BUTTON

・描画関係

arduboy.clear() // 全消去
arduboy.drawRect(x, y, w, h, color) // 矩形を描画
arduboy.fillRect(x, y, w, h, color) // 塗りつぶした矩形を描画
arduboy.fillCircle(x, y, r, color) // 塗りつぶした円を描画

・音関係

arduboy.tunes.tone(frequency, duration) // frequencyはHz、durationはmsec

このほか、テキスト表示を90度回転させるために、Arduboy.cppの中で定義されているdrawChar()を改変して使っています。

最後に、今回作ったスケッチと動作の様子のビデオを載せておきます。

Arduino(10) aitendoの激安キャラクタ液晶をArduino Pro Mini(3.3V)に接続

Arduino Pro MiniへSPI TFT LCDが割とあっさり接続できたので、ついでに買い置きしてあったaitendoのキャラクタ液晶「SPLC792-I2C-M」も接続してみました。

この液晶モジュールは8×8ドットのキャラクタを16字×2行で表示できるものです。
インタフェースはI2Cで、バックライトはLEDです。
価格が50% OFFとなっており、375円(税別)と激安です。
3.3V専用なので、Arduino UNOからはちょっと使いにくいですが、3.3V動作のPro Miniなら問題ありません。

というわけでさっそくピンヘッダを取り付けます。
ジャンパピンが2つ(写真の青い部品)ありますが、これで表示の向きを指定できます。

arduino10-01.jpg

接続は以下のようになります。
電源ラインを除けば、Arduinoの信号線で使うのはI2CのためのA4、A5だけです。
なお電源は、Arduinoに接続したUSBシリアルアダプタが供給する想定です。
また、バックライト(BL+端子)は、100Ωの抵抗を入れて3.3Vに接続しました。
明るさ的にはこれで室内なら十分だと思います。

Arduino Pro MiniのA4、A5端子にはピンヘッダを付けてしまいましたので、接続にブレッドボード用のオス-オス型のジャンパケーブルは使えません。
ブレッドボード側にもピンヘッダを挿して、ピンヘッダ間を接続するメス型コネクタ(デュポンコネクタとかQIコネクタといいます)が両端に付いたワイヤを使います。

arduino10-04.png

(参考→aitendoのI2C低電圧キャラクタ液晶モジュールをArduino Pro Mini(3.3V)で駆動(配線編) – M.C.P.C. (Mamesibori Creation Plus Communication)

ライブラリは先人が作られたものをありがたく使わせていただきました。

I2C液晶のArduinoライブラリ – ST7032 | オレ工房

他のライブラリ同様、ZIPファイルをIDEに取り込めば、スケッチ例も自動的に追加されます。

無事動作確認ができたところで、一応何か作ってみようということで、ありがちですが手元にあったDHT11センサモジュールを使って、温度湿度計を作ってみました。

arduino10-02.jpg

aitendoの商品ページからリンクされているLCDコントローラ(SPLC792A)の仕様書を見ていたら、キャラクタROMにはカタカナも含まれていることが分かったので、カタカナ表示させてみました。
文字コード表を下に引用しておきます。

splc792a.png

使った温度湿度センサモジュールは、よく見かけるDHT11というセンサを使用した、中国Keyes社のKY-015という型番のものです。

arduino10-07.jpg

DHT11をArduinoから使用するためのソフトウェアは、例によってAdafruit製のライブラリがあります。

adafruit/DHT-sensor-library · GitHub

配線は以下の通りです。
(KY-015用の配線です。DHT11を直接接続する場合は配線が異なりますのでご注意ください。)

arduino10-05.png

スケッチファイルも一応アップロードしておきます。

#include <Wire.h>
#include <ST7032.h>
#include <DHT.h>

#define DHTTYPE DHT11
#define DHTPIN 2

ST7032 lcd;
DHT dht(DHTPIN, DHTTYPE);
char str1[14] = {' ',' ',' ',' ',' ',0xdf,'C',' ','/',' ',' ',' ','%',0};
char str2[10] = {' ',' ',0xcc,0xb6,0xb2,0xbc,0xbd,0xb3,0x3a,0};

void setup() {
 lcd.begin(16, 2);
 lcd.setContrast(40);
 lcd.setCursor(0, 0);
 lcd.print(str1);
 lcd.setCursor(0, 1);
 lcd.print(str2);
 
 dht.begin();
}

void loop() {
 delay(2000);
 float h = dht.readHumidity();
 float t = dht.readTemperature();
 if (isnan(h) || isnan(t)) {
   Serial.println("Failed to read from DHT sensor!");
   return;
 }
 float discomfort = 0.81 * t + 0.01 * h * (0.99 * t - 14.3) +46.3;

 lcd.setCursor(3, 0);
 lcd.print(t,0);
 lcd.setCursor(10, 0);
 lcd.print(h,0);
 lcd.setCursor(10, 1);
 lcd.print(discomfort,1);
}

余談ですが、今回使用したセンサモジュールは、中国の通販サイトaliexpressから、Keyes社のモジュール全部入りセットで入手しました。
購入価格は$17(送料無料)でしたので、1モジュール当たり50円強ということになります。

Keyes社のモジュールの一覧は以下のサイトなどで見ることができます。

Arduino 37 sensors – TkkrLab
Advanced Sensors Kit for Arduino – LinkSprite Playgound

届いたものはこんな感じで、全てのモジュールがジップロックの袋に無造作に袋詰めされていました。

arduino10-06.jpg

ホール素子モジュールなどは重複気味ですし、ただのLEDとか、磁気に反応するリードスイッチや傾くと接続する水銀スイッチなどの懐かしいデバイスが多く、ジャイロやI2Cデバイスのような最近のものは入っていませんので、お買い得かといえば迷うところではあります。
しかしロータリーエンコーダやリレー、レーザー、ジョイスティックなど、それなりに使えそうなものもあり、自分で情報を調べて使うことができる人には便利かもしれません。