diff --git a/examples/GatewayM5StackStandalone/GatewayM5StackStandalone.ino b/examples/GatewayM5StackStandalone/GatewayM5StackStandalone.ino
new file mode 100644
index 0000000..bacc1a2
--- /dev/null
+++ b/examples/GatewayM5StackStandalone/GatewayM5StackStandalone.ino
@@ -0,0 +1,213 @@
+#define MY_DEBUG
+
+#define MY_RADIO_RF24
+#define MY_RF24_CE_PIN	(SCL)
+#define MY_RF24_CS_PIN	(SDA)
+#define MY_RF24_PA_LEVEL RF24_PA_LOW
+
+#define MY_REPEATER_FEATURE
+#define MY_GATEWAY_FEATURE
+#define MY_IS_GATEWAY (true)
+#define MY_NODE_TYPE "GW"
+
+// Enable inclusion mode
+#define MY_INCLUSION_MODE_FEATURE
+
+// Set inclusion mode duration (in seconds)
+#define MY_INCLUSION_MODE_DURATION 60
+
+// Replace default LED handler with TFT display indication
+#define MY_INDICATION_HANDLER
+#define TFT_IND_W (20)
+#define TFT_IND_H (20)
+#define TFT_IND_X (320 - 3 * TFT_IND_W)
+#define TFT_IND_Y (240 - 1 * TFT_IND_H)
+
+#include <Arduino.h>
+#include <stdint.h>
+
+#include <M5Stack.h>
+#include <MySensors.h>
+
+// Include from subfolders to avoid funny linking issues from Arduino
+#include "lib/MyGatewayTransportStandalone.h"
+#include "lib/MyGatewayTransportStandalone.cpp"
+
+uint8_t nodeIndex = 0;
+
+void indication( const indication_t ind )
+{
+	if ((INDICATION_TX == ind) || (INDICATION_GW_TX == ind)) {
+		M5.Lcd.fillRect(TFT_IND_X + 0 * TFT_IND_W, TFT_IND_Y, TFT_IND_W, TFT_IND_H, BLUE);
+		delay(25);
+		M5.Lcd.fillRect(TFT_IND_X + 0 * TFT_IND_W, TFT_IND_Y, TFT_IND_W, TFT_IND_H, TFT_BLACK);
+	} else if ((INDICATION_RX == ind) || (INDICATION_GW_RX == ind)) {
+		M5.Lcd.fillRect(TFT_IND_X + 1 * TFT_IND_W, TFT_IND_Y, TFT_IND_W, TFT_IND_H, GREEN);
+		delay(25);
+		M5.Lcd.fillRect(TFT_IND_X + 1 * TFT_IND_W, TFT_IND_Y, TFT_IND_W, TFT_IND_H, TFT_BLACK);
+	} else if (ind > INDICATION_ERR_START) {
+		M5.Lcd.fillRect(TFT_IND_X + 2 * TFT_IND_W, TFT_IND_Y, TFT_IND_W, TFT_IND_H, RED);
+		delay(25);
+		M5.Lcd.fillRect(TFT_IND_X + 2 * TFT_IND_W, TFT_IND_Y, TFT_IND_W, TFT_IND_H, TFT_BLACK);
+	}
+}
+
+void startScreen()
+{
+	M5.Lcd.fillScreen(TFT_BLACK);
+	M5.Lcd.setCursor(0, 0);
+	M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);
+	M5.Lcd.print (" Status: Ready\n");
+	M5.Lcd.printf("Channel: %d\n", MY_RF24_CHANNEL);
+	M5.Lcd.printf("  Nodes: %d\n", getLastNodeId());
+}
+
+void setup()
+{
+	//Set up screen and rotate vertically as SPI pins on M5Stack are on the bottom
+	//
+	// /----- [ SPI ] -----\
+	// |-------------------|
+	// | [ C ] [ B ] [ A ] |
+	// | /---------------\ |
+	// | |               | |
+	// | |               | |
+	// | |               | |
+	// | |               | |
+	// | \---------------/ |
+	// \-------------------/
+	M5.begin();
+	M5.Lcd.setTextSize(3);
+	M5.Lcd.setRotation(3);
+
+	startScreen();
+	setTransportInclusion(false);
+}
+
+void presentation()
+{
+	// Present locally attached sensors
+}
+
+void setInclusion(bool include)
+{
+	if ( getTransportInclusion() && getLastNodeId() == 255 ) {
+		//No available Ids in the network
+		M5.Lcd.setCursor(0, 220);
+		M5.Lcd.setTextColor(TFT_RED, TFT_BLACK);
+		M5.Lcd.print("Nwk full");
+	} else {
+		setTransportInclusion(include);
+	}
+}
+
+bool getInclusion()
+{
+	return getTransportInclusion();
+}
+
+void resetGateway()
+{
+	for (uint16_t i=0; i<EEPROM_LOCAL_CONFIG_ADDRESS; i++) {
+		hwWriteConfig(i, 0xFF);
+	}
+	resetTransport();
+}
+
+void loop()
+{
+	//Call M5 lib to keep track of button states
+	M5.update();
+
+	//M5.BtnA/B/C.pressedFor(uint32_t ms);isPressed();wasReleasedFor(uint32_t ms);wasPressed();isPressed();
+	if (M5.BtnA.pressedFor(5000)) {//hold button A to reset gateway
+		M5.Lcd.fillScreen(TFT_BLACK);
+		M5.Lcd.setCursor(0, 0);
+		M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);
+		M5.Lcd.print("Resetting...\n");
+		resetGateway();
+		M5.Lcd.print("Reset done.\n");
+		delay(1000);
+		startScreen();
+		setTransportInclusion(false);
+	} else if (M5.BtnB.wasPressed()) {
+		setInclusion(!getInclusion());
+	} else if (M5.BtnC.wasPressed()) {//cycle back and print node state
+		nodeIndex --;
+		nodeIndex = nodeIndex > getLastNodeId() ? getLastNodeId() : nodeIndex;
+		printNodeState(nodeIndex, false);
+	} else if (M5.BtnA.wasPressed()) {//cycle forward and print node state
+		nodeIndex ++;
+		nodeIndex = nodeIndex > getLastNodeId() ? 0 : nodeIndex;
+		printNodeState(nodeIndex, false);
+	}
+
+	if ( getInclusion() && getTransportInclusionTimeout(MY_INCLUSION_MODE_DURATION * 1000) ) {
+		setInclusion(false);
+	}
+
+	M5.Lcd.setCursor(0, 220);
+	if ( getInclusion() ) {
+		M5.Lcd.setTextColor(TFT_GREEN, TFT_BLACK);
+		M5.Lcd.print("Include ");
+	} else {
+		M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);
+		M5.Lcd.print("Normal  ");
+	}
+}
+
+
+//Print some common sensor values like voltage and temperature
+void printNodeState(uint8_t node, bool last)
+{
+	M5.Lcd.fillScreen(TFT_BLACK);
+	M5.Lcd.setCursor(0, 0);
+	M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);
+	
+	nodeState_t nodeState = getNodeState(node);
+
+	if ( last ) {
+		M5.Lcd.printf("Sender: %d\n", getLastMessageSender());
+		M5.Lcd.printf("Sensor: %d\n", getLastMessageSensor());
+		M5.Lcd.printf("  Type: %d\n", getLastMessageType());
+	} else {
+		M5.Lcd.printf("Sender: %d\n", node);
+		if ( nodeState.time > 0 ) {
+			uint32_t nowMillis = millis() - nodeState.time;
+			uint32_t seconds = nowMillis / 1000;
+			int days = seconds / 86400;
+			seconds %= 86400;
+			byte hours = seconds / 3600;
+			seconds %= 3600;
+			byte minutes = seconds / 60;
+			seconds %= 60;
+			M5.Lcd.printf("Ago: %02dh:%02dm:%02ds\n", hours, minutes, seconds);
+		} else {
+			M5.Lcd.printf("   Ago: N/A\n", node);
+		}
+		M5.Lcd.printf("\n");
+	}
+	M5.Lcd.printf("\n");
+
+	M5.Lcd.setTextColor(DARKCYAN, TFT_BLACK);
+	M5.Lcd.printf(" Volts: ");
+	if ( nodeState.voltage != INVALID_F )
+		M5.Lcd.printf("%2.2f", nodeState.voltage);
+	M5.Lcd.printf("\n");
+
+	M5.Lcd.setTextColor(DARKGREEN, TFT_BLACK);
+	M5.Lcd.printf("  Temp: ");
+	if ( nodeState.temp != INVALID_F )
+		M5.Lcd.printf("%2.2f", nodeState.temp);
+	M5.Lcd.printf("\n");
+	
+	M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);
+	M5.Lcd.printf("\n");
+	M5.Lcd.printf("\n");
+	M5.Lcd.printf("Total Rx: %d\n", getMessageCounter());
+}
+
+void received(uint8_t nodeId)
+{
+	printNodeState(nodeId, true);
+}
\ No newline at end of file
diff --git a/examples/GatewayM5StackStandalone/lib/MyGatewayTransportStandalone.cpp b/examples/GatewayM5StackStandalone/lib/MyGatewayTransportStandalone.cpp
new file mode 100644
index 0000000..775d3f2
--- /dev/null
+++ b/examples/GatewayM5StackStandalone/lib/MyGatewayTransportStandalone.cpp
@@ -0,0 +1,216 @@
+/* Following must be included in the sketch
+#define MY_REPEATER_FEATURE
+#define MY_GATEWAY_FEATURE
+#define MY_IS_GATEWAY (true)
+#define MY_NODE_TYPE "GW"
+
+// Enable inclusion mode
+#define MY_INCLUSION_MODE_FEATURE
+
+// Set inclusion mode duration (in seconds)
+#define MY_INCLUSION_MODE_DURATION 60ul
+*/
+
+#include "MyGatewayTransportStandalone.h"
+
+#include <Arduino.h>
+#include <stdint.h>
+
+#include <core/MyProtocol.h>
+#include <core/MyTransport.h>
+#include <core/MyGatewayTransport.h>
+#include <core/MyMessage.h>
+#include <core/MyInclusionMode.h>
+#include <core/MyIndication.h>
+
+#define EEPROM_LAST_NODE_ID (100)
+
+//last known node states in RAM
+nodeState_t nodeStates[255];
+
+//inclusion process vars
+bool inclusion = false;
+uint32_t inclusionStartTime = 0;
+uint8_t nextNodeId = 255;
+
+//messaging vars
+mysensors_command_t lastMessageCommand;
+uint8_t lastMessageSender;
+uint8_t lastMessageSensor;
+uint8_t lastMessageType;
+uint8_t lastMessageByte;
+MyMessage _responseMsg;
+uint16_t messageCounter = 0;
+
+uint16_t getMessageCounter()
+{
+	return messageCounter;
+}
+
+uint8_t getLastMessageSender()
+{
+	return lastMessageSender;
+}
+
+uint8_t getLastMessageSensor()
+{
+	return lastMessageSensor;
+}
+
+uint8_t getLastMessageType()
+{
+	return lastMessageType;
+}
+
+bool getTransportInclusionTimeout(uint32_t duration)
+{
+	return (bool) (millis() - inclusionStartTime > duration);
+}
+
+uint8_t getLastNodeId()
+{
+	uint8_t lastNodeId = loadState(EEPROM_LAST_NODE_ID);
+	if ( lastNodeId == 0xFF ) {
+		lastNodeId = 0;
+	}
+	return lastNodeId;
+}
+
+uint8_t getnextNodeId()
+{
+	uint8_t lastNodeId = loadState(EEPROM_LAST_NODE_ID);
+	if ( lastNodeId == 0xFF ) {
+		lastNodeId = 0;
+	}
+	lastNodeId ++;
+	saveState(EEPROM_LAST_NODE_ID, lastNodeId);
+	return lastNodeId;
+}
+
+void resetTransport()
+{
+	saveState(EEPROM_LAST_NODE_ID, 0);
+}
+
+void setTransportInclusion(bool include)
+{
+	inclusion = include;
+	inclusionModeSet(inclusion);
+	inclusionStartTime = millis();
+	delay(100);
+	if ( !include ) {
+		nextNodeId = 255;
+	}
+}
+
+bool getTransportInclusion()
+{
+	return inclusion;
+}
+
+nodeState_t& getNodeState(uint8_t nodeId)
+{
+	return nodeStates[nodeId];
+}
+
+void gatewayTransportReceived(const MyMessage &message)
+{
+	messageCounter ++;
+
+	lastMessageCommand = message.getCommand();
+	lastMessageSender = message.getSender();
+	lastMessageSensor = message.getSensor();
+	lastMessageType = message.getType();
+	lastMessageByte = message.getByte();
+
+	if ( lastMessageSensor == 1 && lastMessageType == 0 ) { //temp
+		nodeStates[lastMessageSender].temp = message.getFloat();
+	}
+
+	if ( lastMessageSensor == 201 && lastMessageType == 38 ) { //battery
+		nodeStates[lastMessageSender].voltage = message.getFloat();
+	}
+
+	nodeStates[lastMessageSender].time = millis();
+
+	//notify that a message has been received
+	received(lastMessageSender);
+}
+
+bool gatewayTransportSend(MyMessage &message)
+{
+	gatewayTransportReceived(message);
+	setIndication(INDICATION_GW_TX);
+	return true;
+}
+
+bool gatewayTransportInit(void)
+{
+	inclusion = false;
+	inclusionInit();
+	inclusionModeSet(false);
+	inclusionStartTime = millis();
+
+	for ( uint8_t i = 0; ; i ++ ) {
+		nodeStates[i].voltage = INVALID_F;
+		nodeStates[i].temp = INVALID_F;
+		nodeStates[i].time = 0;
+		if ( i == 255 )
+			break;
+	}
+	return true;
+}
+
+bool gatewayTransportAvailable(void)
+{
+	bool result = false;
+	if ( ( lastMessageCommand == C_INTERNAL ) && inclusion ) {
+		result = true;
+
+		_responseMsg.clear();
+		_responseMsg.setCommand(C_INTERNAL);
+		_responseMsg.setSender(getNodeId());
+		_responseMsg.setDestination(lastMessageSender);
+
+		switch ( lastMessageType ) {
+		case I_REGISTRATION_REQUEST: //presumably last in the inclusion sequence
+			setIndication(INDICATION_GW_RX);
+			_responseMsg.setType(I_REGISTRATION_RESPONSE);
+			_responseMsg.set((bool) true);
+			break;
+		case I_ID_REQUEST:
+			_responseMsg.setType(I_ID_RESPONSE);
+			_responseMsg.setSensor(AUTO);
+			nextNodeId = nextNodeId == 255 ? getnextNodeId() : nextNodeId;
+			if ( nextNodeId != 0 ) { //sanity check for free Ids available
+				_responseMsg.set((const uint8_t) nextNodeId);
+			}
+			break;
+		case I_FIND_PARENT_REQUEST:
+			_responseMsg.setType(I_FIND_PARENT_RESPONSE);
+			_responseMsg.set((const uint8_t) 0);
+			break;
+		case I_DISCOVER_REQUEST:
+			_responseMsg.setType(I_DISCOVER_RESPONSE);
+			_responseMsg.set((const uint8_t) 0);
+			break;
+		case I_PING:
+			_responseMsg.setType(I_PONG);
+			_responseMsg.set((const uint8_t) lastMessageByte++);
+			break;
+		case I_CONFIG:
+			_responseMsg.setType(I_CONFIG);
+			_responseMsg.set((const uint8_t) 0);// metric
+			break;
+		default:
+			result = false;
+		}
+		lastMessageCommand = C_INVALID_7;//mark as handled
+	}
+	return result;
+}
+
+MyMessage& gatewayTransportReceive(void)
+{
+	return _responseMsg;
+}
\ No newline at end of file
diff --git a/examples/GatewayM5StackStandalone/lib/MyGatewayTransportStandalone.h b/examples/GatewayM5StackStandalone/lib/MyGatewayTransportStandalone.h
new file mode 100644
index 0000000..9f4a559
--- /dev/null
+++ b/examples/GatewayM5StackStandalone/lib/MyGatewayTransportStandalone.h
@@ -0,0 +1,39 @@
+#ifndef MyGatewayTransportStandalone_h
+#define MyGatewayTransportStandalone_h
+
+#include <Arduino.h>
+#include <stdint.h>
+
+const float INVALID_F = -1000;
+
+typedef struct {
+	float voltage;
+	float temp;
+	uint32_t time;
+} nodeState_t;
+
+extern void received(uint8_t nodeId);
+
+bool getTransportInclusionTimeout(uint32_t duration);
+
+uint8_t getLastNodeId();
+
+uint8_t getNextNodeId();
+
+void resetTransport();
+
+void setTransportInclusion(bool include);
+
+bool getTransportInclusion();
+
+nodeState_t& getNodeState(uint8_t nodeId);
+
+uint16_t getMessageCounter();
+
+uint8_t getLastMessageSender();
+
+uint8_t getLastMessageSensor();
+
+uint8_t getLastMessageType();
+
+#endif
\ No newline at end of file