強火で進め

このブログではプログラム関連の記事を中心に書いてます。

2の累乗(べき乗)であるかどうかをシンプルなプログラムでチェック

OpenGLを使っているとテクスチャがちゃんと2の累乗(べき乗)のサイズかどうかをチェックする場面が有るかと思います。
※2の累乗とは2,4,8,16,32など2を何回か掛けた値の事です。
OpenGLのバージョンやハードによっては2の累乗じゃ無くても良い時もあります。

その判定をシンプルに行っている記事がTwitterで紹介されていて、非常にナルホドという記述だったので紹介。

記事はこちら

WebGL and OpenGL Differences - WebGL Public Wiki
http://khronos.org/webgl/wiki/WebGL_and_OpenGL_Differences

該当プログラムはこちらになります。

function isPowerOfTwo(x) {
    return (x & (x - 1)) == 0;
}

例えば8だった場合はビットで表すと 1000 となり、それを-1すると 0111 となります。この様に2の乗数の場合にはちょうどビットが 1 & 1 となるのを回避する並びになり、結果は0となります。それ以外のパターンであれば、いずれかの桁で両方のビットが立っている桁が発生するため結果は0以外となります。

こういうカッコ良いプログラムをサラッと書ける様になりたいものです。

エレキジャックのmbedの入門記事まとめ

エレキジャックのサイトのmbedの記事が良い記事なのですが過去記事が読み辛いのでアクセスしやすい様にリンク集としてまとめました。

最初の方の<1>〜<14>をまとめました。<15>以降はGoogleで以下のフォーマットで検索すれば検索結果のトップ付近に見つかるはずです。

<15>mbed入門 site:www.eleki-jack.com

(検索例)
http://www.google.co.jp/search?hl=ja&source=hp&biw=1063&bih=549&q=%3C15%3Embed%E5%85%A5%E9%96%80+site%3Awww.eleki-jack.com&aq=f&aqi=&aql=&oq=&gs_rfai=

<15>以外の場合は<15>の部分を検索したい番号に変えて検索して下さい。

デバッグ。printf()やgetc()を使う

LEDを点滅させる様な簡単なプログラムが書けたので段々と大規模なプログラムに進もうかと思う所ですが大規模なプログラムになるとコードを目視しただけでのデバッグは辛くなるのでちゃんとデバック方法をチェックしておこうと Debugging のページをチェックしました。

printf()を使う

Debugging - Handbook | mbed
http://mbed.org/handbook/Debugging

ココを見ると printf() が使えるとの事なので早速この様なプログラムで試してみました。最初に printf() で test と出力した後にLEDを点滅させるプログラムです。

#include "mbed.h"

DigitalOut myled1(LED1);

int main() {
    printf("test\n");
    while(1) {
        myled1 = 1;
        wait(0.2);
        myled1 = 0;
        wait(0.2);
    }
}

ターミナルを開いた状態でこちらのプログラムを実行したのですがターミナルには何も表示されませんでした。

「うーむ、こりゃ事前に何かコマンド打っとかないといけないっぽいかな?」と思いこちらのページからリンクが張ってあったこちらのページやGoogle検索をした結果、以下の手順が必要な事が分かりました。

1. まずターミナルで以下のコマンドを実行してmbedがどこに接続されているか確認。

ls /dev/tty.usbmodem*

2. 次に screen コマンドを以下の様な記述で実行。

screen /dev/tty.usbmodem412 9600

※ /dev/tty.usbmodem412 の部分は実際には 1. で確認したパスを設定。
※screenの実行を終了するには Ctrl+a を押した後に \ を押す。確認メッセージが出るので y を押す。

その結果はこちら

何やら改行が上手く処理されて無いみたいですね。改行の\nがCR(行頭に復帰)+LF(改行)ではなくLF(改行)として解釈されているっぽいですね。

色々、検索してみたのですがどのサイトでも screen のこの改行の解釈を変更する方法が記載されていませんでした。どのサイトでも screen コマンドを使う代わりに別のアプリを使用する事で解決していました。

という事で自分もアプリを導入して解決する事にして色々試してみました。しかし、どれも結構メンドクサイ。最終的にこちらのページのコメント欄で紹介されている「CoolTerm」を使う事にしました。インストールも使用方法も簡単で良いアプリでした。

Terminals - Handbook | mbed
http://mbed.org/handbook/Terminals

アプリはこちらのサイトから「CoolTerm」というアプリを探してDLして下さい。

Roger Meier's Freeware
http://freeware.the-meiers.org/

DLしたら解凍し、フォルダごとアプリケーションフォルダに移動するだけでインストールは完了です。mbedを接続した状態で起動して下さい。

なお、 screen コマンドで接続中のままだとこちらのアプリで繋げない様なのでまだ接続している場合は先にそちらは終了させておいて下さい。

起動すると Connect のアイコンをクリック。これだけで準備完了です。むちゃくちゃ簡単ですね。

この状態でmbedのリセットボタンを3回押したらこの様に表示されました。

理想的な結果ですね。

getc()を使う

printf() 以外にも getc() も使えるみたいなのでこちらも試してみました。

取り敢えず、こちらのサンプルの以下のプログラムをコピペして実行してみました。

#include "mbed.h"

Serial pc(USBTX, USBRX); // tx, rx
PwmOut led(LED1);

float brightness = 0.0;

int main() {
    pc.printf("Press 'u' to turn LED1 brightness up, 'd' to turn it down\n");

    while(1) {
        char c = pc.getc();
        if((c == 'u') && (brightness < 0.5)) {
            brightness += 0.01;
            led = brightness;
        }
        if((c == 'd') && (brightness > 0.0)) {
            brightness -= 0.01;
            led = brightness;
        } 

    }
}

プログラムを読むとPCのキー入力でLEDの明るさを変更するプログラムの様です。uキーを押すと明るくなり、dキーを押すと暗くなる様です。

実行したところバッチリ反応しました。しかし、これだと現在どの位の値に成っているのかが分から無いので以下の様にdキーの入力判定処理の後に printf() で表示させてみました。

        if((c == 'd') && (brightness > 0.0)) {
            brightness -= 0.01;
            led = brightness;
        } 
        pc.printf("brightness=%f\n", brightness);
    }
}

これを実行した結果がこちら。とても分り易くなりましたね。

mbed、printf()やgetc()が使えるのは良いですね。これはデバックやちょっとしたテストにとても重宝しそうです。

関連ページ

Serial Communication with a PC(翻訳) | mbed
http://mbed.org/users/kokotaro/notebook/Serial-Communication-with-a-PC-ja/

SerialPC - Handbook | mbed
http://mbed.org/handbook/SerialPC

Terminals - Handbook | mbed
http://mbed.org/handbook/Terminals

Debugging - Handbook | mbed
http://mbed.org/handbook/Debugging