#1 2021-04-23 13:06:47

Black Wolf
Учасник
Зареєстрований: 2021-04-05
Повідомлень: 4

Правильно инициализировать экземпляр класса SoftSerial в своем классе.

Доброго времени суток!
Есть у меня необходимость сделать обработку нескольких считывателей RDM6300 125Kгц. Для этого решено написать свой класс.
По одиночке все работает) Как только, инициализируется 2 датчика - работает только инициализированый последним.
Примечание - ранее писал на языке не поддерживающем ООП. Прошу не пинать ногами.

Сам класс:

#include <SoftwareSerial.h>
class RDM6300 {
  public:
    RDM6300(byte pinSignal, byte pinDenyLed, byte pinAllowLed);
    void static initBuzzer(byte pinBuzzer);
    static void buzzer(byte Povtor, int Millisec = 400, int Tone = 1000);
    void setLed(bool DenyLed = 1, bool AllowLed = 1);
    void initRfid();
    void testLed();
    void readRfid();

  private:
    byte _pinSignal;
    byte _pinDenyLed;
    byte _pinAllowLed;
    static byte _pinBuzzer;
    SoftwareSerial _RFID = SoftwareSerial(0, 0); // Вот эта недоконструкция мной была использована 
                                                                //для хоть какой-то инициализации.
    static int _rx_counter;
    static byte _rx_data[14]; // 1+10+2+11
    void pauseRead();
    byte _ascii_char_to_num(byte a);
    void printResultReadRfid();
    bool _flagPause;

};

Код инициализации:

RDM6300::RDM6300(byte pinSignal, byte pinDenyLed, byte pinAllowLed) {
  _pinSignal = pinSignal;
  _pinDenyLed = pinDenyLed;
  _pinAllowLed = pinAllowLed;
}

void RDM6300::initRfid() {
  pinMode(_pinDenyLed, OUTPUT);
  pinMode(_pinAllowLed, OUTPUT);
  _RFID = SoftwareSerial(_pinSignal, 0);   //Вот в этом месте срабатывает переназначение на нужный пин SoftSerial.
                                                       // но только в датчике, инициированом последним в setup().
  _RFID.begin(9600);
  testLed();
  buzzer(1);
}

Инициализация:

#define BuzzerPin A3
byte RDM6300::_pinBuzzer;
int RDM6300::_rx_counter;
byte RDM6300::_rx_data[14]; // 1+10+2+11

RDM6300 rfidVhod(7, A4, A5);
RDM6300 rfidExit(6, A1, A2);



void setup() {
  Serial.begin(9600);
  RDM6300::initBuzzer(BuzzerPin);
  
  rfidExit.initRfid();
  rfidVhod.initRfid(); //Вот этот будет работать..

  initNetwork();
  printDHCP_test();

}

Насколько я понимаю, я не создаю в каждом екземпляре класса новый обьект SoftSerial.
Подскажите как его правильно создать в своем классе (Замена вот этого: 

SoftwareSerial _RFID = SoftwareSerial(0, 0);

)?
Или я чего-то совсем не понимаю?

Остання редакція Black Wolf (2021-04-23 13:07:24)

Неактивний

#2 2021-04-23 14:47:21

Black Wolf
Учасник
Зареєстрований: 2021-04-05
Повідомлень: 4

Re: Правильно инициализировать экземпляр класса SoftSerial в своем классе.

Сам отвечу:
Не знаю или я таки правильно провожу инициализацию экземпляра SoftSerial с позиции синтаксиса, но  конструкция приведенная выше все же отрабатывает правильно.

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

Пока в тестовом варианте реализовано коряво так:

void loop() {
  if (millis() - ChangeListenTimer >= 500) {   // таймер на 500 мс (2 раза в сек)
    ChangeListenTimer = millis();
    if (rfidExit.rfidGetListen() == true) {
      rfidVhod.rfidSetListen(true);
      rfidExit.rfidSetListen(false);
    } else {
      rfidVhod.rfidSetListen(false);
      rfidExit.rfidSetListen(true);
    }
  }

  if (rfidExit.rfidGetListen()) {
    rfidExit.readRfid();
  }

  if (rfidVhod.rfidGetListen()) {
    rfidVhod.readRfid();
  }
}

Соответственно в код описания класса добавлено:

  public:
       bool rfidGetListen();
    void rfidSetListen(bool state = false);

  private:
        bool _flagListen;

А в код реализации класса:

void RDM6300::rfidSetListen(bool state) {
  _flagListen = state;
  if (_flagListen == true) {
    _RFID.listen();
  }
}

bool RDM6300::rfidGetListen() {
  return _flagListen;
}

Не знаю, может кому и понадобится, потому оставлю это сдесь.

Остання редакція Black Wolf (2021-04-23 14:49:08)

Неактивний

#3 2021-04-23 16:26:23

Kaka
Учасник
Зареєстрований: 2018-03-21
Повідомлень: 405

Re: Правильно инициализировать экземпляр класса SoftSerial в своем классе.

Но, работать всё равно будет криво.

Неактивний

#4 2021-04-23 21:55:36

Black Wolf
Учасник
Зареєстрований: 2021-04-05
Повідомлень: 4

Re: Правильно инициализировать экземпляр класса SoftSerial в своем классе.

Kaka пише:

Но, работать всё равно будет криво.

Проверяли с периодом опроса в 25 миллисекунд все 4 считывателя. Для задачи СКУД (турникет) подходит. Для более критичных по времени задач - нужно думать.
Подскажите, может что мы не заметили?

Остання редакція Black Wolf (2021-04-23 21:56:00)

Неактивний

#5 2021-04-23 22:59:49

Kaka
Учасник
Зареєстрований: 2018-03-21
Повідомлень: 405

Re: Правильно инициализировать экземпляр класса SoftSerial в своем классе.

Да, почему, если Вам подходит, то и флаг в руки.

Но. Иногда, ни с того ни с сего, без видимых причин, вдруг будут теряться байты. Нечасто, но будут. Если задача позволяет на это забить, то и слава Богу.

Неактивний

#6 2021-04-23 23:31:08

Black Wolf
Учасник
Зареєстрований: 2021-04-05
Повідомлень: 4

Re: Правильно инициализировать экземпляр класса SoftSerial в своем классе.

Kaka пише:

Да, почему, если Вам подходит, то и флаг в руки.

Но. Иногда, ни с того ни с сего, без видимых причин, вдруг будут теряться байты. Нечасто, но будут. Если задача позволяет на это забить, то и слава Богу.

Благодарю за ответ. Действительно потери будут, тем более что библиотека SoftSerial используется. И при переключении считывателей методом listen об этом прямо сказано.
Но, как верно замечено, указанная задача это позволяет.
Мной пока не придумано, как можно реализовать по другому.

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму