// The next line makes it play the first track in the list for // a few seconds, then the next, looping at the end. // Comment it out to make track changes RFID-activated. //#define IPOD_TESTING // // iPod Stuff // #include AdvancedRemote advancedRemote; #include #include #include // initialize the library with the numbers of the interface pins LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // // Absolute min and max eeprom addresses. // Actual values are hardware-dependent. // // These values can be changed e.g. to protect // eeprom cells outside this range. // const int EEPROM_MIN_ADDR = 0; const int EEPROM_MAX_ADDR = 3900; //500 for uno etc const int BUFSIZE = 50; char buf[BUFSIZE]; int readlength; //int startpointread = 0; int endpointread = 16; // The index in the current playlist of the currently-playing track. unsigned long currentTrackIndex = 0UL; //static char lastCode[10]; //static char code[10]; int failed; //For KEYPAD DATA ENTRY int debouncetime = 1000; //delay after pressing a key until keypad active again, helps stop double entries of same number int thousands; int hundreds; int tens; int units; int locationinplaylist; int yesno; int setupcontinue; int currenteepromlocation; int nexteepromlocation; int erasecontinue; int startpointread; int bufferlength; // For RFID reader char val = 0; const uint8_t RFID_ENABLE_PIN = 2; //const unsigned long RFID_DELAY_BETWEEN_READS_MS = 10000UL; //10 sec const unsigned long RFID_DELAY_BETWEEN_READS_MS = 10000UL; //10 sec const int HEADER_BYTE = 10; const int STOP_BYTE = 13; const size_t TAG_LENGTH = 10; const int REQUIRED_CONSECUTIVE_MATCHES = 3; int bytesread; static char lastCode[11]; static char code[11]; static char previousCode[TAG_LENGTH + 1]; // end of RFID stuff //Keypad stuff const byte ROWS = 4; // Four rows const byte COLS = 3; // Three columns // Define the Keymap char keys[ROWS][COLS] = { {'1','2','3'}, {'4','5','6'}, {'7','8','9'}, {'*','0','#'} }; // Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins. byte rowPins[ROWS] = { 41, 43, 45, 47 }; // Connect keypad COL0, COL1 and COL2 to these Arduino pins. byte colPins[COLS] = { 49, 51, 53 }; // Create the Keypad Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); #define ledpin 13 //end of keypad stuff // True once the playlist has been selected and switched to // at startup. Before this point changing tracks won't // actually play them. bool jumpedToPlaylist = false; // True if polling (which makes the iPod send back elapsed time // and track change information) has been enabled. bool pollingEnabled = false; // Enable polling, unless it's already been enabled. void enablePolling() { if (pollingEnabled) { // nothing to do } else { pollingEnabled = true; Serial.println("Turning on polling"); advancedRemote.setPollingMode(AdvancedRemote::POLLING_START); } } //XXXXXXXXXXXXXXXXXXXXXXX ENTER TRACK LOCATION STUFF XXXXXXXXXXXXXXXXXXXXXX void entertracklocation() { delay(50); Serial.println("Enter number of track in the iPod playlist that you want to pair with this RFID card, i.e. 75 = 0075"); delay(50); //Serial1.print(12, BYTE); //clears screen // XXXXXXXXXXXXXXXX Clears Screen XXXXXXXXXXXXXXXXXXXXXXX lcd.setCursor(0, 0); lcd.print(" "); //overflows from line 0 to line 2 lcd.setCursor(0, 1); lcd.print(" "); //overflows from line 1 to line 3 // XXXXXXXXXXXXXXXXX End of clears screen XXXXXXXXXXXXXXXXX //clear() //clears screen and puts to top left corner //lcdSerial.print(13, BYTE); //newline delay(50); lcd.setCursor(0, 0); lcd.print("Enter track number "); lcd.setCursor(0, 1); //line 2 lcd.print("in iPod playlist to"); delay(50); lcd.setCursor(0, 2); //line 3 lcd.print("PAIR with this card"); lcd.setCursor(0, 3); //line 4 lcd.print("e.g. 75=0075 "); /* Serial1.print(13, BYTE); //newline delay(50); Serial1.print("in playlist to"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("PAIR with RFID"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("i.e. 75=0075 "); */ delay(50); //lcd.setCursor(15, 3); //column 15 line 4 char key = keypad.getKey(); do{ //do nothing till you receive input key = keypad.getKey(); } while (key == '\0'); thousands = (key);//for some reason 0 comes out as 48 so we subtract 48! thousands = thousands - 48; Serial.println(thousands); lcd.print(thousands);//print what is pressed on key delay(debouncetime); do{ //do nothing till you receive input key = keypad.getKey(); } while (key == '\0'); hundreds = (key);//for some reason 0 comes out as 48 so we subtract 48! hundreds = hundreds - 48; Serial.println(hundreds); lcd.print(hundreds);//print what is pressed on key delay(debouncetime); do{ //do nothing till you receive input key = keypad.getKey(); } while (key == '\0'); tens = (key);//for some reason 0 comes out as 48 so we subtract 48! tens = tens - 48; Serial.println(tens); lcd.print(tens);//print what is pressed on key delay(debouncetime); do{ //do nothing till you receive input key = keypad.getKey(); } while (key == '\0'); units = (key);//again 0 comes out as 48 for some reason so we subtract 48 units = units - 48; Serial.println(units); lcd.print(units);//print what is pressed on key delay(debouncetime); locationinplaylist = (int) (thousands*1000) + (hundreds*100) + (tens*10) + units; //delay(50); //Serial1.print(4, BYTE); //puts off flashing cursor //noCursor() //puts off cursor } // end of enter track location //XXXXXXXXXXXXXXXXXXXXXXXXXX END OF ENTER TRACK LOCATION STUFF XXXXXXXXXXXXXX //XXXXXXXXXXXXXXXXXXXXXX PLAYBACK STUFF XXXXXXXXXXXXXXXXXXXXXXXXXXXXX // Disable polling, unless it's already been disabled. void disablePolling() { if (pollingEnabled) { pollingEnabled = false; Serial.println("Turning off polling"); advancedRemote.setPollingMode(AdvancedRemote::POLLING_STOP); } else { // nothing to do } } // Begin the process of requesting information for // the specified track. // First, we'll ask for the title. // When we get that back we'll ask for the artist. // Lastly, when we get back the artist we'll ask // for the album. void getTrackInfo(unsigned long trackIndex) { // start by getting the title advancedRemote.getTitle(currentTrackIndex); // wait for title handler to get called. // From there we'll ask for the artist, etc. } // This function will be called back by AdvancedRemote when it // gets a response from the iPad to a command that we issue. void feedbackHandler(AdvancedRemote::Feedback feedback, byte cmd) { if (feedback != AdvancedRemote::FEEDBACK_SUCCESS) { Serial.println("Last command failed: feedback wasn't SUCCESS"); return; } switch (cmd) { case AdvancedRemote::CMD_SWITCH_TO_ITEM: Serial.println("Switched to an item."); // Presume we're getting this from a switch-to-playlist // request, so now start it playing. advancedRemote.executeSwitch(0xFFFFFFFF); break; case AdvancedRemote::CMD_SWITCH_TO_MAIN_LIBRARY_PLAYLIST: // as above, but for the the "main" library playlist. Serial.println("Switched to main library playlist."); // now start it playing advancedRemote.executeSwitch(0xFFFFFFFF); break; case AdvancedRemote::CMD_EXECUTE_SWITCH: Serial.println("Execute switched."); // jumping will work now jumpedToPlaylist = true; break; case AdvancedRemote::CMD_JUMP_TO_SONG_IN_CURRENT_PLAYLIST: Serial.println("Jumped to a song"); if (pollingEnabled) { // polling will get the track info for us. } else { // we'd better ask for the track info getTrackInfo(currentTrackIndex); // turn on polling; it will get the elapsed time // and track info for subsequent tracks. enablePolling(); } break; case AdvancedRemote::CMD_PLAYBACK_CONTROL: // play/pause etc Serial.println("playback control complete"); break; case AdvancedRemote::CMD_POLLING_MODE: Serial.println("polling mode change complete"); // from experimentation it starts playing automatically break; default: Serial.print("got feedback we didn't expect: 0x"); Serial.println(cmd, HEX); break; } } // Called when the iPod returns the name of a track to us. void titleHandler(const char *name) { Serial.print("Title: "); Serial.println(name); // XXXXXXXXXXXXXXXX Clears Screen XXXXXXXXXXXXXXXXXXXXXXX lcd.setCursor(0, 0); lcd.print(" "); //overflows from line 0 to line 2 lcd.setCursor(0, 1); lcd.print(" "); //overflows from line 1 to line 3 // XXXXXXXXXXXXXXXXX End of clears screen XXXXXXXXXXXXXXXXX //clear() //clears screen and puts to top left corner //lcdSerial.print(13, BYTE); //newline //delay(50); lcd.setCursor(0, 0); lcd.print("Track: "); lcd.setCursor(0, 1); //line 2 lcd.print(name); // Serial1.print("Track: "); // Serial1.print(name); advancedRemote.getArtist(currentTrackIndex); // wait for artist handler to get called } // Called when the iPod returns the name of an artist to us. void artistHandler(const char *name) { Serial.print("Artist: "); Serial.println(name); //Serial1.print('\r', BYTE); //Serial1.print("Artist: "); //Serial1.println(name); /* // XXXXXXXXXXXXXXXX Clears Screen XXXXXXXXXXXXXXXXXXXXXXX lcd.setCursor(0, 0); lcd.print(" "); //overflows from line 0 to line 2 lcd.setCursor(0, 1); lcd.print(" "); //overflows from line 1 to line 3 // XXXXXXXXXXXXXXXXX End of clears screen XXXXXXXXXXXXXXXXX */ //clear() //clears screen and puts to top left corner //lcdSerial.print(13, BYTE); //newline //delay(50); lcd.setCursor(0, 2); //line 3 lcd.print("Artist: "); lcd.setCursor(0, 3); //line 4 lcd.print(name); advancedRemote.getAlbum(currentTrackIndex); // wait for album handler to get called } // Called when the iPod returns the name of an album to us. void albumHandler(const char *name) { Serial.print("Album: "); Serial.println(name); } // Helper function to convert elapsed time in milliseconds // to "1m 2s" format. void printTime(const unsigned long ms) { const unsigned long totalSecs = ms / 1000; const unsigned int mins = totalSecs / 60; const unsigned int partialSecs = totalSecs % 60; Serial.print(mins, DEC); Serial.print("m "); Serial.print(partialSecs, DEC); Serial.println("s"); } // Called when the iPod returns elapsed-time information to us, // which should be every 500ms, or when a track ends and the // next begins. void pollingHandler(AdvancedRemote::PollingCommand command, unsigned long playlistPositionOrElapsedTimeMs) { Serial.print("Poll: "); switch (command) { case AdvancedRemote::POLLING_TRACK_CHANGE: Serial.print("track change to: "); Serial.println(playlistPositionOrElapsedTimeMs, DEC); // we just naturally went to the next track, // so update the song we're at and get its details currentTrackIndex = playlistPositionOrElapsedTimeMs; getTrackInfo(currentTrackIndex); break; case AdvancedRemote::POLLING_ELAPSED_TIME: Serial.print("elapsed time: "); printTime(playlistPositionOrElapsedTimeMs); break; default: Serial.print("unknown: "); Serial.println(playlistPositionOrElapsedTimeMs, DEC); break; } } //XXXXXXXXXXXXXXXXXXXXXXX END OF PLAYBACK STUFF XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX //XXXXXXXXXXXXXXXXXXXXXXXXX eeprom section XXXXXXXXXXXXXXXXXXXXXXXXX // Initialize eeprom memory with // the specified byte. // Default value is 0xFF. // void eeprom_erase_all(byte b = 0xFF) { int i; for (i = EEPROM_MIN_ADDR; i <= EEPROM_MAX_ADDR; i++) { EEPROM.write(i, b); } } // A pair of functions to show how long it takes to work with eeprom. // int start_time; int stop_time; void start_timing() { start_time = millis(); } void print_elapsed() { stop_time = millis(); Serial.print("Time elapsed (ms): "); Serial.println(stop_time - start_time); } // // Dump eeprom memory contents over serial port in tabular form. // Each printed row shows the value of bytesPerRow bytes // (by default 16). // void eeprom_serial_dump_table(int bytesPerRow = 16) { // address counter int i; // row bytes counter int j; // byte read from eeprom byte b; // temporary buffer for sprintf char buf[10]; // initialize row counter j = 0; // go from first to last eeprom address for (i = EEPROM_MIN_ADDR; i <= EEPROM_MAX_ADDR; i++) { // if this is the first byte of the row, // start row by printing the byte address if (j == 0) { sprintf(buf, "%03X: ", i); Serial.print(buf); } // read current byte from eeprom b = EEPROM.read(i); // write byte in hex form sprintf(buf, "%02X ", b); // increment row counter j++; // if this is the last byte of the row, // reset row counter and use println() // to start a new line if (j == bytesPerRow) { j = 0; Serial.println(buf); } // else just print the hex value with print() else { Serial.print(buf); } } } // This function is used by the other, higher-level functions // to prevent bugs and runtime errors due to invalid addresses. // boolean eeprom_is_addr_ok(int addr) { return ((addr >= EEPROM_MIN_ADDR) && (addr <= EEPROM_MAX_ADDR)); } boolean eeprom_read_string(int addr, char* buffer, int bufSize) { // byte read from eeprom Serial.print("addr: '"); Serial.println(addr); byte ch; // number of bytes read so far int bytesRead; // check start address if (!eeprom_is_addr_ok(addr)) { return false; } // how can we store bytes in an empty buffer ? if (bufSize == 0) { return false; } // is there is room for the string terminator only, // no reason to go further if (bufSize == 1) { buffer[0] = 0; return true; } // initialize byte counter bytesRead = 0; // read next byte from eeprom ch = EEPROM.read(addr + bytesRead); // store it into the user buffer buffer[bytesRead] = ch; // increment byte counter bytesRead++; // stop conditions: // - the character just read is the string terminator one (0x00) // - we have filled the user buffer // - we have reached the last eeprom address while ( (ch != 0x00) && (bytesRead < (readlength + 1)) && ((addr + bytesRead) <= EEPROM_MAX_ADDR) ) { // if no stop condition is met, read the next byte from eeprom ch = EEPROM.read(addr + bytesRead); // store it into the user buffer buffer[bytesRead] = ch; // increment byte counter bytesRead++; } // make sure the user buffer has a string terminator // (0x00) as its last byte if ((ch != 0x00) && (bytesRead >= 1)) { buffer[bytesRead - 1] = 0; } return true; } // Writes a sequence of bytes to eeprom starting at the specified address. // Returns true if the whole array is successfully written. // Returns false if the start or end addresses aren't between // the minimum and maximum allowed values. // When returning false, nothing gets written to eeprom. // boolean eeprom_write_bytes(int startAddr, const byte* array, int numBytes) { // counter int i; // both first byte and last byte addresses must fall within // the allowed range if (!eeprom_is_addr_ok(startAddr) || !eeprom_is_addr_ok(startAddr + numBytes)) { return false; } for (i = 0; i < numBytes; i++) { EEPROM.write(startAddr + i, array[i]); } return true; } // Writes a string starting at the specified address. // Returns true if the whole string is successfully written. // Returns false if the address of one or more bytes // fall outside the allowed range. // If false is returned, nothing gets written to the eeprom. // eeprom_write_string(currenteepromlocation, stringOne boolean eeprom_write_string(int addr, const char* string) { // actual number of bytes to be written int numBytes; // we'll need to write the string contents // plus the string terminator byte (0x00) numBytes = strlen(string) + 1; return eeprom_write_bytes(addr, (const byte*)string, numBytes); } //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX end of eeprom section XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX RFID XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // RFID Stuff // /* const uint8_t RFID_ENABLE_PIN = 2; const unsigned long RFID_DELAY_BETWEEN_READS_MS = 10000UL; //10 sec const int HEADER_BYTE = 10; const int STOP_BYTE = 13; const size_t TAG_LENGTH = 10; const int REQUIRED_CONSECUTIVE_MATCHES = 3; */ /* struct Track { const char *code; // The RFID tag's code for this track const char *title1; // Title 1 message to display for this track const char *title2; // Title 2 message to display for this track long index; // index of this track }; */ /* // The Arduino auto-format likes the extra lines in this track list (sigh) Track tracks[] = { { "0100F24EC7", "ACE OF BASE SINGLES", "OF THE 90's", 2 }, //1 { "0100F348EE", "FLOOR 3 FILLERS", "CLUB CLASSICS", 18 }, //2 { "0100F35884", "100 HITS", "DANCE CD4", 37 }, //3 { "0100F342E7", "ABBA GOLD", "Tonia's fave!", 57 }, //4 { "0100F22805", "IBIZA 2000-2010", "JUDGE JULES CD1", 76 }, //5 { "0100F250EC", "FLOOR FILLERS", "ANTHEMS FLOOR 1", 91 }, //6 { "0100F360BA", "AHORA 08 CD2", "", 113 }, //7 { "0100F360A7", "AHORA 08 CD3", "", 133 }, //8 { "0100F26306", "100 HITS DANCE", "ANTHEMS FLOOR CD5", 153 }, //9 { "0100F3608D", "100 HITS DISCO", "CD1", 173 }, //10 { "0100E0852E", "CHRISTMAS HITS", "CD1", 192 }, //11 { "0100D54746", "100 HITS DANCE", "CD3", 211 }, //12 { "0100D542FB", "NOW 76", "CD1", 231 }, //13 { "0100D543D8", "NOW 47", "CD2", 254 }, //14 { "0100F280BB", "100 HITS DANCE", "CD1", 276 }, //15 { "0100F0C004", "NOW 76", "CD2", 296 }, //16 { "0100F0AE8B", "FLOORFILLERS", "CD3", 319 }, //17 { "0100F0C0EB", "FLOORFILLERS", "CD2", 338 }, //18 { "0100F28882", "STREET DANCE", "2010 CD2", 356 }, //19 { "0100F26792", "STREET DANCE", "2010 CD1", 376 }, //20 { "0100F27ED0", "MONSTER FLOOR", "FILLERS CD2", 396 }, //21 { "27009CA0B7", "SATURDAY NIGHT", "FEVER", 420 }, //22 { "23006F814F", "100% IBIZA", "ANTHEMS ", 432 }, //23 { "2200536662", "BIGGEST 80's HITS", "EVER CD1", 452 }, //24 { "250060C215", "BIGGEST 80's HITS", "EVER CD2", 472 }, //25 { "0100F3412B", "SUNNY'S SUMMER", "PARTY", 492 }, //26 { "0100F29545", "CLUBBERS GUIDE", "2008 CD3", 508 }, //27 { "0100F27FB1", "MUSIC TO WATCH", "GIRLS BY", 526 }, //28 { "0100F353C3", "NOW THAT'S WHAT I", "CALL MUSIC 77", 545 } //29 // Put as many in here as you like, // Note that the last entry shouldn't have a comma after it. }; */ //const size_t NUM_TRACKS = sizeof(tracks) / sizeof(tracks[0]); //const size_t NUM_TRACKS = 29; //needs to self update during learning mode void rfidActivate() { Serial.println("Activating RFID"); digitalWrite(RFID_ENABLE_PIN, HIGH); //high to activate the ID12 delay(100); } void rfidDeactivate() { Serial.println("Deactivating RFID"); digitalWrite(RFID_ENABLE_PIN, LOW); //low to deactivate the ID12 delay(100); } int rfidReadByte() { Serial.println("rfidReadByte"); // wait for a byte to become available while (Serial2.available() == 0) { // Delay a little bit just so we don't sit and spin. delay(100); } // now return the first available byte, // since we know from the avoid that at least one is // now waiting for us return Serial2.read(); } void rfidReadHeader() { Serial.println("Waiting for header"); while (rfidReadByte() != HEADER_BYTE) { // rfidReadByte does all the waiting // for us, so we can just go round again } Serial.println("Header found"); } // buffer must be at least TAG_LENGTH+1 bytes long bool rfidReadTagOnce(char *buffer) { Serial.println("bool rfidReadTagOnce char*buffer"); rfidReadHeader(); int bytesRead = 0; for (; bytesRead < TAG_LENGTH; bytesRead++) { buffer[bytesRead] = rfidReadByte(); if ((buffer[bytesRead] == HEADER_BYTE) || (buffer[bytesRead] == STOP_BYTE)) { Serial.println("Giving up on read due to HEADER/STOP byte."); break; } } // null-terminate the string buffer[bytesRead] = '\0'; // we'll get here either with a <10 length // string in buffer or a 10-length // string. bufferlength = strlen(buffer); Serial.print("bufferlength="); Serial.println(bufferlength); return strlen(buffer) == TAG_LENGTH; } bool rfidReadTag(char *buffer) { Serial.println("bool rfidReadTagCharBuffer"); char compareBuffer[TAG_LENGTH+1]; compareBuffer[0] = '\0'; if (!rfidReadTagOnce(buffer)) { // failed on first attempt, so give up return false; } // remember the tag we just read strcpy(compareBuffer, buffer); // start loop at 1 since we've read once above for (int i = 1; i < REQUIRED_CONSECUTIVE_MATCHES; i++) { Serial.print("ReadingRFID attempt "); Serial.println(i); if (rfidReadTagOnce(buffer) && (strcmp(compareBuffer, buffer) == 0)) { // read a tag and it matches, so go around again Serial.print("match"); } else { // failed to read or it didn't match; // either way we give up return false; Serial.println("didn't match"); } } // yay, we read the same code REQUIRED_CONSECUTIVE_MATCHES // times in a row Serial.println("Success - reached required number of tag matches in series"); return true; } void jumpToSongAtTrackIndex(unsigned long index) { Serial.print("Jumping to track at index (Dec) "); Serial.println(index, DEC); Serial.print("Jumping to track at index (Hex)"); Serial.println(index, HEX); advancedRemote.jumpToSongInCurrentPlaylist(index); } //XXXXXXXXXXXXXXXXXXXXXXXXXXXX our key code for changing tracks by reading from EEPROM XXXXXXXXXXXXXXXXX void switchToTrackForCode(const char *code) { Serial.print("Looking for track with code "); Serial.println(code); failed = 0; startpointread = 0; endpointread = 16; Serial.println("Reading 10 char strings from eeprom and comparing them..."); int i; for (i = 0; i < 29; i++) { readlength = 10; // we just want the RFID 10 char strings from EEPROM to compare them //eeprom_read_string(startpointread, buf, BUFSIZE); eeprom_read_string(startpointread, buf, BUFSIZE); Serial.print("10 character string from EEPROM to see if it matches the new RFID: "); Serial.println(buf); //buf is //compare the string; buf (from eeprom) with our latest RFID read; code if (strcmp(buf, code) == 0) { //i.e. if buf (from eeprom) and code (from RFID) are the same /* delay(50); Serial1.print(12, BYTE); delay(50); Serial1.print("Changing track, new"); delay(50); Serial1.print('\r', BYTE); delay(50); Serial1.print("RFID detected"); */ // XXXXXXXXXXXXXXXX Clears Screen XXXXXXXXXXXXXXXXXXXXXXX lcd.setCursor(0, 0); lcd.print(" "); //overflows from line 0 to line 2 lcd.setCursor(0, 1); lcd.print(" "); //overflows from line 1 to line 3 // XXXXXXXXXXXXXXXXX End of clears screen XXXXXXXXXXXXXXXXX //clear() //clears screen and puts to top left corner //lcdSerial.print(13, BYTE); //newline //delay(50); lcd.setCursor(0, 0); lcd.print("Changing track as"); lcd.setCursor(0, 1); //line 2 lcd.print("new card detected."); Serial.print("Changing track as match found in EEPROM for latest RFID code"); Serial.print("code = "); Serial.println(code); Serial.print("buf = "); Serial.println(buf); // now we need to retrieve the number of the track we are on from the eeprom readlength = 5; // this time we just want the RFID 5 char strings from EEPROM to compare them startpointread = startpointread + 10; // we only want the last 5 chars this time so start 10 spaces further along the eeprom CARE! messing with startpoint in an increment that is not 16 //eeprom_read_string(startpointread, buf, BUFSIZE); eeprom_read_string(startpointread, buf, BUFSIZE); Serial.println("Trying to read the index from the EEPROM"); Serial.print("buf = "); Serial.println(buf); //currentTrackIndex = tracks[i].index; //currentTrackIndex = atoi(buf); //converts 4 character string to an integer currentTrackIndex = (unsigned long) atoi(buf) -1; //converts 4 character string to an integer. Force it to be an unsigned long as that is format that currentTrackIndex has to be in if (currentTrackIndex < 0){ currentTrackIndex = 0;} Serial.print("Current track index after atoi attempt = "); Serial.println(currentTrackIndex, DEC); jumpToSongAtTrackIndex(currentTrackIndex); return; } //end of if // we havent found a match so we now jump along the EEPROM another 15 spaces and check for a match again startpointread = startpointread + 16; endpointread = endpointread + 16; Serial.println("No match, moving along eeprom another 16 spaces to try again"); } //end of for loop /* for (size_t i = 0; i < NUM_TRACKS; ++i) { if (strcmp(tracks[i].code, code) == 0) { Serial1.print(12, BYTE); Serial1.print("Playing........."); Serial1.print('\r', BYTE); Serial1.print(tracks[i].title1); delay(100); Serial1.print('\r', BYTE); Serial1.print(tracks[i].title2); delay(100); Serial1.print('\r', BYTE); currentTrackIndex = tracks[i].index; jumpToSongAtTrackIndex(currentTrackIndex); return; } } */ Serial.print("Failed to find any track matching codes."); failed == 1; //failed to find a track // XXXXXXXXXXXXXXXX Clears Screen XXXXXXXXXXXXXXXXXXXXXXX lcd.setCursor(0, 0); lcd.print(" "); //overflows from line 0 to line 2 lcd.setCursor(0, 1); lcd.print(" "); //overflows from line 1 to line 3 // XXXXXXXXXXXXXXXXX End of clears screen XXXXXXXXXXXXXXXXX lcd.setCursor(0, 0); lcd.print("Failed to find song"); lcd.setCursor(0, 1); //line 2 lcd.print("? unpaired card"); } //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX end of key bit of code XXXXXXXXXXXXXXXXXXXXXXXXXXXXX //XXXXXXXXXXXXXXXXXXXXXXX RFID CHECK DOES IT ALL NOW FOR THE ID12 READER XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX void rfidCheck() //simply decides if we need to change track (but not to which track yet) { //static char lastCode[10]; //char code[TAG_LENGTH + 1]; Serial.println("rfidcheck subroutine"); rfidActivate(); delay(200); Serial.println("rfidactivate subroutine"); //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Read the tag XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX //char code[10]; int i; int waitforread = 0; int waitforstartoftext = 0; //digitalWrite(RFID_ENABLE_PIN, HIGH); //pull up reset line while (waitforread == 0){ if (Serial2.available() > 0 ) { Serial.println("Serial2 i.e. RFID is available"); while(waitforstartoftext == 0){ if ( (val = Serial2.read()) == 02 ) { // look for Start Of Text marker Serial.println("Start of text marker has been found"); Serial.print("[SOT] "); // reda until you get End Of Text for ( i = 0; (val = Serial2.read()) != 03 ; i++) { Serial.print(val, HEX); Serial.print(" "); code[i] = val; } Serial.println("[EOT]"); Serial.println(); Serial.print("new just read code: "); code[10] = 0x00; // tie off code string at the CR-LF Serial.print(code); Serial.println(); //resetID12(); // reset after a valid read not used as we turn rfid reader off lower down below this //rfidDeactivate(); delay(200); waitforstartoftext = 1; }//end if if val = serial2 read etc Serial.println(val, DEC); } // end of if waitforstartoftext == 0 } // end of if serial2 available waitforread = 1; } // end of while waitfor read = 0 //XXXXXXXXXXXXXXXXXXXXXXXXXXX End of read the tag XXXXXXXXXXXXXXXXXXXXXXXXXX Serial.print("Lastcode: "); Serial.println(lastCode); if (strcmp(code, lastCode) != 0) { if (failed == 1){ // if no matching track was found so we need to stay with one we are on, i.e. make the code the same as the previous successfully working one: strcpy(code, lastCode); // make the current code the same as the previous (OK) one since no matches were found } switchToTrackForCode(code); // i.e. change tracks go to this routine which needs to be changed to EEPROM read // remember this code for next time strcpy(lastCode, code); } rfidDeactivate(); delay(2000); } void rfidsetupCheck() //simply decides if we need to change track (but not to which track yet) { //static char lastCode[10]; //char code[TAG_LENGTH + 1]; Serial.println("rfidsetupcheck subroutine"); rfidActivate(); delay(200); Serial.println("rfidactivate subroutine"); //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Read the tag XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX //char code[10]; int i; int waitforread = 0; int waitforstartoftext = 0; //digitalWrite(RFID_ENABLE_PIN, HIGH); //pull up reset line while (waitforread == 0){ if (Serial2.available() > 0 ) { Serial.println("Serial2 i.e. RFID is available"); while(waitforstartoftext == 0){ if ( (val = Serial2.read()) == 02 ) { // look for Start Of Text marker Serial.println("Start of text marker has been found"); Serial.print("[SOT] "); // reda until you get End Of Text for ( i = 0; (val = Serial2.read()) != 03 ; i++) { Serial.print(val, HEX); Serial.print(" "); code[i] = val; } Serial.println("[EOT]"); Serial.println(); Serial.print("new just read code: "); code[10] = 0x00; // tie off code string at the CR-LF Serial.print(code); Serial.println(); //resetID12(); // reset after a valid read not used as we turn rfid reader off lower down below this //rfidDeactivate(); delay(200); waitforstartoftext = 1; }//end if if val = serial2 read etc Serial.println(val, DEC); } // end of if waitforstartoftext == 0 } // end of if serial2 available waitforread = 1; } // end of while waitfor read = 0 //XXXXXXXXXXXXXXXXXXXXXXXXXXX End of read the tag XXXXXXXXXXXXXXXXXXXXXXXXXX Serial.print("Lastcode: "); Serial.println(lastCode); /* if (strcmp(code, lastCode) != 0) { if (failed == 1){ // if no matching track was found so we need to stay with one we are on, i.e. make the code the same as the previous successfully working one: strcpy(code, lastCode); // make the current code the same as the previous (OK) one since no matches were found } switchToTrackForCode(code); // i.e. change tracks go to this routine which needs to be changed to EEPROM read // remember this code for next time strcpy(lastCode, code); } */ rfidDeactivate(); delay(2000); } /* void rfidCheck() //simply decides if we need to change track (but not to which track yet) { static char lastCode[TAG_LENGTH + 1]; char code[TAG_LENGTH + 1]; rfidActivate(); if (rfidReadTag(code) && (strcmp(code, lastCode) != 0)) { switchToTrackForCode(code); // i.e. change tracks go to this routine which needs to be changed to EEPROM read // remember this code for next time strcpy(lastCode, code); } rfidDeactivate(); } */ //end of old rfidCheck // // Standard sketch stuff // void setup() { // Debug Serial.begin(115200); // Display lcd.begin(16, 4); /* Serial1.begin(9600); //NOTE: THIS WORKS A LOT BETTER THAN 9600 WITH MY PARTICULAR SERIAL-LCD DISPLAY delay(50); Serial1.print(19, BYTE); //backlight on delay(100); Serial1.print(12, BYTE); //clears screen delay(100); Serial1.print(4, BYTE); //puts off flashing cursor delay(100); */ // RFID Serial2.begin(9600); // RFID reader SOUT is 9600 for the ID12 RFID reader pinMode(RFID_ENABLE_PIN, OUTPUT); // Set digital pin 2 as OUTPUT to connect it to the RFID /ENABLE pin rfidDeactivate(); /* Serial1.print("READY........"); Serial1.print('\r', BYTE); Serial1.print("Place card in tray"); delay(100); Serial1.print('\r', BYTE); Serial1.print("and press button."); delay (2000); */ delay(2000); // iPod advancedRemote.setSerial(Serial3); // Register callback functions for the things we're going to get callbacks for advancedRemote.setFeedbackHandler(feedbackHandler); advancedRemote.setPollingHandler(pollingHandler); advancedRemote.setTitleHandler(titleHandler); advancedRemote.setArtistHandler(artistHandler); advancedRemote.setAlbumHandler(albumHandler); // Let the library set itself up, now we've done our configuration of it advancedRemote.setup(); // Start in advanced remote mode advancedRemote.enable(); // Switch to the playlist we wan't to use. // For now we rely on that being the first user-specified playlist, // playlist number 1. (0 is always the main library playlist.) //advancedRemote.switchToMainLibraryPlaylist(); advancedRemote.switchToItem(AdvancedRemote::ITEM_PLAYLIST, 1); } // Used to remember we when last asked the RFID reader // to look for a tag. unsigned long timeOfLastRead = 0UL; void loop() { delay(1000); nexteepromlocation = EEPROM.read(3700); Serial.print("nexteepromlocation ="); Serial.print(nexteepromlocation); Serial.println("Welcome, Press Key 5 to add new card or any other key for play"); /* delay(50); Serial1.print(12, BYTE); //clears screen delay(50); Serial1.print(" WELCOME"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("Press Key 5 to"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("ADD NEW CARD or any"); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("other key for PLAY"); delay(1000); */ // XXXXXXXXXXXXXXXX Clears Screen XXXXXXXXXXXXXXXXXXXXXXX lcd.setCursor(0, 0); lcd.print(" "); //overflows from line 0 to line 2 lcd.setCursor(0, 1); lcd.print(" "); //overflows from line 1 to line 3 // XXXXXXXXXXXXXXXXX End of clears screen XXXXXXXXXXXXXXXXX //clear() //clears screen and puts to top left corner //lcdSerial.print(13, BYTE); //newline //delay(50); lcd.setCursor(0, 0); lcd.print("Welcome"); lcd.setCursor(0, 1); //line 2 lcd.print("Press Key 5 to"); lcd.setCursor(0, 2); lcd.print("ADD NEW CARD or any"); lcd.setCursor(0, 3); //line 2 lcd.print("other key for PLAY"); char key = keypad.getKey(); for (int j = 0; j < 30000; j++) { key = keypad.getKey(); if (key != '\0'){ j = 30000; //do nothing till you receive input then if a key is pressed break out of j loop } } // end of for int j loop otherwise it times out and goes into play mode /* //countdown display for (int j = 0; j < 10; j++) { Serial1.print(12, BYTE); //clears screen delay(50); key = keypad.getKey(); Serial1.print("Countdown to PLAY: "); Serial1.print(10-j); Serial.println(10-j); delay(950); } */ int playorsetup; playorsetup = (key);//again 0 comes out as 48 for some reason so we subtract 48 playorsetup = playorsetup - 48; if (playorsetup == 5){ //i.e. we have chosen "setup RFIDs" Serial.println("New Cards Setup, Are you sure? AnyKey = continue RESET=Start again"); delay(50); /* Serial1.print(12, BYTE); //clears screen delay(50); Serial1.print("NEW CARDS SETUP"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("Are you sure?"); delay(3000); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("AnyKey = Continue"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("RESET = Start Again"); */ // XXXXXXXXXXXXXXXX Clears Screen XXXXXXXXXXXXXXXXXXXXXXX lcd.setCursor(0, 0); lcd.print(" "); //overflows from line 0 to line 2 lcd.setCursor(0, 1); lcd.print(" "); //overflows from line 1 to line 3 // XXXXXXXXXXXXXXXXX End of clears screen XXXXXXXXXXXXXXXXX //clear() //clears screen and puts to top left corner //lcdSerial.print(13, BYTE); //newline //delay(50); lcd.setCursor(0, 0); lcd.print("NEW CARDS SETUP"); lcd.setCursor(0, 1); //line 2 lcd.print("ARE YOU SURE?"); lcd.setCursor(0, 2); lcd.print("# Key = Continue"); lcd.setCursor(0, 3); //line 2 lcd.print("RESET = Start Again"); do{ //do nothing till you receive input key = keypad.getKey(); } while (key == '\0'); Serial.println("Key 1 = Start from scratch.....be careful OtherKey = Add to existing list"); /* delay(50); Serial1.print(12, BYTE); //clears screen delay(50); Serial1.print("Key 1 = START FROM"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("SCRATCH..be careful"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("Other Key = ADD TO"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("EXISTING LIST"); delay(3000); */ // XXXXXXXXXXXXXXXX Clears Screen XXXXXXXXXXXXXXXXXXXXXXX lcd.setCursor(0, 0); lcd.print(" "); //overflows from line 0 to line 2 lcd.setCursor(0, 1); lcd.print(" "); //overflows from line 1 to line 3 // XXXXXXXXXXXXXXXXX End of clears screen XXXXXXXXXXXXXXXXX //clear() //clears screen and puts to top left corner //lcdSerial.print(13, BYTE); //newline //delay(50); lcd.setCursor(0, 0); lcd.print("Key 1 = START FROM"); lcd.setCursor(0, 1); //line 2 lcd.print("SCRATCH..be careful"); lcd.setCursor(0, 2); lcd.print("Key # = ADD TO"); lcd.setCursor(0, 3); //line 2 lcd.print("EXISTING LIST"); delay(3000); do{ //do nothing till you receive input key = keypad.getKey(); } while (key == '\0'); erasecontinue = (key);//again 0 comes out as 48 for some reason so we subtract 48 erasecontinue = erasecontinue - 48; Serial.print("erasecontinue ="); Serial.println(erasecontinue); setuproutine(); //go into setup routine while(1);{ delay(5000); //stalls after up to 200 RFIDs have been entered } } //XXXXXXXXXXXXXXXXXXXX MAIN PLAYBACK ROUTINE XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX if(playorsetup != 5){ Serial.println("Playback mode selected"); /* Serial1.print(12, BYTE); //clears screen delay(50); Serial1.print("PLAYBACK MODE"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("SELECTED"); */ // XXXXXXXXXXXXXXXX Clears Screen XXXXXXXXXXXXXXXXXXXXXXX lcd.setCursor(0, 0); lcd.print(" "); //overflows from line 0 to line 2 lcd.setCursor(0, 1); lcd.print(" "); //overflows from line 1 to line 3 // XXXXXXXXXXXXXXXXX End of clears screen XXXXXXXXXXXXXXXXX //clear() //clears screen and puts to top left corner //lcdSerial.print(13, BYTE); //newline //delay(50); lcd.setCursor(0, 0); lcd.print("PLAYBACK MODE"); lcd.setCursor(0, 1); //line 2 lcd.print("SELECTED"); delay(2000); while(1){ //i.e. if you have NOT chosen setup, you have chosen PLAYBACK // Let the AdvancedRemote do its thing. // (basically, respond to data coming back from the iPod) advancedRemote.loop(); //Serial.println("Advanced remote on"); // See if it's time to try a read. unsigned long now = millis(); if (jumpedToPlaylist && ((timeOfLastRead == 0) || ((now - timeOfLastRead) >= RFID_DELAY_BETWEEN_READS_MS))) { #if defined(IPOD_TESTING) // just pick a fake track index static size_t i = 0UL; i = ++i % NUM_TRACKS; //currentTrackIndex = tracks[i].index; currentTrackIndex = 2; //just for testing purposes jumpToSongAtTrackIndex(currentTrackIndex); #else // see if RFID tag wants us to change tracks Serial.println("About to do an RFIDcheck"); rfidCheck(); #endif // Remember the end of this read for delaying of the next one timeOfLastRead = millis(); } } //end of while(1) } //end of if(playorsetup != 5) } // end of main void loop // XXXXXXXXXXXXXXXXXXX ENF OF MAIN PLAYBACK ROUTINE XXXXXXXXXXXXXXXXXXX //XXXXXXXXXXXXXXXXXXXXXXXX MAIN SETUP ROUTINE XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX void setuproutine() { char key = keypad.getKey(); //get nexteepromlocation from location 3700 and multiply it by 16 and define it as the currenteepromlocation // read current byte from eeprom currenteepromlocation = (EEPROM.read(3700) * 16); Serial.print("reconstituted currenteepromlocation ="); Serial.print(currenteepromlocation); if (erasecontinue == 1){ //we selected to start from scratch i.e. eeprom location 0 // XXXXXXXXXXXXXXXX Clears Screen XXXXXXXXXXXXXXXXXXXXXXX lcd.setCursor(0, 0); lcd.print(" "); //overflows from line 0 to line 2 lcd.setCursor(0, 1); lcd.print(" "); //overflows from line 1 to line 3 // XXXXXXXXXXXXXXXXX End of clears screen XXXXXXXXXXXXXXXXX //clear() //clears screen and puts to top left corner //lcdSerial.print(13, BYTE); //newline //delay(50); lcd.setCursor(0, 0); lcd.print("ERASING all paired"); lcd.setCursor(0, 1); //line 2 lcd.print("cards. ARE YOU SURE?"); lcd.setCursor(0, 2); lcd.print("# key = CONTINUE"); lcd.setCursor(0, 3); //line 2 lcd.print("RESET = Start again"); delay(2000); do{ //do nothing till you receive input key = keypad.getKey(); } while (key == '\0'); Serial.println("Erasing memory..."); //EEPROM ERASE delay(100); /* Serial1.print(12, BYTE); //clears screen delay(50); Serial1.print("Erasing memory..."); */ // XXXXXXXXXXXXXXXX Clears Screen XXXXXXXXXXXXXXXXXXXXXXX lcd.setCursor(0, 0); lcd.print(" "); //overflows from line 0 to line 2 lcd.setCursor(0, 1); lcd.print(" "); //overflows from line 1 to line 3 // XXXXXXXXXXXXXXXXX End of clears screen XXXXXXXXXXXXXXXXX //clear() //clears screen and puts to top left corner //lcdSerial.print(13, BYTE); //newline //delay(50); lcd.setCursor(0, 0); lcd.print("ERASING ALL CARDS"); lcd.setCursor(0, 1); //line 2 lcd.print("FROM MEMORY"); lcd.setCursor(0, 2); lcd.print("READY TO START CARD"); lcd.setCursor(0, 3); //line 2 lcd.print("LIBRARY OVER AGAIN"); start_timing(); eeprom_erase_all(); print_elapsed(); currenteepromlocation = 0; } //So, if erasecontinue does not = 1 then we do NOT erase the whole eeprom and we continue adding RFID codes from the current eepromlocation retrieved from location 3700 in eeprom for (int j = 0; j < 200; j++) { //stalls after max of 200 RFIDs have been entered delay(1000); //1) XXXXXXXXXXXXXXXXXXXXXX Read the RFID XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Serial.println("Put fresh card on reader. Press any key when ready"); /* delay(50); Serial1.print(12, BYTE); //clears screen delay(50); Serial1.print("Put fresh"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("card on reader."); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("Press any key"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("When ready"); */ // XXXXXXXXXXXXXXXX Clears Screen XXXXXXXXXXXXXXXXXXXXXXX lcd.setCursor(0, 0); lcd.print(" "); //overflows from line 0 to line 2 lcd.setCursor(0, 1); lcd.print(" "); //overflows from line 1 to line 3 // XXXXXXXXXXXXXXXXX End of clears screen XXXXXXXXXXXXXXXXX //clear() //clears screen and puts to top left corner //lcdSerial.print(13, BYTE); //newline //delay(50); lcd.setCursor(0, 0); lcd.print("Put fresh unpaired"); lcd.setCursor(0, 1); //line 2 lcd.print("card on reader"); lcd.setCursor(0, 2); lcd.print("Press * key"); lcd.setCursor(0, 3); //line 2 lcd.print("when ready."); delay(3000); Serial.print("Currenteepromlocation we are going to write to = "); Serial.println(currenteepromlocation); char key = keypad.getKey(); do{ //do nothing till you receive input key = keypad.getKey(); } while (key == '\0'); // Read the RFID //static char lastCode[TAG_LENGTH + 1]; //char code[TAG_LENGTH + 1]; //char code[10]; //rfidReadTag(code) delay(debouncetime); //rfidActivate(); //new //rfidReadTag(code); rfidsetupCheck(); //new while (strcmp(code, previousCode) == 0){ //while new code is same as previous code wait until user changes the card delay(1000); rfidsetupCheck(); //keep reading RFID until code read is NOT the same as the code of previously used RFID i.e. (previousCode)i.e. we have a good new reading } //rfidDeactivate(); //new Serial.println("Have read good new and different-to-previous-RFID-card-used, RFID code OK - I think"); Serial.print("Code is: "); Serial.println(code); Serial.print("previousCode was: "); Serial.println(previousCode); //XXXXXXXXXXXXXXXXXXXXXXXXXXX end of read the RFID XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX //2) Display RFID value on screen /* delay(50); Serial1.print(12, BYTE); //clears screen delay(50); Serial1.print("Current card ID code"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("is: "); delay(50); Serial1.print(code); delay(50); */ // XXXXXXXXXXXXXXXX Clears Screen XXXXXXXXXXXXXXXXXXXXXXX lcd.setCursor(0, 0); lcd.print(" "); //overflows from line 0 to line 2 lcd.setCursor(0, 1); lcd.print(" "); //overflows from line 1 to line 3 // XXXXXXXXXXXXXXXXX End of clears screen XXXXXXXXXXXXXXXXX //clear() //clears screen and puts to top left corner //lcdSerial.print(13, BYTE); //newline //delay(50); lcd.setCursor(0, 0); lcd.print("Fresh card ID code"); lcd.setCursor(0, 1); //line 2 lcd.print("is: "); lcd.setCursor(0, 2); lcd.print(code); Serial.print("Current RFID code is "); Serial.println(code); delay(2000); //3) Pause, what track do you want to PAIR with this RFID card? (Press # to finish setup) entertracklocation(); //command to get the 4 digit track location from keypad the variable is up to 4 digit and is "locationinplaylist" delay(2000); //4 Is this correct? 4=No 5=Yes /* Serial1.print(12, BYTE); //clears screen delay(50); Serial1.print("Entered PodPlaylist"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("location is: "); delay(50); Serial1.print(locationinplaylist); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("Press 5 to PAIR"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("Other key=try again"); */ // XXXXXXXXXXXXXXXX Clears Screen XXXXXXXXXXXXXXXXXXXXXXX lcd.setCursor(0, 0); lcd.print(" "); //overflows from line 0 to line 2 lcd.setCursor(0, 1); lcd.print(" "); //overflows from line 1 to line 3 // XXXXXXXXXXXXXXXXX End of clears screen XXXXXXXXXXXXXXXXX //clear() //clears screen and puts to top left corner //lcdSerial.print(13, BYTE); //newline //delay(50); lcd.setCursor(0, 0); lcd.print("iPod track number"); lcd.setCursor(0, 1); //line 2 lcd.print("will be:"); lcd.print(locationinplaylist); lcd.setCursor(0, 2); lcd.print("Press 5 key to PAIR"); lcd.setCursor(0, 3); //line 2 lcd.print("OtherKey= try again"); Serial.print("Entered iPod playlist location is: "); Serial.println(locationinplaylist); Serial.println("Press 5 to PAIR, Other key=try again"); do{ //do nothing till you receive input key = keypad.getKey(); } while (key == '\0'); yesno = (key);//again 0 comes out as 48 for some reason so we subtract 48 yesno = yesno - 48; //5) If yes then enter "code" + "locationinplaylist" + "z" into a 16 char string then add it to EEPROM if (yesno == 5){ strcpy(previousCode, code); //make a note of the previous RFID card we used delay(200); Serial.println("Pairing selected"); //XXXXXXXXXXXX attempt to merge the RFID code then location in playlist (always 4 digits) and a z at the end into an array to go to eepromXXXXXXXXXXXXXXXXXXX int arrayforeeprom[20]; //create an array we are going to paste from into the eeprom. arrayforeeprom[0] = code[0]; arrayforeeprom[1] = code[1]; arrayforeeprom[2] = code[2]; arrayforeeprom[3] = code[3]; arrayforeeprom[4] = code[4]; arrayforeeprom[5] = code[5]; arrayforeeprom[6] = code[6]; arrayforeeprom[7] = code[7]; arrayforeeprom[8] = code[8]; arrayforeeprom[9] = code[9]; arrayforeeprom[10] = 48; //null at end before track number arrayforeeprom[11] = thousands + 48; arrayforeeprom[12] = hundreds + 48; arrayforeeprom[13] = tens + 48; arrayforeeprom[14] = units + 48; arrayforeeprom[15] = 122; //asci for z It helps when you dump the ascii table and are looking for dividers Serial.println("Printing arrayforeeprom we are about to put into EEPROM"); for (int i = 0; i < 16; i++) { Serial.println(arrayforeeprom[i]); } //XXXXXXXXXXXXXXXXXXXXXXXXXXX write array to EEPROM XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Serial.println("PAIRING, Writing to the EEPROM"); Serial.print("Current location in eeprom is now: "); Serial.println(currenteepromlocation); /* delay(50); Serial1.print(12, BYTE); //clears screen delay(50); Serial1.print("PAIRING....."); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("Writing to memory"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("Start location in"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("EEPROM: "); delay(50); Serial1.println(currenteepromlocation); */ // XXXXXXXXXXXXXXXX Clears Screen XXXXXXXXXXXXXXXXXXXXXXX lcd.setCursor(0, 0); lcd.print(" "); //overflows from line 0 to line 2 lcd.setCursor(0, 1); lcd.print(" "); //overflows from line 1 to line 3 // XXXXXXXXXXXXXXXXX End of clears screen XXXXXXXXXXXXXXXXX //clear() //clears screen and puts to top left corner //lcdSerial.print(13, BYTE); //newline //delay(50); lcd.setCursor(0, 0); lcd.print("PAIRING....."); delay(1000); lcd.setCursor(0, 1); //line 2 lcd.print("Writing to memory"); lcd.setCursor(0, 2); //lcd.print("Start location in"); //lcd.setCursor(0, 3); //line 2 //lcd.print("EEPROM:"); //lcd.print(currenteepromlocation); delay(2000); for (int i = 0; i < 16; i++) { EEPROM.write(currenteepromlocation + i, arrayforeeprom[i]); } /* // COMMENT THIS SECTION BACK IN IF YOU WANT TO CHECK NEW CARDS ARE GOING INTO EEPROM TABLE OK //XXXXXXXXXXXXXXXXXXXXXX print out what is in eeprom - hopefully something has been added XXXXXXXXXXXX Serial.println("Dumping eeprom contents..."); eeprom_serial_dump_table(); //so you can check where the new 15 char string ended up! //XXXXXXXXXXXXXXXX read back from the EEPROM and see what we get !!! XXXXXXXXXXXXXXXXXXXX */ Serial.print("EEPROM location we have just written to = "); Serial.println(currenteepromlocation); Serial.print("nexteepromlocation this time = "); Serial.println(nexteepromlocation); //range 0 - 200 //need to increase the currenteepromlocation variable by 16. Has to match the Read/Playback code sketch. currenteepromlocation = currenteepromlocation + 16; nexteepromlocation = currenteepromlocation/16; Serial.print("EEPROM location we are writing to next time = "); Serial.println(currenteepromlocation); Serial.print("nexteepromlocation next time = "); Serial.println(nexteepromlocation); //range 0 - 200 Serial.println(" "); //XXXXXXXXXXXXXXXXXXXXXXXXXXX end of stringOne to EEPROM XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX } // end of if yesno = 5 if (yesno != 5){ Serial.println("Try to pair again. Place card in reader Keys: 3=Pair OtherKey = end setup"); /* delay(50); Serial1.print(12, BYTE); //clears screen delay(50); Serial1.print("Try to pair again"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("Place card in reader"); delay(2000); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("Keys: 3=PAIR"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("Other key=End setup"); delay(50); */ // XXXXXXXXXXXXXXXX Clears Screen XXXXXXXXXXXXXXXXXXXXXXX lcd.setCursor(0, 0); lcd.print(" "); //overflows from line 0 to line 2 lcd.setCursor(0, 1); lcd.print(" "); //overflows from line 1 to line 3 // XXXXXXXXXXXXXXXXX End of clears screen XXXXXXXXXXXXXXXXX //clear() //clears screen and puts to top left corner //lcdSerial.print(13, BYTE); //newline //delay(50); lcd.setCursor(0, 0); lcd.print("Try again. Place the"); lcd.setCursor(0, 1); //line 2 lcd.print("new card in reader"); lcd.setCursor(0, 2); lcd.print("Keys: 3 = PAIR"); lcd.setCursor(0, 3); //line 2 lcd.print("Otherkey=EXIT setup"); } //6) Either go round void loop again, or end the setup routine if (yesno == 5){ Serial.println("Paired OK. Keys: 3=Pair another card OtherKey=End Setup"); /* delay(50); Serial1.print(12, BYTE); //clears screen delay(50); Serial1.print("PAIRED OK !"); delay(2000); Serial1.print("Keys:"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("3=PAIR ANOTHER CARD"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("Other key=END SETUP"); delay(50); */ // XXXXXXXXXXXXXXXX Clears Screen XXXXXXXXXXXXXXXXXXXXXXX lcd.setCursor(0, 0); lcd.print(" "); //overflows from line 0 to line 2 lcd.setCursor(0, 1); lcd.print(" "); //overflows from line 1 to line 3 // XXXXXXXXXXXXXXXXX End of clears screen XXXXXXXXXXXXXXXXX //clear() //clears screen and puts to top left corner //lcdSerial.print(13, BYTE); //newline //delay(50); lcd.setCursor(0, 0); lcd.print("Paired OK"); lcd.setCursor(0, 1); //line 2 lcd.print("Keys: "); lcd.setCursor(0, 2); lcd.print("3=PAIR ANOTHER CARD"); lcd.setCursor(0, 3); //line 2 lcd.print("Otherkey=EXIT setup"); } delay(debouncetime); int setupcontinue; do{ //do nothing till you receive input key = keypad.getKey(); } while (key == '\0'); setupcontinue = (key);//again 0 comes out as 48 so we subtract 48 setupcontinue = setupcontinue - 48; if (setupcontinue != 3){ //end setup as we have NOT pressed button 3 Serial.println("Setup finished, press Red reset button to re-start & select playback"); /* Serial1.print(12, BYTE); //clears screen delay(50); Serial1.print("SETUP FINISHED"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("PRESS RED RESET"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("BUTTON TO RE-START"); delay(50); Serial1.print(13, BYTE); //newline delay(50); Serial1.print("& SELECT PLAYBACK"); */ // XXXXXXXXXXXXXXXX Clears Screen XXXXXXXXXXXXXXXXXXXXXXX lcd.setCursor(0, 0); lcd.print(" "); //overflows from line 0 to line 2 lcd.setCursor(0, 1); lcd.print(" "); //overflows from line 1 to line 3 // XXXXXXXXXXXXXXXXX End of clears screen XXXXXXXXXXXXXXXXX //clear() //clears screen and puts to top left corner //lcdSerial.print(13, BYTE); //newline //delay(50); lcd.setCursor(0, 0); lcd.print("SETUP FINISHED"); lcd.setCursor(0, 1); //line 2 lcd.print("PRESS RED RESET"); lcd.setCursor(0, 2); lcd.print("BUTTON TO RE-START"); lcd.setCursor(0, 3); //line 2 lcd.print("& SELECT PLAYBACK"); delay(debouncetime); EEPROM.write(3700, nexteepromlocation); //save the next eeprom location we want to start from next time if we want to update add more RFIDS later to existing EEPROM list //save at eeprom location 3700 while(1){ delay(500); //stalls forever until you press reset button } } //end of if setupcontinue !=3 //we want to carry on with another RFID so go round void loop again } //end of for j = 200 loop } //end of setup routine //XXXXXXXXXXXXXXXXXXXXXXXXX END OF SETUP ROUTINE XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX