RFID WL-134A 十六进制解码 Arduino

问题描述 投票:0回答:1

我有一个连接到 Arduino 模块的动物标签阅读器,并且由于用户 red_car 成功读取了数据,但我遇到了标签 ID 不正确的问题,它似乎通过了校验和并提供了给定标签的正确国家/地区代码。但标签数据解码错误。该系统有一个手册(附照片),它似乎与 red_car 示例中的结构匹配,但标签 ID 始终是错误的。

因此,为了隔离问题,我更改了从手动设置的代码中读取的代码,并输入了手册中的示例。

例子是:

02 31 37 31 41 39 32 35 33 41 33 34 38 33 30 30 31 30 30 30 30 30 30 30 30 30 30 07 f8 03 通过 ASICII 转换时:171A9253A34830010000000000

其中包含: 标签ID:1-10字节(10长) 国家代码字节 11-14(4 个长)

171A9253A3 483 0010000000000

应生成:国家/地区:900 标签:250000023921

byte buffer[30] = {0x02, 0x31, 0x37, 0x31, 0x41, 0x39, 0x32, 0x35, 0x33, 0x41, 0x33, 0x34, 0x38, 0x33, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x07, 0xf8, 0x03};
byte b;
uint8_t idx;
boolean started = false;

byte     XOR;
byte     inverted;

uint32_t   value;


void setup() {
  // Initialize serial communication at 9600 baud
  Serial.begin(9600);
  delay(1000);
  Serial.println("start:");
}

void loop() {
  
        // Print the contents of the buffer to Serial Monitor for verification
        for (int i = 0; i < sizeof(buffer); i++) {
          Serial.print(buffer[i], HEX);
          Serial.print(" ");
        }
        Serial.println();

        // Check we received the message ok.  XOR checksum on bytes 01-26 should match byte 27.
        XOR = buffer[1];
        for (int x = 2; x <= 26; x++)
        {
          XOR ^= buffer[x];  
        }
        Serial.print("Calculated checksum: ");
        Serial.print(XOR, HEX);

        if (XOR == buffer[27])
          Serial.println(" (Correct)");
        else
          Serial.println(" (Error)");


        // Check the inverted XOR checksum
        inverted = ~XOR;
        Serial.print("Inverted checksum: ");
        Serial.print(inverted, HEX);
        if (inverted == buffer[28])
          Serial.println(" (Correct)");
        else
          Serial.println(" (Error)");

        
        // Extract the card number from bytes 01 (LSB) - 10 (MSB).
        value = 0;
        for (int x = 10; x >= 1; x--)
        {
          if(buffer[x] <= '9')
            value = (value<<4) + buffer[x] - '0';  
          else
            value = (value<<4) + buffer[x] - '7';  
        }
        Serial.print("Card number: ");
        Serial.println(value);


        // Extract the country number from bytes 11 (LSB) - 14 (MSB).
        value = 0;
        for (int x = 14; x >= 11; x--)
        {
          if(buffer[x] <= '9')
            value = (value<<4) + buffer[x] - '0';
          else
            value = (value<<4) + buffer[x] - '7';  
        }
        Serial.print("Country number: ");
        Serial.println(value);


        // Extract the Data Block from byte 15.
        Serial.print("Data block: ");
        Serial.println(buffer[15] - '0');

        
        // Extract the Animal Flag from byte 16.
        Serial.print("Animal flag: ");
        Serial.println(buffer[16] - '0');

        Serial.println("\r");
delay(100000);
}

返回卡 ID:891920753

2 31 37 31 41 39 32 35 33 41 33 34 38 33 30 30 31 30 30 30 30 30 30 30 30 30 30 7 F8 3 
Calculated checksum: 7 (Correct)
Inverted checksum: F8 (Correct)
Card number: 891920753
Country number: 900
Data block: 0
Animal flag: 1

c++ arduino hex ascii rfid
1个回答
0
投票

这是将您的输入转换为实际值的方法。 我把校验和计算留给你:)

#include <array>
#include <cstdint>
#include <iostream>

std::array<std::uint8_t, 30> buffer = { 0x02, 0x31, 0x37, 0x31, 0x41, 0x39, 0x32, 0x35, 0x33, 0x41, 0x33, 0x34, 0x38, 0x33, 0x30,
                                        0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x07, 0xf8, 0x03 };

// helper function to convecrt ascii hex character to a decimal number
std::uint64_t from_hex(const char c)
{
    if(c >= '0' && c <= '9')
        return c - '0';
    return c - 'A' + 10;
}

struct tag_info_t
{
    tag_info_t(const std::array<std::uint8_t, 30>& buffer)
    {
        // copy the data from the buffer to the struct
        std::memcpy(&m_data, buffer.data(), sizeof(tag_info_t));

        // then convert the ascii hex values to a single integer
        // start at last digit and work forwards
        for(int i = static_cast<int>(m_data.tag_id.size()-1); i >= 0; --i)
        {
            // each time we get to a new character the current
            // value is shifted left by 4 bits (multiplied by 16)
            m_tag_id = (m_tag_id << 4);

            // then we convert the current character in the input buffer 
            // to a number and add it to the current value
            m_tag_id += from_hex(m_data.tag_id[i]);
        }

        for(int i = static_cast<int>(m_data.country_id.size()-1); i >= 0; --i)
        {
            m_country_id = (m_country_id << 4);
            m_country_id += from_hex(m_data.country_id[i]);
        }
    }

    bool validate()
    {
        if(m_data.start_byte != 0x02)
            return false;
        if(m_data.end_byte != 0x03)
            return false;
        //TODO checksum
        return true;
    }

    std::uint64_t get_tag_id() const noexcept
    {
        return m_tag_id;
    }

    std::uint64_t get_country_id() const noexcept
    {
        return m_country_id;
    }

private:
    // not strictly needed
    // you can index into the raw array directly
    // but this lets me show you a bit more clearly
    // where I am getting the bytes from
    struct data_block_t
    {
        std::uint8_t start_byte;
        std::array<std::uint8_t, 10> tag_id;
        std::array<std::uint8_t, 4> country_id;
        std::uint8_t data_block;
        std::uint8_t animal_flag;
        std::array<std::uint8_t, 4> reserved4;
        std::array<std::uint8_t, 6> reserved6;
        std::uint8_t crc1;
        std::uint8_t crc2;
        std::uint8_t end_byte;
    };

    data_block_t m_data;
    std::uint64_t m_country_id{};
    std::uint64_t m_tag_id{};
};

int main()
{
    tag_info_t tag_info{ buffer };
    if(tag_info.validate())
    {
        std::cout << "Country ID: " << tag_info.get_country_id() << "\n";
        std::cout << "Tag ID: " << tag_info.get_tag_id() << "\n";
    }

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.