#include "LedControl.h"
#include "Timer.h"
/*
MAX7129 8x8 led matrix indexing
7 6 ... 1 0
0 x x ... x x
1 x x ... x x
. ...
. ...
6 x x ... x x
7 x x ... x x
*/
/* https://wokwi.com/projects/300754474795794957"
this https://wokwi.com/projects/291779699024069128
face https://randomnerdtutorials.com/guide-for-8x8-dot-matrix-max7219-with-arduino-pong-game/
*/
/*************************************************
* General stuffs
*************************************************/
#define CS_PIN PB0
#define CLK_PIN PB1
#define DIN_PIN PB2
#define BTN_PIN PB4
#define RND_PIN A0
#define MAX_SEG 1
#define LED_ON 1
#define LED_OFF 0
enum MachineState{
ON, OFF
};
MachineState currentMachineState;
LedControl matrix = LedControl(DIN_PIN, CLK_PIN, CS_PIN, MAX_SEG); // MAX7219
bool waitRefresh = false;
/*************************************************
* for Avoid Collosion Game
*************************************************/
const byte MAX_NUMBER_ENEMIES = 4;
const byte FIX_AVOID_COL_INDEX = 7;
const byte STR_AVOID_ROW_INDEX = 7;
byte currAvoidRowIndex = 0;
byte prevAvoidRowIndex = 0;
byte currEnemiesR[MAX_NUMBER_ENEMIES] = { 1, 3, 5, 7 }; // row
byte currEnemiesC[MAX_NUMBER_ENEMIES] = { 0, 0, 0, 0 }; // column
byte currEnemiesL[MAX_NUMBER_ENEMIES] = { 1, 2, 3, 4 }; // length
byte prevEnemiesC[MAX_NUMBER_ENEMIES] = { 7, 7, 7, 7 }; // prev column
int currEnemiesRnd[MAX_NUMBER_ENEMIES] = { 100, 100, 100, 100 };
Timer currEnemyiesTimer[MAX_NUMBER_ENEMIES];
Timer currEnemyTimer1;
Timer currEnemyTimer2;
Timer currEnemyTimer3;
Timer currEnemyTimer4;
/*************************************************
* General functions
*************************************************/
/* pin change interrupt wakes us up */
ISR (PCINT0_vect) {
currentMachineState = ON;
}
void setup() {
cli();
PCMSK |= (1 << BTN_PIN);
GIMSK |= (1 << PCIE);
pinMode(BTN_PIN, INPUT_PULLUP);
randomSeed(analogRead(RND_PIN));
currentMachineState = OFF;
sei();
currAvoidRowIndex = STR_AVOID_ROW_INDEX;
prevAvoidRowIndex = 0;
matrix.shutdown(0, false);
matrix.setIntensity(0, 7);
matrix.clearDisplay(0);
for(int i=0;i<MAX_NUMBER_ENEMIES;i++){
currEnemiesRnd[i] = random(150, 300);
currEnemyiesTimer[i].setInterval(currEnemiesRnd[i]);
switch(i){
case 0: currEnemyiesTimer[i].setCallback(AvoidCollosionBoth0); break;
case 1: currEnemyiesTimer[i].setCallback(AvoidCollosionBoth1); break;
case 2: currEnemyiesTimer[i].setCallback(AvoidCollosionBoth2); break;
case 3: currEnemyiesTimer[i].setCallback(AvoidCollosionBoth3); break;
}
currEnemyiesTimer[i].start();
}
}
void loop() {
AvoidCollosionGame();
}
void AvoidCollosionBoth0(){
AvoidCollosionEnemiesOff(0);
AvoidCollosionEnemiesOn(0);
}
void AvoidCollosionBoth1(){
AvoidCollosionEnemiesOff(1);
AvoidCollosionEnemiesOn(1);
}
void AvoidCollosionBoth2(){
AvoidCollosionEnemiesOff(2);
AvoidCollosionEnemiesOn(2);
}
void AvoidCollosionBoth3(){
AvoidCollosionEnemiesOff(3);
AvoidCollosionEnemiesOn(3);
}
void AvoidCollosionEnemiesOff(byte i){
prevEnemiesC[i] = currEnemiesC[i];
currEnemiesC[i] = ( currEnemiesC[i] + 1 ) % 8;
matrix.setLed(0, currEnemiesR[i], prevEnemiesC[i], LED_OFF);
if(currEnemiesC[i] == 0){
int a = 2*i;
int b = 2*i+1;
currEnemiesR[i] = random(a,b);
// if(i == 0){currEnemiesR[0] = 0,1;}
// currEnemiesR[1] = random(2,3);
// currEnemiesR[2] = random(4,5);
// currEnemiesR[3] = random(6,7);
}
}
void AvoidCollosionEnemiesOn(byte i){
matrix.setLed(0, currEnemiesR[i], currEnemiesC[i], LED_ON);
}
void AvoidCollosionGame(){
/* update parameters of all enemies */
for(int i=0;i<MAX_NUMBER_ENEMIES;i++){
currEnemyiesTimer[i].update();
}
/* button pushed so move up the ball and enemies */
if( !digitalRead(BTN_PIN) && currentMachineState == ON ){
if( 0 < currAvoidRowIndex ){
prevAvoidRowIndex = currAvoidRowIndex;
currAvoidRowIndex = currAvoidRowIndex - 1;
}else{
prevAvoidRowIndex = 0;
currAvoidRowIndex = STR_AVOID_ROW_INDEX;
};
matrix.setLed(0, currAvoidRowIndex, FIX_AVOID_COL_INDEX, LED_ON);
delay(50);
matrix.setLed(0, prevAvoidRowIndex, FIX_AVOID_COL_INDEX, LED_OFF);
currentMachineState = OFF;
}else{
delay(50);
}
}