投稿者「shoarai」のアーカイブ

はじめてのM5StickC PlusでCO2を測った

先日はじめてギターアンプを自作しましたが、今回はM5StickC Plusを使った電子工作です。在宅勤務が今後も続きそうなので、自宅の快適さを測りたいと思い、集中力に影響があると言われているCO2の濃度を測ることにしました。

デバイスと部品

M5StickC Plusの外観
MH-Z19Cの外観

ジャンパーワイヤー

MH-Z19Bという下位バージョンのものもありますが、フェイク品が出回っているそうで、秋月で確実に買えるMH-Z19Cにしました。その他にPC、PCとM5StickC Plusを繋ぐためのUSB Type−Cケーブルが必要です。

環境構築

  • Arduino IDEをインストールしてセットアップ

Arduino IDEのインストールやセットアップは、Interfaceの以下の記事を参考にしました。実施するのはステップ1、2だけです。
M5StickC Plusの開発環境(Arduino IDE)構築の手順 – Interface

記事ではWindows10で、僕はMacで実施しましたが問題ありませんでした。Macの場合は、zipファイルがダウンロードされ、解凍するとappファイルができます。また、記事中にある「ESP32パッケージのJSONファイルURL」は以下になります。コピペ用にどうぞ。
https://dl.espressif.com/dl/package_esp32_index.json

バージョンは以下の通り。

  • Arduino IDE:1.8.15
  • ESP32パッケージ:1.0.6

PlatformIOという開発環境もあるようですが、初心者なのでまずは基本的な環境であるArduino IDEを使ってみます。

サンプルプログラムの実行

試しにサンプルプログラムを動かしてみます。メニューバーの「ファイル → スケッチ例 → M5StickCPlus → Basics → IMU」を選ぶと、サンプルプログラムのソースコードが表示されます。画面左上の「マイコンボードに書き込む」ボタンを押して、プログラムをマイコンに書き込みます。IMUというのは加速度センサーのサンプルです。

M5StickC Plusのサンプルプログラムの画面

初めて書き込みを実行したときは、「シリアルポートが選択されていません。」というエラーが表示されました。「cu.usbserial-…」というポートを選んで再度実行したところ、正常に書き込め、プログラム実行できました。

CO2濃度の計測

M5StickC PlusとMH-Z19Cを接続します。以下のピン同士をジャンプワイヤー オス-メスで繋げます。

M5StickC PlusのピンMH-Z19Cのピン
GNDGND
5V→VIN
G26Rx
G36(G36/G25と記載されているピン)Tx

プログラムにはmhz19_uartというライブラリを使わせてもらいます。zipファイルをダウンロードし、メニューバーの「スケッチ → ライブラリのインクルード → .ZIP形式のライブラリをインストール…」からインストールします。

このライブラリには実行サンプルコードも付属しているので、使わせてもらいましょう。メニューバーの「ファイル → スケッチ例 → MHZ19_uart → MHZ19_getco2」を選ぶと、サンプルコードが表示されます。ただし、まだマイコンに書き込みません。下記のコメント記載部分を追記、変更してからマイコンに書き込みます。

// 追記:M5StickC Plusで必要なヘッダをインクルードする。
#include <M5StickCPlus.h>
#include <MHZ19_uart.h>
// 変更:接続するピンの番号を変更する。
const int rx_pin = 36;
const int tx_pin = 26;
MHZ19_uart mhz19;
void setup()
{
// 追記:M5StickC Plusの初期化と、G36ピンを使うためにG25ピンをフローティングにする。
M5.begin();
pinMode(36, INPUT);
gpio_pulldown_dis(GPIO_NUM_25);
gpio_pullup_dis(GPIO_NUM_25);
Serial.begin(9600);
mhz19.begin(rx_pin, tx_pin);
mhz19.setAutoCalibration(false);
// 追記:デフォルトだと画面が見づらいので、横向き表示でフォントを大きくする。
M5.Lcd.setRotation(3);
M5.Lcd.setTextSize(4);
// 変更:文字を画面に表示する。
M5.Lcd.println("MH-Z19 is warming up now.");
delay(10 * 1000);
}
void loop()
{
int co2ppm = mhz19.getCO2PPM();
int temp = mhz19.getTemperature();
// 追記:画面の表示とカーソルを初期化することで、前回の文字の表示を消す。
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setCursor(0, 0);
// 変更:文字を画面に表示する。
M5.Lcd.print("co2: ");
M5.Lcd.println(co2ppm);
M5.Lcd.print("temp: ");
M5.Lcd.println(temp);
delay(5000);
}

CO2濃度を測定できました!!ついでに温度も!

CO2濃度の測定画面

外気のCO2濃度は400ppm前後だそうなので、870ppmは少し高めでしょうか。エアコンをつけて窓を締め切っている状態なので、感覚的には正しいように思います。
息を吹きかけてみると、10秒後ぐらいに3,000ppmぐらいになりました。息に反応する程度には計測できているようです。

とりあえず測定はできたので今回はここまで。この後はMH-Z19Cのキャリブレーションや画面表示のデザイン、クラウドへのアップロードなどを試してみたいと思います。

電子工作をなるべくお金をかけずに始める方法

先日、初めて電子工作をしました。電子工作を始めるにはいろいろな部品や道具を準備する必要があり、お金がかかります。ただ、いきなりすべての道具を揃えるのは金銭的にもキビしいし、すぐ飽きてしまうかも。。そこで、必要になったら買い足していくことにしました。その進め方のステップについて紹介します。

今回、僕はギターアンプを作ったので、他の電子工作には当てはまらかもしれませんが、進め方は多少参考になるかもしれません。

注意事項

電子工作は工具の扱いや配線作業において危険がともなうため、怪我などに十分ご注意ください。本記事の内容を参考にして発生した事故などは、shoaraiは一切責任を負いません。自己責任でお願いいたします。

作ったもの

LM386ギターアンプの外観

こちらが今回作ったギターアンプです。機能や回路図は以下の記事で紹介しています。

始め方〜完成までのステップ

  1. 作りたい回路を調べる。
  2. ブレッドボードで回路を組むための部品を買う。
  3. 回路を入れる箱を買う。
  4. 箱の穴を開けるための道具を買う。
  5. 箱に回路を組むための部品を買う。

作りたい回路を調べる。

作りたい回路は人によるので、ここでは詳しく説明しません。今回はギターアンプを作りたかったので、とりあえず「ギターアンプ 自作」でGoogle検索。個人ブログで作り方が紹介されていますが、紹介されている回路が正しいのかどうかわからなかったので、ある程度信頼できる本を購入しました。

ブレッドボードで回路を組むための部品を買う。

なぜ今回ギターアンプを作りたいかというと、結局のところ、ギターの音を出したいわけです。最悪、回路が箱に入っておらず剥き出しの状態でも問題ありません。そこで、まずはブレッドボード上で回路を組んで音を出すことを目標とします。

ブレッドボード上で回路を組むために、僕が買った部品は以下の通り。

  • 回路部品(入力ジャック、スピーカー、抵抗やコンデンサなど、回路によって異なる)
  • ブレッドボード
  • 9V電池
  • 電池スナップ
  • ジャンパーワイヤー
  • クリップ付コード
電子工作でよく使う電子部品セット
ブレッドボード
9V電池
9V電池スナップ
ジャンパーワイヤー
クリップ付コード

実はこれだけあれば、回路を組んで音を出すことができます。はんだごてやニッパーがなくても回路は組めるんです。

机の上

上の画像がブレッドボード上に回路を組んで音が出る状態です。(画像からはわかりにくいですが;)入力ジャックとスピーカーは、ジャンプワイヤーとクリップ付コードでブレッドボードに繋いでいます。クリップ付コードで部品を挟むときは、なるべくコード同士が触れないようにカバー部分を深くかぶせるといいです。

ボリューム

ボリュームもクリップ付コードで繋げましたが、問題なく動きました。クリップが隣同士触れないように注意!

最低限、音が出るところまでできたら、抵抗やコンデンサの値を変えたり、部品の構成を変えたりして、音がどう変わるか試してみました。抵抗やコンデンサは複数セットになっているものを買っておきました。

この状態でも問題ないかもしれませんが、ブレッドボードだとスペースを食うので多少邪魔だったり、箱に入れないとボリュームが回しにくいです。やっぱり箱に入れたい!となったタイミングで箱を探しました。

回路を入れる箱を買う。

箱探しがなかなか難しい。今回作るLM386を使ったギターアンプは、スモーキーアンプという名前で知られていて、名前の通りタバコの箱に入るぐらい小さくできます。つまり紙の箱でも問題ないようです。ただ紙だと耐久性に問題あるし、今回は音量やゲイン調整用のボリュームを付けたかったので、ポリケースにしました。

100均でポリケースを探しまくりました。結果、見つけたのはこちら。

ポリケース

本体がポリプロピレン、蓋がポリエステルのケースです。3つ入りでしたが、1つ使ったので画像は2つだけ写ってます。なかなかちょうどいいサイズの箱が見つからないかもしれませんが、とりあえず買ってみて部品をあててみるのがいいかもしれません。100円だし、ケースなので他の用途にも使えそうなので。

箱の穴を開けるための道具を買う。

箱を買ったら、その箱に穴を開けるための道具を調べて買います。エフェクター製作だとよく使われるのはアルミダイキャストケースですが、今回はポリケースなので必要な道具は少ないです。

僕が買った道具は以下の通り。

  • ピンバイス本体
  • ピンバイスに取り付けるドリル
  • リーマー
ピンバイス

ドリル

リーマー

ピンバイスで穴を開け、リーマーで穴を広げます。

箱に回路を組むための道具や部品を買う。

箱に穴を開けられたら、ついにはんだごてを買って基板上で回路を組みます。

僕が買った道具は以下の通り。

  • ユニバーサル基板
  • 配線材
  • ニッパー
  • はんだごて
  • こて台
  • はんだ
  • はんだ吸取線
ユニバーサル基板
配線材
ニッパー
はんだごて
こて台
はんだ
はんだ吸取線

ユニバーサル基盤の上に回路を組み、配線材で配線していきます。

ボリューム

↑初めてのはんだ付け。

この記事の冒頭でも説明しましたが、完成品は以下の記事で紹介してます。

LM386でギターアンプを作った

日頃、仕事やプライベートでプログラミングをしていますが、今回始めて電子工作でギターアンプを作りました。

注意事項

電子工作は工具の扱いや配線作業において危険がともなうため、怪我などに十分ご注意ください。本記事の内容を参考にして発生した事故などは、shoaraiは一切責任を負いません。自己責任でお願いいたします。

作りたいもの

ギターは持っているのですが、アンプは随分前に売ってしまい、PCに繋いで音を出していました。ただ毎回PCに繋ぐのは面倒なので、簡単に音出ししたいときのために、ギターに直差しできるような小型のアンプがほしいと思っていました。でもギターに直差しできて、かつスピーカーがついているアンプが売ってない。。ヘッドフォンを繋いで使うようなミニアンプはあるんですが。そこで、自分で作れないか調べたところ、わりと簡単にしかも安く作れるようなので試してみました。

作りたいもののイメージは以下の通り。

  • ちょっと弾きたいときに、ギターに直差しして使える。
  • 自分が聞こえればいいので、音量は小さくてもいい。
  • 音色は幅広く、クリーンも歪みも出したい。歪み具合は調整したい。

作ったもの

LM386ギターアンプの外観

こちらが作成したギターアンプです。左上のトグルスイッチは電源、左下はゲインのON/OFF切り替えです。右上のつまみは音量、右下はゲインの調整になっています。ギターに直差ししたときに、右手でスピーカーを隠さずにつまみを調整できるように、右側につまみがくるように配置しました。電源を入れると青色LEDが光ります。ステレオジャックがあり、短いパッチケーブルを使ってギターと接続することができます。

ステレオジャックではなくステレオプラグを取り付けてギターに直差しできるようにすることも考えましたが、卓上に置いても使えるようにステレオジャックを付けました。

LM386ギターアンプの中身

後で部品を交換したり修理したりできるように、グルーガンなど使わずにナットで部品を締めて取り付けました。

電子回路の外観
はんだ付け

基盤上に部品をキツキツに詰めてますが、今後拡張したくなったときのためにまだカットしていません。

回路図

4.7kΩ220μF100Ω10μF10μF9V0.047μF220μF1kΩB100ΩB8Ω0.5WLM386N-1Blue LED154236876.3mmStereo Jack

回路にはLM386という小型パワーアンプICを使っています。抵抗やコンデンサなどの構成はほとんど公式のデータシートに記載されているものと同じです。違いとしては、音量とゲイン調整用のスイッチとボリューム、電源の状態確認用のLEDと抵抗をつけたぐらいです。また、5番ピンにある抵抗をデータシート記載の10Ωで試したところ、なぜか手前のコンデンサが異常に熱くなったので、100Ωに変えました。セラミックコンデンサを使っているからなのか、原因はわからず。LEDに繋ぐ抵抗は1kΩ、2.2kΩあたりも試したのですが、LEDの光が眩しすぎたので4.7kΩにしました。

振り返り

スピーカーをケースに取り付ける前と後で音を比べると、取り付けた後は少しこもった音になってしまいました。ケース本体の素材はポリプロピレン、蓋はポリエチレンなので、素材が原因なのか、ケースの穴が空いていない部分が影響しているのかわかりませんが、改善したいところです。スピーカーを覆っている部分をすべて穴開けしてもいいかもしれません。

配線が少し複雑になってしまった気がします。基盤のレイアウトを考えるときに、ケースに取り付けた部品の位置を考慮して配線しやすいようにすればよかったと思いました。

ボリュームのシャフトが少し長すぎるため、つまみからはみ出てしまっています。短く切るのは面倒ですし道具もないので、ボリュームとケースの間に何か挟んで高さを調整すれば解消するかも。

最後に、お気づきでしょうか?実はスピーカーを固定しているネジが1本足りません笑。これは買ってあったスピーカー抑え金具を急遽使ったのですが、そのネジが3本しかなかったためです。できれば4箇所とも別のネジを使いたいところです。

補足

初めてギターアンプを作るにあたって今回購入したものを以下の記事にまとめました。参考まで。

KotlinでToastをカスタマイズする

先日、ポップアップアラームという設定した時刻にポップアップを表示するアプリを作りました。このページではその中でもポップアップであるToastをカスタマイズして表示する処理について紹介します。

ポップアップアラームの設定画面
ポップアップアラームの通知画面

標準のToastを表示する

標準のToastは以下のコードで表示できます。

object ToastView {
    fun showToast(context: Context, message: String) {
        Toast.makeText(context, message, Toast.LENGTH_LONG).show()
    }
}

Toastをカスタマイズする

ポップアップアラームの通知画面

前述のような標準のToastだと目立たず、通知を見逃しやすいので、上の画像のようにToastのサイズやフォントサイズが大きい独自のレイアウトを作成します。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="1">

    <TextView
        android:id="@+id/message"
        android:layout_width="320dp"
        android:layout_height="80dp"
        android:background="@drawable/toast_shape"
        android:gravity="center"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:textColor="@color/colorBase"
        android:textSize="40sp" />

</LinearLayout>

上記の独自レイアウトを表示します。

object ToastView {
    fun showToast(context: Context, message: String) {
        val inflate = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
        val view = inflate.inflate(R.layout.toast, null)
        val textView = view.findViewById(R.id.message) as TextView
        textView.text = text

        Toast(context).run {
            this.view = view
            duration = Toast.LENGTH_LONG
            setGravity(Gravity.BOTTOM, 0, 250)
            show()
        }
    }
}

KotlinでAndroidの時刻を検知する

先日、ポップアップアラームという設定した時刻にポップアップを表示するアプリを作りました。このページではその中でも時刻の検知の処理について紹介します。

ポップアップアラームの設定画面
ポップアップアラームの通知画面

アラームを開始、停止する

Androidアプリで、ある時刻になったら処理を実行したい場合、AlarmManagerを使用します。厳密には、ある時刻になったことを通知するのではなく、ある時間を経過したことを通知できます。
今回はアラームアプリなので、ある程度正確な時間を通知できるsetExact()を呼びます。通知はBroadcastReceiverで受け取ります。
以下のクラスでは、アラームを開始して1度だけ通知します。別のアラームがすでに実行中なら、実行中のアラームは停止し、新しいアラームが開始されます。

object OnceAlarmManager {
    private const val REQUEST_CODE = 0
    private var alarmManager: AlarmManager? = null
    private var pendingIntent: PendingIntent? = null

    fun startAlarm(context: Context, calendar: Calendar) {
        alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        val intent = Intent(context, AlarmBroadcastReceiver::class.java)
        pendingIntent = PendingIntent.getBroadcast(
                context, REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT)
        alarmManager?.setExact(AlarmManager.RTC, calendar.timeInMillis, pendingIntent)
    }

    fun stopAlarm() {
        alarmManager?.cancel(pendingIntent)
    }
}

アラームアプリでは、1つのアラームで時刻通知したら次のアラームを開始する必要があるので、以下の通り、設定がONになっているアラームを開始します。

object WeeklyAlarmManager {
    fun startNextAlarm(context: Context) {
        var weeklyAlarms = WeeklyAlarmDataManager.weeklyAlarms
        if (WeeklyAlarmUtil.hasPowerOn(weeklyAlarms)) {
            val calendar = WeeklyAlarmUtil.getNextAlarmAsCalendar(weeklyAlarms)
            OnceAlarmManager.startAlarm(context, calendar)
        } else {
            OnceAlarmManager.stopAlarm()
        }
    }
}

アラーム通知を受け取る

前述の通り、BroadcastReceiverでアラーム通知を受け取ります。通知を受け取ったら、ポップアップを表示し、次のアラームを開始します。

class AlarmBroadcastReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        // Show popup.
        WeeklyAlarmManager.startNextAlarm(context)
    }
}

BroadcastReceiverをアプリに登録します。

<application
    ...
    <receiver android:name=".AlarmBroadcastReceiver">
    </receiver>
</application>

端末の再起動時やタイムゾーンの変更時に、アラームを再設定する

端末が再起動されたことやタイムゾーンが変更されたことを、BroadcastReceiverで受け取れるよう、actionを設定します。

<application
    ...
    <receiver android:name=".AlarmBroadcastReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.TIMEZONE_CHANGED" />
            <action android:name="android.intent.action.TIME_SET" />
            <action android:name="android.intent.action.DATE_CHANGED" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.PACKAGE_REPLACED" />
            <data
                android:path="com.isolity.toastalarm"
                android:scheme="package" />
        </intent-filter>
    </receiver>
</application>

上記で設定したactionの通知時にも、BroadcastReceiverのonReceive()が実行されます。アラーム通知の場合のみ(ここではactionがnullのとき)、ポップアップメッセージを表示します。

class AlarmBroadcastReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == null) {
            // Show popup.
        }
        WeeklyAlarmManager.startNextAlarm(context)
    }
}

改善点

上記コードの改善点として、例えば、アラーム通知の判定がaction==nullだとわかりにくいので、アクション名つけた方がいいですね。あとはDIとかテストの方法はこれから調べます。

※Huaweiのスマホでの注意事項

Huaweiのスマホでは、以下の設定をしないと、アプリをKillしたあとにAlarmManagerの処理が止まってしまい、通知を受け取れなくなってしまいます。
設定 > 詳細設定 > バッテリーマネージャー > 保護されたアプリ > 対象のアプリをONにする
アプリごとに設定が必要なので、アプリを初めてインストールしたときに設定しておきます。僕はHuaweiのP8liteというスマホを使っていて、Emulatorでは動くのに実機で動かず非常に苦労しました。。Android開発者は各端末の知識も必要で大変ですね;

KotlinでAndroidアラームアプリを作った

Androidのアラームアプリを作ったときにやったこと、調べたことを紹介します。

作ったアプリ

ポップアップアラームという設定した時刻にポップアップを表示するアプリを作りました。
ストアに公開したので、ぜひ触ってみてください!

ポップアップアラームの設定画面
ポップアップアラームの通知画面

やったこと

Cordova/PhoneGapでAndroidアプリを作ったことはありますが、ネイティブで作るのは初めてなので、まずは言語仕様の理解から始めました。

  1. Kotlinの理解
  2. 開発環境の構築
  3. 実装
  4. アイコンの作成
  5. リリース

Kotlinの理解

開発言語として、JavaではなくKotlinを選びました。
型推論が欲しいこと、Null安全に興味があったこと、周囲の評判が良かったことが理由です。
※先日、KotlinがAndroidアプリ公式の開発言語に選ばれましたが、僕が選んだ後の話だったのでニュースを見たときは幸せを感じました笑
言語仕様は、その言語を書き始める前にざっと知っておいた方が効率がいいと思っているので、以下の本を読みました。

Kotlinスタートブック

その他、実装中にリスト操作について知りたいことが多かったので、以下の記事を参考にさせていただきました。

Qiita:Kotlin のコレクション使い方メモ

開発環境の構築

Android Studioのインストールは公式サイトより。
Android StudioへのKotlinの導入は、前述のKotlin本を参考にしました。取り急ぎこれで十分かと。
JavaのコードをコピペするとKotlinコードに自動的に変換されるのは、Kotlinの大きなメリットでもありますね。

実装

実装した主な機能は以下の通り。

Androidネイティブの実装は初めてということもあり、だいぶ詰まりました…
細かい部分も含めて、別ページで紹介しようと思います。

広告の実装

アプリにバナー広告を実装してみました。使ったのはGoogleのAdMobです。手順は公式サイトを参考のこと。Android Studioと連携できるのでほぼ自動で実装できました。

アイコンの作成

アイコンの作成には、Inkscapeという無料の画像編集ソフトを使いました。

リリース

リリースの際、APKに署名する必要がありますが、これもAndroid Studioからできます。
むしろ、アプリの説明文を記載するのがなかなか大変ですね。

かかった時間

ざっくりですが、開発にかかった実時間の内訳は以下のような感じ。
といっても期間としては3ヶ月ぐらいかかってます。途中、実装に詰まって手が止まりました;

  • Kotlinの理解 → 1日
  • 開発環境の構築 → 1日
  • 実装 → 2週間
  • アイコンの作成 → 半日
  • リリース → 1日

振り返り

Contextの扱いであったりResourceファイルの違いであったり、Android開発の知識が乏しく実装中に手が止まることが多かったです。実装する前にAndroidの基礎本を読んでおけばよかったかなと。
試しに広告を入れてみましたが、はじめから広告ありきで画面設計、実装しておけば、広告を表示する隙間をあとで開ける必要はなかったかなと。

IonicアプリのCordovaをアップデートする

久しぶりにGoogle Play Developer Consoleを見たら、アラートが表示されていました。
セキュリティアラート画面
アラートが出ているのはIonicで作ったアプリです。このアプリが使用しているCordovaのバージョンに脆弱性があるようで、期限内にアップロードしてね、という通知でした。

Ionicのアップデート

Ionicが依存するCordovaのバージョンは、Ionicのバージョンによって決まります。よってIonicをアップデートする必要があります。

$ npm i -g ionic

アプリのアップデート

Ionicをアップデートしても、アプリはアップデートされないため、一度アプリを消してから作り直す必要があります。まずはアプリを削除します。

$ ionic platform rm android

アプリをビルドし直します。

$ ionic build android

今後も脆弱性が見つかるかもしれないので、都度アップデートする必要がありますね。

C++によるベクトルと行列の計算クラス

大学の研究で運動機構のシミュレーションをしていた時に作った、ベクトルや行列の計算をするクラスを紹介します。GitHubにあるのでダウンロードしてみて下さい。
https://github.com/shoarai/arith

使い方

ベクトルの計算

ベクトルを含んだ計算を演算子のオーバーロードを使って実現することで、数式のようにスッキリと書けます。例では3次元ベクトルを計算していますが、z成分の値を0にすれば2次元ベクトルの計算も問題なくできます。

#include "arith/src/arith.h"
using namespace arith;
int main()
{
    // 初期化
    Vector vecA;              // x=0, y=0,  z=0
    Vector vecB(1, 10, 100);  // x=1, y=10, z=100
    // 要素の設定
    vecA.set(1, 2, 3);
    // 要素の取得
    double x = vecA.getx();
    double y = vecA.gety();
    double z = vecA.getz();
    Vector vecC;
    // ベクトル同士の加減算
    vecC  = vecA + vecB;
    vecC += vecA;
    vecC  = vecA - vecB;
    vecC -= vecA;
    int val = 10;
    // ベクトルとスカラの乗除算
    vecC  = vecA * val;
    vecC *= val;
    vecC  = vecA / val;
    vecC /= val;
    // 外積
    vecC = vecA * vecB;
    // 内積
    double inner = vecA % vecB;
    // ノルム
    double norm = vecA.norm();
    // 正規化
    vecC = vecA.normalize();
    return 0;
}

行列の計算

次は行列の計算!

#include "arith/src/arith.h"
using namespace arith;
int main
{
    // 初期化
    Matrix matA(3, 2);    // 3行2列行列
    Matrix matB(3, 2);    // 3行2列行列
    // 要素の設定
    matA(0, 1) = 10;
    matB(2, 1) = 20;
    // 要素の取得
    double a01 = matA(0, 1);
    double b21 = matB(2, 1);
    // 行列同士の加減算
    Matrix matC = matA + matB;
    matC += matA;
    matC  = matA - matB;
    matC -= matB;
    Matrix matD(2, 3);
    // 行列同士の乗算
    Matrix matE = matD * matA;
    int val = 10;
    // 行列とスカラの乗除算
    matA  = matB * val;
    matA *= val;
    matA  = matB / val;
    matA /= val;
    // 転置行列
    matA = matD.transpose();
    return 0;
}

正方行列の計算

次は行列の中でも、行と列の数が同じ正方行列の計算です。正方行列にのみ定義されている値を計算できます。

#include "arith/src/arith.h"
using namespace arith;
int main
{
    // 初期化
    SquareMatrix smatA(3);    // 3行3列の正方行列
    Matrix matA(2, 2);
    // 正方行列への型変換
    SquareMatrix smatB = matA;
    // 行列式
    double det = smatA.det();
    // 逆行列
    if (det != 0) {
        SquareMatrix smatC = smatA.invrs(det);
    }
    return 0;
}

IonicによるAndroidアプリ作成の最低限

このページでは、UIフレームワークのIonicを使ったアプリの作成について紹介します。

Ionicのインストール

Ionicとその依存モジュールであるcordovaをインストールします。

$ npm install -g cordova ionic

アプリの新規作成

アプリ名はIonicAppとします。テンプレートは作りたいアプリに近いものを選ぶと楽です。

$ ionic start IonicApp blank

Ionicのテンプレート一覧

実装

実装は作りたいアプリに応じてご自由に!!笑

デバッグ&実行

アプリ内のHTMLやJavascriptなどをPCでデバッグしたい場合、以下のコマンドを実行します。ファイルを更新すると自動でブラウザが更新されるのでとっても便利です。

$ ionic serve

モバイル機器でアプリを実行したい場合、対応するプラットフォームを追加します。iPhoneやiPadで実行したい場合、「android」ではなく「ios」となります。

$ ionic platform add android

追加したプラットフォームを実行します。

$ ionic run android

また、上記PCでの実行と同様に、HTMLやJavascriptを更新した時に、再ビルドなしで実行するためには、以下のコマンドを実行します。「-l」はlivereloadの意味です。このコマンドで実行した場合、HTMLなどのソースはモバイル機器にダウンロードされるのではなく、PCがWebサーバーとなってモバイル機器からアクセスされるようになります。

$ ionic run android -l

アイコンの作成

Ionicのアプリアイコンのファイルはresourcesフォルダ内にあります。icon.pngはホーム画面に表示されるアプリのアイコン画像であり、splash.pngはアプリ起動時に表示されるスプラッシュ画像です。これらのファイルをそれぞれ上書きしてから下記コマンドを実行すると、各プラットフォーム用のアイコンサイズに変換してくれます。

$ ionic resources

APK作成

作ったアプリをAndroidアプリとしてGoogle Playに公開するために、APKファイルを作成します。手順はPhoneGapアプリの公開用APKを作るをご覧ください。

多言語化

アプリが日本語で公開できるレベルになったら、ぜひ英語でも公開しましょう。一度仕組みを作ってしまえば簡単に多言語化できます。
まず多言語化を行うangular-translateと多言語ファイルを外部ファイルとして読み込むangular-translate-loader-static-filesをダウンロードします。

$ ionic add angular-translate
$ ionic add angular-translate-loader-static-files

これらのモジュールをHTMLから読み込みます。

<!-- www/index.html -->
<!DOCTYPE html>
  ...
  <script src="lib/angular-translate/angular-translate.min.js"></script>
  <script src="lib/angular-translate-loader-static-files/angular-translate-loader-static-files.min.js"></script>
  ...
</html>

アプリのAngularJSモジュールとして追加します。

// www/js/app.js
angular.module('starter', [
 ... , 'pascalprecht.translate'
])
...

多言語ファイルの読み込み設定と言語の適用を行います。言語の適用はOSに設定された言語を使用し、もしその言語用のファイルがなければ変数defaultLangに入れた言語が適用されます。多言語ファイルはjs/langフォルダ内の言語コード.json(例:ja.json)を使用します。これで多言語化の準備は完了です。対応する言語を増やしたいときは、その言語の用語ファイルを追加するだけです。

// www/js/app.js
...
.config(function($translateProvider) {
  $translateProvider.useStaticFilesLoader({
    prefix: 'js/lang/',
    suffix: '.json'
  });
  var defaultLang = 'en';
  var getLang = function() {
    try {
      return (navigator.browserLanguage || navigator.language || navigator.userLanguage).substr(0, 2)
    } catch (e) {
      return defaultLang;
    }
  }
  $translateProvider.preferredLanguage(getLang());
  $translateProvider.fallbackLanguage(defaultLang);
})

実際に多言語化するためには、下記のような用語ファイルをlangフォルダに作ります。各メッセージにIDを振ります。

www/js/lang/ja.json
{
  "START": "はじめる",
  "GAMEOVER": "Game Over",
  "RESTART": "もう一度",
  "": ""
}
www/js/lang/en.json
{
 "START": "Start",
 "GAMEOVER": "Game Over",
 "RESTART": "Restart",
 "": ""
}

HTMLからこれらの用語を使うには、translate属性を追加してメッセージIDを指定します。

<!-- www/index.html -->
...
   <button class="button button-assertive" translate>START</button>
...

Javascriptから使うにはtranslateサービスを使います。

// controller.js
app.controller('Ctrl', ['$scope', '$translate', function($scope, $translate) {
  $scope.start = $translate('START');
}]);

終わりに

アプリ作成のために必要最低限のことを突っ走って書いてきましたが、他に必要だと思ったら適宜追記します。
僕自身はIonicを使って2つのアプリを作りました。動作の確認のためなど試しに触って見てください。
ぽりごんのアプリアイコン           Compositionのアプリアイコン

kizAPIを使って関連語を取得する

このページでは、kizAPIを使ってある言葉の関連語を取得する方法を紹介します。

kizAPIとは

kizAPIとは、kizasi.jpというブログ検索サイトが提供しているWeb APIです。機能としては、ある言葉に関連する言葉を取得したり、今話題になっている言葉を取得できたりします。利用規約はここの最下部「利用規約」にあるので、利用する場合はあらかじめご確認ください。

関連語の取得

下記index.htmlをブラウザで表示すると、「sho」に関連する言葉が表示されます。依存モジュールとしてjQueryとjquery.xdomainajax.jsを利用しています。jquery.xdomainajax.jsはクロスドメイン対策で利用しています。ここからダウンロードして下さい。

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>kizAPI</title>
</head>
<body>
  <h1>Terms</h1>
  <div id="terms"></div>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
  <script src="js/jquery.xdomainajax.js"></script>
  <script src="js/kizapi.js"></script>
  <script src="js/index.js"></script>
</body>
</html>

kizAPIにアクセスしているのがkizapi.jsです。引数で渡した検索語の関連語を取得できます。

// js/kizapi.js
/**
 * @fileOverview kizapi API
 */
(function(global) {
  'use strict';
  var kizapi = {
    /**
     * 関連語を取得する
     * @param    {string}   key   検索語&nbsp;
     * @param    {string}   span  '24':1日, '1w':1週間 or '1m':1月
     * @return   {object}         レスポンス
     * @property {string[]} terms 関連語
     */
    getRelatedTerms: function(key, span) {
      var defer = $.Deferred();
      if (this._reqFlag && this._reqId.abort) {
        this._reqId.abort();
      }
      this._reqFlag = true;
      var that = this;
      this._reqId = $.ajax({
        type: 'GET',
        url: 'http://kizasi.jp/kizapi.py',
        data: {
          span: span,
          kw_expr: key,
          type: 'coll'
        }
      }).done(function(data, statusText, jqXHR) {
        var xml = data.results[0];
        var json = $.parseXML(xml);
        var terms = [];
        $(xml).find('channel').find('item').each(function() {
          var item = $(this).text();
          var items = item.split(/\r?\n/g);
          var term = items[1].trim();
          terms.push(term);
        });
        defer.resolve({
          terms: terms
        });
      }).always(function() {
        that._reqFlag = false;
      });
      return defer.promise();
    },
    _reqId: {},
    _reqFlag: false
  };
  if ('process' in global) {
    module.exports = kizapi;
  }
  global.kizapi = kizapi;
}((this || 0).self || global));

kizAPIを呼び出しているのがindex.jsです。検索語「sho」の関連語を画面に表示しています。

// js/index.js
$(function() {
  var key = 'sho';
  kizapi.getRelatedTerms(key, '1m').done(function(data) {
   var html = '';
   var terms = data.terms;
   for (var i = 0, len = terms.length; i < len; i++) {
     html += '<span>' + terms[i] + '</span>;';
   }
   $('#terms').html(html);
 });
});

関連語取得サービス

上記のモジュールを利用して作ったのが「ke」です。「ke」は検索したいキーワードの関連語を表示してくれます。
keのアプリ画面

感想

以上、いろいろなWebAPIを試してみて、何に活用できるかを考えるのは楽しいですね。