Avance.Lab

実験

MPU-6050で倒立振子を作ってみる ~前編~

公開日:2025.01.10 更新日:2025.01.10

tag: Arduino

こんにちは、hsです。

今回は、MPU6050というジャイロセンサがあったため、勉強も兼ねて倒立振子というものを作ってみることにしました。

倒立振子で検索を行うと、他にも様々な方が制作しており、かなりメジャーな印象です。
しかし、今までジャイロセンサすら使用したことはなく、他の方々を比べ色々と至らない点があるかと思いますが、温かい目で見ていただけますと幸いです。

倒立振子について

倒立振子を調べると以下のような説明がありました。

「支点よりも重心が高い位置にある振り子をいう。」(Wikipedia引用)
https://ja.wikipedia.org/wiki/倒立振子

つまり、手の上に棒を垂直に立てている状況と同様であり、支点部分(手)を動かすなどして、棒を垂直に維持していなくては棒が倒れてきてしまいます。

そこで今回は、倒立振子を垂直に保つ方法として、支点をモータ等で動かし、振子のバランスを機械的に維持することを目的とします。

構想

ここで紹介する倒立振子は、セグウェイ型と呼ばれるもので、2つの平行したタイヤを使用し、1方向の移動で本体のバランスを保つ仕組みです。

例えば振子が左側(-30°)に傾いた場合、車輪を左回転させ振子を左へ移動させます。
その動作により、振子を垂直に保つことが可能となります。

■必要な材料

・マイコン
Arduino(ATmega328P)
→ギアボックスの動作、センサの読み取り等に使用

・ジャイロセンサ
MPU6050
→傾きの測定に使用

・モータドライバ
リレー
トランジスタ
→持ち合わせがなかったため、トランジスタとリレーで代用

・ギアボックス
タミヤ(TAMIYA) 楽しい工作シリーズ No.103
→支点の移動に使用

・タイヤ
エルパ (ELPA) タイヤ30mm2個入
→支点の移動に使用

・その他
抵抗器やタクトスイッチ、セラミックコンデンサなど、、、
→モータ制御やマイコンの動作環境構築に使用

MPU-6050を使ってみる

■まずArduinoを使ってMPU6050で傾きを取得できるか検証を行います。

1.ArduinoとMPU6050をジャンパワイヤなどを使用して以下のように接続します。

ArduinoピンMPU6050ピン
VCC(5V)VCC
GNDGND
A4SDA
A5SCL

2.Arduinoへ以下のコードを書き込みます。
・コンパイラについては公式サイト「https://www.arduino.cc/」にて入手してください。
※ジャイロセンサのプログラム作成は以下の記事を参考にさせていただきました。
https://tsuchidalab.jp/basic/part2/

#include <Wire.h>

void setup() {
  Serial.begin(9600);           //シリアル通信を開始し、ボーレート(通信速度)を9600bpsに設定
  Wire.begin();                 //I2C通信スタート
  Wire.beginTransmission(0x68); //MPU6050との通信アドレス指定
  Wire.write(0x6b);             //MPU6050の電源用レジスタ指定
  Wire.write(0x00);             //MPU6050を起動
  Wire.endTransmission();       //送信を終了
}
void loop() {
  Wire.beginTransmission(0x68); //MPU6050との通信アドレス指定
  Wire.write(0x3d);             //0x3bから14バイト先までにデータがあるので、ここを通信アドレスに指定
  Wire.endTransmission();       //送信を終了
  Wire.requestFrom(0x68, 2);    //0x3bから2バイト先までの値を要求(Y軸の加速度が取れる)

  if (Wire.available() == 2) {  
    //16ビットのデータが8バイトずつ送られるので、最初の8バイトと2回目の8バイトをorで結合する
    uint8_t first = Wire.read();              //最初の8バイト
    uint8_t second = Wire.read();             //最後の8バイト
    int16_t addition = (first << 8) | second; //両方のデータを結合
   
    Serial.println(addition);   //値を出力
  }
  delay(100);
}

・シリアルモニタで値が取れることを確認します。

左画像は、センサをおおよそ水平にした場合、右画像はセンサをおおよそ45度に傾けた場合です。
値の変化を確認することができました。

制御回路の制作

ここでは、Arduinoとセンサ、モータをすべて接続していきます。
しかし、Arduinoに直接モータを接続すると過電流を起こし故障してしまうため、通常であればモータドライバICを使用します。
ですが、モータドライバICを持っていなかったため、トランジスタとリレーで代用しています。

以下より、回路の解説を行っていきます。

1.Arduino
Arduinoボードのピンソケット部分の接触が良くなく、ジャンパワイヤの角度によっては電流が流れないことがしばしばあるため、今回はブートローダ書き込み済みのATMEGA328Pを使用しArduino互換ボードを作成しています。

■使用しているピン番号の対応

ATMEGA328P
ピン番号
Arduinoピン番号接続先
17番デジタルピン:11番(PWM対応)モータ回転制御用のトランジスタ(Base)へ接続
23番アナログピン:0番(出力として使用)リレーのON/OFFに使用(モータ回転切り替え)
27番アナログピン:4番MPU6050のSDAへ接続
28番アナログピン:5番MPU6050のSCLへ接続

・ピン番号の対応については秋月電子さんの以下ページが参考になります。
https://akizukidenshi.com/catalog/g/g112774/

・Arduinoの互換ボードについて

互換ボード作成は以下の記事を参考にさせていただきました。
https://ht-deko.com/arduino/atmega328p.html

2.モータ制御

■トランジスタを使用してモータの回転数を制御します。
半固定抵抗を使用してトランジスタのBaseに流れる電流と調整することで、モータの回転数制御を行っています。
※回路図と若干抵抗器の値が異なります。
以下回路図となります。

■リレーを使用してモータの回転方向を制御します。
トランジスタを使用した回転数制御に加えて、物理的に切り分けられた回路が入っているリレーを使用することで、モータの回転方向を変えています。
※リレーはブレッドボートに刺したところ、端子が短いせいで接触不良を起こし動作しなかったため、画像を撮っていません。
以下回路図となります。

3.MPU6050

こちらは「MPU-6050を使ってみる」で紹介している内容と同じ回路となります。

トラブル

■事象
モータをマイコンで制御する際、マイコンへの電力供給は本来5V前後欲しい所、約1V~3.5Vを往復していたためマイコンが再起動を繰り返し、まともに動作させることができませんでした。

■原因
モータの電源とマイコンの電源を同じ所から取っており、電源も電池を直列に4本つなぎ6Vとしていました。
そのため、乾電池の内部抵抗や回路内の抵抗を加味しないものとしても、モータによる電力消費が激しく、乾電池の最大電力量を超えてしまい、電圧降下が発生してマイコンに供給される電圧が下がってしまったと思われます。

■発端
今回のトラブルの発端となったこととして、私の知識不足はもちろんですが、ブレッドボード上でのテストを行わなかったことにあります。
ジャンパワイヤーの手持ちが足りなかったこともあり、テスト回路の作成を行わず、はんだ付けの作業に入ったため、実働時に不具合に気づくこととなってしまいました。

まとめ

今回はプログラムを書く時間と、電圧降下の対応を行う時間が取れなかったためここまでとなります。
次回はマイコンとモータの共存と、一番のメインとなる倒立振子として動作させるためのプログラム作成を行う予定となります。

Arduinoを使用したモータ制御やジャイロセンサの使用は、今まで行ったことがなかったため、とても良い勉強になりました。
途中トラブルだらけとなり、グダグダになってしまいましたが、実際に動いた瞬間などが見れるととても嬉しいものがありますので、ぜひ挑戦してみてください。

hs

最近は、部屋の模様替えに凝っています。
畳の目の隙間に入り込んだ汚れの、簡単な掃除方法を模索中です。

関連記事