Как можно при нажатии на кнопку отображать ее имя
Мне нужно распознавать сигнал от ИК-пульта, а не использовать библиотеку для работы с ИК-пультами/приемниками. Как можно при нажатии на кнопку отображать ее имя. У меня есть микроконтроллер PIC12F615 с этим кодом: code и к нему подключено 5 кнопок и мне нужно распознать какая кнопка нажата. У меня есть код, но он дает разные шестнадцатеричные коды, если я нажимаю одну и ту же кнопку.
byte IRpin = 2;
volatile boolean remote = false;
volatile unsigned long irCode = 0;
void remoting ()
{
if ( remote )
{
remote = false;
unsigned long T;
for ( byte n = 0; n < 32; n ++ )
{
do
{
T = pulseIn ( IRpin, HIGH, 2200 );
}
while ( T < 64 );
bitWrite ( irCode, n, T > 1120 );
}
}
}
void setup ()
{
Serial.begin ( 9600 );
Serial.println ( "\n\tReady for keyboard reading!\n" );
pinMode ( IRpin, INPUT_PULLUP );
attachInterrupt ( digitalPinToInterrupt ( IRpin ), remoting, FALLING );
}
void loop ()
{
if (irCode)
{
Serial.println (irCode, HEX);
irCode = 0;
}
delay (40);
remote = true;
}
Схема:
@Good York, 👍1
Обсуждение1 ответ
Лучший ответ:
Функция pulseIn() имеет следующий комментарий в исходном коде: "Эта функция лучше работает с короткими импульсами в контексте noInterrupt()" см.: https://github.com/arduino/ArduinoCore-avr/blob/ master/cores/arduino/wiring_pulse.c. Неясно, нарушает ли ваш код "короткий импульс" правило, однако, блокирование процедуры обслуживания прерывания (в вашем случае, процедуры обратного вызова внешнего прерывания remoting() ) для всей длины потока данных IR наверняка вызовет другие проблемы, например, с таймером millis().
Это соответствует стилю вашего кода, но не использует прерывания. Он был протестирован с пультом дистанционного управления NEC и дает воспроизводимые результаты. Ваш код не прошел тот же тест.
byte IRpin = 2;
unsigned long irCode = 0;
void setup ()
{
Serial.begin ( 9600 );
Serial.println ( "\n\tReady for keyboard reading!\n" );
pinMode ( IRpin, INPUT_PULLUP );
}
void loop () {
while ( digitalRead ( IRpin ) ); // ждем начала первого импульса
unsigned long T;
uint8_t validPulses = 0 ;
for ( byte n = 0; n < 36 ; n ++ ) // достаточно, чтобы удалить длинный заголовок
{
T = pulseIn ( IRpin, HIGH , 12000 ); // тайм-аут 12 мс
if ( T < 4000 && T > 400 && validPulses < 32 ) {
// действительный импульс
bitWrite ( irCode, validPulses++, T > 1120 );
}
}
if (irCode > 0 ) Serial.println (irCode, HEX);
else Serial.println ("no code");
irCode = 0 ;
}
можно ли это сделать через прерывание по пину или прерывание по таймеру?, @Good York
@GoodYork Действительно есть, и я бы порекомендовал в вашем случае использовать режим захвата ввода Таймера 1. Это было бы неблокирующим, если бы все было сделано осторожно. Есть ли в этом упражнении какие-либо другие ограничения, например, какой вывод использовать или что использование pulseIn() является обязательным? Если это так, добавьте все это в свой исходный вопрос. В любом случае, с тем, что у вас есть, вы сможете проверить, работает ли PIC., @6v6gt
Задача: При написании программы НЕ допускается использование библиотек для работы с ИК-пультами/приемниками. Сигнал от приемника должен обрабатываться с помощью внешнего прерывания. Ваш код работает, вот у меня есть код, который работает через таймер 1, но это не работает, @Good York
- Как сгенерировать аппаратное прерывание в mpu6050 для пробуждения Arduino из режима SLEEP_MODE_PWR_DOWN?
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- Как правильно использовать volatile переменные в Arduino?
- Как прервать функцию цикла и перезапустить ее?
- 4-битный счетчик вверх и вниз
- Включить и отключить отдельные прерывания
- Управление функцией включения на драйвере микрошагового устройства
- Захват прерывания на обоих фронтах, когда он установлен на RISING или FALLING
пульт дистанционного управления может выводить изменяющийся код, @jsotola
и как мне сделать так чтобы при нажатии на кнопку отображалось ее название, @Good York
пожалуйста, не задавайте вопрос в комментарии ... отредактируйте свой пост и добавьте свой вопрос, @jsotola
У вас есть PIC12F615, как в вашем вопросе, или Uno, как в тегах и на схеме?, @Nick Gammon
Похоже, вы используете pulseIn() в процедуре обслуживания прерывания для того же вывода, который используется для инициирования прерывания. Это конечно странно. pulseIn() может быть ненадежным в ISR, и вам в любом случае не следует блокировать ISR. Это, безусловно, новое решение — попытаться интерпретировать протокол NEC IR, сгенерированный этим PIC., @6v6gt
Работает ли Arduino или PIC (или оба) на симуляторе?, @6v6gt
Оба работают на симуляторе, @Good York
Этот симулятор работает в реальном времени? Если нет, есть ли способ проверить, что все моделируемые объекты работают в одной и той же временной области, скажем, путем попытки (быстрой) последовательной связи между ними?, @6v6gt
работаю в протеусе, @Good York
В Proteus есть логический анализатор. Подключите его к контакту 5 PIC и одновременно к контакту 2 Arduino. Добавьте примеры трассировок и соответствующие выходные данные последовательной консоли arduino к исходному вопросу. Это должно помочь выяснить, является ли это проблемой PIC, Proteus или Arduino., @6v6gt
Я использовал осциллограф [ссылка](https://imgur.com/t7bStKQ), желтый контакт 5, синий контакт 2, @Good York