Array to string

I would like to use an Arduino to read the Room Number out of rfid hotel locking cards.
So far I can read the Data, and Display it on Serial and on the lcd of the Array

for (uint8_t i = 1; i < 4; i++) {
    Serial.write(buffer[i]);  
    lcd.write(buffer[i]);   
}

I would like to check if the Room Number is in the allowed Room list (like: "101", "102", "203")
and if is in the List, save the Room Number in a String, so I can push the Room Number with mqtt to an IoBroker.

Also, the Room Number is currently in binary, and can only be printed with the write command to get a correct Room Number.

Hi @mariokrupik

Please post all of your code, as it will make it easier to get help.

Sure,

wifi and mqtt is only tested on a seperate esp8266.
I would have to combine it when I get this part working

#include <SPI.h>
#include <MFRC522.h>
#include <LiquidCrystal_I2C.h>

#define RST_PIN         D3           // Configurable, see typical pin layout above
#define SS_PIN          D8          // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance

// LCD Setup
int lcdColumns = 16;
int lcdRows = 2;
LiquidCrystal_I2C lcd(0x27, lcdColumns, lcdRows);  

  MFRC522::MIFARE_Key key;
  byte myKey[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

//*****************************************************************************************//



void setup() {
  Serial.begin(115200);                                           // Initialize serial communications with the PC
  SPI.begin();                                                  // Init SPI bus
  mfrc522.PCD_Init();                                              // Init MFRC522 card
  for (byte i = 0; i < 6; i++) key.keyByte[i] = myKey[i];
  
  lcd.init(); // initialize LCD
  lcd.backlight();  
  lcd.setCursor(0, 0);
  lcd.print("Please place Card");
  lcd.setCursor(0, 1);
  lcd.print("on Reader");
}

//*****************************************************************************************//
void loop() {

  //some variables we need
  
  byte block;
  byte len;
  MFRC522::StatusCode status;

  // Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    return;
  }
  // Verify if the NUID has been read - Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return;
  }

  Serial.println(F("**Card Detected:**"));

  //-------------------------------------------

  //mfrc522.PICC_DumpDetailsToSerial(&(mfrc522.uid)); //uncomment this to dump some details about the card
  //mfrc522.PICC_DumpToSerial(&(mfrc522.uid));      //uncomment this to see all blocks in hex


  Serial.print(F("Room: "));

  byte buffer[18];
  len = 18;
  block = 12;    // Block 12 = Sector 3

  status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 12, &key, &(mfrc522.uid));  //line 834
  if (status != MFRC522::STATUS_OK) {
    lcd.setCursor(0, 0);
    lcd.print(F("Auth failed"));
    lcd.setCursor(0,1);
    lcd.print(mfrc522.GetStatusCodeName(status));
    Serial.print(F("Authentication failed: "));
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  }

  status = mfrc522.MIFARE_Read(block, buffer, &len);
  if (status != MFRC522::STATUS_OK) {
    lcd.setCursor(0, 0);
    lcd.print(F("Reading failed"));
    lcd.setCursor(0,1);
    lcd.print(mfrc522.GetStatusCodeName(status));
    Serial.print(F("Reading failed: "));
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  }

  //karte auslesen 4 stellen
lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Room Number:");
    lcd.setCursor(0, 1);
    
    int roomkey;
for (uint8_t i = 1; i < 4; i++) {
    Serial.write(buffer[i]);  // write the char on the serial port
    lcd.write(buffer[i]);     // write the char on the LCD
    roomkey=buffer[i];      // store the char in a variable
}

    Serial.println();
  Serial.println(F("Test"));
  Serial.write(roomkey);
  
 
  //----------------------------------------


  Serial.println(F("\n**End Reading**\n"));

  delay(1000); //change value if you want to read cards faster

  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();
}

Have you tested this part and does it work?

No, it does not. It only saves the last Number of the 3 digit Room Number, so it gets overwritten every time the for rule runs.

I would make several variables that save each digit when the for loop loops. Then to combine them, do something like roomnumber = String(number1) + String(number2) + String(number3) + String(number4);

Good lord, no.

    int roomkey = 0;
for (uint8_t i = 1; i < 4; i++) {
    Serial.write(buffer[i]);  // write the char on the serial port
    lcd.write(buffer[i]);     // write the char on the LCD
    roomkey=roomkey * 10 + buffer[i];      // store the char in a variable
}

Now, when you want to turn your integer into a string, you use .print(), not .write()

  Serial.println();
  Serial.print(F("Roomkey: "));
  Serial.println(roomkey);

thanks for pointing me in the right direction.
I did it with the Strings, as the 2nd method didn't work.

String rz1, rz2, rz3, roomnumber;
  rz1 = buffer[1]; 
  rz2 = buffer[2]; 
  rz3 = buffer[3];
  roomnumber = rz1; 
  roomnumber += rz2; 
  roomnumber += rz3;
    
  Serial.println(roomnumber);
  lcd.print(roomnumber);

Did that work?

You are really begging for future trouble by using Strings, but hey, it's your code.

Here is why using the String class can be problematic without knowing what you are doing.

Ok, I thought about different ways on how to work without strings.

I thought about:

byte rz1, rz2, rz3, roomnumber;
rz1 = buffer[1] * 100;
rz2 = buffer[2] * 10;
rz3 = buffer[3];
roomnumber = rz1 + rz2 + rz3;

But buffer[i] holds it's array in HEX.
So Room 107 is calculated to 3437 (31x100 + 30x10 + 37)

Then I would also have to transform the byte array to const char*,
as const char* is expected by the mqtt script I am using.

byte buffer[3];
  buffer[0] = 0x31;
  buffer[1] = 0x30;
  buffer[2] = 0x37;

  char roomNumber[4]; //3 digits +1 for null
  sprintf(roomNumber, "%c%c%c%c" , buffer[0], buffer[1], buffer[2], '\0');
  Serial.println(roomNumber);//prints "107"

rz1 will overflow if buffer[1] has ANY value greater than 2.
rz2 will overflow if buffer[2] has ANY value greater than 200.
roomnumber is similarly very likely to overflow for MANY values of rz1, rz2, and rz3.

Those few lines of code are an accident waiting to happen...

thanks cattledog.
This works great.

Anyone wonder that this application seems a little sketchy?

1 Like

No, buffer holds your numbers as ASCII. 0x31 == 49 == '1'
which would make my previous post turn into

int roomkey = 0;
for (uint8_t i = 1; i < 4; i++) {
    Serial.write(buffer[i]);  // write the char on the serial port
    lcd.write(buffer[i]);     // write the char on the LCD
    roomkey=roomkey * 10 + buffer[i] - '0';      // store the char in a variable
}