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

8x8x8 RGBLEDキューブ

コンポーネントと消耗品

>
RGB拡散共通アノード
× 512
DM13ALEDドライバー
× 12
74HC138 3〜8行のデコード
× 1
IRF9640PチャネルMOSFET
× 8
Arduino UNO
ATmega328、16Mhzクリスタル、2 x22pfコンデンサーだけでブレッドボードバージョンを作成することもできます
× 1
Digilent 5V 2.5A Switching Power Supply
× 1
抵抗10kオーム
× 8
抵抗1kオーム
× 8
抵抗100オーム
× 8

アプリとオンラインサービス

>
Arduino IDE

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

ビデオ

ビルド

このビルドは、Kevin DarrahRGBキューブに触発されました。

<図>

ケビンの体格を見ると、彼の忍耐力には限界がないはずです。残念ながら、私の忍耐力には限界があります。

24個のシフトレジスタ、192個のトランジスタ、640個の抵抗を12個のDM13a LEDドライバ(eBayでそれぞれ約1米ドル)に交換することにしました。

<図>

キューブ自体は、Kevinが次のビデオで説明しているように構築されました:

<図>

キューブができたら、DM13Aドライバーチップとキューブ自体を保持するトナー方式を使用してプリント回路基板を作成しました。スルーホールメッキを施した市販のボードのコストを支払うのではなく、ワイヤラップワイヤを使用して各LED接続を適切なDM13Aピンに手作業で配線することにしました。含まれているEagleファイルには、手動で配線されたバージョンと自動ルーティングされたバージョン(テストされていない)が含まれています。

<図> <図>

マイクロプロセッサとアノードボードには、MSGEQ7-7バンドグラフィックイコライザーとマイクプリアンプも搭載されています。これらは将来実験する予定です。現在、使用されていません。市販のUNOまたはNanoボードを使用する場合、必要なのは74HC138 3〜8ラインデコーダーと8つのPチャネルMOSFETおよび関連する抵抗器だけです。必要に応じて、これらをプロトボードに配線することもできます。

5V20W電源はeBayで購入しました。ケースは40mmx9mmのドレスパインで作りました。

<図>

Kevinのキューブソフトウェアにいくつかのアニメーションを追加しましたが、基本的には変更されていません。

結論

600 x5mmのCommonAnode拡散RGBLEDをeBayから約$ 30USで購入できるはずです。電子機器を簡素化した後でも、キューブの構築には非常に時間がかかりましたが、最終的にはやりがいがありました。

コード

  • Cube_8x8x8_V1.ino
Cube_8x8x8_V1.ino C / C ++
 / * KevinDarrahLatestV12による作業に基づくJohnBradnamによる8x8x8RGB LED Cubeリリースノート:V11-BAMタイミングのバグを修正-ブランクピンのセットアップをISRに移動し、V12ビット単位の操作に書き込まれるまでピンがデッドになるように設定ピンLOWは正しくありませんでしたPORTx&=〜(1 < // SPIライブラリシフトレジスタにデータをクロックアウトするために使用されます#defineLATCH_PIN 2 //シフトレジスタをラッチしたい任意のピンを使用できます#defineBLANK_PIN 4 //同じ、これに必要な任意のピンを使用できます。 1k〜5V#define DATA_PIN 11 // SPIで使用、ピン11である必要があります#define CLOCK_PIN 13 // SPIで使用、13#define LAYER_A 5 // 74138 A Input#define LAYER_B 6 // 74138 A Input# define LAYER_C 7 // 74138 A Input#define SWITCH_PGM 10 // PB2#define SWITCH_SEQ 9 // PB1#define CUBE_SIZE 8 // cube#defineの列、行、またはレベルの数CUBE_MAX(CUBE_SIZE-1)//最大キューブインデックス#defineLEDS_PER_LEVEL(CUBE_SIZE * CUBE_SIZE)//レベルごとのLEDの数// ***変数***変数***変数***変数***変数** *変数***変数***変数//これらの変数は多重化とビット角度変調コードによって使用されます//これはすべてのLEDの輝度が保存される方法です//各LEDはそれを知るために「ビット」のみを必要としますオンまたはオフにする必要があるため、64バイトで512ビット=512 LED // 4ビットの解像度を使用してLEDを変調しているため、各色には64ビットの各バイトを含む4つのアレイがありますred0 [LEDS_PER_LEVEL]、red1 [LEDS_PER_LEVEL]、red2 [LEDS_PER_LEVEL]、red3 [LEDS_PER_LEVEL]; byte blue0 [LEDS_PER_LEVEL]、blue1 [LEDS_PER_LEVEL]、blue2 [LEDS_PER_LEVEL]、blue3 [LEDS_PER_LEVEL]; byte green0 [LEDS_PER_LEVEL]、green1 [LEDS_PER_LEVEL]、green2 [LEDS_PER_; //解像度が高くなると貴重なRAMintレベル=0が消費されることに注意してください; //データをintanodLevel =にシフトするレベルを追跡します0; //これはアノードレベルを介して増分しますintBAM_Bit、BAM_Counter =0; // thingsintアニメーションを追跡するためのビット角度変調変数=0; //メインループでアニメーションを追跡します// **** setup **** setup **** setup **** setup **** setup **** setup **** setup **** setup **** setup **** setup **** setup **** setup **** setupvoid setup(){SPI.setBitOrder(MSBFIRST); //最上位ビットファーストSPI.setDataMode(SPI_MODE0); //モード0データの立ち上がりエッジ、クロックを低く保ちますSPI.setClockDivider(SPI_CLOCK_DIV2); //データを16MHz / 2〜8MHzで実行します//Serial.begin(115200); //必要に応じて? noInterrupts(); //全員が設定されるまで割り込みを強制終了//タイマー1を使用してキューブを更新しますTCCR1A =B00000000; //ピンを切り替えないためAをすべて0に登録しますTCCR1B =B00001011; //ビット3セットCTCモードに設定するには、カウンターマッチで割り込みを呼び出します//ビット0と1はクロックを64で除算するように設定されているため、16MHz / 64 =250kHz TIMSK1 =B00000010; //ビット1は割り込みを呼び出すように設定されていますOCR1AはOCR1A =30と一致します。 //これで遊ぶことができますが、30に設定します。つまり、//クロックは250kHzで動作します。つまり、1 / 250kHz =4us // OCR1Aを30に設定すると、割り込みが毎回呼び出されることを意味します( 30 + 1)x4us =124us、//約8kHzのマルチプレックス周波数を提供//最終的に出力を設定pinMode(LATCH_PIN、OUTPUT); //ラッチpinMode(DATA_PIN、OUTPUT); // MOSI DATA pinMode(CLOCK_PIN、 OUTPUT); // SPIクロックpinMode(LAYER_A、OUTPUT); // 74138 A入力pinMode(LAYER_B、OUTPUT); // 74138 B入力pinMode(LAYER_C、OUTPUT); // 74138 C入力digitalWrite(LAYER_A、LOW); digitalWrite(LAYER_B、LOW); digitalWrite(LAYER_C、LOW); pinMode(SWITCH_PGM、INPUT); // PGM 1 / PGM 2スイッチpinMode(SWITCH_SEQ、INPUT); // SEQ / COLORスイッチ// pinMode(BLANK_PIN、OUTPUT); //出力これを最後に行うことが重要であるため、LEDは起動時にフラッシュしないSPI.begin(); // SPIライブラリの割り込みを起動する(); //ショーを開始します。これにより、多重化が開始されます} // ***ループの開始***ループの開始*** start loop *** start loop *** start loop *** start loop *** start loop *** start loop *** start loopvoid loop(){//サブルーチン内にある各アニメーション//制御するにはLED、単純に:// LED(必要なレベル0-CUBE_MAX、必要な行0-CUBE_MAX、必要な列0-CUBE_MAX、赤の明るさ0-15、緑の明るさ0-15、青の明るさ0-15); if(digitalRead(SWITCH_PGM)==HIGH)test_leds(); else {clean();アニメーション=アニメーション+1;スイッチ(アニメーション){ケース1:rainVersionTwo(20);壊す;ケース2:folder(10);壊す;ケース3:sinwaveTwo(15);壊す;ケース4:randomColor(10);壊す;ケース5:wipe_out(10);壊す;ケース6:bouncyvTwo(15);壊す;ケース7:color_wheelTWO(10);壊す;ケース8:harlem_shake();壊す;ケース9:リップル(10);壊す;ケース10:アニメーション=0;壊す; }}} // **** LEDルーチン**** LEDルーチン**** LEDルーチン**** LEDルーチンvoidLED(int level、int row、int column、byte red、byte green、byte blue){ //これがすべての始まりです//このルーチンはLEDが更新される方法であり、LEDの位置とそのRGおよびBの輝度レベルの入力を使用します//まず、制限を超えていないことを確認し、場所の場合は0または7、輝度レベルの場合は0または15 =Constraint(level、0、CUBE_MAX);行=制約(行、0、CUBE_MAX);列=制約(列、0、CUBE_MAX);赤=制約(赤、0、15);緑=制約(緑、0、15);青=制約(青、0、15); //キューブには(CUBE_SIZE * CUBE_SIZE * CUBE_SIZE)LEDがあるため、レベル2、列5、行4に書き込む場合は、0から(CUBE_SIZE * CUBE_SIZE * CUBE_SIZE)-1までの数値に変換する必要があります。 //第1レベルのLEDが最初に順番に表示され、次に第2レベル、次に第3レベル、というように続きます。//4x 4 x 4キューブの場合、(レベル*(4 * 4))は、レベルの開始位置を示すものです。したがって、レベル0はLED 0〜15、レベル1はLED 16〜31などです。//立方体を見下ろし、最下位レベルのみを見た場合// 00 01 02 03 // 04 05 06 07 / / 08 09 10 11 // 12 13 14 15 // 8 x 8 x 8キューブの場合、(レベル*(8 * 8))はレベルの開始位置を示すものであるため、レベル0はLED 0〜63、レベル1です。 LED 64〜127などです。//立方体を見下ろし、最下層のみを見た場合// 00 01 02 03 04 05 06 07 // 08 09 10 11 12 13 14 15 // 16 17 18 19 20 21 22 23 // 24 25 26 27 28 29 30 31 // 32 33 34 35 36 37 38 39 // 40 41 42 43 44 45 46 47 // 48 49 50 51 52 53 54 55 // 56 57 58 59 60 61 62 63 //次に、レベルをインクリメントすると、上のグリッドの右上は(CUBE_SIZE * CUBE_SIZE)で始まります//これを行う理由は、そうしないためです。各LEDの数値を記憶して、レベル、行、列を使用できるようにする必要があります。//では、8で割った値はどうでしょうか。 // ...まあ、1バイトあたり8ビットで、各LEDに必要な512ビットすべてに対して64バイトのメモリがあるので、//見つけた数を8で割り、その整数を取ります。したがって、どのバイトが、そのビットが//混乱して配置されているかがわかりますか?それは大丈夫です、例を見てみましょう。キューブ内の最後のLEDにLEDを書き込みたい場合は、7、7、7 //(7 * 64)+(7 * 8)=7 =を与えます。 511、これは正しいですが、今度は8で除算して511/8 =63.875とし、その整数をとると、63が得られます。//これは配列の最後のバイトです。これは正しいので、最後のLED // LED番号を取得0-511int integer =(level * LEDS_PER_LEVEL)+(row * CUBE_SIZE)+ column; //インデックスを配列に取得します。インデックスが付けられた各位置は、1バイトまたは8ビットを保持します。 int whichbyte =int(wholebyte / 8); int whichbit =(wholebyte&7); //これはすべて1秒で意味があります//これは4ビットの色解像度であるため、各色にはx4 64バイト配列が含まれます。以下の説明:bitWrite(red0 [whichbyte]、whichbit、bitRead(red、0)); bitWrite(red1 [whichbyte]、whichbit、bitRead(red、1)); bitWrite(red2 [whichbyte]、whichbit、bitRead(red、2)); bitWrite(red3 [whichbyte]、whichbit、bitRead(red、3)); bitWrite(green0 [whichbyte]、whichbit、bitRead(green、0)); bitWrite(green1 [whichbyte]、whichbit、bitRead(green、1)); bitWrite(green2 [whichbyte]、whichbit、bitRead(green、2)); bitWrite(green3 [whichbyte]、whichbit、bitRead(green、3)); bitWrite(blue0 [whichbyte]、whichbit、bitRead(blue、0)); bitWrite(blue1 [whichbyte]、whichbit、bitRead(blue、1)); bitWrite(blue2 [whichbyte]、whichbit、bitRead(blue、2)); bitWrite(blue3 [whichbyte]、whichbit、bitRead(blue、3)); //今はもっと混乱していますか?あなたはすべきではありません!それは今意味をなし始めています。各行がbitWriteであることに注意してください。つまり、// bitWrite(書き込みたいバイト、書き込みたいバイトのビット、書き込みたい0または1)//これは「whichbyte」を意味します。 0から51までのLEDに対応するビットが0から63までのバイトです//なぜそれをしたのか、今では意味がありますか?各LEDは// 64バイトの配列のビットを表すため、0〜511の値を取得して0〜63の値に変換します。 //次の行はどのビットです 'wholebyte-(8 * whichbyte)' //これは単にLEDの値0-511を取得し、そのビットが8回目に配置されたBYTEからサブプラクティスします//考えてみてください63には504から511までのLEDが含まれるため、505-(8 * 63)を使用すると、1が得られます。これは、// LED番号505が配列のバイト63のビット1にあることを意味します。それ?いいえ、書き込もうとしている明るさ0〜15のbitReadを実行する必要があります。//15をREDに書き込んだ場合、そのLEDの4つのアレイすべてにそのビットが1になり、オンになります。 100%//これが、4つの配列がRED、GREEN、およびBLUEに入力された値の0〜4を読み取る理由です//うまくいけば、これはすべて意味がありますか?} // *** MultiPlex BAM *** MultiPlex BAM ** * MultiPlex BAM *** MultiPlex BAM *** MultiPlex BAM *** MultiPlex BAM *** MultiPlex BAMISR(TIMER1_COMPA_vect){//このルーチンは、OCR1Aによって設定された頻度でバックグラウンドで自動的に呼び出されます//このコードでは、 OCR1Aを30にすると、これは124usごとに呼び出され、キューブ内の各レベルにオン時間の124usを与えます// 8つのレベルがあるため、次のレベルがオン//多重化の周波数は124us * 8 =992us、または1 / 992us =約1kHzPORTD | =1 < =CUBE_SIZE){fx =CUBE_MAX; fxm =-1; } 壊す;ケース1:fy =fy + fym; if(fy <0){fy =0; fym =1; } if(fy> =CUBE_SIZE){fy =CUBE_MAX; fym =-1; } 壊す;ケース2:fz =fz + fzm; if(fz <0){fz =0; fzm =1; } if(fz> =CUBE_SIZE){fz =CUBE_MAX; fzm =-1; } 壊す; } switch(random(3)){case 0:ftx =ftx + ftxm; if(ftx <0){ftx =0; ftxm =1; } if(ftx> =CUBE_SIZE){ftx =CUBE_MAX; ftxm =-1; } 壊す;ケース1:fty =fty + ftym; if(fty <0){fty =0; ftym =1; } if(fty> =CUBE_SIZE){fty =CUBE_MAX; ftym =-1; } 壊す;ケース2:ftz =ftz + ftzm; if(ftz <0){ftz =0; ftzm =1; } if(ftz> =CUBE_SIZE){ftz =CUBE_MAX; ftzm =-1; } 壊す; }} // while clean();} // wipeout // **** rainVersionTwo **** rainVersionTwo **** rainVersionTwo **** rainVersionTwo **** rainVersionTwovoid rainVersionTwo(int runtimeInSeconds){int x [LEDS_PER_LEVEL ]、y [LEDS_PER_LEVEL]、z [LEDS_PER_LEVEL]、ledcolor; int xx [LEDS_PER_LEVEL]、yy [LEDS_PER_LEVEL]、zz [LEDS_PER_LEVEL]、xold [LEDS_PER_LEVEL]、yold [LEDS_PER_LEVEL]、zold [LEDS_PER_LEVEL]; for(int addr =0; addr  =200 &&ledcolor <300){for(int addr =0; addr  =300 &&ledcolor <400){} if(ledcolor> =500 &&ledcolor <600){} ledcolor ++; if(ledcolor> =300)ledcolor =0; for(int addr =0; addr  

回路図

eagle_files_WfqPEUP7Mp.zip

製造プロセス

  1. 喉の渇き警報プラント警報
  2. 5x5x5LEDキューブ
  3. イタリア語の単語時計
  4. SigfoxkWhメーター
  5. ArduinoRGBカラーミキサー
  6. Bluetooth温度モニター
  7. DMX RGBLED屋外
  8. ジェスチャー制御ロック
  9. コンパニオンIC
  10. Arduino用の絶縁アナログ入力
  11. 反応時間を測定する