|
setup diary |
昨年、共用のディスプレイが故障した。他にも故障しているディスプレイを集めてみると、三台あった。一台はバラしてしまって部品取り用にして、その他の二台を修理することができた。二台ともインバーター回路のトランジスタが死んでいたので、移植することによって動くようになった。先月一台が不調になったので、追加修理をした。
今日、メインに使っている液晶ディスプレイが急に動かなくなった。幸い、昨年卒業した学生が使っていたものが余っていたので、それに置き換えて仕事ができるようになった。今回壊れたのはIO-DATAのLCD-AD194VBというものである。いつ購入したか覚えていないが、おそらく三年前ぐらいだと思う。問題は、どう修理するかだ。
まず、中を開けてみて気がついたのが、前のものにくらべて、インバーター回路がすっきりとしているということだ。前回の経験を生かすことができない。見た目では電解コンデンサは大丈夫なようだし、インバーター回路のトランジスタがどこにあるのかも分からない。今度の故障箇所を特定するのは難しそうだ。
s=open("/dev/ttyS0","r+") system("stty raw -echo -crtscts 9600 cs8 -parenb cstopb </dev/ttyS0") # 9600bps 8bit, 2 stop bit, no parity loop{ i=rand(256) puts '%02x'%i s.write(i.chr) s.flush sleep 1 }この信号をMAX232でTTLレベルに変換して、それをtiny2313のUSARTの機能を使って受信する。あとは液晶表示ルーチンを利用して表示するだけだ。あまりきれいではないけれど、そのソースはこんな感じ。
#include次は、PS2のモニターを作ろうと思うが、なかなか時間が取れないので、なかなか進まないかな。#include #define F_CPU 1000000 /* 1MHz */ #include #define BAUD 9600 /* 9600bps */ #define SET_BAUD F_CPU/8/BAUD-1 // U2X=1 #define setbit(PORT,BIT) PORT|=_BV(BIT) #define clearbit(PORT,BIT) PORT&=~_BV(BIT) #define checkbit(PORT,BIT) (PORT&_BV(BIT)) // LCD #define LCD_PORT PORTD #define LCD_DDR DDRD #define LCD_MASK 0x3c // data PD 2-5 #define LCD_RS 1 //PA #define LCD_RS_PORT PORTA //PA #define LCD_RS_DDR DDRA //PA #define LCD_RW 0 //PA #define LCD_RW_PORT PORTA //PA #define LCD_RW_DDR DDRA //PA #define LCD_EN 6 //PD #define LCD_EN_PORT PORTD //PD #define LCD_EN_DDR DDRD //PD static volatile unsigned char lcd_buf[16]="123456789012345"; void lcd_send(unsigned char c){ // c=((c&0x0f)<<4)|((c&0xf0)>>4); //reverse // c=((c&0x33)<<2)|((c&0xcc)>>2); //reverse // c=((c&0x55)<<1)|((c&0xaa)>>1); //reverse c>>=2; c&=LCD_MASK; setbit(LCD_EN_PORT,LCD_EN); LCD_PORT=(LCD_PORT&~LCD_MASK)|c; clearbit(LCD_EN_PORT,LCD_EN); _delay_us(1); } void lcd_command8(unsigned char c){ clearbit(LCD_RS_PORT,LCD_RS); clearbit(LCD_RW_PORT,LCD_RW); lcd_send(c); _delay_us(100); } void lcd_command(unsigned char c){ //while(busy_address()&0x80){_delay_us(1);} clearbit(LCD_RS_PORT,LCD_RS); clearbit(LCD_RW_PORT,LCD_RW); lcd_send(c); lcd_send(c<<4); _delay_us(100); } void lcd_write(unsigned char c){ setbit(LCD_RS_PORT,LCD_RS); clearbit(LCD_RW_PORT,LCD_RW); lcd_send(c); lcd_send(c<<4); } void lcd_display(){ unsigned char i,j; i=0; for(j=0;j<0x48;j++){ if(j==0x08){j=0x40;} lcd_command(0x80+j); // DDRAM lcd_write(lcd_buf[i++]); } lcd_command(0x0f); // display } void lcd_shift(unsigned char s){ unsigned char n; for(n=0;n<15;n++){ lcd_buf[n]=lcd_buf[n+1]; } lcd_buf[15]=s; lcd_display(); } void lcd_init(){ _delay_ms(15); LCD_PORT=0; setbit(LCD_RS_DDR,LCD_RS); setbit(LCD_RW_DDR,LCD_RW); setbit(LCD_EN_DDR,LCD_EN); // LCD_DDR=0x0f|_BV(LCD_RS)|_BV(LCD_RW)|_BV(LCD_EN) ; LCD_DDR|=LCD_MASK; _delay_ms(15); lcd_command8(0x30); _delay_us(4000); lcd_command8(0x30); lcd_command8(0x30); lcd_command8(0x20); // 4bit lcd_command(0x2c); // 4bit //command(0x07); // mode,shift lcd_command(0x06); // mode,no shift lcd_command(0x01); // clear lcd_command(0x02); // home lcd_command(0x0f); // display } void disp_num(unsigned char c){ unsigned char i; // lcd_shift(0x20); i=c>>4; lcd_shift(i+((i<10)?0x30:0x37)); i=c&0x0f; lcd_shift(i+((i<10)?0x30:0x37)); } /* rs232c */ void init_rs232c(){ UBRRH=0; UBRRL=SET_BAUD; _delay_ms(5); setbit(UCSRA,U2X); /* double speed */ setbit(UCSRB,RXEN); /* RXCIE,TXCIE,UDRIE,RXEN,TXEN */ setbit(UCSRB,RXCIE); /* RXCIE,TXCIE,UDRIE,RXEN,TXEN */ setbit(UCSRC,USBS); /* 2 stop bits */ setbit(UCSRC,UCSZ0); /* 8bit*/ setbit(UCSRC,UCSZ1); /* 8bit*/ clearbit(UCSRB,UCSZ2); /* 8bit*/ } char receive_data(){ while(checkbit(UCSRA,RXC)==0){} /* received */ return UDR; } ISR(USART_RX_vect){ /* recieved */ char c; c=receive_data(); disp_num(c); } int main() { unsigned char i,j; _delay_ms(9000); init_rs232c(); lcd_init(); sei(); for(;;); }
今年の夏は例年に比べて相当暑い気がする。しかし、やはり自分でそのデータを示さないことには結論を出せないだろう。というわけで、AVRで温度計を作ってみることにした。ICとしては、tiny261を使うことにした。これにはAD converterが内臓されており、さらに内臓温度計の電圧を測ることによって、温度も分かる。しかし、UARTは無いので、RS232Cでデータを送信するのは難しい。そこで、測定結果は、液晶に表示するようにした。
さて、いろいろと苦労をして、なんとか測定できるようになった。引っかかった点としては、電源の方向、reset端子になっているためにIOとしては使えないpinの位置、液晶のコントラストの調整、周波数の設定などである。液晶も普段使っている16*1が余っていないので、16*2のものを使った。
1.1Vを基準電圧として、10bitでADが行われるので、理想的な分解能は約1.1mVということになる。一方、温度センサは、1mV/1度らしい。ということは、分解能は1.1度しか無いことになってしまう。これでは使い物にならない。外部に適切な温度計をつないで、電圧を読むようにしないと。
aptitude install railsで、ほとんどのパッケージが入るようだ。データベースはsqliteがデフォルトのようだ。railsはまだ全く理解していないのだが、試しにテストをしてみた。
rails memo cd memo ruby script/generate scaffold memo date:date title:string body:text check:boolean rake db:migrate ruby script/serverとすると、http://localhost:3000/memosに簡単なメモのwebアプリができた。なんとなくrailsの一部を感じることができた気がする。今はwebrickでwebサーバーを動かしているが、apach+SCGIで動かすのが良いらしい。SCGIはlibapache2-mod-scgiを入れれば良いのかな。
script/generateで指定できるのは、controller, integration_test, mailer, migration, model, observer, plugin, resource, scaffold, session_migrationがあるようですが、それぞれが何をするものなのかまだ理解していません。
ちなみに、scaffoldで指定するデータの型としては、
:primary_key, :integer, :float, :string, :text, :datetime, :timestamp, :date, :time, :boolean, :binaryが使えるらしい。
rails use cd use ruby script/generate scaffold member name:string affiliation:string rake db:migrate ruby script/generate scaffold use from:time to:time member_id:integer rake db:migrateとして、人のデータベースと、時間のデータベースを作る。そして、app/models/use.rbにbelongs_to :memberと追記して、 app/views/uses/index.html.erbとshow.html.erbのuse.member_idをuse.member.nameに変える。そして、app/views/uses/new.html.erbとedit.html.erbのf.text_field :member_idを
select("use","member_id",Member.find(:all).collect{|i| [i.name,i.id]})に変更する。これで、member_idをリストから選べるようになった。