Прерывания в классе

gasan333
Offline
Зарегистрирован: 16.10.2015

Я пытаюсь создать класс, который работает с клавиатурой. Я понимаю, что член класса не является правильным форматом функции. Ну все таки я последовал примеру http://www.gammon.com.au/forum/?id=12983. Если присваивать переменной значение в функции pressKey() то выводит ошибку при компиляции   collect2: error: ld returned 1 exit status *** [.pio/build/esp32doit-devkit-v1/firmware.elf] Error 1

#ifndef MYKEY_H
#define MYKEY_H
#include <Arduino.h>
#include <PCF8574.h>
//#include "board_tr02.h"



class MyKey {
    #define ENTER_KEY 1
    #define BACK_KEY 2
    #define UPP_KEY 0
    #define DOWN_KEY 3
    static MyKey *instance;

public:
    MyKey(uint8_t interapt_pin);
    MyKey();
    uint8_t isUpp();
    uint8_t isDown();
    uint8_t isEnter();
    uint8_t isBack();
    

private: 
    PCF8574 *inExtender;
    bool _flagInterapt;
    uint8_t _pressStat;
    static void intteraptKeys();
    void pressKey();

} ;
#endif


MyKey::MyKey(uint8_t interapt_pin){
    this->_flagInterapt = true;
    inExtender = new PCF8574(0x21, interapt_pin,  intteraptKeys);
    inExtender->pinMode(DOWN_KEY, INPUT_PULLUP);
    inExtender->pinMode(UPP_KEY, INPUT_PULLUP);
    inExtender->pinMode(ENTER_KEY, INPUT_PULLUP);
    inExtender->pinMode(BACK_KEY,INPUT_PULLUP);
    inExtender->begin();   
}

MyKey::MyKey(){ // now interrapt
    this->_flagInterapt = false;
    inExtender = new PCF8574(0x21);
    inExtender->pinMode(DOWN_KEY, INPUT_PULLUP);
    inExtender->pinMode(UPP_KEY, INPUT_PULLUP);
    inExtender->pinMode(ENTER_KEY, INPUT_PULLUP);
    inExtender->pinMode(BACK_KEY,INPUT_PULLUP);
    inExtender->begin(); 
}

void MyKey::pressKey(){
    this->_pressStat =true;
}

void MyKey::intteraptKeys(){
    if(MyKey::instance != NULL)
         MyKey::instance->pressKey();
}

 

b707
Offline
Зарегистрирован: 26.05.2017

Метод экземпляра нельзя вызывать в качестве обработчика прерывания. Создайте обработчик вне класса, а уже в нем вызывайте метод через указатель на экземпляр

gasan333
Offline
Зарегистрирован: 16.10.2015
#ifndef MYKEY_H
#define MYKEY_H
#include <Arduino.h>
#include <PCF8574.h>
//#include "board_tr02.h"

static void intteraptKeys();

class MyKey {
    #define ENTER_KEY 1
    #define BACK_KEY 2
    #define UPP_KEY 0
    #define DOWN_KEY 3
    

public:
    MyKey(uint8_t interapt_pin);
    MyKey();
    uint8_t isUpp();
    uint8_t isDown();
    uint8_t isEnter();
    uint8_t isBack();
    static MyKey *instance;

private: 
    PCF8574 *inExtender;
    bool _flagInterapt;
    uint8_t _pressStat;
    void pressKey();

} ;
#endif


MyKey::MyKey(uint8_t interapt_pin){
    this->_flagInterapt = true;
    inExtender = new PCF8574(0x21, interapt_pin,  intteraptKeys);
    inExtender->pinMode(DOWN_KEY, INPUT_PULLUP);
    inExtender->pinMode(UPP_KEY, INPUT_PULLUP);
    inExtender->pinMode(ENTER_KEY, INPUT_PULLUP);
    inExtender->pinMode(BACK_KEY,INPUT_PULLUP);
    inExtender->begin();   
}

MyKey::MyKey(){ // now interrapt
    this->_flagInterapt = false;
    inExtender = new PCF8574(0x21);
    inExtender->pinMode(DOWN_KEY, INPUT_PULLUP);
    inExtender->pinMode(UPP_KEY, INPUT_PULLUP);
    inExtender->pinMode(ENTER_KEY, INPUT_PULLUP);
    inExtender->pinMode(BACK_KEY,INPUT_PULLUP);
    inExtender->begin(); 
}

void MyKey::pressKey(){
    this->_pressStat =true;
}

void intteraptKeys(){
    if(MyKey::instance != NULL)
         MyKey::instance->_pressStat= true;
}

Не совсем понял, создал вне класса все рано не коммпилится 

b707
Offline
Зарегистрирован: 26.05.2017

Instanse сделайте глобальной и волатильной, присваивайте ей указатель на текущий экземпляр в конструкторе или отдельном методе
Ищите примеры в гугле, я счас в электричке еду, неудобно код набирать:)

rkit
Онлайн
Зарегистрирован: 23.11.2016

В классе статически объявляется прерывание, которое вызывает обработчик, принадлежащий к правильному экземпляру.

gasan333
Offline
Зарегистрирован: 16.10.2015

Я запарился иже искать, не знаю может плохо ищу, вот пример https://overcoder.net/q/1944963/%D0%BF%D1%80%D0%B5%D1%80%D1%8B%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F-%D0%B2-%D0%BA%D0%BB%D0%B0%D1%81%D1%81%D0%B5, но пучему то у меня не работает. 

#ifndef MYKEY_H
#define MYKEY_H
#include <Arduino.h>
#include <PCF8574.h>
//#include "board_tr02.h"



class MyKey {
    #define ENTER_KEY 1
    #define BACK_KEY 2
    #define UPP_KEY 0
    #define DOWN_KEY 3
    static volatile MyKey *instance;

public:
    MyKey(uint8_t interapt_pin);
    MyKey();
    uint8_t isUpp();
    uint8_t isDown();
    uint8_t isEnter();
    uint8_t isBack();
    

private: 
    PCF8574 *inExtender;
    bool _flagInterapt;
    uint8_t _pressStat;
    static void intteraptKeys();
    void pressKey();

} ;
#endif


MyKey::MyKey(uint8_t interapt_pin){
    this->_flagInterapt = true;
    inExtender = new PCF8574(0x21, interapt_pin,  intteraptKeys);
    inExtender->pinMode(DOWN_KEY, INPUT_PULLUP);
    inExtender->pinMode(UPP_KEY, INPUT_PULLUP);
    inExtender->pinMode(ENTER_KEY, INPUT_PULLUP);
    inExtender->pinMode(BACK_KEY,INPUT_PULLUP);
    inExtender->begin();  
    instance = this;
}

MyKey::MyKey(){ // now interrapt
    this->_flagInterapt = false;
    inExtender = new PCF8574(0x21);
    inExtender->pinMode(DOWN_KEY, INPUT_PULLUP);
    inExtender->pinMode(UPP_KEY, INPUT_PULLUP);
    inExtender->pinMode(ENTER_KEY, INPUT_PULLUP);
    inExtender->pinMode(BACK_KEY,INPUT_PULLUP);
    inExtender->begin(); 
}

void MyKey::pressKey(){
   // this->_pressStat =true;
}

void MyKey::intteraptKeys(){
    if(MyKey::instance != NULL)
         MyKey::instance->pressKey();
}

src/MyKey.h:63:36: error: passing 'volatile MyKey' as 'this' argument discards qualifiers [-fpermissive]

b707
Offline
Зарегистрирован: 26.05.2017

Ну здравствуйте, запарился он:) В чем тогда цимес написания кода, если не сидеть ночами долбясь головой в стенку, разбираясь почему код не работает?
Судя по коду. Вы невнимательно читаете, что вам пишут

b707
Offline
Зарегистрирован: 26.05.2017

rkit пишет:

В классе статически объявляется прерывание, которое вызывает обработчик, принадлежащий к правильному экземпляру.


наверно так правильнее, но я просто описываю обработчик и указатель на экземпляр " снаружи" класса... и все работает

rkit
Онлайн
Зарегистрирован: 23.11.2016

А зачем было объявлять указатель волатильным? Зачем тебе вообще класс, если у тебя только один экземпляр?

b707
Offline
Зарегистрирован: 26.05.2017

Почему обязательно один? Иногда несколько. Тогда создаю массив указателей на экземпляры и вызываю их по очереди.
Неправильно?

rkit
Онлайн
Зарегистрирован: 23.11.2016

Я говорю про код в примере.

gasan333
Offline
Зарегистрирован: 16.10.2015

Дайте  ссылку на примерчик :) плиз 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

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

gasan333
Offline
Зарегистрирован: 16.10.2015

дык там микросхема PCF8574 она подключена по I2C если небудет прерывания мне приходится все время опрашивать и занимать I2C шину

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

тем более воткните внутрь прерывания запустить метод tick, или run для класса. Пусть опросить и вызовет нужный обработчик.

Ну где-то подобное. #4

gasan333
Offline
Зарегистрирован: 16.10.2015

И сколько раз ты отпросишь ? Я говорю мне свободная I2C  нужно так как там много устройств сидят, все время опрашивать микруху не целесообразно, ладно мы отходим от темы тут проблема в коде, которая не хочет компилится 

gasan333
Offline
Зарегистрирован: 16.10.2015
#ifndef MYKEY_H
#define MYKEY_H
#include <Arduino.h>
#include <PCF8574.h>
//#include "board_tr02.h"



class MyKey {
    #define ENTER_KEY 1
    #define BACK_KEY 2
    #define UPP_KEY 0
    #define DOWN_KEY 3

public:
    MyKey(uint8_t interapt_pin);
    MyKey();
    uint8_t isUpp();
    uint8_t isDown();
    uint8_t isEnter();
    uint8_t isBack();
    
private: 
    PCF8574 *inExtender;
    bool _flagInterapt;
    uint8_t _pressStat;
    static void intteraptKeys();
} ;
#endif

static  MyKey instance;

MyKey::MyKey(uint8_t interapt_pin){
    this->_flagInterapt = true;
    inExtender = new PCF8574(0x21, interapt_pin,  intteraptKeys);
    inExtender->pinMode(DOWN_KEY, INPUT_PULLUP);
    inExtender->pinMode(UPP_KEY, INPUT_PULLUP);
    inExtender->pinMode(ENTER_KEY, INPUT_PULLUP);
    inExtender->pinMode(BACK_KEY,INPUT_PULLUP);
    inExtender->begin();  
}

MyKey::MyKey(){ // now interrapt
    this->_flagInterapt = false;
    inExtender = new PCF8574(0x21);
    inExtender->pinMode(DOWN_KEY, INPUT_PULLUP);
    inExtender->pinMode(UPP_KEY, INPUT_PULLUP);
    inExtender->pinMode(ENTER_KEY, INPUT_PULLUP);
    inExtender->pinMode(BACK_KEY,INPUT_PULLUP);
    inExtender->begin(); 
}

void MyKey::intteraptKeys(){
    
    instance._pressStat = true;
}

Вопрос закрыт 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну если вопрос закрыт. то 35 и 44 вызывают утечку памяти. Но если память течет, то сидя на берегу можно увидеть труп проплывающего врага крах системы

b707
Offline
Зарегистрирован: 26.05.2017

Пипец, в instanсe весь класс копируем ради изменения одного флага?
Гасан, с указателями у вас все плохо?

gasan333
Offline
Зарегистрирован: 16.10.2015

b707 пишет:
Пипец, в instanсe весь класс копируем ради изменения одного флага? Гасан, с указателями у вас все плохо?
Ну покажите тогда как делать ? 

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

gasan333 пишет:
Ну покажите тогда как делать ?
Я бы может и подсказал, если бы понимал ЧТО сделать?

Izvekoff
Offline
Зарегистрирован: 02.03.2020

b707 пишет:
Ну здравствуйте, запарился он:) В чем тогда цимес написания кода, если не сидеть ночами долбясь головой в стенку, разбираясь почему код не работает? Судя по коду. Вы невнимательно читаете, что вам пишут

да Вы батенька экстремал )))

gasan333
Offline
Зарегистрирован: 16.10.2015

qwone пишет:

Ну если вопрос закрыт. то 35 и 44 вызывают утечку памяти. Но если память течет, то сидя на берегу можно увидеть труп проплывающего врага крах системы

Не забывайте это контроллер а не программа на ПК, объект создается один раз никакой утечки не будет. ну чтобы успокоить вашу душу добавлю деструктор  

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

gasan333 пишет:
Не забывайте это контроллер а не программа на ПК, объект создается один раз никакой утечки не будет. ну чтобы успокоить вашу душу добавлю деструктор  

Включили /отключили прерывание и пара байтиков ку-ку. В контроллере байтиков маловастенко и мож через часок другой система подвиснет по непонятной причине. И будет любимая ситуация программиста "почувствуй себя идиотом". 

пс: http://adatum.ru/pcf8574-kak-legko-uvelichit-chislo-pinov-na-arduino.html   последняя программа

gasan333
Offline
Зарегистрирован: 16.10.2015

qwone пишет:

gasan333 пишет:
Не забывайте это контроллер а не программа на ПК, объект создается один раз никакой утечки не будет. ну чтобы успокоить вашу душу добавлю деструктор  

Включили /отключили прерывание и пара байтиков ку-ку. В контроллере байтиков маловастенко и мож через часок другой система подвиснет по непонятной причине. И будет любимая ситуация программиста "почувствуй себя идиотом". 

пс: http://adatum.ru/pcf8574-kak-legko-uvelichit-chislo-pinov-na-arduino.html   последняя программа

Вот именно при включении и отключении прерывании а я не собираюсь отключать и включать

b707
Offline
Зарегистрирован: 26.05.2017

Гасан, что спорить то? Вы для чего сюда пришли - ведь чтобы учиться. Значит слушайте, что вам говорят.

gasan333
Offline
Зарегистрирован: 16.10.2015

Я понимаю если мне скажут где ошибка почему покажут как делать , а тут просто воздух гоняют одни воздуханы

b707
Offline
Зарегистрирован: 26.05.2017

Ошибки вам давно указали. Не копируйте весь класс по значению, используйте ссылки. Или вы ждете, что кто-то код за вас напишет?