StickC如何快速创建显示菜单-Arduino中文社区 - Powered by Discuz! Archiver

vany5921 发表于 2020-2-27 17:38

StickC如何快速创建显示菜单

本帖最后由 vany5921 于 2020-2-27 18:04 编辑

    介绍一个我个人比较喜欢的一个轻量级菜单系统,使用简单,适合对项目做一些复杂设置,以下示例我基于ArduinoMenuLibrary(Arduino库管理器内下载该库)的demo修改用以演示。其实StickC的关机按键里有彩蛋,但是可能没有用户去深入了解,仔细扒一下AXP192的库,你就能发现关机键也可以作为正常按键使用,因此菜单的上下选择及确认键都具备了,剩下就看你如何去应用了。本篇可能你学到的最重要的就是如何将关机键作为普通按键使用。关于这个库怎么用大家自己多摸索多实验,讲解的话可能不如你自己实验更有体会,除了屏幕会有菜单显示,串口同样可以输出菜单并进行操作。菜单的显示方式可以横屏也可以竖屏,选择条的长宽根据屏幕旋转调整。另外注意字体的宽度高度与选择条会相互影响,根据实际情况调整,另外cpp里也可以修改相关的参数。



#include <M5StickC.h>
#include <menu.h>
#include <menuIO/serialIO.h>
#include <menuIO/TFT_eSPIOut.h>
// #include <menuIO/chainStream.h>
#include <menuIO/esp8266Out.h>//must include this even if not doing web output...
#define LEDPIN 10


using namespace Menu;

TFT_eSPI gfx = TFT_eSPI(80, 160);

result doAlert(eventMask e, prompt &item);

int test=55;

int ledCtrl=HIGH;

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

TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,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) override {
    return out.printRaw(F("special prompt!"),len);;
}
};

MENU(subMenu,"Sub-Menu",doNothing,noEvent,noStyle
,altOP(altPrompt,"",doNothing,noEvent)
,OP("Op",doNothing,noEvent)
,EXIT("<Back")
);

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

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

// define menu colors --------------------------------------------------------
//{{disabled normal,disabled selected},{enabled normal,enabled selected, enabled editing}}
//monochromatic color table


#define Black RGB565(0,0,0)
#define Red      RGB565(255,0,0)
#define Green RGB565(0,255,0)
#define Blue RGB565(0,0,255)
#define Gray RGB565(128,128,128)
#define LighterRed RGB565(255,150,150)
#define LighterGreen RGB565(150,255,150)
#define LighterBlue RGB565(150,150,255)
#define DarkerRed RGB565(150,0,0)
#define DarkerGreen RGB565(0,150,0)
#define DarkerBlue RGB565(0,0,150)
#define Cyan RGB565(0,255,255)
#define Magenta RGB565(255,0,255)
#define Yellow RGB565(255,255,0)
#define White RGB565(255,255,255)

const colorDef<uint16_t> colors[] MEMMODE={
{{(uint16_t)Black,(uint16_t)Black}, {(uint16_t)Black, (uint16_t)Blue,(uint16_t)Blue}},//bgColor
{{(uint16_t)Gray, (uint16_t)Gray},{(uint16_t)White, (uint16_t)White, (uint16_t)White}},//fgColor
{{(uint16_t)White,(uint16_t)Black}, {(uint16_t)Yellow,(uint16_t)Yellow,(uint16_t)Red}},//valColor
{{(uint16_t)White,(uint16_t)Black}, {(uint16_t)White, (uint16_t)Yellow,(uint16_t)Yellow}},//unitColor
{{(uint16_t)White,(uint16_t)Gray},{(uint16_t)Black, (uint16_t)Blue,(uint16_t)White}},//cursorColor
{{(uint16_t)White,(uint16_t)Yellow},{(uint16_t)Blue,(uint16_t)Red,   (uint16_t)Red}},//titleColor
};

#define MAX_DEPTH 4

serialIn serial(Serial);

//MENU_INPUTS(in,&serial);its single, no need to `chainStream`

//define serial output device
idx_t serialTops={0};
serialOut outSerial(Serial,serialTops);

#define GFX_WIDTH 160 //显示条宽度根据屏幕调整
#define GFX_HEIGHT 80 //显示条高度根据屏幕调整
#define fontW 6 //根据字体大小谨慎调整
#define fontH 9//根据字体大小谨慎调整

constMEM panel panels[] MEMMODE = {{0, 0, GFX_WIDTH/fontW, GFX_HEIGHT/fontH }};
navNode* nodes; //navNodes to store navigation status
panelsList pList(panels, nodes, 1); //a list of panels and nodes
idx_t eSpiTops={0};
TFT_eSPIOut eSpiOut(gfx,colors,eSpiTops,pList,fontW, fontH+1);
menuOut* constMEM outputs[] MEMMODE={&outSerial,&eSpiOut};//list of output devices
outputsList out(outputs,sizeof(outputs)/sizeof(menuOut*));//outputs list controller

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

//when menu is suspended
result idle(menuOut& o,idleEvent e) {
if (e==idling) {
    o.println(F("suspended..."));
    o.println(F("press "));
    o.println(F("to continue"));
}
return proceed;
}

//config myOptions('*','-',defaultNavCodes,false);

void button_loop()
{
    // Check for button presses
    if(M5.Axp.GetBtnPress() == 0x02)
      nav.doNav(downCmd);
    if(M5.BtnB.wasPressed())
      nav.doNav(upCmd);
    if(M5.BtnA.wasPressed())
      nav.doNav(enterCmd);
}


void setup() {
//options=&myOptions;//can customize options
M5.begin();
gfx.init();
pinMode(LEDPIN,OUTPUT);

//Serial.begin(115200);
while(!Serial);
Serial.println("menu 4.x test");
Serial.flush();
nav.idleTask=idle;//point a function to be used when menu is suspended
mainMenu.disable();
//outGfx.usePreview=true;//reserve one panel for preview?
//nav.showTitle=false;//show menu title?

//SPI.begin();

gfx.setRotation(3);//屏幕旋转
//gfx.setTextSize(2);//test scalling
}

void loop() {
button_loop();
nav.poll();//this device only draws when needed
digitalWrite(LEDPIN, ledCtrl);
delay(100);//simulate a delay when other tasks are done
M5.update();
}

页: [1]
查看完整版本: StickC如何快速创建显示菜单