まごころせいじつ堂

浜町庄金 研究開発  マイコンで遊んでばっかりで

2012年08月

PS/2キーボード変換器の製作(15) US配列→JP配列の問題点

US配列から日本語配列に変換する部分を作成した。
Arduino用のスケッチは以下のとおり。これはUSB HIDキーボードに文字を出力すると共にシリアルポートにデバッグ情報を流す。
https://gist.github.com/3464019
ライブラリ(ps2kybd.h、ps2kybd.cpp)は前回から修正なし。
https://gist.github.com/ab100bfb33a78ddf067d



記号の置き換えは、以下のパターンで行う。
(1)SHIFTを押していない状態でSHIFTを押したような入力……右シフトキーpress、置き換えコード、右シフトキーrelease
(2)SHIFTを押していない状態で記号の置き換え……置き換えコード
(3)SHIFTを押した状態でSHIFTを押したような入力……置き換えコード
(4)SHIFTを押した状態でSHIFTを押さないような入力……左右のシフトキーをrelease、置き換えコード、元のシフトキーをpress

ALTキーを押した状態では、[`~]キーは変換せずにそのまま出力することで[ALT]+[漢字]と同じ操作になる。

 これで記号の置き換え、漢字入力のON/OFFができた。

 残った問題点。
(1)CapsLockの扱い。CapsLockはUSキーではSHIFT併用だが、日本語キーではそのまま。
→Capsフラグはライブラリ側にまかせているが、これをスケッチ側で対処
(2)[¥_]が入力できない →Arduino LeonardoはいったんASCIIコードで受けて内部で変換しUSB HIDコードを送っている。USキーのレイアウトを前提にしているため、日本語配列の[¥_]は対応するものがない。
(3)このアダプタをWindowsXPに接続するたびにデバイスドライバの確認ダイアログが登場する。

(2)、(3)は非常に大きな問題。

(2)はUSB HIDを直接送出する方法を調べなければならない。
(3)はArduinoのブートローダを置き換えなければならない。

うーん、これはけっこう難しいぞ……

鳥人間Harpy nano/H2A nanoは3V3と5Vが入れ替わっている

株式会社鳥人間の小型Arduino互換ボード Harpy nanoと、Arduino用シールドを取り付けるためのアダプタH2A nanoだけど、3.3V動作の回路を工作してて気付いた。H2A nanoの3.3Vと5Vが入れ替わっている。
2012harpy
H2A nano。

左から RESET,3V3,5V,GNDの順だけど、H2A nanoの端子をテスタで確認したら 3V3と5Vが入れ替わっていた。
H2A nano 回路図によるとRESET,5V,3V3の順になっている。シルクは通常のArduinoと同じ。

 持ってる方はご注意を。製造元には連絡済みなので次の版からは直るかもしれません。

追記:次の版は修正済で、旧版を持ってる方は交換対応してくれるとのことです。

GR-SAKURAのイーサポートがシールドと干渉する

2012grsakura1

 見たまんま。シールドによってはショートする危険性もある。

2012grsakura2

 まあこうするしかないよね。

 Netduino plusという、同じようにイーサの口を持ったボードはこうなってる。

2012netduino1

 プラスチック製で絶縁されており、基板の下に逃がしてあるので背が低い。
 2012netduino2


スイッチサイエンス32U4ブレークアウトボードとAVRISPmkII

スイッチサイエンスの32U4ブレークアウトボードをArduino Leonardo化した。

SWITCH SCIENCE 32U4ブレークアウトボード

AVR ISPmkIIでArduinoブートローダを書き込むための端子は以下。

SCK (2).B1
MOSI (3).B2
MISO (4).B3
RST (5)
Vcc (6)
GND (21)

ACR ISPmkIIのICSP端子を上から見た図
AVRISPmkIIcon

ブレッドボード上で書き込み用の接続。32U4ブレークアウトボードはひっくり返して載せてる。また、AVR ISPmkIIのICSPコネクタは写真では上を向けているのでVccが左上に見える(赤い線)。
AVRISPmkII-32U4
 
 Arduino IDEから[ツール]→[書込装置]でAVRISPmkIIを選択し、[ツール]→[ブートローダを書き込む]でしばらく待つと青いLEDが点滅するようになる。これでOK。

参考:
AVRC Programming-Programmer

GR-SAKURA がじぇるねボード

RSコンポーネンツで注文したGR-SAKURA がじぇるねボードが届いた。ルネサスのRX63Nマイコンを搭載し、Arduinoのシールドが使える。単体でもEther、USB、SDカードなど機能豊富。

 2012sakura1

 USBコネクタが部品で付属している。必要なら半田付け。

2012sakura

 USBケーブルを接続して赤いリセットボタンを押すと、GR-SAKURAがドライブとして認識される。これにwebコンパイラでコンパイルしたバイナリをコピーするとそれを実行する。えらい簡単。

 MacOSXで動作確認した。/Volumes/GR-SAKURAとして見える。

がじぇっとるねさす
SAKURA BOARD 

 浮動小数点演算のハードを内蔵しているということで、whetstoneでも試してみようかと思い動かしてみた。

元ネタ:Benchmark Programs and Reports

/*GR-SAKURA Sketch Template Version: V1.00*/
#include <rxduino.h>

#define INTERVAL 100


#define ITERATIONS    10000 /* 1 Million Whetstone instructions */

#include "math.h"

#define PREC float

PREC        x1, x2, x3, x4, x, y, z, t, t1, t2;
PREC         e1[4];
int        i, j, k, l, n1, n2, n3, n4, n6, n7, n8, n9, n10, n11;


void setup()
{
    Serial.begin(9600); 
    pinMode(PIN_LED0,OUTPUT);
    pinMode(PIN_LED1,OUTPUT);
    pinMode(PIN_LED2,OUTPUT);
    pinMode(PIN_LED3,OUTPUT);
}

void pa(PREC *e)
{
    register int j;

    j = 0;
     lab:
    e[0] = (  e[0] + e[1] + e[2] - e[3] ) * t;
    e[1] = (  e[0] + e[1] - e[2] + e[3] ) * t;
    e[2] = (  e[0] - e[1] + e[2] + e[3] ) * t;
    e[3] = ( -e[0] + e[1] + e[2] + e[3] ) / t2;
    j += 1;
    if (j < 6)
        goto lab;
    return;
}


void p3(PREC x, PREC y, PREC *z)
{
    x  = t * (x + y);
    y  = t * (x + y);
    *z = (x + y) /t2;
    return;
}


void p0()
{
    e1[j] = e1[k];
    e1[k] = e1[l];
    e1[l] = e1[j];
    return;
}

#ifdef POUT
pout(int n, int j, int k, PREC x1, PREC x2, PREC x3, PREC x4)
{
    printf("%6d%6d%6d  %5e  %5e  %5e  %5e\n",
        n, j, k, x1, x2, x3, x4);
}
#endif

void testfloat() {

    /* initialize constants */

    t   =   0.499975;
    t1  =   0.50025;
    t2  =   2.0;

    /* set values of module weights */

    n1  =   0 * ITERATIONS;
    n2  =  12 * ITERATIONS;
    n3  =  14 * ITERATIONS;
    n4  = 345 * ITERATIONS;
    n6  = 210 * ITERATIONS;
    n7  =  32 * ITERATIONS;
    n8  = 899 * ITERATIONS;
    n9  = 616 * ITERATIONS;
    n10 =   0 * ITERATIONS;
    n11 =  93 * ITERATIONS;

/* MODULE 1:  simple identifiers */
    digitalWrite(PIN_LED0, 1);

    x1 =  1.0;
    x2 = x3 = x4 = -1.0;

    for(i = 1; i <= n1; i += 1) {
        x1 = ( x1 + x2 + x3 - x4 ) * t;
        x2 = ( x1 + x2 - x3 - x4 ) * t;
        x3 = ( x1 - x2 + x3 + x4 ) * t;
        x4 = (-x1 + x2 + x3 + x4 ) * t;
    }
#ifdef POUT
    pout(n1, n1, n1, x1, x2, x3, x4);
#endif


/* MODULE 2:  array elements */
    digitalWrite(PIN_LED1, 1);

    e1[0] =  1.0;
    e1[1] = e1[2] = e1[3] = -1.0;

    for (i = 1; i <= n2; i +=1) {
        e1[0] = ( e1[0] + e1[1] + e1[2] - e1[3] ) * t;
        e1[1] = ( e1[0] + e1[1] - e1[2] + e1[3] ) * t;
        e1[2] = ( e1[0] - e1[1] + e1[2] + e1[3] ) * t;
        e1[3] = (-e1[0] + e1[1] + e1[2] + e1[3] ) * t;
    }
#ifdef POUT
    pout(n2, n3, n2, e1[0], e1[1], e1[2], e1[3]);
#endif

/* MODULE 3:  array as parameter */
    digitalWrite(PIN_LED2, 1);

    for (i = 1; i <= n3; i += 1)
        pa(e1);
#ifdef POUT
    pout(n3, n2, n2, e1[0], e1[1], e1[2], e1[3]);
#endif

/* MODULE 4:  conditional jumps */
    digitalWrite(PIN_LED3, 1);

    j = 1;
    for (i = 1; i <= n4; i += 1) {
        if (j == 1)
            j = 2;
        else
            j = 3;

        if (j > 2)
            j = 0;
        else
            j = 1;

        if (j < 1 )
            j = 1;
        else
            j = 0;
    }
#ifdef POUT
    pout(n4, j, j, x1, x2, x3, x4);
#endif

/* MODULE 5:  omitted */

/* MODULE 6:  integer arithmetic */
    digitalWrite(PIN_LED0, 0);

    j = 1;
    k = 2;
    l = 3;

    for (i = 1; i <= n6; i += 1) {
        j = j * (k - j) * (l -k);
        k = l * k - (l - j) * k;
        l = (l - k) * (k + j);

        e1[l - 2] = j + k + l;        /* C arrays are zero based */
        e1[k - 2] = j * k * l;
    }
#ifdef POUT
    pout(n6, j, k, e1[0], e1[1], e1[2], e1[3]);
#endif

/* MODULE 7:  trig. functions */
    digitalWrite(PIN_LED1, 0);

    x = y = 0.5;

    for(i = 1; i <= n7; i +=1) {
        x = t * atan(t2*sin(x)*cos(x)/(cos(x+y)+cos(x-y)-1.0));
        y = t * atan(t2*sin(y)*cos(y)/(cos(x+y)+cos(x-y)-1.0));
        // x = x * 2;
        // y = y * 2;
}
#ifdef POUT
    pout(n7, j, k, x, x, y, y);
#endif

/* MODULE 8:  procedure calls */
    digitalWrite(PIN_LED2, 0);

    x = y = z = 1.0;

    for (i = 1; i <= n8; i +=1)
        p3(x, y, &z);
#ifdef POUT
    pout(n8, j, k, x, y, z, z);
#endif

/* MODULE9:  array references */
    digitalWrite(PIN_LED3, 0);

    j = 1;
    k = 2;
    l = 3;

    e1[0] = 1.0;
    e1[1] = 2.0;
    e1[2] = 3.0;

    for(i = 1; i <= n9; i += 1)
        p0();
#ifdef POUT
    pout(n9, j, k, e1[0], e1[1], e1[2], e1[3]);
#endif

/* MODULE10:  integer arithmetic */
    digitalWrite(PIN_LED0, 1);
    digitalWrite(PIN_LED1, 1);

    j = 2;
    k = 3;

    for(i = 1; i <= n10; i +=1) {
        j = j + k;
        k = j + k;
        j = k - j;
        k = k - j - j;
    }
#ifdef POUT
    pout(n10, j, k, x1, x2, x3, x4);
#endif

/* MODULE11:  standard functions */
    digitalWrite(PIN_LED2, 1);
    digitalWrite(PIN_LED3, 1);

    x = 0.75;
    for(i = 1; i <= n11; i +=1)
        x = sqrt( exp( log(x) / t1));
        // x = x / 2;
#ifdef POUT
    pout(n11, j, k, x, x, x, x);
#endif

// -----------------------------

}

void loop() {
    digitalWrite(PIN_LED0, 0);
    digitalWrite(PIN_LED1, 0);
    digitalWrite(PIN_LED2, 0);
    digitalWrite(PIN_LED3, 0);
    Serial.println(millis());
    testfloat();
}


 ITERATIONSを1000倍にして15秒だったので、1000÷15=約66.7MWIPSかな?目安程度に。

 当初、doubleとfloatの実行速度が変わらなくて「?」だったのだが、Arduino互換ということでfloatもdoubleも単精度となる。実際にdouble版とfloat版でコンパイルしてバイナリを比較したら一致した。

 LEDが4個載っているのでprintfデバッグも楽、web上でコンパイルできるため開発環境をインストールしなくて済む。フラッシュ1MB/RAM 128KBで入出力も豊富。これはたのしい。
記事検索
プロフィール

hardyboy

カテゴリ別アーカイブ
月別アーカイブ
QRコード
QRコード
  • ライブドアブログ