BAB 4 PERANCANGAN
4.1
Membangun Proyek
Salah satu perangkat elektronik DIY jolliFactory hadir dengan
Bi-color LED Matrix
Driver Module Kit. Modul ini dirancang agar bisa berantai
sehingga An- da dapat menyusun
modul dengan jumlah
modul yang sesuai dengan proyek
Anda.
Berikut adalah beberapa proyek yang dibangun meng- gunakan modul Bi-color LED Matrix Driver ini:
- Instruksikan untuk membangun 7 Bi-color LED Ma- trix Scrolling Text Display.
- Instruksikan untuk membangun Input Suara Ardu- ino Bi-color LED Matrix Scrolling Text Display (Blue- tooth + Android) Instruksikan untuk membangun Vi- sualizer Visual Matrix Audio Matrix berbasis Arduino Sungguh menakjubkan melihat-lihat instruksional dan menemukan proyek yang mungkin menarik minat dan mengilhami Anda untuk memulai proyek atau me- micu gagasan baru untuk proyek Anda.
Tetris adalah permainan video teka-teki yang di- sesuaikan dengan ubin yang
dirilis pada tahun 1984 dan merupakan versi
genggam yang sangat sukses un- tuk Game Boy yang diluncurkan pada tahun 1989 yang
membuat game ini sebagai salah satu yang paling po- puler.
Hanya untuk
FUN, kami pikir kami bisa memba- ngun game Tetris
sederhana dengan memasang dua modul
Bi-warna LED Matrix Driver bersama-sama yang
digerakkan oleh mikrokontroler Arduino hanya
dengan mengadaptasi proyek
serupa yang ditemukan di instruk- sinya. Kami mencari
melalui petunjuk di sini tapi tidak
berhasil menemukan proyek Tetris yang serupa untuk dikerjakan.
Kami memperluas pencarian kami ke situs online lainnya dan berhasil menemukan beberapa informasi
yang kami adaptasikan untuk membangun
permainan Tetron LED Matrix Tetris sederhana berbasis Arduino di sini.
Untuk membangun proyek ini, pengetahuan elek- tronika dasar
dengan keahlian penyalur komponen elek-
tronik dan beberapa pengetahuan tentang penggunaan Arduino diperlukan.
Untuk membangun proyek ini, pengetahuan elek- tronika dasar
dengan keahlian penyalur komponen elek-
tronik dan beberapa pengetahuan tentang penggunaan Arduino diperlukan. berikut komponen elektroniknya:
4.1.1Bangun Bi-warna LED Matrix Dri- ver Module
Kami akan membangun dua game Matrix Tetris tinggi di sini didorong oleh Arduino Nano
untuk pro- yek ini. Kita membutuhkan dua Bi-color
(Red / Gre- en) LED Matrix Driver
Module Kit dari jolliFactory. Masing-masing modul
ini menggunakan dua MAX7219
Display Driver ICs untuk mengemudikan Bi-color
LED Matrix. IC ini sangat bagus karena mereka membu- tuhkan banyak kerja dari mikrokontroler dan menye- derhanakan
desain pengkabelan dan logika.
Anda bisa menemukan Bi-color LED Matrix Dri- ver Module kit dari sini. Kit ini hadir dengan semua komponen melalui lubang dan seseorang
dengan kete- rampilan solder dasar harus dapat
merakitnya tanpa banyak kesulitan.
4.1.2 Pengkabelan
Setelah semua kit Modul Matrix
Driver LED sele- sai, mereka terhubung bersamaan dengan mikrokon-
troler Arduino Nano seperti yang ditunjukkan pada diagram pengkabelan (Matriks
LED tidak terpasang untuk tampilan yang lebih baik).
Untuk keluaran audio game, kami menggunakan sa- tu speaker
8 ohm 0,5 watt yang digerakkan langsung oleh salah satu
pin digital Arduino
melalui resistor 100 ohm. Nada suara dasar digunakan
untuk proyek ini dan volume suara rendah harus cukup untuk permain- an genggam dengan pengaturan
sederhana ini.
Empat Panel SPST Panel Sentuh
Tombol Push But- ton diperlukan untuk proyek
navigasi dan rotasi
blok Tetris.
Perhatikan penggunaan resistor pull-down 10Kohms pada pin
input DATA IN, CLK dan LOAD. Saat po-
wer
pertama kali diaplikasikan pada micro-controller
atau saat reset, garis I / O saya mengapung. The MAX7219 dapat melihat
ini sebagai data yang valid dan menampilkan sampah sampai kendali
mikro kon- trol kontrol. Resistor pull-down mencegah masalah
ini. Untuk mengurangi jumlah bagian proyek ini,
Anda da- pat mencoba tanpa
resistor pull-down 10Kohms
untuk jalur input DATA IN dan CLK.
Kecuali dua modul Bi-warna LED Matrix Driver dan empat tombol push switch, kami menghubungk-
an keseluruhan rangkaian
pada bagian kecil perf-board
berukuran 60mm x 60mm.
Perhatikan bahwa ada empat tombol mount mount PCB pada perf-board di foto. Awalnya
kami meng- gunakannya untuk kontrol
permainan namun setelah membangun kandang sederhana untuk permainan, ka- mi
memutuskan untuk menggunakan empat panel mo- unt tombol
push, bukan untuk
kontrol permainan yang lebih baik. Kami sejajar
memasang tombol push mo- unt panel
dengan tombol tekan mount PCB sehing- ga
kontrol permainan sekarang bisa dilakukan dengan menggunakan tombol
tekan panel PCB
atau panel.
Edit: Bagi yang tidak mau main-main dengan ka- bel
yang terlalu banyak menggunakan
perf-board, jolli- Factory
telah merancang papan
PCB antarmuka yang pas untuk membangun proyek ini. Jika Anda meng- gunakan papan
PCB antarmuka ini, ingatlah untuk mengubah output speaker pin digital dari D9 ke D8 pada
sketsa yang didownload dari instruksinya ini ke drive speaker.
4.1.3 Memprogram
Dewan Arduino
Dewan Arduino perlu dimuat
dengan sketsa Ardu- ino untuk menjalankan display.Kami menggunakan Arduino
IDE V1.03 untuk pro- yek kami. Download
sketsa Arduino di bawah untuk
proyek ini.Download jollifactory_Tetris_V1_1.ino
Sketsa permainan Tetris yang kita miliki
di sini sa- ngat
mendasar tanpa tingkat
permainan dan skor.
Anda dapat mengubah dan meningkatkan sketsa.Catatan: Memiliki beberapa masalah dengan modul
Matrix LED Bi-warna
Anda? Download program uji berikut untuk menguji setiap
modul Anda seca- ra terpisah. Layar harus
menyala RED, GREEN dan ORANGE di urutan baris demi baris untuk mengisi keseluruhan tampilan berulang-ulang.
4.14 Sintak
Program
/* Tetris Code
Adapted from Tetris.ino code by
Jae Yeong Bae UBC ECE jocker.tistory.com
/* =============== LED Matrix Display
=============== */
#include <SPI.h>
#define GREEN 0
#define RED 1
#define offREDoffGREEN 0
#define offREDonGREEN 1
#define onREDoffGREEN 2
#define ISR_FREQ 190 //190=650Hz // Sets the speed of the ISR
int SPI_CS = 10;// This SPI Chip Select pin con- trols the
MAX7219
int bi_maxInUse = 2; //No. of Bi-color LED Ma- trix used
int maxInShutdown = RED; // indicates which LED
Matrix color is currently off
int SetbrightnessValue = 15; int colorMode = ’3’;
// default color (1 = RED, 2 = GREEN, 3 = ORA- NGE, 4 = blank off)
/* =========Audio ===============*/
int speakerOut = 9;
#define mC 1911
#define mC1 1804
#define mD 1703
#define mEb 1607
#define mE 1517
#define mF 1432
#define mF1 1352
#define mG 1276
#define mAb 1204
#define mA 1136
#define mBb 1073
#define mB 1012
#define mc 955
#define mc1 902
#define md 851
#define meb 803
#define me 758
#define mf 716
#define mf1 676
#define mg 638
#define mab 602
#define ma 568
#define mbb 536
#define mb 506
#define mp 0 //pause
/* ============= Tetris Game =============
*
/ long delays = 0; short delay_ = 500; long bdelay = 0;
short
buttondelay = 150; short btdowndelay = 30; short btsidedelay = 80; unsigned char blocktype; unsigned char blockrotation; boolean block[8][18];
//2 extra for
rotation boolean pile[8][16]; boolean disp[8][16];
boolean
gameoverFlag = false; boolean selectColor = RED;
unsigned long
startTime; unsigned long elapsedTime; int cnt = 0;
int buttonRotate = 4;
// Rotate int buttonRight = 5;
// Right int buttonLeft = 6;
// Left int buttonDown = 7;
//
Down
//*******************************
void setup() { pinMode(SPI_CS,
OUTPUT); pinMode(speakerOut, OUTPUT); TriggerSound();
Serial.begin (9600);
Serial.println(”jolliFactory Tetris LED Matrix Ga- me example 1.1”);
SPI.begin();
//setup SPI
Interface bi_maxTransferAll(0x0F, 0x00);
// 00 - Turn off Test mode bi_maxTransferAll(0x09, 0x00);
//Register 09 - BCD Decoding
// 0 = No decoding bi_maxTransferAll(0x0B, 0x07);
//Register
B - Scan limit 1-7 //
7 = All LEDS bi_maxTransferAll(0x0C, 0x01); // 01 = on 00 = Power saving mode or shutdown
setBrightness();
setISRtimer();
//
setup the timer startISR();
// start
the timer to toggle shutdown clearDisplay(GREEN);
clearDisplay(RED);
int seed
= (analogRead(0)+1)* (analogRead(1)+1)* (analogRead(2)+1)* (analogRead(3)+1);
randomSeed(seed);
random(10,9610806);
seed = seed
*random(3336,15679912)+analogRead(ran- dom(4)) ;
randomSeed(seed); random(10,98046); cli();
//stop interrupts
//set
timer0 interrupt at 2kHz TCCR1A = 0;
// set entire TCCR0A register to 0 TCCR1B = 0;
// same for TCCR0B TCNT1 = 0;
//initialize counter value to 0
// set compare match register for 2khz increments OCR1A = 259;
// = (16*10^6) / (2000*64) - 1 (must be <256)
// turn on CTC mode TCCR1A |= (1 « WGM01);
// Set CS11 and CS10 bits for 1024 prescaler TCCR1B
|= (1 « CS12) | (1
« CS10);
// enable timer compare interrupt TIMSK1 |=
(1
« OCIE0A);
sei();
//allow interrupts
pinMode(buttonRotate,
INPUT_PULLUP);
// Rotate pinMode(buttonRight, INPUT_PULLUP);
// Right
pinMode(buttonLeft, INPUT_PULLUP);
// Left pinMode(buttonDown,
INPUT_PULLUP);
//
Down newBlock(); updateLED(); }
//******************************* void loop() { delay(30);
if (delays < millis()) { delays = millis() + delay_; movedown(); }
//buttun actions int button = readBut(); if (button
== 1)
//up=rotate rotate();
if (button == 2) //right=moveright moveright(); if
(button == 3) //left=moveleft moveleft();
if (button == 4) //down=movedown movedown();
}
//******************************* boolean moveleft() { TriggerSound();
if (space_left()) { int i; int j; for (i=0;i<7;i++) {
for (j=0;j<16;j++) { block[i][j]=block[i+1][j];
}
}
for (j=0;j<16;j++) { block[7][j]=0; } updateLED(); return 1; }
return 0; }
//******************************* boolean
moveright() { TriggerSound();
if (space_right()) { int i; int j; for (i=7;i>0;i–) { for (j=0;j<16;j++) { block[i][j]=block[i-1][j]; } }
for (j=0;j<16;j++) { block[0][j]=0; } updateLED();
return 1; }
return 0; }
//*******************************
int readBut() { if (bdelay > millis()) { return 0;
}
if ((digitalRead(buttonLeft) == LOW)) { //left bdelay = millis() + btsidedelay; return
2; }
if ((digitalRead(buttonDown) == LOW)) { //do- wn bdelay = millis() + btdowndelay; return
4; }
if ((digitalRead(buttonRight) == LOW)) {
//right bdelay = millis() + btsidedelay; return 3; }
if ((digitalRead(buttonRotate)
== LOW)) { //ro-
tate bdelay = millis()
+ buttondelay; return
1; } return 0; }
//*******************************
void updateLED() { int i; int j; for (i=0;i<8;i++)
{ for (j=0;j<16;j++) { disp[i][j] = block[i][j] |
pile[i][j];
} } }
//*******************************
void
rotate() { TriggerSound(); //skip for square block(3) if (blocktype == 3) return;
int xi; int yi;
int i; int j;
//detect left for (i=7;i>=0;i–) { for (j=0;j<16;j++)
{ if (block[i][j]) { xi = i; } } }
//detect up for (i=15;i>=0;i–) { for (j=0;j<8;j++)
{ if (block[j][i]) { yi = i; } } }
if (blocktype == 0) { if (blockrotation == 0) { if (!space_left()) {
if (space_right3()) {
if (!moveright()) return;
xi++; } else
return; } else if (!space_right()) {
if (space_left3()) {
if (!moveleft()) return;
if (!moveleft()) return;
xi–; xi–; } else return;
}
else if (!space_right2()) { if (space_left2()) {
if (!moveleft()) return;
xi–; } else return;
} block[xi][yi]=0; block[xi][yi+2]=0; block[xi][yi+3]=0; block[xi-1][yi+1]=1;
block[xi+1][yi+1]=1; block[xi+2][yi+1]=1; blockrotation = 1; } else
{ block[xi][yi]=0; block[xi+2][yi]=0; block[xi+3][yi]=0; block[xi+1][yi-1]=1;
block[xi+1][yi+1]=1; block[xi+1][yi+2]=1; blockrotation = 0; } }
//offset to mid xi ++; yi ++;
if (blocktype == 1) {
if (blockrotation == 0) { block[xi-1][yi-1] = 0;
block[xi-1][yi] = 0;
block[xi+1][yi] = 0;
block[xi][yi-1] = 1;
block[xi+1][yi-1] = 1;
block[xi][yi+1] = 1; blockrotation = 1; }
else if (blockrotation == 1) {
if (!space_left()) {
if (!moveright()) return; xi++; } xi–; block[xi][yi-1]
= 0;
block[xi+1][yi-1] = 0;
block[xi][yi+1] = 0;
block[xi-1][yi] = 1;
block[xi+1][yi] = 1;
block[xi+1][yi+1] = 1; blockrotation = 2; }
else if (blockrotation == 2)
{ yi –; block[xi-1][yi] = 0; block[xi+1][yi] = 0;
block[xi+1][yi+1] = 0;
block[xi][yi-1] = 1;
block[xi][yi+1] = 1;
block[xi-1][yi+1] = 1; blockrotation = 3; }
else { if (!space_right()) {
if (!moveleft()) return;
xi–; } block[xi][yi-1]
= 0;
block[xi][yi+1] = 0;
block[xi-1][yi+1] = 0;
block[xi-1][yi-1] = 1;
block[xi-1][yi] = 1;
block[xi+1][yi] = 1; blockrotation = 0; } }
if (blocktype == 2)
{ if (blockrotation == 0) { block[xi+1][yi-1] = 0; block[xi-1][yi]
= 0;
block[xi+1][yi] = 0;
block[xi][yi-1] = 1;
block[xi+1][yi+1] = 1;
block[xi][yi+1] = 1; blockrotation = 1;
} else
if (blockrotation == 1) { if (!space_left()) {
if (!moveright()) return; xi++; } xi–; block[xi][yi-1] = 0; block[xi+1][yi+1] = 0;
block[xi][yi+1] = 0;
block[xi-1][yi] = 1;
block[xi+1][yi] = 1;
block[xi-1][yi+1] = 1; blockrotation = 2; }
else
if (blockrotation == 2) { yi –; block[xi-1][yi] =
0;
block[xi+1][yi] = 0;
block[xi-1][yi+1] = 0;
block[xi][yi-1] = 1;
block[xi][yi+1] = 1;
block[xi-1][yi-1] = 1; blockrotation = 3; } else { if (!space_right())
{ if (!moveleft()) return; xi–; } block[xi][yi-1] = 0;
block[xi][yi+1] = 0;
block[xi-1][yi-1] = 0;
block[xi+1][yi-1] = 1;
block[xi-1][yi] = 1;
block[xi+1][yi] = 1; blockrotation = 0; } }
if (blocktype == 4) { if (blockrotation == 0)
{ block[xi+1][yi-1] = 0; block[xi-1][yi]
= 0;
block[xi+1][yi] = 1;
block[xi+1][yi+1] = 1; blockrotation = 1; }
else
{ if (!space_left()) { if (!moveright()) return; xi++; } xi–; block[xi+1][yi] = 0;
block[xi+1][yi+1] = 0;
block[xi-1][yi] = 1;
block[xi+1][yi-1] = 1; blockrotation = 0; } }
if (blocktype == 5)
{ if (blockrotation == 0)
{ block[xi][yi-1] = 0;
block[xi-1][yi] = 0;
block[xi+1][yi] = 0;
block[xi][yi-1] = 1;
block[xi+1][yi] = 1;
block[xi][yi+1] = 1; blockrotation = 1; }
else if (blockrotation == 1)
{ if (!space_left())
{ if (!moveright()) return; xi++; } xi–; block[xi][yi-1] = 0;
block[xi+1][yi] = 0;
block[xi][yi+1] = 0;
block[xi-1][yi] = 1;
block[xi+1][yi] = 1;
block[xi][yi+1] = 1; blockrotation = 2; }
else if (blockrotation == 2)
{ yi –; block[xi-1][yi] = 0; block[xi+1][yi] = 0;
block[xi][yi+1] = 0;
block[xi][yi-1] = 1;
block[xi-1][yi] = 1;
block[xi][yi+1] = 1; blockrotation = 3; }
else { if (!space_right()) {
if (!moveleft()) return;
xi–; } block[xi][yi-1]
= 0;
block[xi-1][yi] = 0;
block[xi][yi+1] = 0;
block[xi][yi-1] = 1;
block[xi-1][yi] = 1;
block[xi+1][yi] = 1; blockrotation = 0; } }
if (blocktype == 6)
{ if (blockrotation == 0)
{ block[xi-1][yi-1] = 0;
block[xi][yi-1] = 0;
block[xi+1][yi-1] = 1;
block[xi][yi+1] = 1; blockrotation = 1; }
else { if (!space_left()) {
if (!moveright()) return; xi++; } xi–; block[xi+1][yi-1] = 0; block[xi][yi+1] = 0;
block[xi-1][yi-1] = 1;
block[xi][yi-1] = 1; blockrotation = 0; } }
//if rotating made
block and pile
overlap, push rows up while (!check_overlap()) { for (i=0;i<18;i++) { for
(j=0;j<8;j++) { block[j][i] = block[j][i+1]; } } delays
= millis() + delay_; }
updateLED(); }
//******************************* void movedown() {
if (space_below()) {
//move down int i; for (i=15;i>=0;i–) {
int j; for (j=0;j<8;j++)
{ block[j][i] = block[j][i-1]; } }
for (i=0;i<7;i++) { block[i][0] = 0; } }
else
{ //merge and new block int i; int j; for (i=0;i<8;i++)
{ for(j=0;j<16;j++) {
if (block[i][j]) { pile[i][j]=1; block[i][j]=0;
} } }
newBlock(); }
updateLED(); }
//*******************************
boolean check_overlap() { int i; int j;
for (i=0;i<16;i++)
{ for (j=0;j<7;j++) { if (block[j][i])
{ if (pile[j][i]) return false; } } }
for (i=16;i<18;i++) { for
(j=0;j<7;j++)
{ if (block[j][i]) { return false; } } }
return true; }
//******************************* void check_gameover() {
int i; int j;
int cnt=0;; for(i=15;i>=0; i–) { cnt=0;
for (j=0;j<8;j++) {
if (pile[j][i]) { cnt ++; } }
if (cnt == 8) { for (j=0;j<8;j++) { pile[j][i]=0; } updateLED();
delay(50); int k;
for(k=i;k>0;k–) { for (j=0;j<8;j++) {
pile[j][k] =
pile[j][k-1]; } }
for (j=0;j<8;j++) { pile[j][0] = 0;
} updateLED(); delay(50); i++; } } for(i=0;i<8;i++) {
if (pile[i][0])
gameover(); } return; }
//******************************* void gameover() {
int i; int j;
gameoverFlag = true; startTime =
millis(); delay(300);
while(true) //To re-play if any buttons depressed again { int button =
readBut();
if ((button <
5) && (button >
0)) { gameover- Flag = false; for(i=15;i>=0;i–) { for
(j=0;j<8;j++) { pile[j][i]=0; } }
break; } } }
//******************************* void newBlock() { check_gameover();
if (selectColor == RED) selectColor = GREEN; else selectColor = RED;
blocktype = random(7);
if (blocktype == 0) // 0 // 0 // 0 // 0 { block[3][0]=1;
block[3][1]=1;
block[3][2]=1;
block[3][3]=1; }
if (blocktype == 1) // 0 // 0 0 0 { block[2][0]=1; block[2][1]=1;
block[3][1]=1;
block[4][1]=1; }
if (blocktype == 2) // 0 // 0 0 0 { block[4][0]=1; block[2][1]=1;
block[3][1]=1;
block[4][1]=1; }
if (blocktype == 3) // 0 0 // 0 0 { block[3][0]=1; block[3][1]=1;
block[4][0]=1; block[4][1]=1; }
if (blocktype == 4) // 0 0 // 0 0 { block[4][0]=1; block[5][0]=1;
block[3][1]=1; block[4][1]=1; }
if (blocktype == 5) // 0 // 0 0 0 { block[4][0]=1; block[3][1]=1;
block[4][1]=1; block[5][1]=1; }
if (blocktype == 6) // 0 0 // 0 0 { block[3][0]=1; block[4][0]=1;
block[4][1]=1; block[5][1]=1; }
blockrotation = 0; }
//******************************* boolean space_below() { int i;
int j;
for (i=15;i>=0;i–) { for (j=0;j<8;j++) { if (block[j][i])
{ if (i == 15) return false;
if (pile[j][i+1]) { return false; } } } } return true; }
//*******************************
boolean spa- ce_left2() { int i;
int j;
for (i=15;i>=0;i–) { for (j=0;j<8;j++) { if (block[j][i])
{ if (j == 0 || j == 1) return false; if (pile[j-1][i] | pi- le[j-2][i]) { return false; } } } }
return true; }
//******************************* boolean space_left3() {
int i; int j;
for (i=15;i>=0;i–) { for (j=0;j<8;j++) { if (block[j][i])
{ if (j == 0 || j == 1 ||j == 2 ) return false;
if (pile[j-1][i] |
pile[j-2][i]|pile[j-3][i]) {
return false; }
} } }
return true; }
//******************************* boolean space_left() {
int i; int j;
for (i=15;i>=0;i–) { for (j=0;j<8;j++) { if (block[j][i])
{ if (j == 0) return false; if (pile[j-1][i]) { return false;
} } } }
return true; }
//******************************* boolean space_right() {
int i; int j;
for (i=15;i>=0;i–) { for (j=0;j<8;j++) { if (block[j][i])
{ if (j == 7) return false;
if (pile[j+1][i]) { return false; } } } } return true; }
//******************************* boolean space_right3() {
int i; int j;
for (i=15;i>=0;i–) { for (j=0;j<8;j++) { if (block[j][i])
{ if (j == 7||j == 6||j ==
5) return false;
if (pile[j+1][i] |pile[j+2][i] | pile[j+3][i]) { return
fal- se; } } } }
return true; }
//******************************* boolean space_right2() {
int i; int j;
for (i=15;i>=0;i–) { for (j=0;j<8;j++) { if (block[j][i])
{ if (j == 7 || j == 6) return false;
if (pile[j+1][i] |pile[j+2][i]) { return false;
} } } } return true; }
//******************************* ISR(TIMER1_COMPA_vect){ //change the 0 to
1 for timer1 and 2 for
timer2 LEDRefresh(); }
//******************************* void LEDRefresh() {
int i; int k;
boolean
tmpdispUpper[8][8]; boolean
tmpdispLower[8][8]; boolean
tmppileUpper[8][8]; boolean tmppileLower[8][8];
//rotate 90 degrees for upper Bicolor
LED matrix for
(k=0;k<8;k++) { for(i=0;i<8;i++) { tmpdispUp- per[k][i]=disp[i][k];
} }
//rotate 90 degrees for lower Bicolor LED matrix
for (k=8;k<16;k++) { for(i=0;i<8;i++) {
tmpdispLo- wer[k-8][i]=disp[i][k]; } }
//For pile //rotate 90
degrees for upper Bicolor LED matrix for (k=0;k<8;k++) { for(i=0;i<8;i++) { tmppileUpper[k][i]=pile[i][k]; } }
//rotate 90 degrees for lower Bicolor LED matrix
for (k=8;k<16;k++) { for(i=0;i<8;i++) { tmppileLo- wer[k-8][i]=pile[i][k]; } }
for(i=0;i<8;i++) { byte upper = 0; int b; for(b
= 0;b<8;b++) {
upper «= 1;
if
(tmpdispUpper[b][i]) upper |= 1; } byte lower
= 0;
for(b = 0; b<8;b++) {
lower «= 1;
if (tmpdispLower[b][i]) lower |=
1; }
if (gameoverFlag == true) { elapsedTime
= millis()
- startTime;
// Display
random pattern for pre-defined period before blanking display if (elapsedTime < 2000) { bi_ma-
xTransferSingle(RED, 1, i, random(255));
bi_maxTransferSingle(RED, 2, i, random(255)); bi_maxTransferSingle(GREEN, 1, i, random(255));
bi_maxTransferSingle(GREEN, 2, i, random(255));
cnt = cnt + 1; if (cnt > 80) { TriggerSound(); Trig-
gerSound(); cnt = 0; } }
else
{ bi_maxTransferSingle(RED, 1, i, 0x00);
//
clear bi_maxTransferSingle(RED, 2, i, 0x00);
// clear
bi_maxTransferSingle(GREEN, 1, i, 0x00);
// clear bi_maxTransferSingle(GREEN, 2, i, 0x00);
// clear } }
else
{ if (selectColor == RED)
{ bi_maxTransfer- Single(GREEN, 1, i, lower);
bi_maxTransferSingle(GREEN, 2, i, upper);
} else { bi_maxTransferSingle(RED, 1, i, lower); bi_maxTransferSingle(RED, 2, i, upper);
} } }
if (gameoverFlag == false) {
// For pile - to display
orange for(i=0;i<8;i++) { byte upper = 0; int b; for(b = 0;b<8;b++) { upper «= 1;
if
(tmppileUpper[b][i]) upper |= 1; } byte lower
= 0; for(b = 0;b<8;b++)
{ lower «= 1;
if (tmppileLower[b][i]) lower |=
1; }
// To alternate color of new block between
RED and GREEN if (selectColor == RED) { bi_maxTran- sferSingle(RED, 1, i, lower);
bi_maxTransferSingle(RED, 2, i, upper); }
else {
bi_maxTransferSingle(GREEN, 1, i, lower); bi_maxTransferSingle(GREEN, 2, i,
upper); }
} } }
//*******************************
// Change Max72xx brightness void setBrightness()
{
bi_maxTransferAll(0x0A, SetbrightnessValue);
//Set Brightness bi_maxTransferAll(0x00, 0x00);
//No-op commands }
//*******************************
// Clear Display
void clearDisplay(uint8_t whichCo- lor)
//whichColor = 1 for RED,
2 for GREEN { for
(int y=0; y<8; y++) { bi_maxTransferSingle(whichColor, 1, y, 0);
//Turn all Off //For X1 LED matrix Game bi_ma- xTransferSingle(whichColor, 2, y, 0);
//Turn all Off
//For
X1 LED matrix Game } }
//********************************
void bi_maxTransferAll(uint8_t address, uint8_t value) { stopISR(); digitalWrite(SPI_CS, LOW);
for
( int c=1; c<=
bi_maxInUse*2;c++) { SPI.tran- sfer(address);
// specify register SPI.transfer(value);
// put data }
digitalWrite(SPI_CS,
HIGH); startISR(); }
//*******************************
void bi_maxTransferOne(uint8_t whichMax, uint8_t address, uint8_t
value) {
byte noop_reg = 0x00;
//max7219 No op register byte noop_value = 0x00;
//value stopISR();
digitalWrite(SPI_CS,
LOW);
for
(int i=bi_maxInUse; i>0; i–)
// Loop
through our number
of Bi-color LED
Ma- trices {
if (i==whichMax) {
SPI.transfer(address);
// Send the register address
SPI.transfer(value);
// Send the value SPI.transfer(address);
// Send the register address
SPI.transfer(value);
// Send the value
}
else { SPI.transfer(noop_reg);
// Send the register address SPI.transfer(noop_va- lue);
// Send the value SPI.transfer(noop_reg);
// Send the register address SPI.transfer(noop_va- lue);
// Send the value } } digitalWrite(SPI_CS, HIGH); startISR();
}
//
//*******************************
void bi_maxTransferSingle(uint8_t whichColor, uint8_t whichMax, uint8_t address, uint8_t value) {
//whichColor = 1 for RED, 2 for GREEN
byte
noop_reg = 0x00;
//max7219 No op register
byte noop_value = 0x00;
//value
stopISR(); digitalWrite(SPI_CS, LOW);
if (whichColor==GREEN) { for (int i=bi_maxI- nUse; i>0; i–)
// Loop
through our number
of Bi-color LED
Ma- trices { if (i==whichMax) { SPI.transfer(address+1);
// Send the register address SPI.transfer(value);
// Send the value SPI.transfer(noop_reg);
// Send the register address SPI.transfer(noop_va- lue);
// Send the value
} else {
SPI.transfer(noop_reg);
// Send the register address SPI.transfer(noop_va- lue);
// Send the value SPI.transfer(noop_reg);
// Send the register address SPI.transfer(noop_va- lue);
// Send
the value } } } else
{ for (int i=bi_maxI- nUse; i>0; i–)
// Loop
through our number
of Bi-color LED
Ma- trices { if (i==whichMax) { SPI.transfer(noop_reg);
// Send the register address SPI.transfer(noop_va- lue);
// Send the value SPI.transfer(address+1);
// Send the register address SPI.transfer(value);
// Send the value
}
else { SPI.transfer(noop_reg);
// Send the register address SPI.transfer(noop_va- lue);
// Send the value SPI.transfer(noop_reg);
// Send the register address SPI.transfer(noop_va- lue);
// Send the value } } } digitalWrite(SPI_CS, HIGH); startISR();
}
//
//*******************************
void bi_maxShutdown(uint8_t cmd)
{ byte noop_reg
= 0x00;
//max7219_reg_no_op byte shutdown_reg = 0x0c;
//max7219_reg_shutdown
byte col = 0x01;
//shutdown false byte
col2 = 0x00;
//shutdown true
if (cmd == offREDoffGREEN) { stopISR(); digi- talWrite(SPI_CS, LOW);
for (int c =1;
c<= bi_maxInUse; c++) { SPI.tran- sfer(shutdown_reg);
// Send the register address SPI.transfer(col2);
// Send the value SPI.transfer(shutdown_reg);
// Send the register address SPI.transfer(col2);
// Send the value }
digitalWrite(SPI_CS,
HIGH); startISR(); } else if (cmd == offREDonGREEN) { stopISR(); digitalWri- te(SPI_CS, LOW);
for (int c =1;
c<= bi_maxInUse; c++) { SPI.tran- sfer(shutdown_reg);
// Send the register address SPI.transfer(col);
// Send the value SPI.transfer(shutdown_reg);
// Send the register address SPI.transfer(col2);
// Send the value }
digitalWrite(SPI_CS,
HIGH); startISR(); } else if (cmd == onREDoffGREEN) { stopISR(); digitalWri- te(SPI_CS, LOW);
for (int c =1;
c<= bi_maxInUse; c++) { SPI.tran- sfer(shutdown_reg);
// Send the register address SPI.transfer(col2);
// Send the value SPI.transfer(shutdown_reg);
// Send the register address SPI.transfer(col);
// Send the value }
digitalWrite(SPI_CS,
HIGH); startISR(); }
//No ops register to shift out instructions stopISR(); digitalWrite(SPI_CS, LOW);
for (int c =1; c<= bi_maxInUse; c++) { SPI.tran- sfer(noop_reg);
// Send the register address SPI.transfer(0x00);
// Send the value SPI.transfer(noop_reg);
// Send the register address SPI.transfer(0x00);
// Send the value }
digitalWrite(SPI_CS,
HIGH); startISR(); }
//******************************* void altShutDown()
//alternate shutdown of MAX7219 chips for RED and GREEN LEDs { if (colorMode == ’3’)
//Scrolling in ORANGE { if(maxInShutdown==RED){ bi_maxShutdown(onREDoffGREEN);
maxInShutdown=GREEN; }
else {
bi_maxShutdown(offREDonGREEN); maxInShutdown=RED;
} }
else if (colorMode == ’2’)
//Scrolling in GREEN { bi_maxShutdown(offRE- DonGREEN);
maxInShutdown=RED;
} else if (colorMode == ’1’)
//Scrolling in RED { bi_maxShutdown(onREDo- ffGREEN);
maxInShutdown=GREEN;
} else if (colorMode == ’4’)
//Blank Display { bi_maxShutdown(offREDoffGRE- EN);
maxInShutdown=GREEN;
} }
//******************************* if (colorMode == ’3’)
// ORANGE { if(maxInShutdown==RED){
bi_ma- xShutdown(onREDoffGREEN);
maxInShutdown=GREEN; }
else {
bi_maxShutdown(offREDonGREEN); maxInShutdown=RED;
} }
else if (colorMode == ’2’) // GREEN { bi_ma- xShutdown(offREDonGREEN);
maxInShutdown=RED;
}
else
if (colorMode == ’1’)
// RED { bi_maxShutdown(onREDoffGREEN); ma- xInShutdown=GREEN; }
else
if (colorMode == ’4’) //Blank
Display { bi_ma- xShutdown(offREDoffGREEN);
maxInShutdown=GREEN; } }
//******************************* void setISRtimer()
// setup ISR timer controling toggleing { TCCR2A
= 0x02;
// WGM22=0
+ WGM21=1 + WGM20=0
= Mo- de2 (CTC)
TCCR2B = 0x05;
// CS22=1
+ CS21=0 + CS20=1
= /128 prescaler (125kHz) TCNT2 = 0;
// clear counter OCR2A =
ISR_FREQ;
// set TOP (divisor) - see #define }
//******************************* void startISR()
// Starts the ISR { TCNT2 = 0;
// clear counter (needed here also)
TIMSK2|=(1«OCIE2A);
// set interrupts=enabled (calls ISR(TIMER2_COM-
PA_vect)
}
//******************************* void stopISR()
//Stops the ISR { TIMSK2&=~(1«OCIE2A);
//
disable interrupts }
//******************************* void TriggerSound() {
// Set up a counter
to pull from melody[] and be-
ats[] for (int i=0; i<MAX_COUNT; i++) { tone_ = melody[i];
beat = beats[i];
duration
= beat * tempo;
// Set
up timing playTone();
delayMicroseconds(pause); } }
//*******************************
// Pulse the speaker
to play a tone for a particular duration void playTone() { long elapsed_time = 0; if (tone_ > 0) {
// if this isn’t a Rest beat, while the tone has
// played less
long than ’duration’, pulse speaker HIGH and LOW while (elapsed_time < duration) {
digitalWrite(speakerOut,HIGH);
delayMicrosecon- ds(tone_ / 2);
// DOWN
digitalWrite(speakerOut, LOW); delayMicroseconds(tone_ / 2);
// Keep track of how long we pulsed elapsed_time
+= (tone_); } } else {
// Rest beat; loop times
delay for (int j = 0; j < rest_count; j++) {
// See NOTE on rest_count delayMicroseconds(du- ration);
} }
}
Setelah semua kit Modul Matrix
Driver LED sele- sai, mereka terhubung bersamaan dengan mikrokon-
troler Arduino Nano seperti yang ditunjukkan pada diagram pengkabelan (Matriks
LED tidak terpasang untuk tampilan yang lebih baik).
Untuk keluaran audio game, kami menggunakan sa- tu speaker
8 ohm 0,5 watt yang digerakkan langsung oleh salah satu
pin digital Arduino
melalui resistor 100 ohm. Nada suara dasar digunakan
untuk proyek ini dan volume suara rendah harus cukup untuk permain- an genggam dengan pengaturan
sederhana ini.
Empat Panel SPST Panel Sentuh
Tombol Push But- ton diperlukan untuk proyek
navigasi dan rotasi
blok Tetris.
Perhatikan penggunaan resistor pull-down 10Kohms pada pin
input DATA IN, CLK dan LOAD. Saat po-
wer
pertama kali diaplikasikan pada micro-controller
atau saat reset, garis I / O saya mengapung. The MAX7219 dapat melihat
ini sebagai data yang valid dan menampilkan sampah sampai kendali
mikro kon- trol kontrol. Resistor pull-down mencegah masalah
ini. Untuk mengurangi jumlah bagian proyek ini,
Anda da- pat mencoba tanpa
resistor pull-down 10Kohms
untuk jalur input DATA IN dan CLK.
Kecuali dua modul Bi-warna LED Matrix Driver dan empat tombol push switch, kami menghubungk-
an keseluruhan rangkaian
pada bagian kecil perf-board
berukuran 60mm x 60mm.
Perhatikan bahwa ada empat tombol mount mount PCB pada perf-board di foto. Awalnya
kami meng- gunakannya untuk kontrol
permainan namun setelah membangun kandang sederhana untuk permainan, ka- mi
memutuskan untuk menggunakan empat panel mo- unt tombol
push, bukan untuk
kontrol permainan yang lebih baik. Kami sejajar
memasang tombol push mo- unt panel
dengan tombol tekan mount PCB sehing- ga
kontrol permainan sekarang bisa dilakukan dengan menggunakan tombol
tekan panel PCB
atau panel.
4.1.3 Memprogram
Dewan Arduino
Dewan Arduino perlu dimuat
dengan sketsa Ardu- ino untuk menjalankan display.Kami menggunakan Arduino
IDE V1.03 untuk pro- yek kami. Download
sketsa Arduino di bawah untuk
proyek ini.Download jollifactory_Tetris_V1_1.ino
Sketsa permainan Tetris yang kita miliki
di sini sa- ngat
mendasar tanpa tingkat
permainan dan skor.
Anda dapat mengubah dan meningkatkan sketsa.Catatan: Memiliki beberapa masalah dengan modul
Matrix LED Bi-warna
Anda? Download program uji berikut untuk menguji setiap
modul Anda seca- ra terpisah. Layar harus
menyala RED, GREEN dan ORANGE di urutan baris demi baris untuk mengisi keseluruhan tampilan berulang-ulang.
/* Tetris Code
Adapted from Tetris.ino code by
Jae Yeong Bae UBC ECE jocker.tistory.com
/* =============== LED Matrix Display
=============== */
#include <SPI.h>
#define GREEN 0
#define RED 1
#define offREDoffGREEN 0
#define offREDonGREEN 1
#define onREDoffGREEN 2
#define ISR_FREQ 190 //190=650Hz // Sets the speed of the ISR
int SPI_CS = 10;// This SPI Chip Select pin con- trols the
MAX7219
int bi_maxInUse = 2; //No. of Bi-color LED Ma- trix used
int maxInShutdown = RED; // indicates which LED
Matrix color is currently off
int SetbrightnessValue = 15; int colorMode = ’3’;
// default color (1 = RED, 2 = GREEN, 3 = ORA- NGE, 4 = blank off)
/* =========Audio ===============*/
int speakerOut = 9;
#define mC 1911
#define mC1 1804
#define mD 1703
#define mEb 1607
#define mE 1517
#define mF 1432
#define mF1 1352
#define mG 1276
#define mAb 1204
#define mA 1136
#define mBb 1073
#define mB 1012
#define mc 955
#define mc1 902
#define md 851
#define meb 803
#define me 758
#define mf 716
#define mf1 676
#define mg 638
#define mab 602
#define ma 568
#define mbb 536
#define mb 506
#define mp 0 //pause
/* ============= Tetris Game =============
*
/ long delays = 0; short delay_ = 500; long bdelay = 0;
short
buttondelay = 150; short btdowndelay = 30; short btsidedelay = 80; unsigned char blocktype; unsigned char blockrotation; boolean block[8][18];
//2 extra for
rotation boolean pile[8][16]; boolean disp[8][16];
boolean
gameoverFlag = false; boolean selectColor = RED;
unsigned long
startTime; unsigned long elapsedTime; int cnt = 0;
int buttonRotate = 4;
// Rotate int buttonRight = 5;
// Right int buttonLeft = 6;
// Left int buttonDown = 7;
//
Down
//*******************************
void setup() { pinMode(SPI_CS,
OUTPUT); pinMode(speakerOut, OUTPUT); TriggerSound();
Serial.begin (9600);
Serial.println(”jolliFactory Tetris LED Matrix Ga- me example 1.1”);
SPI.begin();
//setup SPI
Interface bi_maxTransferAll(0x0F, 0x00);
// 00 - Turn off Test mode bi_maxTransferAll(0x09, 0x00);
//Register 09 - BCD Decoding
// 0 = No decoding bi_maxTransferAll(0x0B, 0x07);
//Register
B - Scan limit 1-7 //
7 = All LEDS bi_maxTransferAll(0x0C, 0x01); // 01 = on 00 = Power saving mode or shutdown
setBrightness();
setISRtimer();
//
setup the timer startISR();
// start
the timer to toggle shutdown clearDisplay(GREEN);
clearDisplay(RED);
int seed
= (analogRead(0)+1)* (analogRead(1)+1)* (analogRead(2)+1)* (analogRead(3)+1);
randomSeed(seed);
random(10,9610806);
seed = seed
*random(3336,15679912)+analogRead(ran- dom(4)) ;
randomSeed(seed); random(10,98046); cli();
//stop interrupts
//set
timer0 interrupt at 2kHz TCCR1A = 0;
// set entire TCCR0A register to 0 TCCR1B = 0;
// same for TCCR0B TCNT1 = 0;
//initialize counter value to 0
// set compare match register for 2khz increments OCR1A = 259;
// = (16*10^6) / (2000*64) - 1 (must be <256)
// turn on CTC mode TCCR1A |= (1 « WGM01);
// Set CS11 and CS10 bits for 1024 prescaler TCCR1B
|= (1 « CS12) | (1
« CS10);
// enable timer compare interrupt TIMSK1 |=
(1
« OCIE0A);
sei();
//allow interrupts
pinMode(buttonRotate,
INPUT_PULLUP);
// Rotate pinMode(buttonRight, INPUT_PULLUP);
// Right
pinMode(buttonLeft, INPUT_PULLUP);
// Left pinMode(buttonDown,
INPUT_PULLUP);
//
Down newBlock(); updateLED(); }
//******************************* void loop() { delay(30);
if (delays < millis()) { delays = millis() + delay_; movedown(); }
//buttun actions int button = readBut(); if (button
== 1)
//up=rotate rotate();
if (button == 2) //right=moveright moveright(); if
(button == 3) //left=moveleft moveleft();
if (button == 4) //down=movedown movedown();
}
//******************************* boolean moveleft() { TriggerSound();
if (space_left()) { int i; int j; for (i=0;i<7;i++) {
for (j=0;j<16;j++) { block[i][j]=block[i+1][j];
}
}
for (j=0;j<16;j++) { block[7][j]=0; } updateLED(); return 1; }
return 0; }
//******************************* boolean
moveright() { TriggerSound();
if (space_right()) { int i; int j; for (i=7;i>0;i–) { for (j=0;j<16;j++) { block[i][j]=block[i-1][j]; } }
for (j=0;j<16;j++) { block[0][j]=0; } updateLED();
return 1; }
return 0; }
//*******************************
int readBut() { if (bdelay > millis()) { return 0;
}
if ((digitalRead(buttonLeft) == LOW)) { //left bdelay = millis() + btsidedelay; return
2; }
if ((digitalRead(buttonDown) == LOW)) { //do- wn bdelay = millis() + btdowndelay; return
4; }
if ((digitalRead(buttonRight) == LOW)) {
//right bdelay = millis() + btsidedelay; return 3; }
if ((digitalRead(buttonRotate)
== LOW)) { //ro-
tate bdelay = millis()
+ buttondelay; return
1; } return 0; }
//*******************************
void updateLED() { int i; int j; for (i=0;i<8;i++)
{ for (j=0;j<16;j++) { disp[i][j] = block[i][j] |
pile[i][j];
} } }
//*******************************
void
rotate() { TriggerSound(); //skip for square block(3) if (blocktype == 3) return;
int xi; int yi;
int i; int j;
//detect left for (i=7;i>=0;i–) { for (j=0;j<16;j++)
{ if (block[i][j]) { xi = i; } } }
//detect up for (i=15;i>=0;i–) { for (j=0;j<8;j++)
{ if (block[j][i]) { yi = i; } } }
if (blocktype == 0) { if (blockrotation == 0) { if (!space_left()) {
if (space_right3()) {
if (!moveright()) return;
xi++; } else
return; } else if (!space_right()) {
if (space_left3()) {
if (!moveleft()) return;
if (!moveleft()) return;
xi–; xi–; } else return;
}
else if (!space_right2()) { if (space_left2()) {
if (!moveleft()) return;
xi–; } else return;
} block[xi][yi]=0; block[xi][yi+2]=0; block[xi][yi+3]=0; block[xi-1][yi+1]=1;
block[xi+1][yi+1]=1; block[xi+2][yi+1]=1; blockrotation = 1; } else
{ block[xi][yi]=0; block[xi+2][yi]=0; block[xi+3][yi]=0; block[xi+1][yi-1]=1;
block[xi+1][yi+1]=1; block[xi+1][yi+2]=1; blockrotation = 0; } }
//offset to mid xi ++; yi ++;
if (blocktype == 1) {
if (blockrotation == 0) { block[xi-1][yi-1] = 0;
block[xi-1][yi] = 0;
block[xi+1][yi] = 0;
block[xi][yi-1] = 1;
block[xi+1][yi-1] = 1;
block[xi][yi+1] = 1; blockrotation = 1; }
else if (blockrotation == 1) {
if (!space_left()) {
if (!moveright()) return; xi++; } xi–; block[xi][yi-1]
= 0;
block[xi+1][yi-1] = 0;
block[xi][yi+1] = 0;
block[xi-1][yi] = 1;
block[xi+1][yi] = 1;
block[xi+1][yi+1] = 1; blockrotation = 2; }
else if (blockrotation == 2)
{ yi –; block[xi-1][yi] = 0; block[xi+1][yi] = 0;
block[xi+1][yi+1] = 0;
block[xi][yi-1] = 1;
block[xi][yi+1] = 1;
block[xi-1][yi+1] = 1; blockrotation = 3; }
else { if (!space_right()) {
if (!moveleft()) return;
xi–; } block[xi][yi-1]
= 0;
block[xi][yi+1] = 0;
block[xi-1][yi+1] = 0;
block[xi-1][yi-1] = 1;
block[xi-1][yi] = 1;
block[xi+1][yi] = 1; blockrotation = 0; } }
if (blocktype == 2)
{ if (blockrotation == 0) { block[xi+1][yi-1] = 0; block[xi-1][yi]
= 0;
block[xi+1][yi] = 0;
block[xi][yi-1] = 1;
block[xi+1][yi+1] = 1;
block[xi][yi+1] = 1; blockrotation = 1;
} else
if (blockrotation == 1) { if (!space_left()) {
if (!moveright()) return; xi++; } xi–; block[xi][yi-1] = 0; block[xi+1][yi+1] = 0;
block[xi][yi+1] = 0;
block[xi-1][yi] = 1;
block[xi+1][yi] = 1;
block[xi-1][yi+1] = 1; blockrotation = 2; }
else
if (blockrotation == 2) { yi –; block[xi-1][yi] =
0;
block[xi+1][yi] = 0;
block[xi-1][yi+1] = 0;
block[xi][yi-1] = 1;
block[xi][yi+1] = 1;
block[xi-1][yi-1] = 1; blockrotation = 3; } else { if (!space_right())
{ if (!moveleft()) return; xi–; } block[xi][yi-1] = 0;
block[xi][yi+1] = 0;
block[xi-1][yi-1] = 0;
block[xi+1][yi-1] = 1;
block[xi-1][yi] = 1;
block[xi+1][yi] = 1; blockrotation = 0; } }
if (blocktype == 4) { if (blockrotation == 0)
{ block[xi+1][yi-1] = 0; block[xi-1][yi]
= 0;
block[xi+1][yi] = 1;
block[xi+1][yi+1] = 1; blockrotation = 1; }
else
{ if (!space_left()) { if (!moveright()) return; xi++; } xi–; block[xi+1][yi] = 0;
block[xi+1][yi+1] = 0;
block[xi-1][yi] = 1;
block[xi+1][yi-1] = 1; blockrotation = 0; } }
if (blocktype == 5)
{ if (blockrotation == 0)
{ block[xi][yi-1] = 0;
block[xi-1][yi] = 0;
block[xi+1][yi] = 0;
block[xi][yi-1] = 1;
block[xi+1][yi] = 1;
block[xi][yi+1] = 1; blockrotation = 1; }
else if (blockrotation == 1)
{ if (!space_left())
{ if (!moveright()) return; xi++; } xi–; block[xi][yi-1] = 0;
block[xi+1][yi] = 0;
block[xi][yi+1] = 0;
block[xi-1][yi] = 1;
block[xi+1][yi] = 1;
block[xi][yi+1] = 1; blockrotation = 2; }
else if (blockrotation == 2)
{ yi –; block[xi-1][yi] = 0; block[xi+1][yi] = 0;
block[xi][yi+1] = 0;
block[xi][yi-1] = 1;
block[xi-1][yi] = 1;
block[xi][yi+1] = 1; blockrotation = 3; }
else { if (!space_right()) {
if (!moveleft()) return;
xi–; } block[xi][yi-1]
= 0;
block[xi-1][yi] = 0;
block[xi][yi+1] = 0;
block[xi][yi-1] = 1;
block[xi-1][yi] = 1;
block[xi+1][yi] = 1; blockrotation = 0; } }
if (blocktype == 6)
{ if (blockrotation == 0)
{ block[xi-1][yi-1] = 0;
block[xi][yi-1] = 0;
block[xi+1][yi-1] = 1;
block[xi][yi+1] = 1; blockrotation = 1; }
else { if (!space_left()) {
if (!moveright()) return; xi++; } xi–; block[xi+1][yi-1] = 0; block[xi][yi+1] = 0;
block[xi-1][yi-1] = 1;
block[xi][yi-1] = 1; blockrotation = 0; } }
//if rotating made
block and pile
overlap, push rows up while (!check_overlap()) { for (i=0;i<18;i++) { for
(j=0;j<8;j++) { block[j][i] = block[j][i+1]; } } delays
= millis() + delay_; }
updateLED(); }
//******************************* void movedown() {
if (space_below()) {
//move down int i; for (i=15;i>=0;i–) {
int j; for (j=0;j<8;j++)
{ block[j][i] = block[j][i-1]; } }
for (i=0;i<7;i++) { block[i][0] = 0; } }
else
{ //merge and new block int i; int j; for (i=0;i<8;i++)
{ for(j=0;j<16;j++) {
if (block[i][j]) { pile[i][j]=1; block[i][j]=0;
} } }
newBlock(); }
updateLED(); }
//*******************************
boolean check_overlap() { int i; int j;
for (i=0;i<16;i++)
{ for (j=0;j<7;j++) { if (block[j][i])
{ if (pile[j][i]) return false; } } }
for (i=16;i<18;i++) { for
(j=0;j<7;j++)
{ if (block[j][i]) { return false; } } }
return true; }
//******************************* void check_gameover() {
int i; int j;
int cnt=0;; for(i=15;i>=0; i–) { cnt=0;
for (j=0;j<8;j++) {
if (pile[j][i]) { cnt ++; } }
if (cnt == 8) { for (j=0;j<8;j++) { pile[j][i]=0; } updateLED();
delay(50); int k;
for(k=i;k>0;k–) { for (j=0;j<8;j++) {
pile[j][k] =
pile[j][k-1]; } }
for (j=0;j<8;j++) { pile[j][0] = 0;
} updateLED(); delay(50); i++; } } for(i=0;i<8;i++) {
if (pile[i][0])
gameover(); } return; }
//******************************* void gameover() {
int i; int j;
gameoverFlag = true; startTime =
millis(); delay(300);
while(true) //To re-play if any buttons depressed again { int button =
readBut();
if ((button <
5) && (button >
0)) { gameover- Flag = false; for(i=15;i>=0;i–) { for
(j=0;j<8;j++) { pile[j][i]=0; } }
break; } } }
//******************************* void newBlock() { check_gameover();
if (selectColor == RED) selectColor = GREEN; else selectColor = RED;
blocktype = random(7);
if (blocktype == 0) // 0 // 0 // 0 // 0 { block[3][0]=1;
block[3][1]=1;
block[3][2]=1;
block[3][3]=1; }
if (blocktype == 1) // 0 // 0 0 0 { block[2][0]=1; block[2][1]=1;
block[3][1]=1;
block[4][1]=1; }
if (blocktype == 2) // 0 // 0 0 0 { block[4][0]=1; block[2][1]=1;
block[3][1]=1;
block[4][1]=1; }
if (blocktype == 3) // 0 0 // 0 0 { block[3][0]=1; block[3][1]=1;
block[4][0]=1; block[4][1]=1; }
if (blocktype == 4) // 0 0 // 0 0 { block[4][0]=1; block[5][0]=1;
block[3][1]=1; block[4][1]=1; }
if (blocktype == 5) // 0 // 0 0 0 { block[4][0]=1; block[3][1]=1;
block[4][1]=1; block[5][1]=1; }
if (blocktype == 6) // 0 0 // 0 0 { block[3][0]=1; block[4][0]=1;
block[4][1]=1; block[5][1]=1; }
blockrotation = 0; }
//******************************* boolean space_below() { int i;
int j;
for (i=15;i>=0;i–) { for (j=0;j<8;j++) { if (block[j][i])
{ if (i == 15) return false;
if (pile[j][i+1]) { return false; } } } } return true; }
//*******************************
boolean spa- ce_left2() { int i;
int j;
for (i=15;i>=0;i–) { for (j=0;j<8;j++) { if (block[j][i])
{ if (j == 0 || j == 1) return false; if (pile[j-1][i] | pi- le[j-2][i]) { return false; } } } }
return true; }
//******************************* boolean space_left3() {
int i; int j;
for (i=15;i>=0;i–) { for (j=0;j<8;j++) { if (block[j][i])
{ if (j == 0 || j == 1 ||j == 2 ) return false;
if (pile[j-1][i] |
pile[j-2][i]|pile[j-3][i]) {
return false; }
} } }
return true; }
//******************************* boolean space_left() {
int i; int j;
for (i=15;i>=0;i–) { for (j=0;j<8;j++) { if (block[j][i])
{ if (j == 0) return false; if (pile[j-1][i]) { return false;
} } } }
return true; }
//******************************* boolean space_right() {
int i; int j;
for (i=15;i>=0;i–) { for (j=0;j<8;j++) { if (block[j][i])
{ if (j == 7) return false;
if (pile[j+1][i]) { return false; } } } } return true; }
//******************************* boolean space_right3() {
int i; int j;
for (i=15;i>=0;i–) { for (j=0;j<8;j++) { if (block[j][i])
{ if (j == 7||j == 6||j ==
5) return false;
if (pile[j+1][i] |pile[j+2][i] | pile[j+3][i]) { return
fal- se; } } } }
return true; }
//******************************* boolean space_right2() {
int i; int j;
for (i=15;i>=0;i–) { for (j=0;j<8;j++) { if (block[j][i])
{ if (j == 7 || j == 6) return false;
if (pile[j+1][i] |pile[j+2][i]) { return false;
} } } } return true; }
//******************************* ISR(TIMER1_COMPA_vect){ //change the 0 to
1 for timer1 and 2 for
timer2 LEDRefresh(); }
//******************************* void LEDRefresh() {
int i; int k;
boolean
tmpdispUpper[8][8]; boolean
tmpdispLower[8][8]; boolean
tmppileUpper[8][8]; boolean tmppileLower[8][8];
//rotate 90 degrees for upper Bicolor
LED matrix for
(k=0;k<8;k++) { for(i=0;i<8;i++) { tmpdispUp- per[k][i]=disp[i][k];
} }
//rotate 90 degrees for lower Bicolor LED matrix
for (k=8;k<16;k++) { for(i=0;i<8;i++) {
tmpdispLo- wer[k-8][i]=disp[i][k]; } }
//For pile //rotate 90
degrees for upper Bicolor LED matrix for (k=0;k<8;k++) { for(i=0;i<8;i++) { tmppileUpper[k][i]=pile[i][k]; } }
//rotate 90 degrees for lower Bicolor LED matrix
for (k=8;k<16;k++) { for(i=0;i<8;i++) { tmppileLo- wer[k-8][i]=pile[i][k]; } }
for(i=0;i<8;i++) { byte upper = 0; int b; for(b
= 0;b<8;b++) {
upper «= 1;
if
(tmpdispUpper[b][i]) upper |= 1; } byte lower
= 0;
for(b = 0; b<8;b++) {
lower «= 1;
if (tmpdispLower[b][i]) lower |=
1; }
if (gameoverFlag == true) { elapsedTime
= millis()
- startTime;
// Display
random pattern for pre-defined period before blanking display if (elapsedTime < 2000) { bi_ma-
xTransferSingle(RED, 1, i, random(255));
bi_maxTransferSingle(RED, 2, i, random(255)); bi_maxTransferSingle(GREEN, 1, i, random(255));
bi_maxTransferSingle(GREEN, 2, i, random(255));
cnt = cnt + 1; if (cnt > 80) { TriggerSound(); Trig-
gerSound(); cnt = 0; } }
else
{ bi_maxTransferSingle(RED, 1, i, 0x00);
//
clear bi_maxTransferSingle(RED, 2, i, 0x00);
// clear
bi_maxTransferSingle(GREEN, 1, i, 0x00);
// clear bi_maxTransferSingle(GREEN, 2, i, 0x00);
// clear } }
else
{ if (selectColor == RED)
{ bi_maxTransfer- Single(GREEN, 1, i, lower);
bi_maxTransferSingle(GREEN, 2, i, upper);
} else { bi_maxTransferSingle(RED, 1, i, lower); bi_maxTransferSingle(RED, 2, i, upper);
} } }
if (gameoverFlag == false) {
// For pile - to display
orange for(i=0;i<8;i++) { byte upper = 0; int b; for(b = 0;b<8;b++) { upper «= 1;
if
(tmppileUpper[b][i]) upper |= 1; } byte lower
= 0; for(b = 0;b<8;b++)
{ lower «= 1;
if (tmppileLower[b][i]) lower |=
1; }
// To alternate color of new block between
RED and GREEN if (selectColor == RED) { bi_maxTran- sferSingle(RED, 1, i, lower);
bi_maxTransferSingle(RED, 2, i, upper); }
else {
bi_maxTransferSingle(GREEN, 1, i, lower); bi_maxTransferSingle(GREEN, 2, i,
upper); }
} } }
//*******************************
// Change Max72xx brightness void setBrightness()
{
bi_maxTransferAll(0x0A, SetbrightnessValue);
//Set Brightness bi_maxTransferAll(0x00, 0x00);
//No-op commands }
//*******************************
// Clear Display
void clearDisplay(uint8_t whichCo- lor)
//whichColor = 1 for RED,
2 for GREEN { for
(int y=0; y<8; y++) { bi_maxTransferSingle(whichColor, 1, y, 0);
//Turn all Off //For X1 LED matrix Game bi_ma- xTransferSingle(whichColor, 2, y, 0);
//Turn all Off
//For
X1 LED matrix Game } }
//********************************
void bi_maxTransferAll(uint8_t address, uint8_t value) { stopISR(); digitalWrite(SPI_CS, LOW);
for
( int c=1; c<=
bi_maxInUse*2;c++) { SPI.tran- sfer(address);
// specify register SPI.transfer(value);
// put data }
digitalWrite(SPI_CS,
HIGH); startISR(); }
//*******************************
void bi_maxTransferOne(uint8_t whichMax, uint8_t address, uint8_t
value) {
byte noop_reg = 0x00;
//max7219 No op register byte noop_value = 0x00;
//value stopISR();
digitalWrite(SPI_CS,
LOW);
for
(int i=bi_maxInUse; i>0; i–)
// Loop
through our number
of Bi-color LED
Ma- trices {
if (i==whichMax) {
SPI.transfer(address);
// Send the register address
SPI.transfer(value);
// Send the value SPI.transfer(address);
// Send the register address
SPI.transfer(value);
// Send the value
}
else { SPI.transfer(noop_reg);
// Send the register address SPI.transfer(noop_va- lue);
// Send the value SPI.transfer(noop_reg);
// Send the register address SPI.transfer(noop_va- lue);
// Send the value } } digitalWrite(SPI_CS, HIGH); startISR();
}
//
//*******************************
void bi_maxTransferSingle(uint8_t whichColor, uint8_t whichMax, uint8_t address, uint8_t value) {
//whichColor = 1 for RED, 2 for GREEN
byte
noop_reg = 0x00;
//max7219 No op register
byte noop_value = 0x00;
//value
stopISR(); digitalWrite(SPI_CS, LOW);
if (whichColor==GREEN) { for (int i=bi_maxI- nUse; i>0; i–)
// Loop
through our number
of Bi-color LED
Ma- trices { if (i==whichMax) { SPI.transfer(address+1);
// Send the register address SPI.transfer(value);
// Send the value SPI.transfer(noop_reg);
// Send the register address SPI.transfer(noop_va- lue);
// Send the value
} else {
SPI.transfer(noop_reg);
// Send the register address SPI.transfer(noop_va- lue);
// Send the value SPI.transfer(noop_reg);
// Send the register address SPI.transfer(noop_va- lue);
// Send
the value } } } else
{ for (int i=bi_maxI- nUse; i>0; i–)
// Loop
through our number
of Bi-color LED
Ma- trices { if (i==whichMax) { SPI.transfer(noop_reg);
// Send the register address SPI.transfer(noop_va- lue);
// Send the value SPI.transfer(address+1);
// Send the register address SPI.transfer(value);
// Send the value
}
else { SPI.transfer(noop_reg);
// Send the register address SPI.transfer(noop_va- lue);
// Send the value SPI.transfer(noop_reg);
// Send the register address SPI.transfer(noop_va- lue);
// Send the value } } } digitalWrite(SPI_CS, HIGH); startISR();
}
//
//*******************************
void bi_maxShutdown(uint8_t cmd)
{ byte noop_reg
= 0x00;
//max7219_reg_no_op byte shutdown_reg = 0x0c;
//max7219_reg_shutdown
byte col = 0x01;
//shutdown false byte
col2 = 0x00;
//shutdown true
if (cmd == offREDoffGREEN) { stopISR(); digi- talWrite(SPI_CS, LOW);
for (int c =1;
c<= bi_maxInUse; c++) { SPI.tran- sfer(shutdown_reg);
// Send the register address SPI.transfer(col2);
// Send the value SPI.transfer(shutdown_reg);
// Send the register address SPI.transfer(col2);
// Send the value }
digitalWrite(SPI_CS,
HIGH); startISR(); } else if (cmd == offREDonGREEN) { stopISR(); digitalWri- te(SPI_CS, LOW);
for (int c =1;
c<= bi_maxInUse; c++) { SPI.tran- sfer(shutdown_reg);
// Send the register address SPI.transfer(col);
// Send the value SPI.transfer(shutdown_reg);
// Send the register address SPI.transfer(col2);
// Send the value }
digitalWrite(SPI_CS,
HIGH); startISR(); } else if (cmd == onREDoffGREEN) { stopISR(); digitalWri- te(SPI_CS, LOW);
for (int c =1;
c<= bi_maxInUse; c++) { SPI.tran- sfer(shutdown_reg);
// Send the register address SPI.transfer(col2);
// Send the value SPI.transfer(shutdown_reg);
// Send the register address SPI.transfer(col);
// Send the value }
digitalWrite(SPI_CS,
HIGH); startISR(); }
//No ops register to shift out instructions stopISR(); digitalWrite(SPI_CS, LOW);
for (int c =1; c<= bi_maxInUse; c++) { SPI.tran- sfer(noop_reg);
// Send the register address SPI.transfer(0x00);
// Send the value SPI.transfer(noop_reg);
// Send the register address SPI.transfer(0x00);
// Send the value }
digitalWrite(SPI_CS,
HIGH); startISR(); }
//******************************* void altShutDown()
//alternate shutdown of MAX7219 chips for RED and GREEN LEDs { if (colorMode == ’3’)
//Scrolling in ORANGE { if(maxInShutdown==RED){ bi_maxShutdown(onREDoffGREEN);
maxInShutdown=GREEN; }
else {
bi_maxShutdown(offREDonGREEN); maxInShutdown=RED;
} }
else if (colorMode == ’2’)
//Scrolling in GREEN { bi_maxShutdown(offRE- DonGREEN);
maxInShutdown=RED;
} else if (colorMode == ’1’)
//Scrolling in RED { bi_maxShutdown(onREDo- ffGREEN);
maxInShutdown=GREEN;
} else if (colorMode == ’4’)
//Blank Display { bi_maxShutdown(offREDoffGRE- EN);
maxInShutdown=GREEN;
} }
//******************************* if (colorMode == ’3’)
// ORANGE { if(maxInShutdown==RED){
bi_ma- xShutdown(onREDoffGREEN);
maxInShutdown=GREEN; }
else {
bi_maxShutdown(offREDonGREEN); maxInShutdown=RED;
} }
else if (colorMode == ’2’) // GREEN { bi_ma- xShutdown(offREDonGREEN);
maxInShutdown=RED;
}
else
if (colorMode == ’1’)
// RED { bi_maxShutdown(onREDoffGREEN); ma- xInShutdown=GREEN; }
else
if (colorMode == ’4’) //Blank
Display { bi_ma- xShutdown(offREDoffGREEN);
maxInShutdown=GREEN; } }
//******************************* void setISRtimer()
// setup ISR timer controling toggleing { TCCR2A
= 0x02;
// WGM22=0
+ WGM21=1 + WGM20=0
= Mo- de2 (CTC)
TCCR2B = 0x05;
// CS22=1
+ CS21=0 + CS20=1
= /128 prescaler (125kHz) TCNT2 = 0;
// clear counter OCR2A =
ISR_FREQ;
// set TOP (divisor) - see #define }
//******************************* void startISR()
// Starts the ISR { TCNT2 = 0;
// clear counter (needed here also)
TIMSK2|=(1«OCIE2A);
// set interrupts=enabled (calls ISR(TIMER2_COM-
PA_vect)
}
//******************************* void stopISR()
//Stops the ISR { TIMSK2&=~(1«OCIE2A);
//
disable interrupts }
//******************************* void TriggerSound() {
// Set up a counter
to pull from melody[] and be-
ats[] for (int i=0; i<MAX_COUNT; i++) { tone_ = melody[i];
beat = beats[i];
duration
= beat * tempo;
// Set
up timing playTone();
delayMicroseconds(pause); } }
//*******************************
// Pulse the speaker
to play a tone for a particular duration void playTone() { long elapsed_time = 0; if (tone_ > 0) {
// if this isn’t a Rest beat, while the tone has
// played less
long than ’duration’, pulse speaker HIGH and LOW while (elapsed_time < duration) {
digitalWrite(speakerOut,HIGH);
delayMicrosecon- ds(tone_ / 2);
// DOWN
digitalWrite(speakerOut, LOW); delayMicroseconds(tone_ / 2);
// Keep track of how long we pulsed elapsed_time
+= (tone_); } } else {
// Rest beat; loop times
delay for (int j = 0; j < rest_count; j++) {
// See NOTE on rest_count delayMicroseconds(du- ration);
} }
}
4.1.5 Lampiran dan
Majelis
Karena proyek ini
hanya dibangun untuk faktor FUN
tanpa niat untuk menggunakannya lama, kami
tidak terlalu memperhatikan untuk membangun kan- dang yang layak. Namun,
kandang yang dibangun harus memungkinkan pemain untuk menggenggam ga- dget agar bisa dimainkan dengan cukup nyaman.
Yang kami punya untuk
kandang itu adalah
kotak kardus yang dilengkapi dengan
pelindung depan ber- warna biru akrilik
dengan saklar tombol kontrol pemainan yang terpasang. Kami bahkan tidak menga- mankan modul ke kandang
karena mereka pas di dalam kandang.
Kami tidak akan menyelidiki detail
tentang bagai- mana kami membangun kandang
permainan kami di sini. Gambar-gambar tersebut
menunjukkan berba- gai tahap perakitan
sub-modul yang lengkap bersama- sama.
4.2
Spesifikasi
Game ini menggunakan LCD pada nuvoton
sebagai tampilan dan seven segment untuk menampilkan sco- re.Permainan ini dimulai
pada level 1 yaitu dengan
ba- lok kecepatan yang lambat. Seiring
berjalannya waktu, ketika mencapaiscore tertentu
maka permainan akan otomatis
berpindah levelsehingga kecepatan bermain akan meningkat dan kesulitan
akan meningkat. Per- mainan selesai apabila blok tetris yang akan datang tidak dapat muncul secara sempurna dilayar.Game ter- sebut menggunakan lima buah tombol keypad,
LCD, dan Seven Segment
yang tersedia di Board Nuvoton.Berikut spesifikasi dari Game Tetris tersebut spesifikasi tersebut adalah sebagai berikut:
•
Game
ditampilkan di LCD dan score ditampikan di seven segment.
•
Contoler terdiri
dari 4 buah tombol, tombol
hijau untuk menurunkan lebih cepat rangkain , tom- bol putih untuk memutar
rangkaina, tombol biru dan merah untuk
menggerakn kekanan dan
kekiri pada rangkain tersebut.
4.2.1 FSM game Tetris
Berikut FSM dari gae tetris tersebut.
Gambar4.5 FSM game tetris
Gambar 4.6 DFD game tetris
4.2.2 Teknik Implmentasi Real Time
Teknik
implementasi real time untuk
game tetris ini menggunakan RTOS. Penggunaan
RTOS pada game ini menjadikan game tetris fast respon terhadap
input yang diberikan. Game tetris ini dalam pembuatannya menggunakan 4 task yang berjalan secara roundrobi-
nyaitu task A untuk
menjalankan FSM game tetris dan scanningtombol, task B untuk menjalankan tampilan LCD, task C untuk menjalankan perhitungan blok te- tris
dan update score,
dan task C untuk menjalankan scanning seven segment.
Komentar
Posting Komentar