Назначьте тип для значения 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];
}
Возможно, есть еще несколько решений этой проблемы, но это те, которые пришли мне в голову первыми.