Прерывание Adafruit Circuit Playground Express не работает

У меня есть прерывания, подключенные к контактам 4 и 5, которые соответствуют левой и правой встроенным кнопкам на игровой площадке экспресс (https://learn.adafruit.com/adafruit-circuit-playground-express/pinouts). По какой-то причине прерывание правой кнопки работает отлично, а прерывание левой даже не срабатывает. Вот код:

#include <Adafruit_Circuit_Playground.h>
#include <Adafruit_CircuitPlayground.h>

volatile bool leftState = false, rightState = false;

void left()
{
    if (CircuitPlayground.leftButton())
        leftState = !leftState;
}

void right()
{
    if (CircuitPlayground.rightButton())
        rightState = !rightState;
}

void setup()
{
    CircuitPlayground.begin();
    Serial.begin(9600);

    attachInterrupt(digitalPinToInterrupt(4), left, CHANGE);
    attachInterrupt(digitalPinToInterrupt(5), right, CHANGE);
}


void loop()
{
    Serial.print(leftState);
    Serial.print("\t");
    Serial.print(rightState);
    Serial.print("\n");
} 

, 👍0


1 ответ


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

2

Контакт 4 на Zero нельзя использовать с attachInterrupt. Это контакт PA08 платы SAMD21, и он имеет NMI в качестве функции управления прерываниями в EIC и не может использоваться как EXTINT.

Adafruit Circuit Playground сопоставляет PA28 с контактом 4, но описание контакта оставлено как для Zero и не объявляет возможность прерывания.

В файле arduino/hardware/samd/1.6.21/variants/circuitplay/variant.cpp измените строку для контакта 4 на

  { PORTA, 28, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8  },                           // GPIO D4 / левая кнопка

Пакеты находятся в ~/.arduino15/packages/ в Linux и %userprofile%\AppData\Local\Arduino15\packages\ в Windows (AppData — это скрытая папка).

Предупреждение: в variant.cpp таблица обзорных комментариев описывает Zero, а не Circuit Playground.

Примечание. Читать кнопку с прерыванием невыгодно. Вы можете только установить какой-либо флаг в прерывании, а затем обработать его в цикле(). Но тогда вы можете напрямую проверить в цикле состояние контакта, потому что он будет активен во многих циклах, даже если пользователь нажмет его на короткое время.

,

У меня много задержек в моем основном цикле (код, который я разместил, упрощен, чтобы изолировать проблему), поэтому входы кнопок не будут регистрироваться. Чтобы было ясно, какое значение я должен указать в качестве первого параметра, когда я прикрепляю прерывание для левой кнопки?, @James A

подождите, значит, в распиновке для экспресс-игры указано, что кнопка a является контактом прерывания, но вы не можете использовать его как контакт прерывания?, @James A

распиновка где? Я проверил вариант.cpp для этой платы в пакете плат Arduino SAMD., @Juraj

https://cdn-learn.adafruit.com/assets/assets/000/049/780/original/Adafruit_Circuit_Playground_Express_Pinout.pdf Кнопка A помечена как прерывание, @James A

описание в variant.cpp не соответствует истинному используемому сопоставлению. Я переписываю ответ. вам нужно будет исправить variant.cpp, @Juraj

Давайте [продолжим это обсуждение в чате](https://chat.stackexchange.com/rooms/94087/discussion-between-james-a-and-juraj)., @James A

я изменил ответ, @Juraj

Я получаю ошибки компиляции сейчас, @James A

@JamesA, у Adafruit есть собственный пакет плат SAMD с Circuit Playground Express. у него такая же ошибка в варианте ant.cpp, @Juraj

Я внес изменения в код в репо. Теперь это должно быть исправлено. Моя проблема заключалась в том, что когда я редактировал файл с помощью vscode, он вставлял специальные невидимые символы, что приводило к ошибкам. Когда я изменил его с помощью блокнота, все было хорошо, @James A