スイッチのソースの書き方について

このQ&Aのポイント
  • ライントレースのタッチセンサー1つを使ってON/OFFができるようにする方法を教えてください
  • 白い部分でもスイッチがきくようにするにはどのようにすればいいのですか?
  • スイッチのソースコードを改良して、白い部分でもON/OFFができるようにしたいです
回答を見る
  • ベストアンサー

スイッチのソースの書き方について

ライントレースのタッチセンサー1つを使ってON/OFFができるようにしたいのですが 下記のソースだとライントレースをしていて、黒いラインの上にいるときにしかON/OFFできません。 これを白い部分(ラインから外れたところ)でもスイッチがきくようにするにはどのようにすればいいでしょうか? /* ライトセンサーの判定値 */ #define kuro 10 /* Touch Sensor control */ /* タッチセンサーの状態を判断 戻り値 0:タッチセンサーが押されていない 1:タッチセンサーが押されている */ int GetTouch(unsigned char ch) { if (pAnalog->Pin6[ch][pAnalog->Actual[ch]] > 1000) { return 1; } else { return 0; } } int migi(unsigned char ch) /*右まわり*/ { MotorPower(CH_C, -20); /* 出力ポートCのパワーを-20%(逆回転)に変更 */ MotorPower(CH_B, 40); /* 出力ポートBのパワーを10%(逆回転)に変更 */ return 0; } int hidari(unsigned char ch)/*左まわり*/ { MotorPower(CH_C, 40); /* 出力ポートCのパワーを10%(逆回転)に変更 */ MotorPower(CH_B, -20); /* 出力ポートBのパワーを-20%(逆回転)に変更 */ return 1; } int mae(unsigned char ch) /*前進*/ { MotorPower(CH_C,45 ); /* 出力ポートCのパワーを10%(逆回転)に変更 */ MotorPower(CH_B,40 ); /* 出力ポートBのパワーを-20%(逆回転)に変更 */ return 1; } /* Light Sensor control */ /* ライトセンサーの値を取得 */ unsigned char GetSensor(unsigned char ch) { return((unsigned char)pUart->Raw[ch][pUart->Actual[ch]][0]); } int main(void) { int R = 0; MotorReset(CH_B|CH_C); /* モーターの状態をリセット */ MotorStart(CH_B|CH_C); /* モーター起動 */ while(1) { /* 永久ループ */ if(GetTouch(CH_2) == 1){ while(GetTouch(CH_2) == 0); MotorPower(CH_B|CH_C, 0); /*出力ポートB,Cのパワーを0にする*/ while(GetTouch(CH_2) == 1); /* はなされるまで待つ */ while(GetTouch(CH_2) == 0); /*押されるまで待つ*/ MotorPower(CH_B|CH_C, 40); /*出力ポートB,Cのパワーを50、50にする*/ while(GetTouch(CH_2) == 1); } clock_t start,end; if (GetSensor(CH_3) > kuro ){ /* 入力ポート3のライトセンサーが設定値を超えている場合…*/ start = clock(); /*時間測定スタート(ここから)*/ if( R == 1 ){ migi(CH_B|CH_C); /*右回り*/ }else{ hidari(CH_B|CH_C); /*左回り*/ }//elseのカッコ }//ifのカッコ while(GetSensor(CH_3) > kuro){/* 入力ポート3のライトセンサーが設定値を超えている場合…*/ end = clock();/*時間測定終了(ここまで)*/ if(((double)(end - start)/CLOCKS_PER_SEC)>0.2){ if( R == 1 ){ hidari(CH_B|CH_C); /*左回り*/ R = 0; while(GetSensor(CH_3) > kuro);/* 入力ポート3ライトセンサーが設定値を超えている場合は待つ*/ }else{ migi(CH_B|CH_C); /*右回り*/ R = 1; while(GetSensor(CH_3) > kuro);/* 入力ポート3ライトセンサーが設定値を超えている場合は待つ*/ }//elseのカッコ }//ifのカッコ }//whileのカッコ mae(CH_B|CH_C); /*前進する*/ }//whileのカッコ }//mainのカッコ

質問者が選んだベストアンサー

  • ベストアンサー
  • myuki1232
  • ベストアンサー率57% (97/170)
回答No.1

一応それっぽく動くだけなら、if(GetTouch(CH_2) == 1){ ... の処理を while(GetSensor(CH_3) > kuro); /* 入力ポート3ライトセンサーが ... のループの中に入れれば動きそうです。 ただし、このやり方ではもう少し複雑な動きをさせようとすると途端に破綻します。 ソースを書く前に、例えば状態遷移図などを使って動作を設計する手法を覚える必要があるでしょう。

関連するQ&A

  • ライントレース 変数の使い方について

    プログラミングについておききしたいのですが、 ライントレースで左右のカーブを曲がる際に 変数を使って、「さっきは右に曲がったので次は右から曲がる」や 「さっきは左に曲がったから左から曲がる」といったプログラムは どのようにつくったらいいのでしょうか? まだ初心者なので変数をうまく使えなくて悩んでいます。 よろしくお願いします。 今のところ下記のような感じにできているのですが 修正点や加えた方がいい点、省略できる点はありますでしょうか? よろしくお願いします。 mainの上は省略させて頂きました。 int main(void) {  int R = 0; while(1) {  if(GetTouch(CH_2) == 1){//タッチスイッチでのON/OFFスイッチです  while(GetTouch(CH_2) == 0);  MotorPower(CH_B|CH_C, 0);  while(GetTouch(CH_2) == 1);  while(GetTouch(CH_2) == 0);  MotorPower(CH_B|CH_C, 40);  while(GetTouch(CH_2) == 1); }else{  //ここからライントレースの内容です  clock_t start,end;  clock_t start2,end2; if (GetSensor(CH_3) > kuro && R == 0) {  start = clock();  migi(CH_B|CH_C);  while(GetSensor(CH_3) > kuro){  end = clock();  start2 = clock(); if(((double)(end - start)/CLOCKS_PER_SEC)>0.2){  hidari(CH_B|CH_C);  while(GetSensor(CH_3) > kuro);  end2 = clock();  MotorPower(CH_B|CH_C,40);  R = 1;  break; } while( R == 1 ){ if(GetSensor(CH_3) > kuro){ hidari(CH_B|CH_C); while(GetSensor(CH_3) > kuro); MotorPower(CH_B|CH_C,40); R = 0; break; }else { if(((double)(end2 - start2)/CLOCKS_PER_SEC)>0.2){ migi(CH_B|CH_C); while(GetSensor(CH_3) > kuro); MotorPower(CH_B|CH_C,40); }//ifのカッコ }//whileのカッコ }//elseのカッコ }//whileのカッコ }//ifのカッコ }//elseのカッコ }//whileのカッコ }//mainのカッコ

  • c言語関数の(1)~(5)までの部分が何をやっているのかよく分からない

    c言語関数の(1)~(5)までの部分が何をやっているのかよく分からないので、どなたか解説をお願いします。 int memcmp(const void *s1, const void *s2, size_t n) { const unsigned char *p1 = (const unsigned char *)s1; const unsigned char *p2 = (const unsigned char *)s2; while (n-- > 0) { if (*p1 != *p2) return (*p1 - *p2); p1++; p2++; } return (0); } return (*p1 - *p2); > (1) ---------------------------------------------------------------------- char *strcat(char *s1, const char *s2) { char *p = s1; while (*s1) s1++; /* s1を末尾まで進める */ while (*s1++ = *s2++) ; /* '\0'が見つかるまでs2をコピー */ return (p); } while (*s1++ = *s2++) ; > (2) ---------------------------------------------------------------------- char *strstr(const char *s1, const char *s2) { const char *p1 = s1; const char *p2 = s2; while (*p1 && *p2) { if (*p1 == *p2) { p1++; p2++; } else { p1 -= p2 - s2 - 1; p2 = s2; } } return (*p2 ? NULL : (char *)(p1 - (p2 - s2))); } while (*p1 && *p2) > (3) p1 -= p2 - s2 - 1; > (4) ---------------------------------------------------------------------- char *strcpy(char *s1, const char *s2) { char *p = s1; while (*s1++ = *s2++) ; return (p); } while (*s1++ = *s2++)   > (5) ;          > (5) ----------------------------------------------------------------------

  • H8S/2552Fにおけるプログラミング

    現在イエローソフト社のH8S/2552F USB-IF CPUボードを用いて,I/Oポートから32bitトルグスイッチの状態を出力しようとしています。それらのデータをシフトしつつ外部SRAMに送り、さらに32bitのデータとしてPCに取り込みたいと考えているのですが、その方法がわかりません。 以下に現状のプログラムを載せさせて頂きました。(間違いがあるのは十分承知です…) どなたか教えて下さい。よろしくお願い致します。 #define PORT4 (*((volatile unsigned char *)0xFFFFB3)) #define PORT9 (*((volatile unsigned char *)0xFFFFB8)) #define PORTH (*((volatile unsigned char *)0xFFFA14)) #define PORTJ (*((volatile unsigned char *)0xFFFA15)) unsigned long in_switch(void) {     return (PORTJ <<24);     return (PORTH <<16);     return (PORT9 <<8 );     return (PORTJ | PORTH | PORT9 | PORT4) ; } void main() {    puts("トグルスイッチテストプログラム");    while (1) {          unsigned long data;          printf("リターンキーで現在のスイッチ状態を表示します。");          fgetc(stdin); //リターンキー入力待ち          data = in_switch();//スイッチの状態を入力          printf("現在のスイッチ状態=%d(H'%02X)\n", data, data); //スイッチ状態表示 } }

  • Cの共用体を使ったローテートについて

    独習Cで独学中です。 Cでローテート関数を作る下記の模範解答があり、動作も確認済みですが、どうしてそうなるのかイマイチ理解できません。 教えてください。 ========ここから=================================== #include <stdio.h> void rotate(unsigned char *c); int main(void) { unsigned char ch; int i; ch = 1; for(i=0; i<16; i++) { rotate(&ch); printf("%u\n", ch); } return 0; } void rotate(unsigned char *c) { union { unsigned char ch[2]; unsigned u; } rot; rot.u = 0; /* 16ビットをクリア */ ---(1) rot.ch[0] = *c;          ---(2)  /* 整数を左にシフト */ rot.u = rot.u << 1;        ---(3) /* ビットがc[1]にシフトしたかどうか確認する。 シフトしていれば、OR演算を実行して他方の端に戻る */ if(rot.ch[1]) rot.ch[0] = rot.ch[0] | 1; *c = rot.ch[0]; } ========ここまで============================== 私の考えでは (1)のときにビットの状態は 0000 0000 0000 0000 (2)により ch[0]にchの値が渡されるので 0000 0001 0000 0000 <-ch[0]->|<-ch[1]-> (3)で左に1シフトされると 0000 0010 0000 0000 となり、i=1のときch[0]が2、以後インクリメントごとに4,8,・・・,128まではわかります。 その後、ビットからはみ出した1が最下位に戻ってくるところがよくわかりません。 コメント行の「c[1]」はビット番号のことではなくてch[1]の間違いなのか? だとしてもif文のch[1]は0ではないか???と悩んでます。 解説をどうかよろしくお願いします!

  • 押したら動くプログラム

    プログラミング初心者なのです。 タッチセンサーを押したら、ライトセンサーの下に置いてある物の色(黒か白か)を判別して右に流すか左に流すようなプログラムを考えているのですが、流れとしてはこんな感じでいいのでしょうか? while(gettouch(CH_2)==0);  ボタンが押されるまで待つ  if(gettouch(CH_2)==1){   ボタンが押されたら   if(getsensor(CH_3)>5){   ライトセンサーの値が5よりも大きかったら    motorpower(CH_A,10);  モーターパワーを10    sieep(3);           3秒待つ    motorpower(CH_A,0);   モーターパワーを0   }else{    motorpower(CH_A,-10); モーターパワーを-10    sieep(3);           3秒待つ    motorpower(CH_A,0);   モーターパワーを0   } } 上記のようなプログラムで動くでしょうか? もし足りないところなどあったらご指摘いただけると幸いです。

  • C言語

    文字列を逆順にするプログラムを考えているのですが分かりません。(例)qwerならrewqです。入力終了は、EOFです。考えたのですが、分かりません。(コンパイルエラーです。)教えてください。宜しくお願いします。#include <stdio.h> unsigned str_length(const char str[]) { unsigned len=0; while (str[len]) len++; return (len); } void put_rstring(const char str[]) { unsigned i = str_length(str): while (i-- >0) putchar(str[i]); } int main(void) { char str[30]; int ch; printf("文字列を入力\n"); /* ----この文字列を入力したあとに、Ctrl+Zを押すと、逆から表示               で反対から、文字列が表示----*/ while (1) { ch=getchar(); if (ch==EOF) break; } printf("逆から表示"); put_rstring(str); puts("です。"); return(0); }

  • C言語strcmpについて

    下記のプログラムでstrcmp動かしたところ、理論的には、68と表示されるところ、1と表示される理由を教えてください。詳細部分は、省略します、たとえば、include,const strcmp("ABCDE","ABC"); int strcmp(char *s1,char *s2){ while(*s1==*s2){ if(*s1=='\0') return (0); s1++; s2++; } return(( unsigned char)*s1 - (unsigned char)*s2);  

  • ちょっとした疑問なんですが・・・(C言語)

    何度も質問してごめんなさい! ちょっとした疑問なんですが、下記のプログラム中の、 while(!feof(in)) { ch = fgetc(in); if(!feof(in)) fputc(~ch, out); } のコードで、「while(!feof(in))」でストリーム「in」結び付けられているファイルの終わりに達していれば繰り返し処理を終えるのは分かるのですが、 なぜ、インクリメントも無くファイルの終わりまで文字を調べ進めることができるのでしょうか? 未熟者の私ですが教えて頂けないでしょうか? 【プログラム例】 #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { FILE *in, *out; unsigned char ch; if(argc!=3) { printf("使用法: <プログラム名> <入力ファイル名> " "<出力ファイル名>\n"); exit(1); } if((in = fopen(argv[1], "rb"))==NULL) { printf("入力ファイルを開くことができません\n"); exit(1); } if((out = fopen(argv[2], "wb"))==NULL) { printf("出力ファイルを開くことができません\n"); exit(1); } while(!feof(in)) { ch = fgetc(in); if(!feof(in)) fputc(~ch, out); } fclose(in); fclose(out); return 0; }

  • 配列の練習問題

    #include<iostream> using namespace std; //count関数の宣言 int count(char str[], char ch); int main() { char str[100]; char ch; cout << "文字列を入力して下さい。\n"; cin >> str; cout << "文字列から探す文字を入力して下さい。\n"; cin >> ch; int c = count(str, ch); cout << str << "の中に" << ch << "は" << c << "個あります。\n"; return 0; } //count関数の定義 int count(char str[], char ch) { int i = 0; int c = 0; while (str[i]) { if (str[i] == ch) c++; i++; } return c; } こんにちは。 この問題の解答のプログラムの意味がイマイチ解らないので良かったら教えて下さい。 確認がてらに質問します。 よろしくお願いします。

  • ポインタと文字列(C言語)

    サンプルソース char *myfgets(char *s, int n, FILE *in){-----(1) int ch; while((ch = fgetc(in)) != '\n'){ if(ch == EOF) return NULL; *s++ = ch; if(*s == (n - 1))------(2) return NULL; } *s++ = '\n'; *s = '\0'; return s; } 自分でfgets関数を作ろうという課題なのですがポインタがいまいちつかめません。 (1)のchar *myfgetsの部分の関数のポインタというのは要するにどういうことに使うのでしょうか? (2)の場合の*sは配列の要素数を表しているのでしょうか?

専門家に質問してみよう