arcade.ino
/* First Release April 11, 2013 by Jenna Yun Lee, Cooper Union, All rights reserved. I strongly support open source programming. Free to distribute and modify, but please keep the original copyright information. Contact lee55@cooper.edu for suggestions/errors/helps! */ /* As of March 29, 2013 This code aims at: 1. recognizes an input signal that a button is hit 2. get the address of the button 3. light up the LED in the corresponding address */ #include "SPI.h" #include "Adafruit_WS2801.h" uint8_t dataPin = 2; uint8_t clockPin = 3; boolean side =0; int pinZ = A5; //PinZ set as Analog as we had a power inconsistence problem. int pinA = 8; int pinB = 9; int pinC = 10; int pinD = 11; int pinE = 12; int pinF = 13; int pixnum = 6; int address[6]; int binary[6]; boolean state[25]; Adafruit_WS2801 strip ((uint16_t)5, (uint16_t)5, dataPin, clockPin); void setup() { Serial.begin(9600); for(int i = 0; i<(sizeof(state))/(sizeof (boolean)); i++) { state[i] = 1; } pinMode(pinZ, OUTPUT); pinMode(pinA, OUTPUT); pinMode(pinB, OUTPUT); pinMode(pinC, OUTPUT); pinMode(pinD, OUTPUT); pinMode(pinE, OUTPUT); pinMode(pinF, OUTPUT); digitalWrite(pinA, LOW); digitalWrite(pinB, LOW); digitalWrite(pinC, LOW); digitalWrite(pinD, LOW); digitalWrite(pinE, LOW); digitalWrite(pinF, LOW); digitalWrite(pinZ, LOW); strip.begin(); strip.show(); } void loop() { check(50); } int check(int num) { int i = 0; while (i<num) { toBinary(i); digitalWrite(pinA, binary[0]); digitalWrite(pinB, binary[1]); digitalWrite(pinC, binary[2]); digitalWrite(pinD, binary[3]); digitalWrite(pinE, binary[4]); digitalWrite(pinF, binary[5]); if(isHit()) { if(i>24) side = 1; if(state[i%25]) { state[i%25] = 0; lightup((i%25)); } break; } i++; } } /* boolean isHit() returns true if the corresponding target is ever hit since the game started, false otherwise. */ boolean isHit() { if(analogRead(pinZ) >100) { return true; } else return false; } /* As of March 29, 2013, boolean isHit2() is not used. But I'm still leaving the code here as it is pretty useful to test the code before buttons are connected to muxes. You can test EVERYTHING other than mux-related commands, only with seven buttons here. Feed inputs from each button to a pin. */ boolean isHit2() { if(digitalRead(pinA) == HIGH || digitalRead(pinB) == HIGH || digitalRead(pinC) == HIGH || digitalRead(pinD) == HIGH || digitalRead(pinE) == HIGH || digitalRead(pinF) == HIGH) { if(digitalRead(pinA) == HIGH) Serial.println("Pin A is hit"); if(digitalRead(pinB) == HIGH) Serial.println("Pin B is hit"); if(digitalRead(pinC) == HIGH) Serial.println("Pin C is hit"); if(digitalRead(pinD) == HIGH) Serial.println("Pin D is hit"); if(digitalRead(pinE) == HIGH) Serial.println("Pin E is hit"); if(digitalRead(pinF) == HIGH) Serial.println("Pin F is hit"); return true; } else return false; } /* toBinary takes an integer n as a parameter, and returns the value in binary. For example, toBinary(16) returns 10000, toBinary(20) returns 10100. Since our project uses 6-digit binaries, datatype INT is not enough to store all values, so an array that stores each digit of a binary to each slot is used. For example if toBinary(20) is called, binary[0] = 0, binary[1] = 1, binary[2] = 0, binary[3]=1, and so on. binary[0]= 0 because toBinary(20) returns 5-digit binary, while the array stores up to 6 digits. */ void toBinary(int n) { if(n !=0) //this part is dangerous but works fine in arduino //as default int array is automatically initiallized with '0'. { int i = 0; int num = (sizeof(binary)/sizeof(int))-1; while (n>1) { binary[num-i] = n%2; n = n/2; i++; } binary[num-i] = 1; if(i<=num) { for(i=i+1; i<=num; i++) binary [num-i]=0; } else Serial.println("Your binary sucks, bitch."); } } /* int toDecimal() converts the existing binary stored in binary[] to decimal. */ int toDecimal() { return (binary[0]*power(2,5))+(binary[1]*power(2,4))+(binary[2]*power(2,3))+(binary[3]*power(2,2))+(binary[4]*power(2,1))+(binary[5]*power(2,0)); } /* void lightup(int n) lights up an LED with address n */ void lightup(int n) { if(side) strip.setPixelColor(((uint16_t)getx(n)),((uint16_t)gety(n)),255,0,0); else strip.setPixelColor(((uint16_t)getx(n)),((uint16_t)gety(n)),0,0,255); strip.show(); delay(200); } /*address from 0-24, converts into coordinate value (x,y) Note: light strip "snakes" */ int getx(int n) { int pixel = n+1; int absx = pixel%(strip.getWidth()); int x = (absx+strip.getWidth()-1)%strip.getWidth(); if(isEven(n) && n<=24 || isEven(n+1) && n>24) { //CHECK THIS CONDITIONS return ((strip.getWidth()-absx)+strip.getWidth())%strip.getWidth(); } else return x; } int gety(int n){ return n/(strip.getWidth()); } /* isEven(int n) is a helper function for x. Returns true if nth pixel is on the even row, false otherwise. */ boolean isEven (int n){ return ((gety(n)%2)==1); } /* Modified version of pow(int base, int exponent) from pre-made Arduino's reference library. Because of the way the datatype float works, pre-made pow() goes only up to 10^4 or so. And as it returns float datatype, datacasting is always the pain in the ass. (Seriously, it is.) This power function goes up to 32768, or 10^5. So If you happen to use binary number that goes more than 7 digits, well... good luck, bro. I personally suggest using an array again to store decimals? */ int power (int base, int exponent) { int value = 1; for(int i = 1; i<=exponent; i++) value*=base; return value; }