2010年06月07日 引越し完了
_ tdiaryの更新
本日、Webサーバーの更新が行われた。rubyは1.8.5になったので、新しいtdiaryにした。見た目はほとんど変えていないが。ようやく基本的な設定が終わって、昔のデータも移し終えた。ユーザー権限では、apacheが作成したデータを書き換えられないので、細かい設定がうまくいかずに苦労した。新しいプラグインも使えると思うので、何か面白いものがないか探してみようと思う。少しずつスタイルを調整していこう。
2010年06月09日 引数の最後のカンマ
_ methodの引数と配列
rubyの引数を取るmethodでは、引数をカンマで区切って、丸括弧で囲む。def test(*a) puts a.class endなどとすると、引数の数が可変になり、それが配列として受け取ることができる。このような場合に、引数を一行ごとに書いて、
test( 1, 2, 3, )などとしたくなるのだが、これだと最後のカンマの後に引数が無いのでエラーが起きてしまう。仕方がないので、これまでは
test( 1, 2, 3 )と書いていたが、多少不便な点があった。例えば、2を除く時には行ごとコメントアウトすれば良いのだが、3を除くときには、少し書き換えなければいけない。これを回避する方法を見つけた。
test(*[ 1, 2, 3, ])と書くと、3を消すときも、一行コメントアウトすれば良いことになる。配列だと、最後のカンマは無視してくれることを利用している。しかし、引数を配列にしてから、もう一度展開するのは二度手間な気がする。そうするならば、初めから配列を引数にすれば良いのだが、必ず配列を渡すのも面倒な時もある。しばらくはこの書き方でいくことにしよう。
2010年06月12日 impressiveでプレゼン
_ netbookで
これまで、プレゼンテーションが必要なときには、prosperで準備して、pdfに変換してacroreadで表示していた。知人がimpressiveというプレゼンテーションツールを使っていて、興味を持ったので試してみた。インストールはaptitude impressiveでできるが、日本語が表示できない。poppler-dataを入れると、表示できるようになる。しかし、非力なPCの場合には変換に時間がかかってしまう。ubuntuのレシピで工夫の仕方が紹介されていた。まず、impressive --geometry 1024x768 -o presen presen.pdfとすると、presenというフォルダに各ページがpngとして展開される。そして、実行するときには、
impressive -t none -c memory -g 1024x768 presenとすると、変換に時間がかからなくなるので、快適に使うことができるようになる。しばらく使ってみることにしようかな。
2010年06月13日 液晶の修理
_ また壊れた
久々に秋葉に行って、部品を買ってきた。以前修理した液晶のディスプレイを修理するために、トランジスタを買ってきた。以前と同様に、2SC5707が壊れたので、その代わりに2SC3709Aを買って、入れ替えると、一応うまくバックライトが点灯した。しかし、直ったと思って組み立て終わって、もう一度チェックすると、また同じ症状になってしまった。一度取り替えた2SC5707がもう一度壊れているので、その原因が別にあるのだろう。トランジスタを取り替えると、しばらくはうまくいくが、また壊れる。今回もそれを再現したのだと思う。その原因を見つけないと、根本的な修理にはならないのだが、どうやってみつけようか。部品取り用の基板もあるので、あやしい部品を総とっかえしてみようかな。
_ 2010/6/15追記
昨晩、もう一度動かしてみたら、普通にバックライトが点灯した。おかしいな、また壊れたはずなのに。どこかに浮いた半田でもあるのかな。もうしばらく様子を見ることにしよう。
2010年06月16日 二年越し
_ AVRでデジットの液晶
二年以上前に、日本橋のデジットで買った規格の分からない液晶を動かすことに成功した。と言っても、私が解析したわけではなく、先人の解析を元にプログラムを書いただけである。液晶は裏にIN50175Hという刻印のあるもので、買った当時検索したが、何も分からなかった。最近検索すると、解析結果が分かったので、動かしてみた。 14セグメントの文字が8文字と9個の記号が表示できる。信号は三本で、各セグメントのon/offをクロックに合わせて送って、その後で表示を指示する。難しいのは、セグメントの順番が、一つの文字で連続していないことだ。いろいろと試行錯誤の結果できあがったattiny2313をつかって表示させるプログラムがこれ。#include <avr/io.h> #include <avr/interrupt.h> #define F_CPU 1000000 /* 1MHz */ #include <util/delay.h> #include <avr/pgmspace.h> /* lcd controller for IN50175H */ // PORTB #define LATCH 3 #define DATA 4 #define CLOCK 5 // 1 Vcc // 2 NCC? // 3 NCC? // 4 latch // 5 data // 6 clock // 7 GND #define setbit(PORT,BIT) PORT|=_BV(BIT) #define clearbit(PORT,BIT) PORT&=~_BV(BIT) #define checkbit(PORT,BIT) (PORT&_BV(BIT)) static volatile unsigned char buf[20]; //static char segsign[14]={1,1,1,1,0,0,0,1,1,1,1,0,0,0}; /* 1:+,:-*/ static unsigned char offset[14]={1,2,3,4,72,71,70,81,82,83,84,152,151,150}; //static unsigned char chars[9]={36,78,79,80,116,117,118,119,120}; unsigned char seg(char c,char s){ /*c:0-7, s:0-13*/ // return c*4*((segsign[s]==0)?-1:+1)+offset[s]; return c*4*((s%7<4)?+1:-1)+offset[s]; } const prog_uint16_t number[0x60]={ // edcba987654321 0b000000000000000, // 0x20 0b000100010000000, //! 0x21 0b000100000100000, //" 0x22 0b001101110101001, //# 0x23 0b001111100101001, //$ 0x24 0b000110001011111, //% 0x25 0b001011001010110, //& 0x26 0b000000001000000, //' 0x27 0b000000001000100, //( 0x28 0b000000000010010, //) 0x29 0b000000101111111, //* 0x2a 0b000000100101001, //+ 0x2b 0b000000000000010, //, 0x2c 0b000000000001001, //- 0x2d 0b000000100000000, //. 0x2e 0b000000001000010, /// 0x2f // edcba987654321 0b011111011000010, //0 0x30 0b010010000000000, //1 0x31 0b011001010001001, //2 0x32 0b011011000001000, //3 0x33 0b010110000001001, //4 0x34 0b001101000000101, //5 0x35 0b001111010001001, //6 0x36 0b011010000000000, //7 0x37 0b011111010001001, //8 0x38 0b011111000001001, //9 0x38 0b000000100100000, //: 0x3a 0b000000000100010, //; 0x3b 0b000000001000101, //< 0x3c 0b000001000001001, //= 0x3d 0b000000000011010, //> 0x3e 0b011000100001000, //? 0x3f // edcba987654321 0b011101010101000, //@ 0x40 0b011110010001001, //A 0x41 0b011011100101000, //B 0x42 0b001101010000000, //C 0x43 0b011011100100000, //D 0x44 0b001101010001001, //E 0x45 0b001100010000001, //F 0x46 0b001111010001000, //G 0x47 0b010110010001001, //H 0x48 0b001001100100000, //I 0x49 0b010011010000000, //J 0x4a 0b000100011000101, //K 0x4b 0b000101010000000, //L 0x4c 0b010110011010000, //M 0x4d 0b010110010010100, //N 0x4e 0b011111010000000, //0 0x4f // edcba987654321 0b011100010001001, //P 0x50 0b011111010000100, //Q 0x51 0b011100010001101, //R 0x52 0b001111000001001, //S 0x53 0b001000100100000, //T 0x54 0b010111010000000, //U 0x55 0b000100011000010, //V 0x56 0b010110010000110, //W 0x57 0b000000001010110, //X 0x58 0b000000101010000, //Y 0x59 0b001001001000010, //Z 0x5a 0b001001000010010, //[ 0x5b 0b000000000010100, //\ 0x5c 0b001001001000100, //] 0x5d 0b000000000000110, //^ 0x5e 0b000001000000000, //_ 0x5f // edcba987654321 0b000000000010000, //` 0x60 0b011110010001001, //A 0x41 0b011011100101000, //B 0x42 0b001101010000000, //C 0x43 0b011011100100000, //D 0x44 0b001101010001001, //E 0x45 0b001100010000001, //F 0x46 0b001111010001000, //G 0x47 0b010110010001001, //H 0x48 0b001001100100000, //I 0x49 0b010011010000000, //J 0x4a 0b000100011000101, //K 0x4b 0b000101010000000, //L 0x4c 0b010110011010000, //M 0x4d 0b010110010010100, //N 0x4e 0b011111010000000, //0 0x4f // edcba987654321 0b011100010001001, //P 0x50 0b011111010000100, //Q 0x51 0b011100010001101, //R 0x52 0b001111000001001, //S 0x53 0b001000100100000, //T 0x54 0b010111010000000, //U 0x55 0b000100011000010, //V 0x56 0b010110010000110, //W 0x57 0b000000001010110, //X 0x58 0b000000101010000, //Y 0x59 0b001001001000010, //Z 0x5a 0b000000100100001, //{ 0x7b 0b000000100100000, //| 0x7c 0b000000100101000, //} 0x7d 0b010000010001001, //~ 0x7e 0b000000000000000 // 0x7f }; void buf_clear(){ unsigned char i; for(i=0;i<20;i++){buf[i]=0x00;} } void buf_display(){ unsigned char i; clearbit(PORTB,LATCH); _delay_us(1); for(i=0;i<161;i++){ if( buf[i>>3]&(1<<(i&7)) ){ setbit(PORTB,DATA); }else{ clearbit(PORTB,DATA); } _delay_us(1); setbit(PORTB,CLOCK); _delay_us(1); clearbit(PORTB,CLOCK); _delay_us(1); } setbit(PORTB,LATCH); _delay_us(1); } void buf_set(char n,unsigned char c){ unsigned char i,s; unsigned int p; for(s=0;s<14;s++){ i=seg(n,s); // p=number[c]; p=pgm_read_word(&number[c-0x20]); if(p&(1<苦労したのは、文字のフォントを打ち込むところと、そのデータをflashに置くためのコードの書き方です。初めは、constにしてもRAMに確保されて、RAM不足になってしまったが、flashにおくには、特殊な書き方が必要のようだ。 動く様子を他の人に見せていたら、14セグメントあると、漢字も表示できるのではないかということになった。微妙なものもあるけれど、そのときに思いついた漢字がこれらです。>3]|=1<<(i&7); }else{ buf[i>>3]&=~(1<<(i&7)); } } } int main(){ unsigned char i,j; PORTB=0; DDRB=0x038; /* write 456 */ _delay_ms(1000); buf_clear(); buf_display(); j=0x20; for(;;){ for(i=0;i<8;i++){buf_set(i,j);if(++j>0x80){j=0x20;}} buf_display(); _delay_ms(2000); } }
大天 田因困 凶 区 円内 小川上工 山 一二三 十 干土 木王 玉平 米他にもいろいろあるだろうけど、214通り考えるのは大変なので、このくらいにしておこう。
2010年06月21日 AVRのconst
_ AVRの定数をflashに置く
以前、flashにconstを作るときには、よく分からずにやっていたが、やり方が分かったので、書いておこう。まず、宣言のところでは、型の後に"PROGMEM"を入れるか、"prog_"が頭についた、flash専用の型で宣言する。以前のプログラムでは、const prog_uint16_t number[0x60];としていた。次に、定数の値を読むときには、pgm_read_byte, pgm_read_word,pgm_read_dwordを使う。
p=pgm_read_word(&number[c-0x20]);などと、アドレスを引数にする必要がある。宣言はさておき、読み取るときの命令が面倒だと感じる。今後、定数を使うときには、flashを有効利用するようにしよう。
2010年06月23日 busyが読めないが
_ AVRで液晶表示
数年前からやろうと思って時間が無くてできなかったが、液晶の表示に成功した。AVRでプログラムを組んでいると、バグがあっても状態を出力する手段がほとんど無いので、バグを発見するのに非常に苦労する。液晶で状態を表示できるようになれば、非常に快適になると思っている。
今回使ったのは、秋月で300円で売っていた16文字の液晶モジュールで、HD44780準拠の標準的なものだ。ライブラリを書いている人もたくさんいるので、これを使っても良いのだが、それでは面白くないので、自分で適当に書いてみた。8bit通信と4bit通信ができるのだが、pinを節約するために、4bit通信を選択する。それでも制御信号が3pin必要なので、7pinも費やしてしまうことになる。tiny2313の通常使える17pinから7pin使うと、残りは10pinになってしまう。
いくつかトラブったことろはあるが、一応の表示には成功した。まず、文字コードを書き込むだけでは表示が消えてしまい、その後で表示オンの指示を出さないといけなかった。マニュアルにはそんな記述は見当たらない気がするんだけどな。あと、busyの読み込みにはなぜか失敗してしまうので、適当なwaitの後で次のコマンドを送るようにした。
面倒なのは、16文字のアドレスが連続していないことだ。他の液晶との互換性のためだろうが、少し処理を書き加えないといけない。
バックライトはないけど、別に見にくいわけではないし、一応の表示ができるようになったので良しとしよう。
2010年06月27日 PS2の勉強
_ PS2モニタ
液晶の表示に成功したので、これを何かに生かしたい。AVRでいくつかやってみたいことはあるのだが、とりあえずは、PS2のモニタを作ろうと思う。
PS2のマウスのプロトコルは昔勉強したことがあるのだが、復習していると新たな発見がいくつかあった。スクロールボタンや5ボタンの扱い方を知らなかったが、これはモードを切り替えると良いらしい。さらに深く理解するために、PCとマウスとの間で、実際にどのようなデータがどのような頻度でやりとりされているのかを観察できるようにPS2モニタがあれば、便利である。
PCからのデータもマウスからのデータも同じdataとclockのラインを使って送られる。PCやマウス自身は、自分が送っていない信号は相手から出たものだと分かるが、第三者から見ると、どちらから出た信号なのかが分かりにくい。さらに、PCからの信号に関しては、マウスは受け取ったという返事をするので、第三者から見て1bit多くなる。途中でデータ転送を中段した場合なども考え出すとどんどん難しくなる。
クロックがlowになったときにdataを見て、highならばPCからのデータで11クロック、lowならばマウスからのデータで12クロック分読み込むようにすれば、途中で中段されない限り、データのやりとりを見ることができるだろう。気をつけないといけないのは、PCからのデータはクロックの立ち上がりで読んで、マウスからのデータは立ち下がりで読むということだ。
これを実現するには、クロックで割り込みをかけると良いだろう。以前はint0を使ったが、今後の拡張も考えるとpcintを使いたい。そうすれば、原理的には同時にいくつものPCやマウスと通信できるはずだ。
さて、大体の構想はまとまったのだが、これを実際に試すのはいつになるのだろう。