Сформировать сигнал из массива битов

Мне нужно воспроизвести с помощью цифрового вывода 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

Обсуждение

вы не задали ни одного вопроса, @jsotola

0b101100001111 никогда не может поместиться в байт., @Majenko

Та новая версия кода, которую вы опубликовали, работает для меня, никаких предупреждений. Для какого Arduino вы компилируете?, @ocrdu

Arduino Uno. Вам удалось мигнуть светодиодом?, @Антон

Не визуально, потому что delayMicroseconds() слишком мал для человеческого глаза. Мой осциллограф показывает правильный сигнал. Если вы хотите проверить визуально, замените delayMicroseconds() на delay()., @ocrdu

Спасибо вам! Этот скетч действительно работает! Я понял, в чем моя проблема: на самом деле мне нужен более длинный ключ (64 бита). Я использую длинный тип: длинный ключ = 0b1000011110001101111100011111001010110001101101111011011100110100; Но long допускает только 32 бита. Что вы рекомендуете делать? Может быть, вам нужно оформить его в виде массива? Я думаю, вы можете сделать это как-то проще. Спасибо, @Антон

Всегда есть uint64_t, который нужно попробовать, на многих машинах он же long long int., @ocrdu


2 ответа


Лучший ответ:

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


2

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

Вот модифицированная версия вашей программы, которая делает это.

Обратите внимание, что я также взял на себя смелость заменить "магическое число" 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);
}
,