Масив в меню

Igoreck
Offline
Зарегистрирован: 01.03.2017

День добрый.

Не могу привязать курсор выбора меню в масиве.

Помогите!

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET     4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const char string_1[] PROGMEM = "setting1";
const char string_2[] PROGMEM = "setting2";
const char string_3[] PROGMEM = "setting3";
const char string_4[] PROGMEM = "setting4";
const char * menu_table[] = {string_1, string_2, string_3, string_4};
//==============================================================
#define CLK 5
#define DT 6
#define SW 4
#include "GyverEncoder.h"
#define PRECISE_ALGORITHM
Encoder enc1(CLK, DT, SW, TYPE1);
//+++++++++++++++++++++++++++++++++++++++++++
byte menuPos = 1;
byte mode ;
void setup() {
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    for(;;);
  }
}
void loop() {
 enc1.tick();
 updatedisplay();  
  if (enc1.isClick())Menu();
}
void printMenu (byte menuPos) {
  byte i;
  display.clearDisplay();
  for (i = 0; i < 5; i++ )
    display.setCursor(0, menuPos);
    display.print(">");
  //  display.drawRect(5, 5, 80, 20, WHITE);// Указатель в виде прямоугольной рамки
  display.display();
}
void Menu() {
 while(1){
      enc1.tick();
    //***************************** Выбор позиции в меню ***********************
    if (enc1.isRight()){menuPos = menuPos + 1;}    
    if (menuPos > 4){menuPos = 1;}
    if (enc1.isLeft()){menuPos = menuPos - 1;}     
    if (menuPos < 1){menuPos = 4;}
    printMenu(menuPos);
    if (enc1.isClick()){
      switch  (menuPos) {
        case 1: setting1(); break;
        case 2: setting2(); break;
        case 3: setting3(); break;
        case 4: setting4(); return;
       }
    }
  }
}
void setting1() {
}
void setting2() {    
}
void setting3() { 
}
void setting4() {
}
void updatedisplay() {  

 

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

и в каком месте у вас сложности?

 

ЗЫ условия строчек 49 и 51 логичнее было бы запихнуть внутрь соответвующих инкрементов энкодера на строчку выше

Igoreck
Offline
Зарегистрирован: 01.03.2017

Когда захожу в "Menu" то там только курсор в виде ">", он перемещается верх и вниз, но нет списка из масива!

Короче надо как-то пришить масив в функцию "void printMenu (byte menuPos)", если я прав!?

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

а причем тут курсор?

Покажите мне, где в вашем коде вы выводите строчки Меню на печать? - этого нет.

В процедуре PrintMenu() вы печатаете на экране только ">" - так чему удивлятся. что только это вы на экране и видите?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Igoreck пишет:

Помогите!

Ну, "пожалуйста" было лишним, мы и без него обязаны помогать каждому, кто, ни буквы не понимая, решил поправить код от AlexGyver, правда?

В оригинале Ваша функция printMenu называлась printPointer и выводила именно курсор / указатель.

Что заставило Вас думать, что стоит только переименовать её в printMenu, как она сразу же начнёт и текст меню печатать?

И почему Вы не просите помощи у автора?

Igoreck
Offline
Зарегистрирован: 01.03.2017

раньше у меня работало только с библиотекой OLED_I2C.
Сейчас я хочу использовать от адафрут, и неполучается с етой функцией.
Помогите пожалуйста.

void printMenu (byte invertLine) {
  byte i;
  myOLED.clrScr();
  for (i = 0; i < 5; i++ )
  { if (i == (invertLine - 1)) myOLED.invertText(true);
    myOLED.print((const __FlashStringHelper *) menu_table[i] , 2, i * 10);
    if (i == (invertLine - 1)) myOLED.invertText(false);
  }
  myOLED.update();
}

 

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

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

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

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

Не очищайте экран!

В п/п печатьменю передавайте 2 значения - предыдущее (куда Вы запишите пробел) и текущее (куда Вы запишите ">").

Должно заработать.

Igoreck
Offline
Зарегистрирован: 01.03.2017

Помогите пожалуйста.

Ну пожалуйста!!!

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

А как Вы себе представляете эту помощь?

Igoreck
Offline
Зарегистрирован: 01.03.2017

andriano пишет:

А как Вы себе представляете эту помощь?

Наверное многое прошу!

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Igoreck пишет:

Помогите пожалуйста.

Ну пожалуйста!!!

Ты наерна невнимательно прочитал.  Пока сам не начнёшь что-то делать, никто тебе не поможет. 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

"Если вы тупой то записывайте - я же записываю"

Возьмите свой код и начиная с 25 строки напишите комментарий - что делает данная строка ...

Может это поможет понять вам что вы делаете не так - нам всё понятно !!!

Igoreck
Offline
Зарегистрирован: 01.03.2017

Komandir пишет:

"Если вы тупой то записывайте - я же записываю"

Возьмите свой код и начиная с 25 строки напишите комментарий - что делает данная строка ...

Может это поможет понять вам что вы делаете не так - нам всё понятно !!!

Не обзывайся!

Все такие умные, а объяснить толком не можете. Вы наверное сразу после прочтения книги стали писать методы,  ООП, или есчё чтото сложное, не важно.

Важно то, что для меня пока это кусок наброска кода, сложный. И я пока учусь этому всему. 

Просто я зашел на форум, за помощью. Так как форум для меня пока, это единственный "учитель". А Вы бросили без зубому старику кость, и мол на поеш, ты же у нас голодный, только смотри не обляпайся.

 

Мне  как новичку, ктото может объяснить что здесь происходит и как переделать это под простой курсор типа ">":

void printMenu (byte invertLine) {
  byte i;
  myOLED.clrScr();
  for (i = 0; i < 4; i++ )
  { if (i == (invertLine - 1)) myOLED.invertText(true);
    myOLED.print((const __FlashStringHelper *) menu_table[i] , 2, i * 10);
    if (i == (invertLine - 1)) myOLED.invertText(false);
  }
  myOLED.update();
}

 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

ИМХО выбранный пункт меню выводится с инверсией, а остальные без инверсии. 

В пятой myOLED.invertText(true); заменить на myOLED.print("> ",...); ... заменить на нужные параметры.

Седьмую закомментировать целиком.

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

Igoreck пишет:

Мне  как новичку, ктото может объяснить что здесь происходит и как переделать это под простой курсор типа ">":

void printMenu (byte invertLine) {
  byte i;
  myOLED.clrScr();
  for (i = 0; i < 4; i++ )
  { if (i == (invertLine - 1)) myOLED.invertText(true);
    myOLED.print((const __FlashStringHelper *) menu_table[i] , 2, i * 10);
    if (i == (invertLine - 1)) myOLED.invertText(false);
  }
  myOLED.update();
}

Судя по коду. эта процедура печатает меню из 4х строк, выделяя цветом ту, номер которой соответвует значению invertLine

Построчно:

строка 3 - чистим экран

строка - 4 цикл от 0 до 3х (судя по всему, в меню 4 строки?)

строка 5 - если текущая строка та самая, которую надо выделить - включаем выделение

строка 6 - печатаем строчку меню

строка 7 - выключаем выделение

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Igoreck наброска кода, сложный

Может начать всё таки с "поморгать диодом" ?

Igoreck
Offline
Зарегистрирован: 01.03.2017

Komandir пишет:

ИМХО выбранный пункт меню выводится с инверсией, а остальные без инверсии. 

В пятой myOLED.invertText(true); заменить на myOLED.print("> ",...); ... заменить на нужные параметры.

Седьмую закомментировать целиком.

Хорошо! А какие параметры и в каком формате и порядке.

Igoreck
Offline
Зарегистрирован: 01.03.2017

Komandir пишет:

Igoreck наброска кода, сложный

Может начать всё таки с "поморгать диодом" ?

Это я уже делал. Получилось.

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

Igoreck пишет:

как переделать это под простой курсор типа ">":

в строке 5 вместо инвертирования текста печаетем ">" если это выделенная строка, во всех остальных печаетм пробел.

Конкретный код не пишу. потому что не помню точно операторов либы Адафруит

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Параметры - координаты как вот тут - myOLED.print((const __FlashStringHelper *) menu_table[i] , 2, i * 10);

Я же не знаю в каком месте вам нужна ">"

Igoreck
Offline
Зарегистрирован: 01.03.2017

Komandir пишет:

Параметры - координаты как вот тут - myOLED.print((const __FlashStringHelper *) menu_table[i] , 2, i * 10);

Я же не знаю в каком месте вам нужна ">"

Вот так чтоли:


#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET     4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const char string_1[] PROGMEM = "setting1";
const char string_2[] PROGMEM = "setting2";
const char string_3[] PROGMEM = "setting3";
const char string_4[] PROGMEM = "setting4";
const char * menu_table[] = {string_1, string_2, string_3, string_4};
//==============================================================
#define CLK 5
#define DT 6
#define SW 4
#include "GyverEncoder.h"
#define PRECISE_ALGORITHM
Encoder enc1(CLK, DT, SW, TYPE1);
//+++++++++++++++++++++++++++++++++++++++++++
byte menuPos = 1;
byte mode ;
byte invertLine;
void setup() {
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    for(;;);
  }
}
void loop() {
 enc1.tick();
 updatedisplay();  
  if (enc1.isClick())Menu();
}
void printMenu (byte * menu_table[]) {
  byte i;
  display.clearDisplay();
  for (i = 0; i < 5; i++ )
   { if (i == (invertLine - 1)) display.print(">",(const __FlashStringHelper *) menu_table[i] , 2, i * 10);
    //display.print((const __FlashStringHelper *) menu_table[i] , 2, i * 10);
    //if (i == (invertLine - 1)) display.invertText(false);
  }
  display.display();
}
void Menu() {
 while(1){
      enc1.tick();
    //***************************** Выбор позиции в меню ***********************
    if (enc1.isRight()){menuPos = menuPos + 1;}    
    if (menuPos > 4){menuPos = 1;}
    if (enc1.isLeft()){menuPos = menuPos - 1;}     
    if (menuPos < 1){menuPos = 4;}
    printMenu(menuPos);
    if (enc1.isClick()){
      switch  (menuPos) {
        case 1: setting1(); break;
        case 2: setting2(); break;
        case 3: setting3(); break;
        case 4: setting4(); return;
       }
    }
  }
}
void setting1() {
}
void setting2() {    
}
void setting3() { 
}
void setting4() {
}
void updatedisplay() {  
    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(SSD1306_WHITE);
    display.setCursor(35, 25); 
    display.print("OLED_Menu");
    display.display(); 
}

Пишет: 

no matching function for call to 'Adafruit_SSD1306::print(const char [2], const __FlashStringHelper*, int, int)'

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Нет.

36 void printMenu (byte * menu_table[]) {

Это что за отсебятина ??????????????????????????????????????????

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Igoreck пишет:

Пишет: 

no matching function for call to 'Adafruit_SSD1306::print(const char [2], const __FlashStringHelper*, int, int)'

Вы знаете, литературные слова уже заканчиваются. Ну, сделайте же Вы то, что Вам ещё в #6 сказали.

Igoreck
Offline
Зарегистрирован: 01.03.2017

Komandir пишет:

Нет.

36 void printMenu (byte * menu_table[]) {

Это что за отсебятина ??????????????????????????????????????????

Извените, просто я уже сплю над этим кодом.

Вот так:


#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET     4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const char string_1[] PROGMEM = "setting1";
const char string_2[] PROGMEM = "setting2";
const char string_3[] PROGMEM = "setting3";
const char string_4[] PROGMEM = "setting4";
const char * menu_table[] = {string_1, string_2, string_3, string_4};
//==============================================================
#define CLK 5
#define DT 6
#define SW 4
#include "GyverEncoder.h"
#define PRECISE_ALGORITHM
Encoder enc1(CLK, DT, SW, TYPE1);
//+++++++++++++++++++++++++++++++++++++++++++
byte menuPos = 1;
byte mode ;
byte invertLine;
void setup() {
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    for(;;);
  }
}
void loop() {
 enc1.tick();
 updatedisplay();  
  if (enc1.isClick())Menu();
}
void printMenu (byte invertLine) {
  byte i;
  display.clearDisplay();
  for (i = 0; i < 5; i++ )
   { if (i == (invertLine - 1)) display.print(">",(const __FlashStringHelper *) menu_table[i] , 2, i * 10);
    //display.print((const __FlashStringHelper *) menu_table[i] , 2, i * 10);
    //if (i == (invertLine - 1)) display.invertText(false);
  }
  display.display();
}
void Menu() {
 while(1){
      enc1.tick();
    //***************************** Выбор позиции в меню ***********************
    if (enc1.isRight()){menuPos = menuPos + 1;}    
    if (menuPos > 4){menuPos = 1;}
    if (enc1.isLeft()){menuPos = menuPos - 1;}     
    if (menuPos < 1){menuPos = 4;}
    printMenu(menuPos);
    if (enc1.isClick()){
      switch  (menuPos) {
        case 1: setting1(); break;
        case 2: setting2(); break;
        case 3: setting3(); break;
        case 4: setting4(); return;
       }
    }
  }
}
void setting1() {
}
void setting2() {    
}
void setting3() { 
}
void setting4() {
}
void updatedisplay() {  
    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(SSD1306_WHITE);
    display.setCursor(35, 25); 
    display.print("OLED_Menu");
    display.display(); 
}

Дык свёрамно: 

no matching function for call to 'Adafruit_SSD1306::print(const char [2], const __FlashStringHelper*, int, int)'

Igoreck
Offline
Зарегистрирован: 01.03.2017

ЕвгенийП пишет:

Igoreck пишет:

Пишет: 

no matching function for call to 'Adafruit_SSD1306::print(const char [2], const __FlashStringHelper*, int, int)'

Вы знаете, литературные слова уже заканчиваются. Ну, сделайте же Вы то, что Вам ещё в #6 сказали.

Так теперь с Вами.

Убрать прогмем, а масив оставить или как? 

Уточните пожалуйста!

const char string_1[] PROGMEM = "setting1";
const char string_2[] PROGMEM = "setting2";
const char string_3[] PROGMEM = "setting3";
const char string_4[] PROGMEM = "setting4";
const char * menu_table[] = {string_1, string_2, string_3, string_4};
Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

myOLED.print("> ",100,i*10)

и раскомментируйте 41

Igoreck
Offline
Зарегистрирован: 01.03.2017

Komandir пишет:

myOLED.print("> ",100,i*10)

и раскомментируйте 41


#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET     4
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const char string_1[] PROGMEM = "setting1";
const char string_2[] PROGMEM = "setting2";
const char string_3[] PROGMEM = "setting3";
const char string_4[] PROGMEM = "setting4";
const char * menu_table[] = {string_1, string_2, string_3, string_4};
//==============================================================
#define CLK 5
#define DT 6
#define SW 4
#include "GyverEncoder.h"
#define PRECISE_ALGORITHM
Encoder enc1(CLK, DT, SW, TYPE1);
//+++++++++++++++++++++++++++++++++++++++++++
byte menuPos = 1;
byte mode ;
byte invertLine;
void setup() {
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    for(;;);
  }
}
void loop() {
 enc1.tick();
 updatedisplay();  
  if (enc1.isClick())Menu();
}
void printMenu (byte invertLine) {
  byte i;
  display.clearDisplay();
  for (i = 0; i < 5; i++ )
   { if (i == (invertLine - 1)) display.print("> ",100,i*10);
    display.print((const __FlashStringHelper *) menu_table[i] , 2, i * 10);
    //if (i == (invertLine - 1)) display.invertText(false);
  }
  display.display();
}
void Menu() {
 while(1){
      enc1.tick();
    //***************************** Выбор позиции в меню ***********************
    if (enc1.isRight()){menuPos = menuPos + 1;}    
    if (menuPos > 4){menuPos = 1;}
    if (enc1.isLeft()){menuPos = menuPos - 1;}     
    if (menuPos < 1){menuPos = 4;}
    printMenu(menuPos);
    if (enc1.isClick()){
      switch  (menuPos) {
        case 1: setting1(); break;
        case 2: setting2(); break;
        case 3: setting3(); break;
        case 4: setting4(); return;
       }
    }
  }
}
void setting1() {
}
void setting2() {    
}
void setting3() { 
}
void setting4() {
}
void updatedisplay() {  
    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(SSD1306_WHITE);
    display.setCursor(35, 25); 
    display.print("OLED_Menu");
    display.display(); 
}

Пишет:

no matching function for call to 'Adafruit_SSD1306::print(const char [3], int, int)'
 
Но с библиотекой OLED_I2C - заработало, а у меня то проэкт, заточен под Adafruit_SSD1306!
 
Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018
void printMenu (byte invertLine) {
  byte i;
  display.clearDisplay();
  for (i = 0; i < 5; i++ ) {
    display.setcursor(2, i*10);
    if (i == (invertLine - 1)) display.print(">")
    else display.print(" ");
    display.print((const __FlashStringHelper *) menu_table[i]);
  }
  display.display();
}

 

Igoreck
Offline
Зарегистрирован: 01.03.2017

Товарищ командир!

Разрешите доложить.

Код уже заработал, низкий Вам поклон и спасибо, только в конце списка меню мусор на экране!

Попробую фото прикрепить.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

04

for (i = 0; i < 5; i++ ) { меняем на for (i = 0; i < 4; i++ ) {

у вас еще и с арифметикой для первого класса беда !!!

Igoreck
Offline
Зарегистрирован: 01.03.2017

Komandir пишет:

04

for (i = 0; i < 5; i++ ) { меняем на for (i = 0; i < 4; i++ ) {

у вас еще и с арифметикой для первого класса беда !!!

я знаю!

Igoreck
Offline
Зарегистрирован: 01.03.2017

Всё, алилуя.

Всем спасибо (Командиру аплодирую стоя) , тема закрыта, дальше я буду пробовать сам.

Всем удачи, да прибудет с вами сила.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Igoreck пишет:

Убрать прогмем, а масив оставить или как? 

Уточните пожалуйста!

даже так вопрос стоит? :-(

Тогда никак не надо.

Послушайте реального доброго совета: начните с изучения языка и простых учебных задач, которые выполняйте при изучении. Месяца через три Вам начнёт казаться, что Вы такие коды, как у Вас сейчас понимаете. Через полгода, Вы действительно начнёте в них что-то понимать, а через год будете нормально их делать. Такие вещи нужно целенаправленно изучать. Подход "посмотрю на пример, почешу репу, попробую что-нибудь поменять и разберусь" тут не работает - нужны базовые знания.

Сейчас же, Вы там ни одной буквы толком не понимаете. Даже если Komandir напишет Вам, всё, что Вам надо - радость Ваша будет недолгой, ровно до того момента, когда потребуется написать что-то ещё. 

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

Igoreck пишет:

дальше я буду пробовать сам.

так я и поверил...

По новой проблеме - опять будете на коленках ползать и сопли размазывать: "П-а-м-агитяя! У-м-оляю!!"