Некорректно выводится текст на дисплей

Савелий
Offline
Зарегистрирован: 26.10.2019
#define ENC_TYPE TYPE2
#define CLK 2
#define DT 3
#define SW 4
#define OLED_MOSI   9
#define OLED_CLK   10
#define OLED_DC    11
#define OLED_CS    12
#define OLED_RESET 13

#include "GyverEncoder.h"
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>


Encoder enc1(CLK, DT, SW);  // для работы c энкодером
Adafruit_SSD1306 display(128, 64, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); // Для работы с дисплеем

static const PROGMEM uint8_t image_data_Image3[1024] = {}; // Тут была заставка, убрал, чтобы удобнее было читать код

int value[3];         // Значения настроек
const int lenght = 4; // Количество пунктов в меню
int cursor_disp;      // Выбранный пункт меню
bool state_setting;   // Мы сейчас находимя в меню настроек?

void setup() {
  Serial.begin(115200);                                           // Открываем соединение с компьютером (необходимо для отладки)

  enc1.setType(ENC_TYPE);                                         // Установка типа энкодера

  display.begin(SSD1306_SWITCHCAPVCC);                            // Инициализируем дисплей
  display.cp437(true);                                            // Необходимо для корректного вывода русских символов на дисплей

  display.clearDisplay();                                         // Очищаем дисплей
  display.drawBitmap(0, 0, image_data_Image3, 128, 64, 1);        // Выводим заставку-картинку
  display.display();                                              // Отправляем на дисплей (обновляем)

}

void loop() {

  enc1.tick();                                    // Обрабатываем энкодер

  if (enc1.isRight()) {                           // Если повернули вправо
    if (state_setting) {                          // Если сейчас идет отображение меню настроек
      cursor_disp++;                              // Передвигаем курсор
      if (cursor_disp == lenght) {                // Если вылезли за пределы
        cursor_disp--;                            // Возвращаем курсор
      }
    }
  }

  if (enc1.isLeft()) {                            // Если повернули влево
    if (state_setting) {                          // Если сейчас идет отображение меню настроек
      cursor_disp--;                              // Передвигаем курсор
      if (cursor_disp == -1) {                    // Если вылезли за пределы
        cursor_disp = 0;                          // Возвращаем
      }
    }
  }

  if (enc1.isRightH()) {                          // Если крутим вправо + удержание
    if (state_setting) {                          // Если сейчас идет отображение меню настроек
      if (cursor_disp != 0) {                     // Если хотим что-то изменить
        value [cursor_disp - 1]++;                // Меняем
      }
    }
  }

  if (enc1.isLeftH()) {                           // Если крутим влево + удержание
    if (state_setting) {                          // Если сейчас идет отображение меню настроек
      if (cursor_disp != 0) {                     // Если хотим что-то изменить
        value [cursor_disp - 1]--;                // Меняем
      }
    }
  }

  if (enc1.isClick()) {

  }

  if (enc1.isSingle()) {
    if (state_setting) {
      if (cursor_disp == 0) {
        state_setting = false;
        display.clearDisplay(); // Очищаем дисплей
        display.setTextSize(1);
        display.setTextColor(WHITE);
        display.setCursor (0, 0);
        display.println (rus("Основной экран - в разработке"));
        display.display ();
      }
    }
  }

  if (enc1.isDouble()) {
    if (!state_setting) {
      state_setting = true;
    }
  }

  if (enc1.isHolded()) {

  }

  if (enc1.isTurn()) {
    if (state_setting) {
      update_disp ();
    }
  }
}

void update_disp () { // Функция отрисовки на дисплей
  display.clearDisplay(); // Очищаем дисплей
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor (0, 0);

  if (cursor_disp == 0) {
    display.print ((char)26);
  }
  display.println (rus ("Настройки: "));
  if (cursor_disp == 1) {
    display.print ((char)26);
  }
  display.print (rus ("Сон через: "));
  display.println (value [0]);
  if (cursor_disp == 2) {
    display.print ((char)26);
  }
  display.print (rus ("Тип настройки: "));
  display.println (value [1]);
  if (cursor_disp == 3) {
    display.print ((char)26);
  }
  display.print (rus ("Температура: "));
  display.println (value [2]);
  display.display ();
}

Скетч использует 17128 байт (55%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 676 байт (33%) динамической памяти, оставляя 1372 байт для локальных переменных. Максимум: 2048 байт.

Основное меню выводится корректно, но когда перехожу на основной экран (проблемный вывод происходит в 92-ой строке), вместо того, чтобы вывести строку "Основной экран - в разработке" выводится просто "разработке". Почему? Заранее спасибо.

Савелий
Offline
Зарегистрирован: 26.10.2019

Дисплей OLED 4-wire SPI 128x64

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

Думаю, строчка "Основной экран - в разработке" просто слишком длинная для экранчика шириной всего 128 точек. Для проверки попробуйте оставить, например, только надпись "Основной экран" - ставлю на то, что такая надпись выведется правильно

Савелий
Offline
Зарегистрирован: 26.10.2019

Сейчас попробую, но когда я оставляю только инициализацию и вывод текста, текст выводится правильно (занимает 2 строки)

Савелий
Offline
Зарегистрирован: 26.10.2019

Забыл добавить в код функцию rus (в ArduinoIDE она была в отдельном файле)


String rus(const String & source)
{
  int i, k;
  String target;
  unsigned char n;
  char m[2] = { '0', '\0' };

  k = source.length(); i = 0;

  while (i < k) {
    n = source[i]; i++;

    if (n >= 0xC0) {
      switch (n) {
        case 0xD0: {
            n = source[i]; i++;
            if (n == 0x81) {
              n = 0xA8;
              break;
            }
            if (n >= 0x90 && n <= 0xBF) n = n + 0x30;
            break;
          }
        case 0xD1: {
            n = source[i]; i++;
            if (n == 0x91) {
              n = 0xB8;
              break;
            }
            if (n >= 0x80 && n <= 0x8F) n = n + 0x70;
            break;
          }
      }
    }
    m[0] = n; target = target + String(m);
  }
  return target;
}

 

Савелий
Offline
Зарегистрирован: 26.10.2019

Да, "Основной экран" вводится корректно, но почему тогда скетч с только инициализацией и выводом длинного текста работает корректно?