理系的な戯れ

理工学系とくにロボットやドローンに関する計算・プログラミング等の話題を扱って、そのようなことに興味がある人たちのお役に立てればと思っております。

S.BUSプロトコル

f:id:kouhei_ito:20200317214601p:plain

はじめに

こんにちは、こうへいです。

ドローンやロボコンやらで,ロボットを遠隔操作しようとしたり,自律化しようとすると S.BUS信号のデコードやエンコードの必要が出てきて,それなりに調べたり実装したりするのに時間がかかります.

今回はS.BUSについて整理して残しておこうと思います.

S.BUSプロトコルとは

ラジコンプロポメーカーの双葉さんが開発した、ラジコン用の通信プロトコルです。 シリアル通信の一種ですが、PCやマイコンで扱おうとすると少し癖があるので注意です。

最近はマルチコプタのラジコンが大流行で、たいていのフライトコントローラがS.BUSをサポートしています。

フライトコントローラにボードPCを繋いだ離して自律型の飛行ロボットにする場合などに、 S.BUSのエンコードがしたくなったのでいろいろ調べました。

S.BUSでぐぐるとホイホイ堂blogさんにたどり着いて、ほとんどのことはわかります。

www.hoihoido.com

改めて、自分用メモも兼ねて以下にS.BUSプロトコルを書いておきます。

S.BUSプロトコル仕様

ホイホイ堂blogさんのところから引用されているFutaba S-BUS controlled by mbed から少し変更を加えて転載させてもらうと、次のような感じになる。

os.mbed.com

通信仕様

  • データ全体の長さ:25 Byte
  • 送信周期:14ms(analog mode) or 7ms(highspeed mode)
  • データの構成:1スタートビット、8データビット、1偶数(Even)パリティビット、2ストップビット[8E2]
  • 速度:100,000 bps
  • 特記事項:データは通常のシリアル信号に対して反転している。

データ全体の構成

[startbyte] [data1] [data2] .... [data22] [flags][endbyte]

  • startbyte = 0xF0
  • data 1-22 = [ch1, 11bit][ch2, 11bit] .... [ch16, 11bit]
  • flags = bit7 = ch17 = digital channel (0x80)
  • bit6 = ch18 = digital channel (0x40)
  • bit5 = Frame lost, equivalent red LED on receiver (0x20)
  • bit4 = failsafe activated (0x10)
  • bit3 = n/a
  • bit2 = n/a
  • bit1 = n/a
  • bit0 = n/a
  • endbyte = 0x00

特記事項が注意点で、マイコンやPCのUARTで読み書きする場合は、信号を反転する必要があります。 信号の反転にはNOT素子やトランジスタを使用します。

以上ではわかりにくいので全データのビット構成を、Excelを使って図示してみました。

f:id:kouhei_ito:20200317073239p:plain
S.BUS信号

反転回路

S.BUS信号は通常のシリアル通信からみると信号のHighとLowがひっくり返っているので、 マイコン等で信号を読み取ったり、逆にS.BUSサーボを動かすために信号を反転する必要があります。

そのためには標準ロジックのInvaterを使ったり、下図のようなトランジスタで反転回路を作ります。

f:id:kouhei_ito:20200317081332p:plain
トランジスタによる反転回路

f:id:kouhei_ito:20200317115322p:plain
反転結果
上図はその辺に転がっていた2SC1815と抵抗R1:3.3kΩ R2:100Ωで実験した結果です.

黄色が反転する前のマイコンが作った入力信号,水色がトランジスタインバータ回路で反転した結果です.

今のところ,ちゃんと分析してないのですが,少し無駄時間があるのと,なまっていますが,これでもサーボは動きました. 水色は黄色が立ち下がった時に,何やらひげが出てるのですが,その後遅れて立ち上がるところが気になるのですが, 今日は深入りしないことににします.適当に作ったトランジスタ回路だとこんなものなのかなあ. (何か忘れている・・・)

akizukidenshi.com

シリアル通信とS.BUS信号の読解

ドローンやロボット制御などでS.BUSを使用したい時に,シリアル通信をのビット列を見ることができれば楽なのですが, そういう環境が無い場合が多いと思います. せめてオシロスコープを繋げて信号を見て確かめることができればと思いますね.

その際に,信号を読めなければならないので,シリアル通信について復習して,S.BUS信号を読んでみたいと思います

シリアル通信について調べてみると大変良い記事に出会いましたので紹介します.

lab.fujiele.co.jp

参考記事で明らかなように,シリアル通信は数ビットのデータ1パックとして,順番に送り出していく方式です. 1パックの中身はおおむね「スタートビット,データビット,パリティビット,ストップビット」で構成されています. それぞれのビットが0なのか1なのか,それらの長さは設定できます.

上記のS.BUSの通信仕様にもありますが,省略して8E2のように書かれることが多いようです. これは,「データは8ビット長で,パリティビットは偶数,ストップビット(値は1)は2ビット長ですよ」という意味です.

パリティビットが偶数の場合は,データビットの部分で1の数が偶数の場合は0になります.

さて,以下はS.BUS受信機の出力をデジタルオシロで取り込みオシロの画面をキャプチャしたものです. 100000bpsと言う通信速度はシリアル通信では珍しいのですが,オシロで見るときは1devを10μsにすると区切りが良くて,見やすいです.

f:id:kouhei_ito:20200317104246p:plain
反転したS.BUS信号のビット列

1パック分の信号について分析してみます.以下の説明は信号を反転させたものについてです.

上の画像はS.BUS信号の最初の1バイト目をとらえたものです.

図を見ると,スタートビットは0です.続いてデータビットがあり,それらのビット列は11110000だとわかります. つづいてパリティビットは0でデータビットの1の数は偶数なのでつじつまが合っています. 最後に,ストップビットですが設定どおり2ビットの1が並んでいます.

S.BUS信号の最初の1バイト目は0xF0が送られることになっていますので,この読解は仕様と一致しています.

間違いやすいので強調したいのですが,シリアル通信のビット列は1バイトのデータの最上位の桁から送られてきます.

我々は最下位ビットから考えがちで,オシロ等でデータを検証するときに, 逆に読んでしまって手動デコードの結果がおかしなことになるので要注意です.

S.BUSとS.BUS2

Twitterでつぶやいたのですが,S.BUSにはS.BUS2という規格があり,受信機から出ている信号を比較してみました. どちらも15ms間隔でシリアル信号を出しています.S.BUS2はそれに加えて60msにテレメトリ関連と思われる信号を出しているということがわかりました.

f:id:kouhei_ito:20200317111918p:plain
S.BUSとS.BUS2の比較

実装の参考

今回はArduinoUNOでS.BUSサーボを動かしたかったので,適当なコードをGitHubで探したのが以下です.感謝です.

github.com

探すとたくさんありますのでお好きなものを活用されたらいいと思います.

やってみて注意ですが,ArduinoUNOで動かしている例はあまりありません. 大体Megaが多いですが,どうやらUNOはUARTが1つしかないのでS.BUSに占有されて,デバグ用のシリアル通信ができなくなるせいだと思いました. UNOでもソースでポートをserial1等に指定されているところをserialに書き換えるだけで,動くと考えられます.

上記のソースもserialに書き換えると旨く動きました.

おわりに

今回は,ドローンやロボット制御で使いたくなるS.BUSについて取り扱ってみました.

自分でロボットを動かすときに毎回毎回調べなおすのも大変ですので,一度まとめておきたくて, すっきりしました.

S.BUS2についてはまだ未確認です.情報もあまりないような気がします.いつかは触れてみたいと思います.

以下はS.BUSにも対応したオープンソースの送信機でJumperのT16です。 電波モジュールが取り外せるので、独自の送信機を作れます。おすすめです。