このDIY電子D20ダイでスタイリッシュに転がる

このDIY電子D20ダイでスタイリッシュに転がる

次の卓上ロールプレイングゲームのために少しユニークなものが欲しいですか?クリティカルヒットとミスのカスタムグラフィックスを備えた電子D20はどうですか?今日は、Arduinoといくつかの簡単なパーツを使って独自に構築する方法を紹介します。





これまでにArduinoを使用したことがなくても心配しないでください。 入門ガイド





ビルドプラン

これは単純なプロジェクトです。 ArduinoはOLEDディスプレイを駆動し、ボタンはサイコロを転がします。カスタムグラフィックは、クリティカルヒットまたはクリティカルミスロールに対して表示されます。コードをD8、D10、またはD12に簡単に変更できます。





何が必要

  • 1 x Arduino
  • 1 x 0.96 ' I2COLEDディスプレイ
  • 1xプッシュボタン
  • 1 x 10k?抵抗器
  • 1xブレッドボード
  • 各種フックアップワイヤー
  • 書かれた指示を完全に実行したくない場合は、ここに完全なコードがあります。

これらは、独自のD20を構築するために必要なコアパーツです。ケース(以下で説明)に取り付けて、回路をより永続的な状態にはんだ付けすることをお勧めします。これを行うために必要な追加の部分は次のとおりです。

  • 4 x M2 x 10mm(0.4インチ)ボルト
  • 4 xM2ナット
  • 4 x 7mm(0.28インチ)ワッシャー
  • 9Vバッテリースナップ(または適切な代替品)
  • 各種熱収縮チューブ

これらのOLEDディスプレイはとてもかっこいいです。それらは通常、白、青、黄色、または3つの混合物で購入できます。ケースに合わせてブルーで購入しました。あなたが得ることを確認してください I2C 代わりにモデル SPI



ほとんどすべてのArduinoが適しています。ケースに収まるほど小さいので、私はNanoを選びました。 Arduinoモデルの詳細については、購入ガイドをご覧ください。

サーキット

必要な回路は次のとおりです。





接続 VCCGND ArduinoへのOLEDディスプレイで + 5V接地 。接続 アナログ4 Arduinoでラベルの付いたピンに SDA 。接続 アナログ5SCL ピン。これらのピンには、I2Cバスを使用してディスプレイを駆動するために必要な回路が含まれています。正確なピンはモデルによって異なりますが、A4とA5はNanoとUnoで使用されます。を確認してください ワイヤーライブラリのドキュメント UnoまたはNanoを使用していない場合は、モデルに使用します。

バッテリーをアースに接続し、 ワイン ピン。これは電圧入力を表し、さまざまな異なるDC電圧を受け入れますが、最初に特定のモデルを確認してください。わずかに異なる場合があります。





ボタンをに接続します デジタルピン2 。どのように10kに注意してください?抵抗はアースに接続されています。これはとても重要です!これはプルダウン抵抗と呼ばれ、Arduinoがボタンを押したときに偽のデータや干渉を検出するのを防ぎます。また、ボードを保護するのにも役立ちます。この抵抗を使用しなかった場合、+ 5Vは直接グランドに接続されます。これはとして知られています デッドショート Arduinoを殺す簡単な方法です。

この回路をはんだ付けする場合は、熱収縮チューブで接続を保護してください。

加熱しすぎないように注意し、回路が機能することを確認してから加熱してください。ケーブルをペアにねじることもできます。これはそれらをきちんと保ち、過度のストレスからそれらを保護するのに役立ちます:

ボタンテスト

回路を構築したので、このテストコードをアップロードします(から正しいボードとポートを選択してください ツール>ボードツール>ポート メニュー):

const int buttonPin = 2; // the number of the button pin
void setup() {
pinMode(buttonPin, INPUT); // setup button
Serial.begin(9600); // setup serial
}
void loop(){
if(digitalRead(buttonPin) == HIGH) {
Serial.print('It Works');
delay(250);
}
}

アップロードしたら、ArduinoをUSB経由で接続したままにして、シリアルモニターを開きます( 右上>シリアルモニター )。あなたは言葉を見るはずです できます ボタンを押すたびにが表示されます。

何も起こらない場合は、回路を再確認してください。

OLEDセットアップ

ディスプレイを駆動するには、2つのライブラリをインストールする必要があります。ダウンロード Adafruit_SSD1306 およびGithubのAdafruit-GFX [現在利用できません]ライブラリをライブラリフォルダーに保存します。ライブラリフォルダがどこにあるかわからない場合は、レトロゲームのチュートリアルを読んでください。このチュートリアルでは、この同じディスプレイをより詳細に構成しています。

Arduino IDEを再起動し、からテストスケッチをアップロードします ファイル>例 メニュー。選択する Adafruit SSD1306 その後 ssd1306_128x64_i2c 。このコードをアップロードすると(しばらく時間がかかります)、ディスプレイにたくさんの形やパターンが表示されるはずです。

何も起こらない場合は、接続を再確認してください。確認しても機能しない場合は、サンプルコードを変更する必要があります。

誰かについて知る方法

この行を変更します(開始時に 設定 関数):

display.begin(SSD1306_SWITCHCAPVCC, 0x3D);

これに:

display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

これにより、使用しているディスプレイに関するライブラリ固有の詳細がわかります。これで、ビルドを続行する準備が整いました。

ケース

ブレッドボード上にこれを構築している場合、またはボックス化したくない場合は、この手順をスキップできます。

このボックスをデザインして3Dプリントしました。ファイルを入手する シンギバース 。 3Dプリンターがなくても心配しないでください-オンラインサービス 3Dハブシェイプウェイズ オンライン印刷サービスを提供します。

この箱は木で作るか、プラスチックを購入することで簡単に作ることができます プロジェクトボックス

ふたはシンプルなプッシュフィットデザインで、ハードウェア用のいくつかの切り欠きが含まれています。

コード

すべての準備ができたので、コードの時間です。これがどのように機能するかです 擬似コード

if button is pressed
generate random number
if random number is 20
show graphic
else if random number is 1
show graphic
else
show number

これが正しく機能するためには、乱数を生成する必要があります。これがサイコロの目です。 Arduinoにはと呼ばれる乱数ジェネレータがあります ランダム 、しかしそれを使用するべきではありません。基本的なランダムタスクには十分ですが、電子ダイには十分にランダムではありません。理由はやや複雑ですが、興味があればもっと読むことができます boallen.com

ダウンロード TrueRandom によるライブラリ サーリーチ Githubで。これをライブラリフォルダに追加し、IDEを再起動します。

次に、新しいファイルを作成し、初期コードをセットアップします(または、完成したコードをGitHubから取得します)。

#include
#include
#include
#include
#include
Adafruit_SSD1306 display(4);
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // setup the OLED
pinMode(buttonPin, INPUT); // setup button
}
void loop() {

}

このコードはOLEDを構成し、新しい乱数ライブラリとともに、OLEDと通信するために必要なすべてのライブラリを含みます。次に、これをメインループに追加します。

if(digitalRead(buttonPin) == HIGH) {
delay(15);
if(digitalRead(buttonPin) == HIGH) {
display.fillScreen(BLACK); // erase the whole display
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(0, 0);
display.println(TrueRandom.random(1, 21)); // print random number
display.display(); // write to display
delay(100);
}
}

これは現時点では非常に基本的なことですが、動作するD20です。ボタンが押されるたびに、1から20までの乱数が画面に表示されます。

これはうまく機能しますが、少し退屈です。良くしましょう。 2つの新しいメソッドを作成します。 drawDieerasedDie

void drawDie() {
display.drawRect(32, 0, 64, 64, WHITE);
}

これらは画面の中央にダイを描画します。 D20やD12などを描画するなどして、これをより複雑にすることもできますが、基本的な6面体のダイを描画する方が簡単です。基本的な使用法は次のとおりです。

drawDie();

次に、メインループを変更して、乱数を描画します。乱数は大きく、中央にのみ表示されます。テキストサイズとカーソルを次のように変更します。

display.setTextColor(WHITE);
display.setCursor(57, 21);

今ではずっと良く見えます:

唯一の問題は、9より大きい数の場合です。

これに対する修正は簡単です。 10未満の数値は、カーソルが10以上の数値とは異なる位置に設定されます。この行を置き換えます:

iPhone6でビデオをトリミングする方法
display.setCursor(57, 21);

これとともに:

int roll = TrueRandom.random(1, 21); // store the random number
if (roll <10) {
// single character number
display.setCursor(57, 21);
}
else {
// dual character number
display.setCursor(47, 21);
}

これが今のように見えます:

残っているのは、クリティカルヒットまたはミスをロールしたときの画像だけです。いくつかのステップが含まれますが、それは十分に単純なプロセスです。

使用する適切な画像を見つけます(ディスプレイは単色のみであるため、シンプルな方が良いです)。これが私が使用した画像です:

画像クレジット: publicdomainvectors.org

使用する画像はすべてHEX配列に変換する必要があります。これは、コード形式での画像の表現です。これを行うために利用できる多くのツールがあり、いくつかはOLEDディスプレイ用に特別に書かれています。最も簡単な方法は、 PicturetoC_Hex オンラインツール。必要な設定は次のとおりです。

なぜ私のテキストは配信されたとは言わないのですか

画像をアップロードし、コード形式を次のように設定します HEX:0x 。設定 のために使用されるすべての描画画像機能の黒/白 。他のすべてのオプションはデフォルトのままにします。必要に応じて、ここで画像のサイズを変更できます。押す C文字列を取得 画像データが表示されるはずです。

この生成されたデータはすぐに必要になります。と呼ばれる2つの関数を作成します drawExplosiondrawSkull (またはお使いのバージョンに適した名前)。コードは次のとおりです。

void drawExplosion() {
// store image in EEPROM
static const unsigned char PROGMEM imExp[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x78,0x7f,0xff,0xc0,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xf0,0x00,0x00,0x00,0x3f,0xff,0xff,0xff,0xfb,0x00,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0xff,0x00,0x01,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x07,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x07,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x07,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x07,0xff,0xff,0xff,0xff,0xff,0xff,0xc0,0x0f,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x1f,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x1f,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x0f,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x01,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x0f,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x07,0xff,0xff,0xf9,0xff,0xd8,0x00,0x00,0x00,0x3f,0xff,0xf0,0x0f,0x00,0x00,0x00,0x00,0x1f,0x1f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xff,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0xff,0xff,0x00,0x00,0x00,0x07,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x0f,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x1f,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x1f,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x01,0xbf,0xff,0xff,0xff,0x30,0x00,0x00,0x00,0x13,0xf7,0xb8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
display.drawBitmap(0, 0, imExp, 64, 62, 1); // draw mushroom cloud
}
void drawSkull() {
// store image in EEPROM
static const unsigned char PROGMEM imSku[] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0xf0,0x00,0x00,0x00,0x00,0x78,0x00,0x07,0xf0,0x00,0x00,0x00,0x00,0xfc,0x00,0x07,0xf8,0x00,0x00,0x00,0x00,0xfe,0x00,0x07,0xf8,0x00,0x00,0x00,0x01,0xfe,0x00,0x07,0xfc,0x00,0x00,0x00,0x01,0xfe,0x00,0x07,0xfe,0x00,0x3f,0xc0,0x03,0xfe,0x00,0x01,0xff,0x81,0xff,0xfc,0x07,0xec,0x00,0x00,0x3f,0xc7,0xff,0xff,0x1f,0xc0,0x00,0x00,0x0f,0xcf,0xff,0xff,0xdf,0x00,0x00,0x00,0x07,0xbf,0xff,0xff,0xee,0x00,0x00,0x00,0x01,0x7f,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x01,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x03,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x07,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x0f,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x0f,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x1f,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x1f,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x1f,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x1f,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x1f,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x1f,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x1e,0x3f,0xff,0x3f,0xc7,0x80,0x00,0x00,0x1e,0x0c,0x0f,0x00,0x07,0x80,0x00,0x00,0x1e,0x00,0x0f,0x00,0x0f,0x80,0x00,0x00,0x1e,0x00,0x19,0x80,0x0f,0x00,0x00,0x00,0x0f,0x00,0x19,0x80,0x0f,0x00,0x00,0x00,0x0d,0x00,0x30,0xc0,0x1f,0x00,0x00,0x00,0x05,0x80,0x70,0xc0,0x1e,0x00,0x00,0x00,0x05,0xf0,0xe0,0xe0,0x36,0x00,0x00,0x00,0x01,0xff,0xe0,0x7f,0xf0,0x00,0x00,0x00,0x03,0xff,0xc4,0x7f,0xf0,0x00,0x00,0x00,0x03,0xff,0xcc,0x7f,0xf0,0x00,0x00,0x00,0x03,0xff,0xcc,0x7f,0xf0,0x00,0x00,0x00,0x03,0xff,0x9e,0x7f,0xf0,0x00,0x00,0x00,0x00,0xff,0xfe,0x7f,0xc0,0x00,0x00,0x00,0x00,0x01,0xff,0xf8,0x1c,0x00,0x00,0x00,0x03,0xe0,0x3f,0x01,0xbf,0x00,0x00,0x00,0x07,0xa6,0x40,0x09,0x9f,0x80,0x00,0x00,0x1f,0x27,0x5a,0x39,0x9f,0xf8,0x00,0x01,0xff,0x27,0xdb,0x39,0x0f,0xfc,0x00,0x03,0xfe,0x31,0x7f,0x39,0x07,0xfc,0x00,0x03,0xfc,0x10,0x1a,0x02,0x03,0xf8,0x00,0x03,0xf8,0x10,0x00,0x02,0x01,0xf0,0x00,0x01,0xf8,0x10,0x00,0x02,0x01,0xe0,0x00,0x00,0x78,0x10,0x00,0x02,0x00,0xe0,0x00,0x00,0x70,0x30,0x00,0x02,0x00,0x00,0x00,0x00,0x30,0x20,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x64,0x00,0x1b,0x00,0x00,0x00,0x00,0x00,0x73,0x55,0x63,0x00,0x00,0x00,0x00,0x00,0xf9,0x55,0x4f,0x00,0x00,0x00,0x00,0x00,0x7f,0x14,0x1f,0x00,0x00,0x00,0x00,0x00,0x1f,0xe0,0xfe,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x07,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
display.drawBitmap(0, 0, imSku, 60, 64, 1); // draw skull cloud
}

私が使用した画像を使用したい場合は、先に進んでコードをコピーしてください。以前に生成した独自の画像を使用する場合は、バイトコードをにコピーします。 imSkuimExp 必要に応じて配列。

これらの画像がディスプレイに表示されるのは次のとおりです。

そのコードの最も重要な部分は次の行です。

static const unsigned char PROGMEM imSku[]

これは、Arduinoに画像をEEPROMに保存するように指示します( EEPROMとは何ですか? )RAMの代わりに( RAMのクイックガイド )。この理由は単純です。 ArduinoのRAMは限られており、画像を保存するためにすべてを使用しても、コードを実行するための残りが残っていない可能性があります

メインを変更する もしも 1つまたは20がロールされたときにこれらの新しいグラフィックを表示するステートメント。画像と一緒にロールされた番号を示すコード行にも注意してください。

if(roll == 20) {
drawExplosion();
display.setCursor(80, 21);
display.println('20');
}
else if(roll == 1) {
display.setCursor(24, 21);
display.println('1');
drawSkull();
}
else if (roll <10) {
// single character number
display.setCursor(57, 21);
display.println(roll); // write the roll
drawDie(); // draw the outline
}
else {
// dual character number
display.setCursor(47, 21);
display.println(roll); // write the roll
drawDie(); // draw the outline
}

そして、これらの新しいロールは次のようになります。

コード側はこれですべてです(すべてスキップした場合は、GitHubからコードを取得してください)。これをD12、D8などに簡単に変更できます。

最終組み立て

他のすべてが終了したので、すべてを箱詰めする時が来ました。ボルトを締めすぎないように注意しながら、ディスプレイをボルトで固定します。これはおそらく最も難しい部分です。ディスプレイにひびが入ったので、プラスチック製のワッシャーを使用することをお勧めします。私はいくつかの正方形を切り取りました プラカード

小さなナットとボルトは接続が難しい場合があります。 ヒント: ドライバーの端にあるBlu-Tackの小片を使用して、最初にナットを固定します。

ボタンをねじ込み、バッテリーを接続して蓋を閉じます。ワイヤーを閉じ込めたり、束ねすぎたりしないように注意してください。ショートの原因となる可能性があります。トレーリングリードの長さによっては、露出した接続をある程度の断熱材で保護する必要がある場合があります(シリアルボックスが適切に機能します)。

内部は次のようになります。

そして、これが完成品です:

あなたは今、電子D20の誇り高い所有者になるはずです!

どのような変更を加えましたか?画像を変更しましたか?コメントで教えてください、私たちはあなたが何をしたか見てみたいです!

共有 共有 つぶやき Eメール スピーチをアニメーション化するためのビギナーズガイド

スピーチのアニメーション化は難しい場合があります。プロジェクトにダイアログを追加する準備ができたら、プロセスを分解します。

次を読む
関連トピック
  • DIY
  • Arduino
  • ボードゲーム
  • エレクトロニクス
著者について ジョーコバーン(136件の記事が公開されました)

Joeは、英国のリンカーン大学でコンピュータサイエンスを卒業しています。彼はプロのソフトウェア開発者であり、ドローンを飛ばしたり音楽を書いたりしていないときは、写真を撮ったりビデオを制作したりしていることがよくあります。

ジョーコバーンのその他の作品

ニュースレターを購読する

ニュースレターに参加して、技術的なヒント、レビュー、無料の電子書籍、限定セールを入手してください。

購読するにはここをクリックしてください
カテゴリ Diy