Нужна помощь с программой для кнопки смены отображения на OLED-дисплее

Итак, я программирую OLED-дисплей с моего Arduino Uno. Я пытаюсь сделать кнопку, которая переключает разные слова на дисплее. (Слова пока являются просто заполнителями для программ.) В моей программе есть кнопка, которая изменяет счетчик, и проверка if, чтобы увидеть, что такое счетчик, чтобы он мог отображать соответствующее слово. Проблема в том, что всякий раз, когда я нажимаю кнопку, дисплей становится черным и больше ничего не делает. Когда я запускаю/сбрасываю Arduino, он отображает TEMPERATURE, но должен показывать TIME.

#include <OLED_I2C.h>

OLED  myOLED(SDA, SCL, 8);

extern uint8_t SmallFont[];
extern uint8_t MediumNumbers[];
extern uint8_t BigNumbers[];

//constants:
const int buttonPin = 2;

//variables:
byte oldButtonState = HIGH;
int screenNumber = 0;
byte buttonState = 0;

void setup()
{
  myOLED.begin();
  myOLED.setFont(SmallFont);
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() { //myOLED.print formats with (string, text_placement,     pixel_location)
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // Test if the button is being pressed
  if (buttonState == HIGH) {
    myOLED.clrScr();
    myOLED.update();
    oldButtonState = buttonState;
    if (screenNumber != 2) {
      ++screenNumber;
    }
    else {
      screenNumber = 0;
    }
    //delay a little to avoid bouncing
    delay(200);
    }

  //Test for the screenNumber variable and change to the
  //according screen
  if (screenNumber == 0) {
    myOLED.print("TIME", CENTER, 16);
    myOLED.update();
  }
  else if (screenNumber == 1) {
    myOLED.print("TEMPERATURE", CENTER, 16);
    myOLED.update();
  }
  else if (screenNumber == 2) {
    myOLED.print("DIRECTION", CENTER, 16);
    myOLED.update();
  }
  else {
    myOLED.print("ERROR", CENTER, 16);
    myOLED.update();
  }
}

, 👍0

Обсуждение

В чем ваш вопрос? Что делает ваш эскиз, чего он не должен делать?, @VE7JRO

внимательно посмотрите на свой код и попытайтесь выяснить, почему он отображает экран №1, @jsotola


3 ответа


Лучший ответ:

-1

Я не увидел проблем в коде, но, возможно, я что-то упустил из виду.

Возможно, проблема не в коде, а в оборудовании. Вы убедились, что вход подключен к GND, если кнопка не нажата?

Примечания и предупреждения

Если контакт ни к чему не подключен, digitalRead() может возвращать либо HIGH, либо LOW (и это может меняться случайным образом).

https://www.arduino.cc/reference/en/language/functions/digital-io/digitalread/

Я предлагаю вам использовать serial для отображения значения buttonState после этой строки

buttonState = digitalRead(buttonPin);

Возможно, это не то, что вы ожидаете.

,

это не применимо. у него INPUT_PULLUP, @Juraj

Я изменил режим ввода на INPUT и добавил Serial.print(buttonState); но он печатает только 0, даже когда я нажимаю кнопку. Есть ли какие-нибудь подсказки, почему это может быть?, @FoxxTech

Поэтому я поменял сторону, с которой провод подключался к контакту 2, и теперь он показывает 1, когда я не нажимаю кнопку, и 0, когда нажимаю., @FoxxTech

Хорошо, что вы нашли проблему. Иногда мы забываем дважды проверить мелочи (их соединения) и концентрируемся только на коде..., @Edgar


1

У вас есть pinMode(buttonPin, INPUT_PULLUP);, поэтому я предполагаю, что вы подключили кнопку между выводом и землей. При подтягивании вывод будет считываться как HIGH, если он не заземлен. Если кнопка нажата, заземление кнопки подтянет ее к LOW. Поэтому вам следует проверить, нажата ли кнопка, сравнивая ее с LOW.

У нас в головах есть эта вводящая в заблуждение идея, что активное — это ВЫСОКОЕ, а неактивное — НИЗКОЕ. Но вы можете увидеть это так:

  • кнопка нажата (низко) — НИЗКО
  • кнопка не нажата, показание HIGH
,

0

Я исправил проблему. Оказалось, что возвращаемое кнопкой значение было 1, когда она не была нажата, и 0, когда она была нажата. Мой новый код:

#include <OLED_I2C.h>

OLED  myOLED(SDA, SCL, 8);

extern uint8_t SmallFont[];
extern uint8_t MediumNumbers[];
extern uint8_t BigNumbers[];

//константы:
const int buttonPin = 2;
const int debug = 0;

//переменные:
int screenNumber = 0;
byte buttonState = 0;

void setup()
{
  myOLED.begin();
  myOLED.setFont(SmallFont);
  pinMode(buttonPin, INPUT);
  myOLED.clrScr();
  myOLED.print("TIME", CENTER, 16);
  myOLED.update();
  Serial.begin(9600);
}

void loop() { //myOLED.print() форматирует с (string, text_placement, pixel_location)
  // считываем входной контакт кнопки:
  buttonState = digitalRead(buttonPin);
  Serial.println(buttonState);
  if (debug == 1) {
    myOLED.clrScr();
    myOLED.print("Start", CENTER, 16);
    myOLED.update();
    delay(debugDelay);
  }
  // сравнить buttonState с его предыдущим состоянием
  if (buttonState == 0) {
    if (screenNumber < 2) {
      screenNumber = screenNumber + 1;
    }
    else {
      screenNumber = 0;
      }
    //немного задержитесь, чтобы избежать подпрыгивания
    delay(100);
    }

  //Проверяем переменную screenNumber и меняем ее на
  //согласно экрану

  if (screenNumber == 0) {
    myOLED.clrScr();
    myOLED.print("TIME", CENTER, 16);
    myOLED.update();
  }
  else if (screenNumber == 1) {
    myOLED.clrScr();
    myOLED.print("TEMPERATURE", CENTER, 16);
    myOLED.update();
  }
  else if (screenNumber == 2) {
    myOLED.clrScr();
    myOLED.print("DIRECTION", CENTER, 16);
    myOLED.update();
  }
  else {
    myOLED.clrScr();
    myOLED.print("ERROR", CENTER, 16);
    myOLED.update();
  }
}
,

и что я написал в своем ответе? вы приняли неправильный ответ, @Juraj

Эдгар сказал мне использовать Serial.print(), чтобы узнать значение кнопки. Это помогло мне больше. Если бы вы просто сказали, что это инверсия того, что я ожидал, это имело бы больше смысла., @FoxxTech