Hi, I'm building an augmented reality game where uses earn points by tagging an RFID reader. A strip of WS8212 LEDs serves as an information display (depicting whose turn, current score, etc.).
I'm experiencing a bug that I've narrowed down to one LED lighting function that if I comment out, disappears. Essentially, the bug is this:
All player points are kept in an int array playerScores[11]. But when I call waitingPlayerLed() on line 136 so the LEDs show the color of the player whose turn it is, somehow the value in playerScores[1] unexpectedly jumps to 255. It should remain as-is unless called by addPlayerPoint(playerTurn) on line 146.
The thing is, there's no functionality inside waitingPlayerLed() that references playerScores[]. All I can think of is something in the fastLED library that may be point to a memory location? ideas? Thanks in advance!
//1.2
//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
//Definitions
//PN532 code ; If using the PN532 with I2C, define the pins connected to the IRQ and reset lines as well.
//You MUST ALSO CONNECT SDA & SCL with i2c Mode! (Nano pins A4/A5) -Josh
#define PN532_IRQ (2)
#define PN532_RESET (3)
//fastLED definitions
#define LED_PIN 7
#define COLOR_ORDER GRB // interesting...
#define CHIPSET WS2812
#define NUM_LEDS 40
#define BASE_LED 8 // the first LEDs on the bottom to be used
#define BRIGHTNESS 50 // up to 255
#define FRAMES_PER_SECOND 60
//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
//LIBRARIES
//PN532
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_PN532.h>
// use this line for a breakout or shield with an I2C connection:
Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET); //
//fastLED
#include <FastLED.h> //See fastLED example file fire2012 for original code comments and explanation
CRGB leds[NUM_LEDS];
//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
//Global Variables
//Game settings
long roundLength = 5000; //in milliseconds
byte numOfRounds = 4;
long rndExpireTime = 30000; // when set by pendingPlayer(), sets the millis time that ends the round
byte numOfPlayers = 2;
//Rfid info
byte uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned Uid from Library
byte uidLength; // Length of the Uid (4 or 7 ints depending on ISO14443A card type)
byte playerColors [11][3] = {{0, 0, 0}, {255, 0, 0}, {0, 0, 255}}; //player x RGB/HSV value
byte playerIDs [11][4]; // first dimension (11) is the number of possible players; 2nd is for the 4 blocks of RFID #
// note that for a 10 player game, I've reserved 11 spaces; this is because int playerTurn
//points to the player number in the array so instead of [0][], player one's uid is at playerIDs [1]
byte p1ID[] = {60, 166, 231, 11}; //red tag I think
byte p2ID[] = {76, 132, 231, 11}; // hard coded for now
bool success = 0;
//Misc bg processes etc.
byte currentRound = 1;
bool gameOver = 0;
bool gameIsLive = 0;
int playerScores[11]; // playerScores[0] = coop group score; playerScores[1]=p1 score; can make this multi-dimensional for roundscores
//round victor calculated by comparing p
byte playerTurn = 1;
int tagDebounce = 200; //used as milliseconds between tagReads before it's recognized
unsigned long lastTagTime = 0;
byte timerPos = 0;
byte hsTimerLum = 0; // 40 or whatever. an independent array on which to do math for the timer
byte pNumJustTagged;
long currentMillis;
//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
//SETUP
//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
void setup(void) {
Serial.begin(115200);
//For PN532
nfc.begin();
nfc.setPassiveActivationRetries(2); //keeps code from searching for card indefinitely
uint32_t versiondata = nfc.getFirmwareVersion();
if (! versiondata) {
Serial.print("Didn't find PN53x board");
while (1); // halt
}
// Got ok data, print it out!
Serial.print("Found chip PN5"); Serial.println((versiondata >> 24) & 0xFF, HEX); Serial.print("Firmware ver. "); Serial.print((versiondata >> 16) & 0xFF, DEC); Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC);
nfc.SAMConfig();
Serial.println("Waiting for an ISO14443A Card ...");
//End PN532 setup code: see pn532 example sketch included with library
//fastLED
FastLED.addLeds<CHIPSET, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
FastLED.setBrightness( BRIGHTNESS );
//My Code
assignPlayer(1, p1ID); //make sure to adjust the TotalPlayers variable
assignPlayer(2, p2ID);
//startAnimation();
}//end setup
//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
// Loop
//▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
void loop() {
delay(1000);
//clear tag variables
memset(uid, 0, sizeof(uid)); // clears uid[]
success = 0;
pNumJustTagged = 0; //This variable holds the player number that just tagged the reader; only calculated once/loop and cleared at the begnning
//processes
currentMillis = millis();
getUid(); // triggers success = 1, populates uid
//Tag events
if (success && currentMillis - lastTagTime > tagDebounce) { //what player # just tagged?
pNumJustTagged = whoTagged();
lastTagTime = currentMillis;
}
printInfo();
//waiting for player to begin
if (!gameIsLive && !gameOver) { //if it's not live or over, it must be waiting for the first player
if (currentRound <= numOfRounds) {
//Serial.println("currentRound <= numOfRounds");
//don't need to check the timer
waitingPlayer(playerTurn);
waitingPlayerLed(); //this works but for some reason makes p1 score 255 after first round
} else {
gameOver = 1;
}
}
// LIVE gameplay
if (gameIsLive) {
timerCheck();
if (playerTurn == pNumJustTagged) {
addPlayerPoint(playerTurn);
//addPointAnimate();
}
//showPlayerScores();
//CountDownLed();
}
if (gameOver) {
//victor animation
//LCD scores
}
// LED display to reflect playerTurn, time left, & all player scores
//HS stands for High Score Game
FastLED.show(); // display this frame
FastLED.delay(1000 / FRAMES_PER_SECOND);
//Serial.println("//end main loop");
} //end main loop