Преобразование из шестнадцатеричного в двоичный
Мне нужно смоделировать серию импульсов. С этим кодом все в порядке, он решает свою проблему. Вопрос в том, что мне нужно изменить ключи, но слишком сложно вручную вводить столько нулей и единиц каждый раз. С другой стороны, я знаю, что мой шестнадцатеричный ключ выглядит намного короче: "B8C4F9". Можно ли создать строку таким образом, чтобы сама система переводилась в двоичную систему?
И второй вопрос: Как можно автоматически измерить длину массива, чтобы не вычислять KEY_LEN вручную?
const int KEY_LEN = 24;
const char key[KEY_LEN] = {"101110001100010011111001"};
int T = 200; // Период повторения импульсов в микросекундах
int Zero = 80; //0,4*T; // Длительность нуля в микросекундах
int One = 120; //0,6*T;// Длительность единицы измерения в микросекундах
const int LED_PIN = 13; // Используется цифровой вывод 13 arduino для подключения передатчика
void setup()
{
pinMode(13, OUTPUT);
}
void loop()
{
for (int n = 0; n < KEY_LEN; n++)
{
if (key1[n] == '1') //If the bit read == 1
{
sendSignal(One);
}
else if (key1[n] == '0')//Если считываемый бит == 0
{
sendSignal(Zero);
}
}
}
void sendSignal(int duration)
{
digitalWrite(LED_PIN, LOW);
delayMicroseconds(duration);
digitalWrite(LED_PIN, HIGH);
delayMicroseconds(T - duration);
}
@Антон, 👍0
Обсуждение1 ответ
Лучший ответ:
На самом деле нет никакой причины сохранять ключ в виде строки, как вы это делаете. Вы можете просто сохранить его как обычный номер. Затем вы также можете использовать шестнадцатеричное представление в своем коде:
unsigned long key = 0xB8C4F9;
Затем вам нужно отправить каждый бит этого числа:
for (int n = 0; n < KEY_LEN; n++)
{
if (key & (1 << n)) { //Если считываемый бит == 1
sendSignal(One);
} else {//Если считываемый бит == 0
sendSignal(Zero);
}
}
В операторе if происходит следующее: (1 << n)
примет значение 1 (двоичное 0b00000001
) и сдвинет биты влево на n цифр. Например: Если n равно 2, то мы получим (0b00000001 << 2) = 0b00000100
. С помощью этого мы можем выбрать бит в нашем числе. Затем мы берем это и делаем побитовое И &
с ключом. Это установит все биты равными нулю, которые в данный момент не выбраны. Результирующее число равно нулю, если соответствующий бит в ключе
равен нулю. Если соответствующий бит равен 1, то он вернет число, отличное от нуля (что интерпретируется как true
. Таким образом, мы проверяем, является ли n-й бит ключа
единицей или нулем.
Как вы можете автоматически измерить длину массива, чтобы не вычислять KEY_LEN вручную?
Как правило, вы можете вычислить размер массива с помощью функции sizeof ()
:
unsigned int size_of_array = sizeof(array)/sizeof(array[0]);
функция sizeof()
возвращает количество байтов. Итак, чтобы получить количество элементов, нам нужно разделить их на количество байтов в каждом элементе;
Для способа, показанного выше, это не так просто. Обычно это не очень нужно, так как такие ключи обычно не очень часто меняют длину. Если вы найдете тип переменной, который точно соответствует вашему размеру ключа, вы можете использовать sizeof(key)*8
, чтобы получить количество битов в нем. Но ваше текущее значение 0xB8C4F9 требует только 3 байта. Я не знаю тип с 3 байтами, но, возможно, где-то вы можете получить что-то вроде
uint24_t
. Честно говоря, здесь я бы просто использовал жестко закодированный размер, так же, как вы используете жестко закодированное значение ключа.
Но в этом случае биты выводятся в обратном порядке (от конца к началу). То есть, если ключ находится в форме, например "D", то будет отображаться 1011, но это не так, вам нужно 1101., @Антон
Чтобы значения считывались правильно, вам нужно это сделать, но это очень долго, и вы можете запутаться: if (ключ & (b100000000000000000000000>>> n)), @Антон
Или вот так:: если (ключ & (0x800000>>> n)), @Антон
@Антон Actually no. Если вы хотите изменить окончание (с LSB первым в моем коде на MSB первым), вам просто нужно изменить направление счета в цикле for: для(int n = KEY_LEN-1; n>=0; n--)
Это начнется с`KEY_LEN-1 " - го бита (MSB вашего ключа) и будет отсчитываться до нулевого бита (LSB). Нет необходимости записывать MSB непосредственно в двоичном или шестнадцатеричном формате., @chrisl
Спасибо! Или вы можете задать другой вопрос: Как вы можете сказать, что является самым последним? ключ & (1 << KEY_LEN-1). Итак?, @Антон
Или вот так: ключ и 1, @Антон
В общем, никакого "последнего кусочка"нет. Вместо этого используются термины MSB и LSB (Первый/Наименее значимый бит). Числа в C/C++ выровнены по правому краю, с LSB справа, MSB слева. ключ & 1
дает вам LSB. ключ & (1 << KEY_LEN-1)
дает вам MSB. Если вы хотите сначала отправить биты MSB (затем перейти к LSB), вы должны начать с ключа & (1 << KEY_LEN-1)
в качестве первого бита в вашей передаче и перейдите к "ключу и 1" (он же ключ и (1 << 0)
), который затем будет последним в вашей передаче., @chrisl
Возникла проблема. При такой длине ключа: длинный ключ без знака = 0xB8C4 все работает нормально, но с увеличением его длины, например: длинный ключ без знака = 0xB8C4F9, все ломается. Как это можно исправить ??, @Антон
- Как использовать SPI на Arduino?
- Как решить проблему «avrdude: stk500_recv(): programmer is not responding»?
- Как создать несколько запущенных потоков?
- Как подключиться к Arduino с помощью WiFi?
- avrdude ser_open() can't set com-state
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Я закирпичил свой Arduino Uno? Проблемы с загрузкой скетчей на плату
это для пульта дистанционного управления телевизором?, @jsotola
Это для управления входной дверью, @Антон