noteで公開しているトイドローンをハッキングft. Arduino - 気軽にドローンを自動操縦という記事の関連です。
目標:
1台の小型ドローンをArduinoに書き込んだプログラムでペアリング、キャリブレーションに加え、飛行〜着陸の一連の動作をさせる。
使用した部品
LTC1660CN
Arduino MEGA
luxon H36(小型のトイドローン)
関連記事
LTC1660CNをArduinoで動かす
LTC1660CN (軍鶏乃記録)2012.6.18
A Library for LTC1665/LTC1660 (Kerry D. Wong)2010.5.2
アナログ電圧の出力
今回はPWMではなくDAコンバータを用います。
その理由や具体的な方法は以下の記事にまとめていますので、ご覧ください。
関連記事:LTC1660CNをArduinoで動かす
コントローラとArduinoを繋げる。
こちらの記事とこの記事のようにコントローラをDAコンバータ介してArduinoに繋げます。
ペアリング - ドローンとコントローラの接続
ドローンとコントローラを接続するためには、(今回使用したドローンでは)左スロットルを上に動かした後に下に戻します。この操作を「ペアリング」と読んでいます。
今回使用しているドローンのコントローラは、
- スロットルが下にある時に電圧が最大に、
- スロットルが上にある時に電圧が最小になります。
それを元にペアリングのコードを書きました。
void paring(){
output(0,1023); // 左スロットルを下に下げておく
changeOutput(0,1); // 段階的に左スロットルを上まであげる
delay(400); // 0.4秒待つ
changeOutput(0,1023); // 段階的に左スロットルを下まで下げる
}
〜解読〜
output()
は関連記事の定義を元にして、少し変えて使ってあります。
void output(long chn, long val){
long t = chn << 12;
t = t | val << 2;
digitalWrite(pinCSLD, LOW);
for (long i = 15; i >= 0; i--)
{
long b = (t >> i) & 1;
digitalWrite(pinIN, b);
digitalWrite(pinSCK, HIGH);
digitalWrite(pinSCK, LOW);
}
digitalWrite(pinCSLD, HIGH);
}
// 左スロットルが0番目、右スロットルの上下が1番目、左右が2番目として配列を用いる。
int deg[] = {1023,512,512}; // 複数のチャンネルの出力に対応できるように配列を用意
long chn[] = {1,2,3};
void output(int chnNum, long val)
{
long t = chn[chnNum] << 12;
t = t | val << 2;
digitalWrite(pinCSLD, LOW);
for (long i = 15; i >= 0; i--)
{
long b = (t >> i) & 1;
digitalWrite(pinIN, b);
digitalWrite(pinSCK, HIGH);
digitalWrite(pinSCK, LOW);
}
digitalWrite(pinCSLD, HIGH);
deg[chnNum] = val;
}
また、スロットルを手で動かす時は電圧が連続に変動するはずです。
プログラムから動かす際にも、その状況に近づけるために連続に動かします。
void changeOutput(){
int postVal = deg[chnNum];
int drctn = 1;
if(val<postVal){drctn = -1;} // 上がるか下がるか調べる
for (int i = 0; i < abs(val-postVal); i+=2)
{
output(chnNum, long(postVal+drctn*i));
delay(1);
}
}
キャリブレーション - ジャイロの初期化
ドローンの平衡感覚を整えてあげる必要があります。
そのためには左スロットルが下にある状態で、右のスロットルを左下に抑えて少し保ちます。
この状況をプログラムで再現します。
void calib(){
output(0,1023); // 左スロットルを下に抑える
changeOutput(1,1023); // 右スロットルを左に倒す
changeOutput(2,1023); // 右スロットルを下に倒す
delay(1000); // 1秒待つ
}
飛んでから着地
これはほぼparing()
と同じです。というか待ち時間を伸ばしただけです。
void flight(){
output(0,1023); // 左スロットルを下に下げておく
changeOutput(0,1); // 段階的に左スロットルを上まであげる
delay(3000); // 3秒待つ
changeOutput(0,1023); // 段階的に左スロットルを下まで下げる
}
ここまででひとまず1つの(やっすい)手動でしか動かせない仕様の小型ドローンをArduinoに書き込んだプログラムで飛ばすことができるようになりました!