RFID RDM6300. Как преобразовать полученные данные в нормальный идентификатор?

ndp7
ndp7 аватар
Offline
Зарегистрирован: 25.01.2017

Win-cчитыватель читает мой rfid-ключ: 3F 00 A2 D0 C0

А arduino mega adk + RFID RDM6300 возвращают с порта варианты (hex/dec):

 33 30 41 44 43 38 3

2   51 70 48 48 65 50 68 48 67 48 56 68   3

33 46 30 30 41 32 44 30 43 30 38 44

 

 

Как из этого получить нормальный идетификатор 3F 00 A2 D0 C0?

 

 

ndp7
ndp7 аватар
Offline
Зарегистрирован: 25.01.2017

2 в начале, 3 в конце - так порт шлёт, спецификация такая. Исключать надо

ndp7
ndp7 аватар
Offline
Зарегистрирован: 25.01.2017

Как переводить?) 3F как получить от туда?)
Не справлюсь никак, пол дня уже))

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

Гдето у меня валялся такой - надопопробовать накодить чегонить.

Поидее все просто вначале числовую строку надо преобразовать в символьную, а потом символьную в число(в 5 байт).

ndp7
ndp7 аватар
Offline
Зарегистрирован: 25.01.2017

На моих данных приведите пример пожалуйста, что во что и как преобразовывать :)

ndp7
ndp7 аватар
Offline
Зарегистрирован: 25.01.2017

Тут дело не в устройстве, оно данные шлёт. Вопрос в том, как их преобразовать в нужный вид

ndp7
ndp7 аватар
Offline
Зарегистрирован: 25.01.2017

33 = 3
46 = F
И т.д. по таблице ASCII.

СПАСИБО! ТЕПЕРЬ ПОНЯЛ!

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

Использую Mega2560 и дисплей 2004 i2c

#include <Wire.h>
#include <LiquidCrystal.h>

char buf[13];
byte code[6];
byte code_ok[6] = {0x3e,0,0x15,0x25,0x35,0x45};
int l;

LiquidCrystal lcd(0x27);

void setup(){
  lcd.begin(20, 4);
  lcd.begin(20, 4);
  lcd.backlight();
  Serial1.begin(9600);
}

void loop(){
  if (Serial1.available()){
    char c = Serial1.read();
    if(c == 0x02){l=0;lcd.clear();}else
    if(c==0x03){
      lcd.setCursor(0, 0);
      lcd.println(buf);
      for(uint8_t i=0;i<6;i++){
        char bt[3]= {buf[i*2],buf[i*2+1],0};
        code[i] = strtol(bt,NULL,16);
      }
      if(memcmp(code,code_ok,6) == 0){
        delay(300);
        lcd.setCursor(0, 1);
        lcd.println("OK!");
      }
      l=0;
    }else if(l<12){
        buf[l] = c;
        l++;
    }
  }
}

 

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

Здравствуйте.

У меня вопрос следующий, на всех моих картах имеется серия и номер, которые напечатаны на самой карте, к примеру

131, 52273

А я при считывании получаю

25553484856516767514948663
 
Как мне связать это значение с кодом на карте?
(в базе хранятся именно 131,52273 в таком формате)
#include <SoftwareSerial.h>
SoftwareSerial RFIDSerial(2,3);
String input,temp;






void setup() {
   Serial.begin(19200);
  RFIDSerial.begin(9600);
}

void loop() {

  
if (RFIDSerial.available()>0) {
  input = RFIDSerial.read();
  temp+=input;
    if (temp.length()==26) {
      Serial.println(temp);
     
      temp="";
      input="";
    }
  }
}

 

 

b707
Offline
Зарегистрирован: 26.05.2017

sharik_28.05 пишет:

А я при считывании получаю

25553484856516767514948663

неправильно читаете.

Вы считываете коды символов, пришедших с RFID, потом превращаете коды в их строковое представление и записываете в строку. Так у вас получается полная ерунда - во-первых строка очень далека от реального кода, считанного с карты. а во вторых то. что длина этой строки 26 символов - никак не связано с тем, что на карте 26-символьный код...

1. Записывайте считанные значения не в String, а символьный массив.

2. Чтобы считать с карты 26-символьный код-  нужно выполнить read() 26 раз.

sharik_28.05
Offline
Зарегистрирован: 05.02.2020
#include <SoftwareSerial.h>
SoftwareSerial SoftSerial(2, 3);
unsigned char buffer[64];
int count=0;



void setup(){
SoftSerial.begin(9600);
Serial.begin(9600);
}



void loop(){



if (SoftSerial.available()){//Если в RDM6300 есть данные - переписываем из в массив
while(SoftSerial.available()){//Чтение данных из RDM6300
buffer[count++]=SoftSerial.read();//Запись данных в переменную массива
if(count == 64)break; }//Если считали первые 64 бита - обрываем чтение
Serial.write(buffer,count);//Если данных больше нет - записываем значение в порт
count = 0;//Обнуление переменной массива
Serial.println();}}//Перевод строки перед записью нового значения
void clearBufferArray(){//Подпрограмма очистки буфера


  
for (int i=0; i<count;i++){
buffer[i]=NULL;}
}//Обнуление ячейки массива

Получаю

75
00
83
CC
31
0B
 
sharik_28.05
Offline
Зарегистрирован: 05.02.2020

Перед 75 и после 0B тоже есть символы (отображаются квадратиком)

b707
Offline
Зарегистрирован: 26.05.2017

вместо строчки 23. которая печатает лабуду, напишите вывод массива buffer на печать поэлементно в HEX виде

 

 

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

Так?

#include <SoftwareSerial.h>
SoftwareSerial SoftSerial(2, 3);
char buffer[64];
int count=0;



void setup(){
  SoftSerial.begin(9600);
  Serial.begin(9600);
}


void loop(){
  if (SoftSerial.available()){
    delay(50);
    while(SoftSerial.available()){
      buffer[count++]=SoftSerial.read();
      if(count == 64)break; 
    }

   for (int i=0; i <= count; i++){
         char a=buffer[i];
      Serial.print(a, HEX);
   }
     count = 0;
      Serial.println();
  }
}//loop

  Получаю 237353030383343433331304230
 
b707
Offline
Зарегистрирован: 26.05.2017

Строка 16 лишняя. Пробелы вставьте между соседними значениями.

 

sharik_28.05
Offline
Зарегистрирован: 05.02.2020
#include <SoftwareSerial.h>
SoftwareSerial SoftSerial(2, 3);
char buffer[64];
int count=0;



void setup(){
  SoftSerial.begin(9600);
  Serial.begin(9600);
}


void loop(){
  if (SoftSerial.available()){
    delay(10);
    while(SoftSerial.available()){
      buffer[count++]=SoftSerial.read();
      if(count == 64)break; 
    }

   for (int i=0; i <= count; i++){
         char a=buffer[i];
      Serial.print(a, HEX);
      Serial.print(" ");
   }
     count = 0;
      Serial.println();
  }
}//loop

Получаю 

2 37 35 30 30 38 33 43 43 33 31 30 42 3 0 
 
Если паузу  убираю
2 0 
37 35 30 0 
30 38 33 43 43 33 0 
31 30 42 3 43 
2 30 
37 35 30 3 
30 38 33 43 43 33 31 0 
30 42 3 43 
 

 

b707
Offline
Зарегистрирован: 26.05.2017

sharik_28.05 пишет:

Получаю 

2 37 35 30 30 38 33 43 43 33 31 30 42 3 0

если паузу оставить - с одной карты идет всегда одна и та же строчка?

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

Да

2 37 35 30 30 38 33 43 43 33 31 30 42 3 0 
2 37 35 30 30 38 33 43 43 33 31 30 42 3 0 
2 37 35 30 30 38 33 43 43 33 31 30 42 3 0 
 
b707
Offline
Зарегистрирован: 26.05.2017

sharik_28.05 пишет:

Да

2 37 35 30 30 38 33 43 43 33 31 30 42 3 0 
2 37 35 30 30 38 33 43 43 33 31 30 42 3 0 
2 37 35 30 30 38 33 43 43 33 31 30 42 3 0 
 

А вот такой надписи на карте нет?

75 00 83 СС 31 0B

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

Нету, изначально проверил эту надпись через конвертер

В программе, при добавлении новых пропусков, ввожу 131, 52273

Считыватель карту сверяет с этим значением.

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

Стоп, прикладываю другой пропуск, получаю это же значение.

b707
Offline
Зарегистрирован: 26.05.2017

sharik_28.05 пишет:

Стоп, прикладываю другой пропуск, получаю это же значение.

может оно никак не связано с этими цифрами?

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

По моему первому скетчу

25553484856516767514948663 это 131, 52273
25553484856516766666956513 это 131, 52158
 
b707
Offline
Зарегистрирован: 26.05.2017

sharik_28.05 пишет:

По моему первому скетчу

25553484856516767514948663 это 131, 52273
25553484856516766666956513 это 131, 52158
 

я уже писал, что в вашем первом скетче слишком много ошибок.

а если эти же пропуска считать новым кодом?

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

b707 пишет:

sharik_28.05 пишет:

Стоп, прикладываю другой пропуск, получаю это же значение.

может оно никак не связано с этими цифрами?

Да, 100%, в программе ввожу серию и номер, и всё ок

b707
Offline
Зарегистрирован: 26.05.2017

sharik_28.05 пишет:

Да, 100%, в программе ввожу серию и номер, и всё ок

в какой программе то7

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

Последним кодом получаю 

2 37 35 30 30 38 33 43 43 33 31 30 42 3 0 
это 131, 52273
 
2 37 35 30 30 38 33 43 42 42 45 38 33 3 0 
это 131, 52158
 
Прошу прощения, невнимательно посмотрел на цифры.
 
Программа перко

 

b707
Offline
Зарегистрирован: 26.05.2017

sharik_28.05 пишет:

Да

2 37 35 30 30 38 33 43 43 33 31 30 42 3 0 
2 37 35 30 30 38 33 43 43 33 31 30 42 3 0 
2 37 35 30 30 38 33 43 43 33 31 30 42 3 0 
 

те данные, что вы получаете с карты этим кодом - имеют правильный формат. Начало посылка "2", конец "3" - означает что код принят полностью. А между двойкой и тройкой 12 байт - 2 байта версия, 8 байт таг и 2 байта контрольной суммы.

Так что судя по всему, все читается правильно.

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

Мне нужно придти к чему то, либо конвертировать базу, значения серия и номер в формат считывания через RDM6300, либо наоборот.

 

b707
Offline
Зарегистрирован: 26.05.2017

sharik_28.05 пишет:

2 37 35 30 30 38 33 43 43 33 31 30 42 3 0 

это 131, 52273
 
2 37 35 30 30 38 33 43 42 42 45 38 33 3 0 
это 131, 52158

все просто

Для первой карты

2 37 35 30 30 38 33 43 43 33 31 30 42 3 0 = таг 00 83 СС 31

0x0083 = 131
0xCC31 = 52273

это 131, 52273
 
для второй
2 37 35 30 30 38 33 43 42 42 45 38 33 3 0 = таг 00 83 СB BE

0x0083 = 131
0xCBBE = 52158

это 131, 52158
 
sharik_28.05
Offline
Зарегистрирован: 05.02.2020

Как конвертировали?

b707
Offline
Зарегистрирован: 26.05.2017

sharik_28.05 пишет:

Как конвертировали?

так я ж вроде выше все расписал. Строчка

2 37 35 30 30 38 33 43 43 33 31 30 42 3 -  это HEX коды символов таблицы ASCII. Перводим в символы - получаем:

2 7 5 0 0 8 3 С С 3 1 0 B 3

удобнее записать парами, отбросив первую двойку и последнюю тройку:

75 00 83 СС 31 0B

Первые два байта. "75" - версия протокола. Последние два - "0В" - контрольная сумма Между ними - тег карты

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

Спасибо. В итоге всё получилось, но код мне мой не нравится

#include <SoftwareSerial.h>
SoftwareSerial RDM6300(2, 3);
char buffers[30];//Массив 30 байт
int count=0;
char c;


void setup(){
  RDM6300.begin(9600);
  Serial.begin(9600);
}


void loop(){
  
  if (RDM6300.available()){
    delay(10);
    while(RDM6300.available()){
    buffers[count++]=RDM6300.read(); 
      if(count == 30){
        Serial.println("Bufer perepolnen");
        break; 
      }
    }

Serial.print("Schitano: ");Serial.print(count+1);Serial.print(" byte");Serial.println("");
    

 String str = String(buffers);
  str.trim();
  Serial.print("Karta= ");Serial.print(str); Serial.println();
  byte len=str.length();
  byte n=str.lastIndexOf("75");
  String Seriia="0x"+str.substring(n+2,n+6); 
  String Nomer=str.substring(len-7,len-3);

 char *SeriiaDEC = Seriia.c_str();
 char *NomerDEC = Nomer.c_str();

long decimal_ser = strtol(SeriiaDEC, NULL, 16);
long decimal_nom = strtol(NomerDEC, NULL, 16);

Serial.print("Seriia: ");Serial.print(Seriia);Serial.print(" - ");Serial.print(decimal_ser);Serial.println("");
Serial.print("Nomer: ");Serial.print(Nomer);Serial.print(" - "); Serial.print(decimal_nom);Serial.println("");

  count = 0;
  Serial.println();
  }
}//loop

 

b707
Offline
Зарегистрирован: 26.05.2017

sharik_28.05 пишет:

Спасибо. В итоге всё получилось, но код мне мой не нравится

ужас!

Зачем эта возня со String и поиском числа 75 ? А вдруг 75 встретится в самом коде карты - и все, программа встанет?

На самом деле можно написать проще. По спецификации ответ ридера должен начинатся с байта 0x02, длина его 14 байт и заканчиваться он должен байтом 0x03. Вот от этого и надо отталкиваться. При этом для кода "131 52278" первое число лежит в маcсиве buffer по смещению buffer+3 . а второе число - по смещению buffer+7

И не надо искать никакие подстроки, конвертировать buufer в String, а потом обратно в C_str()...

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

del

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

Нулевой байт в буфере равен 0x02 - верно

Последний байт равен 0х03 (у меня он предпоследний, последний равен 0) - верно

 if (buffers[0]==0x02)Serial.println("Nachalo OK");
  if (buffers[count-1]==0x03)Serial.println("Konetc OK");

 

b707 пишет:
первое число лежит в маcсиве buffer по смещению buffer+3 . а второе число - по смещению buffer+7

А вот этот момент не понимаю

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

2 7 5 0 0 8 3 С С 3 1 0 B 3

0 1 2 3 4 5 6 7 8 9 

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

Komandir пишет:

2 7 5 0 0 8 3 С С 3 1 0 B 3

0 1 2 3 4 5 6 7 8 9 

Это я понимаю.

char seriia[4];
seriia[0]=buffers[3];
seriia[1]=buffers[4];
seriia[2]=buffers[5];
seriia[3]=buffers[6];
long decimal_ser = strtol(seriia, NULL, 16);

char seriia верно заполняю? (в цикле будет) или есть иной вариант?

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

В конце считанного массива 2 37 35 30 30 38 33 43 43 33 31 30 42 3 0

находится 0

это конец строки \0?

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

И еще вопрос

#include <SoftwareSerial.h>
SoftwareSerial RDM6300(2, 3);
char buffers[20];
byte count=0;
  char seriia[4];
  char nomer[4];

void setup(){
  RDM6300.begin(9600);
  Serial.begin(9600);
}


void loop(){
  
  if (RDM6300.available()){
    delay(10);
    while(RDM6300.available()){
    buffers[count++]=RDM6300.read(); 
   // if (RDM6300.read()=='0')break;
      if(count == 14)break; 
    }

  //Показать данные в HEX
   for (int i=0; i <= count; i++){
      char a=buffers[i];
      Serial.print(a, HEX);
      Serial.print(" ");
   }
  //Показать данные в HEX

  Serial.print("Schitano: ");Serial.print(count);Serial.print(" byte");Serial.println("");
  
  for (byte i=0; i<=3; i++){
      seriia[i]=buffers[i+3];
    }

    for (byte i=0; i<=3; i++){
      nomer[i]=buffers[i+7];
    }
    
long decimal_ser = strtol(seriia, NULL, 16);
long decimal_nom = strtol(nomer, NULL, 16);

Serial.print("Seriia: ");Serial.print(" - ");Serial.print(decimal_ser);Serial.println("");
Serial.print("Nomer: ");Serial.print(" - ");Serial.print(decimal_nom);Serial.println("");

  count = 0;
  Serial.println();
  }
}//loop

Получаю

2 37 35 30 30 38 33 43 43 33 31 30 42 3 0 Schitano: 14 byte
Seriia:  - 131
Nomer:  - 2147483647
 
Номер выводится неверно, но если убираю цикл в строках 34-36, номер выводится верно.в чём дело?
Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Считано 14 байтов - выводишь 15 ? Вот он и лишний 0 в конце.

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

2 37 35 30 30 38 33 43 43 33 31 30 42 3 0

15 байт, отсчет от 0

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

ИМХО нужен пятый символ в seriia и nomer в виде пробела или нуля (конец строки - не 0x30 !).

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

Спасибо

 

  char seriia[5];
  char nomer[5];
  for (byte i=0; i<=3; i++){
      seriia[i]=buffers[i+3];
      nomer[i]=buffers[i+7];
    }


    
long decimal_ser = strtol(seriia, NULL, 16);
long decimal_nom = strtol(nomer, NULL, 16);

 

sharik_28.05
Offline
Зарегистрирован: 05.02.2020
  if (RDM6300.available()){
    delay(10);
    while(RDM6300.available()){
    buffers[count++]=RDM6300.read(); 
      if(count == 14)break; 
    }

Сейчас у меня выход из цикла после чтения 15 байта. Это верно?

Лучше ловить символ окончания строки, как сделать?

   // if (RDM6300.read()=='\0')break;
Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

char seriia[5];

Это условно верно, если не забывать что можно и отключить начальную очистку переменных !

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

По поводу 14 - 15 не подскажу. Нет такого железа под рукой.

b707
Offline
Зарегистрирован: 26.05.2017

sharik_28.05 пишет:

Сейчас у меня выход из цикла после чтения 15 байта. Это верно?

Лучше ловить символ окончания строки, как сделать?

Лучше ловить символ 0x03 - по стандарту именно он означает окончание ответа от ридера.

Ну и неплохо бы добавить в код проверку контрольной суммы, раз она есть в пакете.

sharik_28.05
Offline
Зарегистрирован: 05.02.2020
#include <SoftwareSerial.h>
SoftwareSerial RDM6300(2, 3);
char buffers[20];
byte count=0;
char seriia[5];
char nomer[5];
char summa[3];


void setup(){
  RDM6300.begin(9600);
  Serial.begin(9600);
}

  
void loop(){
  
  if (RDM6300.available()>0){
    delay(10);
    while(RDM6300.available()){
    buffers[count++]=RDM6300.read(); 
    //  if (RDM6300.read()=='0x03')break;
      if(count == 14)break; 
    }//while

  //Показать данные в HEX
   for (int i=0; i <= count; i++){
      char a=buffers[i];
      Serial.print(a, HEX);
      Serial.print(" ");
   }
  //Показать данные в HEX

  Serial.print("Schitano: ");Serial.print(count+1);Serial.print(" byte");Serial.println("");


  
  for (byte i=0; i<=3; i++){
      seriia[i]=buffers[i+3];
      nomer[i]=buffers[i+7];
    }
    
summa[0]=buffers[11];
summa[1]=buffers[12];

    
long decimal_ser = strtol(seriia, NULL, 16);
long decimal_nom = strtol(nomer, NULL, 16);
long decimal_sum = strtol(summa, NULL, 16);
Serial.print("Seriia: ");Serial.print(" - ");Serial.print(decimal_ser);Serial.println("");
Serial.print("Nomer: ");Serial.print(" - ");Serial.print(decimal_nom);Serial.println("");
Serial.print("Summa: ");Serial.print(" - ");Serial.print(decimal_sum);Serial.println("");
  count = 0;
  Serial.println();
  }
}//loop

Строка 22 работает неправильно. В чем косяк?

С контрольной суммой (crc) разбираюсь.

b707
Offline
Зарегистрирован: 26.05.2017

sharik_28.05 пишет:

Строка 22 работает неправильно. В чем косяк?

уберите кавычки

В одинарных кавычках можно указывать одиночный печатный символ, например 'a' или код символа после слежа. например '\0'. Если же вы пишете 0x03 - то это просто число и никакие кавычки не нужны.

sharik_28.05
Offline
Зарегистрирован: 05.02.2020

  if (RDM6300.read()==0x03)break;

Считывается 8 байт

2 35 30 33 43 31 42 0 Schitano: 8 byte