Skip to content

Commit 123f991

Browse files
committed
Preparing for release 1.1, improved examples
1 parent 8789af7 commit 123f991

File tree

14 files changed

+493
-94
lines changed

14 files changed

+493
-94
lines changed

examples/analogDfRobot/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## Use a DF robot board to control the menu system
22

3+
To expediate the release, this example will now be in the next version of tcMenu
4+
35
This example assumes you've got an Uno / MEGA with the DF robot board.
46

57
It uses a the switches that are connected to analog 0 and tries to keep as much in line with the DF robot spec as possible.
@@ -9,3 +11,4 @@ It has two menu items, one to control the PWM output of pin 9, one to read back
911
I've assumed this will be built on either an Uno or MEGA boards, but should work equally well on any other Arduino board with only minor changes.
1012

1113
To get started you can either run as per instructions, or just load the `analogDfRobot.emf` file into the designer, select Code / Generate and change to match your setup.
14+
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,58 @@
11
#include "ledFlashNoRemote.h"
22
#include <EepromAbstraction.h>
33

4+
/**
5+
* This example controls the state of the built in LED using the menu. It also shows the
6+
* status of analog pin A0 on the display too.
7+
*
8+
* For more detail see the README.md file.
9+
*/
10+
11+
// This example saves it's state to EEPROM using the inbuilt eeprom support in tcMenu
12+
// You could choose an At24C based I2C eeprom too. See the takeOverDisplay example.
413
AvrEeprom eeprom;
514

15+
//
16+
// We register this function with task manager to be called every 200 millis and update the
17+
// menu item with the latest reading from pin A0.
18+
//
619
void updateAnalogMenuItem() {
720
menuA0Volts.setCurrentValue(analogRead(A0));
821
}
922

1023
void setup() {
24+
// needed in all sketches and generally added by the designer.
1125
setupMenu();
26+
27+
// We want to control the LED_BUILTIN so we must set to output first.
1228
pinMode(LED_BUILTIN, OUTPUT);
29+
30+
// now load back the previous state from EEPROM.
1331
menuMgr.load(eeprom);
32+
33+
// and set up the task that will read A0 and update the menu item.
1434
taskManager.scheduleFixedRate(200, updateAnalogMenuItem, TIME_MILLIS);
1535
}
1636

1737
void loop() {
38+
// we must always call runLoop in loop, do nothing that takes a long time in loop.
39+
// this is generally added by designer UI.
1840
taskManager.runLoop();
1941
}
2042

43+
//
44+
// When the LED menu item is changed, this is the callback function. We just read the current
45+
// state and set the built in LED pin accordingly.
46+
//
2147
void CALLBACK_FUNCTION onLedChange(int id) {
2248
digitalWrite(LED_BUILTIN, menuBuiltInLED.getBoolean());
2349
}
2450

51+
//
52+
// When the save menu item is pressed, this function is called, it updates the eeprom. In a real
53+
// life system you may want to do this on power down. See the below article:
54+
// https://www.thecoderscorner.com/electronics/microcontrollers/psu-control/detecting-power-loss-in-powersupply/
55+
//
2556
void CALLBACK_FUNCTION onSaveState(int id) {
2657
menuMgr.save(eeprom);
2758
}

examples/ledFlashNoRemote/ledFlashNoRemote.ino.backup

Lines changed: 0 additions & 17 deletions
This file was deleted.
Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
## Shows how to use Serial remote control with a simple menu
22

3-
This is a very simple menu with an example of how to configure remote control over the USB serial interface.
3+
This is a very simple menu with an example of how to configure remote control over the USB serial interface. Ethernet control is equally easy to use. Just create an ethernet instance as usual setting up IP address and MAC address and choose ethernet instead of serial in the code generator.
44

55
You can for example use the Java API or the protocol to communicate with your Arduino from another device.
66

7-
We'll soon be writing an API in C# that is fairly much inline with the Java API.
7+
We'll soon be writing an API in C# that is fairly much inline with the Java API. This will give even more options for using tcMenu remotely.
8+
9+
The files that are in this example:
10+
11+
* `remoteControlSerial.cpp` & `.h` are generated by the menu designer, they should not be edited, include the header file whenever you want to work with the menu items.
12+
* `remoteControlSerial.ino` is the sketch, it will be modified by the designer as needed to add call back functions and required start up code.
13+
* `remoteControlSerial.emf` open in the designer UI, used by the designer to store the menu structure. It is not needed at runtime, only for loading the design into the designer.
14+
* `SerialTransport.cpp` and `.h` is the actual serial transport plug in that is copied by tcmenu into your project, do not edit is overwritten at next code generation.
15+
* `tcMenuLiquidCrystal.cpp` and `.h` is the actual plugin for the display, do not edit will be overwritten at next code generation.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (c) 2018 https://www.thecoderscorner.com (Nutricherry LTD).
3+
* This product is licensed under an Apache license, see the LICENSE file in the top-level directory.
4+
*/
5+
6+
/**
7+
* Serial remote capability plugin. This file is a plugin file and should not be directly edited,
8+
* it will be replaced each time the project is built. If you want to edit this file in place,
9+
* make sure to rename it first.
10+
*/
11+
12+
#include "SerialTransport.h"
13+
#include "tcMenu.h"
14+
15+
SerialTagValServer remoteServer;
16+
17+
SerialTagValueTransport::SerialTagValueTransport() : TagValueTransport() {
18+
this->serialPort = NULL;
19+
}
20+
21+
void SerialTagValueTransport::close() {
22+
currentField.msgType = UNKNOWN_MSG_TYPE;
23+
currentField.fieldType = FVAL_PROCESSING_AWAITINGMSG;
24+
}
25+
26+
void SerialTagValServer::begin(Stream* portStream, const char* namePgm) {
27+
serPort.setStream(portStream);
28+
connector.setName(namePgm);
29+
taskManager.scheduleFixedRate(TICK_INTERVAL, []{remoteServer.runLoop();}, TIME_MILLIS);
30+
}
31+
32+
SerialTagValServer::SerialTagValServer() : connector(&serPort, 0) {
33+
}
34+
35+
void SerialTagValServer::runLoop() {
36+
connector.tick();
37+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright (c) 2018 https://www.thecoderscorner.com (Nutricherry LTD).
3+
* This product is licensed under an Apache license, see the LICENSE file in the top-level directory.
4+
*/
5+
6+
/**
7+
* @file SerialTransport.h
8+
*
9+
* Serial remote capability plugin. This file is a plugin file and should not be directly edited,
10+
* it will be replaced each time the project is built. If you want to edit this file in place,
11+
* make sure to rename it first.
12+
*/
13+
14+
#ifndef _TCMENU_SERIALTRANSPORT_H_
15+
#define _TCMENU_SERIALTRANSPORT_H_
16+
17+
#include <Arduino.h>
18+
#include "RemoteConnector.h"
19+
20+
/**
21+
* Serial transport is an implementation of TagValueTransport that works over a serial port
22+
*/
23+
class SerialTagValueTransport : public TagValueTransport {
24+
private:
25+
Stream* serialPort;
26+
public:
27+
SerialTagValueTransport();
28+
virtual ~SerialTagValueTransport() {}
29+
void setStream(Stream* stream) {this->serialPort = stream; }
30+
31+
virtual void flush() {serialPort->flush();}
32+
virtual int writeChar(char data) { return serialPort->write(data); }
33+
virtual int writeStr(const char* data) { return serialPort->write(data); }
34+
35+
virtual uint8_t readByte() { return serialPort->read(); }
36+
virtual bool readAvailable() { return serialPort->available(); }
37+
virtual bool available() { return serialPort->availableForWrite();}
38+
virtual bool connected() { return true;}
39+
40+
virtual void close();
41+
42+
};
43+
44+
/**
45+
* SerialTagValServer is the implementation of remote communication that provides
46+
* remote menu capability for Serial streams.
47+
*/
48+
class SerialTagValServer {
49+
private:
50+
SerialTagValueTransport serPort;
51+
TagValueRemoteConnector connector;
52+
public:
53+
/** Empty constructor - configured in begin */
54+
SerialTagValServer();
55+
/**
56+
* Begins serial communication on the given port. You must call begin on the stream first.
57+
* @param portStream the stream upon which to communicate, it must be already opened.
58+
* @param namePgm the local name of the application in PROGMEM
59+
*/
60+
void begin(Stream* portStream, const char* namePgm);
61+
/**
62+
* Arranged internally don't call yourself.
63+
*/
64+
void runLoop();
65+
66+
/** returns the remote connector associated with the connection */
67+
TagValueRemoteConnector* getRemoteConnector(int /*num*/) {return &connector;}
68+
};
69+
70+
/**
71+
* the global instance of the SerialTagValServer
72+
*/
73+
extern SerialTagValServer remoteServer;
74+
75+
#endif /* _TCMENU_SERIALTRANSPORT_H_ */
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
The code in this file uses open source libraries provided by thecoderscorner
3+
4+
DO NOT EDIT THIS FILE, IT WILL BE GENERATED EVERY TIME YOU USE THE UI DESIGNER
5+
INSTEAD EITHER PUT CODE IN YOUR SKETCH OR CREATE ANOTHER SOURCE FILE.
6+
7+
All the variables you may need access to are marked extern in this file for easy
8+
use elsewhere.
9+
*/
10+
11+
#include <tcMenu.h>
12+
#include "remoteControlSerial.h"
13+
14+
// Global variable declarations
15+
16+
LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7, ioUsingArduino());
17+
LiquidCrystalRenderer renderer(lcd, LCD_WIDTH, LCD_HEIGHT);
18+
19+
const char PROGMEM applicationName[] = "Serial Test";
20+
21+
// Global Menu Item declarations
22+
const PROGMEM AnyMenuInfo minfoPushMe = { "Push Me", 6, 0xffff, 0, onPushMe };
23+
ActionMenuItem menuPushMe(&minfoPushMe, NULL);
24+
const char enumStrFood_0[] PROGMEM = "Pizza";
25+
const char enumStrFood_1[] PROGMEM = "Pasta";
26+
const char enumStrFood_2[] PROGMEM = "Salad";
27+
const char* const enumStrFood[] PROGMEM = { enumStrFood_0, enumStrFood_1, enumStrFood_2 };
28+
const PROGMEM EnumMenuInfo minfoFood = { "Food", 5, 0xffff, 2, NO_CALLBACK, enumStrFood };
29+
EnumMenuItem menuFood(&minfoFood, 0, &menuPushMe);
30+
const PROGMEM TextMenuInfo minfoMyText = { "MyText", 4, 0xffff, 10, NO_CALLBACK };
31+
TextMenuItem menuMyText(&minfoMyText, &menuFood);
32+
const PROGMEM AnalogMenuInfo minfoA2Voltage = { "A2 Voltage", 3, 0xffff, 1024, NO_CALLBACK, 0, 200, "V" };
33+
AnalogMenuItem menuA2Voltage(&minfoA2Voltage, 0, &menuMyText);
34+
const PROGMEM AnalogMenuInfo minfoA1Voltage = { "A1 Voltage", 2, 0xffff, 1024, NO_CALLBACK, 0, 200, "V" };
35+
AnalogMenuItem menuA1Voltage(&minfoA1Voltage, 0, &menuA2Voltage);
36+
const PROGMEM AnalogMenuInfo minfoA0Voltage = { "A0 Voltage", 1, 0xffff, 1024, NO_CALLBACK, 0, 200, "V" };
37+
AnalogMenuItem menuA0Voltage(&minfoA0Voltage, 0, &menuA1Voltage);
38+
39+
// Set up code
40+
void setupMenu() {
41+
switches.initialise(ioUsingArduino(), true);
42+
menuMgr.initForEncoder(&renderer, &menuA0Voltage, ENCODER_PIN_A, ENCODER_PIN_B, ENCODER_PIN_OK);
43+
lcd.begin(LCD_WIDTH, LCD_HEIGHT);
44+
45+
remoteServer.begin(&Serial, applicationName);
46+
}
47+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"version":"1.00","projectName":"C:\\Users\\dave\\Documents\\Arduino\\libraries\\tcMenu\\examples\\remoteControlSerial\\remoteControlSerial.emf","author":"dave","lastEdited":{"seconds":1548498951,"nanos":445322400},"items":[{"parentId":0,"type":"analogItem","item":{"maxValue":1024,"offset":0,"divisor":200,"unitName":"V","name":"A0 Voltage","id":1,"eepromAddress":-1,"readOnly":false}},{"parentId":0,"type":"analogItem","item":{"maxValue":1024,"offset":0,"divisor":200,"unitName":"V","name":"A1 Voltage","id":2,"eepromAddress":-1,"readOnly":false}},{"parentId":0,"type":"analogItem","item":{"maxValue":1024,"offset":0,"divisor":200,"unitName":"V","name":"A2 Voltage","id":3,"eepromAddress":-1,"readOnly":false}},{"parentId":0,"type":"textItem","item":{"textLength":10,"name":"MyText","id":4,"eepromAddress":-1,"readOnly":false}},{"parentId":0,"type":"enumItem","item":{"enumEntries":["Pizza","Pasta","Salad"],"name":"Food","id":5,"eepromAddress":-1,"readOnly":false}},{"parentId":0,"type":"actionMenu","item":{"name":"Push Me","id":6,"eepromAddress":-1,"functionName":"onPushMe","readOnly":false}}],"codeOptions":{"embeddedPlatform":"ARDUINO","lastDisplayKey":2,"lastInputKey":1,"lastRemoteKey":2,"lastProperties":[{"name":"LCD_RS","latestValue":"8","subsystem":"DISPLAY"},{"name":"LCD_EN","latestValue":"9","subsystem":"DISPLAY"},{"name":"LCD_D4","latestValue":"4","subsystem":"DISPLAY"},{"name":"LCD_D5","latestValue":"5","subsystem":"DISPLAY"},{"name":"LCD_D6","latestValue":"6","subsystem":"DISPLAY"},{"name":"LCD_D7","latestValue":"7","subsystem":"DISPLAY"},{"name":"LCD_WIDTH","latestValue":"16","subsystem":"DISPLAY"},{"name":"LCD_HEIGHT","latestValue":"2","subsystem":"DISPLAY"},{"name":"LCD_PWM_PIN","latestValue":"-1","subsystem":"DISPLAY"},{"name":"PULLUP_LOGIC","latestValue":"true","subsystem":"INPUT"},{"name":"INTERRUPT_SWITCHES","latestValue":"false","subsystem":"INPUT"},{"name":"SWITCH_IODEVICE","latestValue":"","subsystem":"INPUT"},{"name":"ENCODER_PIN_A","latestValue":"2","subsystem":"INPUT"},{"name":"ENCODER_PIN_B","latestValue":"3","subsystem":"INPUT"},{"name":"ENCODER_PIN_OK","latestValue":"A3","subsystem":"INPUT"},{"name":"DEVICE_NAME","latestValue":"Serial Test","subsystem":"REMOTE"},{"name":"SERIAL_PORT","latestValue":"Serial","subsystem":"REMOTE"}]}}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
The code in this file uses open source libraries provided by thecoderscorner
3+
4+
DO NOT EDIT THIS FILE, IT WILL BE GENERATED EVERY TIME YOU USE THE UI DESIGNER
5+
INSTEAD EITHER PUT CODE IN YOUR SKETCH OR CREATE ANOTHER SOURCE FILE.
6+
7+
All the variables you may need access to are marked extern in this file for easy
8+
use elsewhere.
9+
*/
10+
11+
#ifndef MENU_GENERATED_CODE_H
12+
#define MENU_GENERATED_CODE_H
13+
14+
#include<IoAbstraction.h>
15+
#include<Wire.h>
16+
#include<tcMenu.h>
17+
18+
#include "tcMenuLiquidCrystal.h"
19+
#include <RemoteConnector.h>
20+
#include "SerialTransport.h"
21+
22+
// all export definitions
23+
#define ENCODER_PIN_A 2
24+
#define ENCODER_PIN_B 3
25+
#define ENCODER_PIN_OK A3
26+
27+
#define LCD_RS 8
28+
#define LCD_EN 9
29+
#define LCD_D4 4
30+
#define LCD_D5 5
31+
#define LCD_D6 6
32+
#define LCD_D7 7
33+
#define LCD_WIDTH 16
34+
#define LCD_HEIGHT 2
35+
#define LCD_PWM_PIN -1
36+
extern LiquidCrystal lcd;
37+
extern LiquidCrystalRenderer renderer;
38+
39+
40+
extern const char applicationName[];
41+
42+
43+
// all menu item forward references.
44+
extern ActionMenuItem menuPushMe;
45+
extern EnumMenuItem menuFood;
46+
extern TextMenuItem menuMyText;
47+
extern AnalogMenuItem menuA2Voltage;
48+
extern AnalogMenuItem menuA1Voltage;
49+
extern AnalogMenuItem menuA0Voltage;
50+
51+
// all callback functions must have this define on them, it is what the menu designer looks for.
52+
#define CALLBACK_FUNCTION
53+
54+
void CALLBACK_FUNCTION onPushMe(int id);
55+
56+
void setupMenu();
57+
58+
#endif // MENU_GENERATED_CODE_H
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#include "remoteControlSerial.h"
2+
3+
/*
4+
* Shows how to use basic Serial remote communication using the inbuilt serial port
5+
* For more details see the README.md file in this directory.
6+
*/
7+
8+
//
9+
// This function is registered in setup to be called every 200 millis by task manager.
10+
// It updates the analog voltage menu items to show the values on each of the analog pins.
11+
// When we call the setCurrentValue (or setBooleanValue on booleans) not only is the menu
12+
// item updated on the display, but it's also marked as needing sending remotely as well.
13+
//
14+
void updateAnalogMenuItems() {
15+
menuA0Voltage.setCurrentValue(analogRead(A0));
16+
menuA1Voltage.setCurrentValue(analogRead(A1));
17+
menuA2Voltage.setCurrentValue(analogRead(A2));
18+
}
19+
20+
void setup() {
21+
// for 32 bit boards we should wait for serial before proceeding.
22+
while(!Serial);
23+
24+
// for serial communication, we only need to setup the speed here.
25+
Serial.begin(115200);
26+
27+
// we are going to be toggling this so need to set it as output.
28+
pinMode(LED_BUILTIN, OUTPUT);
29+
30+
// added by designer to initialise the menu.
31+
setupMenu();
32+
33+
// task manager is asked to schedule the udpate function below every 200ms
34+
taskManager.scheduleFixedRate(200, updateAnalogMenuItems);
35+
}
36+
37+
void loop() {
38+
// added by designer to run the taskManager. Don't put any long running tasks in loop.
39+
taskManager.runLoop();
40+
}
41+
42+
//
43+
// When the push me (action item) is pressed, this method is called back.
44+
// It purely inverts the current state of the built in LED.
45+
//
46+
void CALLBACK_FUNCTION onPushMe(int id) {
47+
bool ledCurrent = digitalRead(LED_BUILTIN);
48+
digitalWrite(LED_BUILTIN, !ledCurrent);
49+
}

0 commit comments

Comments
 (0)