Помогите разобраться с GyverEncoder.h в Platformio

ReyG

✩✩✩✩✩✩✩
1 Авг 2024
3
0
Добра всем. Пробую в Platformio создать отдельные файлы для функций с использованием классов.
использую библиотеки
#include <GyverEncoder.h>
#include <LiquidCrystal_I2C.h>

Выношу в отдельный файл *.h класс либо функцию (по разному пробовал) в которой есть строки :
if (enc.isTurn() or enc.isPress())
lcd.setBacklight(_flag)

Platformio ругается, что:

error: 'enc' was not declared in this scope
if (enc.isTurn() or enc.isPress())
Compiling .pio\build\nanoatmega328\FrameworkArduino\hooks.c.o
^~~
src\BackLightState.h:14:5: note: suggested alternative: 'getc'
if (enc.isTurn() or enc.isPress())
^~~
getc

и так же

lcd' was not declared in this scope
lcd.setBacklight(_flag);
^~~

подчеркивает enc и lcd

и в файле main.cpp и BackLightState.h обе библиотеки подключены
если в обоих файлах добавить
LiquidCrystal_I2C lcd(0x27, 16, 2);
то lcd уже не подчеркивает, но

At global scope:
src\main.cpp:10:22: error: redefinition of 'LiquidCrystal_I2C lcd'
LiquidCrystal_I2C lcd(0x27, 16, 2);
^
In file included from src\main.cpp:4:0:
src\BackLightState.h:6:19: note: 'LiquidCrystal_I2C lcd' previously declared here
LiquidCrystal_I2C lcd(0x27, 16, 2);
^~~


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

извиняюсь за возможный сумбур в вопросе

C++:
class BackLightState {

  public:
  BackLightState (uint32_t prd) {
  _prd = prd;
}

void BL_St(){
if (enc.isTurn() or enc.isPress())
  {

    _flag = true;
    _tmr = millis();

  }
  if (_flag && millis() - _tmr >= _prd)
  {
    _flag = false;
    }
  lcd.setBacklight(_flag);
  digitalWrite(13,LOW);
}
private:
bool _flag;
unsigned long _tmr;
uint32_t _prd;
};
 

Bruzzer

★★★✩✩✩✩
23 Май 2020
496
144
как правильно написать ...
Чтобы как правильно - надо учиться по учебникам а не по советам на "сомнительных" форумах.
(Я например в классах почти не разбираюсь. И мой совет тоже сомнителен.)
enc - обращение к конкретной переменной, и писать свой класс для работы с конкретной переменной - по моему не правильно. А как правильно - написано в учебниках.

Неправильно - попробовать объявить переменную enc в вашем классе как external
 

poty

★★★★★★✩
19 Фев 2020
3,262
949
@ReyG, по правильному - определение класса должно быть описано в файле *.h, методы класса - в отдельном файле *.cpp.
Но Ваша ошибка не в определении класса, а в невозможности доступа к переменной - экземпляру класса. Экземпляр класса должен быть объявлен так, чтобы все последующие его вхождения в текст программы знали о его создании. В Вашем случае - объявлять enc и lcd нужно до include, в котором они используются.
 

ReyG

✩✩✩✩✩✩✩
1 Авг 2024
3
0
Оформи код соответствующим тэгом, см. Правила
@poty,
Проверил, да, всё верно, переместил *.h после

#include <LiquidCrystal_I2C.h>
// LiquidCrystal_I2C lcd(0x27, cols, rows);
LiquidCrystal_I2C lcd(0x27, 16, 2);
// ********** Переменные для энкодера ***************
#include <GyverEncoder.h>
#define CLK 3 // Энкодер пин A (S1)
#define DT 4 // Энкодер пин B (S2)
#define SW 2 // Кнопка
Encoder enc(CLK, DT, SW, TYPE2);

#include *.h

и всё заработало.
т.е. все дочерние файлы должны подключаться после всех библиотек.
Спасибо!

P.S. и до *.cpp дойдет очередь. Пока на элементарных кодах вникаю в классы, методы, дочерние файлы и пр., как видите не без затыков
 

poty

★★★★★★✩
19 Фев 2020
3,262
949
@ReyG, что за "дочерние файлы"?
По факту: использовать в header-файле глобальные переменные, даже спрятанные внутри класса - неправильно. Это делает header-файл зависимым от места объявления этих переменных, что и произошло в Вашем случае. Если хотите использовать переменные (классы...) в другом классе - передайте их в конструктор и сохраните указатель внутри класса.
 

ReyG

✩✩✩✩✩✩✩
1 Авг 2024
3
0
дочерние файлы - это все файлы функций, классов и т.д (не библиотеки), которые подключаются к родительскому (main.cpp).
цель - научиться правильно выводить часть кода из родительского, дабы не было длиннющей "портянки" вот это и есть "дочерние" файлы.
"...использовать переменные (классы...) в другом классе - передайте их в конструктор и сохраните указатель внутри класса. " - это пока не очень понятно для меня. объекты, классы, структуры, конструкторы и т.д. в языке программирования "слегка" отличаются от релейно-контакторной логики, чем я занимаюсь.
объекты, классы, структуры, конструкторы и т.д. - в процессе изучения.
 

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,412
978
58
Марий-Эл
@ReyG, Я знаю, как это правильно делается.
Но писать сюда сейчас не буду.
Нужно материал подготовить с примерами и комментариями. Это дело не 5ти минут.
Напомните мне в понедельник до 6.30 утра (позже я за комп уже не сяду). Я на работе всё подготовлю и выложу.