Cafe Cappuccino

かふぇ・かぷちの/新幻想的独り言4 ねふぁの気まぐれな独り言

ちょっとした時間に気軽に子供と遊べるおもちゃがないかと思い、Amazonでそこそこ評価がよかったマリオのエアホッケーを買ってみた。

スーパーマリオ ストライクエアホッケーW's(ダブルス)
スーパーマリオ ストライクエアホッケーW’s(ダブルス)

まぁまぁ面白いのだが、まだ小さい子供は騒がしく遊ぶ方が好きなので、最初は点数を付けてゆっくり遊んでいてもすぐに複数のパックを投入して点数を気にせずどんどん落としては戻してを繰り返す様になり飽きてしまう結果になる。

Arduinoで使えるモジュールの一つにレーザーセンサーがあり、気になっていたものの使いどころがなかったため放置していたが、エアホッケーのパック検知に使えそうなのでエアホッケーの得点カウンターを作ってみる事にした。得点表示にはOLEDディスプレイを使う。勝ち負けをグラフィカル表示してもまた楽しさが増しそうである。

使用するのはArduinoで使える5V駆動のレーザーとセンサーモジュール。

DSC05146

レーザー発信器側は5Vを給電するだけ、受光器はVCC/GNDとシグナル線一本をArduinoにつなぐだけ。loop()内で状態をチェックし、シグナルに変化があった場合にカウンタを上げるだけの単純コードで十分動く。

エアホッケーのゴール付近、パックが通過するあたりにレーザーモジュールを取り付ける。こんなモジュールでもかなりまぶしいので、少し奥に配置する。レーザーと受光器は向きを調整しながらホットボンドで固定。

DSC05126

DSC05127

DSC05128

これを両側に取り付ける。

DSC05129

赤く光ってかっこいい。

DSC05139

レーザー発振器のモジュールはKY-008というモデルを中国から安く購入したが、最初うまく動かなかった。単純にS端子に5V、-端子にGNDを接続するだけのはずなのに全くレーザーが点灯しない。情報を検索しているとある掲示板で「中国から購入したが、端子が逆になっていた」の書き込みが。SをGND、-を5Vと接続すると動作したらしい。

matamata

いくら中華製でもプリント基板の+と-表記は逆にしないだろう。

と思いながら接続をひっくり返すと・・・ 動いた。相変わらず中華製品はあなどれない。

エアホッケーはファンで空気を送り込み風圧でパックを浮かすのだが、モーターがおもちゃで良くあるミニ四駆に入っているタイプのモーターだった為、改造ついでにミニ四駆用に売られているパワーアップ系のモーターに差し替えてみた。

DSC05130

DSC05131

結果風圧は上がったが、騒音も上がってしまった。将来ファンと電池もPCケース用の強力静音ファンに変えるかもしれない。

使う電子パーツはArduino本体、センサー2組とOLEDディスプレイ、電源用の電池のみの単純構成。ArduinoはArduino nanoと小さいブレッドボードを使ってお手軽工作にする。こうしておけばArduino nanoのプログラム書き換えもブレッドボードから抜いてさくっと行える。電池は9V電池とホームセンターで購入した9V電池ホルダーを使用。

DSC05132

 電源オフオン用のスイッチを取り付ける為、9V電池のケーブルを途中でカットし、スイッチ用に延長する。

DSC05133

Arduino nanoと電池ホルダー、ケーブルもろもろは両面テープと結束バンドと普通のテープで簡単固定。

DSC05135

スイッチは本体スイッチ横にドリルとルーターとヤスリを使って穴を空け取り付け。

DSC05136

DSC05137

黒い小さいスイッチが得点カウンタArduino用の電源スイッチ。

最後にOLEDディスプレイを取り付け。使用したモジュールは白色OLED I2C接続128×64のディスプレイ。本体中央端に穴を空け、ケーブルを通す。

DSC05138

ディスプレイのホルダーは3Dプリンターでさくっと作成。最近はほぼ一発で欲しい形状の物が作れるようになってきた。

DSC05140

DSC05141

両面テープでホッケー台端に取り付けたら配線を綺麗にしてArduino nanoにプログラムを書き込んで完成!

DSC05142

DSC05143

とりあえず得点と顔文字を表示するだけのもの。Hockeyのスペルをミスっているのはご愛嬌。

DSC05144

最近は電子回路の知識が無くてもモジュールを繋いでちょこっとプログラムを書くだけでこれだけの物が作れるので凄い時代である。

配線はレーザー、センサー、OLEDのVCCとGNDをArduinoの5VとGNDに接続、センサーのシグナルをD3とD4へ、OLEDのSDA/SCLをA4/A5へ接続するのみ。コードは以下の通り。ディスプレイのライブラリにはu8gを使用している。

(2015/11/26)得点表示を少し進化

ただ、欠点もありセンサーをゴール口近くにしたため防御のためマレット(手に持つやつ)がレーザーに触れてもカウントしてしまう。また、パックが少しゴールに入った状態で止めてもカウントしてしまう。センサーの位置や遮断時間である程度は回避出来そうだが、まぁ子供と遊ぶおもちゃなのでとりあえず良しとしよう。

#include <Wire.h>
#include<stdlib.h>
#include "U8glib.h"

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);  // I2C / TWI 

int DetectorA = 3,DetectorB = 4;
int lastflagA,lastflagB;
int countA = 0,countB=0;
char buff[32];
boolean checker;

void u8g_prepare(void) {
  u8g.setFont(u8g_font_6x10);
  u8g.setFontRefHeightExtendedText();
  u8g.setDefaultForegroundColor();
  u8g.setFontPosTop();
}

void draw(int page){
  u8g.firstPage();
  do {
    u8g_prepare();
    if (page == 0)
      clearpage();
    else if (page == 1)
      drawpage();

  } while( u8g.nextPage() );
}

void clearpage(){
  u8g.setColorIndex(1);
  u8g.drawBox( 0, 0, u8g.getWidth(), u8g.getHeight() );
}

void drawpage(){
  u8g.setColorIndex(1);
  u8g.setFont(u8g_font_6x10);
  u8g.drawStr(0,0,"Air Hockey!");
  if (countB < countA)
    u8g.drawStr(17,55,"(>_<)");
  else
    u8g.drawStr(17,55,"(^_^)");
  if (countA < countB)
    u8g.drawStr(86,55,"(>_<)");
  else
    u8g.drawStr(86,55,"(^_^)");
  u8g.setFont(u8g_font_10x20);
  u8g.setScale2x2();
  sprintf(buff,"%.2d",countB);
  u8g.drawStr(6,25,buff);
  sprintf(buff,"%.2d",countA);
  u8g.drawStr(40,25,buff);
  u8g.undoScale();
}

void setup() {
//  Serial.begin (9600);
  pinMode(DetectorA, INPUT);
  pinMode(DetectorB, INPUT);
  lastflagA = 0;
  lastflagB = 0;
  draw(0);
  delay(200);
  draw(1);
}

void loop() {
  checker = digitalRead(DetectorA);
  if (!checker){
    if (lastflagA == 0){
//      Serial.print("detectA ");
//      Serial.println(countA);
      countA++;
      draw(1);
    }
    lastflagA = 1;
  }else{
    lastflagA = 0;
  }
  checker = digitalRead(DetectorB);
  if (!checker){
    if (lastflagB == 0){
//      Serial.print("detectB ");
//      Serial.println(countB);
      countB++;
      draw(1);
    }
    lastflagB = 1;
  }else{
    lastflagB = 0;
  }
}

特定の点数に達したら勝敗をグラフィック表示したり、Arduinoにはmp3の再生モジュールなんてのもあるのでBGMを鳴らし、得点の状況により再生する音楽を変えたり音声ナレーションを付けても盛り上がりそうである。

Print Friendly, PDF & Email

コメントを残す

メールアドレスが公開されることはありません。

CAPTCHA


*

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください