「簡易お掃除ロボットEZ5」の自動走行プログラム。Arduinoスケッチも上げておきます。そう、 | 「藍染 迅(超時空伝説研究所改め)」の部屋

「藍染 迅(超時空伝説研究所改め)」の部屋

小説家ワナビーの「藍染 迅(あいぞめ じん)」です。

書籍化・商業化を目指し、各種コンテストに挑戦しながら、カクヨム、小説家になろう、エブリスタ、アルファポリスなどに作品を投稿しています。

代表作は異世界ファンタジー「「飯屋のせがれ、魔術師になる。」。

このスケッチは、トイラジコンの制御ICであるRX-2Bにラジコン信号をシミュレートして送り込むためのプログラムである。
こうすることによって、複雑なモータ制御を直接行わなくとも、あたかもラジコン送信機で操作されているかのように、車両はArduinoからの指令にしたがって走行する。

部品の改造、追加が最小限で済むので、非常に便利である。


では、スケッチを掲載しておく。

/* Sketch for an autonomous-controlled car w/IR distance sensor
  Will sweep the floor in random directions.
  Automatically avoid an obstacle in the way.

  programmed by Hyper-Space-Lab.
  Ver. 0.8
  24-JUL-2016 */

//  Declaration part
#define  FWD  28  // define constant to denote movement
#define  L  58
#define  R  10
#define  BK  46
#define  RS  34
#define  LS  52  // not in use in this sketch
#define  BR  40  // not in use in this sketch
#define  BL  64  // not in use in this sketch

const int nearby = 350;  // nearby represents the analog read value for 15cm w/IR sensor.
const unsigned long offtimer = 600000UL;  // offtimer to stop running the sketch in ms.

unsigned long timer0 = millis();
unsigned long timer1 = 0;

// 初期化処理
void setup()
{
  pinMode(3, INPUT);      // Use D3 as input
  pinMode(2, OUTPUT);     // Use D2 as output
  pinMode(10, OUTPUT);    // Use D10 as output

  //  Serial.begin(9600);   // Not in use in this sketch
  // mouse_init();

  delay(2000);            // Wait for the circuit to stabilize.
}


// メインループ
void loop()
{
  if  (millis() - timer0 < offtimer)
  {
    randomrun();
  }
}

// ランダム走行
void randomrun()
{
  long n;

  randomSeed(analogRead(2));        // Generates random seed based on unoccupied analog pin input=noise.

  n = random(1, 4);

  switch (int(n))
  {
    case  1:
      goFWD();
      break;
    case  2:
      goR();
      break;
    case  3:
      goL();
      break;
  }
}

// 走行サブルーチン:引数として与えられたmodeの値にしたがって、ラジコン制御信号を送り出す
void go(int mode)
{
  for (int i = 0; i <= 3; i++) // This starts the communication 4 W2 pulses 500Hz 75% duty cycle
  {
    digitalWrite(10, HIGH);
    delayMicroseconds(1500);

    digitalWrite(10, LOW);
    delayMicroseconds(500);
  }
  for (int i = 0; i < mode; i++) // This makes the car move, "mode" times of W1 pulses 1khz 50% duty cycle
  {
    digitalWrite(10, HIGH);
    delayMicroseconds(500);

    digitalWrite(10, LOW);
    delayMicroseconds(500);
  }
  delayMicroseconds(100);
}

// 直進
void goFWD()
{
  int mov;

  timer1 = millis();

  while  (millis() - timer1 < 500)
  {
    if (analogRead(5) > nearby)                // An Obstacle is found.
    {
      goBK();
      goRS();
      return;
    }
    go(FWD);              // Path is clear.
  }
}

// 後退
void goBK()
{
  timer1 = millis();

  while  (millis() - timer1 < 500)
  {
    go(BK);
  }
}

// 右折
void goR()
{
  int mov;

  timer1 = millis();

  while  (millis() - timer1 < 500)
  {
    if (analogRead(5) > nearby)                // An Obstacle is found.
    {
      goBK();
      goRS();
      return;
    }
    go(R);
  }
}

// 左折
void goL()
{
  int mov;

  timer1 = millis();

  while (millis() - timer1 < 500)
  {
    if (analogRead(5) > nearby)                // An Obstacle is found.
    {
      goBK();
      goRS();
      return;
    }
    go(L);
  }
}

// 右旋回
void goRS()
{
  int mov;

  timer1 = millis();

  while  (millis() - timer1 < 500)
  {
    go(RS);
  }
}

// 左旋回
void goLS()
{
  int mov;

  timer1 = millis();

  while  (millis() - timer1 < 500)
  {
    go(LS);
  }
}

// 右折後退
void goBR()
{
  timer1 = millis();

  while  (millis() - timer1 < 500)
  {
    go(BR);
  }
}

// 左折後退
void goBL()
{
  timer1 = millis();

  while  (millis() - timer1 < 500)
  {
    go(BL);
  }
}

細かいところは、フローチャートと違っている部分もある。
現場裁量っていうことで。てへぺろアセアセ

一応、まともに動いているから、とりあえず良しとする。