2010年
7月
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

セットアップ日記


2010年07月15日 今度の修理

_ 液晶ディスプレイが故障

昨年、共用のディスプレイが故障した。他にも故障しているディスプレイを集めてみると、三台あった。一台はバラしてしまって部品取り用にして、その他の二台を修理することができた。二台ともインバーター回路のトランジスタが死んでいたので、移植することによって動くようになった。先月一台が不調になったので、追加修理をした。

今日、メインに使っている液晶ディスプレイが急に動かなくなった。幸い、昨年卒業した学生が使っていたものが余っていたので、それに置き換えて仕事ができるようになった。今回壊れたのはIO-DATAのLCD-AD194VBというものである。いつ購入したか覚えていないが、おそらく三年前ぐらいだと思う。問題は、どう修理するかだ。

まず、中を開けてみて気がついたのが、前のものにくらべて、インバーター回路がすっきりとしているということだ。前回の経験を生かすことができない。見た目では電解コンデンサは大丈夫なようだし、インバーター回路のトランジスタがどこにあるのかも分からない。今度の故障箇所を特定するのは難しそうだ。


2010年07月18日 RS232Cモニター

_ AVRでRS232Cのmonitor

PS2のマウスをAVRで扱おうと計画しているが、その前段階として、RS232Cのモニターを作ってみた。具体的には、PCからRS232Cで送った数字を、液晶で表示するというものだ。PCからのデータは次のようなスクリプトでrubyから送信できる。
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 
#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(;;);
}
次は、PS2のモニターを作ろうと思うが、なかなか時間が取れないので、なかなか進まないかな。

2010年07月25日 温度の記録

_ AVR温度計

今年の夏は例年に比べて相当暑い気がする。しかし、やはり自分でそのデータを示さないことには結論を出せないだろう。というわけで、AVRで温度計を作ってみることにした。ICとしては、tiny261を使うことにした。これにはAD converterが内臓されており、さらに内臓温度計の電圧を測ることによって、温度も分かる。しかし、UARTは無いので、RS232Cでデータを送信するのは難しい。そこで、測定結果は、液晶に表示するようにした。

さて、いろいろと苦労をして、なんとか測定できるようになった。引っかかった点としては、電源の方向、reset端子になっているためにIOとしては使えないpinの位置、液晶のコントラストの調整、周波数の設定などである。液晶も普段使っている16*1が余っていないので、16*2のものを使った。

1.1Vを基準電圧として、10bitでADが行われるので、理想的な分解能は約1.1mVということになる。一方、温度センサは、1mV/1度らしい。ということは、分解能は1.1度しか無いことになってしまう。これでは使い物にならない。外部に適切な温度計をつないで、電圧を読むようにしないと。


2010年07月30日 ruby on rails

_ railsを入れてみた

rubyを使う人間としては、railsをいつか使ってみようと考えていたのだが、debianでインストールしている人の記録を見ると、面倒そうだったのでなかなか手を出していなかった。しかし、いろいろと試してみると、
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を入れれば良いのかな。

_ 2010/7/31追記

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が使えるらしい。


2010年07月31日 2日目のrails

_ railsで二つのデータ

人の名前を選べるようにしてみた。まず、
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をリストから選べるようになった。