# Fill The Board Game using Arduino
## Materials Required
* 8x8 Neopixel LED boards
* 1602A LCD Display 16x2
* Arduino uno board
* Ten Pin Momentary Push Button (12x12x7.3mm)
* Jumper wires
* Breadboard
* PCB
* Multimeter
* Resistors and Potentiometer
* Switches
* Bluetooth chips (optional)
* Analog joystick (optional)
## Tools Required
* Soldering Iron
* Glue gun
* Paper cutters and Scissors
* Plier
## Software Required
* Arduino IDE (linux or windows)
## Arduino + Neopixel
### Circuit Diagram

## Getting started with adafruit neopixel
https://www.instructables.com/Getting-Started-With-NeoPixle-WS2812-RGB-LED/
### Adafruit Library installation:
https://learn.adafruit.com/adafruit-neopixel-uberguide/arduino-library-installation
* via the Library Manager interface.
From the Sketch menu, > Include Library > Manage Libraries... In the text input box type in "NeoPixel".
* Look for "Adafruit NeoPixel by Adafruit" and select the latest version by clicking on the popup menu next to the Install button. Then click on the Install button.
* After it's installed, you can click the "close" button.
## Understanding the Code
Libraries required:
* Adafruit_Neopixel
* LedControl.h
* avr/pgmspace.h
Global variables:
You'll first set up some global variables for the pins your LED will connect to. This will make it easier to differentiate which one is red, green, and blue in the main part of your program
Setup:
The setup() function is called when a sketch starts. Use it to initialize variables, pin modes, start using libraries, etc. The setup() function will only run once, after each powerup or reset of the Arduino board.
Functions:
* Serial
Used for communication between the Arduino board and a computer or other devices.
* PinMode
configure the pins as outputs in setup()
eg:
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
#### Progmem
Store data in flash (program) memory instead of SRAM.
### Serial Communication:
Serial communication is the process of sending one bit of data at a time sequentially from one place to another. The serial library has functions like serial begin, read, available, parseInt, parseString, parseFloat, print, etc.
The serial receive buffer can hold 64 bytes. The data you send from your computer to your Arduino will end up in the serial receive buffer. **Serial.read** is a function of the Arduino Serial Library and what it does is read out the first available byte from the serial receive buffer.
We can use the available function to check how many bytes are available to be read in the serial receive buffer. **Serial.available** will return the number of bytes currently stored in the serial receive buffer.
Using Serial.parseInt() to separate the data by commas, read the information into your variables
eg:
int red = Serial.parseInt();
int green = Serial.parseInt();
int blue = Serial.parseInt();
Loop:
The loop() function does precisely what its name suggests, and loops consecutively, allowing your program to change and respond. Use it to actively control the Arduino board.
Arduino pull-up function:
pull-up means the pushbutton's logic is inverted. It goes HIGH when it's open, and LOW when it's pressed.
### References:
https://www.arduino.cc/reference/en/
https://www.arduino.cc/reference/en/language/variables/utilities/progmem/
https://docs.arduino.cc/built-in-examples/communication/ReadASCIIString
https://docs.arduino.cc/built-in-examples/digital/InputPullupSerial
## Toy models
In order to understand working of neopixel board and address position $(i,j)$ of each LED, we initially work with few toy models.
### Moving coloured dot on display using switch
We will use letters (a,d,w,s) as keyboard inputsto move left, right, up, and down. This way we are able to control position of a dot(object).
Plan:
We can then extend this to longer objects (size=2,3, or 4 ships). We will also use an additional keyboard input to lock the object. We will add a constaint to avoid overlap of objects.

### Code:
```clike=
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
int pin = 2;
int numPixels = 64;
int pixelFormat = NEO_GRB + NEO_KHZ800;
int x;
Adafruit_NeoPixel *pixels;
void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
clock_prescale_set(clock_div_1);
#endif
pixels = new Adafruit_NeoPixel(numPixels, pin, pixelFormat);
pixels->begin();
pixels->clear();
pixels->setBrightness(10);
Serial.begin(9600);
x = 0;
}
void loop() {
char y;
y = Serial.read();
//pixels->clear();
pixels->setPixelColor(x, pixels->Color(0, 0, 255));
if(y == 'd'){
if((x+1)%8 == 0){
x = x-7;
}
else{
x =x+1 ;
} }
if(y == 'a'){
if((x)%8 == 0){
x = x +7;
}
else{
x = x-1;
}}
if(y == 's'){
x = (x+8)%64;
}
if(y == 'w'){
if ((x%64)>7){
x = (x-8)%64;}
else{
x = (56+x)%64;
}
}
pixels->show();
}
```
## Console
Day 2:
A console consists of five switches (up, down, left, right, enter).
We will use a breadboard to implant the switches.
 
### Precautions:
* Place switches such that they do not short. You may use a multimeter for this.
* Provide necessary grounding.
### Code:
```clike=
const int UP_PIN = 10;
const int DOWN_PIN = 8;
const int LEFT_PIN = 9;
const int RIGHT_PIN = 11;
// const int ENTER_PIN = 3;
// const int LED_PIN = 2;
void setup(){
pinMode( UP_PIN, INPUT );
pinMode( DOWN_PIN, INPUT );
pinMode( LEFT_PIN, INPUT );
pinMode( RIGHT_PIN, INPUT );
Serial.begin( 9600 );
}
void loop(){
int value_u,value_d,value_l,value_r;
value_u = digitalRead( UP_PIN );
value_d = digitalRead( DOWN_PIN );
value_l = digitalRead( LEFT_PIN );
value_r = digitalRead( RIGHT_PIN );
// To see if switches are actually working
Serial.println( value_u + value_d + value_l + value_r );
delay(10);
}
```
Day 3:
Trying to simulate console using Tinkercad.

#### Code:
``` clike=
#include <LiquidCrystal.h>
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
int enter = 6, right = 7, left = 10, up = 8, down=9;
int enterstate = 1, rightstate = 0, leftstate = 0, upstate = 0, downstate=0;
void setup() {
lcd.begin(16, 2);
Serial.begin(9600);
lcd.setCursor(0,0);
lcd.print("Press Enter");
lcd.setCursor(0,1);
lcd.print("to Start");
delay(1000);
pinMode(enter, INPUT);
pinMode(right, INPUT);
pinMode(left, INPUT);
pinMode(up, INPUT);
pinMode(down , INPUT);
digitalWrite(enter,HIGH);
digitalWrite(right,HIGH);
digitalWrite(left,HIGH);
digitalWrite(up,HIGH);
digitalWrite(down,HIGH);
}
void loop() {
rightstate=digitalRead(right);
leftstate=digitalRead(left);
upstate=digitalRead(up);
downstate=digitalRead(down);
enterstate=digitalRead(enter);
if (enterstate == LOW) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Hello, "); // to test enter button
lcd.setCursor(0,1);
lcd.print("pls wait");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
}
if (rightstate == LOW) {
lcd.print("right "); // replace this with variable of LED screen
delay(100);
lcd.clear();
lcd.setCursor(0, 0);
}
if (leftstate == LOW) {
lcd.print("left "); // replace this with variable of LED screen
delay(100);
lcd.clear();
lcd.setCursor(0, 0);
}
if (upstate == LOW) {
lcd.print("up "); // replace this with variable of LED screen
delay(100);
lcd.clear();
lcd.setCursor(0, 0);
}
if (downstate == LOW) {
lcd.print("down "); // replace this with variable of LED screen
delay(100);
lcd.clear();
lcd.setCursor(0, 0);
}
Serial.println(enterstate);
}
```
Serial plotter on topright corner of IDE can be used to visualise output series

**References:**
https://www.deviceplus.com/arduino/the-basics-of-arduino-reading-switch-states/
https://create.arduino.cc/projecthub/Alojz/arduino-pocket-game-console-a-maze-maze-game-63c225
## LCD Interface
16x2 LCD 1602A module can be used as the interface to display messages regarding game to the user.
### Libraries used:
* LiquidCrystal Library - Will available in Arduino IDE by default - For the first method.
### Pin description:

### Circuit:

### Code (Example):
``` clike=
#include <LiquidCrystal.h>
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup() {
lcd.begin(16, 2);
lcd.print("First line");
lcd.setCursor(0,1);
lcd.print("Second line");
}
void loop() {
}
```
## FILL THE BOARD GAME WITH CONSOLE
### Game:

Here green colour represent the point which can be moved using controls. Red and majenta colours represent player 1 and 2. White colour represent occupied/locked space.

### Code (with keyboad):
```clike =
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
int pin = 2;
int numPixels = 64;
int pixelFormat = NEO_GRB + NEO_KHZ800;
int x;
int x2;
int g[64] = {};
int b[64] = {};
int y[250] = {};
int k = 0;
int j = 0 ;
int l = 0;
int i;
int m = 0;
int n =0;
int h;
int o =0;
Adafruit_NeoPixel *pixels;
void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
clock_prescale_set(clock_div_1);
#endif
pixels = new Adafruit_NeoPixel(numPixels, pin, pixelFormat);
pixels->begin();
pixels->clear();
pixels->setBrightness(2);
Serial.begin(9600);
x = 0;
x2 = -1;
int green = pixels->Color(0,255,0);
int red = pixels->Color(255,0,0);
int blue = pixels->Color(0,0,255);
int no = pixels->Color(0,0,0);
}
void loop() {
char s;
s = Serial.read();
pixels->setPixelColor(x, pixels->Color(0,255,0));
for(n=0;n<250;n++) {
pixels->setPixelColor(y[n], pixels->Color(198,198,198));
}
for(k=0;k<64;k++) {
pixels->setPixelColor(b[k], pixels->Color(102,0,102));
}
for(i=0;i<64;i++) {
pixels->setPixelColor(g[i], pixels->Color(255,0,0));
}
pixels->setPixelColor(0,pixels->Color(198,198,198));
if(s == 'd'){
pixels->setPixelColor(x,(0,0,0));
if((x+1)%8 == 0){
x = x-7;
}
else{
x =x+1 ;
} }
if(s == 'a'){
pixels->setPixelColor(x,(0,0,0));
if((x)%8 == 0){
x = x +7;
}
else{
x = x-1;
}}
if(s == 's'){ pixels->setPixelColor(x,(0,0,0));
x = (x+8)%64;
}
if(s == 'w'){pixels->setPixelColor(x,(0,0,0));
if ((x%64)>7){
x = (x-8)%64;}
else{
x = (56+x)%64;
}
}
if(s == 'g'){
if (o%2 == 0){
g[j] = x;
j = j+1;
o = o+1;
}
else if(o%2 == 1){
b[l] = x;
l = l+1;
o = o+1;
}
if((x+1) % 8 == 0){
y[m]=x-1;
y[m+1] = x+7;
y[m+2] = x+8;
y[m+4] = x-9;
y[m+3] = x-8;
m = m+5;
}
else if ((x)%8 == 0){
y[m+1] = x+1;
y[m+2] = x+8;
y[m] = x+9;
y[m+4] = x-7;
y[m+3] = x-8;
m = m+5;
}
else{
y[m]=x-1;
y[m+1] = x+1;
y[m+2] = x+8;
y[m+3] = x-8;
y[m+4] = x+7;
y[m+5] = x+9;
y[m+6] = x-7;
y[m+7] = x-9;
m = m+8;
}
}
pixels->show();
}
```
### Code (with console):
```clike=
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#include <LiquidCrystal.h>
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
int enter = 6, right = 7, left = 10, up = 8, down=9;
int enterstate = 1, rightstate = 0, leftstate = 0, upstate = 0, downstate=0;
int pin = 13;
int numPixels = 64;
int pixelFormat = NEO_GRB + NEO_KHZ800;
int x;
int g[64] = {};
int b[64] = {};
int y[250] = {};
int k = 0, j = 0, l = 0, i = 0, m = 0, n =0, o = 0, h = 0;
Adafruit_NeoPixel *pixels;
void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
clock_prescale_set(clock_div_1);
#endif
pixels = new Adafruit_NeoPixel(numPixels, pin, pixelFormat);
pixels->begin();
pixels->clear();
pixels->setBrightness(2);
Serial.begin(9600);
x = 0;
lcd.begin(16, 2);
lcd.setCursor(0,0);
lcd.print("Press Enter");
lcd.setCursor(0,1);
lcd.print("to Start");
delay(1000);
pinMode(enter, INPUT);
pinMode(right, INPUT);
pinMode(left, INPUT);
pinMode(up, INPUT);
pinMode(down , INPUT);
digitalWrite(enter,HIGH);
digitalWrite(right,HIGH);
digitalWrite(left,HIGH);
digitalWrite(up,HIGH);
digitalWrite(down,HIGH);
}
void loop() {
rightstate = digitalRead(right);
leftstate = digitalRead(left);
upstate = digitalRead(up);
downstate = digitalRead(down);
enterstate = digitalRead(enter);
char s;
s = Serial.read();
for(n=0;n<250;n++) {
pixels->setPixelColor(y[n], pixels->Color(198,198,198));}
for(k=0;k<64;k++) {
pixels->setPixelColor(b[k], pixels->Color(102,0,102));}
for(i=0;i<64;i++) {
pixels->setPixelColor(g[i], pixels->Color(255,0,0));}
pixels->setPixelColor(x, pixels->Color(0,255,0));
delay(100);
pixels->setPixelColor(0,pixels->Color(198,198,198));
if(rightstate == LOW){
pixels->setPixelColor(x,(0,0,0));
if((x+1)%8 == 0){
x = x-7;}
else{
x =x+1 ;}
lcd.clear();
lcd.print("right ");
lcd.setCursor(0, 0); }
if(leftstate == LOW){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("left ");
pixels->setPixelColor(x,(0,0,0));
if((x)%8 == 0){
x = x +7;}
else{
x = x-1; }}
if(downstate == LOW){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("down ");
pixels->setPixelColor(x,(0,0,0));
x = (x+8)%64; }
if(upstate == LOW){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("up ");
pixels->setPixelColor(x,(0,0,0));
if ((x%64)>7){
x = (x-8)%64;}
else{
x = (56+x)%64; }}
if(enterstate == LOW){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Hello, "); // to test enter button
lcd.setCursor(0,1);
lcd.print("pls wait");
if (o%2 == 0){
g[j] = x;
j = j+1;
o = o+1;}
else if(o%2 == 1){
b[l] = x;
l = l+1;
o = o+1;}
if((x+1) % 8 == 0){
y[m]=x-1;
y[m+1] = x+7;
y[m+2] = x+8;
y[m+4] = x-9;
y[m+3] = x-8;
m = m+5;}
else if ((x)%8 == 0){
y[m+1] = x+1;
y[m+2] = x+8;
y[m] = x+9;
y[m+4] = x-7;
y[m+3] = x-8;
m = m+5;}
else{
y[m]=x-1;
y[m+1] = x+1;
y[m+2] = x+8;
y[m+3] = x-8;
y[m+4] = x+7;
y[m+5] = x+9;
y[m+6] = x-7;
y[m+7] = x-9;
m = m+8;}}
pixels->show();}
```
## Miscellaneous
Day 3:
  
<b>Soldering pins onto (i) neopixel board (ii) arduino mini board (iii) blank PCB </b>
Day 4:
  
<b>Connected console and LCD screen with LED neopixel game screen powered by 3.7 V battery </b>
  
<b>Finished product </b>
## Tinkercad simulations
https://www.tinkercad.com/things/eZSJMhNGmBO-glorious-fyyran/editel?sharecode=HZk7kbc2HIlq3DclFjFyLp7BOrr01vIiQBhLVCmt97A
## Challenges
* Hardware - We soldered many wires onto boards but nonetheless the possibility of weak connections could not be avoided. We had to add potentiometer to make sure there was no voltage issue.
* Software - Debugging an algorithm takes time!
* Design - All the boards, wires and screens made it very bulky and it ws difficult to fit it into one compact box. We later decided to just fit LCD, LED screens and switch board onto a facade leaving wires, battery, etc externally kept in a rectangular box. This will allow people to see the connections.
## Warning:
* Codes may contain bugs, please make sure you understand the logic. We will be looking into it and updating the code in future.
* The product might face hardware issue. Please make sure voltage potential and current through the circuit is maintained.
## Future Add-ons
* Snake Game
https://create.arduino.cc/projecthub/vasiljevalentin/snake-led-16x16-matrix-game-27ba6d
* Othello game
https://create.arduino.cc/projecthub/krishnalalith/othello-7301fb
* Battleship game
* Analog joystick + bluetooth console
* Voice-assisted bluetooth console
## Team
* Robin KP
* Darsan TI
* Nishanga P
* Adish Illikkal
