週刊 パタパタをArduinoで動かしてみた

電子工作の素人でエアラインファンの人が、ジャンク市で手に入れたかつて空港で使われていた行先表示板「パタパタ」を動かす妄想にとらわれてArduinoやステッピングモーターにお小遣いをつぎ込んでいく趣味の記録です。原則土曜日更新。

カテゴリ: Arduino

このところエイプリルフールのGoogleのパタパタネタとか、大人の科学のパタパタ電波時計とかでお茶を濁してきましたが、とりあえず空港のパタパタも一段落させたいと思い「空港のパタパタがスイッチを押すと動く」というものを作りました。

前回は、Arduinoにケースをつけて、パタパタと一体化させましたが、それにプラスして、スイッチを複数つけてパタパタを自在に(?)操作できるようにしています。

スイッチを作るにあたっては、こことかここを参考にしました。

こんな外観をしています。
58


Arduinoから引っ張ってきている3Vの電気を並列につなげて、それぞれGNDに逃がす途中でArduinoのDIGITAL INに値を返すようにしています(という書き方でいいのかな?)
スイッチは4つで、それぞれ下記のような動きをするように設定しています。

46

・タクトスイッチ(左):押し続けている間、フリップが動く。
・タクトスイッチ(右):フリップが一周して、一つ先のフリップで止まる
・トグルスイッチ(左):スイッチOnの時の間、フリップが動く。(タクト左と同じプログラム)
・トグルスイッチ(右):トグルスイッチ(左)と同じ

プログラムはこんな感じです。相当適当なので、何の参考にもならないと思いますが…

#include
#include // ピン定義。
#define PIN_SPI_MOSI 11
#define PIN_SPI_MISO 12
#define PIN_SPI_SCK 13
#define PIN_SPI_SS 10

void setup()
{ delay(2000); // ピン設定。
pinMode(2,INPUT) ;
pinMode(3,INPUT) ;
pinMode(4,INPUT) ;
pinMode(5,INPUT) ;
pinMode(PIN_SPI_MOSI, OUTPUT);
pinMode(PIN_SPI_MISO, INPUT);
pinMode(PIN_SPI_SCK, OUTPUT);
pinMode(PIN_SPI_SS, OUTPUT);
digitalWrite(PIN_SPI_SS, HIGH);
//SPI通信開始
SPI.begin();
// シリアル通信。
Serial.begin(9600);

SPI.setDataMode(SPI_MODE3);//SCKの立ち上がりでテータを送受信&アイドル時はpinをHIGHに設定 SPI.setBitOrder(MSBFIRST);//MSBから送信

//前のコマンドの引数を消去
L6470_send(0x00);//nop
L6470_send(0x00);
L6470_send(0x00);
L6470_send(0x00);
//デバイスリセットコマンド
L6470_send(0xc0);//ResetRevice
L6470_setup();//L6470を設定
}

void loop(){
//以下に動きを書くとその通りに動く
int i = 0; //一度押すと、61枚送るスイッチ
if (digitalRead(2) == HIGH) { //2番ピンとつながってるスイッチがonになったら下記を実行
while(i < 61){//ここの数字ぶんパタパタする。
L6470_send(0x51);//Run(DIR,SPD),0x51:正転,0x50:逆転L6470_send(0x00);//SPD値(20bit)ここから下の3行でスピードの20bitを表現しているらしい
L6470_send(0x20);//ここの数字を下げると遅くなる
L6470_send(0x00); delay(133);//この数字の時間だけ動作する i++;
}
L6470_send(0xB8);//HradStop_急停止
}

//押している間、パタパタする
if (digitalRead(3) == HIGH) {//3番ピンとつながってるスイッチがonになったら下記を実行
while(i < 1){
L6470_send(0x51);//Run(DIR,SPD),0x51:正転,0x50:逆転
L6470_send(0x00);//SPD値(20bit)ここから下の3行でスピードの20bitを表現しているらしい
L6470_send(0x20);//ここの数字を下げると遅くなる
L6470_send(0x00); delay(133);//この数字の時間だけ動作する i++; }
L6470_send(0xB8);//HradStop_急停止 }

//押している間、パタパタする
if (digitalRead(4) == HIGH) {//4番ピンとつながってるスイッチがonになったら下記を実行
while(i < 1){ L6470_send(0x51);//Run(DIR,SPD),0x51:正転,0x50:逆転 
L6470_send(0x00);//SPD値(20bit)ここから下の3行でスピードの20bitを表現しているらしい
L6470_send(0x20);//ここの数字を下げると遅くなる
L6470_send(0x00); delay(133);//この数字の時間だけ動作する i++; }
L6470_send(0xB8);//HradStop_急停止}

//押している間、パタパタする
if (digitalRead(5) == HIGH) {//5番ピンとつながってるスイッチがonになったら下記を実行
while(i < 1){ L6470_send(0x51);//Run(DIR,SPD),0x51:正転,0x50:逆転 
L6470_send(0x00);//SPD値(20bit)ここから下の3行でスピードの20bitを表現しているらしい
L6470_send(0x20);//ここの数字を下げると遅くなる
L6470_send(0x00); delay(133);//この数字の時間だけ動作する i++; }
L6470_send(0xB8);//HradStop_急停止
 }
//ここまで

}

void L6470_send(unsigned char add_or_val)
{ digitalWrite(PIN_SPI_SS, LOW); SPI.transfer(add_or_val); // アドレスもしくはデータ送信。
digitalWrite(PIN_SPI_SS, HIGH); } void L6470_setup(){ //最大回転スピード
L6470_send(0x07);//レジスタアドレス L6470_send(0x00);//値(10bit),デフォルト0x41
L6470_send(0x30); //モータ停止中の電圧設定 L6470_send(0x09);//レジスタアドレス
L6470_send(0x20);//値(8bit),デフォルト0x29
//モータ定速回転時の電圧設定
L6470_send(0x0a);//レジスタアドレス
L6470_send(0x40);//値(8bit),デフォルト0x29
//加速中の電圧設定
L6470_send(0x0b);//レジスタアドレス
L6470_send(0x40);//値(8bit),デフォルト0x29
//減速中の電圧設定
L6470_send(0x0c);//レジスタアドレス
L6470_send(0x40);//値(8bit),デフォルト0x29
//フ ル ス テ ッ プ,ハ ー フ ス テ ッ プ,1/4, 1/8,…,1/128 ステップの設定
L6470_send(0x16);//レジスタアドレス
L6470_send(0x00);//値(8bit)
}


回路図的な物はこんな感じ。回路図を描くツール、Fritzingを初めて使ってみました。
130504_bread


これで、とりあえずですがパタパタを動かして楽しむことはできるようになりました。





課題は

・スイッチを押し続けるとフリップを送り続けてしまうが、「押しつづけていても1枚だけめくって止まる」という仕組みを作りたい

・正確に1周するようにしたい(現在は時間で歯車を動かしているため、どうしてもずれが生じる)

・12Vの電源アダプタが2個必要なのがかっこわるい

・大人の科学の電子時計みたいに、時を刻むパタパタにしてもいいかも

・見た目にブレッドボードだったり、配線がぐちゃぐちゃでかっこわるいので、もう少しきれいにしたい

などなど。山積みです。
最後のやつ以外は、独力では解決できないかもしれませんが、またいろいろと調べつつ、地味にやって行こうと思います。

 次回は外観を少しきれいにしてみます。

   

ようやくステッピングモーターを制御できるようになり、
パタパタの歯車にあてると回るようになったので、
元のモーターがついていたネジ穴に、新しいステッピングモーターを取り付けて、
ハードとしての完成形を作ってみます。

34
見づらいですが、ステッピングモーターに開いているネジ穴とパタパタのネジ穴の位置が合わず、一カ所しか止められませんでした(写真左のほう)
まぁ、一応固定されているのでよしとしましょう。

10

裏面から見るとこんな感じ。
L6470の基盤は別売りののネジでモーターの裏にぴったりと止められます。
だいぶモノっぽくなってきましたが、Arduinoの基盤がむき出しです。
これだと飾るのにちょっと気を使いそうです。

 そこで、Arduinoのケースを買うことにしました。

純正のケースもあるようですが、見た目がいまいちかっこわるいです。


もう少し探してみると、アクリル板をレーザーカッターで切って作られたケースが売られていました。
ProjectBox for Arduino (グレースモーク) [エレクトロニクス]
 
こちらのほうがなんかかっこいい感じです。価格もこっちの方が安いし。
写真にある黒っぽい半透明の他、透明色やカラーの物もあるようです。
Emerge+という、レーザーカッターの工房で製作しているケースをスイッチサイエンスさんで委託販売されているのですが、Amazonでも販売されてるようです。ややこしい。

ということで、こちらを購入してみました。
53
パーツは合計6個で、保護のために紙が貼られていました。

53
組み立てるのは簡単です。付属のアクリルねじで固定していきます。

24
パタパタにもともとついていたステッピングモーターは大きいので、空いているスペースにネジ止めすることができました。こちらもモーターと同じく1カ所だけのネジ止めなので、少々不安定ですが…

00
裏からみるとこんな感じ。配線がまだ長くて見栄えが悪いですね。これはそのうち…

11
16
ということで、パタパタにArduinoとステッピングモーターをきれいに組み込むことができました。

上の写真ではArduinoからブレッドボードに配線が延びていて、スイッチにつながっていますが、このへんはまた後日。
スイッチを取り付けてボタンを押すとパタパタできるようにしていきます。
この間のGoogleのパタパタ文字入力と同じような感じになると思います。


  

モーターも買い直し、歯車も購入し、ここまでで実にパタパタ本体(2万)の半分くらいのお金をかけてきましたが、ようやく部品としては整ってきた感じです。
23

とりあえず、このサイトに書いてあるやり方をそのままやってみます。

サイトにある通り、L6470のドライバーとArduinoをこのようにつなぎます。

ドライバとモーターの配線は、下の写真のような感じです。上から、赤、緑、青、黄。

04


ドライバの電源は、写真上の赤い線2本から供給します。12Vで、1Aか2Aのものが良いようです。
できれば2Aのほうが余裕があって良いようです。
私は、あまり使っていない外付けハードディスクのACアダプタがたまたまその出力だったので、それを使うことにしました。

サンプルコードをArduinoのアプリに入力して、「マイコンボードに書き込む」を押すと…


おお、回る回る。
スピードや急停止などもコマンドで結構簡単に制御できるんですね。

このサンプルコードは、右まわり、左回り、ゆっくりなど、いろいろな回り方をするようにできています。パタパタを動かすにはちょっと向かないので、少しだけコードを改造して、単純に一定時間まわるようにしました。こんな感じ。

#include <Arduino.h>
#include <SPI.h>

// ピン定義。
#define PIN_SPI_MOSI 11
#define PIN_SPI_MISO 12
#define PIN_SPI_SCK 13
#define PIN_SPI_SS 10

void setup()
{
delay(2000);
// ピン設定。
pinMode(PIN_SPI_MOSI, OUTPUT);
pinMode(PIN_SPI_MISO, INPUT);
pinMode(PIN_SPI_SCK, OUTPUT);
pinMode(PIN_SPI_SS, OUTPUT);
digitalWrite(PIN_SPI_SS, HIGH);
//SPI通信開始
SPI.begin();

// シリアル通信。
Serial.begin(9600);
 
SPI.setDataMode(SPI_MODE3);//SCKの立ち上がりでテータを送受信&アイドル時はpinをHIGHに設定
SPI.setBitOrder(MSBFIRST);//MSBから送信

//前のコマンドの引数を消去
L6470_send(0x00);//nop
L6470_send(0x00);
L6470_send(0x00);
L6470_send(0x00);
//デバイスリセットコマンド
L6470_send(0xc0);//ResetRevice

L6470_setup();//L6470を設定


}

int i = 0;

void loop(){
  
  //以下に動きを書くとその通りに動く

while(i < 61 ){//連続運転 全部で61枚を回転させると、一周+1になる
L6470_send(0x50);//Run(DIR,SPD),0x51:正転,0x50:逆転 
L6470_send(0x00);//SPD値(20bit)いじらない
L6470_send(0x20);//ここの数字を下げると遅くなる
L6470_send(0x00);//いじらない
delay(133);//この数字の時間だけ動作する
L6470_send(0xB8);//HradStop_急停止
i++;
}
 
}

void L6470_send(unsigned char add_or_val){
digitalWrite(PIN_SPI_SS, LOW); 
SPI.transfer(add_or_val); // アドレスもしくはデータ送信。
digitalWrite(PIN_SPI_SS, HIGH); 
}

void L6470_setup(){
//最大回転スピード
L6470_send(0x07);//レジスタアドレス
L6470_send(0x00);//値(10bit),デフォルト0x41
L6470_send(0x30);
//モータ停止中の電圧設定
L6470_send(0x09);//レジスタアドレス
L6470_send(0x20);//値(8bit),デフォルト0x29
//モータ定速回転時の電圧設定
L6470_send(0x0a);//レジスタアドレス
L6470_send(0x40);//値(8bit),デフォルト0x29
//加速中の電圧設定
L6470_send(0x0b);//レジスタアドレス
L6470_send(0x40);//値(8bit),デフォルト0x29
//減速中の電圧設定
L6470_send(0x0c);//レジスタアドレス
L6470_send(0x40);//値(8bit),デフォルト0x29

//フ ル ス テ ッ プ,ハ ー フ ス テ ッ プ,1/4, 1/8,…,1/128 ステップの設定
L6470_send(0x16);//レジスタアドレス
L6470_send(0x00);//値(8bit)



さっそく、歯車を本体に当ててみると…


おお、パタパタしてる!パワーは十分なようです。

これで基本的な部分は実現したことになります。意外と簡単です。
次は、プログラム部分を勉強して、パタパタをもう少し自在に動かしたいものです。
その辺を考えていきます。
 

前回までで、とりあえずパタパタを動かすにはステッピングモーターとArduinoがあればなんとかなりそうだ、ということがわかりました。
ということで、購入してみました。


ステッピングモータSPG20-1362

その他、ダイヤルに使う抵抗などを購入。

で、組みたててみました!
00
どーん。

57

歯車は、もともとのモーターについていたものを取り付けました。
軸の太さが違ったので、東急ハンズでアルミの筒を買ってきてかさ上げ。

プログラムは、こちらのサイトのコードをコピペ。



いい感じに回っています。ではパタパタの歯車に合わせてみましょう。

17


うーむ…
やはり210円のモーターではパワー不足なのか、パタパタの歯車に当てると
回転がぴたっと止まってしまいました…

arduinoのコードが紹介されているサイトでも、「ちゃんとドライバICを使うべき」との記載が。
ドライバICって何だ??





↑このページのトップヘ