2011年8月30日火曜日

プログラマが知るべき97のこと #06

プログラマが知るべき97のこと #06の一部を記載します

/* *** */

#06 ラジット・アタパトゥー(Rajith Attapattu)

すべてをゼロから書き直したい衝動に駆られることもありますが、その誘惑に打ち克たなかればなりません。既存のコードをできる限り活かすべきです。いかに醜悪なコードであっても、そのコードはテストやレビューを通っているものなのです。既存のコード――特に、すでにリリースされたシステムのコード――をすべて破棄するというのは、それまでの何ヶ月(何年)という時間を捨ててしまうということを意味します。大変な作業を経て、曲がりなりにも形にしてきたコードです。その過程では無数に発生した問題の回避策を講じ、数えきれないほどのバグ修正もしてきたでしょう、仮にコードを新たにゼロから書き直したとすると、同じようなことをまた繰り返すことになりますし、既存のコードでは発見/修正してきたバグを、今度は見逃してしまうかもしれません。これでは時間と労力の無駄だし、過去の作業で得た知識も無駄になってしまいます。

/* *** */

一節だけ引用させて頂きましたが
他にも参考になることがたくさん書かれています
アマゾンアソシエイトですがリンクを貼っておきます



またGoogle書籍検索では 日本語ではありませんが プレビューが出来ます
英語が出来る人は少し読んでみても面白いかもしれません

97 Things Every Programmer Should Know: Collective Wisdom from the Experts

2011年8月29日月曜日

挿すそして祈れ

よくある洒落ですね
PnP(Plug and Play)は挿したら実行するみたいな意味ですけど
Play を
Pray にして
挿したら祈れ みたいな意味になるように

前置きが長くなりましたが
FT232RLで遊んでいます
というかUSB<=>TTLRS232のコンバータのTXがなぜか動作しなくなって
急遽秋月で買いました
0.65mmピッチです
大して難しくなかったです

んでPCで色々設定いじりながら
USBのケーブルが切れそうだったので
木工ボンドで止めてみたんですよね
そしたら認識してくれなくなりました

水が45%のものを使ったのでたぶん水の電気抵抗で必要な電位差が稼げなかったとかだと思うんですけど
どっかに木工ボンドの抵抗値のデータとか無いんですかね?w

2011年8月25日木曜日

ちなみに

今年の缶サット甲子園はmbedが使われています
本大会がどうなったかは知らないけど
北海道地方大会では外付けのカメラを使っていた

でもmbedでネットワークカメラ(mbedのIPアドレスにWebブラウザからアクセスするとmbedに接続されたカメラカラの画像が見れる)を作ってる人もいるし
USBホストで市販のWebカメラも接続できそう
処理速度的にはたぶん問題ないはず
画像はSDカードに保存するとか

さすがに高校生に放課後とかに作らせるのはムチャぶりかもしれないけど
誰かやってくれないかな?

mbedでLチカ

#include "mbed.h"

DigitalOut myled[4] = { LED1, LED2, LED3, LED4 };

int main() {
    while(1) {
        for (int i = 0; i < 16; i++) {
            myled[0] = ((i >> 0) & 1);
            myled[1] = ((i >> 1) & 1);
            myled[2] = ((i >> 2) & 1);
            myled[3] = ((i >> 3) & 1);
            wait_ms(500);
        }
    }
}

とりあえずメモ
mbedに搭載されているLED4個で2進4bitカウンタを表示します

mbedのポートの配列を作ってそこに出力
今回は配列にした意味が無いけど forをもう一回使って
myledの代入4行の代わりに
for (int c = 0; c < 4; c++) { myled[c] = ((i >> c) & 1); }
とかでも動くかもしれない(試してはいない)

mbedはPICとかと違ってあまり動作速度を意識しなくてもいいのが利点かな

そういえばmain()の戻り値が組み込みによくあるvoidじゃなくてintになってるけど
これは何なんだろう? ブートローダーから起動してるからとかなのかな

2011年8月19日金曜日

C語高速化のコツ

ちょっと気になったのでメモ

たとえば
byte data[8,8];
っていうのがあったとして そこにデータを入れたい場合 一番手っ取り早いのは


char x, y;
for (x = 0; x < 8; x++) {
for (y = 0; y < 8; y++) {
data[x, y] = ((関数の引数[x] >> y) ? 1 : 0);
}
}

みたいなかんじのコードが楽
だけど PICの場合かなり高コストになっちゃう
ということで 実行速度をなるべく早くしたいなら


char x;
for (x = 0; x < 8; x++) {
data[x, 0] = ((関数の引数[x] >> 0) ? 1 : 0);
data[x, 1] = ((関数の引数[x] >> 1) ? 1 : 0);
data[x, 2] = ((関数の引数[x] >> 2) ? 1 : 0);
data[x, 3] = ((関数の引数[x] >> 3) ? 1 : 0);
data[x, 4] = ((関数の引数[x] >> 4) ? 1 : 0);
data[x, 5] = ((関数の引数[x] >> 5) ? 1 : 0);
data[x, 6] = ((関数の引数[x] >> 6) ? 1 : 0);
data[x, 7] = ((関数の引数[x] >> 7) ? 1 : 0);
}

とかのほうが 早くなると思う

まぁ場合によって多少違うだろうけど
forをネストすると実効速度がどんどん遅くなる っていう感じらしい

"ループ文同士での入れ子はループ文を多用するために、プログラミングのミスによるバグの一つである無限ループが発生しやすくなる。"
ということらしいので
やっぱなるべくネストはしないほうがいいらしい

16F88でLチカ

/* ** */

#include <htc.h>

__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_ON & MCLRE_OFF & BOREN_OFF & LVP_OFF & DEBUG_OFF);

#define _XTAL_FREQ 20000000

#define LED RB4

void main(void) {
TRISA =   0b000000;
TRISB = 0b00000000;
ANSEL = 0;
PORTA = 0;
PORTB = 0;

while(1) {
LED = !LED;
__delay_s(1);
}
}
/* ** */
はい
↓のポストのコードを実際に使うためのコード

このコードでは外部20MHzクロックで
RB4に接続したLEDを点滅させる

だけ

【メモ】HI-TECHでウエイト処理

htc.hをインクルードして
#define _XTAL_FREQ 20000000
をコードに追加
20000000はクロック この場合20MHzね
そしてコードで
__delay_ms(10);
ってやったら10mS待ってくれる
__delay_us
ならマイクロ秒で

そしてついでだから
pic.hに
#define __delay_s(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4.0)))
を追加してみた
これだと秒単位でウエイトができる
20MHzだとして最大で800秒分ちょっと
たぶんusでもmsでもsでもおなじはず


あとWin6.x(Vistaとか7)の場合普通はUACでpic.hを書き換えはできない はず
とりあえず自分はVisualC++を使ってるから 右クリックから 管理者として実行 で起動しておいた

とりあえず
メモ

2011年8月18日木曜日

【メモ】PIC16F88でUSART(受信割り込み)

/* *** */

#include <htc.h>

__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_ON & MCLRE_OFF & BOREN_OFF & LVP_OFF & DEBUG_OFF);

static void interrupt intr(void) {
if (RCIF) {
char t;
RCIF = 0;
TXREG = 'R';
t = RCREG;
RB4 = (t == '0' ? 0 : 1);
}
}

void main(void) {
TRISA = 0b000000;
TRISB = 0b00000100;
ANSEL = 0;
PORTA = 0;
PORTB = 0;

RCIE = 1;
PEIE = 1;
GIE = 1;

TXSTA = 0x20;
RCSTA = 0x90;
SPBRG = 32;

TXREG = 'S';

while(1) {
}
}
/* *** */

とりあえず動作確認だけだから無駄なコードとかあるかも
ハードUSARTなので回路図は省略
とりあえずTXとRXを間違えずに接続してください
あとRB4にLEDを1kΩくらいの抵抗を介してGNDに接続すると
数字の0(アスキーコード49だったかな?)で消灯
それ以外で点灯します
シリアル受信割り込みで処理してるから他の命令を実行中でも動作すると思う

とりあえずメモ程度なので変なバグあっても怒らないでorz
(バグ見っけたらコメント等で教えていただけると)

追記:動作クロックは20MHzです

(includeのあとが表示されない問題を修正 HTMLタグと間違われてたらしい バックスラッシュとかで"<"とかを無効化できたはずなんだけどどうやるんだっけ… 2011/08/19)

2011年8月6日土曜日

.NetMicroFrameworkで2進数文字列を整数に

C#(.NetFull)だと
int num2 = Convert.ToInt32("1111101000", 2);
みたいにやるところだけど

.NetMicroFrameworkでは Convert.ToInt32が使えないみたい
ということで↓の方法を試してみた

        public static int ToInt(string input)
        {
            int i = 0;
            for (int c = 0; c < input.Length; c++) { i = (i << 1) + (input[c] == '0' ? 0 : 1); }
            return i;
        }

ビットシフトを使っただけ
だけど一応動作する
int i = ToInt("1100");
みたいなかんじで使えばおk
整数を2進数文字列にすることも簡単かも
応用して16進とかも
ただ16進になると三項演算子が使えないからちょっとめんどくさいかも

今は2進数だけだったからこれだけで

機会があったら他の進数も試してみます