ロボットを創ろう
/* モータ制御実験 A/Dデータ収集用 プログラム JK5.C
                  1994.9.20. A.Satoh Lab.
           By (Master_1) H.Wani */

#include <stdio.h>
#include <dos.h>
#include <graphics.h>
#include <conio.h>
#include <stdlib.h>
#include <pc98.h>
#include "\fads.h"

typedef struct{
int channel;
int color;
int *data;
int mode;
} ADdata_type;

/* prototype */
/* main */

void jikan();
void setch();
void soku();
void graph();
int ADsave();
int ADload();
void table();
void prg_end();

void cls_txtgraph();
int init_BGI();
void set_section();
ADdata_type *memtodata();
void datatomem();


/* variable */

int data,dataflag,alltime=20;
int chnum=2,dtnum=500;
char BUF[50];
ADdata_type *AD;

/* general use */

void cls_txtgraph()
{
clrscr();
cleardevice();
}

/* init BGI */

int init_BGI(int mode)
{
int gd=PC98,gm=PC98C8;

if(registerbgidriver(PC98_driver) < 0) return 0;
if(mode == 16) gm=PC98C16;
initgraph(&gd,&gm,"");
if(gd<0) return 0;
return 1;
}

/* menu */

void main()
{
init_BGI(8);

if ((AD = memtodata(chnum,dtnum)) == NULL) exit(1);

while(1)
{
cls_txtgraph();
textcolor(3);
gotoxy(28, 5); cprintf(" サーボ実験データ収集 ");
gotoxy(28, 6); printf(" MENU ");
gotoxy(28, 8); printf(" 1.測定時間 ");
gotoxy(28, 9); printf(" 2.チャンネル ");
gotoxy(28,10); cprintf(" 3.測定 ");
gotoxy(28,11); printf(" 4.データ確認 ");
gotoxy(28,12); printf(" 5.グラフ表示 ");
textcolor(2);
gotoxy(28,13); cprintf(" 6.データセーブ ");
gotoxy(28,14); cprintf(" 7.データロード ");
textcolor(4);
gotoxy(28,16); cprintf(" ESC.終了 ");
gotoxy(28,19); printf("番号を入力してください");

switch(getch())
{
case '1':jikan(); break;
case '2':setch(); break;
case '3':soku(); break;
case '4':table(); break;
case '5':graph(); break;
case '6':ADsave(); break;
case '7':ADload(); break;
case 0x1b:prg_end(); break;
}
}
}

void prg_end()
{
datatomem(AD);
cls_txtgraph();
closegraph();
exit(0);
}

/* jikan */

void jikan()
{
int i;

cls_txtgraph();
gotoxy(20, 8); printf("現在の測定時間 %5d sec",alltime);
gotoxy(20,12); printf("測定時間の入力(sec) = ");
gets(BUF);
if (BUF[0] == NULL) return;
i = atoi(BUF);
if (i >= 5 && i <= 1000) { alltime = i; return; }
gotoxy(15,16); printf("時間の範囲は 5 ≦ time ≦ 1000");
getch();
}

/* set channel */

void setch()
{
int i;

cls_txtgraph();
gotoxy(15,5); printf("チャンネルの個数 = %3d\n\n",chnum);
for(i=0;i<chnum;i++)
{
textcolor(AD[i].color);
cprintf(" Data %2d channel %2d color %2d\r\n",
i,AD[i].channel,AD[i].color);
}
printf("\n\n チャンネル数の変更 > ");
gets(BUF);
if(BUF[0] == NULL) return;
i=atoi(BUF);
if(i < 1 || i>16) { printf("\n 範囲外です");
getch();
return; }

datatomem(AD,chnum);
chnum=i;
AD=memtodata(chnum,dtnum);
for(i=0;i<chnum;i++)
{
printf("\n Data %2d channel = ",i);
gets(BUF); AD[i].channel=atoi(BUF);
printf(" color = ");
gets(BUF); AD[i].color=atoi(BUF);
}
return;
}

/* sokutei */

void soku()
{
int i,j,x1=99,x2=100,y1,y2;
int data[20],channel[20];
int adr[1]={0xdc};

for(i=0;i<chnum;i++) channel[i]=AD[i].channel;
set_ADchannel(data,channel,chnum);
set_ADadr(adr);
alltime = set_ADtimer(alltime,dtnum);

set_section(0);

textcolor(4);
gotoxy(34,25); cprintf("Hit any key to start!");
getch();
textcolor(3);
gotoxy(34,25); cprintf(" Hit q key to stop. ");
gotoxy(1,1);

AD_start(100);
if(get_AD() > 0) { printf("ERROR"); }
for(j=0;j<chnum;j++) AD[j].data[0] = data[j];

for(i=1;i<dtnum;i++)
{
if(get_AD() > 0) { printf("ERROR"); }
x1++;
x2++;
for(j=0;j<chnum;j++)
{
AD[j].data[i] = data[j];

y1=(5608-AD[j].data[i-1]) >> 4;
y2=(5608-data[j]) >> 4;
setcolor(AD[j].color);
line(x1,y1,x2,y2);
}
if((char)pc98key(5)=='q') break;
}
AD_stop();
setcolor(15);
textcolor(6);
gotoxy(34,25); cprintf("Hit any key to return.");
getch();
}

/* graph */

void graph()
{
int i,j,x1=99,x2=100,y1,y2;

set_section(0);
for(i=1;i<dtnum;i++)
{
x1++;
x2++;
for(j=0;j<chnum;j++)
{
y1=350-((AD[j].data[i-1]+8) >> 4);
y2=350-((AD[j].data[i]+8) >> 4);
setcolor(AD[j].color);
line(x1,y1,x2,y2);
}
}
setcolor(15);
textcolor(6);
gotoxy(34,25); cprintf("Hit any key to return.");
i = getch();
gotoxy(34,25); printf(" ");
}

/* data save */

int ADsave()
{
FILE *file;
int i,j;

cls_txtgraph();
gotoxy(15,10); printf("input save file name -> ");
gets(BUF);
if ((file=fopen(BUF,"r")) != NULL)
{
fclose(file);
printf("\n\n over write ? (y/n)");
while((i=getch())!='y' && (i!='n'));
if (i=='n') return(0);
}
if ((file=fopen(BUF,"w")) == NULL)
{
printf("\n\n Error writing output file");
getch();
return(0);
}
fprintf(file," %5d, %5d, %5d,\n",alltime,chnum,dtnum);
fprintf(file," %5d,",0);
for(i=0;i<chnum;i++) fprintf(file," %5d,",AD[i].channel); fprintf(file,"\n");
fprintf(file," %5d,",0);
for(i=0;i<chnum;i++) fprintf(file," %5d,",AD[i].color); fprintf(file,"\n");
for(j=0;j<dtnum;j++)
{
fprintf(file," %5d,",j);
for(i=0;i<chnum;i++) fprintf(file," %5d,",AD[i].data[j]);
fprintf(file,"\n");
}
fclose(file);
return(1);
}

/* data load */

int ADload()
{
FILE *file;
int i,j,k;

cls_txtgraph();
gotoxy(15,10);
printf("input load file name -> ");
gets(BUF);
if ((file=fopen(BUF,"r")) == NULL)
{
printf("\n\n Could not find file \"%s\"",BUF);
getch();
return 0;
}

datatomem(AD,chnum);

fscanf(file," %5d, %5d, %5d,",&alltime,&chnum,&dtnum);
AD=memtodata(chnum,dtnum);
fscanf(file," %5d,",&k);
for(i=0;i<chnum;i++) fscanf(file," %5d,",&AD[i].channel);
fscanf(file," %5d,",&k);
for(i=0;i<chnum;i++) fscanf(file," %5d,",&AD[i].color);
for(j=0;j<dtnum;j++)
{
fscanf(file," %5d,",&k);
for(i=0;i<chnum;i++) fscanf(file," %5d,",&AD[i].data[j]);
}
fclose(file);
return 1;
}

/* table */

void table()
{
int i,j,n,top=0;

cls_txtgraph();
gotoxy(10,1); printf("サーボ実験データ 測定時間 = %4d sec",alltime);
gotoxy(4,3); printf("No. Data1 Data2 No. Data1 Data2 No. Data1 Data2 No. Data1 Data2");
setcolor(10);
setlinestyle(SOLID_LINE,0,THICK_WIDTH);
for(i= 12;i<621;i+=152) line (i,31,i,368);
line(12,31,620,31); line(12,47,620,47); line(12,368,620,368);
setlinestyle(SOLID_LINE,0,NORM_WIDTH);
for(i=0;i<457;i+=152) {line (52+i,31,52+i,368); line(108+i,31,108+i,368);}
setcolor(15);
gotoxy(2,25); printf(" ↑:前ページ ↓:次ページ m:表示切換(Real/Volt) q:終了 ");

while(1)
{
for(i=0;i<20;i++)
{
gotoxy(3,4+i);
for(j=0;j<80;j+=20)
{
n = top+i+j;
if(n < dtnum)
{
printf("%4d ",n);
if(AD[0].mode == 0) printf("%5d %5d ",AD[0].data[n],AD[1].data[n]);
else printf("%5.2f %5.2f ",(AD[0].data[n])/409.6/2,(AD[1].data[n])/409.6/2);
}
}
}
switch(getch())
{
case 11:top=(top < 80)?top:top-80; break;
case 10:top=((top+80) > dtnum)?top:top+80; break;
case 'm':AD[0].mode = !AD[0].mode; break;
case 'q':return;
}
window(3,4,76,23); clrscr(); window(1,1,80,25);
}
}

/* memory */

ADdata_type * memtodata(int chnum,int dtnum)
{
ADdata_type *ADdata;
int i,j;

if ((ADdata = (ADdata_type *)calloc(chnum,sizeof(ADdata_type))) == NULL)
{
printf("\n\n memory over");
printf("\n\n Hit any key.");
getch();
return NULL;
}

for(i=0;i<chnum;i++)
{
if ((ADdata[i].data = (int *)calloc(dtnum,sizeof(int))) == NULL)
{
for(j=0;j<i;j++) free(ADdata[i].data);
datatomem(ADdata,i-1);
printf("\n\n memory over %d",i);
printf("\n\n Hit any key.");
getch();
return NULL;
}

ADdata[i].channel = (i*8) % 16;
ADdata[i].color = (1+i) % 8;
ADdata[i].mode = 0;
}
return ADdata;
}

void datatomem(ADdata_type *ADdata,int chnum)
{
int i;

for(i=0;i<chnum;i++) free(ADdata[i].data);
free(ADdata);
}

/* set section */

void set_section(int oy)
{
int i,dec,sign;
char *str;

cls_txtgraph();
setlinestyle(SOLID_LINE,0,THICK_WIDTH);
for(i=0;i<11;i+=10) { line(99+i*50,93,99+i*50,351);
line(100,94+25.6*i,600,94+25.6*i);}
setlinestyle(SOLID_LINE,0,NORM_WIDTH);
for(i=1;i<10;i++) { line(99+i*50,95,99+i*50,350);
line(100,94+25.6*i,600,94+25.6*i);}
settextjustify(CENTER_TEXT,CENTER_TEXT);
settextstyle(DEFAULT_FONT,VERT_DIR,1);
outtextxy( 70,222,"Voltage [Volt]");
for(i=0;i<11;i+=2) outtextxy(90,350-25.6*i,itoa(oy+i/2,BUF,10));
settextstyle(DEFAULT_FONT,HORIZ_DIR,1);
outtextxy(350,374,"T i m e [sec]");
for(i=0;i<11;i++)
{
str = fcvt((double)alltime/10*i,3,&dec,&sign);
str[dec+1]=str[dec]; str[dec]='.'; str[dec+2]=0;
outtextxy(100+i*50,358,str);
}
}

//==============================
// ステップ応答のサンプル
//==============================

#include "mmss.h"

void main()
{
float moku; // 目標値
float pot; // ポテンショメータの電圧
float motor_v; // コンピュータからモータへの電圧
// (実際はこの電圧の約3倍の電圧がモータにかかる)

Init_ss(); // いろいろな前処理

while (1) {
Wait_ss(); // ウェイト

pot = GetVolt(); // ポテンショメータの電圧読み取り(モータの現在位置取得)

moku = 2.5; // 目標値一定
// ポテンショメータが2.5[V]を出力する場所を目標値とする

motor_v = moku - pot; // 計算

OutputVolt(motor_v); // 電圧出力(モータへの出力電圧変更)

Draw(moku, pot); // グラフに点を描画する
}
}
//==============================
// サイン波入力のサンプル
//==============================

#include "mmss.h"

void main()
{
float moku; // 目標値
float pot; // ポテンショメータの電圧
float motor_v; // コンピュータからモータへの電圧
// (実際はこの電圧の約3倍の電圧がモータにかかる)
float now_time = 0; // 現在の時間、単位は秒


Init_ss(); // いろいろな前処理

while (1) {
Wait_ss(); // ウェイト

pot = GetVolt(); // ポテンショメータの電圧読み取り(モータの現在位置取得)

moku = 2.5 * sin(2 * M_PI / 10 * now_time); // サイン波の計算

motor_v = moku - pot; // 計算

OutputVolt(motor_v); // 電圧出力(モータへの出力電圧変更)

Draw(moku, pot); // グラフに点を描画する

now_time = now_time + 0.04; // 時間を進める
}
}


このページで紹介している写真は無断で転載することを禁止します。ただし、記事を模倣してロボットを創ることは大歓迎です。