Как подружить библотеки PinChangeInt и SoftwareSerial?

TevatroN
Offline
Зарегистрирован: 17.11.2013

Подскажите пожалуйста как избежать конфликты используя библиотеки PinChangeInt и SoftwareSerial?

Собрал я счетчик гейгера из этого проекта

А тут исходники и библиотеки

В отличии от оригинала я изменил подключение LCD на i2c, все работает, все отлично.

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

Сколько не городил не обошел ошибку, пытался объединить минимум кода из примеров каждой из библиотек, но безуспешно. Конфликт перекрестный ругаются обе библиотеки, в библиотеках рылся, не нашел явной подсказки, в гугле был, таких примеров проблем не нашел.

Кто из опытных подскажите как справится с данной проблемой?

#include <PinChangeInt.h>
#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX


//#define NO_PIN_NUMBER 10       // to indicate that you don't need the pinState
//#define NO_PIN_NUMBER 11       // to indicate that you don't need the pinState

//#define NO_PIN_NUMBER 10      // to indicate that you don't need the arduinoPin
//#define NO_PIN_NUMBER 11      // to indicate that you don't need the arduinoPin

#define PIN1 2
#define PIN2 3
#define PIN3 4

uint8_t latest_interrupted_pin;
uint8_t interrupt_count[20]={0}; // 20 possible arduino pins
void quicfunc() {
  latest_interrupted_pin=PCintPort::arduinoPin;
  interrupt_count[latest_interrupted_pin]++;
};

// You can assign any number of functions to any number of pins.
// How cool is that?
void pin3func() {
  Serial.print("Pin "); Serial.print(PIN3, DEC); Serial.println("!");
}

void setup() {
  mySerial.begin(4800);
  mySerial.println("Hello, world?");
  pinMode(PIN1, INPUT); digitalWrite(PIN1, HIGH);
  PCintPort::attachInterrupt(PIN1, &quicfunc, FALLING);  // add more attachInterrupt code as required
  pinMode(PIN2, INPUT); digitalWrite(PIN2, HIGH);
  PCintPort::attachInterrupt(PIN2, &quicfunc, FALLING);
  pinMode(PIN3, INPUT); digitalWrite(PIN3, HIGH);
  PCintPort::attachInterrupt(PIN3, &pin3func, CHANGE);
  Serial.begin(115200);
  Serial.println("---------------------------------------");
}

uint8_t i;
void loop() {
  uint8_t count;
  Serial.print(".");
  delay(1000);
  for (i=0; i < 20; i++) {
    if (interrupt_count[i] != 0) {
      count=interrupt_count[i];
      interrupt_count[i]=0;
      Serial.print("Count for pin ");
      if (i < 14) {
        Serial.print("D");
        Serial.print(i, DEC);
      } else {
        Serial.print("A");
        Serial.print(i-14, DEC);
      }
      Serial.print(" is ");
      Serial.println(count, DEC);
    }
  }
}

Игры с отключением пинов тоже не помогают:

//#define NO_PIN_NUMBER 10       // to indicate that you don't need the pinState
//#define NO_PIN_NUMBER 11       // to indicate that you don't need the pinState

//#define NO_PIN_NUMBER 10      // to indicate that you don't need the arduinoPin
//#define NO_PIN_NUMBER 11      // to indicate that you don't need the arduinoPin

 

7up
Offline
Зарегистрирован: 27.12.2016

апну тему, таже проблема. Удалось решить?

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Давайте сюда

1) как можжно более компактный пример в котором проявляется проблема
2) ссылку на используемую библиотеку PinChangeInt

7up
Offline
Зарегистрирован: 27.12.2016

ЕвгенийП пишет:

Давайте сюда

1) как можжно более компактный пример в котором проявляется проблема
2) ссылку на используемую библиотеку PinChangeInt

я пробую испольовать https://github.com/NicoHood/PinChangeInterrupt она по поиску в Arduino IDE устанавливается

есть еще https://github.com/GreyGnome/PinChangeInt пока не пробовал.

простой скетч,при котором получаем ошибку компиляции:

#include <SoftwareSerial.h>
#include "PinChangeInterrupt.h"

SoftwareSerial GSMport(4, 5); // RX, TX

void setup() {
  Serial.begin(9600);
  Serial.println("start");
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(12, INPUT_PULLUP);
  
  attachInterrupt(0, Catch1, FALLING);
  attachInterrupt(1, Catch2, FALLING);

  attachPCINT(digitalPinToPCINT(12), Catch1, FALLING);
}

void loop() {
}


void Catch1() {
  Serial.print("1");
}

спасибо.

7up
Offline
Зарегистрирован: 27.12.2016

проблему решил.

необходимо клонировать библиотеку SoftwareSerial например в mySoftwareSerial и заменить некоторые строки (прилогаю ниже), в дальнейшем использовать модифицированную(клонированную) библиотеку, суть в том, что бы отучить данную библиотеку при запуске использовать все прерывания, а принудительно использовать только одно, остальные в этот момент можно использовать например той же PinChangeInt

в моем случае SIM800 модуль я повесил на А0 и А1, а цифровые ноги испольую как входы по прерываниями INT и PCINT

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Не понял. Она говорит, что у Вас в строке 14 неопределённая переменная Catch2. Так она действительно ингде не определена, чего Вы ожидали?

Есть строку 14 убрать, то там уже лезет куча предупреждений (нехороших, кстати) и ошибка, веткоры прерываний определены дважды.

По поводу ошибки. Вы (PinChangeInterrupt) хотите обрабатывать прерывания PCINT. И SoftwareSerial тоже хочет. Причём PinChangeInterrupt  хочет это делать на любых доступных ногах и SoftwareSerial  - тоже самое. Вот и подрались.

Решением может быть разведеление ног между ними. Т.е. сказать PinChangeInterrupt что мол ты имеешь право обрабатывать только прерывания на таких-то ногах, а на других - не лезь. А SoftwareSerial наоборот на те первые - не лезь, а на тех, что запретны для PinChangeInterrupt  - пожалуйста, обрабатывай. Разумеется при этом надо думать куда подключать девайсы для SoftwareSerial и куда для PinChangeInterrupt.

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Во, блин, пока я писал, Вы уже и решили :)

Поздравляю!

7up
Offline
Зарегистрирован: 27.12.2016

ЕвгенийП пишет:

Во, блин, пока я писал, Вы уже и решили :)

Поздравляю!

спасибо за участие :) надеюсь кому-то данный метод поможет.

7up
Offline
Зарегистрирован: 27.12.2016

Снова столкнулся с проблемой пересечения PCINT в двух библиотеках и поиском наткнулся снова на эту тему :) НО в данном случае вожусь с Мега 2560 где прерываний больше, немного поковыряв настройки нашел более грамотный способ. В библиотеке PinChangeInterrupt есть файл PinChangeInterruptSettings.h где в версии 1.2.5 Release (02.09.2017) (которая вышла после моего поста выше с корявым решением проблемы) куда разработчик добавил Added support to disable pcint/port via -DPCINT_DISABLE_PORT0 etc.

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

Возможно кому-то поможет.