gyver menu

r4wabr

★✩✩✩✩✩✩
21 Май 2019
52
16
42
Ижевск
Всем привет. Есть одна закавыка с библиотекой gyver Menu. Никак не получается использовать кирилицу в меню. Может кто сталкивался и проблема уже кем-то решена?
 

Bruzzer

★★★★✩✩✩
23 Май 2020
708
219
@r4wabr,
Непонятно в чем у вас проблема, поясните. Если вы умеете выводить кириллицу на экран, то и с меню ВРОДЕ проблем быть не должно.

На всякий случай, для простого меню есть другая более старая библиотека с примером с кириллицей GyverOLEDMenu
 

r4wabr

★✩✩✩✩✩✩
21 Май 2019
52
16
42
Ижевск
При попытке вывода кирилицы искажаются коды символов и между буквами лишний символ появляется.

Тут должно быть слово "Пуск"
 

Вложения

bort707

★★★★★★✩
21 Сен 2020
3,319
963
между буквами лишний символ появляется.
наверно потому что кириллица в utf, а там 2 байта на символ.
@r4wabr, давайте сначала - вы хоть что-то в коде понимаете? Знаете, чем отличается 8битная кодировка от 16битной?
 

r4wabr

★✩✩✩✩✩✩
21 Май 2019
52
16
42
Ижевск
наверно потому что кириллица в utf, а там 2 байта на символ.
@r4wabr, давайте сначала - вы хоть что-то в коде понимаете? Знаете, чем отличается 8битная кодировка от 16битной?
Конечно.

Думаю проблема из-за этой строчки.

C++:
#include <Arduino.h>

#include <LCDI2C_Multilingual.h>
#include <GyverMenu.h>
#include <GyverButton.h>
#include <OneWire.h>
#include <MsTimer2.h>
#include <EEPROM.h>
#include <StringN.h>

//Определение пинов
#define LED_RED 8
#define LED_GRN 10
#define OUT1 5
#define OUT2 6
#define ZERO 2
#define BUZZER 9
#define KEYB A0
#define DS18B20 7

//Таймоут датчика перегрева
#define OTHERHEAT_TIME 3000

//Определения включения и выключения выходов и индикации
#define LRED_ON digitalWrite(LED_RED,HIGH)
#define LRED_OFF digitalWrite(LED_RED,LOW)
#define LGRN_ON  digitalWrite(LED_GRN,HIGH)
#define LGRN_OFF digitalWrite(LED_GRN,LOW)
#define OUT1_ON digitalWrite(OUT1,HIGH)
#define OUT1_OFF digitalWrite(OUT1,LOW)
#define OUT2_ON digitalWrite(OUT2,HIGH)
#define OUT2_OFF digitalWrite(OUT2,LOW)
#define T_ALERT tone(BUZZER,1000,400)
#define T_NO noTone(BUZZER)

//Режимы нагрева
#define ONE_HEAT  0
#define TWO_HEAT  1
#define AUTO_HEAT 2

//Переменная таймера перегрева
unsigned long timer_overhert=0;

//Перечисление функций клавиш
enum BUTT_FUNC {
  BUT_LEFT,
  BUT_RIGHT,
  BUT_UP,
  BUT_DOWN,
  BUT_OK
};

struct CONFIG {
  int temp;
  bool OVH;
  uint8_t mode;
  int dt;
} cfg;

GButton butt[5];
GyverMenu menu(16, 2);
OneWire ds(DS18B20);
LCDI2C_Russian lcd(0x27, 16, 2);

int temperature = 10;               // Глобальная переменная для хранения значение температуры с датчика DS18B20
long lastUpdateTime = 0;            // Переменная для хранения времени последнего считывания с датчика
const int TEMP_UPDATE_TIME = 1000;  // Определяем периодичность проверок готовности данных DS18B20
bool OVH_ERROR=false;               // Флаг ошибки перегрева;
bool isMenu=false;
bool isWork=false;
uint8_t H=1;

//Сброс таймера перегрева по прерыванию
void zero(void) {
  timer_overhert=millis();
  OVH_ERROR=false;
}

// ---------------------
bool detectTemperature(void);
void flash(void);
String utf8rus(String);
// ---------------------

void setup() {

  if(EEPROM.read(0)==1) {
    EEPROM.get(1,cfg);
  } else {
    //Данные тестового меню
    cfg.OVH=true;
    cfg.mode=AUTO_HEAT;
    cfg.temp=30;
    cfg.dt=2;
    EEPROM.write(0,1);
    EEPROM.put(1,cfg);
  }
    
  Serial.begin(57600);
  //Подключение прерывания
  attachInterrupt(0, &zero, CHANGE);
 
  //Таймер для мигания светодиодом
  MsTimer2::set(200, flash);    //  период
  MsTimer2::start();
  interrupts();
  //Инициализация дисплея
  lcd.init();
  lcd.backlight();

  //Настройка выходов
  pinMode(ZERO,INPUT_PULLUP);  // Вход сигнала датчика перегрева
  pinMode(LED_RED,OUTPUT);     // Выход на красный светодиод
  pinMode(LED_GRN,OUTPUT);     // Выход на зеленый светодиод
  pinMode(OUT1,OUTPUT);        // Выход на реле 1
  pinMode(OUT2,OUTPUT);        // Выход на реле 2
  pinMode(BUZZER,OUTPUT);      // Выход на бузер
 
  //Меню - ТЕСТ
    menu.onPrint([](const char* str, size_t len) {
        if (str) lcd.Print::write(str, len);
        
    });
    menu.onCursor([](uint8_t row, bool chosen, bool active) -> uint8_t {
        lcd.setCursor(0, row);
        lcd.print(chosen && !active ? '>' : ' ');
        return 1;
    });

    menu.onBuild([](gm::Builder& b) {
        
        if(!isWork && !OVH_ERROR) { b.Button("Run" , []() {if(temperature<cfg.temp){ lcd.clear(); isMenu=false; isWork=true;}}); } else {
            b.Button("Stop" , []() {OUT1_OFF; OUT2_OFF; lcd.clear(); isMenu=false; isWork=false;});
        }
        b.Switch("Buzzer", &cfg.OVH, [](bool v) { Serial.println(v); });
       // b.ValueStr("ValueStr", "foo");
       // b.Label("Some line");
        b.Select("Mode", &cfg.mode,"Low;High;Auto", [](uint8_t n, const char* str, uint8_t len) { Serial.print(n); Serial.print("-"); Serial.write(str, len);  });
        b.ValueInt<int>("Temp", &cfg.temp, 0, 90, 10, DEC, "C", [](int v) { Serial.println(v); });
        b.ValueInt<int>("dT", &cfg.dt, 0, 5, 1, DEC, "C", [](int v) { Serial.println(v); });
       // b.ValueFloat("ValueFloat", &valf, -5, 5, 0.25, 3, "mm", [](float v) { Serial.println(v); });
        b.Button("Save", []() { EEPROM.put(1,cfg); menu.home(); });
        b.Button("Reset", []() { cfg.OVH=true; cfg.mode=AUTO_HEAT; cfg.temp=30; cfg.dt=2; EEPROM.put(1,cfg); menu.home(); });
        b.Button("Exit", []() {  isMenu=false; lcd.clear(); }); 
    });

   // menu.refresh();
    
}

void loop() {
 
 { // Опрос кнопок

  int analog=analogRead(KEYB);
  butt[BUT_OK].tick(analog < 800 && analog > 600);
  butt[BUT_RIGHT].tick(analog < 600 && analog > 400);
  butt[BUT_DOWN].tick(analog < 400 && analog > 200);
  butt[BUT_UP].tick(analog < 200 && analog > 100);
  butt[BUT_LEFT].tick(analog < 100 && analog > 0);

 }
  
  //Вывод температуры
  if(!isMenu){
    if(detectTemperature()) {
   lcd.setCursor(0,0);
   lcd.print("Температура");
   lcd.setCursor(12,0);
   lcd.print(temperature);
   }
   if(isWork && !OVH_ERROR) {
      LGRN_ON;
      lcd.setCursor(0,1);
      switch (cfg.mode) {
        case ONE_HEAT:
          lcd.print("Нагрев T1 > "); lcd.print(cfg.temp);
          OUT1_ON;
          OUT2_OFF;
          break;
        case TWO_HEAT:
          lcd.print("Нагрев T2 > "); lcd.print(cfg.temp);
          OUT1_ON;
          OUT2_ON;
          break;
        case AUTO_HEAT:
          lcd.print("Нагрев авто > "); lcd.print(cfg.temp);
          if(temperature < cfg.temp/2 ){
            OUT1_ON;
            OUT2_ON;
          } else {
            OUT1_ON;
            OUT2_OFF;
          }
          break; 
        default:
          break; 
      }
      
      if(temperature > cfg.temp) {isWork=false;}
    } else {
      LGRN_OFF;
      lcd.setCursor(0,1);
      lcd.print("Нагрев выкл."); if(OVH_ERROR)lcd.print("-OVH");
      OUT1_OFF;
      OUT2_OFF;
    }
  }
    
    // Навигация по меню
    if (butt[BUT_OK].isClick()) {if (!isMenu) {menu.refresh(); isMenu=true;} else {menu.set();}}
    if (butt[BUT_UP].isClick() && isMenu) menu.up();
    if (butt[BUT_DOWN].isClick() && isMenu) menu.down();
    if (butt[BUT_LEFT].isClick() && isMenu) menu.left();
    if (butt[BUT_RIGHT].isClick() && isMenu) menu.right();

  // Проверка на сработку датчика перегрева
  if((millis()-timer_overhert) > OTHERHEAT_TIME) {
  // OVH_ERROR=true;
    
  }
 
}

bool detectTemperature(){
  static int last_temp;
  int temp;

  byte data[2];
  ds.reset();
  ds.write(0xCC);
  ds.write(0x44);

  if (millis() - lastUpdateTime > TEMP_UPDATE_TIME)
  {
    lastUpdateTime = millis();
    ds.reset();
    ds.write(0xCC);
    ds.write(0xBE);
    data[0] = ds.read();
    data[1] = ds.read();

    //Формируем значение
    temp = (data[1] << 8) + data[0]; temp = temp >> 4;
    if (abs(temp-last_temp)>cfg.dt) {
      last_temp=temp;
      temperature=temp;
      }
      return true;
  }
  return false;
}

//Мигание светодиодами
void flash(void) {
  static bool lred=false;
  if(OVH_ERROR){
    lred=!lred;
    if(cfg.OVH) lred ? T_ALERT: T_NO;
    digitalWrite(LED_RED,lred);
  } else {
    LRED_OFF;
    T_NO;
  }
}