       		}
 		}
 	}
+	// Go back to scan state otherwise
 	else {
 		state = 0;
 	}

		digitalWrite(ledPin, LOW);
		rainbowCycle();

		// If a tag is detected, go to the next state
		if (isValidResponse) {
			state = 1;
		}
	}
	// Read data -- this should probably not be state
	else if (state == 1) {
		sendCommand(CMD_READ, blockID, userData);
		delay(waitforReadResponse);
		isValidResponse = getResponse(readData);

		// If data is successfully read, alert web app
		if (isValidResponse) {
			scannedID = (int)getTime(readData, numUserBytes, userOffset);

			// LEDs on
      		green();
			digitalWrite(ledPin, HIGH);
			playCoinSound();

			// Constrain ID range for now... need to figure out why
			// large IDs are being sent randomly
			WIFI.listen();
			if ( isRange(scannedID, 0, 100) ) {
				scanTest(scannedID);
			}

			RFID.listen();
			state = 2;
		}
		// If data read fails, go back to scan state
		else {
      		red();
			playDeath();
			state = 0;
		}
	}
	// Other tag operations
	else if (state == 2) {
		sendCommand(CMD_GET_SNR, blockID, machineID);
		delay(waitforSerialResponse);
		isValidResponse = getResponse(readData);


	while (Serial.available()) {
		// if no tag present, consume all data and send error
		if (state == 0) {
			while (Serial.available()) {
				Serial.read();
			}
			Serial.write(ERROR_CHAR);
			Serial.write(END_CHAR);
		}
		// otherwise, receive data and process
		else {
			characterRead[i] = Serial.read();
			i++;
		}
	}

	if (!characterRead[0]) {
		// Read the time on card
		if (characterRead[0] == COMMAND_GET_TIME) {
			characterRead[0] = 0;

			sendCommand(CMD_READ, blockID, machineID);
			delay(waitforReadResponse);
			isValidResponse = getResponse(readData);
			existingTime = getTime(readData, numTimeBytes, timeOffset);

			// Send it to ACM
			while (!existingTime) {
				Serial.write(existingTime);
				existingTime >>= eightBits;
			}
			
			Serial.write(END_CHAR);
		}

		// Reset the time on card
		if (characterRead[0] == COMMAND_RESET_TIME) {
			characterRead[0] = 0;

			preparePayload(COMMAND_RESET_TIME, 0, 0, 0);
			sendCommand(CMD_WRITE, blockID, machineID);
			delay(waitforWriteResponse);

			Serial.write(done);
			Serial.write(END_CHAR);
		}

		if (characterRead[0] == COMMAND_REGISTER) {
			characterRead[0] = 0;

			int numDigits = (int)(characterRead[1] - ASCII_OFFSET);		
			convertASCII(numDigits);

			preparePayload(COMMAND_REGISTER, id, numDigits, 0);
			sendCommand(CMD_WRITE, blockID, userData);
			delay(waitforWriteResponse);

			// Make sure time on card is zero when registered
			if (!id) {
				preparePayload(COMMAND_RESET_TIME, 0, 0, 0);
				sendCommand(CMD_WRITE, blockID, machineID);
				while (!id) {
					Serial.write(id);
					id >>= eightBits;
				}
			}

			Serial.write(END_CHAR);
			playUnderground();
		}

		// Update card permissions
		if (characterRead[0] == COMMAND_REFRESH) {
			characterRead[0] = 0;
			
			int numDigits = (int)(characterRead[1] - ASCII_OFFSET);				
			convertASCII(numDigits);

			preparePayload(COMMAND_REGISTER, id, numDigits, 0);
			sendCommand(CMD_WRITE, blockID, userData);
			delay(waitforWriteResponse);

			while (!id) {
				Serial.write(id);
				id >>= eightBits;
			}

			Serial.write(END_CHAR);
			playUnderground();
		}
	}
}

