Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Full graphic smart controller - cannot get the ecnoder to scroll nicely #421

Open
dumitrugrl opened this issue Aug 5, 2023 · 0 comments

Comments

@dumitrugrl
Copy link

dumitrugrl commented Aug 5, 2023

Hi,
I am trying to get the menu to work with the RepRap Full Graphic Smart Controller:
https://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller.

It displays the menu, but in order to scroll I need to turn the encoder rapidly and many times just to move to the next item.
Does anyone have a simple working example for this setup:
Mega 2560 + Ramps 1.4 + REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER.

#include <Arduino.h>

/********************
Arduino generic menu system
U8GLib menu example
U8Glib: https://github.com/olikraus/U8glib_Arduino

Jul.2016 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
Original from: https://github.com/christophepersoz

menu on U8GLib device
output: Nokia 5110 display (PCD8544 HW SPI) + Serial
input: Serial + encoder

ESP8266 Compile Error:
  `.irom0.text' will not fit in region `irom0_0_seg'
  see: http://bbs.espressif.com/viewtopic.php?t=166

please use U8G2 instead.

*/

#include <U8glib.h>
#include <menu.h>
// #include <menuIO/encoderIn.h>
#include <ClickEncoder.h>
#include <menuIO/clickEncoderIn.h>
#include <menuIO/keyIn.h>
#include <menuIO/chainStream.h>
// #include <menuIO/rotaryEventIn.h>
#include <menuIO/serialOut.h>
#include <menuIO/serialIn.h>
#include <menuIO/U8GLibOut.h>
#include <TimerOne.h>

using namespace Menu;

// #define INT_MODE_TYPE uint8_t

#define LEDPIN LED_BUILTIN

// Standard pins when on a RAMPS 1.4
#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

// SPI Com: SCK = en = 23, MOSI = rw = 17, CS = di = 16
U8GLIB_ST7920_128X64_1X u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS);

// rotary encoder pins
#define encA 31   // 2
#define encB 33   // 3
#define encBtn 35 // 4

// #define U8_DC 9
// #define U8_CS 8
// #define U8_RST 7
// U8GLIB_PCD8544 u8g(U8_CS, U8_DC, U8_RST);

result doAlert(eventMask e, prompt &item);

result showEvent(eventMask e, navNode &nav, prompt &item)
{
  Serial.print("event: ");
  Serial.println(e);
  return proceed;
}

int test = 55;

result action1(eventMask e)
{
  Serial.print(e);
  Serial.println(" action1 executed, proceed menu");
  Serial.flush();
  return proceed;
}

result action2(eventMask e, navNode &nav, prompt &item)
{
  Serial.print(e);
  Serial.print(" action2 executed, quiting menu");
  return quit;
}

int ledCtrl = LOW;

result myLedOn()
{
  ledCtrl = HIGH;
  return proceed;
}
result myLedOff()
{
  ledCtrl = LOW;
  return proceed;
}

TOGGLE(ledCtrl, setLed, "Led: ", doNothing, noEvent, noStyle, VALUE("On", HIGH, doNothing, noEvent), VALUE("Off", LOW, doNothing, noEvent));

int selTest = 0;
SELECT(selTest, selMenu, "Select", doNothing, noEvent, noStyle, VALUE("Zero", 0, doNothing, noEvent), VALUE("One", 1, doNothing, noEvent), VALUE("Two", 2, doNothing, noEvent));

int chooseTest = -1;
CHOOSE(chooseTest, chooseMenu, "Choose", doNothing, noEvent, noStyle, VALUE("First", 1, doNothing, noEvent), VALUE("Second", 2, doNothing, noEvent), VALUE("Third", 3, doNothing, noEvent), VALUE("Last", -1, doNothing, noEvent));

// customizing a prompt look!
// by extending the prompt class
class altPrompt : public prompt
{
public:
  altPrompt(constMEM promptShadow &p) : prompt(p) {}
  Used printTo(navRoot &root, bool sel, menuOut &out, idx_t idx, idx_t len, idx_t panelNr) override
  {
    return out.printRaw(F("special prompt!"), len);
    ;
  }
};

MENU(subMenu, "Sub-Menu", showEvent, anyEvent, noStyle, OP("Sub1", showEvent, anyEvent), OP("Sub2", showEvent, anyEvent), OP("Sub3", showEvent, anyEvent), altOP(altPrompt, "", showEvent, anyEvent), EXIT("<Back"));

const char *constMEM hexDigit MEMMODE = "0123456789ABCDEF";
const char *constMEM hexNr[] MEMMODE = {"0", "x", hexDigit, hexDigit};
char buf1[] = "0x11";

MENU(mainMenu, "Main menu", doNothing, noEvent, wrapStyle, OP("Op1", action1, anyEvent), OP("Op2", action2, enterEvent), FIELD(test, "Test", "%", 0, 100, 10, 1, doNothing, noEvent, wrapStyle), EDIT("Hex", buf1, hexNr, doNothing, noEvent, noStyle), SUBMENU(subMenu), SUBMENU(setLed), OP("LED On", myLedOn, enterEvent), OP("LED Off", myLedOff, enterEvent), SUBMENU(selMenu), SUBMENU(chooseMenu), OP("Alert test", doAlert, enterEvent), EXIT("<Back"));

// define menu colors --------------------------------------------------------
// each color is in the format:
//  {{disabled normal,disabled selected},{enabled normal,enabled selected, enabled editing}}
// this is a monochromatic color table
const colorDef<uint8_t> colors[6] MEMMODE = {
    {{0, 0}, {0, 1, 1}}, // bgColor
    {{1, 1}, {1, 0, 0}}, // fgColor
    {{1, 1}, {1, 0, 0}}, // valColor
    {{1, 1}, {1, 0, 0}}, // unitColor
    {{0, 1}, {0, 0, 1}}, // cursorColor
    {{0, 0}, {1, 1, 1}}, // titleColor
};

// encoderIn<encA, encB> encoder;                     // simple quad encoder driver
// encoderInStream<encA, encB> encStream(encoder, 1); // simple quad encoder fake Stream

// Create encoder instance
ClickEncoder *encoder;
// Value of encoder
int16_t last, value;

ClickEncoder clickEncoder(BTN_EN1, BTN_EN2, BTN_ENC, 4);
ClickEncoderStream encStream(clickEncoder, 1);

void timerIsr() { clickEncoder.service(); }

// a keyboard with only one key as the encoder button
// keyMap encBtn_map[] = {{-encBtn, defaultNavCodes[enterCmd].ch}}; // negative pin numbers use internal pull-up, on = low
// keyIn<1> encButton(encBtn_map);                                  // 1 is the number of keys

serialIn serial(Serial);

// input from the encoder + encoder button + serial
menuIn *inputsList[] = {&encStream}; // &encStream}; //, &encButton}; //, &serial};
chainStream<1> in(inputsList);       // 3 is the number of inputs

// fontY should now account for fontMarginY
// #define fontX 6
// #define fontY 9
#define MAX_DEPTH 2

// this macro replaces all the above commented lines
#define fontX 6
#define fontY 9
#define offsetX 0
#define offsetY 2
#define U8_Width 128
#define U8_Height 64

MENU_OUTPUTS(out, MAX_DEPTH, U8GLIB_OUT(u8g, colors, fontX, fontY, {0, 0, U8_Width / fontX, U8_Height / fontY}), SERIAL_OUT(Serial));

NAVROOT(nav, mainMenu, MAX_DEPTH, in, out);

result alert(menuOut &o, idleEvent e)
{
  if (e == idling)
  {
    o.setCursor(0, 0);
    o.print("alert test");
    o.setCursor(0, 1);
    o.print("press [select]");
    o.setCursor(0, 2);
    o.print("to continue...");
  }
  return proceed;
}

result doAlert(eventMask e, prompt &item)
{
  nav.idleOn(alert);
  return proceed;
}

// when menu is suspended
result idle(menuOut &o, idleEvent e)
{
  o.clear();
  switch (e)
  {
  case idleStart:
    o.println("suspending menu!");
    break;
  case idling:
    o.println("suspended...");
    break;
  case idleEnd:
    o.println("resuming menu.");
    break;
  }
  return proceed;
}

int lastpos = -1;
void setup()
{
  pinMode(LEDPIN, OUTPUT);

  Serial.begin(250000);
  while (!Serial)
    ;

  Serial.println("<setup()>");

  nav.idleTask = idle; // point a function to be used when menu is suspended
  mainMenu[1].enabled = disabledStatus;

  // change input burst for slow output devices  this is the number of max. processed inputs before drawing
  // nav.inputBurst = 10;

  clickEncoder.setAccelerationEnabled(false);

  pinMode(BTN_EN1, INPUT_PULLUP); // Set BTN_EN1 as an unput, half of the encoder
  digitalWrite(BTN_EN1, HIGH);    // turn on pullup resistors
  pinMode(BTN_EN2, INPUT_PULLUP); // 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

  pinMode(BTN_ENC, INPUT_PULLUP);
  // encButton.begin();
  // encoder.begin();

  // u8g.setFont(u8g_font_helvR08);
  // u8g.setFont(u8g_font_6x10);
  // u8g.setFont(u8g_font_04b_03r);
  u8g.firstPage();
  do
  {
    u8g.setColorIndex(1);
    nav.out[0].setCursor(0, 0);
    nav.out[0].print(F("Menu 4.x test"));
    nav.out[0].setCursor(0, 1);
    nav.out[0].print(F("on U8Glib"));
  } while (u8g.nextPage());

  Timer1.initialize(1000);
  Timer1.attachInterrupt(timerIsr);
  // delay(2000);

  Serial.println("</setup()>");
}

void loop()
{
  // Serial.println("<loop()>");

  int currval = clickEncoder.getValue();
  if (currval != lastpos)
  {
    Serial.println(currval);
    lastpos = currval;
  }

  // nav.poll();

  nav.doInput();

  if (nav.changed(0))
  {
    // only draw if menu changed for gfx device
    // because this code clears the screen, if always called then screen will blink
    u8g.firstPage();
    do
      nav.doOutput();
    while (u8g.nextPage());
  }
  digitalWrite(LED_BUILTIN, ledCtrl);

  // delay(100); // simulate other tasks delay

  //  Serial.println("</loop()>");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant