>お楽しみコーナー>Linux>Linuxで計測 サイトマップ 最終更新日:2005/07/22

センリュウのホームページへ ようこそ!

 LINUXで計測  2 

シリアルポートと秋月電子のデーターロガー(pico ADC-16)を使用した計測プログラム
 pico ADC-16は今や秋月電子で販売されてないかもしれませんが、同様のものがあるみたいです。ADC-16は高性能のわりには1万円代で買えました。しかし、現在のものはちょっと高すぎる気がします。いずれにせよ新しいのを購入した場合でも、下のプログラムを少し書き換えるだけで使用できるのではないかと思います。以下のプログラムは、ADC-16を使って@手動と、A一定時間ごとに自動で電圧をサンプリングするというものです。

プログラムのダウンロード(pico.tar.gz)

 使用方法

ここではCOM2に接続するとします。デバイスはttyS1、ベースポートは0x2f8となります。
@pico ADC-16をONにするには、BASEP0RT=0x2f8として、BASEP0RT+4に対して、2を送信してやります。
Apico ADC-16は1バイトの信号を送ると、3バイトの電圧測定結果が返ってくるようになっています。
 たとえば 0x1f という信号を送ると、チャンネル1を16ビットの分解能で呼び出します。するとチャンネル1から「+**」などと3バイトの返事が返ってきます。
B上のpico.tar.gz をダウンロードして、解凍して下さい。
Cプログラムは、Turbolinuxで作成したものですが、Redhatでうまく作動しない場合はソースのフォントの部分(コメントアウトにしてある)を入れ替えて、 make しなおしてみて下さい。
Dpico_m が手動測定用で、F1キーを押すとサンプリングできます。F2キーは終了となります。
Epico_a が自動測定用で、プログラムが開始されたら、何回サンプリングするか、何秒おきにサンプリングするか入力して下さい。
F計測結果は双方ともdataファイルとして保存されます。

データーロガー pico ADC-16 の特性
 pico ADC-16の特性として +−2500mV でビット配分した場合、−電圧は1200mVまでならだいたいそのまま使える値となりますが、+側は実際の電圧と違ってくるようです(主要には勾配が変わってくる)。したがって、プログラム上で修正が必要となります。


0から-1200mVまで  実際の電圧(mV)=計測値(mV)のまま
0から+160mVまで  実際の電圧(mV)=計測値(mV)×92/160
+160mV以上     実際の電圧(mV)=計測値(mV)×100/160−8

実際の使用例(様々なセンサーを取り付けてみる)


●手動測定(pico_m.c)

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h> //FDclose,read,write,termios,ioperm,lseek
#include <sys/io.h> //ioperm
#include <sys/types.h> //FDopen//lseek,open
#include <sys/stat.h> //FDopen
#include <fcntl.h> //FDopen
#include <termios.h> //termios

#define BASEPORT 0x2f8

int sw;
FILE *fp;

Display *d;
Window wr, w1, w2, wb;
GC gc, gc1, gc2, gcb;
Pixmap pr, p1, p2, pb;
Font f1,f2;
unsigned long black,white;
XColor col[8][8][8];

int FD;
struct termios oldtio, newtio;

int val, valg=0, valg2;
int k=0;


int main(void)
{
pthread_t th1;
void th_func();
void draw_w1base(Display *d, Pixmap p1, Window w1,GC gc1, unsigned long c);
void sig_fnc();

char s[16];

ssize_t len;
char ch1=0x1f;
unsigned char c[3];

system("clear");

if((FD=open("/dev/ttyS1",O_RDWR))==-1){perror("open");exit(1);}
printf("open device:%d\n",FD);
tcgetattr(FD, &oldtio);
bzero(&newtio, sizeof(newtio));
newtio.c_iflag |= (IXON | IXOFF);
newtio.c_oflag = 0;
newtio.c_lflag = 0;
newtio.c_cflag |= (CS8 | CREAD | CLOCAL);
newtio.c_cc[VTIME] = 1;
newtio.c_cc[VMIN] = 0;
cfsetispeed(&newtio, B9600);
cfsetospeed(&newtio, B9600);
tcflush(FD, TCIOFLUSH);
tcsetattr(FD, TCSANOW, &newtio);

if(ioperm(BASEPORT, 8, 1)){perror("ioperm");exit(1);}
outb(2,BASEPORT+4);
printf ("port4 value: %d\n",inw(BASEPORT+4));
if(ioperm(BASEPORT, 8, 0)){perror("ioperm");exit(1);}
usleep(1500000);


if((fp=fopen("./data","w"))==NULL)
{
printf("can not open data_file!");
exit(EXIT_FAILURE);
}

signal(SIGINT,sig_fnc);

sw=0;
pthread_create(&th1, NULL, (void *)th_func, NULL);

while(!sw) usleep(1000);

draw_w1base(d,p1,w1,gc1,black);
XSetForeground(d,gc1,col[7][0][0].pixel);
while(1)
{
write(FD,&ch1,1);
usleep(1000000);
if((len=read(FD,c,3))==3)
{
val=(int)((c[1]*0x100+c[2])*2500/65536);
if(c[0]=='-'){val=-val;}
valg2=valg;
valg=(int)(val*180/2500);

if(k >= 780)
{
draw_w1base(d,p1,w1,gc1,black);
XSetForeground(d,gc1,col[7][0][0].pixel);
k=0;
}
k++;
XDrawLine(d,p1,gc1,k-1,190-valg2,k,190-valg);
XCopyArea(d,p1,w1,gc1,0,0,780,400,0,0);
sprintf(s,"%d mV",val);
XSetForeground(d,gc2,black);
XFillRectangle(d,p2,gc2,0,0,780,80);
XSetForeground(d,gc2,col[0][7][0].pixel);
XDrawString(d,p2,gc2,100,60,s,strlen(s));
XCopyArea(d,p2,w2,gc2,0,0,780,80,0,0);
XFlush(d);
}
}

tcsetattr(FD, TCSANOW, &oldtio);
close(FD);
fclose(fp);

return(0);
}

//////////////////////////////////////////////////////////////////////////////////////////////////

void sig_fnc()
{
tcsetattr(FD, TCSANOW, &oldtio);
close(FD);
fclose(fp);
exit(0);
}

//////////////////////////////////////////////////////////////////////////////////////////////////

void draw_w1base(Display *d, Pixmap p1, Window w1, GC gc1, unsigned long c)
{
XSetForeground(d,gc1,white);
XFillRectangle(d,p1,gc1,0,0,780,400);
XSetForeground(d,gc1,c);
XDrawString(d,p1,gc1,200,385,"200",3);
XDrawString(d,p1,gc1,400,385,"400",3);
XDrawString(d,p1,gc1,600,385,"600",3);
XDrawLine(d,p1,gc1,0,370,780,370);
XDrawLine(d,p1,gc1,0,190,780,190);
XDrawLine(d,p1,gc1,200,0,200,370);
XDrawLine(d,p1,gc1,400,0,400,370);
XDrawLine(d,p1,gc1,600,0,600,370);
XCopyArea(d,p1,w1,gc1,0,0,780,400,0,0);
}

////////////////////////////////////////////////////////////////////////////////////////////////

void th_func()
{
Colormap cmap;
XEvent event;
int bwidth, bheight, x_hot, y_hot;
char ch[8];
char s[16];
int l,m,n;
int i=1;
KeySym key;
struct tm *systime;
time_t t;

d=XOpenDisplay(NULL);

black=BlackPixel(d,0);
white=WhitePixel(d,0);

cmap=DefaultColormap(d,0);
for(l=0;l<8;l++)
{
for(m=0;m<8;m++)
{
for(n=0;n<8;n++)
{
col[l][m][n].red=65535-(7-l)*65535/7;
col[l][m][n].green=65535-(7-m)*65535/7;
col[l][m][n].blue=65535-(7-n)*65535/7;
XAllocColor(d,cmap,&col[l][m][n]);
}

}

wr=XCreateSimpleWindow(d,RootWindow(d,0),100,50,800,530,1,black,white);
w1=XCreateSimpleWindow(d,wr,10,10,780,400,1,black,white);
w2=XCreateSimpleWindow(d,wr,10,410,780,80,1,black,black);
wb=XCreateSimpleWindow(d,wr,700,500,50,15,3,col[7][5][5].pixel,white);

XStoreName(d,wr,"pico");

XSelectInput(d,wr,ExposureMask | KeyPressMask);
XSelectInput(d,wb,ButtonPressMask);

XMapWindow(d,wr);
XMapSubwindows(d,wr);

pr=XCreatePixmap(d,wr,800,530,DefaultDepth(d,0));
p1=XCreatePixmap(d,w1,780,400,DefaultDepth(d,0));
p2=XCreatePixmap(d,w2,780,80,DefaultDepth(d,0));
pb=XCreatePixmap(d,wb,50,15,DefaultDepth(d,0));

gc=XCreateGC(d,pr,0,0);
gc1=XCreateGC(d,p1,0,0);
gc2=XCreateGC(d,p2,0,0);
gcb=XCreateGC(d,pb,0,0);

// f1=XLoadFont(d,"variable");
// f2=XLoadFont(d,"-urw-helvetica-bold-r-normal--42-401-75-75-p-234-iso8859-1");
f1=XLoadFont(d,"-Adobe-Courier-Bold-R-Normal--11-80-100-100-M-60-ISO8859-1");
f2=XLoadFont(d,"-adobe-courier-bold-r-normal--75-721-75-75-m-450-iso8859-1");


XSetFont(d,gc,f1);
XSetFont(d,gc1,f1);
XSetFont(d,gc2,f2);

XSetForeground(d,gc,white);
XFillRectangle(d,pr,gc,0,0,800,530);
XSetForeground(d,gc,black);
XDrawString(d,pr,gc,570,513,"quit : press here =>",20);

XSetForeground(d,gcb,white);
XSetBackground(d,gcb,col[7][0][0].pixel);
XReadBitmapFile(d,wb,"./quit.bmp",&bwidth, &bheight, &pb,&x_hot, &y_hot);

// XCopyArea(d,pr,wr,gc,0,0,800,530,0,0);
// XCopyPlane(d,pb,wb,gcb,0,0,bwidth,bheight,0,0,1);

sw=1;

while(1)
{
usleep(1000);
XNextEvent(d,&event);
switch(event.type)
{
case Expose:
XCopyArea(d,pr,wr,gc,0,0,800,530,0,0);
XCopyArea(d,p1,w1,gc1,0,0,780,400,0,0);
XCopyArea(d,p2,w2,gc2,0,0,780,80,0,0);
XCopyPlane(d,pb,wb,gcb,0,0,bwidth,bheight,0,0,1);
XFlush(d);

case ButtonPress:
if(event.xbutton.window == wb)

tcsetattr(FD, TCSANOW, &oldtio);
close(FD);
fclose(fp);
exit(EXIT_FAILURE);
}

case KeyPress:
if(XLookupString((XKeyEvent *)&event,ch,8,&key,NULL) == 1);
switch(key)
{
case XK_F1:
t=time(NULL);
systime=localtime(&t);
printf("%.2d/%.2d %.2d:%.2d:%.2d %d : %.d mV\a\n", systime->tm_mon+1, systime->tm_mday, systime->tm_hour, systime->tm_min, systime->tm_sec, i, val);
fprintf(fp,"%.2d/%.2d %.2d:%.2d:%.2d %d : %.d mV\n", systime->tm_mon+1, systime->tm_mday, systime->tm_hour, systime->tm_min, systime->tm_sec, i, val);
sprintf(s,"%d",i);
XSetForeground(d,gc1,col[0][0][7].pixel);
XDrawString(d,p1,gc1,k,190-valg,s,strlen(s));
XCopyArea(d,p1,w1,gc1,0,0,780,400,0,0);
XFlush(d);
i++;
XSetForeground(d,gc1,col[7][0][0].pixel);
break;

case XK_F2:
tcsetattr(FD, TCSANOW, &oldtio);
close(FD);
fclose(fp);
exit(EXIT_FAILURE);
}
}
}
}

●自動測定(pico_a.c)

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <time.h>

#include <unistd.h> //FDclose,read,write,termios,ioperm,lseek
#include <sys/io.h> //ioperm
#include <sys/types.h> //FDopen//lseek,open
#include <sys/stat.h> //FDopen
#include <fcntl.h> //FDopen
#include <termios.h> //termios

#define BASEPORT 0x2f8

int sw;
FILE *fp;

Display *d;
Window wr, w1, w2, wb;
GC gc, gc1, gc2, gcb;
Pixmap pr, p1, p2, pb;
Font f1,f2;
unsigned long black,white;
XColor col[8][8][8];

int FD;
struct termios oldtio, newtio;


int main(void)
{
pthread_t th1;
struct tm *systime;
time_t t0, t;
void th_func();
void draw_w1base(Display *d, Pixmap p1, Window w1,GC gc1, unsigned long c);
void sig_fnc();

int sf, timer;
int i=1, k=0;
int val, valg=0, valg2;
char s[16];

ssize_t len;
char ch1=0x1f;
unsigned char c[3];

system("clear");

printf(" Sampling number =? ");
scanf("%d", &sf);
printf(" Interval time(second) =? ");
scanf("%d", &timer);

if((FD=open("/dev/ttyS1",O_RDWR))==-1){perror("open");exit(1);}
printf("open device:%d\n",FD);
tcgetattr(FD, &oldtio);
bzero(&newtio, sizeof(newtio));
newtio.c_iflag |= (IXON | IXOFF);
newtio.c_oflag = 0;
newtio.c_lflag = 0;
newtio.c_cflag |= (CS8 | CREAD | CLOCAL);
newtio.c_cc[VTIME] = 1;
newtio.c_cc[VMIN] = 0;
cfsetispeed(&newtio, B9600);
cfsetospeed(&newtio, B9600);
tcflush(FD, TCIOFLUSH);
tcsetattr(FD, TCSANOW, &newtio);

if(ioperm(BASEPORT, 8, 1)){perror("ioperm");exit(1);}
outb(2,BASEPORT+4);
printf ("port4 value: %d\n",inw(BASEPORT+4));
if(ioperm(BASEPORT, 8, 0)){perror("ioperm");exit(1);}
usleep(1500000);


if((fp=fopen("./data","w"))==NULL)
{
printf("can not open data_file!");
exit(EXIT_FAILURE);
}

signal(SIGINT,sig_fnc);

sw=0;
pthread_create(&th1, NULL, (void *)th_func, NULL);
while(!sw) usleep(1000);

t0=time(NULL);

draw_w1base(d,p1,w1,gc1,black);
XSetForeground(d,gc1,col[7][0][0].pixel);
while(i<=sf)
{
write(FD,&ch1,1);
usleep(1000000);
if((len=read(FD,c,3))==3)
{
val=(int)((c[1]*0x100+c[2])*2500/65536);
if(c[0]=='-'){val=-val;}
valg2=valg;
valg=(int)(val*180/2500);

if(k >= 780)
{
draw_w1base(d,p1,w1,gc1,black);
XSetForeground(d,gc1,col[7][0][0].pixel);
k=0;
}
k++;
XDrawLine(d,p1,gc1,k-1,190-valg2,k,190-valg);
XCopyArea(d,p1,w1,gc1,0,0,780,400,0,0);
sprintf(s,"%d mV",val);
XSetForeground(d,gc2,black);
XFillRectangle(d,p2,gc2,0,0,780,80);
XSetForeground(d,gc2,col[0][7][0].pixel);
XDrawString(d,p2,gc2,100,60,s,strlen(s));
XCopyArea(d,p2,w2,gc2,0,0,780,80,0,0);
XFlush(d);

t=time(NULL);

if(difftime(t,t0) > timer*i)
{
systime=localtime(&t);
printf("%.2d/%.2d %.2d:%.2d:%.2d %d : %.d mV\a\n", systime->tm_mon+1, systime->tm_mday, systime->tm_hour, systime->tm_min, systime->tm_sec, i, val);
fprintf(fp,"%.2d/%.2d %.2d:%.2d:%.2d %d : %.d mV\n", systime->tm_mon+1, systime->tm_mday, systime->tm_hour, systime->tm_min, systime->tm_sec, i, val);
sprintf(s,"%d",i);
XSetForeground(d,gc1,col[0][0][7].pixel);
XDrawString(d,p1,gc1,k,190-valg,s,strlen(s));
XCopyArea(d,p1,w1,gc1,0,0,780,400,0,0);
XFlush(d);
i++;
XSetForeground(d,gc1,col[7][0][0].pixel);
}
}
}

tcsetattr(FD, TCSANOW, &oldtio);
close(FD);
fclose(fp);

while(1)
{
}

return(0);
}

//////////////////////////////////////////////////////////////////////////////////////////////////

void sig_fnc()
{
tcsetattr(FD, TCSANOW, &oldtio);
close(FD);
fclose(fp);
exit(0);
}

//////////////////////////////////////////////////////////////////////////////////////////////////

void draw_w1base(Display *d, Pixmap p1, Window w1, GC gc1, unsigned long c)
{
XSetForeground(d,gc1,white);
XFillRectangle(d,p1,gc1,0,0,780,400);
XSetForeground(d,gc1,c);
XDrawString(d,p1,gc1,200,385,"200",3);
XDrawString(d,p1,gc1,400,385,"400",3);
XDrawString(d,p1,gc1,600,385,"600",3);
XDrawLine(d,p1,gc1,0,370,780,370);
XDrawLine(d,p1,gc1,0,190,780,190);
XDrawLine(d,p1,gc1,200,0,200,370);
XDrawLine(d,p1,gc1,400,0,400,370);
XDrawLine(d,p1,gc1,600,0,600,370);
XCopyArea(d,p1,w1,gc1,0,0,780,400,0,0);
}

////////////////////////////////////////////////////////////////////////////////////////////////

void th_func()
{
Colormap cmap;
XEvent event;
int bwidth, bheight, x_hot, y_hot;
char ch[8];
int i,j,k;
KeySym key;

d=XOpenDisplay(NULL);

black=BlackPixel(d,0);
white=WhitePixel(d,0);

cmap=DefaultColormap(d,0);
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
for(k=0;k<8;k++)
{
col[i][j][k].red=65535-(7-i)*65535/7;
col[i][j][k].green=65535-(7-j)*65535/7;
col[i][j][k].blue=65535-(7-k)*65535/7;
XAllocColor(d,cmap,&col[i][j][k]);
}

}

wr=XCreateSimpleWindow(d,RootWindow(d,0),100,50,800,530,1,black,white);
w1=XCreateSimpleWindow(d,wr,10,10,780,400,1,black,white);
w2=XCreateSimpleWindow(d,wr,10,410,780,80,1,black,black);
wb=XCreateSimpleWindow(d,wr,700,500,50,15,3,col[7][5][5].pixel,white);

XStoreName(d,wr,"pico");

XSelectInput(d,wr,ExposureMask | KeyPressMask);
XSelectInput(d,wb,ButtonPressMask);

XMapWindow(d,wr);
XMapSubwindows(d,wr);

pr=XCreatePixmap(d,wr,800,530,DefaultDepth(d,0));
p1=XCreatePixmap(d,w1,780,400,DefaultDepth(d,0));
p2=XCreatePixmap(d,w2,780,80,DefaultDepth(d,0));
pb=XCreatePixmap(d,wb,50,15,DefaultDepth(d,0));

gc=XCreateGC(d,pr,0,0);
gc1=XCreateGC(d,p1,0,0);
gc2=XCreateGC(d,p2,0,0);
gcb=XCreateGC(d,pb,0,0);

// f1=XLoadFont(d,"variable");
// f2=XLoadFont(d,"-urw-helvetica-bold-r-normal--42-401-75-75-p-234-iso8859-1");
f1=XLoadFont(d,"-Adobe-Courier-Bold-R-Normal--11-80-100-100-M-60-ISO8859-1");
f2=XLoadFont(d,"-adobe-courier-bold-r-normal--75-721-75-75-m-450-iso8859-1");


XSetFont(d,gc,f1);
XSetFont(d,gc1,f1);
XSetFont(d,gc2,f2);

XSetForeground(d,gc,white);
XFillRectangle(d,pr,gc,0,0,800,530);
XSetForeground(d,gc,black);
XDrawString(d,pr,gc,570,513,"quit : press here =>",20);

XSetForeground(d,gcb,white);
XSetBackground(d,gcb,col[7][0][0].pixel);
XReadBitmapFile(d,wb,"./quit.bmp",&bwidth, &bheight, &pb,&x_hot, &y_hot);

// XCopyArea(d,pr,wr,gc,0,0,800,530,0,0);
// XCopyPlane(d,pb,wb,gcb,0,0,bwidth,bheight,0,0,1);

sw=1;

while(1)
{
usleep(1000);
XNextEvent(d,&event);
switch(event.type)
{
case Expose:
XCopyArea(d,pr,wr,gc,0,0,800,530,0,0);
XCopyArea(d,p1,w1,gc1,0,0,780,400,0,0);
XCopyArea(d,p2,w2,gc2,0,0,780,80,0,0);
XCopyPlane(d,pb,wb,gcb,0,0,bwidth,bheight,0,0,1);
XFlush(d);

case ButtonPress:
if(event.xbutton.window == wb)

tcsetattr(FD, TCSANOW, &oldtio);
close(FD);
fclose(fp);
exit(EXIT_FAILURE);
}

case KeyPress:
if(XLookupString((XKeyEvent *)&event,ch,8,&key,NULL) == 1);
switch(key)
{
case XK_F1:
tcsetattr(FD, TCSANOW, &oldtio);
close(FD);
fclose(fp);
exit(EXIT_FAILURE);
case XK_F2:
tcsetattr(FD, TCSANOW, &oldtio);
close(FD);
fclose(fp);
exit(EXIT_FAILURE);
}
}
}
}