Обнаружение входящего импульса 7,875 кГц для использования в качестве триггера

Я написал код, который обнаруживает входящий импульс (квадрат) частотой 7,875 кГц, чтобы активировать выходной высокий уровень на протяжении всей длительности импульса и активировать выходной низкий уровень, если импульс выключен или не обнаружен.

КОД

// Определяем пины
volatile int pulse1 = 2;    // входящий импульс 1 на контакт 2

const int ledPin = 13;   //выход для включения светодиода
    

void setup() {

  pinMode(pulse1, INPUT);
  
  pinMode(ledPin, OUTPUT);
  
  // Настройка таймера
  
  TCCR1A = 0;               // установить весь регистр TCCR1A в 0
  TCCR1B = 0;               // то же самое для TCCR1B
  TCNT1  = 65282;           // инициализируем значение счетчика
  TCCR1B |= (1<<CS10);      // устанавливаем прескалер на 8 бит
  TIMSK1 |= (1 << TOIE1);   // разрешаем прерывание по переполнению таймера

}
ISR(TIMER1_OVF_Vect){
  TCNT1 = 65282;
  attachInterrupt(digitalPinToInterrupt(pulse1), ISR_UV2, FALLING);
  }
  

void loop() {
  attachInterrupt(digitalPinToInterrupt(pulse1), ISR_UV1, RISING);
  
}

// Подпрограммы прерывания

void ISR_UV1(){
  digitalWrite(ledPin, HIGH);      // Отправляем высокий сигнал
}

void ISR_UV2(){
  digitalWrite(ledPin, LOW);      // Отправляем низкий сигнал
}

Правильный ли это подход или я что-то не так делаю? И последнее, что меня беспокоит, это то, что каждый раз, когда я подключаю провод (ни к чему не подключенный) к входному контакту 2, он отправляет сигнал высокого уровня и поддерживает его до тех пор, пока Arduino не будет сброшен. Импульс представляет собой прямоугольную волну с рабочим циклом 50%, генерируемую устройством. Мне не нужно его измерять или считать. Я просто использую его как триггер для отправки ВЫСОКОГО сигнала, когда это происходит. Таким образом, он остается включенным (происходит) в течение 25 мс & выключается, в течение которого его частота. 7,875 МГц & затем он повторяется устройством в соответствии с параметрами устройства. Я знаю, что это очень короткий импульс, но для целей проекта ничто другое не может быть использовано в качестве триггера

Любая помощь будет оценена по достоинству.

, 👍2

Обсуждение

Если вы не подключаете провод ни к чему, штифт все еще плавает. Он может иметь любое значение, даже быстро меняющееся, в зависимости от того, какой шум он улавливает в данный момент. Сам штифт уже может улавливать шум. С прикрепленным проводом вы в основном создаете антенну., @chrisl

Почему вы прикрепляете прерывания снова и снова? Вы никогда не отсоединяете прерывания, так зачем присоединять их снова и снова?, @chrisl

Также мне непонятно, куда вы прикрепляете прерывания. Я не думаю, что это работает, если вы прикрепите 2 прерывания к одному контакту. Тогда вы просто меняете прерывание на очень короткое время, когда таймер переполняется. Вместо этого вы можете просто использовать 1 прерывание с CHANGE вместо RISING или FALLING. Внутри него вы можете прочитать пин, чтобы проверить, какой из них произошел. Вы пробовали, если этот код работает? Или вы заранее спрашиваете?, @chrisl

Можете ли вы описать форму пульсовой волны более подробно? Это такая высокая частота, что вы ничего не можете сделать в это время, кроме как посмотреть, произошло ли это. Пример подробного описания: это ВЫСОКИЙ импульс длительностью 200 нс, возникающий один раз в секунду. Или это 200 нс ВЫСОКИЙ, за которым следует 200 нс НИЗКИЙ, повторяющийся., @Gabriel Staples

Что означает, что пульс «выключен» или «не обнаружен»? ВЫКЛ, когда сигнал НИЗКИЙ? Или это когда вы не видели ВЫСОКИЙ импульс для X нс, или что-то еще?, @Gabriel Staples

Кроме того, взгляните на мой ответ здесь: https://arduinoprosto.ru/q/76981/7727. Только цифровая запись занимает 5 мкс, что на целый порядок больше, чем этот импульс, который вы пытаетесь измерить. Мы можем сократить время цифровой записи до 125 нс, но для записи на выводы придется использовать прямой доступ к регистру., @Gabriel Staples

возможно, вы можете использовать простой демодулятор для извлечения импульса из сигнала 7,875 МГц, @jsotola

@chrisl Спасибо за ваш отзыв., @Malik Elahi

@chrisl Я использую этот код внутри другой программы, и эти подпрограммы должны быть в приоритете, поэтому я подумал, что этот подход сработает. Управление должно быть точным, т.е. как только начинается импульс, высокий сигнал должен быть отправлен наоборот. Вот почему я также использую прерывание по таймеру. Я попробую то, что вы предложили. И, наконец, что касается плавающей проблемы, я просто решил ее, установив НИЗКИЙ уровень и включив его при подключении сигнала., @Malik Elahi

@GabrielStaples Спасибо за ваш вклад. Импульс представляет собой прямоугольную волну с рабочим циклом 50%, генерируемую устройством. Мне не нужно его измерять или считать. Я просто использую его как триггер для отправки ВЫСОКОГО сигнала, когда это происходит. Таким образом, он остается включенным (происходит) в течение 25 мс и выключается, в течение которого его частота. составляет 7,875 МГц, а затем повторяется устройством в соответствии с параметрами устройства. Я знаю, что это очень короткий импульс, но для целей проекта ничто другое не может быть использовано в качестве триггера., @Malik Elahi

@jsotola, я тоже попробую. Но цель состоит в том, чтобы все было как можно проще. так как это часть большого проекта., @Malik Elahi

@chrisl после устранения неполадок, я думаю, он застревает в прерывании таймера. Основная причина использования таймера - использовать его в качестве двойной проверки, чтобы после окончания импульса он отправлял низкий сигнал. Если у вас есть какие-либо предложения о том, как сделать это иначе. это будет полезно., @Malik Elahi

Кроме того, я не уверен, имеет ли это значение или нет, но высокий сигнал импульса составляет 3,3 В. Я не думаю, что это проблема, потому что, насколько мне известно, если напряжение выше 0,6x5 В, все должно быть в порядке ... но дайте мне знать, если это повлияет., @Malik Elahi

3,3В нормально. Он достаточно высок, как вы утверждаете., @Gabriel Staples

Мне очень любопытно, если вы готовы поделиться: каково применение всего этого импульса и триггера?, @Gabriel Staples

@GabrielStaples, короткая версия, триггер будет использоваться для управления УФ-светодиодами (у которых есть собственный контроллер), и я думаю, вы можете предположить, где используется УФ-светодиод =), @Malik Elahi


2 ответа


0

Не думаю, что ваш нынешний подход сработает. Логика кажется мне ущербной (хотя я не могу знать, как именно этот код встроен в ваш реальный код), а частота настолько высока, что микроконтроллеру будет трудно сделать что-то между различными триггерами прерывания.

Я бы предложил два разных подхода, основанных на реальных потребностях:

  1. Вы можете создать демодулятор, который просто даст вам высокое значение, когда ваш сигнал есть, и низкое, если его нет. Здесь вам потребуются дополнительные компоненты.

  2. Вы можете подать сигнал на один из таймеров в качестве источника синхронизации. Затем таймер подсчитывает импульсы (на самом деле вдвое больше импульсов, поскольку таймер увеличивает значение на каждом фронте, нарастающем или спадающем). Вы можете использовать прерывание переполнения, чтобы получить от него значение. Допустим, вы используете Таймер 1 для сигнала и все еще имеете Таймер 0 для работы с временем Arduino (delay(), millis(), micros()< /код>). Затем вы можете написать ISR для прерывания переполнения Timer1. Там вы берете текущее время и вычитаете время последнего прерывания. Затем вы получаете время, которое потребовалось для переполнения таймера. Поскольку вы знаете, сколько импульсов необходимо для переполнения таймера, вы теперь знаете среднюю частоту. Если он находится в нужном диапазоне, вы устанавливаете простую однобайтовую переменную флага (обязательно объявите ее как volatile). Вы можете настроить время для среднего значения, например, с помощью предварительного масштабирования.

    Затем в основном коде вы можете проверить установленный флаг и сделать соответствующие действия. Сбросьте флаг, если вы что-то сделали, и сохраните метку времени. Проверьте свой основной код, если с момента последней временной метки прошло определенное время. Если да, то это означает, что сигнал потерян. Там вы можете действовать соответствующим образом

,

Еще раз большое спасибо за ваши предложения, я попробую их и дам вам знать, если это сработает. Я подозреваю, что в конце концов мне придется перейти к подходу демодулятора., @Malik Elahi

Мои извинения!!! Частота указана в кГц, а не в мегагерцах. Я дважды проверил это с помощью прицела. Тем не менее .. я попробую ваши предложения., @Malik Elahi

@MalikElahi, эта новая частота меняет все! :) Кроме того, детали, которые вы предоставили нам в своих комментариях, везде должны быть в вашем вопросе. Пожалуйста, обновите свой вопрос со всеми вашими новыми данными, и я посмотрю, смогу ли я дать ответ сегодня. То, что вы хотите сделать, безусловно, выполнимо., @Gabriel Staples

@GabrielStaples Большое спасибо, да, конечно, я обновлю вопрос. Я попробовал свой код, предложенный * chrisl *, чтобы изменить «восходящий» на «изменить», и он работает, но все еще есть несколько ошибок, и я на 90% уверен, что он застревает в прерывании таймера или после счетчика таймера не является целым числом, таймер отключен на пару микросекунд, @Malik Elahi

@MalikElahi, вам следует подумать об использовании прямого управления портом вместо вызовов digitalWrite(). По моему опыту, самая высокая частота, которую вы можете достичь с помощью digitalWrite(), составляет ~ 500 Гц на arduno uno. На самом деле, мне интересно, как вы заставляете это работать на частоте 7 кГц., @Sim Son


2

Итак, я понял, в чем проблема: мне пришлось отключать прерывания в подпрограммах обработки прерываний, а не в моем основном коде. Итак, в основном эти изменения:

void loop() {
  digitalWrite(ledPin, LOW);
  attachInterrupt(digitalPinToInterrupt(pulse1), ISR_UV1, CHANGING);
  
}

& в подпрограммах прерывания:

digitalWrite(ledPin, HIGH);      // Отправить высокий или низкий уровень в зависимости от подпрограммы
detachInterrupt(digitalPinToInterrupt(pulse1));

& в основном это работает как шарм, & есть еще проблемы с таймером, но они будут решены в моем основном коде с другим датчиком.

,