Closed PeteMoog closed 4 years ago
Hi Pete!
It should work...
feel free to add error messages or code to this issue :+1:
rui
many thanks for the quick reply, i am on child care duties in the morning but will try as soon as i can get to my desk, 👍
Hi again I have been working on this frequently since we last spoke but have been reluctant to ask for help as my C++ and arduino knowledge is so basic I thought I had better RTFM first, which I now have, my understanding is slightly greater but much of it is still a mystery.
I now have an example compiling and the screen displaying the default menu, I also know the buttons on the shield are being read via the SPI as I have put some code in the Void loop() to read the buttons using the shield's seesaw/SPI and when I press a button or move the joystick I see these being printed in the serial monitor view (i am using eclipse/sloeber).
#include <Arduino.h>
/********************
Sept. 2014 ~ Oct 2016 Rui Azevedo - ruihfazevedo(@rrob@)gmail.com
menu with adafruit GFX
output: 1.8" TFT 128*160 (ST7735 HW SPI)
input: Serial + encoder
www.r-site.net
alternative encoder (clickEncoder) uses:
https://github.com/0xPIT/encoder
https://github.com/PaulStoffregen/TimerOne
***/
//removed as extra libs are not included into travis
// #define USE_CLICK_ENCODER
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <menu.h>
#include <menuIO/adafruitGfxOut.h>
#ifdef USE_CLICK_ENCODER
#include <TimerOne.h>
#include <ClickEncoder.h>
#include <menuIO/clickEncoderIn.h>
#else
#include <menuIO/encoderIn.h>
#endif
#include <menuIO/keyIn.h>
#include <menuIO/chainStream.h>
#include <menuIO/serialOut.h>
#include <menuIO/serialIn.h>
#include <Adafruit_seesaw.h>
#include <Adafruit_TFTShield18.h>
Adafruit_TFTShield18 ss;
using namespace Menu;
//ST7735 1.8TFT 128x160 This was original by RUI - replaced below by example from seesaw_shield18_test
// #define TFT_CS A1
// #define TFT_DC A0
// #define TFT_RST A2
// #define SD_CS 4 // Chip select line for SD card on Shield //from seesaw_shield18_test
#define TFT_CS 10 // Chip select line for TFT display on Shield //from seesaw_shield18_test
#define TFT_DC 8 // Data/command line for TFT on Shield //from seesaw_shield18_test
#define TFT_RST -1 // Reset line for TFT is handled by seesaw! //from seesaw_shield18_test
Adafruit_ST7735 gfx(TFT_CS, TFT_DC, TFT_RST);
#define LEDPIN A3
// rotary encoder pins
#define encA 2
#define encB 3
#define encBtn 4
result doAlert(eventMask e, prompt &item);
int test=55;
int ledCtrl=LOW;
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,"Main test menu",doNothing,noEvent,wrapStyle
,OP("Speed",doNothing,noEvent)
,OP("Distance",doNothing,noEvent)
// ,FIELD(test,"Test","%",0,100,10,1,doNothing,noEvent,wrapStyle)
,FIELD(test,"Pause int","%",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 ST7735_GRAY RGB565(128,128,128)
const colorDef<uint16_t> colors[6] MEMMODE={
{{(uint16_t)ST7735_BLACK,(uint16_t)ST7735_BLACK}, {(uint16_t)ST7735_BLACK, (uint16_t)ST7735_BLUE, (uint16_t)ST7735_BLUE}},//bgColor
{{(uint16_t)ST7735_GRAY, (uint16_t)ST7735_GRAY}, {(uint16_t)ST7735_WHITE, (uint16_t)ST7735_WHITE, (uint16_t)ST7735_WHITE}},//fgColor
{{(uint16_t)ST7735_WHITE,(uint16_t)ST7735_BLACK}, {(uint16_t)ST7735_YELLOW,(uint16_t)ST7735_YELLOW,(uint16_t)ST7735_RED}},//valColor
{{(uint16_t)ST7735_WHITE,(uint16_t)ST7735_BLACK}, {(uint16_t)ST7735_WHITE, (uint16_t)ST7735_YELLOW,(uint16_t)ST7735_YELLOW}},//unitColor
{{(uint16_t)ST7735_WHITE,(uint16_t)ST7735_GRAY}, {(uint16_t)ST7735_BLACK, (uint16_t)ST7735_BLUE, (uint16_t)ST7735_WHITE}},//cursorColor
{{(uint16_t)ST7735_WHITE,(uint16_t)ST7735_YELLOW},{(uint16_t)ST7735_BLUE, (uint16_t)ST7735_RED, (uint16_t)ST7735_RED}},//titleColor
};
serialIn serial(Serial);
#ifdef USE_CLICK_ENCODER
ClickEncoder clickEncoder(encA,encB,encBtn);
ClickEncoderStream encStream(clickEncoder,1);
MENU_INPUTS(in,&encStream,&serial);
void timerIsr() {clickEncoder.service();}
#else
encoderIn<encA,encB> encoder;//simple quad encoder driver
encoderInStream<encA,encB> encStream(encoder,4);// simple quad encoder fake Stream
//a keyboard with only one key as the encoder button
keyMap encBtn_map[]={{-encBtn,defaultNavCodes[enterCmd].ch}};//negative pin numbers use internal pull-up, this is on when low
keyIn<1> encButton(encBtn_map);//1 is the number of keys
MENU_INPUTS(in,&encStream,&encButton,&serial);
#endif
#define MAX_DEPTH 4
#define textScale 1
MENU_OUTPUTS(out,MAX_DEPTH
,ADAGFX_OUT(gfx,colors,6*textScale,9*textScale,{0,0,14,8},{14,0,14,8})
,SERIAL_OUT(Serial)
);
NAVROOT(nav,mainMenu,MAX_DEPTH,in,out);
//when menu is suspended
result idle(menuOut& o,idleEvent e) {
if (e==idling) {
o.println(F("suspended..."));
o.println(F("press [select]"));
o.println(F("to continue"));
}
return proceed;
}
//config myOptions('*','-',defaultNavCodes,false);
void setup() {
//options=&myOptions;//can customize options
pinMode(TFT_CS, OUTPUT);
digitalWrite(TFT_CS, LOW);
pinMode(LEDPIN,OUTPUT);
Serial.begin(9600);
while(!Serial);
Serial.println("menu 4.x V2 test");
Serial.flush();
nav.idleTask=idle;//point a function to be used when menu is suspended
mainMenu[1].disable();
//outGfx.usePreview=true;//reserve one panel for preview?
//nav.showTitle=false;//show menu title?
// Start seesaw helper chip
if (!ss.begin()){
Serial.println("seesaw could not be initialized!");
while(1);
}
Serial.println("seesaw started");
Serial.print("Version: "); Serial.println(ss.getVersion(), HEX);
// Start set the backlight off
//ss.setBacklight(TFTSHIELD_BACKLIGHT_OFF);
// Reset the TFT
ss.tftReset();
// Initialize 1.8" TFT
gfx.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab
//Serial.println("TFT OK!");
ss.setBacklight(64000);
//pinMode(encBtn, INPUT_PULLUP);
#ifdef USE_CLICK_ENCODER
Timer1.initialize(1000);
Timer1.attachInterrupt(timerIsr);
#else
encButton.begin();
encoder.begin();
#endif
SPI.begin();
gfx.initR(INITR_BLACKTAB);
gfx.setRotation(3);
gfx.setTextSize(textScale);//test scalling
gfx.setTextWrap(false);
gfx.fillScreen(ST7735_BLACK);
gfx.setTextColor(ST7735_RED,ST7735_BLACK);
gfx.println("Menu 4.x test GFX");
delay(1000);
}
uint8_t buttonhistory = 0;
uint8_t oldbuttonhistory =0;
void loop() {
// Following block reads switch inputs from SPI interface (seesaw) copied from seesaw_shield18
uint32_t buttons = ss.readButtons();
if(! (buttons & TFTSHIELD_BUTTON_DOWN)){ // DOWN
buttonhistory |= 1;
}
if(! (buttons & TFTSHIELD_BUTTON_LEFT)){ // LEFT
buttonhistory |= 2;
}
if(! (buttons & TFTSHIELD_BUTTON_UP)){ // UP
buttonhistory |= 4;
}
if(! (buttons & TFTSHIELD_BUTTON_RIGHT)){ // RIGHT
buttonhistory |= 8;
}
if(! (buttons & TFTSHIELD_BUTTON_1)){ // Button 1
buttonhistory |= 16;
}
if(! (buttons & TFTSHIELD_BUTTON_2)){ // Button 2
buttonhistory |= 32;
}
if(! (buttons & TFTSHIELD_BUTTON_3)){ // Button 3
buttonhistory |= 64;
}
if (! (buttons & TFTSHIELD_BUTTON_IN)) { // Button IN
buttonhistory |= 128;
}
if (oldbuttonhistory != buttonhistory) {
serial.println(buttonhistory);
}
oldbuttonhistory = buttonhistory;
// Serial.println(TFTSHIELD_BUTTON_1);
// Serial.println(buttons);
nav.poll();//this device only draws when needed
digitalWrite(LEDPIN, ledCtrl);
delay(1000);//simulate a delay when other tasks are done
buttonhistory = 0;
}
What I am completely stuck on is how to I transfer the button presses on the shield into Serial input to control ArduinoMenu?
Any example code or examples would be greatly appreciated.
Thanks in advance
P
Hi Rui I have found an example called "codeCtrl.ino" and noticed the "nav.donav(upCmd)" statements, I added these to my loop section as follows and I now have a working screen and the joystick almost works. I cant seem to enter any submenus, or change the 55% in the example, why could that be?
As you can see I started trying to write commands to serialIn so I could concatenate this stream using Chainstream and subsequently after a bit more reading I would have used MENU_INPUTS after realising this does the same thing as chainstream. Would any of the previous methods I mention been better that method I am posting now?
I want to use ArduinoMenu to control a few stepper motors, they must run uninterrupted and run at a defined speed and defined number of steps, I will use the menu so I can set these parameters. The duration of this may be as much as 30 minutes and the steppers should run uninterrupted with the exception of a possible ABORT command driven from a dedicated hardware button on the shield should things go wrong in the physical world.
void loop() {
// Following block reads switch inputs from SPI interface (seesaw) copied from seesaw_shield18
uint32_t buttons = ss.readButtons();
if(! (buttons & TFTSHIELD_BUTTON_DOWN)){ // DOWN
buttonhistory |= 1;
// strIn.write(downCmd);
nav.doNav(downCmd);
}
if(! (buttons & TFTSHIELD_BUTTON_LEFT)){ // LEFT
buttonhistory |= 2;
// strIn.write(leftCmd);
nav.doNav(leftCmd);
}
if(! (buttons & TFTSHIELD_BUTTON_UP)){ // UP
buttonhistory |= 4;
// strIn.write(upCmd);
nav.doNav(upCmd);
}
if(! (buttons & TFTSHIELD_BUTTON_RIGHT)){ // RIGHT
buttonhistory |= 8;
// strIn.write(rightCmd);
nav.doNav(rightCmd);
}
if(! (buttons & TFTSHIELD_BUTTON_1)){ // Button 1
buttonhistory |= 16;
// strIn.write(Button1=1);
}
if(! (buttons & TFTSHIELD_BUTTON_2)){ // Button 2
buttonhistory |= 32;
// strIn.write(Button2=1);
}
if(! (buttons & TFTSHIELD_BUTTON_3)){ // Button 3
buttonhistory |= 64;
// strIn.write(Button3=1);
}
if (! (buttons & TFTSHIELD_BUTTON_IN)) { // Button IN
buttonhistory |= 128;
// strIn.write(idxCmd);
nav.doNav(upCmd);
}
if (oldbuttonhistory != buttonhistory) {
serial.println(buttonhistory);
}
oldbuttonhistory = buttonhistory;
// Serial.println(TFTSHIELD_BUTTON_1);
// Serial.println(buttons);
nav.poll();//this device only draws when needed
digitalWrite(LEDPIN, ledCtrl);
delay(1000);//simulate a delay when other tasks are done
buttonhistory = 0;
}
PS. I also joined the Gitter bbut I think people are away on bank holidays...
Hi Pete
Thanks for sharing the code... yes, gitter was a bit abandoned but text stays there, I'm on a kindo of holiday cabling my home made CNC.
Stay on holiday, please dont talk to me again until it's Finished 👍
When you are back from holiday tell me how big your CNC is.
PS. fixed the select menu thing, it was a typo.
All almost work, as few small glitches with secondary panel having blank lines when scrolling down the main panel but sure its something I have done. Will close this issue and open a fresh one if I can resolve it. Thanks for your help Rui.
hi I am using a a mega 2560 with the Adafruit 1.8" TFT + joystick and 3 button shield (it's the V2 Shield) here https://www.adafruit.com/product/802
Is it possible to use ArduinoMenu with this shield? the shield uses i2c seesaw chip to communicate and I am struggling to get anything running (or even to compile) to use this board and ArduinoMeno, If there is any sample code that someone could direct me to it would be very helpful. even some ideas to the most suitable libraries or includes would be very helpful.
Do I use
include
include
from the shield example... OR
include
that rui uses in his example "menu_tft_test.ino"
This is my Arduio and first project, I fear I have bitten off more than I can chew!
FYI the board and shield are wired up correctly and the following example runs fine... https://learn.adafruit.com/1-8-tft-display/testing-the-shield
thanks in advance....
Pete