2020年3月31日火曜日

ロボットブログラミングについて

あまプロではArduinoを使ってロボットブログラミングを行う場合が有ります。

生徒が既成品を買うて来て、作り方等を教える場合も有りますが、日本橋で部品を購入して独自のロボットで行う場合も有ります。
独自というても、ArduinoとDCモータ2個とモータドライバ超音波距離センサの組み合わせなんですけど、色々と嵌まる所が有ったのであメログ。
 
Arduinoだけなら角型乾電池(9V)のみで動くんですが、モータを回すとなると電圧が足らなくなるので単3乾電池(1.5V)が2個要ります。
Arduinoと角型乾電池、モータ2個と単3乾電池2個、それらをつなぐモータドライバ
簡単にはこんな仕組みです。

Arduinoは5Vと3.3Vの電圧を出力する事が出来ますが、今回はArduino自体を角型乾電池(9V)で動かそうとしてるので、モータ2個を回すにはどうしても電圧不足になります…無理に動かすとArduinoやモータドライバが不安定になり最悪壊れてまいます。
なもんで、ドライバを介して単3乾電池2個の電圧でモータを回します。
もう一つ超音波距離センサを動かすにも電圧が要るのですが、これはArduinoの5Vで動作し、Arduinoが不安定になる事も有りませんでした。
その他、ギアボックスやキャタピラやブレードボードやビニール線や電池ボックス等々…全部で日本橋で7000円(税込)で買えました。

工具は半田ごてセットとニッパとラジオペンチとネジドライバ(モータドライバとはちゃうよ) 合わせて2000円くらいかな?百均ならもうちょい安く揃えられるかも。

これらを駆使して、頑張ってロボットを組み立てます。

では次、いよいよプログラミング。
ArduinoはC言語みたいなのでプログラミング出来るんですが…正直子供向けのプログラミング教室には敷居が高過ぎます。
なもんで、Scratchに慣れた子どもにはBlocklyDuinoでプログラミングしてもらいます。
こちらScratchの様に予め用意されたブロックを組み合わせるだけで、Arduinoのコードを生成してくれる優れ物です。
日本語やにほんごにも対応してくれますので、これとArduinoIDEが有れば簡単なロボットプログラミングは出来てしまいます。
固有のライブラリをインクルードするとかは(今の所)無理なので、その場合は直接ArduinoIDEでコーディングするしかないんかな?

距離を測る場合は、標準のBlocklyDuinoでは出来ないんですが、設定画面で機能追加する事で距離センサのブロックが追加されます。
他にもサーボとかイーサネットの機能追加ブロックも有るみたいです(使た事ないけど)。

モータドライバを介して前進後進や右回転左回転をするにはドライバの各端子に接続したピンをオンオフ(Hight/Low)して制御します。
動力用電源端子1つと制御用電源端子1つとGND1つとモータ用入力端子4つとモータ用出力端子2つ…モータは2個でモータ用入力は一つ共有なんで…計15端子!
ビニール線を同じ色にすると、訳解らんくらいゴチャゴチャになります。
始めから一気に完成を目指すんやなくて、モータ1つずつ動かすと良ぇと考えます。

今回のロボットは右輪を右モータ、左輪を左モータで動かします。
どの端子をオンにしてどの端子をオフにしたらモータがどちらに回るかはデータシートに載ってます。
しかし、前進後進の度にピンを個別にオンオフしてたらコードも見難くなるので、前進後進停止右回転左回転は関数化して、都度呼び出す様にすると良ぇでしょう。
例えばこんな感じ。
ここで嵌りポイント
関数名を大文字にするとコンパイルエラーになりました。
良く解らんけど、諦めて関数名は小文字にしてます。

もう一つ嵌まりポイント
ピンのオンオフを切り替えたら、即モータが回ってロボットが動…きません。
0.5秒程待つくらいが丁度良ぇみたい。

もう一つハマりポイント
距離センサは超音波で距離を測ります。
モータ選りかは高速に結果を出すけど、それでもCPUの処理速度に比べたら遅いです。
loopの中で制御の度に距離を取得すると、結果取得に間に合わず不正確な距離を返すみたいです。
繰り返しの中では、毎回センサから距離を取得するのではなく、一度距離を取得したら変数に保存しておき変数の距離を参照する様に実装しました。

もう一つハマりポイント
UbuntuのarduinoIDEは偶にUSBでArduinoを接続しても認識せぇへん時が有ります。
そんな時は、ツールのシリアルポートのチェックを付けると良いです。

そんなハマりポイントを何とか解決して、BlocklyDuinoが生成してくれたコードからこちら。

int kyori;

int Sonic_Time_out = 3000;

long Sonic_Timing(){
  digitalWrite(12, LOW);
  delayMicroseconds(2);
  digitalWrite(12, HIGH);
  delayMicroseconds(10);
  digitalWrite(12, LOW);
  long duration = pulseIn(13,HIGH,Sonic_Time_out);
  if ( duration == 0 ){
    duration = Sonic_Time_out;
    digitalWrite(0, HIGH);
    delay(25);
    digitalWrite(0 ,LOW);
    delay(225);
  }
  return duration;
}

void foward() {
  digitalWrite(5, HIGH);
  digitalWrite(6, LOW);
  digitalWrite(7, HIGH);
  digitalWrite(8, HIGH);
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH);
}

void right() {
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, LOW);
  digitalWrite(8, HIGH);
  digitalWrite(9, LOW);
  digitalWrite(10, HIGH);
}

void stop() {
  digitalWrite(5, LOW);
  digitalWrite(10, LOW);
}

void left() {
  digitalWrite(5, HIGH);
  digitalWrite(6, LOW);
  digitalWrite(7, HIGH);
  digitalWrite(8, LOW);
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);
}

void back() {
  digitalWrite(5, HIGH);
  digitalWrite(6, HIGH);
  digitalWrite(7, LOW);
  digitalWrite(8, LOW);
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);
}

void setup()
{
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, INPUT);
  pinMode(0, OUTPUT);
  digitalWrite(11, HIGH);
  pinMode(2, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
}


void loop()
{
  kyori = Sonic_Timing()/29/2;
  if (kyori > 20) {
    foward();
    delay(500);

  } else if (kyori > 10) {
    stop();
    delay(500);
  } else {
    digitalWrite(2, HIGH);
    if (kyori % 2 == 0) {
      right();

    } else {
      left();

    }
    delay(1000);
    back();
    delay(500);
    digitalWrite(2, LOW);

  }

}
これをArduinoIDEへコピペしてArduinoへアップロードするだけです。

センサで距離を測って、20cmより離れてたら前進して、20cm〜10cmの場合は停止して、それより近くなったら方向転換して戻らせてみました。
ちょっと動かしただけで、直ぐに線が外れて動かへん様になるし、ソースは100行以上あるしで、全然子ども向けではないけど…。
大人なロボットプログラミング入門には良ぇんちゃうかな?

0 件のコメント:

コメントを投稿

つっこみ