知的好奇心 for IoT

IoT関連の知的好奇心を探求するブログです

タミヤのカムプログラムロボットは作るのが大変なので、秋月電子で売っているミニスマートロボットモバイルプラットフォームを試した

以前、次のような記事を書いたのですが、このロボット、対象年齢が10歳以上っと書いてある割には作るのが大変で時間がかかるんです。特にギアボックスがっ!

それで、もっと簡単で安く動くものを作ることができないかなぁと思っていたんです。

そうしたら、たまたま秋月電子で良さげなものを見つけました。

 早速作って見た結果がこれです! 

f:id:IntellectualCuriosity:20190615120004j:plainf:id:IntellectualCuriosity:20190615120031j:plain

既に秋月電子の製品ぺージを見ている人は”あれっ?”という印象を持ったと思いますが、下の写真のようにマニュアルではタイヤの方が後ろになっています。

f:id:IntellectualCuriosity:20190615154021p:plain

しかし、よく考えてください。小さい球の付いたベアリングホイールが前だと、ちょっとした障害物にも引っかかってしまいますよね?移動は前に進むことが圧倒的に多いので、前進しやすい状態にするためにぼくは前後を逆にしたんです。

動作ビデオ

 

回路

タミヤのロボットの時と使っている部品は同じで、両目のLEDを外しただけなので、回路は殆ど変わっていません。

f:id:IntellectualCuriosity:20190615155529p:plain

ただ、筐体が小さくなったのに合わせて、小さいブレッドボードと単4電池3本用の電池ボックスに変更しています。(電池はニッケル水素1.2Vでないとダメですよ。1.5Vの電池だと3本で4.5Vになってしまうので、WeMos D1 miniやモーターの動作電圧を上回ってしまいます。)

使用部品リスト

 

Blynkアプリ

今回は追っかけ機能はやめて、レーザー距離センサは衝突防止・後ずさり用に使っているので、Blynkのウィジェットは操作用のジョイスティックと距離表示だけにしています。

JoystickとGaugeの配置

f:id:IntellectualCuriosity:20190615163638p:plain

JoystickとGaugeの設定

f:id:IntellectualCuriosity:20190615164047p:plain f:id:IntellectualCuriosity:20190615164104p:plain

 

スケッチ

スケッチはタミヤのロボットのものをベースに、クルクル回りやすくなっているので左右の動作を緩慢にしたり 、衝突防止・後ずさり動作とジョイスティック操作を両立するように工夫しています。

/*
 * Robot2.ino
 * June 15, 2019
 * By Hiroyuki ITO
 * http://intellectualcuriosity.hatenablog.com/  
 * MIT Licensed.
*/
#define BLYNK_PRINT Serial

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Wire.h>
#include <Adafruit_VL53L0X.h>

// Set Blynk Auth Token and WiFi credentials.
const char *auth = "YourAuthToken";
const char *ssid = "YourNetworkName";
const char *pass = "YourPassword";

// DRV8835
// GPIO
#define PIN_AIN1 14     // D5 Right Motor Blue
#define PIN_AIN2 12     // D6 Right Motor Yellow
#define PIN_BIN1 13     // D7 Left  Motor Yellow
#define PIN_BIN2 15     // D8 Left  Motor Blue
// PWM
#define PWM_FREQ 1000   // PWM frequency: 1000Hz(1kHz)
#define PWM_RANGE 100   // PWM range: 100
// Distance
#define RANGE_REVERSE 100 // 100 mm
#define RANGE_STOP 200    // 200 mm

// VL53L0X
Adafruit_VL53L0X lox = Adafruit_VL53L0X();

// Global
int mr_pwm = 0;         // Right motor speed
int ml_pwm = 0;         // Left  motor speed
int distance = 0;       // Ranging distance
int x = 0;              // Joystick x axis
int y = 0;              // Joystick y axis
boolean Reverse_flag = false;
BlynkTimer timer;
VL53L0X_RangingMeasurementData_t measure;

/*
 * ABS Function
 */
int setABS(int pwm_value) {
  pwm_value = abs(pwm_value);
  if (pwm_value != 0) {
    pwm_value = pwm_value;
    if (pwm_value > 100) {
      pwm_value = 100;
    }
  }
  return pwm_value;
}

/*
 * Set Motor
 */
void setMotor() {
  // Right Motor
  if (mr_pwm > -1) {
    // CW Forward
    analogWrite(PIN_AIN1, 0);
    analogWrite(PIN_AIN2, setABS(mr_pwm));
  } else {
    // CCW Reverse
    analogWrite(PIN_AIN1, setABS(mr_pwm));
    analogWrite(PIN_AIN2, 0);
  }

  // Left Motor
  if (ml_pwm > -1) {
    // CW Forward
    analogWrite(PIN_BIN1, 0);
    analogWrite(PIN_BIN2, setABS(ml_pwm));
  } else {
    // CCW Reverse
    analogWrite(PIN_BIN1, setABS(ml_pwm));
    analogWrite(PIN_BIN2, 0);
  }
}

/*
 * Keep Distance
 */
void keepDistance() {
  if (Reverse_flag) {
    mr_pwm = 0;
    ml_pwm = 0;
    Reverse_flag = false;
  }
  lox.rangingTest(&measure, false); // pass in 'true' to get debug data printout!
  if (measure.RangeStatus != 4) {   // phase failures have incorrect data
    distance = measure.RangeMilliMeter;
    if (distance < RANGE_REVERSE) {     // Less than 100 mm
      mr_pwm = -100;
      ml_pwm = -100;
      Reverse_flag = true;
    }
  } else {
    distance = 9999;  // dummy value
  }
  if (distance > RANGE_STOP || y < 0) { // Greater than 200 mm or Reverse
    if (y > -1 ) {    // Forward
      mr_pwm = y; 
      ml_pwm = y + x;
    } else {          // Reverse
      mr_pwm = y + x; 
      ml_pwm = y;
    }
  }
  setMotor();
}

/*
 * Send Distance
 */
void sendDistance() {
  Blynk.virtualWrite(V2, distance);
  BLYNK_LOG2("sendDistance: ", distance);
}

/*
 * Joystick x axis, y axis
 */
BLYNK_WRITE(V1) {
  x = param[0].asInt(); // Joystick x axis
  y = param[1].asInt(); // Joystick y axis
  BLYNK_LOG2("Joystick x:", x);
  BLYNK_LOG2("Joystick y:", y);
}

void setup() {
  delay(10);
  Serial.begin(74880);

  // Initialize GPIO
  pinMode(PIN_AIN1, OUTPUT);
  pinMode(PIN_AIN2, OUTPUT);
  pinMode(PIN_BIN1, OUTPUT);
  pinMode(PIN_BIN2, OUTPUT);

  // Initialize PWM
  analogWriteFreq(PWM_FREQ);
  analogWriteRange(PWM_RANGE);

  // Initialize VL53LOX
  lox.begin();

  // Connect WiFi and Blynk cloud server
  Blynk.begin(auth, ssid, pass);
  timer.setInterval(100L, keepDistance); // 100 msec
  timer.setInterval(1000L, sendDistance); // 1000 msec
}

void loop() {
  Blynk.run();
  timer.run();
}

 

おわり