実践Linux                 TOPへ  Cプログラミング目次へ

計測プログラミング  2011年7月

@秋月電子のデーターロガー(pico ADC-16)とUSB-シリアル変換器を使用したPC計測 →こちらへ
Aトランジスタ技術増刊「今すぐ使えるパソコン計測USBマイコン基板」に付属のTRZ1102モジュールを使用したPC計測


トランジスタ技術増刊「今すぐ使えるパソコン計測USBマイコン基板」に付属のTRZ1102モジュールを使用した計測プログラム

TRZ1102モジュールには、USBマイコンPIC18F14K50と 24bitA-DコンバータAD7793が搭載されており、USBケーブルでPC接続することで、高性能のPC計測ができます。ただ、この書籍にはWindows用のソフトしか準備されていません。しかし、このモジュールはUSBの標準的な CDC (Communication Device Class) として実装されているので、 Linuxでは接続するだけで自動的に serial 接続のデバイスとして認識してくれます。

 ←トランジスタ技術増刊「今すぐ使えるパソコン計測USBマイコン基板」に付属のTRZ1102モジュール


接続確認
モジュールを接続すると、/dev/ttyACM0が生成される。(システム→管理→ハードウェア(下方)→USB(下方)→USB-ADC AD7793 CQ Board→USB Communications Interface→Serial Port→詳細 /dev/ttyACM0)
このデバイスにはroot:uucpにrwの権限が与えられている。
# dmesg | grep tty  確認。
# stty -F /dev/ttyACM0 -a でデバイスの設定がわかる。

# lsusb  USBデバイスの情報を確認する。
Bus 002 Device 002: ID 04d8:0fba Microchip Technology. Inc. 等と表示される。
lsusbは/proc/bus/usb/devicesから情報を読み込んでいる。# cat /proc/bus/usb/devices
lsusb -vは、詳細表示。
lsusb -tは、USB階層をツリー形式で表示する。


プログラムについて
1、シリアル・ポートの設定にはtermiosを使う。
2、open、write、readなどを使ってやりとりをする。

AD7793操作コマンド(詳しくは、附属のDVD解説pdfを参照。)
 「Ctrl-X=16進で18h」: ADCインターフェースをリセット
 「C08000A」: 「C」はコミュニケーション・レジスタへの書き込み。08でモード・レジスタ(これが10だと設定レジスタ)を選択。000Aで変換レートを16.7Hzに設定。
 「R」: 「R」は変換データ読み出し。「R」だけだと1回読み出し。(「RA」だとA=10回読み出し。)


●汎用Makefile
プログラムソースをtest.cで保存して、Makefileを以下の内容で準備し、makeを実行する。
字下げはTabキーで行うこと。

INCLUDE = /usr/X11R6/include/X11
LIB = /usr/X11R6/lib
CC = gcc
CFLAGS = -lX11 -lpthread
TARGETS = test
OBJ = ${SRC:.c=.o}
SRC = test.c

$(TARGETS):${OBJ}
  ${CC} -I ${INCLUDE} -L ${LIB} ${CFLAGS} ${OBJ} -o ${TARGETS}

${OBJ}:${SRC}
  ${CC} ${SRC} -c -o ${OBJ}

clean:
  rm -f *.o $(TARGETS)


●簡単な計測プログラム
Ctrl+Cキーで計測中止。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h> //lseek,close,read,write,termios
#include <sys/types.h> //lseek,open
#include <sys/stat.h> //open
#include <fcntl.h> //open
#include <termios.h> //termios
#include <signal.h>

int FD;
struct termios oldtio, newtio;

int main()
{
ssize_t len;
void sig_fnc();
int portstatus;
unsigned char c[6];
char buff[8];
int val;

if((FD=open(“/dev/ttyACM0”,O_RDWR))==-1){perror(“open”);exit(1);}
printf(“open device:%d\n”,FD);

tcgetattr(FD, &oldtio);

bzero(&newtio, sizeof(newtio));
newtio.c_cflag |= (CS8 | CREAD | CLOCAL);
newtio.c_iflag |= IGNCR;
newtio.c_oflag = 0;
newtio.c_lflag = 0;
// newtio.c_cc[VTIME] = 0;
// newtio.c_cc[VMIN] = 0;

cfsetispeed(&newtio, B38400);
cfsetospeed(&newtio, B38400);
tcflush(FD, TCIOFLUSH);
tcsetattr(FD, TCSANOW, &newtio);

usleep(1000000);
signal(SIGINT,sig_fnc);
write(FD,”\x18\n”,2); //ADCインターフェース・リセット
write(FD,”C08000A\n”,8); //ADCモード・レジスタ書き込み(変換レートを16.7Hzに設定)
//write(FD,”C101086\n”,8); //内蔵温度センサーを選ぶときの設定
usleep(500000);
tcflush(FD, TCIOFLUSH);
while(1){
write(FD,”R\n”,2); //変換データ1回読み出し要求
usleep(500000);
if((len=read(FD,c,6))>0)
{
strcpy(buff, “0x”);
strcat(buff, c); //800000を0x800000のように書き換える

val=(strtol(buff, NULL, 16)-8388608)/8388*1.17;
//val=strtol(buff, NULL, 16)/16777*1.17; //内蔵温度センサー用

printf(“value=%d mv\n”,val);
}
tcflush(FD, TCIOFLUSH);
}
tcsetattr(FD, TCSANOW, &oldtio);

close(FD);
printf(“close device and end\n”);
exit(0);
}

void sig_fnc()
{
tcsetattr(FD, TCSANOW, &oldtio);

close(FD);
printf(“close device and end\n”);
exit(0);
}

TOPへ  Cプログラミング目次へ