• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Budowa Menu - pomoc w kodzie
#1
Witam serdecznie, 
jestem początkujący i walczę aktualnie od kilku dni z tematem menu. 

Układ : Arduino Mega + Ramps + Full Graphic Smart Controller (LCD) . 

Wszystko szło fajnie ale przekopałem masę kodów i nie znalazłem odpowiedzi ani przykładu na którym mógłbym się wzorować. 

W Menu aktualnym wyświetlają mi się dwie 4 linie z napisami :

poz. A : xx cm 
poz. B : yy cm  
Start : OFF / ON 
Home : OFF / ON 

chciałbym osiągnąć małą zmianę. 
Za pomocą enkodera w FGSC wybierać i modyfikować zmienne. 
Dzisiaj kręcąc enkoderem zmieniam parametr poz. A  i  poz. B jednocześnie. 
Wciśnięcie powoduje zmianę START : ON/OFF 

Chciałbym osiągnąć taki efekt :
1. Znacznik/Strzałka przed napisem "poz A" ---> Kliknięcie w przycisk enkodera ---> ruch enkodera zmienia parametr xx cm ---> kliknięcie w przycisk enkodera ---> pojawienie się strzałki przy napisie "poz A"

2. Ruch enkodera ---> znacznik schodzi przy napis "poz. B" i tu mamy tę samą sytuację co w poz. 1 

3/4. i tu znów podobnie jak wyżej  tyle, że po zejściu znacznikiem do "start" lub do "home" po kliknięciu enkodera następuje zmiana z OFF na ON lub odwrotnie 

Będę wdzięczny za pomoc w modyfikacji kodu lub przykład  kodu gdzie osiągnę taką funkcjonalność

Kod:
#include <SPI.h>
#include <U8glib.h>
#include <SD.h>
// Definicja silnika // motor def
#define Z_STEP_PIN         46
#define Z_DIR_PIN          48
#define Z_ENABLE_PIN       62
#define Z_MIN_PIN          18
#define Z_MAX_PIN          19

// Definicje dla wyswietlacza   /// display definie


#define DOGLCD_CS       16
#define DOGLCD_MOSI     17
#define DOGLCD_SCK      23
#define BTN_EN1         31
#define BTN_EN2         33
#define BTN_ENC         35
#define SD_DETECT_PIN   49
#define SDSS            53
#define BEEPER_PIN      37
#define KILL_PIN        41
Sd2Card card;
SdVolume volume;

// INT
int x=0;                                //Offset postion of title 
int kill_pin_status = 1;                //Last read status of the stop pin, start at 1 to ensure buzzer is off
int encoderPos = 1;                     //Current encoder position
int encoderPoss = 1;
int encoder0PinALast;                   //Used to decode rotory encoder, last value
int encoder0PinNow;                     //Used to decode rotory encoder, current value
char posStr[4];                         //Char array to store encoderPos as a string 
char tmp_string[16];
int enc_pin_status;                     //Last read status of the encoder button
int sd_detect_pin_status = true;               //Last read status of the SD detect pin
int scroll_direction=1;                 //Direction of title scroll, 1 right, -1 left
unsigned long previousMillis = 0;       //Previous Millis value
unsigned long currentMillis;            //Current Millis value
const long interval = 1000/3;           //How often to run the display loop, every 1/3 of a second aproximatly
boolean gotsddata = false;
int sdcardinit;
int sdcardtype;
int sdvolumeinit;
int sdvolumefattype;
int predkosc;
unsigned long sdvolumebpc;
unsigned long sdvolumecc;

U8GLIB_ST7920_128X64_1X u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS);

void setup()
{
  //Motor setting
  pinMode(Z_STEP_PIN  , OUTPUT);
  pinMode(Z_DIR_PIN    , OUTPUT);
  pinMode(Z_ENABLE_PIN    , OUTPUT);
  digitalWrite(Z_ENABLE_PIN    , LOW);

// Display settings
  pinMode(SD_DETECT_PIN, INPUT);        // Set SD_DETECT_PIN as an unput
  digitalWrite(SD_DETECT_PIN, HIGH);    // turn on pullup resistors
  pinMode(KILL_PIN, INPUT);             // Set KILL_PIN as an unput
  digitalWrite(KILL_PIN, HIGH);         // turn on pullup resistors
  pinMode(BTN_EN1, INPUT);              // Set BTN_EN1 as an unput, half of the encoder
  digitalWrite(BTN_EN1, HIGH);          // turn on pullup resistors
  pinMode(BTN_EN2, INPUT);              // Set BTN_EN2 as an unput, second half of the encoder
  digitalWrite(BTN_EN2, HIGH);          // turn on pullup resistors
  pinMode(BTN_ENC, INPUT_PULLUP);              // Set BTN_ENC as an unput, encoder button
  digitalWrite(BTN_ENC, HIGH);          // turn on pullup resistors
  u8g.setFont(u8g_font_helvR08);        //Set the font for the display
  u8g.setColorIndex(1);                 // Instructs the display to draw with a pixel on.
}

void loop()
{//Void loop start

predkosc = map(encoderPos, 0, 20, 0, 2000);
if(enc_pin_status==0)
{
  for(int i = 0; i < predkosc; i++)
  {
     digitalWrite(Z_STEP_PIN, HIGH);
    delayMicroseconds(1000);
    digitalWrite(Z_STEP_PIN, LOW);
    delayMicroseconds(1000);
  }
}



/////////////////////============DISPLAY==========/////////////////////////
// Read the encoder and update encoderPos   
  encoder0PinNow = digitalRead(BTN_EN1);
  if ((encoder0PinALast == LOW) && (encoder0PinNow == HIGH) && (kill_pin_status == LOW)) {
    if (digitalRead(BTN_EN2) == LOW) {
      encoderPos++;
    } else {
      encoderPos--;
    }
  }
  encoder0PinALast = encoder0PinNow;

encoder0PinNow = digitalRead(BTN_EN1);
  if ((encoder0PinALast == LOW) && (encoder0PinNow == HIGH) && (kill_pin_status == HIGH)) {
    if (digitalRead(BTN_EN2) == LOW) {
      encoderPoss++;
    } else {
      encoderPoss--;
    }
  }
  encoder0PinALast = encoder0PinNow;



currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    //read the kill pin status
    kill_pin_status = digitalRead(KILL_PIN);
    //read the encoder button status
    enc_pin_status = digitalRead(BTN_ENC);
    //read the SD detect pin status 
    sd_detect_pin_status = digitalRead(SD_DETECT_PIN);
    if (sd_detect_pin_status) {
      gotsddata = false;
    }
 
   
     u8g.firstPage();
    do { 
       draw();
    } while( u8g.nextPage() );
  

    //Update Title position
    x=x+scroll_direction;
    if (x > 40) scroll_direction = -1;
    if (x < 1) scroll_direction = 1;
  }
  /////////////////////============END DISPLAY==========/////////////////////////

}//Void loop stop

void draw(){

 
  u8g.setColorIndex(0);
  u8g.drawBox(0,0,128,64);
  u8g.setColorIndex(1);
 
  u8g.drawStr( 2+x, 10, "NAUKA22");

 
 
  u8g.drawStr( 20, 3*9, "poz.  A:");
 
  sprintf (posStr, "%d""cm", encoderPos);
  u8g.drawStr( 84, 3*9, posStr );

  u8g.drawStr( 20, 4*9, "poz. B:");
   sprintf (posStr, "%d""cm", encoderPoss);
  u8g.drawStr( 84, 4*9, posStr );

  u8g.drawStr( 20, 5*9, "Start:");
  if (enc_pin_status) u8g.drawStr( 84, 5*9, "OFF");
  else u8g.drawStr( 84, 5*9, "ON");

  u8g.drawStr( 20, 6*9, "HOME:");
  if (kill_pin_status) u8g.drawStr( 84, 6*9, "OFF");
  else u8g.drawStr( 84, 6*9, "ON");
 

  u8g.drawFrame(0,0,128,64);
}
 
Odpowiedź
#2
Ja zawsze piszę swoje funkcje,

najprościej zrobić tak że:

mieć zmienną pozycja_menu (gdzie podajemy nr opcji)
zmianą pozycji (strzałki/enkoder czy co chcesz..) zmieniasz wartość pozycja_menu  na odpowiednio większą lub mniejszą...

po wykryciu przycisków/enkodera zmiany przez switch ustalasz co zmieniasz (tj. jaka była wartość pozycja_menu  i zależnie od tego reagujesz na przyciski zmiany)

Ja tak buduję MENU z różnymi poziomami i wieloma funkcjami


poniżej masz przykładowy kod (skopiowany z jednego projektu wiec nie koniecznie czytelny Wink

Kod:
/**************************************************/
/*                    MENU                        */
/**************************************************/
//KONFIG
byte MENU_how_many_options=4; //Ustawienie konfiguracjne...
//-KONFIG


byte MENU_current_option=0;//wybrana opcja
byte MENU_start_option_number=0;//nr opcji początkowej - przy przewijaniu...
byte MENU_option_number=0;//nr opcji - żeby nie podawać na sztywno nr opcji
byte MENU_button_current=0;
byte MENU_submenu=0;

//KONFIG
void MENU_option_draw(char *text,byte pos,bool selected)
{
  int y = (pos) * 10 + 9;

    LCDline(0, (y - 2), 83, (y - 2), 1);

    if (selected)
    {
      LCDsymbol(1, y, 1, 1, 0x11,true);
      LCDString(8, y, text, 1, 0x11,true);
    }
    else
    {
      LCDString(7, y, text, 1, 0x11,true);
      LCDsymbol(1, y, 0, 1, 0x11,true);
    }
}

void MENU_draw(char *text){
  LCDrectangle(0, 0, 83, 47, 1, false);
  LCDString(0, 0, text, 0, 0x11,false);
}

byte MENU_button(void)
{
  byte R=0;
  switch (Button()) {
    case 1:
    R=1;  //left (-)
    break;
    case 2:
    R=2;  //right (+)
    break;
    case 3:
    R=3;  //down (+)
    break;
    case 4:
    R=4;  //up (-)
    break;
    case 0:
    R=10;  //menu
    break;
    case 127:
    R=11;  //ok
    break;
    case 126:
    R=12;  //back
    break;
   
  }
MENU_button_current=R;
  return R;
}
//-KONFIG

 
bool MENU_option(char *text){
  bool R=false;
  byte pos=(MENU_option_number-MENU_start_option_number);//pos to jest nr wiersza na ekranie menu
  if((pos>=0)&&(pos<MENU_how_many_options))//mieszczą sie na ekranie....
  {
    if(MENU_current_option==MENU_option_number){R=true;}
    MENU_option_draw(text,pos,R);//wywołanie funkcji wyświeltającej odpowiednnią opcję
  }
  MENU_current_option++;
  return R;
}


bool MENU_option_submenu(char *text, byte no_submenu)
{
  bool R=MENU_option(text);

  if((MENU_button_current==11)||(MENU_button_current==1)||(MENU_button_current==2))
  {
    MENU_submenu=no_submenu;
  }
  return R;
}


bool MENU_option_integer(char *text, int &value,int value_min=-32768,int value_max=32768, bool value_loop=true)
{
/*  char buffer[13];
  itoa (LCDcontrast, buffer, HEX);
  text=text.replace("#HEX#", buffer);
    itoa (LCDcontrast, buffer, DEC);
  text=text.replace("#HDEC#", buffer);*/
  bool R=MENU_option(text);
  if (R){
    R=false;
  if(MENU_button_current==1)
  {
  value--;
  if(value<value_min)
  {
    if(value_loop)
    {
      value=value_max+value-value_min;
    }
    else
    {
      value=value_min;
    }
  }
  R=true;
  }
  if(MENU_button_current==2)
  {
  value++;
  if(value>value_max)
  {
    if(value_loop)
    {
      value=value-value_max +value_min;
    }
    else
    {
      value=value_max;
    }
  }
  R=true;
  }
 
  }
  return R;
}



bool MENU(void){

  MENU_button(); //Pobieram przycisk
  if(MENU_submenu==0){if(MENU_button_current!=10){return false;} MENU_submenu=1;}  //Funkcja sprawdzająca czy wyświeltić menu

  MENU_draw("    MENU    ");//rysuje menu
           

  switch (MENU_submenu)
  {
     
      case 1:
        MENU_option_submenu("Ustawienia [1]",1);
        MENU_option_submenu("Ustawienia 2  ",2);
        MENU_option_submenu("Ustawienia 3  ",3);
        MENU_option_submenu("Ustawienia 0  ",0);
      break;
        case 2:
        MENU_option_submenu("Ustawienia 1  ",1);
        MENU_option_submenu("Ustawienia [2]",2);
        MENU_option_submenu("Ustawienia 3  ",3);
        MENU_option_submenu("Ustawienia 0  ",0);
      break;
        case 3:
        MENU_option_integer("integer #HEX#",LCDcontrast);
      if(MENU_option_integer("integer #DEC#",LCDcontrast)){LcdInitialise();};
        MENU_option_integer("Ustawienia #DEC#",3);
        MENU_option_submenu("Ustawienia 0  ",0);
      break;
     
     
  }
  return true;
  }
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości