工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

効率的なArduino PWMリーダー&RC受信機デコーダー:フェイルセーフ内蔵

必要なパーツと用品

パーツ数量備考
Arduino UNO1Nano/Pro Miniでも可
SG90 マイクロサーボ2サーボミキサー実演用

プロジェクト概要

RC受信機(または任意のPWM信号)を任意のArduino入力ピンで読み取り、送信機信号喪失時にフェイルセーフを発動させる、汎用的で効率的なコードを提供します。ピンチェンジ割り込みを用いるため、pulseIn()のようにメインループをブロックしません。

下記動画では、このコード(PWMread_RCfailsafe.ino)を使ってArduino Unoをサーボミキサーとして動作させています:

目次

サーボとスピードコントローラーはPWMでどう制御されるか

PWM信号(パルス幅変調)の理解を前提とします。詳しくはJoop Brokking氏の動画が参考になります。また、Arduino IDE、変数型、制御構文、配列、Servoライブラリの基礎知識も必要です。

RC模型/ロボットでのArduino活用例

コード概要:フェイルセーフ付きRC受信機PWMデコード

ピンチェンジ割り込みでPWM信号を測定。Uno/Nano/Pro Miniの全デジタル/アナログピン(A6/A7除く)に対応。割り込みレジスタ設定を自動化し、異なるプロジェクト/ピン配置へ容易に移植可能です。

注意: SoftwareSerial等、ピンチェンジ割り込みを使用するライブラリと併用不可。

仕組み:

詳細はポート操作チュートリアルも参照。

専用関数RC_decode()でパルス幅(1000〜2000μs)を±100%(±1.0)の制御信号に変換。フェイルセーフは10〜330Hz、500〜2500μsの許容範囲外で所定値を返します。キャリブレーション値とフェイルセーフ位置は各チャネルごとにPWMread_RCfailsafe.ino内で設定可能。

PWMread_RCfailsafe.inoの使い方

ステップ1:ハードウェア接続例(Arduino Uno)

ステップ2:ファイルをスケッチフォルダにコピー

PWMread_RCfailsafe.inoをメインスケッチと同じフォルダに配置。IDEで開き直すと2つ目のタブとして表示されます。

ステップ3:入力ピンを指定

PWMread_RCfailsafeタブの「USER DEFINED VARIABLES」セクションでpwmPIN[]配列にピン番号を入力。最初の要素がチャネル1、2番目がチャネル2...対応。A6/A7は使用不可。Megaは未対応(要望があれば対応可能)。

ステップ4:利用可能な関数を確認

ステップ5:生パルス幅をシリアル出力して確認

付属のRC_Read_Exampleを書き込み、送信機ONでシリアルモニタを見る。RC_avail()でデータ揃い次第print_RCpwm()で出力。

ステップ6:送信機キャリブレーション

シリアル出力された生パルス幅を見て、RC_min[], RC_mid[], RC_max[]を手動調整。フルレートで操作して最大解像度を得ること。

ステップ7:キャリブレーション済み値を出力確認

print_RCpwm()をコメントアウトし、RC_decode(ch)で±1.0に変換、decimal2percentage()でパーセント表示。

ステップ8:フェイルセーフ位置設定

RC_failsafe[]に各チャネルのフェイルセーフ位置(±1.0範囲)を設定。送信機ON/OFFで動作確認。※受信機側のフェイルセーフ機能は無効化推奨(そうでないとArduinoが信号喪失を検知できない)。

受信機フレームレート・周波数の表示

チャネル1(最初のパルス)でPWM_read(1)→PWM_period(), PWM_freq()で取得・表示。フレーム周期がわかると、データ未受信時のフェイルセーフ発動タイミング(例:21ms経過で強制更新)を制御できます。RC_Read_Example.inoに実装例あり。

サーボミキシング例

付属のRC_ServoMixer_Example.inoで、チャネル2(エレベーター)とチャネル3(エルロン)をミキシングし、2つのサーボ(ピン9,10)を駆動。方向・レート・サブトリム設定も含む。ミキシング式:

mix1 = ch2 - ch3  (エレベーター - エルロン)
mix2 = ch2 + ch3  (エレベーター + エルロン)

出力を±1.0にクリップ後、calc_uS()でサーボ用パルス幅(μs)に変換:

pulse_μs = 1500 + (servo_position_% × rates × direction + sub_trim) × 500

標準ニュートラル1500μs、±500μs(=1000〜2000μs)が基本。レート1.0で±500μs、2.0で±1000μs。

このアプローチを採った理由

pulseIn()はパルス待ちでブロッキングし、マルチチャネルではデータ取りこぼし発生。ピンチェンジ割り込み+直接ポート操作ならメインループをほぼ止めず高速処理可能だが、実装が面倒。そこで「汎用.inoファイルをコピーするだけで割り込みの恩恵を受けられる」仕組みを作りました。

制限事項

micros()関数の分解能

4μsステップでカウント。実用上十分だが、タイマー割り込みで0.5μs分解能化も可能(参考)。

効率

6ch受信時、ISR実行時間は約24μs/回。パルス1つでISRが2回(立ち上がり/立ち下がり)走るため96μs。6chで約288μs/フレーム。受信機周期20msとするとCPU使用率約1.44%。pulseIn()ならチャネルごとに最大20msブロックされるので大幅改善。2chなら0.16%。

実用的な最大周波数

他用途で使う場合、最大約2.5kHzまで(micros()で100ステップ分解能)。1chでCPU 3%、最小測定デューティ0.03(12μs)。より高周波ならISRを専用実装すべし。

コード

全コードは記事内に掲載(長いためここでは省略)。GitHub等から入手可能。

回路図

RC受信機:ICSPピンの5V/GNDから給電、信号6chをピン2〜7へ。
マイクロサーボ1:5V/GND、信号→ピン9。
マイクロサーボ2:3.3V/GND、信号→ピン10。

製造プロセス

  1. Arduino UNOで作るLCDアニメーション&ゲーム入門
  2. Arduinoとスマホで作るスマート電圧計 – 簡単DIYプロジェクト
  3. Arduinoで温湿度ロガーを作る – DHT11とEthernetシールドでSDカード記録
  4. DHT11 と Blynk で温湿度をリアルタイム監視する Arduino チュートリアル
  5. Python 3からArduino UNOを制御 – シリアル通信でLED点滅デモ
  6. Arduino Nanoと128x64 OLEDで実行するセルラーオートマトン「ライフゲーム」
  7. Arduino NanoとRDA5807Mで作るコンパクトFMラジオ
  8. ArduinoとTEA5767で作る高性能FMラジオ受信機
  9. ArduinoとGoogleスプレッドシート連携 リアルタイムRFID勤怠管理システム
  10. Arduino用絶縁アナログ入力回路の設計:LM331 V-F変換+フォトカプラでノイズ耐性を確保
  11. C言語の入出力マスター:標準関数とファイル操作