Назначьте тип для значения uint8_t

В моем проекте я прочитал уникальный идентификатор из метки RFID, результат в форме uint8_t TagRead[4],

Результат сравнивается с рядом предопределенных значений идентификатора тега, чтобы определить, какой тег был прочитан.

Например:

uint8_t RED1[4] = { 0x73, 0xD5, 0xB7, 0xAC };
uint8_t RED2[4] = { 0x7E, 0x27, 0x49, 0x4E };
uint8_t RED3[4] = { 0x02, 0xFD, 0x06, 0x40 };
uint8_t GREEN1[4] = { 0xAB, 0xEC, 0x68, 0x80 };
uint8_t GREEN2[4] = { 0xEE, 0x20, 0x50, 0x4E };
uint8_t GREEN3[4] = { 0x27, 0x06, 0x40, 0x73 };

if (*((uint32_t *)TagRead) == *((uint32_t *)RED2)) {
    // RED2 tag has been read
}

else if (*((uint32_t *)TagRead) == *((uint32_t *)GREEN3)) {
    // GREEN3 tag has been read
}

Мой вопрос касается возможности назначить тип / категорию группе тегов, чтобы можно было выполнить действие в зависимости от цвета отсканированного тега.

Возможно, что при сканировании КРАСНОЙ метки мы включаем красный светодиод, а при сканировании ЗЕЛЕНОЙ метки мы включаем синий светодиод.

Поскольку существует около 50 тегов каждого цвета, я не хочу перечислять все имена тегов в операторе If. Вместо этого можно ли назначить цвет тегу?

Тогда можно будет сделать:

Если отсканированный тег имеет тип КРАСНЫЙ, выполните красное действие. Если отсканированный тег имеет тип ЗЕЛЕНЫЙ, выполните зеленое действие.

Спасибо за вашу помощь.

3 ответа

Во-первых, ваше сравнение - неопределенное поведение. Правильный путь с std::memcmp, Вы также должны заботиться о порядке байтов.

Чтобы прикрепить свойства (например, цвет) к вашим тегам, просто определите структуру:

struct rfid_tag
{
    uint8_t value[4];
    enum { ... } color;
};

Как только вы получили структуру, вы можете обогатить ее operator== так что вы можете использовать std::find() искать соответствующий тег в одной строке:

#include <iostream>
#include <array>
#include <algorithm>
#include <cstring>

struct rfid_tag
{
    enum color_type { red = 10, blue = 11 };

    std::array<uint8_t, 4> value;
    color_type             color;
};

bool operator==(std::array<uint8_t, 4> const& tagvalue, rfid_tag const& rhs)
{
    return std::memcmp(tagvalue.data(), rhs.value.data(), rhs.value.size()) == 0;
}

bool operator==(rfid_tag const& lhs, std::array<uint8_t, 4> const& tagvalue)
{
    return tagvalue == lhs;
}


static const std::array<rfid_tag, 3> known_tags = {
    rfid_tag{ { 0x00, 0x01, 0x02, 0x03 }, rfid_tag::red },
    rfid_tag{ { 0x10, 0x11, 0x12, 0x13 }, rfid_tag::blue },
    rfid_tag{ { 0x20, 0x21, 0x22, 0x23 }, rfid_tag::red }
};

int main()
{
    const std::array<uint8_t, 4> tag_to_find{ 0x10, 0x11, 0x12, 0x13 };
    std::cout << std::find(begin(known_tags), end(known_tags), tag_to_find)->color << "\n"; // outputs "11" as expected
}

демонстрация

Вы можете создать структуру с идентификатором и цветовым перечислением:

enum class Color { red, green };

struct Tag
{
    uint8_t id[4];
    Color color;
};

Tag RED1 = { { 0x73, 0xD5, 0xB7, 0xAC }, Color::red } ;
Tag RED2 = { { 0x7E, 0x27, 0x49, 0x4E }, Color::red } ;
Tag RED3 = { { 0x02, 0xFD, 0x06, 0x40 }, Color::red } ;
Tag GREEN1 = { { 0xAB, 0xEC, 0x68, 0x80 }, Color::green } ;
Tag GREEN2 = { { 0xEE, 0x20, 0x50, 0x4E }, Color::green } ;
Tag GREEN3 = { { 0x27, 0x06, 0x40, 0x73 }, Color::green } ;

void test(Tag tag)
{
    if (tag.color == Color::red)
    {
        //
    }
    else if (tag.color == Color::green)
    {

    }
}

Есть несколько способов.

Вы можете написать структуру, которая содержит ваш тег вместе с вашим цветом, например так:

struct ColoredTag
{
    uint8_t[4] value;
    std::string color;

} typename ColoredTag_t;

ColoredTag_t RED1 = {{ 0x73, 0xD5, 0xB7, 0xAC }, "Red"};
ColoredTag_t RED2 = {{ 0x7E, 0x27, 0x49, 0x4E }, "Red"};
ColoredTag_t RED3 = {{ 0x02, 0xFD, 0x06, 0x40  }, "Red"};
ColoredTag_t GREEN1 = {{ 0xAB, 0xEC, 0x68, 0x80 }, "Green"};
ColoredTag_t GREEN2 = {{ 0xEE, 0x20, 0x50, 0x4E }, "Green"};
ColoredTag_t GREEN3 = {{ 0x27, 0x06, 0x40, 0x73 }, "Green"};

Или вы можете использовать std::map назначить цвет тегу, как это

std map<uint8_t[4], std::string> tags;

public void fillTags()
{
    tags[RED1] = "Red";
    tags[RED2] = "Red";
    //...

}

std::string getColor(uint8_t tag)
{
    return tags[tag];

}

Возможно, есть еще несколько решений этой проблемы, но это те, которые пришли мне в голову первыми.

Другие вопросы по тегам