Androidを使ったテープLEDストリップライト
スマートフォンに3色テープLEDを接続し、タッチパネルによる制御で、光のショーを演出できます!
コーヒーテーブルの下や、自転車、あるいはちょっと彩りを付けたいと思う物に、彩りが変化するLEDを取り付けてみましょう。
組込用マイクロコントローラーに、スマートフォンを接続するには色々な方法があります。
このプロジェクトでは、USBホストモードに対応しているAndroidスマートフォンを使用します。
このやり方で、AndroidスマートフォンはArduinoに対し、電源供給と通信の両方ができてしまいます! ArduinoがUSB接続されている時は、PCにArduinoが接続された時と同様、シリアル通信が行なわれます。
ひとたびスマートフォンがArduinoと通信できてしまえば、新たなるプロジェクトの全貌が見えてきます!
プログラムのダウンロード
- アプリのダウンロードとインストールはこちら→http://trevorshp.com/creations/ArduinoColor.apk
- 全ソースコードはこちら→http://github.com/trevorshannon/ArduinoColor
【ご注意】このプロジェクトのビルドは自己責任の元において行なってください。筆者はビルドテストの際に携帯電話を壊してしまっています。
Androidスマートフォンの中には、USBホストモードに対応していない物があります。Android OS、USBホストモードドライバーと互換性のあるスマートフォンを使用してください。
お持ちのAndroidデバイスが、USBホストモード(OTG)に対応しているかどうかをお知りになりたい場合、詳細についてはこちらをご覧下さい→http://android.stackexchange.com/questions/36887/how-can-i-determine-if-my-device-has-usb-host-mode-otg-support
ステップ1:回路作成
- 3色テープLEDは通常4線(電源、赤、緑、青の3色制御用)となっています。
- テープLEDは電源投入時、各色制御用の線をGNDに直接接続すると、LED素子が最大輝度で点灯します。
- 各色制御用の線にPWM(パルス幅による制御)信号を与えることにより、輝度を操作することが出来ます。
- RGB各色が最大輝度で点灯した場合、長さ1mのテープLEDには、1A近くの電流が流れます。
- Arduinoの出力ピンからは電流を40mAしか流せないので、出力アップさせるためには、ドライバー回路を使わなければなりません。
- この回路は、Arduinoから3つのPWM信号を出力してトランジスターを駆動し、RGB各色のLED素子に電流を供給します。これで各色の輝度制御が個別に可能になり、RGB各色の光の組合せにより様々な色彩を作ることが出来るのです。
- 【ご参考】テープLED全体ではなくて、1~2個だけ、電源を供給したいのであれば、トランジスターは要らないので、LED素子を、Arduinoの出力ピンに直接接続してください。
- 1番目の写真のドライバー回路は、基本的なトランジスターによる増幅回路を3つ並べただけです。
- PWM信号(5Vの小電流)は、Arduinoから1kΩの抵抗器を介して、トランジスターのベース(B)に流れ込みます。
- このPWM信号がトランジスターをスイッチOnすると、12Vの大きな電流が、トランジスターのコレクター(C)、エミッター(E)を介し、LED素子に流れます。
- トランジスターのスイッチング速度が十分に速いため、PWMの入力信号通りLED素子に電流が与えられますので、ご希望の輝度に調整することが出来ます。
- 【ご参考】2番目の写真のように、トランジスター「TIP31」のピン配置に応じ、色をコントロールするトランジスターごとに、ピンを正しく接続してください。
- あと、ArduinoのGNDを、12V電源のGNDへ、必ず接続してください!
- 3番目の写真のような回路が完成します。回路の出力は(【訳者注】ブレッドボード上にある)右側の4ピンヘッダーに流れるので、3色テープLEDを接続することが出来るようになります。
ステップ2:OTGケーブル自作(オプション)
- 多くのAndroidスマートフォンは、USB On-The-Go(OTG)デバイスです。
- すなわち、USBホストモード(電源を提供する側)、USBスレーブモード(電源が供給される側)の両方で動作できるということです。
- スマートフォンと、ArduinoのようなUSBデバイスを接続するためには、USB OTGケーブルが必要です。
- オンラインで数ドルほどで購入することができますが、旧規格のUSBケーブルをお持ちであれば、こちらにご紹介のとおり、自作してみるのも面白いかと存じます→http://makezine.com/projects/usb-otg-cable/
ステップ3:Androidアプリのインストール
- Androidアプリに数行のコードを追加すれば、USB OTGケーブルを介し、Arduinoへ様々な種類のデータを送信することができます。
- ここでは、赤、緑、青の各色LEDへ、0~255の間の輝度値を送信します。
- Mike Wakerlyさんが、このパズルの重要部分を紹介しています。
- 彼は、Arduino基板上にあるUSB-シリアル変換IC用の、素晴らしいドライバー・プログラムを作成しました。「usb-serial-for-android」といいます。
- スマートフォンからArduinoへのデータ送信が、Androidアプリ上で「device.write()」を呼び出すだけで出来てしまうのです!
- Katie Dektarさんの素晴らしいサンプルアプリ(「Color Namer」という名のオープンソースコードです)はこちらにございます→http://github.com/kaytdek/ColorNamer
- ここのプロジェクトのために、筆者は「Color Namer」を簡単な作りにしました。「Arduino Color」といいます。
- こちらからダウンロード/インストールできます→http://trevorshp.com/creations/ArduinoColor.apk
- 全ソースコードはこちらから取得できます→http://github.com/trevorshannon/ArduinoColor
ステップ4:ご自身のアプリ作成(オプション)
- ご自身のアプリを開発したいのであれば、こちらのWakerlyさんのドライバー・プログラムをダウンロードしてください→http://code.google.com/p/usb-serial-for-android
- そして「usb-serial-for-android」のJarファイルを「[アプリのrootディレクトリー]/libs directory」へコピーしてください。
- このJarファイルはプリコンパイルされたライブラリーであり、Androidアプリからシリアル通信デバイスOpen/Close/Write/Readの実行に必要なファンクションが全て格納されております。
- 次に、ファイル「device_filter.xml」を「[アプリのrootディレクトリー]/res/xml」へコピーします。
- このファイルは、スマートフォンに接続されているUSBデバイスのルックアップテーブルとして機能します。
- Arduinoを接続すると(USB-シリアル変換ICのメーカーによって設定された)デバイスIDが、スマートフォンに送信されます。
- アプリ内のファイル「device_filter.xml」上にデバイスIDが存在すれば、そのアプリが自動的に実行されます(ArduinoのIDは「device_filter.xml」上に既にあるため、このファイルに変更を加える必要はございません)
- 最後に、一番最初にUSBデバイスが検索(ルックアップ)されるようアプリの設定をします。
- アプリ内のファイル「AndroidManifest.xml」を開き、タグ内に適宜情報を追加記述してください。サンプルコード1はこちら→http://cdn.makezine.com/make/36/step-4-example1.doc
- Wakerlyさんのライブラリーとマージする際は、アプリ開始時にシリアル通信デバイスをオープンし、アプリ停止時にデバイスをクローズするコードを記述してください。
- 例として「Arduino Color」からのコードを掲載します。サンプルコード2はこちら→http://cdn.makezine.com/make/36/step-4-example2.doc
private UsbManager usbManager;
private UsbSerialDriver device;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// USB managerをAndroidから取得
usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
...
}
protected void onResume() {
super.onResume();
// USB-Serialデバイスのオブジェクトを取得
device = UsbSerialProber.acquire(usbManager);
if (device == null) {
//接続されているデバイスが無い
Log.d(TAG, “No USB serial device connected.”);
} else {
try {
//デバイスをオープン
device.open();
//通信スピードを設定
device.setBaudRate(115200); //接続先デバイスの設定と合っているかご確認ください! 【訳者注:Arduinoスケッチで設定されているボーレートと同値であることを確認してください】
} catch (IOException err) {
Log.e(TAG, “Error setting up USB device: “ + err.getMessage(), err);
try {
//オープンに失敗した場合デバイスをクローズ
device.close();
} catch (IOException err2) {
//クローズに失敗した場合は何も行なう必要無し
}
device = null;
return;
}
}
}
protected void onPause() {
super.onPause();
//デバイスが既にクローズされているかどうかチェック
if (device != null) {
try {
device.close();
} catch (IOException e) {
//クローズに失敗した場合は何も行なう必要無し
}
//デバイスへの参照を解除【訳者注:nullを設定することによりデバイスのオブジェクトが参照されなくなり、デバイスが解放されます】
device = null;
}
}
- そして、メソッド「write()」を使用し、オープンされたシリアル通信デバイスへ、データを送信することができます。
- 例えば、アプリ「Arduino Color」は、色を指すピッカーにユーザーがタッチすると、シリアル通信により色制御データを送信します。サンプルコード3はこちら→http://cdn.makezine.com/make/36/step-4-example3.doc
//カラーパレットにタッチした時に呼出される
public boolean onTouch(View view, MotionEvent event) {
int color = 0;
color = colorPicker.getColor(event.getX(),event.getY(),true);
...
//データをArduinoへ送信
sendToArduino(color);
return true;
}
//色データを{R, G, B, 0x0A}形式でシリアルデバイスへ送信
private void sendToArduino(int color){
byte[] dataToSend = {(byte)Color.red(color),(byte)Color.green(color),(byte)Color.blue(color), 0x0A};
//シリアルデバイスがデータと混同しないように、色データの中に改行文字があった場合はあらかじめ除去しておく
for (int i=0; i<dataToSend.length-1; i++){
if (dataToSend[i] == 0x0A){
dataToSend[i] = 0x0B;
}
}
//色データをシリアルデバイスへ送信
if (device != null){
try{
device.write(dataToSend, 500);
}
catch (IOException e){
Log.e(TAG, “couldn’t write color bytes to serial device”);
}
}
}
ステップ5:Arduinoスケッチのアップロード
- 本プロジェクトのArduinoスケッチ(コード)はとてもシンプルです。
- スケッチはこちら→http://trevorshp.com/creations/android_leds.ino
- //Serial RGB led controller
- //Author: Trevor Shannon
- //see http://trevorshp.com/creations/android_led.htm
- //ピン定義(PWM機能が使用できるピンを使うこと!)
- const int redPin = 9;
- const int greenPin = 10;
- const int bluePin = 11;
- //各色のLED素子間の色調バランスを整えるための
- //デューティー比最大値
- //白色 (R=255, G=255, B=255) で色付きが発生してしまった場合、
- //下記の定数値を小さくして調整します
- const int max_red = 255;
- const int max_green = 90;
- const int max_blue = 100;
- byte colors[3] = {0, 0, 0}; //各色LED素子の輝度値を保持する配列
- byte lineEnding = 0x0A; //ASCII改行文字(10進数の値10)
- void setup(){
- //LED素子への出力ピンを3色分全て設定
- pinMode(redPin, OUTPUT);
- pinMode(greenPin, OUTPUT);
- pinMode(bluePin, OUTPUT);
- //シリアル通信開始【訳者注:引数はボーレート】
- Serial.begin(115200);
- }
- void loop(){
- //シリアルポート上に、読取可能データが
- //最低3バイト存在するかチェック
- if (Serial.available() > 2){
- //改行文字(0x0A)が現れるまでデータを読取り、配列にセット
- int bytesRead = Serial.readBytesUntil(lineEnding, (char*)colors, 3);
- }
- //シリアルポートから読込んだデータに応じて、3つのPWMピン出力信号を設定
- //map()により値を設定すれば、R, G, B各色の色調バランスが取れるようになります
- analogWrite(redPin, map(colors[0], 0, 255, 0, max_red));
- analogWrite(greenPin, map(colors[1], 0, 255, 0, max_green));
- analogWrite(bluePin, map(colors[2], 0, 255, 0, max_blue));
- }
- 上記スケッチをダウンロードし、Arduino IDE(統合開発環境)で開き、Arduino基板へアップロード(書込)してください。
- コードはArduino IDEで提供されているSerialライブラリーを使っています。シリアル通信でArduinoへ送信されたデータを、スケッチで簡単に読込めます。
- 無限ループのコード内で、シリアルポート上の読取可能バイト数を照会します。
- 最低3バイトの有効なデータが送られた場合、読込まれたバイトデータは、赤、緑、青の輝度値として配列にセットされます。
- 上記の輝度レベルを使い、それに対応したPWM出力が設定されます。
- 以下の様な定数(constant)がございます。
- max_red
- max_green
- max_blue
- テープLED上のLED素子は、色調バランスがうまくとれないことがあります。
- 赤、緑、青の各色LED素子を最大輝度で点灯した場合、理論上は白色光ができるはずです。
- ところが実際には、わずかに色付いてしまっていることが分かります(一般的には緑色や青色が付きやすい)。
- こうしたことは、関数「map」を呼出し、定数の値(最大値)を微調整することによって補うことが可能です。
- こちらのサンプルコード4をご覧下さい→http://cdn.makezine.com/make/36/step-5-example.doc
ステップ6:全てを接続
- 光のショーを始める準備ができました! スマートフォンにArduinoを接続すると、Arduinoのアプリを実行するか否かの確認ポップアップが表示されると思います。それでは、どうぞ!
- (ブレッドボード上の)ドライバー回路にテープLEDを接続し、12V電源を投入します。スマートフォンにインストールされたAndroidアプリを使い、テープLEDの光の色彩をリアルタイム調整できるかと存じます。
- テープLEDを、コーヒーテーブルの下側に取り付けたり、夜のパーティー用に持っていったり、自転車に取り付けたりしてみましょう!
No Comment to " Androidを使ったテープLEDストリップライト "