カテゴリ
リンク

当サイトは、玄箱PRO (KURO-BOX/Pro)を中心とした組み込み、Linuxと電子工作を扱っています。
会社案内

情報セキュリティおよび個人情報の取り扱いについて


コメントとトラックバックは、spamを予防するために、編集担当が公開の作業をするまで非公開になっています。コメントはそれぞれ投稿した人のものです。

プログラム
 まずは、プログラム単体で測定値を標準出力に表示するプログラムを作る必要があります。作成したプログラムを以下に示します。
 ソース・リスト中には、コマンドとして送信するコードが埋め込まれています。1-Wire システムでも、一つだけのデバイスをつなぐのであれば、これだけでかまわないようです。これらのコマンドについては、データシートと見比べてみてください。

 簡単に受信フォーマット部分だけを説明しますと、「温度データ受信指示」部分がマニュアルでいうところの、READ MEMORY SEQUENCE に相当しており、ここで 14 バイト受信される中の 8 バイト分(Read 8 Bytes Data)が DS18S20 側の MEMORY MAP のコピー(中継して送られてくる)であり、その冒頭2バイトが温度データ部です。
 これは、全体としてのデータ列としては、4 と 5 バイト目ですので、それを狙って拾い出し数値化しています。 なお、デフォルトでは 9600BPS での転送レートに設定されています。
/* DALLAS  DS18(S)20 と DS9097U-09 を使った温度計測
 * 0-85°(マイナス側未計算)
 * 2007-12-28 (k-wada)
 */

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <sys time.h=""> 
#include <sys fcntl.h=""> 
#include <sys termios.h=""> 
#include <sys ioctl.h=""> 

#define SIO   "/dev/ttyUSB0"
#define BAUD  9600

int FD232c;
char buff[32];
struct termios qtermios;

// Pullup     39
// Reset      c1
// Skip rom   cc
// Date mode  e1
// Convert    44
// Read mem   f0
// Data read  ff
// Temp read  be
// Arm Pullup ef
// Term pulse f1
char conv0[] = {9, 0x39, 0xc1, 0xe1, 0xcc, 0xe3, 0xef, 0xf1, 0xe1, 0x44};
char conv1[] = {5, 0xef, 0xe3, 0xed, 0xf1, 0xc1};
char get0[] = {15, 0xc1, 0xe1, 0xcc, 0xbe,
	      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	      0xe3, 0xc1};
char vb[] = {0x00};
char *q = vb;

trans(char *p)
{
  char byte;
  byte = *p++;
  while(byte--) {
    usleep(5000);
    write(FD232c, p++, 1);
  }
}

dammyread()
{
  char c;
  while(c = read(FD232c, buff, 1)) {
       ;
  }
}

dataread()
{
  char c, data;
  float deg;
  for(c = 0; c < 14; c++) {
    read(FD232c, &data, 1);
    switch(c) {
    case 4:
      deg = data;
      break;
    case 5:
      deg += 256 * data;
      break;
    }
  }
  deg *= 0.5 ;
    fprintf(stdout, "%2.0f\n0\nTEMP\n-\n", deg);
}

int main()
{
  int r, c, loop;
  if((r = open232c(SIO)) > 0) {
    fprintf(stderr, "Can't Open.\n");
    exit (1);
  }
  loop = 1;
  while (loop--) {
    trans(conv0);        /* 変換開始シーケンス */
    sleep(1);            /* 変換時間待機       */
    trans(conv1);        /* 変換終了シーケンス */
    dammyread();         /* 不要な受信をクリア */
    trans(get0);         /* 温度データ受信指示 */
    dataread();          /* 温度データ取得     */
    return 0;
  }
  close(FD232c);
}


int open232c(char* ttyname)
{
  struct termios  tty;
  int             r;
  int modemline;
  
  if((FD232c = open(ttyname, O_RDWR|O_NDELAY|O_NONBLOCK, 0477)) >= 0) {
    qtermios.c_iflag = IXOFF;
    qtermios.c_lflag = (PENDIN|ECHOKE|ECHOE);
    qtermios.c_cflag = (CLOCAL|HUPCL|CREAD|CS8);
    qtermios.c_ispeed = BAUD;
    qtermios.c_ospeed = BAUD;
    ioctl(FD232c, TIOCMGET, &modemline);
    modemline = TIOCM_DTR | TIOCM_RTS;
    ioctl(FD232c, TIOCMSET, &modemline);
    tcsetattr (FD232c, TCSANOW, &qtermios);
    return 0;
  }
  perror("Can't open SIO.\n");
  return 1; 
}
マニュアルより温度データ部分のバイナリ値を引用してみますと、このようになっています。
 
測定温度範囲 温度デジタル出力(バイナリ) 16進表示
+85.0 ℃ 0000 0000 1010 1010 00AAh
+25.0 ℃ 0000 0000 0011 0010 0032h
+0.5 ℃ 0000 0000 0000 0001 0001h
0 ℃ 0000 0000 0000 0000 0000h
-0.5 ℃ 1111 1111 1111 1111 FFFFh
-25.0 ℃ 1111 1111 1100 1110 FFCEh
-55.0 ℃ 1111 1111 1001 0010 FF92h

 "通過"してくるDS18S20の目盛データ(8バイト)の始めの2バイトが温度部分ですが、下図のように対応しています。

バイト 内容 (85 ℃の場合)
byte 0 温度データ LSB (AAh)
byte 1 温度データ MSB (00h)
以下省略 ..............

 プログラム群はここにありますのでダウンロードしてください。Makefile が含まれているので、make してください。  ds18s20 を実行されれば、温度が読み取れるはずです。現在、通信上のエラーチェック(CRC)も省略してありますが、
 

の 182 ページからはその詳細がありましたので勉強になりました。
 このプログラムではシリアル通信によってデバイスにコマンドを送り、返ってきた値を分析して温度を数値化していますが、後述する温度グラフ作成用に若干のおまけ文字列が付いています。
 
温度を計ってみる
 コンパイル後、生成されたコマンド(ここではds18s20)を入力して温度が表示されれば OK です。ところで、こんな感じにキーボードからコマンドを入力して、画面の温度表示を読むのであれば、直接に温度計を眺めたほうが手っ取り早いですよね。せっかく、玄箱(pro)を利用しているのですから、当然、これらを記録してグラフ表示する流れになります。そのための資料もインターネットで拾い集めるこ とができました。
 具体的には、次回の「MRTG編」のところで実際の内容を説明しますが、思わぬ落し穴が待っていました。
<和田 好司>

 カテゴリ 

 

トラックバック(0)

このブログ記事を参照しているブログ一覧: シリアル・インターフェースを利用して温度を観測する(その2)

このブログ記事に対するトラックバックURL: http://www.eleki-jack.com/mt/mt-tb.cgi/1241

コメントする

おすすめ書籍
Powered by
Movable Type 4.1