Прерывания иногда не срабатывают

Я новичок в ардуино, так что простите, если вопрос покажется немного нубским.

Ниже я прикрепил код. Я использую Arduino Mega и фотодатчики, в частности этот EE-SPY415 отражающий фотомикродатчик с обнаруживаемым датчиком. расстояние от 3 до 19 мм

Я использую это с аркадой типа «Скибол», а Arduino использует USB для связи с Pi. Я не уверен, что это лучший способ, поэтому, если у кого-то есть способ получше, дайте мне знать. Сейчас имеется 6 датчиков и еще 2 нужно подключить. Я буду использовать библиотеку, которая позволяет использовать более 6 прерываний, но хочу исключить библиотеку как неисправную.

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

https://pastebin.com/zbVuqec2

Вот искомый файл.

#include <Wire.h>

String inputString = "";         // строка для хранения входящих данных
boolean startGame = false;
boolean stopGame = false;
boolean readSensors = false;

boolean sensor_1_tripped = false;
boolean sensor_2_tripped = false;
boolean sensor_3_tripped = false;
boolean sensor_4_tripped = false;
boolean sensor_5_tripped = false;
boolean sensor_6_tripped = false;

#define SENSOR_1 2
#define SENSOR_2 3
#define SENSOR_3 21
#define SENSOR_4 20
#define SENSOR_5 19
#define SENSOR_6 18

void setup() {
  // поместите сюда свой код установки для однократного запуска:
  Serial.begin(9600);

  pinMode(SENSOR_1, INPUT_PULLUP);
  pinMode(SENSOR_2, INPUT_PULLUP);
  pinMode(SENSOR_3, INPUT_PULLUP);
  pinMode(SENSOR_4, INPUT_PULLUP);
  pinMode(SENSOR_5, INPUT_PULLUP);
  pinMode(SENSOR_6, INPUT_PULLUP);

  // резервируем 200 байт для входной строки:
  inputString.reserve(200);
}

void loop() {
  while (Serial.available()) {
    // получаем новый байт:
    char inChar = (char)Serial.read();
    // добавляем его во входную строку:
    inputString += inChar;
    // если входящий символ является новой строкой, устанавливаем флаг
    // чтобы основной цикл мог что-то с этим сделать:
    if (inputString == "start") {
      startGame = true;
      stopGame = false;
      readSensors = true;
      Serial.write("STARTED");
      inputString = "";
      return;
    }
    if (inputString == "stop") {
      stopGame = true;
      startGame = false;
      readSensors = false;
      return;
    }
  }

  while (startGame) {
    while(readSensors) {

      attachInterrupt(digitalPinToInterrupt(SENSOR_1), sensor_1_callback, FALLING);
      attachInterrupt(digitalPinToInterrupt(SENSOR_2), sensor_2_callback, FALLING);
      attachInterrupt(digitalPinToInterrupt(SENSOR_3), sensor_3_callback, FALLING);
      attachInterrupt(digitalPinToInterrupt(SENSOR_4), sensor_4_callback, FALLING);
      attachInterrupt(digitalPinToInterrupt(SENSOR_5), sensor_5_callback, FALLING);
      attachInterrupt(digitalPinToInterrupt(SENSOR_6), sensor_6_callback, FALLING);

      if(Serial.available()) {
        char inChar = (char)Serial.read();
        inputString += inChar;
        if (inputString == "stop") {
          stopGame = true;
          startGame = false;
          readSensors = false;
          inputString = "";
          Serial.write("STOPPED");
          break;
        }
      }

      if(sensor_1_tripped == true) {
        sensor_1_tripped = false;
        Serial.write("1");
      }
      if(sensor_2_tripped == true) {
        sensor_2_tripped = false;
        Serial.write("2");
      }
      if(sensor_3_tripped == true) {
        sensor_3_tripped = false;
        Serial.write("3");
      }
      if(sensor_4_tripped == true) {
        sensor_4_tripped = false;
        Serial.write("4");
      }
      if(sensor_5_tripped == true) {
        sensor_5_tripped = false;
        Serial.write("5");
      }
      if(sensor_6_tripped == true) {
        sensor_6_tripped = false;
        Serial.write("6");
      }
    }
  }
}

void sensor_1_callback() {
  sensor_1_tripped = true;
}
void sensor_2_callback() {
  sensor_2_tripped = true;
}
void sensor_3_callback() {
  sensor_3_tripped = true;
}
void sensor_4_callback() {
  sensor_4_tripped = true;
}
void sensor_5_callback() {
  sensor_5_tripped = true;
}
void sensor_6_callback() {
  sensor_6_tripped = true;
}

, 👍1

Обсуждение

Почему вы используете AttachInterrupt() каждый раз, когда считываются датчики? Разве недостаточно сделать это только в начале игры?, @AltAir

Те логические значения, которые используются в ISR и также считываются из цикла, должны быть изменчивыми., @Delta_G

Я добавил летучий, но это не помогло (хотя я читал о том, как это нужно сделать). Что касается AttachInterrupt, то он сейчас у меня есть в setup(), но если он уже подключен, он его игнорирует. В любом случае прерывания по-прежнему не работают должным образом., @Fyb3roptik

Не могли бы вы попробовать протестировать более простой код без какого-либо Serial.read(), а также исправить свой код в вопросе (нестабильный и прикрепляемый только при настройке). Помочь легче, если проблему сузить максимально., @hpekristiansen

В итоге я использовал библиотеку Android Things GPIO и создал специальную плату, которая подключается к Pi через UART., @Fyb3roptik


1 ответ


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

-1

Лучшее решение, которое я нашел для передачи прерываний на Pi3 от Arduino, — это использование GPIO. В Android Things есть библиотека для этого, и все это работает без каких-либо задержек!

,