Skip to content

Commit 0145163

Browse files
authored
Merge pull request #214 from knockoutperformance/master
adding interrupt based joy button for arduino due
2 parents 838e627 + 9a4dcb2 commit 0145163

File tree

2 files changed

+464
-0
lines changed

2 files changed

+464
-0
lines changed
Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
#include <Arduino.h>
2+
3+
/********************
4+
Sept. 2014 ~ Oct 2016 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
5+
Oct. 2018 - modified by Kevin O'rourke to use interrupts on pins for the sam3x
6+
7+
menu with the newer adafruit GFX
8+
output: 1.8" TFT 128*160 (ST7735 HW SPI) or
9+
output: 1.8" TFT 128*160 (ST7735 SOFT SPI)
10+
11+
input: Serial + interrupts
12+
www.r-site.net
13+
14+
***/
15+
16+
//removed as extra libs are not included into travis
17+
// #define USE_CLICK_ENCODER
18+
#define USE_INTERRUPT_PINS // using a joy button
19+
#define DONT_SHOW_SUSPEND // dont show the suspended screen
20+
21+
#include <Adafruit_GFX.h>
22+
#include <Adafruit_SPITFT.h>
23+
#include <Adafruit_ST7735.h>
24+
#include <menu.h>
25+
#include <menuIO/adafruitGfxOut.h>
26+
#ifndef USE_INTERRUPT_PINS
27+
#ifdef USE_CLICK_ENCODER
28+
#include <TimerOne.h>
29+
#include <ClickEncoder.h>
30+
#include <menuIO/clickEncoderIn.h>
31+
#else
32+
#include <menuIO/encoderIn.h>
33+
#endif
34+
#include <menuIO/keyIn.h>
35+
#include <menuIO/chainStream.h>
36+
#include <menuIO/serialOut.h>
37+
#include <menuIO/serialIn.h>
38+
#else
39+
#include <menuIO/interruptPins.h>
40+
#include <menuIO/chainStream.h>
41+
#include <menuIO/serialOut.h>
42+
#include <menuIO/serialIn.h>
43+
44+
#endif
45+
46+
47+
using namespace Menu;
48+
49+
//ST7735 1.8TFT 128x160
50+
//#define TFT_CS A1
51+
//#define TFT_DC A0
52+
//#define TFT_RST A2
53+
54+
55+
56+
void wait_for(uint32_t wait) {
57+
uint64_t myMillis = wait * 11986; // approx 11986000 nop nop per sec
58+
for (uint64_t Counting = 0; Counting <= myMillis; Counting++) {
59+
__asm__("nop\n\t");
60+
}
61+
}
62+
63+
64+
#define SPI_SCK 13
65+
#define SPI_DI 12
66+
#define SPI_DO 11
67+
#define TFT_CS 15
68+
#define TFT_RST 0
69+
#define TFT_DC 8
70+
71+
//Adafruit_ST7735 gfx(TFT_CS, TFT_DC, TFT_RST); // hardware if possible
72+
73+
Adafruit_ST7735 gfx = Adafruit_ST7735(TFT_CS, TFT_DC, SPI_DO, SPI_SCK, TFT_RST);// software spi on the due
74+
75+
#define LEDPIN LED_BUILTIN
76+
77+
#ifndef USE_INTERRUPT_PINS
78+
// rotary encoder pins
79+
#define encA 2
80+
#define encB 3
81+
#define encBtn 4
82+
#else
83+
// interrupt pins sam3x with joy button
84+
#define BTN_UP 2
85+
#define BTN_DOWN 3
86+
#define BTN_SEL 5
87+
#define BTN_LEFT 6
88+
#define BTN_RIGHT 7
89+
#endif
90+
91+
result doAlert(eventMask e, prompt &item);
92+
93+
int test=55;
94+
95+
int ledCtrl=LOW;
96+
97+
result myLedOn() {
98+
ledCtrl=HIGH;
99+
return proceed;
100+
}
101+
result myLedOff() {
102+
ledCtrl=LOW;
103+
return proceed;
104+
}
105+
106+
TOGGLE(ledCtrl,setLed,"Led: ",doNothing,noEvent,noStyle//,doExit,enterEvent,noStyle
107+
,VALUE("On",HIGH,doNothing,noEvent)
108+
,VALUE("Off",LOW,doNothing,noEvent)
109+
);
110+
111+
int selTest=0;
112+
SELECT(selTest,selMenu,"Select",doNothing,noEvent,noStyle
113+
,VALUE("Zero",0,doNothing,noEvent)
114+
,VALUE("One",1,doNothing,noEvent)
115+
,VALUE("Two",2,doNothing,noEvent)
116+
);
117+
118+
int chooseTest=-1;
119+
CHOOSE(chooseTest,chooseMenu,"Choose",doNothing,noEvent,noStyle
120+
,VALUE("First",1,doNothing,noEvent)
121+
,VALUE("Second",2,doNothing,noEvent)
122+
,VALUE("Third",3,doNothing,noEvent)
123+
,VALUE("Last",-1,doNothing,noEvent)
124+
);
125+
126+
//customizing a prompt look!
127+
//by extending the prompt class
128+
class confirmExit:public menu {
129+
public:
130+
confirmExit(constMEM menuNodeShadow& shadow):menu(shadow) {}
131+
Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t p) override {
132+
if(idx<0){menu::printTo(root,sel,out,idx,len,p);}
133+
else{out.printRaw((constText*)F("Exit"),len);}
134+
return idx;
135+
}
136+
};
137+
class altPrompt:public prompt {
138+
public:
139+
altPrompt(constMEM promptShadow& p):prompt(p) {}
140+
Used printTo(navRoot &root,bool sel,menuOut& out, idx_t idx,idx_t len,idx_t) override {
141+
return out.printRaw(F("special prompt!"),len);;
142+
}
143+
};
144+
145+
result systemExit();
146+
altMENU(confirmExit,subMenu2,"Exit?",doNothing,noEvent,wrapStyle,(Menu::_menuData|Menu::_canNav)
147+
,OP("Yes",systemExit,enterEvent)
148+
,EXIT("Cancel")
149+
);
150+
151+
MENU(subMenu,"Sub-Menu",doNothing,noEvent,noStyle
152+
,altOP(altPrompt,"",doNothing,noEvent)
153+
,OP("Op",doNothing,noEvent)
154+
,EXIT("<Back")
155+
);
156+
157+
char* constMEM hexDigit MEMMODE="0123456789ABCDEF";
158+
char* constMEM hexNr[] MEMMODE={"0","x",hexDigit,hexDigit};
159+
char buf1[]="0x11";
160+
161+
MENU(mainMenu,"Main menu",doNothing,noEvent,wrapStyle
162+
,OP("Op1",doNothing,noEvent)
163+
,OP("Op2",doNothing,noEvent)
164+
,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
165+
,SUBMENU(subMenu)
166+
,SUBMENU(setLed)
167+
,OP("LED On",myLedOn,enterEvent)
168+
,OP("LED Off",myLedOff,enterEvent)
169+
,SUBMENU(selMenu)
170+
,SUBMENU(chooseMenu)
171+
//,OP("Alert test",doAlert,enterEvent)
172+
,EDIT("Hex",buf1,hexNr,doNothing,noEvent,noStyle)
173+
//,EXIT("<Back")
174+
,SUBMENU(subMenu2)
175+
);
176+
177+
// define menu colors --------------------------------------------------------
178+
// {{disabled normal,disabled selected},{enabled normal,enabled selected, enabled editing}}
179+
//monochromatic color table
180+
181+
#define ST7735_GRAY RGB565(128,128,128)
182+
183+
const colorDef<uint16_t> colors[] MEMMODE={
184+
{{ST7735_BLACK,ST7735_BLACK},{ST7735_BLACK,ST7735_BLUE,ST7735_BLUE}},//bgColor
185+
{{ST7735_GRAY,ST7735_GRAY},{ST7735_WHITE,ST7735_WHITE,ST7735_WHITE}},//fgColor
186+
{{ST7735_WHITE,ST7735_BLACK},{ST7735_YELLOW,ST7735_YELLOW,ST7735_RED}},//valColor
187+
{{ST7735_WHITE,ST7735_BLACK},{ST7735_WHITE,ST7735_YELLOW,ST7735_YELLOW}},//unitColor
188+
{{ST7735_WHITE,ST7735_GRAY},{ST7735_BLACK,ST7735_BLUE,ST7735_WHITE}},//cursorColor
189+
{{ST7735_WHITE,ST7735_YELLOW},{ST7735_BLUE,ST7735_RED,ST7735_RED}},//titleColor
190+
};
191+
192+
serialIn serial(Serial);
193+
194+
#ifndef USE_INTERRUPT_PINS
195+
#ifdef USE_CLICK_ENCODER
196+
ClickEncoder clickEncoder(encA,encB,encBtn);
197+
ClickEncoderStream encStream(clickEncoder,1);
198+
MENU_INPUTS(in,&encStream,&serial);
199+
void timerIsr() {clickEncoder.service();}
200+
#else
201+
encoderIn<encA,encB> encoder;//simple quad encoder driver
202+
encoderInStream<encA,encB> encStream(encoder,4);// simple quad encoder fake Stream
203+
//a keyboard with only one key as the encoder button
204+
keyMap encBtn_map[]={{-encBtn,defaultNavCodes[enterCmd].ch}};//negative pin numbers use internal pull-up, this is on when low
205+
keyIn<1> encButton(encBtn_map);//1 is the number of keys
206+
MENU_INPUTS(in,&encStream,&encButton,&serial);
207+
#endif
208+
#else
209+
encoderIn<BTN_UP,BTN_DOWN,BTN_SEL,BTN_LEFT,BTN_RIGHT> encoder;//simple quad encoder driver
210+
encoderInStream<BTN_UP,BTN_DOWN,BTN_SEL,BTN_LEFT,BTN_RIGHT> encStream(encoder);// simple quad encoder fake Stream
211+
MENU_INPUTS(in,&encStream,&serial);
212+
#endif
213+
214+
#define MAX_DEPTH 4
215+
#define textScale 1
216+
MENU_OUTPUTS(out,MAX_DEPTH
217+
,ADAGFX_OUT(gfx,colors,6*textScale,9*textScale,{0,0,14,8},{14,0,14,8})
218+
,SERIAL_OUT(Serial)
219+
);
220+
221+
NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);
222+
223+
//when menu is suspended
224+
result idle(menuOut& o,idleEvent e) {
225+
#ifndef DONT_SHOW_SUSPEND
226+
if (e==idling) {
227+
o.println(F("suspended..."));
228+
o.println(F("press [select]"));
229+
o.println(F("to continue"));
230+
}
231+
#endif
232+
return proceed;
233+
}
234+
235+
result systemExit() {
236+
encoder.menu_running = false;//prevents the menu from running again!
237+
nav.reset();
238+
nav.idleOn();//suspend the menu system
239+
gfx.fillScreen(ST7735_BLACK);
240+
return quit;
241+
}
242+
//config myOptions('*','-',defaultNavCodes,false);
243+
244+
void setup() {
245+
//options=&myOptions;//can customize options
246+
pinMode(LEDPIN,OUTPUT);
247+
Serial.begin(211000);
248+
while(!Serial);
249+
Serial.println("menu 4.x test");
250+
Serial.flush();
251+
252+
//outGfx.usePreview=true;//reserve one panel for preview?
253+
//nav.showTitle=false;//show menu title?
254+
255+
//pinMode(encBtn, INPUT_PULLUP);
256+
#ifndef USE_INTERRUPT_PINS
257+
#ifdef USE_CLICK_ENCODER
258+
Timer1.initialize(1000);
259+
Timer1.attachInterrupt(timerIsr);
260+
#else
261+
encButton.begin();
262+
encoder.begin();
263+
#endif
264+
nav.idleTask=idle;//point a function to be used when menu is suspended
265+
#else
266+
encoder.begin();
267+
nav.idleOn(); // suspend the menu system
268+
#endif
269+
mainMenu[0].disable();
270+
SPI.begin();
271+
gfx.initR(INITR_BLACKTAB);
272+
gfx.setRotation(3);
273+
gfx.setTextSize(textScale);//test scalling
274+
gfx.setTextWrap(false);
275+
gfx.fillScreen(ST7735_BLACK);
276+
gfx.setTextColor(ST7735_RED,ST7735_BLACK);
277+
gfx.println("Menu 4.x test on GFX");
278+
delay(2000);
279+
gfx.fillScreen(ST7735_BLACK);
280+
}
281+
282+
void loop() {
283+
284+
#ifndef USE_INTERRUPT_PINS
285+
nav.poll();//this device only draws when needed
286+
delay(100);//simulate a delay when other tasks are done
287+
#else
288+
if((encoder.menu_running)&&(encoder.menu_interrupt)){
289+
encoder.menu_interrupt = false;
290+
nav.doInput();
291+
nav.doOutput();
292+
}
293+
#endif
294+
digitalWrite(LEDPIN, ledCtrl);
295+
}

0 commit comments

Comments
 (0)