Сформировать сигнал из массива битов
Мне нужно воспроизвести с помощью цифрового вывода Arduino такой ключ в виде последовательности единиц и 0, где единица занимает 2 мс и 2 мс, а ноль занимает 1 мс и 1 мс.
int key = 0b101100001111;
void setup()
{
pinMode(13, OUTPUT);
}
void loop()
{
for (int n = 0; n < 12; n++)
{
if (bitRead(key, n) == 1) //выполнить, если значение бита == 1
{
sendSignal(2000);
}
else //выполнить, если значение бита == 0
{
sendSignal(1000);
}
}
}
void sendSignal(int duration)
{
digitalWrite(13, HIGH);
delayMicroseconds(duration);
digitalWrite(13, LOW);
delayMicroseconds(duration);
}
Этот скетч действительно работает! Я понял, в чем моя проблема: на самом деле мне нужен более длинный ключ (64 бита). Я использую длинный тип: длинный ключ = 0b10000111111000110111111100011111001010110001101101111011011100110100; но long допускает только 32 бита. Что вы рекомендуете делать? Может быть, вам нужно оформить его в виде массива? Я думаю, вы можете как-то облегчить это. Спасибо
@Антон, 👍3
Обсуждение2 ответа
Лучший ответ:
Вы должны сделать
byte key = 0b101100001111;
глобальный, то есть поместите его ПЕРЕД функцией настройки
, а не внутри нее.
Кроме того, байт может содержать только 8 бит, вам нужно 12, поэтому сделайте его int (благодаря ocrdu, см. Комментарий Ниже):
int key = 0b101100001111;
Если вам нужно больше битов, вы можете использовать uint32_t или uint64_t и считать дальше, чем текущие 12.
Теперь ключ
- это локальная переменная, которая удаляется после выхода из функции настройки.
Я не уверен, откуда берется слово "ключ" в:
switch (bitRead(key, n)) {
Вы получаете ошибку компилятора или вы ТАКЖЕ определили глобальную переменную с именем key
?
В любом случае, если вы сделаете ключ
глобальным, это исправится в любом случае.
Несколько других замечаний:
- Попробуйте выровнять скобки, например, 3 } в конце, расставьте их правильно, это сделает ваш код намного более читабельным
- Вместо
переключателя
/case
в этом случае вы могли бы использоватьоператор if
, поскольку re - это только (и всегда) два возможных значения (0 и 1):
Таким образом:
if(bitRead(key, n) == 0)
{
...
}
else // 1
{
...
}
Попробуйте также комментарии писать на английском, а не на греческом, вы никогда не знаете, когда ваши комментарии будут прочитаны негреческими читателями (как сейчас).
Вы можете сделать следующий фрагмент короче и менее повторяющимся:
Оригинал:
digitalWrite(13, HIGH);
delayMicroseconds(1000);
digitalWrite(13, LOW);
delayMicroseconds(1000);
Если вы обернете это в функцию:
void sendSignal(int duration)
{
digitalWrite(13, HIGH);
delayMicroseconds(duration);
digitalWrite(13, LOW);
delayMicroseconds(duration);
}
Затем вы можете написать 1, вызвав:
sendSignal(2000);
и 0, вызвав:
sendSignal(1000);
Это русский, а не греческий. Просто говорю 8-)., @ocrdu
@orcdu спасибо :-), @Michel Keijzers
Большое вам спасибо! Действительно хороший совет! Сделав это, кажется, что скетч без ошибок и он загружен на плату. Но я не могу отследить эти импульсы на осциллографе. Я попытался изменить длительность импульсов на несколько секунд, но банального мигания светодиода на 13-м выводе глазом не вижу, он всегда включен. Я не понимаю, что не так, в скетче все кажется логичным, @Антон
ключ int, а не байтовый ключ. 12 бит не поместятся., @ocrdu
@ocrdu хороший момент, я обновлю свой ответ, @Michel Keijzers
@Антон Смотрите комментарий ocrdu; это дополнительное исправление ошибки., @Michel Keijzers
Возможно, в следующий раз вы подумаете о том, чтобы удалить строки, специфичные для Arduino, и использовать отладчик ПК для пошагового выполнения., @Michel Keijzers
@Downvoter, не могли бы вы вместо того, чтобы опускать все мои посты, объяснить, ПОЧЕМУ вы понизили голос, чтобы я мог улучшить пост., @Michel Keijzers
Если вы немного измените код, вы можете использовать массив символов любой длины, поэтому вам не нужно беспокоиться о длине цифрового слова.
Вот модифицированная версия вашей программы, которая делает это.
Обратите внимание, что я также взял на себя смелость заменить "магическое число" 13 на LED_PIN, а "магическое число" 12 на KEY_LEN. Я бы посоветовал вам сделать то же самое с вашими значениями ширины импульса - может быть, что-то вроде PULSE_WIDTH_ONE_USEC и PULSE_WIDTH_ZERO_USEC? Таким образом, кто-то другой (или вы 3 месяца спустя), просматривая ваш код, может легко увидеть, для чего предназначены значения
const int KEY_LEN = 62;
const char key[KEY_LEN] = { "10110110110101111001011010110100101011011100110110101101101100" };
const int LED_PIN = 13;
//int key = 0b101100001111;
void setup()
{
Serial.begin(115200);
pinMode(13, OUTPUT);
}
void loop()
{
for (int n = 0; n < KEY_LEN; n++)
{
if (key[n]== '1') //execute if bit value == 1
{
Serial.print("1");
sendSignal(200);
}
else if (key[n] == '0')//execute if bit value == 0
{
Serial.print("0");
sendSignal(100);
}
else
{
Serial.print("x");
}
}
Serial.println();
}
void sendSignal(int duration)
{
digitalWrite(LED_PIN, HIGH);
//delayMicroseconds(duration);
delay(duration);
digitalWrite(LED_PIN, LOW);
//delayMicroseconds(duration);
delay(duration);
}
- устаревшее преобразование из строковой константы в 'char*'
- Какие есть другие IDE для Arduino?
- Esp8266 Vin контакт
- Ошибка: invalid application of 'sizeof' to incomplete type 'int []' при попытке вычислить размер массива в библиотеке
- Работает ли конструкция int array[100] = {0} на Arduino?
- Длина константного массива uint8_t*
- Плата для разработки STM8 с Arduino IDE
- Шестнадцатеричное/Байтовое реверсирование и преобразование
вы не задали ни одного вопроса, @jsotola
0b101100001111
никогда не может поместиться в байт., @MajenkoТа новая версия кода, которую вы опубликовали, работает для меня, никаких предупреждений. Для какого Arduino вы компилируете?, @ocrdu
Arduino Uno. Вам удалось мигнуть светодиодом?, @Антон
Не визуально, потому что delayMicroseconds() слишком мал для человеческого глаза. Мой осциллограф показывает правильный сигнал. Если вы хотите проверить визуально, замените delayMicroseconds() на delay()., @ocrdu
Спасибо вам! Этот скетч действительно работает! Я понял, в чем моя проблема: на самом деле мне нужен более длинный ключ (64 бита). Я использую длинный тип: длинный ключ = 0b1000011110001101111100011111001010110001101101111011011100110100; Но long допускает только 32 бита. Что вы рекомендуете делать? Может быть, вам нужно оформить его в виде массива? Я думаю, вы можете сделать это как-то проще. Спасибо, @Антон
Всегда есть uint64_t, который нужно попробовать, на многих машинах он же long long int., @ocrdu