Skip to content

Commit 64ee5c8

Browse files
committed
MCUFRIEND example
1 parent b342fbb commit 64ee5c8

File tree

3 files changed

+293
-0
lines changed

3 files changed

+293
-0
lines changed
Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
/*********************
2+
* Sept. 2014 ~ Oct 2016 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
3+
* May 2020 - review by: Neftali Loya Garibay
4+
5+
* This menu example works for Chinese MCUFRIEND_kbv TFT LCD's normally sold by Banggood and
6+
* alike places. It is based on adafruit GFX library and on its own "MCUFRIEND_kbv.h" library,
7+
* downlodble from gitHub. It was tested on an ATMEGA-2560 board and it uses an encoder as the
8+
* navigation device. The encoder has also a switch and it was used as the enter key.
9+
*
10+
* Output: 3.5 inch, 480*320 TFT-LCD Arduino UNO and MEGA shield, ILI9486.
11+
* Input: Serial + encoder
12+
*
13+
* www.r-site.net
14+
*
15+
* Alternative encoder (clickEncoder) uses:
16+
* https://github.com/0xPIT/encoder
17+
* https://github.com/PaulStoffregen/TimerOne
18+
*
19+
*********************/
20+
21+
#include <Arduino.h>
22+
23+
//**** TFT-LCD RELATED LIBRARIES ***
24+
#include "Adafruit_GFX.h"
25+
#include <MCUFRIEND_kbv.h>
26+
MCUFRIEND_kbv tft;
27+
28+
//*** MENU LIBRARY AND ASSOCIATED ENCODER LIBRARIES ***
29+
#include <menu.h>
30+
#include <menuIO/adafruitGfxOut.h>
31+
#include <TimerOne.h>
32+
#include <ClickEncoder.h>
33+
#include <menuIO/clickEncoderIn.h>
34+
#include <menuIO/encoderIn.h>
35+
#include <menuIO/keyIn.h>
36+
#include <menuIO/chainStream.h>
37+
#include <menuIO/serialOut.h>
38+
#include <menuIO/serialIn.h>
39+
40+
using namespace Menu;
41+
42+
#define LEDPIN 42
43+
44+
//*** ROTARY ENCODER PINS AS USED ON AN ARDUINO MEGA-2560 ***
45+
#define encBtn 44 // Use as input with pull-ups
46+
#define encB 46 // Use as input with pull-ups
47+
#define encC 48 // Set it to GND
48+
#define encA 50 // Use as input with pull-ups
49+
#define encBtn2 52 // Set it as output to GND
50+
51+
/* HUMAN READABLE COLOR DEFINITIONS. Not all the following color defiitions are used on the
52+
* example. However, it is handy to have them available for tailoring the menu's look according
53+
* to our liking. These definitions are a Bodmer's contribution.
54+
*/
55+
#define BLACK 0x0000 /* 0, 0, 0 */
56+
#define NAVY 0x000F /* 0, 0, 128 */
57+
#define DARKGREEN 0x03E0 /* 0, 128, 0 */
58+
#define DARKCYAN 0x03EF /* 0, 128, 128 */
59+
#define MAROON 0x7800 /* 128, 0, 0 */
60+
#define PURPLE 0x780F /* 128, 0, 128 */
61+
#define OLIVE 0x7BE0 /* 128, 128, 0 */
62+
/*#define LIGHTGREY 0xC618 /* 128, 128, 0 */
63+
#define GRAY 0xC618 /* 192, 192, 192 */
64+
#define DARKGRAY 0x7BEF /* 128, 128, 128 */
65+
#define BLUE 0x001F /* 0, 0, 255 */
66+
#define GREEN 0x07E0 /* 0, 255, 0 */
67+
#define CYAN 0x07FF /* 0, 255, 255 */
68+
#define RED 0xF800 /* 255, 0, 0 */
69+
#define MAGENTA 0xF81F /* 255, 0, 255 */
70+
#define YELLOW 0xFFE0 /* 255, 255, 0 */
71+
#define WHITE 0xFFFF /* 255, 255, 255 */
72+
#define ORANGE 0xFDA0 /* 255, 180, 0 */
73+
#define GREENYELLOW 0xB7E0 /* 180, 255, 0 */
74+
#define PINK 0xFC9F
75+
76+
77+
result doAlert(eventMask e, prompt &item);
78+
79+
int test=55;
80+
81+
int ledCtrl=LOW;
82+
83+
result myLedOn() {
84+
ledCtrl=HIGH;
85+
return proceed;
86+
}
87+
result myLedOff() {
88+
ledCtrl=LOW;
89+
return proceed;
90+
}
91+
92+
TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,noStyle
93+
,VALUE("On",HIGH,doNothing,noEvent)
94+
,VALUE("Off",LOW,doNothing,noEvent)
95+
);
96+
97+
int selTest=0;
98+
SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
99+
,VALUE("Zero",0,doNothing,noEvent)
100+
,VALUE("One",1,doNothing,noEvent)
101+
,VALUE("Two",2,doNothing,noEvent)
102+
);
103+
104+
int chooseTest=-1;
105+
CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
106+
,VALUE("First",1,doNothing,noEvent)
107+
,VALUE("Second",2,doNothing,noEvent)
108+
,VALUE("Third",3,doNothing,noEvent)
109+
,VALUE("Last",-1,doNothing,noEvent)
110+
);
111+
112+
//customizing a prompt look!
113+
//by extending the prompt class
114+
class altPrompt:public prompt {
115+
public:
116+
altPrompt(constMEM promptShadow& p):prompt(p) {}
117+
Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
118+
return out.printRaw(F("special prompt!"),len);;
119+
}
120+
};
121+
122+
MENU(subMenu,"Sub-Menu",doNothing,noEvent,noStyle
123+
,altOP(altPrompt,"",doNothing,noEvent)
124+
,OP("Op",doNothing,noEvent)
125+
,EXIT("<Back")
126+
);
127+
128+
char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
129+
char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
130+
char buf1[]="0x11";
131+
132+
MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
133+
,OP("Op1",doNothing,noEvent)
134+
,OP("Op2",doNothing,noEvent)
135+
// ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
136+
,SUBMENU(subMenu)
137+
,SUBMENU(setLed)
138+
,OP("LED On",myLedOn,enterEvent)
139+
,OP("LED Off",myLedOff,enterEvent)
140+
,SUBMENU(selMenu)
141+
,SUBMENU(chooseMenu)
142+
//,OP("Alert test",doAlert,enterEvent)
143+
,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
144+
,EXIT("<Back")
145+
);
146+
147+
//*** DEFINE MENU COLORS ***______________________________________________________________________________
148+
const colorDef<uint16_t> colors[6] MEMMODE={
149+
{{(uint16_t)BLACK,(uint16_t)BLACK}, {(uint16_t)BLACK, (uint16_t)BLUE, (uint16_t)BLUE}}, //bgColor
150+
{{(uint16_t)GRAY, (uint16_t)GRAY}, {(uint16_t)WHITE, (uint16_t)WHITE, (uint16_t)WHITE}}, //fgColor
151+
{{(uint16_t)WHITE,(uint16_t)BLACK}, {(uint16_t)YELLOW,(uint16_t)YELLOW,(uint16_t)RED}}, //valColor
152+
{{(uint16_t)WHITE,(uint16_t)BLACK}, {(uint16_t)WHITE, (uint16_t)YELLOW,(uint16_t)YELLOW}},//unitColor
153+
{{(uint16_t)WHITE,(uint16_t)GRAY}, {(uint16_t)BLACK, (uint16_t)BLUE, (uint16_t)WHITE}}, //cursorColor
154+
{{(uint16_t)WHITE,(uint16_t)YELLOW},{(uint16_t)BLUE, (uint16_t)RED, (uint16_t)RED}}, //titleColor
155+
};
156+
157+
serialIn serial(Serial);
158+
159+
#ifdef USE_CLICK_ENCODER
160+
ClickEncoder clickEncoder(encA,encB,encBtn);
161+
ClickEncoderStream encStream(clickEncoder,1);
162+
MENU_INPUTS(in,&encStream,&serial);
163+
void timerIsr() {clickEncoder.service();}
164+
#else
165+
encoderIn<encA,encB> encoder;//simple quad encoder driver
166+
encoderInStream<encA,encB> encStream(encoder,1);// simple quad encoder fake Stream
167+
//a keyboard with only one key as the encoder button
168+
keyMap encBtn_map[]={{-encBtn,defaultNavCodes[enterCmd].ch}};//negative pin numbers use internal pull-up, this is on when low
169+
keyIn<1> encButton(encBtn_map);//1 is the number of keys
170+
MENU_INPUTS(in,&encStream,&encButton,&serial);
171+
#endif
172+
173+
#define MAX_DEPTH 5
174+
#define textScale 2
175+
MENU_OUTPUTS(out,MAX_DEPTH
176+
,ADAGFX_OUT(tft,colors,6*textScale,9*textScale,{0,0,14,8},{14,0,14,8})
177+
,SERIAL_OUT(Serial)
178+
);
179+
180+
NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);
181+
182+
//*** WHEN MENU IS SUSPENDED ***
183+
result idle(menuOut& o,idleEvent e) {
184+
if (e==idling) {
185+
o.println(F("suspended..."));
186+
o.println(F("press [select]"));
187+
o.println(F("to continue"));
188+
}
189+
return proceed;
190+
}
191+
192+
// config myOptions('*','-',defaultNavCodes,false);
193+
194+
void setup() {
195+
uint16_t ID;
196+
Serial.begin(9600);
197+
Serial.print("Show BMP files on TFT with ID:0x");
198+
ID = tft.readID();
199+
Serial.println(ID, HEX);
200+
if (ID == 0x0D3D3) ID = 0x9481;
201+
tft.begin(ID);
202+
tft.fillScreen(0x001F);
203+
tft.setTextColor(0xFFFF, 0x0000);
204+
205+
//options=&myOptions;//can customize option
206+
pinMode(encBtn, INPUT_PULLUP);
207+
pinMode(encA, INPUT_PULLUP);
208+
pinMode(encB, INPUT_PULLUP);
209+
pinMode(encC, OUTPUT-LOW);
210+
pinMode(encBtn2, OUTPUT-LOW);
211+
pinMode(LEDPIN,OUTPUT);
212+
Serial.begin(115200);
213+
while(!Serial);
214+
Serial.println("menu 4.x test");
215+
Serial.flush();
216+
nav.idleTask=idle;//point a function to be used when menu is suspended
217+
mainMenu[1].disable();
218+
//outGfx.usePreview=true;//reserve one panel for preview?
219+
//nav.showTitle=false;//show menu title?
220+
221+
222+
#ifdef USE_CLICK_ENCODER
223+
Timer1.initialize(1000);
224+
Timer1.attachInterrupt(timerIsr);
225+
#else
226+
encButton.begin();
227+
encoder.begin();
228+
#endif
229+
230+
tft.setRotation(3);
231+
tft.setTextSize(textScale); // test scalling
232+
//tft.setTextWrap(false); // NOT AVAILABLE WITHIN THE "MCUFRIEND_kbv.h" library
233+
tft.fillScreen(BLACK);
234+
tft.setTextColor(RED,BLACK);
235+
tft.println("Menu 4.x T est on GFX");
236+
delay(1000);
237+
}
238+
239+
void loop() {
240+
nav.poll(); // This device only draws when needed.
241+
digitalWrite(LEDPIN, ledCtrl);
242+
delay(100); // Simulate a delay when other tasks are done.
243+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
This directory is intended for project header files.
3+
4+
A header file is a file containing C declarations and macro definitions
5+
to be shared between several project source files. You request the use of a
6+
header file in your project source file (C, C++, etc) located in `src` folder
7+
by including it, with the C preprocessing directive `#include'.
8+
9+
```src/main.c
10+
11+
#include "header.h"
12+
13+
int main (void)
14+
{
15+
...
16+
}
17+
```
18+
19+
Including a header file produces the same results as copying the header file
20+
into each source file that needs it. Such copying would be time-consuming
21+
and error-prone. With a header file, the related declarations appear
22+
in only one place. If they need to be changed, they can be changed in one
23+
place, and programs that include the header file will automatically use the
24+
new version when next recompiled. The header file eliminates the labor of
25+
finding and changing all the copies as well as the risk that a failure to
26+
find one copy will result in inconsistencies within a program.
27+
28+
In C, the usual convention is to give header files names that end with `.h'.
29+
It is most portable to use only letters, digits, dashes, and underscores in
30+
header file names, and at most one dot.
31+
32+
Read more about using header files in official GCC documentation:
33+
34+
* Include Syntax
35+
* Include Operation
36+
* Once-Only Headers
37+
* Computed Includes
38+
39+
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
This directory is intended for PIO Unit Testing and project tests.
3+
4+
Unit Testing is a software testing method by which individual units of
5+
source code, sets of one or more MCU program modules together with associated
6+
control data, usage procedures, and operating procedures, are tested to
7+
determine whether they are fit for use. Unit testing finds problems early
8+
in the development cycle.
9+
10+
More information about PIO Unit Testing:
11+
- https://docs.platformio.org/page/plus/unit-testing.html

0 commit comments

Comments
 (0)