工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

ArduinoNanoおよびI2COLEDディスプレイを備えたArduboyクローン

コンポーネントと消耗品

>
Arduino Nano R3
× 1
グラフィックOLED、128 x 64
× 1
ブザー
× 1
触覚スイッチ、上部作動
× 6
RGB拡散コモンカソード
× 1
抵抗221オーム
× 3
抵抗10kオーム
× 1

必要なツールとマシン

>
3Dプリンター(汎用)
はんだごて(汎用)

このプロジェクトについて

Arduboyは、クレジットカードサイズのミニチュアゲームシステムです。従来の8ビットゲームがインストールされており、オンラインで利用できるオープンソースゲームのライブラリから再プログラムできます。 Arduboyはオープンソースであるため、独自のゲームのコーディングと作成を学ぶことができます。元のバージョンは、ATmega32U4マイクロコントローラーと128x64ピクセルのシリアルOLEDディスプレイに基づいています。

以下に構造を示すコンソールは、Arduino NanoとI2CバージョンのOLEDディスプレイで構成されており、低価格で簡単に見つけることができます。必要なライブラリとコードは次の場所からダウンロードできます:

https://github.com/harbaum/Arduboy2

<図>

3Dプリンターをお持ちの場合は、コンソールがインストールされている可能性のあるボックスオプションの.STLファイルをダウンロードすることもできます。詳細なインストールガイドは、同じサイトで入手できます。 3.7vのリチウムイオンバッテリーを1つ搭載したArduinoNanoを搭載しており、非常にうまく機能します。

私はこのコンソールで多くのゲームをテストしましたが、そのすべてがうまく機能しています:

-ArduBreakout

-ピンボール

-シャドウランナー

-ヘビ

-VIRUS-LQP-79

--Nineteen43

その他多数...

<図>

概略図を以下に示します。

例として、ArduBreakoutゲームにコードを提示していますが、このバージョンのコンソールと互換性のあるArduboyのサイトで他のゲームをダウンロードできます。

コード

  • ArduBreakoutゲーム
ArduBreakoutゲーム Arduino
 / * Breakout Copyright(C)2011 Sebastian Goscik All rightsreserved。 Scott Allen 2016による変更(???による以前の変更後)このライブラリはフリーソフトウェアです。フリーソフトウェアファウンデーションによって公開されているGNULesser General Public Licenseの条件の下で、再配布および/または変更することができます。ライセンスのバージョン2.1、または(オプションで)それ以降のバージョン。 * /#include  // EEPROMでブロックしてハイスコアを保存します#defineEE_FILE 2Arduboy2 arduboy; BeepPin1 beep; const unsigned int FRAME_RATE =40; //フレームレート(フレーム/秒)const unsigned int COLUMNS =13; // bricksconstの列unsignedint ROWS =4; // bricksintの行dx =-1; //バリントの最初の動きdy =-1; // ballintの最初の動きxb; //位置を開始するボールyb; // possitionbooleanを開始するボールがリリースされました; //プレーヤーによってボールがリリースされた場合booleanpaused =false; //ゲームが一時停止されている場合bytexPaddle; //パドルブールのX位置isHit [ROWS] [COLUMNS]; //ブリックがヒットしたかどうかの配列booleanbounced =false; //ダブルバウンスグリッチバイトの寿命を修正するために使用=3; //ライフバイトレベルの量=1; //現在のlevelunsignedint score =0; // gameunsigned intbrickCountのスコア; //レンガの量hitbooleanpad、pad2、pad3; //一時停止の繰り返しを停止するために使用されるボタン押下バッファbooleanoldpad、oldpad2、oldpad3; char text_buffer [16]; //一般的な文字列bufferbooleanstart =false; //メニューまたはgamebooleanの場合initialDraw =false; //最初の描画が発生した場合charinitials [3]; //ハイスコアで使用されるイニシャル//衝突検出で使用されるボール境界byteleftBall; byte rightBall; byte topBall; bytebottomBall; //衝突検出で使用されるBrickBoundsbyte leftBrick; byte rightBrick; byte topBrick; byte bottomBrick; byte tick; void setup (){arduboy.begin(); beep.begin(); arduboy.setFrameRate(FRAME_RATE); arduboy.initRandomSeed();} void loop(){//次のフレームの時間になるまでレンダリングを一時停止if(!(arduboy.nextFrame()))return; //トーンのタイミングと停止を処理しますbeep.timer(); //タイトル画面のループがタイトル画面から//(!start){start =titleScreen();の間にFIREが押されるまでハイスコアに切り替わります。 if(!start){start =displayHighScores(EE_FILE); }} //初期レベルの描画if(!initialDraw){//画面をクリアしますarduboy.clear(); //フォントを選択します//新しいレベルを描画しますlevel =1; newLevel();スコア=0; initialDraw =true; } if(lives> 0){drawPaddle(); // FIREが押された場合はゲームを一時停止しますpad =arduboy.pressed(A_BUTTON)|| arduboy.pressed(B_BUTTON); if(pad ==true &&oldpad ==false &&リリース){oldpad2 =false; //パッドループ2を1回実行するように強制しますpause(); } oldpad =pad; drawBall(); if(brickCount ==ROWS * COLUMNS){level ++; newLevel(); }} else {drawGameOver(); if(score> 0){enterHighScore(EE_FILE); } arduboy.clear(); initialDraw =false; start =false;生活=3; newLevel(); } arduboy.display();} void movePaddle(){//右に移動if(xPaddle  0){if(arduboy.pressed(LEFT_BUTTON)){xPaddle- =2; }}} void moveBall(){tick ++; if(released){//ボールを移動if(abs(dx)==2){xb + =dx / 2; // 2xの速度は実際には1.5の速度ですif(tick%2 ==0)xb + =dx / 2; } else {xb + =dx; } yb =yb + dy; //境界を設定leftBall =xb; rightBall =xb + 2; topBall =yb; bottomBall =yb + 2; //上端で跳ね返るif(yb <=0){yb =2; dy =-dy; playTone(523、250); } //下端がヒットした場合にライフを失うif(yb> =64){arduboy.drawRect(xPaddle、63、11、1、0); xPaddle =54; yb =60;リリース済み=false;生きている-; playToneTimed(175、500); if(random(0、2)==0){dx =1; } else {dx =-1; }} //左側で跳ね返るif(xb <=0){xb =2; dx =-dx; playTone(523、250); } //右側で跳ね返るif(xb> =WIDTH-2){xb =WIDTH-4; dx =-dx; playTone(523、250); } //パドルを跳ね返すif(xb + 1> =xPaddle &&xb <=xPaddle + 12 &&yb + 2> =63 &&yb <=64){dy =-dy; dx =((xb-(xPaddle + 6))/ 3); //ボールにスピンを適用します//ストレートバウンスを防ぎますif(dx ==0){dx =(random(0,2)==1)? 1:-1; } playTone(200、250); } //ブリックをバウンスするfor(byte row =0; row  =topBrick &&leftBall <=rightBrick &&rightBall> =leftBrick){Score();一方、brickCount ++; isHit [row] [column] =true; arduboy.drawRect(10 * column、2 + 6 * row、8、4、0); //垂直衝突if(bottomBall> bottomBrick || topBall  rightBrick){//各ボールが移動するたびに1回だけバウンスするif(!bounced){dx =-dx; xb + =dx;バウンス=true; playTone(261、250); }}}}}}} //バウンスをリセットbounced =false; } else {//ボールはパドルの後に続くxb =xPaddle + 5; // FIREが押された場合はボールを解放しますpad3 =arduboy.pressed(A_BUTTON)|| arduboy.pressed(B_BUTTON); if(pad3 ==true &&oldpad3 ==false){リリース済み=true; //リリース時にボールにランダムな方向を適用しますif(random(0、2)==0){dx =1; } else {dx =-1; } //ボールが上向きになっていることを確認しますdy =-1; } oldpad3 =pad3; }} void drawBall(){// arduboy.setCursor(0,0); // arduboy.print(arduboy.cpuLoad()); // arduboy.print( ""); arduboy.drawPixel(xb、yb、0); arduboy.drawPixel(xb + 1、yb、0); arduboy.drawPixel(xb、yb + 1、0); arduboy.drawPixel(xb + 1、yb + 1、0); moveBall(); arduboy.drawPixel(xb、yb、1); arduboy.drawPixel(xb + 1、yb、1); arduboy.drawPixel(xb、yb + 1、1); arduboy.drawPixel(xb + 1、yb + 1、1);} void drawPaddle(){arduboy.drawRect(xPaddle、63、11、1、0); movePaddle(); arduboy.drawRect(xPaddle、63、11、1、1);} void drawGameOver(){arduboy.drawPixel(xb、yb、0); arduboy.drawPixel(xb + 1、yb、0); arduboy.drawPixel(xb、yb + 1、0); arduboy.drawPixel(xb + 1、yb + 1、0); arduboy.setCursor(37、42); arduboy.print( "ゲームオーバー"); arduboy.setCursor(31、56); arduboy.print( "スコア:"); arduboy.print(score); arduboy.display(); arduboy.delayShort(4000);} void pause(){paused =true; //画面に一時停止を描画しますarduboy.setCursor(52、45); arduboy.print( "PAUSE"); arduboy.display(); while(一時停止){arduboy.delayShort(150); // FIREが押された場合は一時停止を解除しますpad2 =arduboy.pressed(A_BUTTON)|| arduboy.pressed(B_BUTTON); if(pad2 ==true &&oldpad2 ==false &&リリース){arduboy.fillRect(52、45、30、11、0); paused =false; } oldpad2 =pad2; }} void Score(){score + =(level * 10);} void newLevel(){//パドルを元に戻すarduboy.drawRect(xPaddle、63、11、1、0); //ボールを描画解除しますarduboy.drawPixel(xb、yb、0); arduboy.drawPixel(xb + 1、yb、0); arduboy.drawPixel(xb、yb + 1、0); arduboy.drawPixel(xb + 1、yb + 1、0); //さまざまな変数を変更してゲームをリセットしますxPaddle =54; yb =60;一方、brickCount =0;リリース済み=false; //新しいブリックを描画し、その値をリセットしますfor(byte row =0; row <4; row ++){for(byte column =0; column <13; column ++){isHit [row] [column] =false; arduboy.drawRect(10 * column、2 + 6 * row、8、4、1); }} arduboy.display();} //ボタンの読み取り中に画像を遅延させるために使用されますinputbooleanpollFireButton(int n){for(int i =0; i  0){sprintf(text_buffer、 "%c%c%c%u"、イニシャル[0]、イニシャル[1]、イニシャル[2]、スコア); arduboy.setCursor(x + 24、y +(i * 8)); arduboy.print(text_buffer); arduboy.display(); }} if(pollFireButton(300)){trueを返す; } falseを返します。 arduboy.display();} boolean titleScreen(){//画面をクリアしますarduboy.clear(); arduboy.setCursor(16,22); arduboy.setTextSize(2); arduboy.print( "BREAKOUT"); arduboy.setTextSize(1); arduboy.display(); if(pollFireButton(25)){trueを返します; } // "Press FIRE"を5回フラッシュfor(byte i =0; i <5; i ++){// "Press FIRE"を描画arduboy.setCursor(31、53); arduboy.print( "PRESS FIRE!"); arduboy.display(); if(pollFireButton(50)){trueを返します; } // "Press FIRE"を削除しますarduboy.setCursor(31、53); arduboy.print( ""); arduboy.display(); if(pollFireButton(25)){trueを返します; }} return false;} //高スコアを追加する向知性デザインによる関数voidenterInitials(){byte index =0; arduboy.clear();イニシャル[0] ='';イニシャル[1] ='';イニシャル[2] =''; while(true){arduboy.display(); arduboy.clear(); arduboy.setCursor(16,0); arduboy.print( "HIGH SCORE"); sprintf(text_buffer、 "%u"、score); arduboy.setCursor(88、0); arduboy.print(text_buffer); arduboy.setCursor(56、20); arduboy.print(イニシャル[0]); arduboy.setCursor(64、20); arduboy.print(イニシャル[1]); arduboy.setCursor(72、20); arduboy.print(イニシャル[2]); for(byte i =0; i <3; i ++){arduboy.drawLine(56 +(i * 8)、27、56 +(i * 8)+ 6、27、1); } arduboy.drawLine(56、28、88、28、0); arduboy.drawLine(56 +(インデックス* 8)、28、56 +(インデックス* 8)+ 6、28、1); arduboy.delayShort(70); if(arduboy.pressed(LEFT_BUTTON)|| arduboy.pressed(B_BUTTON)){if(index> 0){index--; playToneTimed(1046、80); }} if(arduboy.pressed(RIGHT_BUTTON)){if(index <2){index ++; playToneTimed(1046、80); }} if(arduboy.pressed(UP_BUTTON)){イニシャル[インデックス] ++; playToneTimed(523、80); // A-Z 0-9:-? !-/ '' if(initials [index] =='0'){initials [index] =''; } if(initials [index] =='!'){initials [index] ='A'; } if(initials [index] =='['){initials [index] ='0'; } if(initials [index] =='@'){initials [index] ='!'; }} if(arduboy.pressed(DOWN_BUTTON)){イニシャル[インデックス]-; playToneTimed(523、80); if(initials [index] ==''){initials [index] ='?'; } if(initials [index] =='/'){initials [index] ='Z'; } if(initials [index] ==31){initials [index] ='/'; } if(initials [index] =='@'){initials [index] =''; }} if(arduboy.pressed(A_BUTTON)){playToneTimed(1046、80); if(index <2){index ++; } else {return; }}}} void enterHighScore(byte file){// EEPROMの各ブロックには7つのハイスコアがあり、各ハイスコアエントリは//長さが5バイトです。イニシャル用に3バイト、スコア用に2バイトです。 intアドレス=ファイル* 7 * 5 + EEPROM_STORAGE_SPACE_START;バイトこんにちは、lo; char tmpInitials [3]; unsigned int tmpScore =0; //ハイスコア処理for(byte i =0; i <7; i ++){hi =EEPROM.read(address +(5 * i)); lo =EEPROM.read(address +(5 * i)+ 1); if((hi ==0xFF)&&(lo ==0xFF)){//値は初期化されていないため、このエントリを//スコア0として扱います。tmpScore=0; } else {tmpScore =(hi <<8)| lo; } if(score> tmpScore){enterInitials(); for(byte j =i; j <7; j ++){hi =EEPROM.read(address +(5 * j)); lo =EEPROM.read(address +(5 * j)+ 1); if((hi ==0xFF)&&(lo ==0xFF)){tmpScore =0; } else {tmpScore =(hi <<8)| lo; } tmpInitials [0] =(char)EEPROM.read(address +(5 * j)+ 2); tmpInitials [1] =(char)EEPROM.read(address +(5 * j)+ 3); tmpInitials [2] =(char)EEPROM.read(address +(5 * j)+ 4); //スコアとイニシャルを現在のスロットに書き込みますEEPROM.update(address +(5 * j)、((score>> 8)&0xFF)); EEPROM.update(アドレス+(5 * j)+ 1、(スコア&0xFF)); EEPROM.update(アドレス+(5 * j)+ 2、イニシャル[0]); EEPROM.update(アドレス+(5 * j)+ 3、イニシャル[1]); EEPROM.update(アドレス+(5 * j)+ 4、イニシャル[2]); // tmpScoreとtmpInitialsは、次のスロットに//書き込みたいものを保持します。スコア=tmpScore;イニシャル[0] =tmpInitials [0];イニシャル[1] =tmpInitials [1];イニシャル[2] =tmpInitials [2]; }スコア=0;イニシャル[0] ='';イニシャル[1] ='';イニシャル[2] ='';戻る; }}} //指定された周波数で指定された期間トーンを再生します。voidplayTone(unsigned int frequency、unsigned int duration){beep.tone(beep.freq(frequency)、duration /(1000 / FRAME_RATE));} //指定された周波数で指定された期間トーンを再生します//トーンのタイミングを計る遅延を使用します//beep.timer()が呼び出されていないときに使用されます.voidplayToneTimed(unsigned int frequency、unsigned int duration){ beep.tone(beep.freq(frequency)); arduboy.delayShort(duration); beep.noTone();} 

カスタムパーツとエンクロージャー

3d_parts_ThLGvJvWga.rar

回路図


製造プロセス

  1. Raspi 2WIOTとのArduinoI2C通信
  2. ハンドヘルドゲームコンソール| Arduboyクローン
  3. ArduinoPongゲーム-OLEDディスプレイ
  4. ArduinoTemp。 3.2ディスプレイを備えたモニターとリアルタイムクロック
  5. Arduinoを搭載したシンプルな障害物センサー
  6. Nextionディスプレイで遊ぶ
  7. Arduino Nano:ジョイスティックで2つのステッピングモーターを制御
  8. ArduinoとNokia5110ディスプレイを備えたDIY電圧計
  9. ArduinoおよびOLEDベースのセルオートマトン
  10. ArduinoNanoを搭載したハンドヘルドガイガーカウンター
  11. Arduino用の絶縁アナログ入力