D69 3 Posted August 25, 2013 Share Posted August 25, 2013 Hi all I'm currently working with Eelcor's excellent port of the RC522 Mifare library. All is well on the hardware side and most of the code is functioning fine, there's just one section where I'm trying to use a switch/case based on the results of an array lookup (as for loop). The switch works comparing an integer but the value I want is in a char* array which is the only way I can get the array working with the data I want. The funny thing occurs when I try to get a variable to take on the int value of the array. The number always comes out as a negative but can also change, I think based on the amount of code but I'm not sure. I'm positive I'm just being dense and it's something simple but I've gone over it several times and can't figure it out. Any help appreciated Cheers Dean /* Example file for communicating with the NFRC522. The program prints the card data. Created by Eelco Rouw - Originally adapted by Grant Gibson. */ // Pinout // SDA - 2.2 // SCK - 1.5 // Mosi - 1.7 // Miso - 1.6 // IRQ - NC // GND - GND // RST - 1.3 // VCC - VCC #include <Mfrc522.h> // the sensor communicates using SPI, so include the library: #include <SPI.h> int chipSelectPin = 10; int NRSTDP = 5; int ledpin1 = 13; int ledpin2 = 12; int ledpin3 = 11; int cardint = 5; Mfrc522 Mfrc522(chipSelectPin,NRSTDP); unsigned char serNum[5]; int secLevel; String secLevel2; unsigned char sectorKey[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; unsigned char readData[16]; void setup() { Serial.begin(9600); // RFID reader SOUT pin connected to Serial RX pin at 2400bps // Start the SPI library: SPI.begin(); // Initialize the Card Reader digitalWrite(chipSelectPin, LOW); pinMode(RED_LED, OUTPUT); pinMode(ledpin1, OUTPUT); pinMode(ledpin2, OUTPUT); pinMode(ledpin3, OUTPUT); digitalWrite(ledpin1, LOW); digitalWrite(ledpin2, LOW); digitalWrite(ledpin3, LOW); Mfrc522.Init(); } void loop() { unsigned char i,tmp; unsigned char status; unsigned char str[MAX_LEN]; unsigned char RC_size; unsigned char blockAddr; String mycardno; char* myarray[3][5]={ //Array of tags and related names, tag numbers copied from serial console after 1st run {"205928944228","1251291514471","7748944415","157172894468","611918944247"}, {"Dad","Mum","Baby","Dog","Cat"}, {"5","4","3","2","1"} }; status = Mfrc522.Request(PICC_REQIDL, str); if (status == MI_OK) { Serial.println("Card detected"); Serial.print(str[0],BIN); Serial.print(" , "); Serial.print(str[1],BIN); Serial.println(" "); } status = Mfrc522.Anticoll(str); memcpy(serNum, str, 5); if (status == MI_OK) { Serial.println("The card's number is : "); Serial.print(serNum[0], DEC); Serial.print(" , "); Serial.print(serNum[1], DEC); Serial.print(" , "); Serial.print(serNum[2], DEC); Serial.print(" , "); Serial.print(serNum[3], DEC); Serial.print(" , "); Serial.print(serNum[4], DEC); Serial.println(" "); mycardno = String(serNum[0]) += String(serNum[1]) += String(serNum[2]) += String(serNum[3]) += String(serNum[4]); // Appends the content of the serNum array to give a unique card no Serial.println(mycardno); Mfrc522.SelectTag(serNum); status = Mfrc522.Auth(PICC_AUTHENT1A,1,sectorKey,serNum); if (status == MI_OK) { Serial.println("Authenticated...\r\n"); } else { Serial.println("Error authenticating...\r\n"); } status = Mfrc522.ReadBlock(1, readData); if (status == MI_OK) { for(i=0; i<16; i++) { Serial.write(readData[i]); delay(10); } } else { Serial.println("Error reading."); } int i; for(i = 0; i < 5; i = i + 1) { if (mycardno == myarray[0][i]) { Serial.print("Hello "); Serial.println(myarray[1][i]); // Should Print out name matching tag secLevel = int(myarray[2][i]); // Tried setting this to the int of the unsigned char secLevel2 = String(myarray[2][i]); // Setting the string version, works better Serial.print("Security level: "); Serial.println(myarray[2][i]); // Returns correctly Serial.println(secLevel); // Returns random number based on current amount of code Serial.println(secLevel2); // Returns correctly } /*else { Serial.println("Bugger Off"); }*/ } { switch (secLevel) { case -9844: digitalWrite(ledpin1, HIGH); digitalWrite(ledpin2, LOW); digitalWrite(ledpin3, LOW); break; case -9842: digitalWrite(ledpin1, LOW); digitalWrite(ledpin2, HIGH); digitalWrite(ledpin3, LOW); break; case -9840: digitalWrite(ledpin1, LOW); digitalWrite(ledpin2, LOW); digitalWrite(ledpin3, HIGH); break; case -9838: digitalWrite(ledpin1, HIGH); digitalWrite(ledpin2, LOW); digitalWrite(ledpin3, HIGH); break; case -9836: digitalWrite(ledpin1, HIGH); digitalWrite(ledpin2, HIGH); digitalWrite(ledpin3, LOW); break; } } delay(1000); Mfrc522.Init(); } //Serial.println(" "); Mfrc522.Halt(); } Quote Link to post Share on other sites
chicken 630 Posted August 25, 2013 Share Posted August 25, 2013 Do you try to get the integer values of these strings? "5","4","3","2","1" If so, the function you're looking for is atoi (ascii to integer). secLevel = atoi(myArray[2]); However, as long as we're talking about a single digit, you can also use secLevel = myarray[2][i][0] Note that [0] accesses the first character of the string stored at [2]. Subtract 0x30 (or '0') if you want to have an integer from 0-9, but the switch statement can handle character too ('0' is a character, "0" is a string). D69 and energia 2 Quote Link to post Share on other sites
D69 3 Posted August 25, 2013 Author Share Posted August 25, 2013 Atoi worked a treat, thanks ever so much for the reply Quote Link to post Share on other sites
grahamf72 169 Posted August 25, 2013 Share Posted August 25, 2013 Your problem arises because my array[2] is the pointer to the string, not the string itself. Consequently your code seclevel=myarray[2] assigns the pointer value to sec level, not the data. That's why you get a seemingly random value depending on code size. myarray[2][0] will return the first char of the string pointed to by my array[2]. You could also dereference the pointer by using *(myarray[2]). energia 1 Quote Link to post Share on other sites
D69 3 Posted August 26, 2013 Author Share Posted August 26, 2013 Your problem arises because my array[2] is the pointer to the string, not the string itself. Consequently your code seclevel=myarray[2] assigns the pointer value to sec level, not the data. That's why you get a seemingly random value depending on code size. myarray[2][0] will return the first char of the string pointed to by my array[2]. You could also dereference the pointer by using *(myarray[2]). Hi Graham Is that because I used char*? I'm not sure why the array would only work as char*, maybe because of the mixed type of values? Quote Link to post Share on other sites
grahamf72 169 Posted August 26, 2013 Share Posted August 26, 2013 @@D69 - the problem you were encountering is fundamental to the way C handles arrays and strings. Firstly, as I'm sure you're aware a string is merely a null-terminated array of characters. So the string "abc" is represented in memory as a group of characters, 'a', 'b', 'c' and '\0'. When you declare your array your array as char * myArray[3][5], you are creating an array of pointers to char arrays, so myArray[2][0] will return the pointer to the string "5", not the actual character 5. To get the character '5' you need to dereference the pointer, ie *(myArray[2][0]). Personally, for ease of readability, rather than a multi-dimensioned array, I'd probably do something along the lines of: typedef struct { char CardNo[13]; //1 larger than the maximum size so as to have room for the \0 char Name[5]; char SecurityLevel; } tSecInfo; tSecInfo myArray[5]={{"205928944228","Dad",5},{"1291251914471","Mum",4}, ... }; ... //then access the various parts with things like... Serial.Println(myArray[i].Name); seclevel=myArray[i].SecurityLevel; etc. energia and D69 2 Quote Link to post Share on other sites
roadrunner84 466 Posted August 27, 2013 Share Posted August 27, 2013 You're using the wrong design of your data type. You don't have an array of arrays of characters; you have an array of structures where each structure contains a serial number, a name and a sequence id (?). Try replacing your data type as needed. Whenever you need to cast (force a type onto another type), you need to consider you're using the wrong design of your data. Usually my answers are more complete, but I'm not capable of that right now. energia and D69 2 Quote Link to post Share on other sites
D69 3 Posted August 29, 2013 Author Share Posted August 29, 2013 Hi Graham After a bit of pondering your code really makes sense, just looking at rewriting mine to incorporate it now, should save a few lines and tidy it all up a bit. I've not used typedef before but it actually seems quite logical, I'm assuming the order of variables declared should match the order they're listed in the array. Thanks very much for the assistance, this forum seems to have one of the best user bases I've seen in a while! energia 1 Quote Link to post Share on other sites
D69 3 Posted August 29, 2013 Author Share Posted August 29, 2013 Hi RoadRunner Your answer is complete enough for me! I figured I'd come across problems trying to fudge an array of strings and chars but I'm not competent enough yet to know what else to do I double-posted for some reason and graham has suggested using another method that should hopefully improve using typedef struct instead. Thanks for the reply, any guidance is always appreciated. Quote Link to post Share on other sites
Promila 0 Posted February 1, 2014 Share Posted February 1, 2014 http://www.aliexpress.com/store/product/Free-shipping-RFID-module-Kits-RC522-RFID-SPI-Write-Read-for-uno-2560/320981_968016332.html Hi ! Please take a look at the above RFID card. I am getting a status of 2 after the Request. I think I am not doing some connection incorrectly. .. I needed to finish this tonight but I am stuck.. I have tried connections based upon the pin connections above but does not seem to be working.. The NSS and the RST pins are the ones I am not sure I am connecting correctly. Thanks !!!!! Quote Link to post Share on other sites
Promila 0 Posted February 1, 2014 Share Posted February 1, 2014 Please ignore my message above. Everything worked for me now and the pin connections too ... Thanks !! Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.