- 記事公開日
カード自動配り&シャッフラー装置
プレイする人数に合わせて、カードを自動で振り分ける装置を作りました。
スイッチをONするとテーブルが回転し、カードを一枚ずつ等間隔に排出します。
また、[ランダム振り分けモード]に設定することで、ディールシャッフルのような混ぜ方をすることができます。
※ピカチュウの人形は、ローラーとカードを密着させるための重りです。
装置構成
この装置の肝は「確実にカード一枚を排出できるか?」にかかっています。
摩擦によってカードがくっついて2枚続けて排出されてしまったり、モーターに取り付けたローラーがカードをうまく噛んでくれずにカードが排出されないタイミングが一度でも起きてしまうと、カード配り装置として意味を成しません。
カードフィーダー部
カードフィーダー部には、上下2つのモーターを搭載しています。
- 下:ミニモーター標準ギヤボックス(8速)ギヤ比 ⇒ 8.5:1
- 上:ミニモーター薄型ギアボックス(2速)ギヤ比 ⇒ 71.4:1
カードホルダーの下にあるモーターが、カードを前方に送り出します。
カード排出のタイミングになると、このモーターが回転し、カード一枚分の高さしかないゲートを通って、一枚だけが送り出されます。
確実にカードを送り出せたかどうかは光センサによって検知しています。
光センサの上にカードが覆いかぶさると、光センサが反応し、カード送りモーターはストップします。
上側のモーターは、カードを完全に外に押し出すためのもので、常に回転しています。
このモーターがないと、下のモーターとゲートのところで送り出しが止まってしまいます。
カードの押し出しについては、下記の過去記事が参考になると思います↓
回転テーブル部
カードを一枚排出すると、次のカードを排出する位置までテーブルが回転します。
シングルギヤボックス(4速タイプ)を[ギヤ比]344.2:1で使用しています。
配線図
テーブルを回転させるためのモーターは、結構な重量物を抱えているため、大きなトルクが必要です。
マイコンから供給する電流ではトルクが足りないので、外部電源が利用できるモータードライバーを使用し、単三電池2個をこのモーターだけの電源に使用しています。
モーターの動作はPWM制御を行っているので、Arduinoは「波線」が付いているピンを使用します。
光センサは、ボリュームで反応する光量を調整して「1」「0」の信号を出力できるモジュールを使用しています。
使用部品
主にタミヤの楽しい工作シリーズで構成しています。
その他、マイコンやモータードライバ・光センサなどの電子パーツが必要です。
タミヤの楽しい工作シリーズ
- 【No.245】ミニモーター薄型ギアボックス(2速)ー Amazon
- 【No.188】ミニモーター標準ギヤボックス(8速)ー Amazon
- 【No.167】 シングルギヤボックス 4速タイプ ー Amazon
- 【No.172】 ユニバーサルプレートL(210×160mm)- Amazon
- 【No.157】ユニバーサルプレート(2枚セット)ー Amazon
- 【No.212】 クロスユニバーサルアームセット - Amazon
- その他のキットに含まれるスペーサーやL字アングル等
その他
プログラム
// 光センサ(CDS)からの信号を受け取るピン
int csdPin = 4;
// カード送りモーター
int motorShotPin1L = 5;
int motorShotPin1R = 6;
// カード排出モーター
int motorShotPin2L = 10;
int motorShotPin2R = 11;
// テーブル回転モーター
int motorShotPin3L = 3;
int motorShotPin3R = 9;
// モーター速度(0が停止・255が最大)
int motorSpeed = 255;
// テーブルの現在ポジション
int pos = 1;
// 次のポジション
int nextPos = 1;
// 回転する時間
int move = 0;
// 各モーターの回転開始タイミングを設定するためのフラグ
int flag = 0;
// モード変更(1:順番にカードを配るモード、2:ランダムにカードを配るシャッフルモード)
int mode = 1;
// カードを配る人数
int maxcard = 4;
// -------------------------------------------
// SETUP
// -------------------------------------------
void setup() {
// シリアルデータの通信速度
Serial.begin(9600);
// 光センサ
pinMode(csdPin, INPUT);
// 各モーター
pinMode(motorShotPin1L, OUTPUT);
pinMode(motorShotPin1R, OUTPUT);
pinMode(motorShotPin2L, OUTPUT);
pinMode(motorShotPin2R, OUTPUT);
pinMode(motorShotPin3L, OUTPUT);
pinMode(motorShotPin3R, OUTPUT);
}
// -------------------------------------------
// LOOP
// -------------------------------------------
void loop() {
// カード排出モーターをON
analogWrite(motorShotPin2L, motorSpeed);
analogWrite(motorShotPin2R, 0);
// 光センサが暗くなったとき
if (digitalRead(csdPin)) {
// テーブル回転モーターをRESET
digitalWrite(motorShotPin3L, LOW);
digitalWrite(motorShotPin3R, LOW);
delay(300);
// カード送りモーターをOFF
analogWrite(motorShotPin1L, 0);
analogWrite(motorShotPin1R, 0);
//delay(300);
// カードを送り出して光センサが暗を判定したタイミングでイベント開始
flag = 1;
// CDSが明るい状態のとき
} else {
// イベント開始フラグがONになっていたら
if (flag) {
// カード送りモーターをOFF
analogWrite(motorShotPin1L, 0);
analogWrite(motorShotPin1R, 0);
delay(300);
// 順番にカードを配るモード
if (mode == 1) {
nextPos = nextPos + 1;
if(nextPos > maxcard) {
// テーブルを初期位置に戻す
digitalWrite(motorShotPin3L, LOW);
digitalWrite(motorShotPin3R, HIGH);
delay(520);
// テーブル回転モーターをRESET
//digitalWrite(motorShotPin3L, LOW);
//digitalWrite(motorShotPin3R, LOW);
//delay(300);
// テーブルポジションを初期値に戻す
nextPos = 1;
} else {
// テーブルの移動時間を細かく指定可能
switch (nextPos) {
case 2:
move = 180;
break;
case 3:
move = 180;
break;
case 4:
move = 180;
break;
}
digitalWrite(motorShotPin3L, HIGH);
digitalWrite(motorShotPin3R, LOW);
delay(move);
}
// ランダムにカードを配るシャッフルモード)
} else {
while(1) {
nextPos = random(1,maxcard);
if (nextPos != pos) {
break;
}
}
// 現在のポジションより大きいポジションまで回転するとき(差分を正転)
if (nextPos > pos) {
move = (nextPos - pos) * 180;
digitalWrite(motorShotPin3L, HIGH);
digitalWrite(motorShotPin3R, LOW);
delay(move);
}
// 現在のポジションより小さいポジションまで回転するとき(差分を逆転)
else if (nextPos < pos) {
move = (pos - nextPos) * 180;
digitalWrite(motorShotPin3L, LOW);
digitalWrite(motorShotPin3R, HIGH);
delay(move);
}
}
Serial.print("nextPos: ");
Serial.println(nextPos);
Serial.print("pos: ");
Serial.println(pos);
Serial.println("");
// 回転が終わったら現在のポジションとして設定
pos = nextPos;
// テーブル回転モーターをRESET
digitalWrite(motorShotPin3L, LOW);
digitalWrite(motorShotPin3R, LOW);
delay(300);
flag = 0;
}
}
if (!flag) {
// カード送りモーターをON
analogWrite(motorShotPin1L, motorSpeed);
analogWrite(motorShotPin1R, 0);
}
}
テーブルの回転に使用しているモーターは、DCモーターです。
カードを排出する位置までのテーブル回転は、時間(delay関数)で管理しています。
多少のズレは覚悟していましたが、思ったよりも正確にポジションを維持してくれます。
本来であれば、「ステッピングモーター」や「サーボモーター」を使うのが適切ですが、今回はできるだけタミヤの楽しい工作シリーズを使って作りたかったので・・・