アタッチメントの自動判別
CdS | 100xxx |
マイク | xxx000 |
IR | x10xxx |
「アタッチメントが何かを判定する」プログラム |
---|
// ファイル名 getOption.c
// アタッチメントが何かを判定する。
// 緑: ライントレース
// 白: CdS
// 消灯: マイク
#include <htc.h>
__CONFIG(PWRTEN&HS&WDTDIS&UNPROTECT&MCLRDIS&BORDIS&IESODIS&FCMDIS);
#define _XTAL_FREQ 20000000
#define PERIOD 100
#define false 0
#define true 1
#define AN4 0x91
#define AN5 0x95
#define AN6 0x99
#define AN7 0x9d
#define AN10 0xa9
#define AN11 0xad
#define ABS(x) ((x>=0) ? (x) : -(x))
typedef unsigned char byte;
void LED(byte n, byte times);
void Delay50();
void Delay100();
void initialize();
byte getOption();
void getAD(byte channel, byte* flag);
// グローバル変数の宣言
byte counter=0;
byte LeftCdS, CenterCdS, RightCdS,ExRCdS;
byte threshold[4];
byte ADch=0;
byte ConvEndFlag;
byte ADC[4]={AN4,AN5,AN6,AN11};
byte Leftspeed=208;
byte Centerspeed=208;
byte Rightspeed=208;
// 割り込み処理ルーチン
int ADvalue;
void interrupt Intr(void)
{
// 約2ms毎に割り込む
if(T0IF) { // 割り込みがtimer0からか?
counter++;
TMR0 = PERIOD;
T0IF = 0; // 割り込みフラグクリア
return;
}
if(ADIF) { // 割り込みがADコンバーターからか?
ADvalue = ADRESH;
ADvalue = ADvalue*256 + ADRESL;
if(ADch==0) LeftCdS = ADvalue;
else if(ADch==1) CenterCdS = ADvalue;
else if(ADch==2) RightCdS = ADvalue;
else if(ADch==3) ExRCdS = ADvalue;
ConvEndFlag=true; // データの更新あり
ADIF = 0; // 割り込みフラグクリア
}
}
main()
{
#define SLOW 35
#define LOW 40
#define MIDDLE 80
#define MIDDLE2 120
#define HIGH 160
int i;
byte state=0;
initialize();
while(true) {
state = getOption();
LED(state, 2);
for(i=0; i<10; i++) Delay100();
}
}
void initialize()
{
PORTA = 0; // PORTAを0にする
TRISA = 0; // PORTAを出力に設定する
TRISB = 0x30; // 4,5input
PORTB = 0;
PORTC = 0; // PORTCを0にする
TRISC = 0x0f; // PORTC下4bit入力、上4bit出力
ANSEL = 0xF0; // AN4,5,6,7 ON
ANSELH = 0x0C; // AN10,11 ON
ADCON0 = AN4; // ADFM=1(右詰) AN4 adOn
// 1 = Right justified
OPTION = 0;
// 1:8 prescale
T1CON = 0x31; // Timer1 settings
TMR1IF = 0; // clear TMR1IF
TMR1H = 0xf8; // Initialize Timer1 register
TMR1L = 0x00;
ADC[0]=AN4;
ADC[1]=AN5;
ADC[2]=AN6;
ADC[3]=AN11;
}
void LED(byte n, byte times)
{
byte i;
for(i=0; i<times; i++) {
PORTA = n;
Delay50(); // 50msディレイ
PORTA = 0;
Delay50(); // 50msディレイ
}
}
void Delay50() // 50m秒ディレイ
{
int i;
for(i=0; i<5; i++)
__delay_ms(10);
}
void Delay100() // 100m秒ディレイ
{
int i;
for(i=0; i<10; i++)
__delay_ms(10);
}
#define optTH 100
byte getOption()
{
byte flag;
byte x;
getAD(AN4,&flag);
getAD(AN5, &x);
if(x) flag|=2;
getAD(AN6, &x);
if(x) flag|=4;
getAD(AN7, &x);
if(x) flag|=8;
getAD(AN10, &x);
if(x) flag|=0x10;
getAD(AN11, &x);
if(x) flag|=0x20;
return flag;
}
void getAD(byte channel, byte* flag)
{
int x;
ADCON0 = channel;
GODONE = 1;
while(GODONE);
x = ADRESH;
x = x*256+ADRESL;
*flag = x > optTH;
}
|
void getAD(byte channel, byte* flag)
| 指定されたADコンバータの値を読み取り、それが0なのか1なのかをflagとして戻す。 |
byte getOption()
| ADコンバータから下位bitからAN4, AN5, AN6, AN7, AN10,AN11 の順番で0か1を判定して、bit列を作り、その値をflagとして戻します。 |
以下のプログラムをコピーして、貼り付けて使用してください。
「外部センサオプション番号を判別してライントレースとマイクを実行する」プログラム |
---|
// ファイル名 gtLineTrace.c
// 外部センサオプション番号を判別してライントレースとマイクを実行する。// 明るさ設定は電源投入時直後に白レベルを読み取る。
#include <htc.h>
__CONFIG(PWRTEN&HS&WDTDIS&UNPROTECT&MCLRDIS&BORDIS&IESODIS&FCMDIS);
#define _XTAL_FREQ 20000000
#define PERIOD 100
#define false 0
#define true 1
#define AN4 0x91
#define AN5 0x95
#define AN6 0x99
#define AN7 0x9d
#define AN10 0xa9
#define AN11 0xad
#define ABS(x) ((x>=0) ? (x) : -(x))
typedef unsigned char byte;
void LED(byte n, byte times);
void Delay50();
void Delay100();
void initialize();
void setIRThreshold(byte th);
byte checkIR();
void LineTrace();
byte getOption();
void getAD(byte channel, byte* flag);
void Mic();
void setInterrupt();
// グローバル変数の宣言
byte counter=0;
byte LeftCdS, CenterCdS, RightCdS,ExRCdS;
byte threshold[4];
byte ADch=0;
byte ConvEndFlag;
byte ADC[4]={AN4,AN5,AN6,AN11};
byte Leftspeed=208;
byte Centerspeed=208;
byte Rightspeed=208;
// 割り込み処理ルーチン
void interrupt Intr(void)
{
// 約2ms毎に割り込む
if(T0IF) { // 割り込みがtimer0からか?
counter++;
TMR0 = PERIOD;
T0IF = 0; // 割り込みフラグクリア
return;
}
if(ADIF) { // 割り込みがADコンバーターからか?
if(ADch==0) LeftCdS = ADRESL;
else if(ADch==1) CenterCdS = ADRESL;
else if(ADch==2) RightCdS = ADRESL;
else if(ADch==3) ExRCdS = ADRESL;
ConvEndFlag=true; // データの更新あり
ADIF = 0; // 割り込みフラグクリア
}
}
main()
{
#define SLOW 35
#define LOW 40
#define MIDDLE 80
#define MIDDLE2 120
#define HIGH 160
int i;
byte state=0;
byte extOption; // 外部センサオプション番号
initialize();
extOption = getOption();
if((extOption & 0x18)==0x10) { // photo refrector
setIRThreshold(13); // ライントレース
state=2;
LED(state, 5);
}
else if((extOption & 0x07)==0) { // マイクモード
state=7;
LED(state,5);
}
setInterrupt(); // タイマーとADの割り込み設定
while(true) {
switch(state) {
case 2: LineTrace(); break;
case 7: Mic(); break;
}
}
}
void setInterrupt()
{
// Timer0 の設定
T0IE=1; // Timer0 の割り込みON
T0IF=0; // 割り込みフラグクリア
// ADコンバーターの設定
ADIE = 1; // ADコンバータの割り込み許可
ADIF = 0; // 割り込みフラグクリア
PEIE = 1; // 周辺装置の割り込み許可
GIE = 1; // CPUへの割り込み許可
}
void initialize()
{
PORTA = 0; // PORTAを0にする
TRISA = 0; // PORTAを出力に設定する
TRISB = 0x30; // 4,5input
PORTB = 0;
PORTC = 0; // PORTCを0にする
TRISC = 0x0f; // PORTC下4bit入力、上4bit出力
ANSEL = 0xF0; // AN4,5,6,7 ON
ANSELH = 0x0C; // AN10,11 ON
ADCON0 = AN4; // ADFM=1(右詰) AN4 adOn
// 1 = Right justified
OPTION = 0;
// 1:8 prescale
T1CON = 0x31; // Timer1 settings
TMR1IF = 0; // clear TMR1IF
TMR1H = 0xf8; // Initialize Timer1 register
TMR1L = 0x00;
ADC[0]=AN4;
ADC[1]=AN5;
ADC[2]=AN6;
ADC[3]=AN11;
}
void LineTrace()
{
while(RA3)
{
switch(checkIR()){
case 3: Rightspeed=Leftspeed=MIDDLE2; // 直進 青
RC5=0; RC7=0;
break;
case 7:
case 6: Rightspeed = 100; Leftspeed = MIDDLE; //左に行く 紫
RC5=0; RC7=0;
break;
case 4: Rightspeed = MIDDLE; Leftspeed = ~SLOW; //左に行く 赤
RC5=0; RC7=1;
break;
case 11:
case 9: Rightspeed = MIDDLE; Leftspeed = 100; // 水色
RC5=0; RC7=0;
break;
case 8: Rightspeed = ~SLOW; Leftspeed = MIDDLE; // 緑
RC5=1; RC7=0;
break;
} // switch
RC4 = (counter<Rightspeed)?1:0;
RC6 = (counter<Leftspeed)?1:0;
} // while
}
void LED(byte n, byte times)
{
byte i;
for(i=0; i<times; i++) {
PORTA = n;
Delay50(); // 50msディレイ
PORTA = 0;
Delay50(); // 50msディレイ
}
}
void Delay50() // 50m秒ディレイ
{
int i;
for(i=0; i<5; i++)
__delay_ms(10);
}
void Delay100() // 100m秒ディレイ
{
int i;
for(i=0; i<10; i++)
__delay_ms(10);
}
void setIRThreshold(byte th)
{
byte i, j, x;
int average[4]={0,0,0,0};
GIE=0;
// 明るいときの値 明るいと大きい値
ADC[0]=AN4;
ADC[1]=AN5;
ADC[2]=AN6;
ADC[3]=AN11;
for(j=0; j<40; j++) {
for(i=0; i<4; i++) {
ADCON0 = ADC[i];
GODONE = 1;
while(GODONE);
x = ADRESL;
average[i] = (average[i]*9+x)/10;
}
}
for(i=0; i<4; i++)
threshold[i]=average[i]*th/20;
GIE=1;
}
byte checkIR()
{
byte status;
if(ConvEndFlag) { // AD変換が終わったらすぐに次のチャンネルの変換を行う
ConvEndFlag = false;
if(++ADch==4) ADch=0;
ADCON0 = ADC[ADch]; // 変換スタート
GODONE = 1;
}
PORTA=0;
status = 0;
RA2 = ExRCdS<threshold[3];
RA1 = CenterCdS<threshold[1];
RA0 = LeftCdS<threshold[0];
status = RightCdS<threshold[2];
status += RA1 ? 2 : 0;
status += RA0 ? 4 : 0;
status += RA2 ? 8 : 0;
return status;
}
#define optTH 100
byte getOption()
{
byte flag;
byte x;
getAD(AN4,&flag);
getAD(AN5, &x);
if(x) flag|=2;
getAD(AN6, &x);
if(x) flag|=4;
getAD(AN7, &x);
if(x) flag|=8;
getAD(AN10, &x);
if(x) flag|=0x10;
getAD(AN11, &x);
if(x) flag|=0x20;
return flag;
}
void getAD(byte channel, byte* flag)
{
int x;
ADCON0 = channel;
GODONE = 1;
while(GODONE);
x = ADRESH;
x = x*256+ADRESL;
*flag = x > optTH;
}
#define MICTH 4
#define MIDLOW 80
void Mic()
{
byte i;
int average[3]={0,0,0};
int average2[3]={0,0,0};
int x,y,diff[3];
byte a,b,c,max;
unsigned int cnt=0;
GIE=0;
ADC[0]=AN7;
ADC[1]=AN10;
ADC[2]=AN11;
for(cnt=0; cnt<1000; cnt++) {
for(i=0; i<3; i++) {
ADCON0 = ADC[i];
GODONE = 1;
while(GODONE);
x = ADRESL;
average[i] = (average[i]*9+x)/10;
if(x > average[i])
average2[i] = (average2[i]*11+x)/12;
}
}
// 半永久ループ
while(RA3){ // スイッチが押されたら抜ける
for(i=0; i<3; i++) {
ADCON0 = ADC[i];
GODONE = 1;
while(GODONE);
x = ADRESL;
average[i] = (average[i]*9+x)/10;
if(x > average[i])
average2[i] = (average2[i]*11+x)/12;
diff[i] = average2[i] - average[i];
}
if((diff[0] >MICTH) || (diff[1]>MICTH) ||
(diff[2]>MICTH)) {
a=diff[0]; b=diff[1]; c=diff[2];
if(a>b) {
if(a>c) { max=0; }
else { max=2;}
}
else if(b>c) { max = 1; }
else { max=2; }
GIE=1;
x=500; // 回転カウント
switch(max){
case 2: // Left
PORTA = 4;
Rightspeed = ~MIDLOW; Leftspeed = MIDLOW;
RC5=1; RC7=0;
break;
case 1: // backward
PORTA = 2;
if(diff[1]&1){ // たまに逆回りする
Rightspeed = ~MIDLOW; Leftspeed = MIDLOW;
RC5=1; RC7=0;
}
else {
Rightspeed = MIDLOW; Leftspeed = ~MIDLOW;
RC5=0; RC7=1;
}
x = 700;
break;
case 0: // Right
PORTA = 1;
Rightspeed = MIDLOW; Leftspeed = ~MIDLOW;
RC5=0; RC7=1;
break;
default:
PORTC &= 0x0f;
}
counter=0;
cnt=0;
while(cnt!=x) {
if(counter==0) cnt++;
RC4 = (counter<Rightspeed)?1:0;
RC6 = (counter<Leftspeed)?1:0;
if(!RA3) return;
}
PORTC &= 0x0f;
PORTA = 0;
GIE=0;
Delay100();
for(cnt=0; cnt<500; cnt++) {
for(i=0; i<3; i++) {
ADCON0 = ADC[i];
GODONE = 1;
while(GODONE);
x = ADRESL;
average[i] = (average[i]*9+x)/10;
}
}
for(i=0; i<3; i++) average2[i] = average[i];
} //if
}
GIE=1;
}
|
CdSのアタッチメントも判別できるか追加してみます。
以下のプログラムをコピーして、貼り付けてください。
「手かざし動作を追加」プログラム |
---|
// ファイル名 gtLineTrace2.c
// 外部センサオプション番号を判別してライントレースとマイク、手かざし動作を実行する。
// 明るさ設定は電源投入時直後に白レベルを読み取る。
#include <htc.h>
__CONFIG(PWRTEN&HS&WDTDIS&UNPROTECT&MCLRDIS&BORDIS&IESODIS&FCMDIS);
#define _XTAL_FREQ 20000000
#define PERIOD 100
#define false 0
#define true 1
#define AN4 0x91
#define AN5 0x95
#define AN6 0x99
#define AN7 0x9d
#define AN10 0xa9
#define AN11 0xad
#define ABS(x) ((x>=0) ? (x) : -(x))
typedef unsigned char byte;
void LED(byte n, byte times);
void Delay50();
void Delay100();
void initialize();
void setIRThreshold(byte th);
byte checkIR();
void LineTrace();
byte getOption();
void getAD(byte channel, byte* flag);
void Mic();
void setInterrupt();
byte checkCdS();
void setThreshold(byte th);
void overHand();
// グローバル変数の宣言
byte counter=0;
byte LeftCdS, CenterCdS, RightCdS,ExRCdS;
byte threshold[4];
byte ADch=0;
byte ConvEndFlag;
byte ADC[4]={AN4,AN5,AN6,AN11};
byte Leftspeed=208;
byte Centerspeed=208;
byte Rightspeed=208;
byte CdSInt;
// 割り込み処理ルーチン
void interrupt Intr(void)
{
// 約2ms毎に割り込む
if(T0IF) { // 割り込みがtimer0からか?
counter++;
TMR0 = PERIOD;
T0IF = 0; // 割り込みフラグクリア
return;
}
if(ADIF) { // 割り込みがADコンバーターからか?
if(CdSInt) { // それはCdS使用か?
if(ADch==0) LeftCdS = ADRESH;
else if(ADch==1) CenterCdS = ADRESH;
else if(ADch==2) RightCdS = ADRESH;
}
else {
if(ADch==0) LeftCdS = ADRESL;
else if(ADch==1) CenterCdS = ADRESL;
else if(ADch==2) RightCdS = ADRESL;
else if(ADch==3) ExRCdS = ADRESL;
}
ConvEndFlag=true; // データの更新あり
ADIF = 0; // 割り込みフラグクリア
}
}
main()
{
#define SLOW 35
#define LOW 40
#define MIDDLE 80
#define MIDDLE2 120
#define HIGH 160
int i;
byte state=0;
byte extOption; // 外部センサオプション番号
initialize();
extOption = getOption();
if((extOption & 0x38)==0x20) { // 手かざしモード
state=6;
LED(state, 5); // 水色
CdSInt = true;
setThreshold(65); // 白レベルの値から閾値(65%)に決める
}
else if((extOption & 0x07)==0) { // マイクモード
state=7;
LED(state,5);
CdSInt = false;
}
else if((extOption & 0x18)==0x10) { // photo refrector
setIRThreshold(13); // ライントレース
state=2;
LED(state, 5); // 青
CdSInt = false;
}
setInterrupt(); // タイマーとADの割り込み設定
GODONE = 1; // AD変換スタート
while(true) {
switch(state) {
case 2: LineTrace(); break;
case 6: overHand(); break; // CdSでモーターを動かす
case 7: Mic(); break;
}
}
}
void setInterrupt()
{
// Timer0 の設定
T0IE=1; // Timer0 の割り込みON
T0IF=0; // 割り込みフラグクリア
// ADコンバーターの設定
ADIE = 1; // ADコンバータの割り込み許可
ADIF = 0; // 割り込みフラグクリア
PEIE = 1; // 周辺装置の割り込み許可
GIE = 1; // CPUへの割り込み許可
}
void initialize()
{
PORTA = 0; // PORTAを0にする
TRISA = 0; // PORTAを出力に設定する
TRISB = 0x30; // 4,5input
PORTB = 0;
PORTC = 0; // PORTCを0にする
TRISC = 0x0f; // PORTC下4bit入力、上4bit出力
ANSEL = 0xF0; // AN4,5,6,7 ON
ANSELH = 0x0C; // AN10,11 ON
ADCON0 = AN4; // ADFM=1(右詰) AN4 adOn
// 1 = Right justified
OPTION = 0;
// 1:8 prescale
T1CON = 0x31; // Timer1 settings
TMR1IF = 0; // clear TMR1IF
TMR1H = 0xf8; // Initialize Timer1 register
TMR1L = 0x00;
ADC[0]=AN4;
ADC[1]=AN5;
ADC[2]=AN6;
ADC[3]=AN11;
CdSInt = false; // CdSは付いていない
}
void LineTrace()
{
while(RA3)
{
switch(checkIR()){
case 3: Rightspeed=Leftspeed=MIDDLE2; // 直進 青
RC5=0; RC7=0;
break;
case 7:
case 6: Rightspeed = 100; Leftspeed = MIDDLE; //左に行く 紫
RC5=0; RC7=0;
break;
case 4: Rightspeed = MIDDLE; Leftspeed = ~SLOW; //左に行く 赤
RC5=0; RC7=1;
break;
case 11:
case 9: Rightspeed = MIDDLE; Leftspeed = 100; // 水色
RC5=0; RC7=0;
break;
case 8: Rightspeed = ~SLOW; Leftspeed = MIDDLE; // 緑
RC5=1; RC7=0;
break;
} // switch
RC4 = counter < Rightspeed;
RC6 = counter < Leftspeed;
} // while
}
void LED(byte n, byte times)
{
byte i;
for(i=0; i<times; i++) {
PORTA = n;
Delay50(); // 50msディレイ
PORTA = 0;
Delay50(); // 50msディレイ
}
}
void Delay50() // 50m秒ディレイ
{
int i;
for(i=0; i<5; i++)
__delay_ms(10);
}
void Delay100() // 100m秒ディレイ
{
int i;
for(i=0; i<10; i++)
__delay_ms(10);
}
void setIRThreshold(byte th)
{
byte i, j, x;
int average[4]={0,0,0,0};
GIE=0;
// 明るいときの値 明るいと大きい値
ADC[0]=AN4;
ADC[1]=AN5;
ADC[2]=AN6;
ADC[3]=AN11;
for(j=0; j<40; j++) {
for(i=0; i<4; i++) {
ADCON0 = ADC[i];
GODONE = 1;
while(GODONE);
x = ADRESL;
average[i] = (average[i]*9+x)/10;
}
}
for(i=0; i<4; i++)
threshold[i]=average[i]*th/20;
GIE=1;
}
byte checkIR()
{
byte status;
if(ConvEndFlag) { // AD変換が終わったらすぐに次のチャンネルの変換を行う
ConvEndFlag = false;
if(++ADch==4) ADch=0;
ADCON0 = ADC[ADch]; // 変換スタート
GODONE = 1;
}
PORTA=0;
status = 0;
RA2 = ExRCdS<threshold[3];
RA1 = CenterCdS<threshold[1];
RA0 = LeftCdS<threshold[0];
status = RightCdS<threshold[2];
status += RA1 ? 2 : 0;
status += RA0 ? 4 : 0;
status += RA2 ? 8 : 0;
return status;
}
#define optTH 100
byte getOption()
{
byte flag;
byte x;
getAD(AN4,&flag);
getAD(AN5, &x);
if(x) flag|=2;
getAD(AN6, &x);
if(x) flag|=4;
getAD(AN7, &x);
if(x) flag|=8;
getAD(AN10, &x);
if(x) flag|=0x10;
getAD(AN11, &x);
if(x) flag|=0x20;
return flag;
}
void getAD(byte channel, byte* flag)
{
int x;
ADCON0 = channel;
GODONE = 1;
while(GODONE);
x = ADRESH;
x = x*256+ADRESL;
*flag = x > optTH;
}
#define MICTH 4
#define MIDLOW 80
void Mic()
{
byte i;
int average[3]={0,0,0};
int average2[3]={0,0,0};
int x,y,diff[3];
byte a,b,c,max;
unsigned int cnt=0;
GIE=0;
ADC[0]=AN7;
ADC[1]=AN10;
ADC[2]=AN11;
for(cnt=0; cnt<1000; cnt++) {
for(i=0; i<3; i++) {
ADCON0 = ADC[i];
GODONE = 1;
while(GODONE);
x = ADRESL;
average[i] = (average[i]*9+x)/10;
if(x > average[i])
average2[i] = (average2[i]*11+x)/12;
}
}
// 半永久ループ
while(RA3){ // スイッチが押されたら抜ける
for(i=0; i<3; i++) {
ADCON0 = ADC[i];
GODONE = 1;
while(GODONE);
x = ADRESL;
average[i] = (average[i]*9+x)/10;
if(x > average[i])
average2[i] = (average2[i]*11+x)/12;
diff[i] = average2[i] - average[i];
}
if((diff[0] >MICTH) || (diff[1]>MICTH) ||
(diff[2]>MICTH)) {
a=diff[0]; b=diff[1]; c=diff[2];
if(a>b) {
if(a>c) { max=0; }
else { max=2;}
}
else if(b>c) { max = 1; }
else { max=2; }
GIE=1;
x=500; // 回転カウント
switch(max){
case 2: // Left
PORTA = 4;
Rightspeed = ~MIDLOW; Leftspeed = MIDLOW;
RC5=1; RC7=0;
break;
case 1: // backward
PORTA = 2;
if(diff[1]&1){ // たまに逆回りする
Rightspeed = ~MIDLOW; Leftspeed = MIDLOW;
RC5=1; RC7=0;
}
else {
Rightspeed = MIDLOW; Leftspeed = ~MIDLOW;
RC5=0; RC7=1;
}
x = 700;
break;
case 0: // Right
PORTA = 1;
Rightspeed = MIDLOW; Leftspeed = ~MIDLOW;
RC5=0; RC7=1;
break;
default:
PORTC &= 0x0f;
}
counter=0;
cnt=0;
while(cnt!=x) {
if(counter==0) cnt++;
RC4 = counter < Rightspeed;
RC6 = counter < Leftspeed;
if(!RA3) return;
}
PORTC &= 0x0f;
PORTA = 0;
GIE=0;
Delay100();
for(cnt=0; cnt<500; cnt++) {
for(i=0; i<3; i++) {
ADCON0 = ADC[i];
GODONE = 1;
while(GODONE);
x = ADRESL;
average[i] = (average[i]*9+x)/10;
}
}
for(i=0; i<3; i++) average2[i] = average[i];
} //if
}
GIE=1;
}
byte checkCdS()
{
byte status;
if(ConvEndFlag) { // AD変換が終わったらすぐに次のチャンネルの変換を行う
ConvEndFlag = false;
if(++ADch==3) ADch=0;
ADCON0 = ADC[ADch]; // ADチャンネル変更
GODONE = 1; // AD変換スタート
}
PORTA=0;
RA2 = RightCdS < threshold[2]; // 赤
RA1 = CenterCdS < threshold[1]; // 緑
RA0 = LeftCdS < threshold[0]; // 青
status = RA2;
status += RA1 ? 2 : 0;
status += RA0 ? 4 : 0;
return status;
}
void setThreshold(byte th) // 平均の指定%を閾値にする
{
byte i, j, x, g;
int average[3]={0,0,0};
g = GIE; // 割り込み状態の保存
GIE=0; // 割り込みは使わない
// 明るいときの値 明るいと大きい値
ADC[0]=AN4&0x7f;
ADC[1]=AN5&0x7f;
ADC[2]=AN6&0x7f;
for(j=0; j<40; j++) { // 平均の明るさを求める
for(i=0; i<3; i++) {
ADCON0 = ADC[i];
GODONE = 1;
while(GODONE);
x = ADRESH;
average[i] = (average[i]*9+x)/10;
}
}
for(i=0; i<3; i++)
threshold[i]=average[i]*th/100;
GIE = g; // CPUへの割り込み状態を戻す
}
void overHand()
{
while(RA3){
switch(checkCdS()) {
case 7: Rightspeed=Leftspeed=MIDDLE; // 直進
RC5 = RC7 = 0;
break;
case 6: Rightspeed = LOW; Leftspeed = MIDDLE;
RC5 = 0; RC7 = 0;
break;
case 4: Rightspeed = ~MIDDLE; Leftspeed = MIDDLE;
RC5 = 1; RC7 = 0;
break;
case 3: Rightspeed = MIDDLE; Leftspeed = LOW;
RC5 = 0; RC7 = 0;
break;
case 1: Rightspeed = MIDDLE; Leftspeed = ~MIDDLE;
RC5 = 0; RC7 = 1;
break;
case 2:
Rightspeed=Leftspeed=~MIDDLE;
RC5 = RC7 = 1;
break;
default:
case 0: Rightspeed=Leftspeed=255;
RC5 = RC7 = 1;
break;
}
RC4 = counter<Rightspeed;
RC6 = counter<Leftspeed;
}
}
|