Register / Login | Desktop view |
#ifndef MENU_GENERATED_CODE_H
#define MENU_GENERATED_CODE_H
#include <tcMenu.h>
#include "SerialTransport.h"
#include <RemoteConnector.h>
#include "tcMenuU8g2.h"
// all define statements needed
#define TCMENU_USING_PROGMEM true
#define ENCODER_PIN_A 28
#define ENCODER_PIN_B 29
#define ENCODER_PIN_OK 30
// all variables that need exporting
extern U8G2_SSD1325_NHD_128X64_F_4W_HW_SPI gfx; //like this?--> U8G2_SSD1325_NHD_128X64_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 23, /* dc=*/ 22, /* reset=*/ 24);
extern U8g2MenuRenderer renderer;
extern IoAbstractionRef io8574;
// all menu item forward references.
extern AnalogMenuItem menuGeneralVolume;
extern BooleanMenuItem menuMute;
extern AnalogMenuItem menuHighLevel;
extern AnalogMenuItem menuMidLevel;
extern AnalogMenuItem menuLowLevel;
extern BackMenuItem menuBackVolume;
extern SubMenuItem menuVolume;
extern const ConnectorLocalInfo applicationInfo;
// Callback functions must always include CALLBACK_FUNCTION after the return type
#define CALLBACK_FUNCTION
void setupMenu();
#endif // MENU_GENERATED_CODE_H
#include "Arduino_menu.h"
// the width and height of the attached OLED display.
#define OLED_WIDTH 128 <<<--- is that ok?
#define OLED_HEIGHT 64 <<<---- is that ok?
U8G2_SSD1325_NHD_128X64_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 23, /* dc=*/ 22, /* reset=*/ 24);
IoAbstractionRef arduinoPins = ioUsingArduino();
void setup() {
setupMenu();
}
void loop() {
taskManager.runLoop();
}
void CALLBACK_FUNCTION onHighLevel(int id) {
// TODO - your menu change code
}
void CALLBACK_FUNCTION onDisplayContrast(int id) {
// TODO - your menu change code
}
void CALLBACK_FUNCTION onLowLevel(int id) {
// TODO - your menu change code
}
void CALLBACK_FUNCTION onGeneralLevel(int id) {
// TODO - your menu change code
}
void CALLBACK_FUNCTION onMidLevel(int id) {
// TODO - your menu change code
}
void CALLBACK_FUNCTION onMute(int id) {
// TODO - your menu change code
}
#include <U8x8lib.h>
#include <U8g2lib.h>
#include "takeOverDisplay_menu.h"
//#include <EepromAbstractionWire.h>
#include <IoAbstractionWire.h>
#include <TaskManager.h>
//#include <RemoteAuthentication.h>
//#include <RemoteMenuItem.h>
/**
* This TcMenu example shows how to take over the display for your own purposes from a menu item.
* It also shows how to use the dialog facilities to locally show an information dialog and also a
* question dialog.
*
* For more detail see the README.md file
*/
// Arduino direct Pins
IoAbstractionRef arduinoPins = ioUsingArduino();
//u8g2 Display Configurieren
U8G2_SSD1325_NHD_128X64_F_4W_HW_SPI my_u8g2(U8G2_R0, /* cs=*/ 23, /* dc=*/ 22, /* reset=*/ 24);
// ? F=FullFrame ? Constuckt bezieht sich nur auf die U8G2lib, nur damit wird das Display ohne Menu (takeOverdispaly) gesteuert (z.B. in myDisplayFunktion).
// ? renderer wird in ****_menu.h konfiguriert. der Konstruckt 'renderer' wird zum steuern der u8g2lib im Menu benutzt.
//extern U8g2MenuRenderer renderer;
// U8g2GfxMenuConfig config;
// a counter that we use in the display function when we take over the display.
int counter = 0;
// if you don't have an i2c rom uncomment the avr variant and remove the i2c one.
/*AvrEeprom eeprom; */
void setup() {
my_u8g2.begin(); //u8g2 inizialisieren
U8g2GfxMenuConfig config;
Serial.begin(115200);
// When the renderer times out and is about to reset to main menu, you can get a callback.
// For example if the menu should only be displayed during configuration.
//
// Call BEFORE setupMenu to ensure it takes effect immediately, call AFTER setupMenu if you
// want to start in menu mode, but then apply the reset handler from that point onwards.
renderer.setResetIntervalTimeSeconds(60); // die ResetZeit bis zum TakeOverMenu(max 60sec), ? BaseRenderer.h
renderer.setResetCallback([] {
counter = 0;
renderer.takeOverDisplay(myDisplayFunction);
});
serdebug("Added the reset callback");
//prepareDisplayConfig();
config.titleFont = u8g2_font_cupcakemetoyourleader_tr; // ?----- that is not working
// this is put in by the menu designer and must be called (always ensure devices are setup first).
setupMenu();
// here we use the EEPROM to load back the last set of values.
//menuMgr.load(eeprom);
}
//
// standard setup for all taskManager based sketches. Always call runLoop in the loop.
// Never do anything long running in here.
//
void loop() {
taskManager.runLoop();
}
//
// When the food choice option is changed on the menu, this function is called, it takes
// the value from menuFood and renders it as text in the menuText text item.
//
void CALLBACK_FUNCTION onFoodChoice(int /*id*/) {
// copy the enum text for the current value
char enumStr[20];
int enumVal = menuFood.getCurrentValue();
menuFood.copyEnumStrToBuffer(enumStr, sizeof(enumStr), enumVal);
Serial.print("Changed food choice to ");
Serial.println(enumStr);
// and put it into a text menu item
menuText.setTextValue(enumStr);
}
//
// this is the function called by the renderer every 1/5 second once the display is
// taken over, we pass this function to takeOverDisplay below.
//
void myDisplayFunction(unsigned int encoderValue, bool clicked) {
if(counter == 0) {
switches.changeEncoderPrecision(999, 50);
//serdebug("in myDisplayFunktion");
my_u8g2.clearBuffer(); //Speicher lehren
my_u8g2.setFont(u8g2_font_cupcakemetoyourleader_tr);
my_u8g2.drawStr(15,18,"We have it!"); //String ausgeben x,y, string
my_u8g2.setFont(u8g2_font_7x14_tf);
my_u8g2.setCursor(13,35);
my_u8g2.print("fast geschafft");
my_u8g2.sendBuffer(); // den oben gefüllten Speicher ausgeben
}
// We are told when the button is pressed in by the boolean parameter.
// When the button is clicked, we give back to the menu..
if(clicked) {
renderer.giveBackDisplay();
counter = 0;
}
else {
//u8g2.clearBuffer();
my_u8g2.drawRFrame(18,44,90,14, 4); //Ein Rechteck mit Abrundungen Zeichnen (x,y,breite,höhe,radfius)
my_u8g2.setFont(u8g2_font_unifont_t_symbols); //Zeichensatz wählen (unifont_symbols enthält nur zeichen
my_u8g2.drawGlyph(53,59,0x2603); //ein Symbol zeichnen x,y,hex-wert aus Font
my_u8g2.setFont(u8g2_font_t0_11b_tn);
my_u8g2.setCursor(23,55); //Position x,y, in Pixels
my_u8g2.print(encoderValue); // Str und int Ausgabe
my_u8g2.setCursor(82,55);
my_u8g2.print(++counter);
my_u8g2.sendBuffer(); //den oben gefüllten Buffer ausgeben
/*
char buffer[5];
// otherwise update the counter.
my_u8g2.setCursor(4, 48);
ltoaClrBuff(buffer, ++counter, 4, ' ', sizeof(buffer));
my_u8g2.print(buffer);
my_u8g2.setCursor(80, 48);
ltoaClrBuff(buffer, encoderValue, 4, '0', sizeof(buffer));
my_u8g2.print(buffer);
*/
}
}
//
// We have an option on the menu to take over the display, this function is called when that
// option is chosen.
//
void CALLBACK_FUNCTION onTakeOverDisplay(int /*id*/) {
// in order to take over rendering onto the display we just request the display
// at which point tcMenu will stop rendering until the display is "given back".
// Don't forget that LiquidCrystalIO uses task manager and things can be happening
// in the background. Always ensure all operations with the LCD occur on the rendering
// call back.
counter = 0;
renderer.takeOverDisplay(myDisplayFunction);
}
const char pgmInfoHeader[] PROGMEM = "Information dialog";
const char pgmQuestionHeader[] PROGMEM = "Order Food?";
void CALLBACK_FUNCTION onInfoDlg(int /*id*/) {
// every renderer apart from NoRenderer has a dialog, that can be used to present
// very basic info locally onto any display. Used in situations where something
// needs to be confirmed / printed onto the local display.
BaseDialog* dlg = renderer.getDialog();
if(!dlg) return;
// first we set the buttons how we want them. BTNTYPE_NONE means no button.
dlg->setButtons(BTNTYPE_NONE, BTNTYPE_CLOSE);
// then we show the dialog - 2nd boolean parameter is if dialog is local only
dlg->show(pgmInfoHeader, true);
// and then we set the second line (buffer) - must be after show.
dlg->copyIntoBuffer("to be set..");
// you can set the dialog buffer at some point later, it's safe, even if it's been dismissed.
taskManager.scheduleOnce(1000, [] {
BaseDialog* dlg = renderer.getDialog();
dlg->copyIntoBuffer("now it's set..");
});
}
//
// It's also possible to know when the dialog has finished, and what button was pressed.
// This is done by passing a function like below as second parameter to show.
//
void onFinished(ButtonType btn, void* /*userData*/) {
if(btn == BTNTYPE_ACCEPT) {
Serial.print("Food chosen was ");
char sz[20];
menuFood.copyEnumStrToBuffer(sz, sizeof(sz), menuFood.getCurrentValue());
Serial.println(sz);
}
else {
Serial.println("User did not choose to proceed.");
}
}
void CALLBACK_FUNCTION onQuestionDlg(int /*id*/) {
// yet another dialog, to ask a question this time.
BaseDialog* dlg = renderer.getDialog();
// this time we use two buttons and provide the selected index at the end (zero based)
dlg->setButtons(BTNTYPE_ACCEPT, BTNTYPE_CANCEL, 1);
// we can optionally set some data that will be given to us in the finished call back.
dlg->setUserData(NULL);
// now we show the dialog (also giving the finished callback)
dlg->show(pgmQuestionHeader, true, onFinished);
// and lastly we set the text in the buffer area (2nd line)
char sz[20];
menuFood.copyEnumStrToBuffer(sz, sizeof(sz), menuFood.getCurrentValue());
dlg->copyIntoBuffer(sz);
}
//
// We have a save option on the menu to save the settings. In a real system we could instead
// look at using a power down detection circuit to do this. For more info see below link.
// https://www.thecoderscorner.com/electronics/microcontrollers/psu-control/detecting-power-loss-in-powersupply/
//
void CALLBACK_FUNCTION onSaveSettings(int /*id*/) {
// menuMgr.save(eeprom);
}
/**
* Provides a basic graphics configuration suitable for low / medium resolution displays
* @param config usually a global variable holding the graphics configuration.
*/
void prepareBasicU8x8Config(U8g2GfxMenuConfig& config) {
makePadding(config.titlePadding, 1, 1, 1, 1);
makePadding(config.itemPadding, 1, 1, 1, 1);
makePadding(config.widgetPadding, 2, 2, 0, 2);
config.bgTitleColor = WHITE;
config.fgTitleColor = BLACK;
config.titleFont = u8g2_font_6x12_tf;
config.titleBottomMargin = 1;
config.widgetColor = BLACK;
config.titleFontMagnification = 1;
config.bgItemColor = BLACK;
config.fgItemColor = WHITE;
config.bgSelectColor = BLACK;
config.fgSelectColor = WHITE;
config.itemFont = u8g2_font_6x10_tf;
config.itemFontMagnification = 1;
config.editIcon = loResEditingIcon;
config.activeIcon = loResActiveIcon;
config.editIconHeight = 6;
config.editIconWidth = 8;
}
tcMenuU8g2.cpp.o: In function makePadding
Error linking for board Arduino Due (Programming Port)
GfxMenuConfig.h:36: multiple definition of prepareBasicU8x8Config(ColorGfxMenuConfig<unsigned char const*>&)
Build failed for project 'takeOverDisplay'
takeOverDisplay.cpp.o: C:\Users\Andre\Documents\Arduino\
#include <U8x8lib.h>
#include <U8g2lib.h>
#include "takeOverDisplay_menu.h"
//#include <EepromAbstractionWire.h>
#include <IoAbstractionWire.h>
#include <TaskManager.h>
//#include <RemoteAuthentication.h>
//#include <RemoteMenuItem.h>
/**
* This TcMenu example shows how to take over the display for your own purposes from a menu item.
* It also shows how to use the dialog facilities to locally show an information dialog and also a
* question dialog.
*
* For more detail see the README.md file
*/
// Arduino direct Pins
IoAbstractionRef arduinoPins = ioUsingArduino();
//u8g2 Display Configurieren
U8G2_SSD1325_NHD_128X64_F_4W_HW_SPI my_u8g2(U8G2_R0, /* cs=*/ 23, /* dc=*/ 22, /* reset=*/ 24);
// ? F=FullFrame ? Constuckt bezieht sich nur auf die U8G2lib, nur damit wird das Display ohne Menu (takeOverdispaly) gesteuert (z.B. in myDisplayFunktion).
// ? renderer wird in ****_menu.h konfiguriert. der Konstruckt 'renderer' wird zum steuern der u8g2lib im Menu benutzt.
// a counter that we use in the display function when we take over the display.
int counter = 0;
// EEPROM storage - very useful for an amplifier, two options
// if you want to store to eeprom, just purchase an i2c AT24C128 or AT24C256 or other size EEPROM (very cheap) and reliable for saving and loading
// if it's implemented for you board, you could also use the EEPROM wrapper.
// See: https://www.thecoderscorner.com/products/arduino-libraries/io-abstraction/eeprom-impl-seamless-8-and-32-bit/
/*AvrEeprom eeprom; */
// never create a varialbe that's being passed somewhere else to keep in C locally
// unless it's allocated using new. Moved it to global.
U8g2GfxMenuConfig myConfig;
/**
* Here you can change the colours, padding and fonts for your display.
*/
void prepareIceMenuConfiguration(U8g2GfxMenuConfig& config) {
makePadding(config.titlePadding, 1, 1, 1, 1);
makePadding(config.itemPadding, 1, 1, 1, 1);
makePadding(config.widgetPadding, 2, 2, 0, 2);
config.bgTitleColor = WHITE;
config.fgTitleColor = BLACK;
config.titleFont = u8g2_font_6x12_tf;
config.titleBottomMargin = 1;
config.widgetColor = BLACK;
config.titleFontMagnification = 1;
config.bgItemColor = BLACK;
config.fgItemColor = WHITE;
config.bgSelectColor = BLACK;
config.fgSelectColor = WHITE;
config.itemFont = u8g2_font_6x10_tf;
config.itemFontMagnification = 1;
config.editIcon = loResEditingIcon;
config.activeIcon = loResActiveIcon;
config.editIconHeight = 6;
config.editIconWidth = 8;
}
void setup() {
my_u8g2.begin(); //u8g2 inizialisieren
Serial.begin(115200);
// When the renderer times out and is about to reset to main menu, you can get a callback.
// For example if the menu should only be displayed during configuration.
//
// Call BEFORE setupMenu to ensure it takes effect immediately, call AFTER setupMenu if you
// want to start in menu mode, but then apply the reset handler from that point onwards.
renderer.setResetIntervalTimeSeconds(60); // die ResetZeit bis zum TakeOverMenu(max 60sec), ? BaseRenderer.h
renderer.setResetCallback([] {
counter = 0;
renderer.takeOverDisplay(myDisplayFunction);
});
serdebug("Added the reset callback");
prepareIceMenuConfiguration(myConfig);
// this is put in by the menu designer and must be called (always ensure devices are setup first).
setupMenu();
// here we use the EEPROM to load back the last set of values.
//menuMgr.load(eeprom);
}
//
// standard setup for all taskManager based sketches. Always call runLoop in the loop.
// Never do anything long running in here.
//
void loop() {
taskManager.runLoop();
}
//
// When the food choice option is changed on the menu, this function is called, it takes
// the value from menuFood and renders it as text in the menuText text item.
//
void CALLBACK_FUNCTION onFoodChoice(int /*id*/) {
// copy the enum text for the current value
char enumStr[20];
int enumVal = menuFood.getCurrentValue();
menuFood.copyEnumStrToBuffer(enumStr, sizeof(enumStr), enumVal);
Serial.print("Changed food choice to ");
Serial.println(enumStr);
// and put it into a text menu item
menuText.setTextValue(enumStr);
}
//
// this is the function called by the renderer every 1/5 second once the display is
// taken over, we pass this function to takeOverDisplay below.
//
void myDisplayFunction(unsigned int encoderValue, bool clicked) {
if(counter == 0) {
switches.changeEncoderPrecision(999, 50);
//serdebug("in myDisplayFunktion");
my_u8g2.clearBuffer(); //Speicher lehren
my_u8g2.setFont(u8g2_font_cupcakemetoyourleader_tr);
my_u8g2.drawStr(15,18,"We have it!"); //String ausgeben x,y, string
my_u8g2.setFont(u8g2_font_7x14_tf);
my_u8g2.setCursor(13,35);
my_u8g2.print("fast geschafft");
my_u8g2.sendBuffer(); // den oben gefüllten Speicher ausgeben
}
// We are told when the button is pressed in by the boolean parameter.
// When the button is clicked, we give back to the menu..
if(clicked) {
renderer.giveBackDisplay();
counter = 0;
}
else {
//u8g2.clearBuffer();
my_u8g2.drawRFrame(18,44,90,14, 4); //Ein Rechteck mit Abrundungen Zeichnen (x,y,breite,höhe,radfius)
my_u8g2.setFont(u8g2_font_unifont_t_symbols); //Zeichensatz wählen (unifont_symbols enthält nur zeichen
my_u8g2.drawGlyph(53,59,0x2603); //ein Symbol zeichnen x,y,hex-wert aus Font
my_u8g2.setFont(u8g2_font_t0_11b_tn);
my_u8g2.setCursor(23,55); //Position x,y, in Pixels
my_u8g2.print(encoderValue); // Str und int Ausgabe
my_u8g2.setCursor(82,55);
my_u8g2.print(++counter);
my_u8g2.sendBuffer(); //den oben gefüllten Buffer ausgeben
/*
char buffer[5];
// otherwise update the counter.
my_u8g2.setCursor(4, 48);
ltoaClrBuff(buffer, ++counter, 4, ' ', sizeof(buffer));
my_u8g2.print(buffer);
my_u8g2.setCursor(80, 48);
ltoaClrBuff(buffer, encoderValue, 4, '0', sizeof(buffer));
my_u8g2.print(buffer);
*/
}
}
//
// We have an option on the menu to take over the display, this function is called when that
// option is chosen.
//
void CALLBACK_FUNCTION onTakeOverDisplay(int /*id*/) {
// in order to take over rendering onto the display we just request the display
// at which point tcMenu will stop rendering until the display is "given back".
// Don't forget that LiquidCrystalIO uses task manager and things can be happening
// in the background. Always ensure all operations with the LCD occur on the rendering
// call back.
counter = 0;
renderer.takeOverDisplay(myDisplayFunction);
}
const char pgmInfoHeader[] PROGMEM = "Information dialog";
const char pgmQuestionHeader[] PROGMEM = "Order Food?";
void CALLBACK_FUNCTION onInfoDlg(int /*id*/) {
// every renderer apart from NoRenderer has a dialog, that can be used to present
// very basic info locally onto any display. Used in situations where something
// needs to be confirmed / printed onto the local display.
BaseDialog* dlg = renderer.getDialog();
if(!dlg) return;
// first we set the buttons how we want them. BTNTYPE_NONE means no button.
dlg->setButtons(BTNTYPE_NONE, BTNTYPE_CLOSE);
// then we show the dialog - 2nd boolean parameter is if dialog is local only
dlg->show(pgmInfoHeader, true);
// and then we set the second line (buffer) - must be after show.
dlg->copyIntoBuffer("to be set..");
// you can set the dialog buffer at some point later, it's safe, even if it's been dismissed.
taskManager.scheduleOnce(1000, [] {
BaseDialog* dlg = renderer.getDialog();
dlg->copyIntoBuffer("now it's set..");
});
}
//
// It's also possible to know when the dialog has finished, and what button was pressed.
// This is done by passing a function like below as second parameter to show.
//
void onFinished(ButtonType btn, void* /*userData*/) {
if(btn == BTNTYPE_ACCEPT) {
Serial.print("Food chosen was ");
char sz[20];
menuFood.copyEnumStrToBuffer(sz, sizeof(sz), menuFood.getCurrentValue());
Serial.println(sz);
}
else {
Serial.println("User did not choose to proceed.");
}
}
`
void CALLBACK_FUNCTION onQuestionDlg(int /*id*/) {
// yet another dialog, to ask a question this time.
BaseDialog* dlg = renderer.getDialog();
// this time we use two buttons and provide the selected index at the end (zero based)
dlg->setButtons(BTNTYPE_ACCEPT, BTNTYPE_CANCEL, 1);
// we can optionally set some data that will be given to us in the finished call back.
dlg->setUserData(NULL);
// now we show the dialog (also giving the finished callback)
dlg->show(pgmQuestionHeader, true, onFinished);
// and lastly we set the text in the buffer area (2nd line)
char sz[20];
menuFood.copyEnumStrToBuffer(sz, sizeof(sz), menuFood.getCurrentValue());
dlg->copyIntoBuffer(sz);
}
//
// We have a save option on the menu to save the settings. In a real system we could instead
// look at using a power down detection circuit to do this. For more info see below link.
// https://www.thecoderscorner.com/electronics/microcontrollers/psu-control/detecting-power-loss-in-powersupply/
//
void CALLBACK_FUNCTION onSaveSettings(int /*id*/) {
// menuMgr.save(eeprom);
}
config.titleFont = u8g2_font_cupcakemetoyourleader_tr;
nothing changed in the Display.