Как я могу правильно вызвать функцию lcd.begin() из нескольких разных файлов кода?
У меня есть проект, разделенный на несколько файлов:
//Loop.cpp
#include "LiquidCrystal.h"
void setup(){
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
lcd.begin(16, 2);
}
void loop() {
//Code
}
//Display.cpp
#include "LiquidCrystal.h"
namespace display {
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void displayData(const InputPacket &inputPacket, const DataPacket &dataPacket) {
lcd.setCursor(0,1);
lcd.print("Foo"); //Это создает ошибку отображения, если только я не вызову lcd.begin(16, 2) в этой функции
}
} //namespace display
Моя первоначальная проблема заключается в том, что - без вызова функции lcd.begin() из функции displayData() - символы отображаются неправильно. Другими словами, вызов функции lcd.begin() в setup() не помогает. (Мне кажется, что setup() имеет неявное статическое свойство, не так ли?)
В качестве попытки решения я мог бы создать жидкокристаллический объект в Display.cpp, и вызовите lcd.begin() из displayData(). Даже если символы отображаются правильно, это дает мне мерцание дисплея. (Предположительно в результате повторного вызова этих функций в цикле во время выполнения).
Таким образом, единственное решение этой дилеммы, которое я могу придумать, - это вызвать lcd.begin() из функции, написанной для запуска только один раз внутри displayData(). Или это так?
Мой вопрос в том, есть ли другие более элегантные решения/альтернативы?
@Erik, 👍0
1 ответ
Лучший ответ:
Объект под названием lcd
, который вы создаете внутри функции setup
, является локальной переменной. Он живет только до тех пор, пока эта функция выполняется - так что не очень долго. Оно не существует вне этой функции.
ЖК
-объект, который у вас есть в пространстве имен
, с другой стороны, является глобальной переменной. Этот живет до тех пор, пока ваша программа, что означает, пока вы не сбросите свой Arduino здесь. (Это совершенно не связано с объектом внутри установки
.)
Если вы хотите, чтобы весь ваш ЖК-код был сгруппирован внутри пространства имен дисплея, вы можете сделать это в
Display.cpp
:
namespace display {
// Это глобальная переменная, полное имя `display::lcd`
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
// этот `жк-дисплей` относится к глобальному `дисплею::lcd`, определенному выше
lcd.begin(16, 2);
}
// остальные функции дисплея
}
Создайте файл Display.h
, чтобы предоставить прототипы для модуля отображения:
#ifndef DISPLAY_H
#define DISPLAY_H
// Include заголовок, определяющий InputPacket и DataPacket здесь
namespace display
{
void setup();
void displayData(const InputPacket &inputPacket, const DataPacket &dataPacket);
}
#endif
Тогда ваш основной файл может вызвать функцию отображения. Основной файл даже не должен знать, что вы используете жидкокристаллический дисплей, если вы упаковываете весь жидкокристаллический код в файл дисплея.
#include "Display.h" // нет необходимости включать LiquidCrystal.h, если все
// Обработка жидкокристаллического дисплея производится в Display.cpp
void setup(){
// Initialize display
display::setup();
}
Потрясающе, спасибо. Ваш ответ дал мне много интересного для размышления!, @Erik