Arduinoダイスを振る
コンポーネントと消耗品
> |
| × | 1 | |||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
必要なツールとマシン
> |
| |||
|
アプリとオンラインサービス
> |
| |||
|
このプロジェクトについて
約1年前に息子と 私 構築 Arduinoを使用した電子サイコロ といくつかのLED。これはまだ初心者にとって理想的なプロジェクトです。今年はたくさんのことを学んだので、更新の時期が来ています。
サイコロはまだ完璧なスタータープロジェクトです。機能は誰にとっても明確であり、マイクロコントローラー、単純な電子機器、コーディングなど、さまざまな分野を簡単に理解できます。
バージョン2.0
サイコロも素晴らしく、さらに一歩進んで、他の領域をリンクします。
今日、ほとんどすべてに対応する既成のコンポーネントがあります。これは、ArduinoまたはRaspberryPiのスターターキットを探すときに最もよく見られます。 LED、プッシュボタン、あらゆるタイプのセンサーなどのコンポーネントは回路基板上に構築されているため、GPIOに数本のワイヤーで接続して使用できます。
シンプルですが十分な3Dプリンターは、eBayで140ユーロ未満で購入できます。ほとんどすべてのブラケット、取り付け、またはケーシングのバリエーションをそれを使用して作成できます。
独自のプロジェクトを開発する機会は他にもたくさんあります。この例は、新しいサイコロ2.0です。
傾斜センサー
サイコロはまったく異なる方法で実装します。内部では、ArduinoNanoがスペース上の理由で機能しています。オンオフスイッチはまだありますが、ボタンはありません。ダイシングは、キューブ全体を振ることによって行われます。
この目的のために、傾斜センサーまたは振動センサーが使用されます。ボタンのように機能します。ガラス管の中では、ボールが動きます。接続接点に当たると回路が閉じます。この接点は、非常に短い場合もあり、信号に使用されます。
センサーを振ると、金属球の動きがよく聞こえます。
<図>通常、設置位置は傾斜センサーにとって決定的です。特定の角度位置で信号をトリガーすることになっています。私たちの場合、これはケースを振ることによって起こります。ここでは、どの方向に振っても信号がトリガーされるため、状況はそれほど重要ではありません。安全のために、プロジェクトでは2つのセンサーを使用します。これらのセンサーは互いに90°オフセットして配置されています。したがって、常に信頼できるシェイク信号を取得します。
割り込み
揺れていることを認識できるようにするには、傾斜センサーの入力ピンをスケッチで照会する必要があります。ただし、これが時間内にいつ発生するか、およびスケッチが他に何をしなければならないかによっては、1つ以上のイベントが見過ごされる可能性が常にあります。
より良い解決策は、ハードウェア割り込みを使用することです。これは、関数attachInterruptによって定義されます。パラメータとして、信号で呼び出されるサブプログラムが指定されます。
Arduinoは、ピンD2とD3の2つのハードウェア割り込みを提供します。
表示
もちろん、サイコロの画像の表示は、7つの個別のLEDを使用して行うこともできます。ただし、ここで完成したコンポーネントを使用する方が興味深いです。
<図>このプロジェクトで私たちが選択するのは、MAX7219ドライバICを備えた8x8LEDマトリックスです。必要なスペースはごくわずかで、費用もわずかで、コーディングも簡単です。
購入する場所によっては、はんだ付けして単一の部品を組み立てる必要があります。通常は問題ありません。起こりうる唯一の間違いは、LEDマトリックスをねじってジャックに入れることです。
<図>これは上の写真で示されています。ここでは、マトリックスをソケットから慎重に引き出し、180°回転させるだけで十分です。
いくつかの物理学
LEDマトリックスは、結果としてサイコロの画像を表示するだけではありません。それはいくつかのショー効果を提供するはずです。 6つのサイコロの目がマトリックス上を移動します。それらは端で跳ね返り、ゆっくりと速度を失います。
2つの傾斜センサーを通して、どれだけの揺れが行われたかを見ることができます。この情報は、サイコロの動きの「速度」としてサイコロの目を示します。
サイコロの結果を表示するときにも同様の効果を使用します。目は、立方体の画像のランダムな位置から正しい位置に回転します。
電源
まず、スペース上の理由から、2つの3VCR2032ボタン電池を取り付けました。最初はそれもかなり良さそうだった。 ArduinoとLEDマトリックスが一緒に動作し、すべてが機能しました。ただし、数分間の操作後、ボタン電池の電源が壊れます。
サイコロを振るたびにArduinoをオフにすると、そのように使用できます。それは完璧ではないので、より良い2つのAAAバッテリーを取り付けます。ただし、これらは3Vのみを一緒に供給します。そのため、電圧を5Vに上げるステップアップコンバータが必要です。接続は引き続きArduinoのVINピンで行われます。
住宅設計
適切な住宅の最良の選択肢は、3Dプリントによる独自の設計と製造です。建設のための多くのアプリがあります。このプロジェクトではAutodeskFusion360を使用しました。優れた機能を備えており、3D印刷はPrintStudioソフトウェアとうまく統合されています。 Autodesk Fusion 360に興味がある場合は、ブログ記事Parametric Enclosures(ドイツ語のみ)にいくつかの提案があります。
私たちの住宅は3つの部分で構成されています:
- 大文字
- AAAセル用のバッテリーホルダー付き下部ケース
- プレキシグラスカバー(必ずしもそうである必要はありません)
LEDマトリックスは、その前に乳白色のプレキシガラスカバーを付けるとさらに見栄えが良くなります。これにより、オフのLEDを認識できなくなり、画像がより鮮明になります。
スケッチ
LEDマトリックスを制御するには、LedControlライブラリが必要です。まだインストールされていない場合は、arduino.cchttps://playground.arduino.cc/Main/LedControlからダウンロードできます。
次に、他の変数定義を行います。まず、サイコロの目がマトリックスにどのように表示されるかを決定します。ダイスアイは4つのLEDポイントで構成されています。配列では、左上隅がX / Y座標として指定されています(-1はディスプレイの外側を意味します)。
int DicePic [8] [6] [2] ={…{// 1:{4,4}、// 1。パンク{-1、-1}、// 2。パンク{-1、-1}、// 3。パンク{-1、-1}、// 4。パンク{-1、-1}、// 5。パンク{-1、-1} // 6。パンク}、{// 2:{2,2}、// 1。パンク{6,6}、// 2。パンク{-1、-1}、// 3。パンク{-1、-1}、// 4。パンク{-1、-1}、// 5。パンク{-1、-1} // 6。パンク}、…
もちろん、ここではすべてが可能です。あなたの想像力を駆り立てましょう。必ずしも典型的な目の画像である必要はありません。
コードに直接記載されているその他のコメント。
組み立て
一種のシールドとして、Arduinoをソケットストリップに置きます。 LEDマトリックスの5つの接点は同じ方法で接続されます。 Arduinoが中央に配置されている場合は、スペースが最適に使用されます。したがって、マトリックスにはCS、CLK、およびDINにピン5、6、7を使用するのが最適です。ここでは、はんだポイントのみを接続する必要があります。 5VとGNDへの接続は、小さなジャンパーを介して行われます。
<図>また、2つの傾斜センサーを短いワイヤーで接続します。これらはピン2と3、5VとGNDに接続されています。
<図>これで、すべてを組み立てることができます。プレキシガラスは最初にホットグルーで固定されます。 LEDマトリックスでも同じことをします。ホットグルーの小さなポイントで十分です。
次に、オン/オフスイッチを取り付け、ホットグルーで固定し、適切なワイヤーに接続します。
<図>
電源の取り付け
電源は少しいじくり回されています。使用しているオプションとコンポーネントに応じて、プラスとマイナスの接点をそれに応じて調整できます。
使用済みバッテリーコンパートメントのスプリングとピンを使用しています。ハウジングの底に取り付けるには、ワイヤーと少量のホットグルーを再度使用します。
<図>ステップアップブーストコンバーターは、約インストール前に5V。そのためには、抵抗を少しひねる必要があります。
次に、大文字と小文字を組み合わせます。 0.1mmのはめあいのため、それ以上固定せずに一緒に差し込むだけで十分です。そして、バッテリー交換のために再び開くことができます。
そして、それは終了しました!
サイコロの楽しみ2.0が始まります!
必要なもの
- Arduino Nano(またはESP8266)
- 2 x傾斜センサー(抵抗が統合されている)
- MAX7219 IC、SPCを備えた8x8LEDマトリックス
- ソケットストリップ
- オン/オフスイッチ
- PCB
- 2 xAAAバッテリー
詳細情報
詳細については、当社のWebサイトtechpluscode.de/arduino-wuerfel-2-0を確認してください。
申し訳ありませんが、この拡張ブログはドイツ語でのみご利用いただけます;-)
コード
- wuerfel8x8.ino
wuerfel8x8.ino Arduino
揺れるサイコロのコード/ * Blog-Artikel:Schttel-Wrfel mit LED Matrix und Bewegungssimulationhttps://techpluscode.de/schuettel-wuerfel-mit-led-matrix-und-bewegungssimulation/techpluscode.deCopyright 2019 von Thomas Angielsky * /// Bibliothek fr die Ansteuerung der 8x8 LED-Matrix einbinden // 8x8 LEDマトリックスのライブラリを含める#include "LedControl.h" int PinTiltX =2; // Pin fr Tiltsensor Xint PinTiltY =3; // Pin fr Tiltsensor Y // Pins der LED-Matrix // LEDmatrixのピンintPinCLK =7; int PinCS =6; int PinDIN =5; LedControl lc =LedControl(PinDIN、PinCLK、PinCS、1); // Coordinaten der Wrfelaugen in der LED-Matrix // LEDマトリックス内のダイスポイントの座標intDicePic [8] [ 6] [2] ={// leere Matrix und Startposition:{9,9}、// 1。パンク{9,8}、// 2。パンク{9,7}、// 3。パンク{9,6}、// 4。パンク{9,5}、// 5。パンク{9,4} // 6。パンク}、{// 1:{4,4}、// 1。パンク{-1、-1}、// 2。パンク{-1、-1}、// 3。パンク{-1、-1}、// 4。パンク{-1、-1}、// 5。パンク{-1、-1} // 6。パンク}、{// 2:{2,2}、// 1。パンク{6,6}、// 2。パンク{-1、-1}、// 3。パンク{-1、-1}、// 4。パンク{-1、-1}、// 5。パンク{-1、-1} // 6。パンク}、{// 3:{2,6}、// 1。パンク{6,2}、// 2。パンク{4,4}、// 3。パンク{-1、-1}、// 4。パンク{-1、-1}、// 5。パンク{-1、-1} // 6。パンク}、{// 4:{2,2}、// 1。パンク{2,6}、// 2。パンク{6,2}、// 3。パンク{6,6}、// 4。パンク{-1、-1}、// 5。パンク{-1、-1} // 6。パンク}、{// 5:{2,2}、// 1。パンク{2,6}、// 2。パンク{6,2}、// 3。パンク{6,6}、// 4。パンク{4,4}、// 5。パンク{-1、-1} // 6。パンク}、{// 6:{2,1}、// 1。パンク{2,4}、// 2。パンク{2,7}、// 3。パンク{6,1}、// 4。パンク{6,4}、// 5。パンク{6,7} // 6。パンク}、{//開始:{-1、-1}、// 1。パンク{-1、-1}、// 2。パンク{-1、-1}、// 3。パンク{-1、-1}、// 4。パンク{-1、-1}、// 5。パンク{-1、-1} // 6。 Punkt}}; // Variablen der Wrfelaugen:Position、Richtung、Geschwindigkeit fr X und Y // Diceの変数:位置、方向、XおよびYfloatの速度DiceXpos [6]; float DiceXdir [6]; volatile byte DiceXspeed [ 6]; float DiceYpos [6]; float DiceYdir [6]; volatile byte DiceYspeed [6]; int DiceValue; unsigned long timestamp; byte Mode; int volatile shakes; int ShakesPerSecond; int step; void InterruptChecks(){// Schttel -Anzahl zhlen // Count Shakes shakes =shakes + 1; //Serial.println(millis()); timestamp =millis();} void SetSpeedX(){if(Mode ==0){// Xのwrfelをallebeschleunigen // Xのダイスを高速化for(int i =0; i <6; i ++){if (DiceXspeed [i] <255){DiceXspeed [i] =DiceXspeed [i] +5;}}} InterruptChecks();} void SetSpeedY(){if(Mode ==0){// Alle Wrfel in Y beschleunigen / / Yのダイスをスピードアップfor(int i =0; i <6; i ++){if(DiceYspeed [i] <255){DiceYspeed [i] =DiceYspeed [i] +5;}}} InterruptChecks(); } void ShowLed(int x、int y、bool onoff){// LED nur anzeigen、wenn im sichtbaren Bereich // show only、when x / y in matrix if((x <8)and(y <8)and( x> =0)および(y> =0)){lc.setLed(0、x、y、onoff); }} void ShowDot(int x、int y、bool onoff){// Wrfel-Auge anzeigen oder ausblenden //ダイスポイントを表示または非表示にするShowLed(x-1、y-1、onoff); ShowLed(x、y-1、onoff); ShowLed(x-1、y、onoff); ShowLed(x、y、onoff);} void ShowDicePic(int value){// Wurf anzeigen // Show diceboolean done; // alle Punkte von der aktuellen Position aus zur Zielposition von DiceValue bewegen //すべてのポイントを現在の位置からDiceValueの宛先に移動しますfor(int i =0; i <6; i ++){DiceXspeed [i] =100; DiceYspeed [i] =100; // Werte fr X berechnen // x値を計算しますDiceXdir [i] =0; if(int(DiceXpos [i])> DicePic [value] [i] [0]){DiceXdir [i] =-1;} else if(int(DiceXpos [i])DicePic [value] [i] [1]){DiceYdir [i] =-1;} else if(int(DiceYpos [i]) 7){pos =7; dir =dir *(-1); } if(pos <1){pos =1; dir =dir *(-1); }} // Geschwindigkeit wird pro Schritt langsamer //速度はステップごとに減少しますif(sp> 0){sp =sp-1;}} void MoveDots(){// alle Wrfel einen Schritt weiter bewegen //ダイスポイントを1ステップ移動しますさらにfor(int i =0; i <6; i ++){// neue Koordinaten berechnen //新しい座標を計算するDoStep(DiceXpos [i]、DiceXdir [i]、DiceXspeed [i]、true); DoStep(DiceYpos [i]、DiceYdir [i]、DiceYspeed [i]、true); } // Wrfel-Augen anzeigen //ダイスポイントを表示lc.clearDisplay(0); for(int i =0; i <6; i ++){ShowDot(int(DiceXpos [i])、int(DiceYpos [i])、true); }} void setup(){// Der MAX7219 ist beim Starten im Power-Saving Modus、// er muss aufgewecktwerden。 // MAX7219は起動時に省電力モードになっています、//ウェイクアップ呼び出しを行う必要がありますlc.shutdown(0、false); // Helligkeit auf einen Mittelwert //明るさを中程度の値に設定しますlc.setIntensity(0、8); // und Display lschen //そして表示をクリアしますlc.clearDisplay(0); randomSeed(analogRead(0)); DiceValue =0; for(int i =0; i <6; i ++){DiceXpos [i] =DicePic [7] [i] [0]; DiceYpos [i] =DicePic [7] [i] [1]; DiceXdir [i] =random(3)-1; DiceYdir [i] =random(3)-1; DiceXspeed [i] =random(126)+120; DiceYspeed [i] =random(126)+120; } // Pins einstellen //ピンを設定しますpinMode(PinTiltX、INPUT_PULLUP); pinMode(PinTiltY、INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(PinTiltX)、SetSpeedX、CHANGE); attachInterrupt(digitalPinToInterrupt(PinTiltY)、SetSpeedY、CHANGE); lc.clearDisplay(0);タイムスタンプ=ミリス();モード=1; ShowDicePic(6); delay(1000); lc.clearDisplay(0);モード=0; Serial.begin(9600); step =0; shakes =0;} void loop(){delay(50); step =step + 1; if(step> 20){// 1 sek ist vorbei // 1秒がstep =0を超えています; ShakesPerSecond =シェイク; shakes =0; } if(Mode ==0){MoveDots(); if(millis()-timestamp> 2000){// 2 sek kein Schttelnmehrを設定します// 2秒なので揺れはありませんMode =1; DiceValue =random(6)+1; ShowDicePic(DiceValue); }} if(ShakesPerSecond> 5){// Es wird wieder geschttelt //もう一度振るMode =0; }}
カスタムパーツとエンクロージャー
回路図
これは回路の私のスケッチです。 製造プロセス