適当のごった煮

Pythonと境界標とQGISを中心にいろいろと

ダイソーのプチ電車を赤外線で動かす

スポンサードリンク

ダイソーで売られているプチ電車を赤外線を使ってラジコン化しました。

youtu.be

最初は車体をそのまま使う予定でしたが、色々な部品を乗せる都合上、台車をプラ板、車体は工作用紙で作りました。

凸型電気機関車が無蓋貨車を引いているようなイメージで、大雑把な形だけ似せて作りました。

f:id:tekito-gottani:20190825113259j:plain

赤外線の送信はジョイスティックを使って、一定以上前後に倒したときに信号を送っています。同様に、左右方向の情報も送信できます。電源は9Vの電池です。

f:id:tekito-gottani:20190825113541j:plain

受信側は、Arduino Nanoでもサイズが大きかったので、以下のサイトを参考にAttiny85への書き込みに挑戦しました。

受信側の電源は、電気店で見つけたカメラ用に売られているCR2という小型3V電池を使用しています。もともとプチ電車についていた電池ボックスの金具に線を取り付けて再利用し、プラ板でボックスを作りました。

f:id:tekito-gottani:20190825114147j:plain

モーター側は、プチ電車のモーターとギアの位置関係を測って、ちょうど合うようにプラ板に穴を開けてモーターを差し込んでいます。

f:id:tekito-gottani:20190825114214j:plain

送受信のスケッチは、かなり単純です。

送信側は、ジョイスティックの移動量を0~10までの数値に変換して、それがHighの送信時間でデータ自体を表します。

int irPin = 5; // 赤外線送信
int xPin = 1;
int yPin = 2;

void setup() {
  pinMode(irPin, OUTPUT);
  Serial.begin(115200);
  Serial.println("Serial Start.");
}

void loop() {
  int i, x, y;

  while (true){
    // 前後左右の方向と移動量取得
    x = analogRead(xPin) / 100;
    y = analogRead(yPin) / 100;

    Serial.print(x);
    Serial.print(" ");
    Serial.println(y);

    // データ送信
    sousin(9000, 4500);
    sousin(x*100, (15-x)*100); // HとLの合計送信時間を一定にする
    sousin(y*100, (15-y)*100);    
    sousin(600, 0); // ストップビット
    delay(200);
  }
}

void sousin(int hh, int ll){
  int j=hh/26; // 周期26usの方形波の出力回数を決める

  // High送信
  for (int i=0; i<j; i++){
    digitalWrite(irPin, HIGH);
    delayMicroseconds(7);
    digitalWrite(irPin, LOW);
    delayMicroseconds(13);
  }
  // Low送信
  digitalWrite(irPin, LOW);
  delayMicroseconds(ll);
}

受信側は、そのHighの受信時間を計測して、送信同様0~10までの数値に変換してモーターへ指示を出しています。

int ain1 = 1; // ピン1をモータードライバのAIN1に接続
int ain2 = 0; // ピン0をモータードライバのAIN2に接続
int irPin = 3; // 赤外線受信

void setup() {
  pinMode(ain1, OUTPUT);
  pinMode(ain2, OUTPUT);
  pinMode(irPin, INPUT);
}

void loop() {
  int i;
  int zgsy[2] = {0, 0}; // 前後左右の移動指示配列
  int start, ltime, htime, len;
  
  // 最初にモーターを停止状態にする
  digitalWrite(ain1, 0);
  digitalWrite(ain2, 0);
  
  while(1){
    zgsy[0] = 0;
    // 赤外線読み取り
    while (digitalRead(irPin) == HIGH){;} // 未送信状態のHIGH。読み飛ばし
    start = micros();
    while (digitalRead(irPin) == LOW){;} // 赤外線受信開始
    ltime = micros() - start;
    
    if (ltime > 8000 and ltime < 10000){
      start = micros();
      while (digitalRead(irPin) == HIGH){;}
      htime = micros() - start;
      if (htime > 3500 and htime < 5500){
        for(int i=0; i<2; i++){
          start = micros();
          while (digitalRead(irPin) == LOW){;}
          len = micros() - start;
          zgsy[i] = len / 100;
          while (digitalRead(irPin) == HIGH){;}
        }
      }
    }
    while (digitalRead(irPin) == LOW){;} // ストップビット

    // zgsy[0]の数字に応じてモーターへ指示を出す
    if (zgsy[0] > 7){
      analogWrite(ain1, zgsy[0] / 10 * 250);
      digitalWrite(ain2, LOW);
    } else if(zgsy[0] < 4){
      digitalWrite(ain1, LOW);
      analogWrite(ain2, (10 - zgsy[0]) / 10 * 250);
    } else {
      digitalWrite(ain1, LOW);
      digitalWrite(ain2, LOW);
    }
    delay(100);
  }
}

車体などをもう少し作りこんでLEDなどを仕込んだり、細かなスピード調整ができるようにしたら、より本格的な鉄道模型に近づきそうですが、とりあえず動いたことに満足してここで一区切りにしようと思っています。

f:id:tekito-gottani:20190825115146j:plain

車体の製作