Помогите написать написать скетч управления экраном через кнопку

Всем привет. Потихоньку вникаю в ардуино, вот уже как неделю. Захотел написать скетч: при нажатии на кнопку экран бы включался и выводил “HELLO, WORLD !”, при повторном включении экран бы выключался. Взял готовый скетч для кнопочного управления и вставил туда элементы управления экраном. Однако всё оказалось не так просто, а моих знаний пока не хватает, чтобы понять, что не так. Ничего конкретного по проблеме в интернете не нашёл. Почитал и посмотрел про создание менюшек на LCD, но никто не управлял питанием через кнопку. Помогите, пожалуйста, написать адекватный код.
Снизу приложу код и фото самой схемы.
Использую экран LCD1602 c модулем I2C и плату Arduino Nano. GND подключен к земле платы, VCC к цифровому выходу 9 (по задумке с этого пина должно было поступать либо 0, либо 1 в экран, в зависимости от нажатия кнопки), SDA к А4 и SCL к А5. Сама кнопка через макетку подсоединена к земле (чтобы провода не заслоняли экран) и к цифровому пину 7 (в который с неё должно было поступать либо 0, либо 1).


#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

#define BUTTON_PIN  3
#define LCD_PIN     9
LiquidCrystal_I2C LCD(0x27,16,2);

bool butt_flag = 1;  
bool pwr_flag = 0;
 
void setup()
{
  pinMode(LCD_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  LCD.init(); 
  LCD.backlight();
}
 
void loop()
{
  bool button = digitalRead(BUTTON_PIN);
  if (butt_flag && !button) {
    delay(10);
    button = digitalRead(BUTTON_PIN);
    if (!button) 
    {
      pwr_flag = !(pwr_flag);
      analogWrite(LCD_PIN, pwr_flag);
    }
  }
  butt_flag = button;
LCD.clear();
LCD.setCursor(5,0);
LCD.print("HELLO,");
LCD.setCursor(5,1);
LCD.print("WORLD !");
}

В коде опечатка: не 3 пин, а 7 должен быть. Однако проблемы это не решает(

В строке 13 ты не подаешь питание на дисплей, но далее проводишь инициализацию и включаешь подсветку, что нужно делать после подачи питания.

А пин не сгорит?

По какой?

И для чего там analogWrite()? Зачем два раза читать button_pin?

Для надёжности.

Как-то напомнило …

1 лайк

Т.е. инициализацию и включение подсветки засунуть под if(!button) после analogWrite(LCD_PIN, pwr_flag); ?

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

Даже не знаю, как Вы искали. В половине проектов с маломощными дисплеями, питание дисплея сделано от пина микроконтроллера и дисплей включается подачей HIGH на пин. А там уж подавайте этот HIGH хоть по кнопке, хоть по входящей смс-ке, это дело тридцать третье.

Вот, например - ОСОБЕННОСТИ РАБОТЫ С ЖКИ ДИСПЛЕЕМ NOKIA 5110 – тема научной статьи по компьютерным и информационным наукам читайте бесплатно текст научно-исследовательской работы в электронной библиотеке КиберЛенинка

Включение digitalWrite() , затем инициализация

зачем аналог?

Ну, как зачем? Это для подачи питания от аналогового источника! Был бы цифровой БП - другое дело!

#define BUTTON_PIN  7
#define LCD_PIN     9
void setup() {
  pinMode(LCD_PIN, OUTPUT);
  Serial.begin(115200);
}

bool lastBtnState = false;
void loop() {
  bool btnState = digitalRead(BUTTON_PIN);
  if (btnState and (btnState != lastBtnState)) {
    delay(30);  //Защиту от дребезга можно и без delay сделать
    btnState = digitalRead(BUTTON_PIN);
    if (btnState) {
      bool f = !digitalRead(LCD_PIN);
      digitalWrite(LCD_PIN, f);
      if (f) {
        Serial.println("On");
        //Тут инициализируй дисплей и делай что нужно при его включении
      } else {
        Serial.println("Off");
      }
    }
  }
  lastBtnState = btnState;
}

Не знаю сколько потребляет LCD, но учитывай это. С пина ардуины около 40 (или даже 20, не помню)мА можно… И каждый раз при подаче питания нужно заново инициализировать дисплей… не смотрел в код библиотеки, но скорее всего нужно.
Но может все таки не нужно полностью питание “рубить”, а просто “тушить” экран и “зажигать”… noBacklight(); и backlight();

Спойлер
#include <LiquidCrystal_I2C.h>
#define BUTTON_PIN  7
LiquidCrystal_I2C LCD(0x27, 16, 2);

void setup() {
  LCD.init();
}

bool lastBtnState = false; bool f = false;
void loop() {
  bool btnState = digitalRead(BUTTON_PIN);
  if (btnState and (btnState != lastBtnState)) {
    delay(30);  //Защиту от дребезга можно и без delay сделать
    btnState = digitalRead(BUTTON_PIN);
    if (btnState) {
      f = !f;
      if (f) {
        LCD.setCursor(5, 0);
        LCD.print("HELLO,");
        LCD.setCursor(5, 1);
        LCD.print("WORLD !");
        LCD.backlight();
      } else {
        LCD.clear();
        LCD.noBacklight();
      }
    }
  }
  lastBtnState = btnState;
}

Спасибо большое!