机から落ちない自走ロボットのスケッチです。
/* This sketch is for the automation clenaer of Toda Yorozu Kenkyujyo. */ #include < SoftwareSerial.h > //コネクタの接続。タイヤ制御は左右それぞれディジタル2,アナログ1出力が必要。 // left tire #define LdirectionA 2 // 1st bit of direction of the left tire// INPUT1 #define LdirectionB 3 // 2nd bit of direction of the left tire// INPUT2 #define Lspeed 9 // Speed of left tire, analog write only 5,6,9,10,11 //Ain // right tire #define RdirectionA 4 // 1st bit of direction of the right tire//INPUT1 #define RdirectionB 5 // 2nd bit of direction of the right tire//INPUT2 #define Rspeed 10 // Speed of left tire, analog write only 5,6,9,10,11//Ain // sensors センサー用の入力analog inが3つ。 #define Lsensor 0 // sensor for tire analog in #define Rsensor 1 // sensor for tire analog in #define Fsensor 2 // sensor for tire /analog in // PORTD=B00000; stop //停止 // PORTD=B00010; turn right //右展開(左タイヤのみon) // PORTD=B01000; turn left // 左展開(右タイヤのみon) // PORTD=B01010; go forward //前進(左右のタイヤをon) // PORTD=B10100; go back //後退(左右の対ぎゃを逆転) unsigned int Lrpm=250; //0 to 255 左タイヤ回転速度 unsigned int Rrpm=250; //0 to 255 右タイヤ回転速度 unsigned long time1=1; //計測時間 unsigned long dt=50; //dt=0.1 msec //制御の単位時間 unsigned int Ltire=1023; //左タイヤのセンサー unsigned int Rtire=1023; //右タイヤのセンサー unsigned int FrontSens=1023; //前センサー unsigned int NoG=200; //Not on the ground=センサー出力が200以下になった時に床が無いと判断する。 unsigned int DirectRandom=49; //ランダム回転用の係数1 unsigned int DirectRandom2=49; //ランダム回転用の係数2 unsigned int TurnNo=0; // 左右のターンを何回繰り返したかを示す。 void Scan(){ //check the ground and decide the motion Ltire=analogRead(Lsensor); //左タイヤセンサーの値を読み取る Rtire=analogRead(Rsensor); //右タイヤセンサーの値を読み取る FrontSens=analogRead(Fsensor); //前センサーの値を読み取る if (Ltire<NoG && Rtire<NoG && FrontSens<NoG){Handling();} //全てのセンサーがoffの時には、handling中としてタイヤを停止させる。 else{ if (Ltire<NoG && Rtire<NoG){ChangeToStraight();} //後ろのタイヤが二つともoffの時には前進。 if (Ltire<NoG && Rtire>NoG){ChangeToTurnRight();} //左のタイヤがoffの時には右に回転。 if (Ltire>NoG && Rtire<NoG){ChangeToTurnLeft();} //右のタイヤがoffの時には左に回転。 if (Ltire>NoG && Rtire>NoG && FrontSens<NoG){ChangeToBack();} //前センサーがoffの時には後退する。 } } void ChangeToStraight(){PORTD=B000000; delay(5); PORTD=B101000;delay(dt);TurnNo=0;} //前進 void ChangeToTurnRight(){PORTD=B000000; delay(5); PORTD=B011000;delay(dt);TurnNo++;} //右回転(右タイヤを逆方向、左タイヤを順方向に回転させる) void ChangeToTurnLeft(){PORTD=B000000; delay(5); PORTD=B100100;delay(dt);TurnNo++;} //左回転(左タイヤを逆方向、右タイヤを順方向に回転させる) void ChangeToBack(){PORTD=B000000; delay(5); PORTD=B0101000;delay(dt);TurnNo=0;} //後退 void Handling(){PORTD=B000000;delay(2000);} //しばらく停止。 //試験用のサブルーチン:dtの間だけ前進。 void GoStraight(){ //go straight for 0.1 sec PORTD=B000000; delay (5); time1=millis(); analogWrite(Lspeed,Lrpm); analogWrite(Rspeed,Rrpm); PORTD=B010100; // PD1,PD3 =high while ((millis()-time1) < dt){delay(10);} } //試験用のサブルーチン:dtの間だけ右回転。 void TurnRight(){ PORTD=B000000; delay (5); time1=millis(); analogWrite(Lspeed,Lrpm); analogWrite(Rspeed,Rrpm); PORTD=B011000; // PD1 =high while ((millis()-time1)<dt){delay(10);} } //試験用のサブルーチン:dtの間だけ左回転。 void TurnLeft(){ PORTD=B000000; delay (5); time1=millis(); analogWrite(Lspeed,Lrpm); analogWrite(Rspeed,Rrpm); PORTD=B100100; // PD1 =high while ((millis()-time1)<dt){delay(10);} } //試験用のサブルーチン:dtの間だけ後退。 void GoBack(){ PORTD=B000000; delay (5); time1=millis(); analogWrite(Lspeed,Lrpm); analogWrite(Rspeed,Rrpm); PORTD=B101000; // PD1,PD3 =high while ((millis()-time1)<dt){delay(10);} } //試験用のサブルーチン:dtの間だけ停止。 void Freezing(){PORTD=B000000; delay(dt);} // PD1,PD3 =high //試験用のサブルーチン:dtの間だけブレーキ。 void Breaking(){ PORTD=B000000; delay (10); time1=millis(); PORTD=B111100; while ((millis()-time1)<dt){delay(10);} } // PD1,PD3 =high //試験用のサブルーチン:前進、停止、後退、ブレーキ、停止、右回転、左回転をテスト。 void TestRun(){ Serial.println("straight"); for (int i=0; i<5; i++){GoStraight();} Serial.println("freezing"); for (int i=0; i<5; i++){Freezing();} Serial.println("go back"); for (int i=0; i<5; i++){GoBack();} Serial.println("breaking"); for (int i=0; i<5; i++){Breaking();} Serial.println("freezing"); for (int i=0; i<5; i++){Freezing();} Serial.println("turn right"); for (int i=0; i<5; i++){TurnRight();} Serial.println("turn left"); for (int i=0; i<5; i++){TurnLeft();} } //セットアップ void setup(){ Serial.begin(9600); //試験用のシリアル通信 pinMode(LdirectionA, OUTPUT); //LdirectionA=2番端子をアウトプットに設定 pinMode(LdirectionB, OUTPUT); //LdirectionB=3番端子をアウトプットに設定 pinMode(RdirectionA, OUTPUT); //RdirectionA=4番端子をアウトプットに設定 pinMode(RdirectionB, OUTPUT); //RdirectionA=5番端子をアウトプットに設定 pinMode(Lspeed, OUTPUT); //Lspeed=9番端子をアウトプットに設定 pinMode(Rspeed, OUTPUT); //Rspeed=10番端子をアウトプットに設定 DDRD=DDRD|B11111100; //digital out D端子の2-7番を使用。 TestRun(); //上記test runで動作確認。 TurnNo=0; //turn noを元に戻す。 } //メインプログラム void loop(){ Scan(); //センサーでスキャンして、進む方向を決定。 //以下は乱数で回転運動を決める。この回転の途中でスキャンをして危険なら方向を変える。 DirectRandom=random(100); DirectRandom2=random(50000); if(DirectRandom2<5){ if ((DirectRandom%2)==0){for (int i=0; i<(DirectRandom/70); i++){TurnRight(); Scan();}} else{for (int i=0; i<(DirectRandom/70); i++){TurnLeft(); Scan();}} } if(TurnNo>5){PORTD=B000000; delay(5); PORTD=B010100; delay(dt); TurnNo=0;} //5回左右に連続してターンしたら後ろが机の端に近いと判断して前進を始める。 } ///void loop end
ここで公開するアイデア/装置は安全性を保障しておりません。 用途に応じた設計を行い、十分な安全検査を行ってからご利用ください。 本サイトの情報の営利目的での利用はご遠慮ください。 本サイトの内容の無断転載を禁じます。© 2010 TYK