산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

수제 16x8 매트릭스의 Arduino Nano 테트리스 게임

구성품 및 소모품

Arduino Nano R3
× 1
SparkFun 푸시버튼 스위치 12mm
× 4
Texas Instruments Shift Register - 직렬에서 병렬로
× 2
슬라이드 스위치
× 1
5mm LED:노란색
× 128

필요한 도구 및 기계

납땜 인두(일반)

앱 및 온라인 서비스

Arduino IDE

이 프로젝트 정보

집에서 만든 16x8 LED 매트릭스, Arduino Nano 및 2개의 74hc595 시프트 레지스터로 이 테트리스 게임을 만들었습니다. 아무 버튼이나 누를 때 삐 소리가 나는 것도 추가했습니다.

<섹션 클래스="섹션 컨테이너 섹션 축소 가능" id="코드">

코드

<울>
  • 코드
  • 코드Arduino
    /*작성자:배재영 UBC ECE jocker.tistory.com 날짜:2013년 1월 18일 파일:Tetris v2Changelog:v2:게임오버 시 점수 표시 목적:킬링타임.. + 재미를 위한 회로+핀:Led Matrix:2 74HC575 순서대로 레지스터 이동:녹색, 파란색, 빨간색 핀:래치 =3 클록 =2 데이터 =4 행 양극 =두 매트릭스 버튼 간에 공유되는 5 ~ 13(8핀)(디지털):A4 =왼쪽 A5 =아래쪽 A6 =오른쪽 A7 =up (rotate) 코멘트:이것은 저의 두 번째 Arduino 프로젝트입니다. 코드가 지저분하고 비효율적일 수 있습니다. Arduino 라이브러리 및 데이터시트의 참조.*/unsigned char latchPin =3, unsigned char clockPin =2, unsigned char dataPin =4, unsigned char rowPin =5, 긴 지연 =0, 짧은 지연_ =500, 긴 bdelay =0, 짧은 버튼 지연 =150, 짧은 btdowndelay =30, 짧은 btsidedelay =80, unsigned char blocktype, unsigned char blockrotation, int lines =0, boolean block[8][18]; //회전을 위한 추가 2개boolean pile[8][16];boolean disp[8][16];boolean lib[10][5][7];void setup() {lib[0][1][0] =1;lib[0][2][0] =1;lib[0][3][0] =1;lib[0][0][1] =1;lib[0][4][ 1] =1;lib[0][3][2] =1;lib[0][0][2] =1;lib[0][4][2] =1;lib[0][2 ][3] =1;lib[0][0][3] =1;lib[0][4][3] =1;lib[0][1][4] =1;lib[0] [0][4] =1;lib[0][4][4] =1;lib[0][0][5] =1;lib[0][4][5] =1;lib[ 0][1][6] =1;lib[0][2][6] =1;lib[0][3][6] =1;lib[1][2][0] =1; lib[1][1][1] =1;lib[1][2][1] =1;lib[1][2][2] =1;lib[1][2][3] =1;lib[1][2][4] =1;lib[1][2][5] =1;lib[1][1][6] =1;lib[1][2][6 ] =1;lib[1][3][6] =1;lib[2][1][0] =1;lib[2][2][0] =1;lib[2][3] [0] =1;lib[2][0][1] =1;lib[2][4][1] =1;lib[2][4][2] =1;lib[2][ 3][3] =1;lib[2][2][4] =1;lib[2][1][5] =1;lib[2][0][6] =1;lib[2 ][1][6] =1;lib[2][2][6] =1;lib[2][3][6] =1;lib[2][4][6] =1;lib [3][0][0] =1;lib[3][1][0] =1;lib[3][2][0] =1;lib[3][3][0] =1;lib[3][4][0] =1;lib[3][3][1] =1;lib[3][2][2] =1;lib[3][3][3] =1;lib[3][4][4] =1;lib[3][0][5] =1;l ib[3][4][5] =1;lib[3][1][6] =1;lib[3][2][6] =1;lib[3][3][6] =1;lib[4][3][0] =1;lib[4][2][1] =1;lib[4][3][1] =1;lib[4][1][2 ] =1;lib[4][3][2] =1;lib[4][0][3] =1;lib[4][3][3] =1;lib[4][0] [4] =1;lib[4][1][4] =1;lib[4][2][4] =1;lib[4][3][4] =1;lib[4][ 4][4] =1;lib[4][3][5] =1;lib[4][3][6] =1;lib[5][0][0] =1;lib[5 ][1][0] =1;lib[5][2][0] =1;lib[5][3][0] =1;lib[5][4][0] =1;lib [5][0][1] =1;lib[5][0][2] =1;lib[5][1][2] =1;lib[5][2][2] =1;lib[5][3][2] =1;lib[5][4][3] =1;lib[5][4][4] =1;lib[5][0][5] =1;lib[5][4][5] =1;lib[5][1][6] =1;lib[5][2][6] =1;lib[5][3][ 6] =1;lib[6][2][0] =1;lib[6][3][0] =1;lib[6][1][1] =1;lib[6][0 ][2] =1;lib[6][0][3] =1;lib[6][1][3] =1;lib[6][2][3] =1;lib[6] [3][3] =1;lib[6][0][4] =1;lib[6][4][4] =1;lib[6][0][5] =1;lib[ 6][4][5] =1;lib[6][1][6] =1;lib[6][2][6] =1;lib[6][3][6] =1; lib[7][0][0] =1;lib[7][1][0] =1;lib[7][2][0] =1;lib[7][3][0] =1;lib[7][4][0] =1;lib[7][4][1] =1;lib[7][3][2] =1;lib[7][2][3 ] =1;lib[7][1][4] =1;lib[7][1][5] =1;lib[7][1][6] =1;lib[8][1][0] =1;lib[8][2][0 ] =1;lib[8][3][0] =1;lib[8][0][1] =1;lib[8][4][1] =1;lib[8][0] [2] =1;lib[8][4][2] =1;lib[8][1][3] =1;lib[8][2][3] =1;lib[8][ 3][3] =1;lib[8][0][4] =1;lib[8][4][4] =1;lib[8][0][5] =1;lib[8 ][4][5] =1;lib[8][1][6] =1;lib[8][2][6] =1;lib[8][3][6] =1;lib [9][1][0] =1;lib[9][2][0] =1;lib[9][3][0] =1;lib[9][0][1] =1;lib[9][4][1] =1;lib[9][0][2] =1;lib[9][4][2] =1;lib[9][1][3] =1;lib[9][2][3] =1;lib[9][3][3] =1;lib[9][4][3] =1;lib[9][4][ 4] =1;lib[9][3][5] =1;lib[9][1][6] =1;lib[9][2][6] =1; 정수 시드 =(analogRead(0)+1)* (analogRead(1)+1)* (analogRead(2)+1)* (analogRead(3)+1); randomSeed(시드); 랜덤(10,9610806); 시드 =시드 *random(3336,15679912)+analogRead(random(4)); randomSeed(시드); 랜덤(10,98046); cli();//인터럽트 중지//2kHz에서 타이머0 인터럽트 설정 TCCR1A =0;// 전체 TCCR0A 레지스터를 0으로 설정 TCCR1B =0;// TCCR0B와 동일 TCNT1 =0;//카운터 값을 0으로 초기화 // 설정 2khz 증분에 대한 비교 일치 레지스터 OCR1A =259;// =(16*10^6) / (2000*64) - 1 (<256이어야 함) // CTC 모드 켜기 TCCR1A |=(1 <0;i--) { for (j=0;j<16;j++) { block[i][j]=block[i-1][j]; } } for (j=0;j<16;j++) { 블록[0][j]=0; } 업데이트LED(); 반환 1; } return 0;}int readBut(){ if (bdelay> millis()) { return 0; } if (analogRead(A4)> 500) { //왼쪽 bdelay =millis() + btsidedelay; 반환 3; } if (analogRead(A5)> 500) { //다운 bdelay =millis() + btdowndelay; 반환 4; } if (analogRead(A6)> 500) { //오른쪽 bdelay =millis() + btsidedelay; 반환 2; } if (analogRead(A7)> 500) { //업 bdelay =millis() + buttondelay; 반환 1; } 반환 0;} 무효 updateLED(){ int i; 정수 j; for (i=0;i<8;i++) { for (j=0;j<16;j++) { disp[i][j] =블록[i][j] | 더미[i][j]; } }}void 회전(){ //정사각형 블록(3) 건너뛰기 if (blocktype ==3) return; 정수 x; 정수이; 정수 나; 정수 j; // 왼쪽 감지 for (i=7;i>=0;i--) { for (j=0;j<16;j++) { if (block[i][j]) { xi =i; } } } //(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 if (!space_right()) { if (space_left3()) { if (!moveleft()) return; if (! moveleft()) 반환; xi--; xi--; } 그렇지 않으면 반환; } else if (!space_right2()) { if (space_left2()) { if (!moveleft()) return; xi--; } 그렇지 않으면 반환; } 블록[xi][yi]=0; 블록[xi][yi+2]=0; 블록[xi][yi+3]=0; 블록[xi-1][yi+1]=1; 블록[xi+1][yi+1]=1; 블록[xi+2][yi+1]=1; 블록 회전 =1; } else { 블록[xi][yi]=0; 블록[xi+2][yi]=0; 블록[xi+3][yi]=0; 블록[xi+1][yi-1]=1; 블록[xi+1][yi+1]=1; 블록[xi+1][yi+2]=1; 블록 회전 =0; } } //가운데 xi로 오프셋 ++; 이 ++; if (블록 유형 ==1) { if (블록 회전 ==0) { 블록[xi-1][yi-1] =0; 블록[xi-1][yi] =0; 블록[xi+1][yi] =0; 블록[xi][yi-1] =1; 블록[xi+1][yi-1] =1; 블록[xi][yi+1] =1; 블록 회전 =1; } else if (blockrotation ==1) { if (!space_left()) { if (!moveright()) return; xi++; } xi--; 블록[xi][yi-1] =0; 블록[xi+1][yi-1] =0; 블록[xi][yi+1] =0; 블록[xi-1][yi] =1; 블록[xi+1][yi] =1; 블록[xi+1][yi+1] =1; 블록 회전 =2; } else if (블록 회전 ==2) { yi --; 블록[xi-1][yi] =0; 블록[xi+1][yi] =0; 블록[xi+1][yi+1] =0; 블록[xi][yi-1] =1; 블록[xi][yi+1] =1; 블록[xi-1][yi+1] =1; 블록 회전 =3; } else { if (!space_right()) { if (!moveleft()) return; xi--; } 블록[xi][yi-1] =0; 블록[xi][yi+1] =0; 블록[xi-1][yi+1] =0; 블록[xi-1][yi-1] =1; 블록[xi-1][yi] =1; 블록[xi+1][yi] =1; 블록 회전 =0; } } if (블록 유형 ==2) { if (블록 회전 ==0) { 블록[xi+1][yi-1] =0; 블록[xi-1][yi] =0; 블록[xi+1][yi] =0; 블록[xi][yi-1] =1; 블록[xi+1][yi+1] =1; 블록[xi][yi+1] =1; 블록 회전 =1; } else if (blockrotation ==1) { if (!space_left()) { if (!moveright()) return; xi++; } xi--; 블록[xi][yi-1] =0; 블록[xi+1][yi+1] =0; 블록[xi][yi+1] =0; 블록[xi-1][yi] =1; 블록[xi+1][yi] =1; 블록[xi-1][yi+1] =1; 블록 회전 =2; } else if (블록 회전 ==2) { yi --; 블록[xi-1][yi] =0; 블록[xi+1][yi] =0; 블록[xi-1][yi+1] =0; 블록[xi][yi-1] =1; 블록[xi][yi+1] =1; 블록[xi-1][yi-1] =1; 블록 회전 =3; } else { if (!space_right()) { if (!moveleft()) return; xi--; } 블록[xi][yi-1] =0; 블록[xi][yi+1] =0; 블록[xi-1][yi-1] =0; 블록[xi+1][yi-1] =1; 블록[xi-1][yi] =1; 블록[xi+1][yi] =1; 블록 회전 =0; } } if (블록 유형 ==4) { if (블록 회전 ==0) { 블록[xi+1][yi-1] =0; 블록[xi-1][yi] =0; 블록[xi+1][yi] =1; 블록[xi+1][yi+1] =1; 블록 회전 =1; } else { if (!space_left()) { if (!moveright()) return; xi++; } xi--; 블록[xi+1][yi] =0; 블록[xi+1][yi+1] =0; 블록[xi-1][yi] =1; 블록[xi+1][yi-1] =1; 블록 회전 =0; } } if (블록 유형 ==5) { if (블록 회전 ==0) { 블록[xi][yi-1] =0; 블록[xi-1][yi] =0; 블록[xi+1][yi] =0; 블록[xi][yi-1] =1; 블록[xi+1][yi] =1; 블록[xi][yi+1] =1; 블록 회전 =1; } else if (blockrotation ==1) { if (!space_left()) { if (!moveright()) return; xi++; } xi--; 블록[xi][yi-1] =0; 블록[xi+1][yi] =0; 블록[xi][yi+1] =0; 블록[xi-1][yi] =1; 블록[xi+1][yi] =1; 블록[xi][yi+1] =1; 블록 회전 =2; } else if (블록 회전 ==2) { yi --; 블록[xi-1][yi] =0; 블록[xi+1][yi] =0; 블록[xi][yi+1] =0; 블록[xi][yi-1] =1; 블록[xi-1][yi] =1; 블록[xi][yi+1] =1; 블록 회전 =3; } else { if (!space_right()) { if (!moveleft()) return; xi--; } 블록[xi][yi-1] =0; 블록[xi-1][yi] =0; 블록[xi][yi+1] =0; 블록[xi][yi-1] =1; 블록[xi-1][yi] =1; 블록[xi+1][yi] =1; 블록 회전 =0; } } if (블록 유형 ==6) { if (블록 회전 ==0) { 블록[xi-1][yi-1] =0; 블록[xi][yi-1] =0; 블록[xi+1][yi-1] =1; 블록[xi][yi+1] =1; 블록 회전 =1; } else { if (!space_left()) { if (!moveright()) return; xi++; } xi--; 블록[xi+1][yi-1] =0; 블록[xi][yi+1] =0; 블록[xi-1][yi-1] =1; 블록[xi][yi-1] =1; 블록 회전 =0; } } //만든 블록과 더미가 겹치면 회전하면서 행을 위로 올립니다. while (!check_overlap()) { for (i=0;i<18;i++) { for (j=0;j<8;j++) { block [j][i] =블록[j][i+1]; } } 지연 =millis() + delay_; } 업데이트LED(); }void movedown(){ if (space_below()) { //아래로 이동 int i; for (i=15;i>=0;i--) { int j; for (j=0;j<8;j++) { 블록[j][i] =블록[j][i-1]; } } for (i=0;i<7;i++) { 블록[i][0] =0; } } else { // 병합 및 새 블록 int i; 정수 j; for (i=0;i<8;i++) { for(j=0;j<16;j++) { if (block[i][j]) { 말뚝[i][j]=1; 블록[i][j]=0; } } } newBlock(); } 업데이트LED(); }부울 check_overlap(){ int i; 정수 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; } } } 반환 true;} 무효 check_gameover(){ int i; 정수 j; 정수 cnt=0;; for(i=15;i>=0;i--) { cnt=0; for (j=0;j<8;j++) { if (pile[j][i]) { cnt ++; } } if (cnt ==8) { lines++; for (j=0;j<8;j++) { 말뚝[j][i]=0; } 업데이트LED(); 지연(50); 정수 k; for(k=i;k>0;k--) { for (j=0;j<8;j++) { 말뚝[j][k] =말뚝[j][k-1]; } } for (j=0;j<8;j++) { 더미[j][0] =0; } 업데이트LED(); 지연(50); 나는 ++; } } for(i=0;i<8;i++) { if (pile[i][0]) gameover(); } 반환;} 무효 gameover(){ int i; 정수 j; // 블라인드 닫기 for (i=0;i<8;i++) { for (j=0;j<16;j++) { if (j%2) { disp[i][j]=1; } else { disp[7-i][j]=1; } } 지연(60); } // 스코어 보드 계산 int num_lines; num_lines =2; 부울 점수[8][17]; for (i=0;i<8;i++) { for (j=0;j<16;j++) { 점수[i][j] =0; } } 정수 숫자1 =(줄/10) % 10; int digit2 =(줄) % 10; for (i=0;i<5;i++) for (j=0;j<8;j++) { score[7-j][i+3] =lib[digit1][i][j]; } for (i=0;i<5;i++) for (j=0;j<8;j++) { score[7-j][i+9] =lib[digit2][i][j]; } for (i=0;i<16;i++) { 점수[0][i]=0; } // 오픈 블라인드 점수 for (i=0;i<8;i++) { for (j=0;j<16;j++) { if (j%2) { disp[i][j]=score[ 나][j]; } else { disp[7-i][j]=점수[7-i][j]; } } 지연(60); } 지연(100); while(true) { for (i=0;i<8;i++) { for (j=0;j<16;j++) { disp[i][j] =점수[i][j]; } } 부울 템플릿[8]; for (i=0;i<8;i++) { 점수[i][16]=점수[i][0]; } for (i=0;i<8;i++) { for (j=0;j<16;j++) { 점수[i][j] =점수[i][j+1]; } } 지연(100); } } 무효 newBlock(){ check_gameover(); 블록 유형 =무작위(7); if (블록 유형 ==0) // 0 // 0 // 0 // 0 { 블록[3][0]=1; 블록[3][1]=1; 블록[3][2]=1; 블록[3][3]=1; } if (블록 유형 ==1) // 0 // 0 0 0 { 블록[2][0]=1; 블록[2][1]=1; 블록[3][1]=1; 블록[4][1]=1; } if (블록 유형 ==2) // 0 // 0 0 0 { 블록[4][0]=1; 블록[2][1]=1; 블록[3][1]=1; 블록[4][1]=1; } if (블록 유형 ==3) // 0 0 // 0 0 { 블록[3][0]=1; 블록[3][1]=1; 블록[4][0]=1; 블록[4][1]=1; } if (블록 유형 ==4) // 0 0 // 0 0 { 블록[4][0]=1; 블록[5][0]=1; 블록[3][1]=1; 블록[4][1]=1; } if (블록 유형 ==5) // 0 // 0 0 0 { 블록[4][0]=1; 블록[3][1]=1; 블록[4][1]=1; 블록[5][1]=1; } if (블록 유형 ==6) // 0 0 // 0 0 { 블록[3][0]=1; 블록[4][0]=1; 블록[4][1]=1; 블록[5][1]=1; } 블록 회전 =0;}부울 space_below(){ int i; 정수 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]) { false를 반환합니다. } } } } 반환 true;}부울 space_left2(){ int i; 정수 j; for (i=15;i>=0;i--) { for (j=0;j<8;j++) { if (block[j][i]) { if (j ==0 || j ==1) 거짓을 반환합니다. if (말뚝[j-1][i] | 말뚝[j-2][i]) { false를 반환합니다. } } } } 반환 true;}부울 space_left3(){ int i; 정수 j; for (i=15;i>=0;i--) { for (j=0;j<8;j++) { if (block[j][i]) { if (j ==0 || j ==1 ||j ==2 ) false를 반환합니다. if (말뚝[j-1][i] | 말뚝[j-2][i]|말뚝[j-3][i]) { false를 반환합니다. } } } } 반환 true;}부울 space_left(){ int i; 정수 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]) { false를 반환합니다. } } } } 반환 true;}부울 space_right(){ int i; 정수 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]) { false를 반환합니다. } } } } 반환 true;}부울 space_right3(){ int i; 정수 j; for (i=15;i>=0;i--) { for (j=0;j<8;j++) { if (block[j][i]) { if (j ==7||j ==6||j ==5) false를 반환합니다. if (말뚝[j+1][i] |말뚝[j+2][i] | 말뚝[j+3][i]) { false를 반환합니다. } } } } 반환 true;}부울 space_right2(){ int i; 정수 j; for (i=15;i>=0;i--) { for (j=0;j<8;j++) { if (block[j][i]) { if (j ==7 || j ==6) 거짓을 반환합니다. if (pile[j+1][i] |pile[j+2][i]) { return false; } } } } return true;}ISR(TIMER1_COMPA_vect){ // timer1의 경우 0, timer2의 경우 2로 변경 LEDRefresh();}void LEDRefresh(){ int i; 정수 k; //////////////////////////////////////////////////// // 핀을 잘못 납땜했습니다. (01234567 대신 12345670). // 따라서 이 코드 부분은 이 문제를 소프트웨어로 수정하기 위한 것입니다. 부울 tmpdisp[8][16]; for (k=0;k<16;k++) { for(i=1;i<8;i++) { tmpdisp[i][k]=disp[i-1][k]; } tmpdisp[0][k]=disp[7][k]; } ///////////////////////////////////////////////// for(i =0;i<8;i++) { 정수 j; if (i ==0) j =rowPin+7; 그렇지 않으면 j =rowPin+i-1; 바이트 상위 =0; 정수 b; for(b =0;b<8;b++) { 위 <<=1; if (!tmpdisp[b][i]) 위 |=1; } 하위 바이트 =0; for(b =0;b<8;b++) { 아래 <<=1; if (!tmpdisp[b][i+8]) 더 낮은 |=1; } 디지털 쓰기(j,LOW); digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, 하위); shiftOut(dataPin, clockPin, LSBFIRST, 상위); digitalWrite(래치핀, 높음); digitalWrite(rowPin+i,HIGH); 지연(1); } 디지털 쓰기(rowPin+7,LOW); }

    회로도


    제조공정

    1. MPU-6050을 사용한 Arduino 자이로스코프 게임
    2. Arduino 디지털 주사위
    3. 수제 TV B-Gone
    4. Arduino 게임 컨트롤러
    5. MAX7219가 있는 24x16 매트릭스의 Arduino Pong 게임
    6. 픽셀 체이서 게임
    7. 단일 LED 매트릭스 Arduino 플립 시계
    8. NeoMatrix Arduino Pong
    9. Arduino Nano가 있는 휴대용 가이거 계수기
    10. 혼자서는 절대 타지 마세요