Skip to content

Commit 2727ca7

Browse files
committed
LCD fields line clear on value change
1 parent f958306 commit 2727ca7

File tree

5 files changed

+316
-4
lines changed

5 files changed

+316
-4
lines changed

examples/menu_test/menu_test.ino

Lines changed: 312 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,312 @@
1+
/******************
2+
This is my development file... not a good example
3+
Rui Azevedo 2014
4+
ruihfazevedo@[email protected]
5+
********/
6+
7+
#include <VPinsI2C.h>
8+
#include <virtual_pins.h>
9+
#include <HardwareSerial.h>
10+
#include <LiquidCrystal.h>
11+
#include <menu.h>//menu macros and objects
12+
#include <pcint.h>//this is incompatible with software serial (arduino needs an handler!)
13+
#include <quadEncoder.h>//quadrature encoder driver and fake stream
14+
#include <keyStream.h>//keyboard driver and fake stream (for the encoder button)
15+
#include <chainStream.h>// concatenate multiple input streams (this allows adding a button to the encoder)
16+
#include <menuPrint.h>//Print (Serial) menu
17+
18+
#define LCDWIRE_NONE 0
19+
#define LCDWIRE_VPINS_I2C 1
20+
#define LCDWIRE_VPINS_SPI 2
21+
#define LCDWIRE_I2C 3
22+
#define LCDWIRE_DIRECT 4
23+
24+
//how the LCD is wired
25+
//#define LCD_WIRE LCDWIRE_NONE
26+
//#define LCD_WIRE LCDWIRE_VPINS_I2C
27+
#define LCD_WIRE LCDWIRE_VPINS_SPI//on shift registers thru vpins (same library)
28+
//#define LCD_WIRE LCDWIRE_I2C//not tested
29+
//#define LCD_WIRE LCDWIRE_DIRECT//not tested
30+
31+
#define USE_TFT 1//0|1
32+
#define tftCS 5
33+
34+
#if (USE_TFT == 1)
35+
#include <Adafruit_GFX.h> // Co1re graphics library
36+
#include <Adafruit_ST7735.h> // Hardware-specific library
37+
#include <menuGFX.h>
38+
39+
///////////////////////////////////////////////////////////////////////////
40+
//TFT + SD
41+
//#define sdCS 4
42+
#define dc 6
43+
#define rst 7 // you can also connect this to the Arduino reset
44+
45+
Adafruit_ST7735 tft(tftCS, dc, rst);
46+
#endif
47+
48+
#define vpinsSPI_CS 9//vpins SPI CS
49+
#if (LCD_WIRE == LCDWIRE_VPINS_SPI)//LCD wired on shift registers using vpins
50+
#include <SPI.h>
51+
#include <VPinsSPI.h>
52+
#include "menuLCD.h"
53+
#define STCP 9//stcp or latch pin
54+
55+
#define RS 26
56+
//#define RW 25
57+
#define EN 24
58+
SPIBranch spi(SPI,STCP,VPA,1);//TODO: add version that finds a free port and make pin() fynctions the only methid to get a pin number
59+
LiquidCrystal lcd1(RS,EN,20,21,22,23);
60+
#endif
61+
62+
#if (LCD_WIRE == LCDWIRE_VPINS_I2C)// LCD is wired over i2c to another AVR that uses virtual pins and shift registers to control it and virtual port server to share it
63+
#include <Wire.h>
64+
#include "menuLCD.h"
65+
//remote pins over I2C to VPort server
66+
#define vpinsSPI_CS srv_pb.pin(1)//vpins SPI CS
67+
#define STCP srv_pb.pin(1)//stcp or latch pin
68+
69+
//setup i2c network and port/pin/device maps
70+
// my LCD is remote wired... other LCD's should initialize as usual
71+
I2CServerBranch srv_vpa(Wire,0x11,VPA,VPA,1);//virtual (spi) port on i2c vport server (2 bytes)
72+
I2CServerBranch srv_pb(Wire,0x11,VPB,PB,1);//physical port B on i2c vport server is now local virtual port VPB (tied)
73+
I2CServerBranch srv_pc(Wire,0x11,VPC,PC,1);//physical port C on i2c vport server is now local virtual port VPC (tied)
74+
I2CServerBranch srv_pd(Wire,0x11,VPD,PD,1);//physical port D on i2c vport server is now local virtual port VPD (tied)
75+
//here wiring the LCD screen and other stuff over the I2C network...
76+
LiquidCrystal lcd1(srv_vpa.pin(6), srv_vpa.pin(4), srv_vpa.pin(0), srv_vpa.pin(1), srv_vpa.pin(2), srv_vpa.pin(3));
77+
#endif
78+
79+
///////////////////////////////////////////////////////////////////////////////
80+
//set CS pins for LCD or TFT
81+
void selectLCD() {
82+
digitalWrite(vpinsSPI_CS,LOW);
83+
digitalWrite(tftCS,LOW);
84+
}
85+
86+
void selectTFT() {
87+
digitalWrite(vpinsSPI_CS,HIGH);
88+
digitalWrite(tftCS,HIGH);
89+
}
90+
91+
////////////////////////////////////////////
92+
// ENCODER (aka rotary switch) PINS
93+
// rotary
94+
#define encA 2
95+
#define encB 4
96+
//this encoder has a button here
97+
#define encBtn A0
98+
#define LEDPIN A3//on uno use pin 13
99+
100+
///////////////////////////////////////////////////////////////////////////
101+
//functions to wire as menu actions
102+
103+
//aux function
104+
void nothing() {}
105+
106+
void setValue(int &value,prompt &p,menuOut &o, Stream &i,const char* text,const char* units="",int sensivity=5,int low=0,int hi=100,int steps=0,void (*func)()=nothing);
107+
108+
void ledOn() {digitalWrite(LEDPIN,1);}
109+
void ledOff() {digitalWrite(LEDPIN,0);}
110+
void disabledTest(prompt &p,menuOut &o,Stream &i) {
111+
o.clear();
112+
o.setCursor(0,0);
113+
o.print("THIS IS AN ERROR, this option should never be called as it is disabled");
114+
while(i.read()!=13);
115+
}
116+
117+
int frequency=100;
118+
void setFreq(prompt &p,menuOut &o,Stream &i) {setValue(frequency,p,o,i,"Freq:","0 Hz",20,1,1000);}
119+
120+
int dutty=50;
121+
void setDutty(prompt &p,menuOut &o,Stream &i) {setValue(dutty,p,o,i,"Dutty:","%",1,0,100);}
122+
123+
void completeHandlerTest(prompt &p,menuOut &o,Stream &i) {
124+
o.clear();
125+
o.setCursor(0,0);
126+
o.print("Handler test ok!");
127+
while(i.read()!=13);
128+
}
129+
130+
int stv=8;
131+
void scrollUp_test(prompt &p,menuOut &o,Stream &i);
132+
void scrollDown_test(prompt &p,menuOut &o,Stream &i);
133+
134+
/////////////////////////////////////////////////////////////////////////
135+
// MENU DEFINITION
136+
// here we define the menu structure and wire actions functions to it
137+
MENU(subMenu,"LED ON/OFF",
138+
OP("LED On",ledOn),
139+
OP("LED Off",ledOff)
140+
);
141+
142+
MENU(mainMenu,"Sistema",
143+
OP("Frequency",setFreq),
144+
OP("Dutty",setDutty),
145+
OP("Disabled",disabledTest),
146+
/*OP("Scroll up", scrollUp_test),
147+
OP("scroll down", scrollDown_test),
148+
OP("Handler test",completeHandlerTest),
149+
OP("Handler test",completeHandlerTest),
150+
OP("Handler test",completeHandlerTest),
151+
OP("Handler test",completeHandlerTest),
152+
OP("Handler test",completeHandlerTest),
153+
OP("Handler test",completeHandlerTest),
154+
OP("Handler test",completeHandlerTest),
155+
OP("Handler test",completeHandlerTest),
156+
OP("Handler test",completeHandlerTest),
157+
OP("Handler test",completeHandlerTest),*/
158+
SUBMENU(subMenu)
159+
);
160+
161+
//the quadEncoder
162+
quadEncoder quadEncoder(encA,encB);//simple quad encoder driver
163+
quadEncoderStream enc(quadEncoder,5);// simple quad encoder fake Stream
164+
165+
//a keyboard with only one key :D, this is the encoder button
166+
keyMap encBtn_map[]={{-encBtn,13}};//negative pin numbers means we have a pull-up, this is on when low
167+
keyLook<1> encButton(encBtn_map);
168+
169+
//multiple inputs allow conjugation of the quadEncoder with a single key keyboard that is the quadEncoder button
170+
Stream* in[]={&enc,&encButton};
171+
chainStream<2> quadEncoder_button(in);
172+
173+
//alternative to previous but now we can input from Serial too...
174+
Stream* in3[]={&enc,&encButton,&Serial};
175+
chainStream<3> allIn(in3);
176+
177+
//describing a menu output, alternatives so far are Serial or LiquidCrystal LCD
178+
menuPrint serial(Serial);
179+
#if (LCD_WIRE!=LCDWIRE_NONE)
180+
menuLCD lcd(lcd1,16,2);
181+
#endif
182+
#if (USE_TFT == 1)
183+
menuGFX gfx(tft);
184+
//menuGFX gfx(tft,BLUE,BLACK,WHITE,SILVER,5,8);
185+
#endif
186+
menuPrint menuSerialOut(Serial);//describe output device
187+
188+
/////////////////////////////////////////////////////////////////////////
189+
void setup() {
190+
mainMenu.data[2]->enabled=false;//disabling option
191+
192+
Serial.begin(9600);
193+
Serial.println("menu system test");
194+
195+
#if ((LCD_WIRE != LCDWIRE_NONE) || (USE_TFT == 1))
196+
pinMode(vpinsSPI_CS,OUTPUT);
197+
digitalWrite(vpinsSPI_CS,LOW);
198+
#endif
199+
200+
#if (LCD_WIRE == LCDWIRE_VPINS_SPI)
201+
SPI.begin();
202+
lcd1.begin(16,2);
203+
lcd1.print("Menu test");
204+
#endif
205+
206+
#if (LCD_WIRE == LCDWIRE_VPINS_I2C)
207+
Wire.begin();
208+
// LCD is wired over i2c to another AVR that uses virtual pins and shift registers to control it and virtual port server to share it Serial.println("waiting for servers...");
209+
srv_vpa.begin();// wait for server ready (all on same server, so)
210+
//srv_vpb.begin();// wait for server ready
211+
Serial.println("all servers ready!");
212+
213+
#endif
214+
215+
#if (USE_TFT == 1)
216+
digitalWrite(vpinsSPI_CS,HIGH);
217+
digitalWrite(tftCS,HIGH);
218+
tft.initR(INITR_BLACKTAB);
219+
tft.setRotation(3);
220+
tft.setTextWrap(false);
221+
tft.setTextColor(ST7735_RED);
222+
tft.setTextSize(2);
223+
gfx.resX*=2;//update resolution after font size change
224+
gfx.resY*=2;//update resolution after font size change
225+
tft.fillScreen(ST7735_BLACK);
226+
tft.print("Menu test on GFX");
227+
tft.setCursor(0,10);
228+
//update limits after screen rotation
229+
gfx.maxX=tft.width()/gfx.resX;
230+
gfx.maxY=tft.height()/gfx.resY;
231+
#endif
232+
233+
pinMode(encBtn, INPUT);
234+
digitalWrite(encBtn,1);
235+
236+
pinMode(LEDPIN,OUTPUT);
237+
238+
delay(300);
239+
}
240+
241+
///////////////////////////////////////////////////////////////////////////////
242+
// testing the menu system
243+
void loop() {
244+
//mainMenu.activate(menuSerialOut,Serial);//show menu to Serial and read keys from Serial
245+
//Serial.println("");
246+
//Serial.println("Restarting...");
247+
248+
#if (LCD_WIRE != LCDWIRE_NONE)
249+
//digitalWrite(vpinsSPI_CS,LOW);
250+
//digitalWrite(tftCS,LOW);
251+
//mainMenu.activate(lcd,allIn);//show menu on LCD and use multiple inputs to navigate (defined encoder, encoder button, serial)
252+
//mainMenu.activate(lcd,Serial);//very bad combination!
253+
#endif
254+
255+
#if (USE_TFT == 1)
256+
digitalWrite(vpinsSPI_CS,HIGH);
257+
digitalWrite(tftCS,HIGH);
258+
mainMenu.activate(gfx,allIn);//show menu on LCD and use multiple inputs to navigate (defined encoder, encoder button, serial)
259+
#endif
260+
261+
}
262+
263+
void percentBar(menuOut &o,int percent) {
264+
int i=map(percent, 0, 100, 0, o.maxX);
265+
for(int n=0;n<o.maxX;n++)
266+
o.print((char)(n<i?255:' '));
267+
}
268+
269+
//read a value from the input stream device (encoder or serial)
270+
void setValue(int &value,prompt &p,menuOut &o, Stream &i,const char* text,const char* units,int sensivity,int low,int hi,int steps,void (*func)()) {
271+
o.clear();
272+
int at=strlen(text);//.length();
273+
o.setCursor(0,0);
274+
o.print(text);
275+
/*if (o.style==menuOut::enumerated) {//probably a Serial terminal -------------------------------------
276+
//long timeout because some terminals send data righ away when typed, and parseInt would parse a partial number
277+
i.setTimeout(10000);//lib gives no access to previous timeout value :( ... cant restore it then, i would wait forever if possible
278+
value=i.parseInt();//assuming data was all delivered to the buffer (we had a large timeout)
279+
//clamp the entry
280+
if (value>hi) value=hi;
281+
else if (value<low) value=low;
282+
i.setTimeout(1000);//assuming it was default
283+
Serial.println(value);//feed back
284+
while(i.available()) i.read();//clean up extra characters to avoid reentry
285+
} else {*/// then we assume its some kind of encoder ---------------------------------------------------
286+
if (!steps) steps=(hi-low)/(float)o.maxX;
287+
float fact=((float)sensivity)/((float)steps);//sensivity factor
288+
float pos=quadEncoder.pos*fact;
289+
float last=pos;
290+
while(encButton.read()!=13) {
291+
//clamp value
292+
if (value>hi) value=hi;
293+
else if (value<low) value=low;
294+
o.setCursor(at,0);
295+
o.print(value);
296+
o.print(units);
297+
o.print(" ");
298+
o.setCursor(0,1);
299+
percentBar(o,map(value,low,hi,0,100));
300+
pos=quadEncoder.pos*fact;
301+
int delta=pos-last;
302+
if (delta) {
303+
value+=delta;
304+
last=pos;
305+
}
306+
//func();
307+
}
308+
delay(100);
309+
while(encButton.read()==13);
310+
//}
311+
}
312+

examples/serial_menu/serial_menu.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include <menu.h>//menu macros and objects
22
#include <menuFields.h>
33
#include <menuPrint.h>
4-
#include <streamFlow.h>
4+
//#include <streamFlow.h>
55

66
int param;
77

menu.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ www.r-site.net
2424

2525
#include <Stream.h>
2626
#include <HardwareSerial.h>
27-
#include "../utils/streamFlow.h"
27+
//#include <streamFlow.h>
2828

2929
class prompt;
3030
class menu;

menuLCD.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ www.r-site.net
3636
virtual void print(double i) {lcd.print(i);};
3737
virtual void println(double i) {lcd.println(i);};
3838
virtual void print(prompt &o,bool selected,int idx,int posY,int width) {
39-
lcd.setCursor(0,posY);
39+
clearLine(posY);
4040
print(selected?(o.enabled?menu::enabledCursor:menu::disabledCursor):' ');
4141
o.printTo(*this);
4242
}

menuLCDs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ www.r-site.net
3939
virtual void print(double i) {lcd.print(i);};
4040
virtual void println(double i) {lcd.println(i);};
4141
virtual void print(prompt &o,bool selected,int idx,int posY,int width) {
42-
lcd.setCursor(0,posY);
42+
clearLine(posY);
4343
print(selected?(o.enabled?menu::enabledCursor:menu::disabledCursor):' ');
4444
o.printTo(*this);
4545
}

0 commit comments

Comments
 (0)