diff --git a/examples/knx-esp-bme680/bme680.knxprod b/examples/knx-bme680/bme680.knxprod similarity index 100% rename from examples/knx-esp-bme680/bme680.knxprod rename to examples/knx-bme680/bme680.knxprod diff --git a/examples/knx-esp-bme680/bme680.xml b/examples/knx-bme680/bme680.xml similarity index 100% rename from examples/knx-esp-bme680/bme680.xml rename to examples/knx-bme680/bme680.xml diff --git a/examples/knx-esp-bme680/knx-bme680.ino b/examples/knx-bme680/knx-bme680.ino similarity index 99% rename from examples/knx-esp-bme680/knx-bme680.ino rename to examples/knx-bme680/knx-bme680.ino index 1eee699..96de618 100644 --- a/examples/knx-esp-bme680/knx-bme680.ino +++ b/examples/knx-bme680/knx-bme680.ino @@ -90,7 +90,8 @@ void setup(void) if (knx.configured()) { cyclSend = knx.paramInt(0); - Serial.printf("Zykl. send: %d\n", cyclSend); + Serial.print("Zykl. send:"); + Serial.println(cyclSend); } // start the framework. Will get wifi first. diff --git a/examples/knx-esp-demo/knx-esp-demo.knxprod b/examples/knx-demo/knx-demo-ip.knxprod similarity index 100% rename from examples/knx-esp-demo/knx-esp-demo.knxprod rename to examples/knx-demo/knx-demo-ip.knxprod diff --git a/examples/knx-esp-demo/knx-esp-demo.xml b/examples/knx-demo/knx-demo-ip.xml similarity index 100% rename from examples/knx-esp-demo/knx-esp-demo.xml rename to examples/knx-demo/knx-demo-ip.xml diff --git a/examples/knx-demo/knx-demo-tp.knxprod b/examples/knx-demo/knx-demo-tp.knxprod new file mode 100644 index 0000000..ccb1363 Binary files /dev/null and b/examples/knx-demo/knx-demo-tp.knxprod differ diff --git a/examples/knx-demo/knx-demo-tp.xml b/examples/knx-demo/knx-demo-tp.xml new file mode 100644 index 0000000..b7ae008 --- /dev/null +++ b/examples/knx-demo/knx-demo-tp.xml @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/knx-esp-demo/knx-esp-demo.ino b/examples/knx-demo/knx-demo.ino similarity index 83% rename from examples/knx-esp-demo/knx-esp-demo.ino rename to examples/knx-demo/knx-demo.ino index b7ae38c..80e5473 100644 --- a/examples/knx-esp-demo/knx-esp-demo.ino +++ b/examples/knx-demo/knx-demo.ino @@ -1,4 +1,3 @@ -#include #include // declare array of all groupobjects with their sizes in byte @@ -62,7 +61,6 @@ void resetCallback(GroupObject& go) void setup() { Serial.begin(115200); - Serial.setDebugOutput(true); randomSeed(millis()); @@ -77,11 +75,11 @@ void setup() // print values of parameters if device is already configured if (knx.configured()) { - Serial.printf("Timeout: %d\n", knx.paramByte(0)); - Serial.printf("Zykl. senden: %d\n", knx.paramByte(1)); - Serial.printf("Min/Max senden: %d\n", knx.paramByte(2)); - Serial.printf("Aenderung senden: %d\n", knx.paramByte(3)); - Serial.printf("Abgleich %d\n", knx.paramByte(4)); + SerialDBG.print("Timeout: "); SerialDBG.println(knx.paramByte(0)); + SerialDBG.print("Zykl. senden: "); SerialDBG.println(knx.paramByte(1)); + SerialDBG.print("Min/Max senden: "); SerialDBG.println(knx.paramByte(2)); + SerialDBG.print("Aenderung senden: "); SerialDBG.println(knx.paramByte(3)); + SerialDBG.print("Abgleich: "); SerialDBG.println(knx.paramByte(4)); } // start the framework. Will get wifi first. diff --git a/src/arch_config.h b/src/arch_config.h new file mode 100644 index 0000000..044a407 --- /dev/null +++ b/src/arch_config.h @@ -0,0 +1,7 @@ +#pragma once + +#ifdef ARDUINO_ARCH_ESP8266 +#ifndef USE_STATES +#define USE_STATES +#endif +#endif \ No newline at end of file diff --git a/src/button.cpp b/src/button.cpp index e5a719b..5b014a1 100644 --- a/src/button.cpp +++ b/src/button.cpp @@ -2,9 +2,19 @@ #include "state.h" #include "knx_facade.h" +#ifdef USE_STATES unsigned long buttonTimestamp = 0; + +void buttonDown() +{ + buttonTimestamp = millis(); + attachInterrupt(knx.buttonPin(), buttonUp, RISING); +} +#endif + void buttonUp() { +#ifdef USE_STATES if (millis() - buttonTimestamp > 1000) { Serial.println("long button press"); @@ -16,10 +26,15 @@ void buttonUp() currentState->shortButtonPress(); } attachInterrupt(knx.buttonPin(), buttonDown, FALLING); -} - -void buttonDown() -{ - buttonTimestamp = millis(); - attachInterrupt(knx.buttonPin(), buttonUp, RISING); +#else if (knx.progMode()) + { + digitalWrite(knx.ledPin(), LOW); + knx.progMode(false); + } + else + { + digitalWrite(knx.ledPin(), HIGH); + knx.progMode(true); + } +#endif } \ No newline at end of file diff --git a/src/button.h b/src/button.h index 1c32762..4f921c1 100644 --- a/src/button.h +++ b/src/button.h @@ -1,4 +1,8 @@ #pragma once +#include "arch_config.h" + +#ifdef USE_STATES void buttonDown(); +#endif void buttonUp(); \ No newline at end of file diff --git a/src/esp_platform.cpp b/src/esp_platform.cpp index 017ff11..f68b4c0 100644 --- a/src/esp_platform.cpp +++ b/src/esp_platform.cpp @@ -1,4 +1,6 @@ #include "esp_platform.h" + +#ifdef ARDUINO_ARCH_ESP8266 #include #include #include @@ -169,3 +171,4 @@ size_t EspPlatform::readBytesUart(uint8_t *buffer, size_t length) printHex("p>", buffer, length); return length; } +#endif \ No newline at end of file diff --git a/src/esp_platform.h b/src/esp_platform.h index 4d5bd08..a07361d 100644 --- a/src/esp_platform.h +++ b/src/esp_platform.h @@ -1,7 +1,10 @@ +#ifdef ARDUINO_ARCH_ESP8266 #include "knx/platform.h" #include #include +#define SerialDBG Serial + class EspPlatform : public Platform { public: @@ -43,3 +46,4 @@ private: WiFiUDP _udp; }; +#endif \ No newline at end of file diff --git a/src/knx b/src/knx index 0762e75..aaf6c27 160000 --- a/src/knx +++ b/src/knx @@ -1 +1 @@ -Subproject commit 0762e753f73a44ca77a266753d8981203e579a32 +Subproject commit aaf6c275843ddcb541e8fdae4c8870ede1242370 diff --git a/src/knx_facade.cpp b/src/knx_facade.cpp index 0c4956a..efe1e20 100644 --- a/src/knx_facade.cpp +++ b/src/knx_facade.cpp @@ -4,9 +4,17 @@ #include "led.h" #include "nowifistate.h" -KnxFacade knx; +#ifdef ARDUINO_ARCH_SAMD +SamdPlatform platform; +Bau07B0 bau(platform); +#else +EspPlatform platform; +Bau57B0 bau(platform); +#endif +KnxFacade knx(bau); -KnxFacade::KnxFacade() : _bau(_platform) + +KnxFacade::KnxFacade(BauSystemB& bau) : _bau(bau) { manufacturerId(0xfa); _bau.addSaveRestore(this); @@ -69,8 +77,12 @@ void KnxFacade::writeMemory() void KnxFacade::loop() { +#ifdef USE_STATES if (currentState) currentState->loop(); +#else + knxLoop(); +#endif } void KnxFacade::knxLoop() @@ -112,12 +124,17 @@ void KnxFacade::start() { pinMode(_ledPin, OUTPUT); - pinMode(_buttonPin, INPUT); - attachInterrupt(_buttonPin, buttonDown, FALLING); + pinMode(_buttonPin, INPUT_PULLUP); +#ifdef USE_STATES + attachInterrupt(_buttonPin, buttonDown, FALLING); switchToSate(noWifiState); checkStates(); _ticker.attach_ms(100, doLed); +#else + attachInterrupt(knx.buttonPin(), buttonUp, RISING); + enabled(true); +#endif } uint8_t* KnxFacade::paramData(uint32_t addr) diff --git a/src/knx_facade.h b/src/knx_facade.h index 19fb3bc..6cd9fd1 100644 --- a/src/knx_facade.h +++ b/src/knx_facade.h @@ -1,16 +1,28 @@ #pragma once + +#include "arch_config.h" + +#ifdef ARDUINO_ARCH_SAMD +#include "samd_platform.h" +#include "knx/bau07B0.h" +#endif + +#ifdef ARDUINO_ARCH_ESP8266 #include #include "esp_platform.h" #include "knx/bau57B0.h" +#endif +#ifdef USE_STATES class RunningState; +#endif typedef uint8_t* (*saveRestoreCallback)(uint8_t* buffer); class KnxFacade : private SaveRestore { public: - KnxFacade(); + KnxFacade(BauSystemB& bau); bool enabled(); void enabled(bool value); bool progMode(); @@ -38,11 +50,12 @@ public: uint16_t paramWord(uint32_t addr); uint32_t paramInt(uint32_t addr); private: - EspPlatform _platform; - Bau57B0 _bau; + BauSystemB& _bau; uint32_t _ledPin = 16; uint32_t _buttonPin = 0; +#ifdef USE_STATES Ticker _ticker; +#endif saveRestoreCallback _saveCallback = 0; saveRestoreCallback _restoreCallback = 0; diff --git a/src/knx_facade_samd.cpp b/src/knx_facade_samd.cpp new file mode 100644 index 0000000..db2e2f4 --- /dev/null +++ b/src/knx_facade_samd.cpp @@ -0,0 +1,174 @@ +#include "knx_facade.h" +#if 0 +KnxFacade knx; + + +#define SerialDBG SerialUSB + +void buttonUp(); +long buttonTimestamp = 0; +void buttonDown() +{ + buttonTimestamp = millis(); + attachInterrupt(knx.buttonPin(), buttonUp, RISING); +} + +void buttonUp() +{ + // keep short/long for now + if (millis() - buttonTimestamp > 1000) + { + SerialDBG.println("long button press"); + } + else + { + SerialDBG.println("short button press"); + } + + if (knx.progMode()) + { + digitalWrite(knx.ledPin(), LOW); + knx.progMode(false); + } + else + { + digitalWrite(knx.ledPin(), HIGH); + knx.progMode(true); + } + + attachInterrupt(knx.buttonPin(), buttonDown, FALLING); +} + +KnxFacade::KnxFacade() : _bau(_platform) +{ + manufacturerId(0xfa); +} + +bool KnxFacade::enabled() +{ + return _bau.enabled(); +} + +void KnxFacade::enabled(bool value) +{ + _bau.enabled(true); +} + +bool KnxFacade::progMode() +{ + return _bau.deviceObject().progMode(); +} + +void KnxFacade::progMode(bool value) +{ + _bau.deviceObject().progMode(value); +} + +bool KnxFacade::configured() +{ + return _bau.configured(); +} + +uint32_t KnxFacade::ledPin() +{ + return _ledPin; +} + +void KnxFacade::ledPin(uint32_t value) +{ + _ledPin = value; +} + +uint32_t KnxFacade::buttonPin() +{ + return _buttonPin; +} + +void KnxFacade::buttonPin(uint32_t value) +{ + _buttonPin = value; +} + +void KnxFacade::readMemory() +{ + _bau.readMemory(); +} + +void KnxFacade::loop() +{ + _bau.loop(); +} + +void KnxFacade::registerGroupObjects(GroupObject* groupObjects, uint16_t count) +{ + _bau.groupObjectTable().groupObjects(groupObjects, count); +} + +void KnxFacade::manufacturerId(uint16_t value) +{ + _bau.deviceObject().manufacturerId(value); +} + +void KnxFacade::bauNumber(uint32_t value) +{ + _bau.deviceObject().bauNumber(value); +} + +void KnxFacade::orderNumber(const char* value) +{ + _bau.deviceObject().orderNumber(value); +} + +void KnxFacade::hardwareType(uint8_t* value) +{ + _bau.deviceObject().hardwareType(value); +} + +void KnxFacade::version(uint16_t value) +{ + _bau.deviceObject().version(value); +} + +void KnxFacade::start() +{ + pinMode(_ledPin, OUTPUT); + + pinMode(_buttonPin, INPUT_PULLUP); + attachInterrupt(_buttonPin, buttonDown, FALLING); + enabled(true); +} + +uint8_t* KnxFacade::paramData(uint32_t addr) +{ + if (!_bau.configured()) + return nullptr; + + return _bau.parameters().data(addr); +} + +uint8_t KnxFacade::paramByte(uint32_t addr) +{ + if (!_bau.configured()) + return 0; + + return _bau.parameters().getByte(addr); +} + +uint16_t KnxFacade::paramWord(uint32_t addr) +{ + if (!_bau.configured()) + return 0; + + return _bau.parameters().getWord(addr); +} + +uint32_t KnxFacade::paramInt(uint32_t addr) +{ + if (!_bau.configured()) + return 0; + + return _bau.parameters().getInt(addr); +} + + +#endif \ No newline at end of file diff --git a/src/led.cpp b/src/led.cpp index e1a66a6..41030f2 100644 --- a/src/led.cpp +++ b/src/led.cpp @@ -2,6 +2,7 @@ #include "knx_facade.h" #include "state.h" +#ifdef USE_STATES void doLed() { if (!currentState) @@ -25,4 +26,5 @@ void doLed() digitalWrite(knx.ledPin(), HIGH); else digitalWrite(knx.ledPin(), LOW); -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/src/led.h b/src/led.h index 985759a..fadcac6 100644 --- a/src/led.h +++ b/src/led.h @@ -1,3 +1,7 @@ #pragma once -void doLed(); \ No newline at end of file +#include "arch_config.h" + +#ifdef USE_STATES +void doLed(); +#endif \ No newline at end of file diff --git a/src/linux_platform.cpp b/src/linux_platform.cpp new file mode 100644 index 0000000..229f4c0 --- /dev/null +++ b/src/linux_platform.cpp @@ -0,0 +1,279 @@ +#include "linux_platform.h" +#ifdef __linux__ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "knx/device_object.h" +#include "knx/address_table_object.h" +#include "knx/association_table_object.h" +#include "knx/group_object_table_object.h" +#include "knx/application_program_object.h" +#include "knx/ip_parameter_object.h" + +LinuxPlatform::LinuxPlatform() +{ + doMemoryMapping(); +} + +uint32_t LinuxPlatform::currentIpAddress() +{ + return 0; +} + +uint32_t LinuxPlatform::currentSubnetMask() +{ + return 0; +} + +uint32_t LinuxPlatform::currentDefaultGateway() +{ + return 0; +} + +uint32_t LinuxPlatform::millis() +{ + struct timespec spec; + + clock_gettime(CLOCK_MONOTONIC, &spec); + return spec.tv_sec * 1000 + round(spec.tv_nsec / 1.0e6); +} + +void LinuxPlatform::mdelay(uint32_t millis) +{ + struct timespec ts; + ts.tv_sec = millis / 1000; + ts.tv_nsec = (millis % 1000) * 1000000; + nanosleep(&ts, NULL); +} + +void LinuxPlatform::macAddress(uint8_t* data) +{ + // hardcode some address + data[0] = 0x08; + data[1] = 0x00; + data[2] = 0x27; + data[3] = 0x6c; + data[4] = 0xa8; + data[5] = 0x2a; +} + +void LinuxPlatform::restart() +{ + // do nothing +} + +void LinuxPlatform::fatalError() +{ + printf("A fatal error occured. Stopping.\n"); + while (true) + sleep(1); +} + +void LinuxPlatform::setupMultiCast(uint32_t addr, uint16_t port) +{ + _multicastAddr = addr; + _port = port; + + struct ip_mreq command; + uint32_t loop = 1; + + struct sockaddr_in sin; + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_ANY); + sin.sin_port = htons(port); + + _socketFd = socket(AF_INET, SOCK_DGRAM, 0); + if (_socketFd == -1) { + perror("socket()"); + fatalError(); + } + + /* Mehr Prozessen erlauben, denselben Port zu nutzen */ + loop = 1; + if (setsockopt(_socketFd, SOL_SOCKET, SO_REUSEADDR, &loop, sizeof(loop)) < 0) + { + perror("setsockopt:SO_REUSEADDR"); + fatalError(); + } + + if (bind(_socketFd, (struct sockaddr *)&sin, sizeof(sin)) < 0) + { + perror("bind"); + fatalError(); + } + + /* Broadcast auf dieser Maschine zulassen */ + loop = 1; + if (setsockopt(_socketFd, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop)) < 0) + { + perror("setsockopt:IP_MULTICAST_LOOP"); + fatalError(); + } + + /* Join the broadcast group: */ + command.imr_multiaddr.s_addr = htonl(addr); + command.imr_interface.s_addr = htonl(INADDR_ANY); + + if (setsockopt(_socketFd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &command, sizeof(command)) < 0) + { + perror("setsockopt:IP_ADD_MEMBERSHIP"); + fatalError(); + } + + uint32_t flags = fcntl(_socketFd, F_GETFL); + flags |= O_NONBLOCK; + fcntl(_socketFd, F_SETFL, flags); +} + +void LinuxPlatform::closeMultiCast() +{ + struct ip_mreq command; + command.imr_multiaddr.s_addr = htonl(_multicastAddr); + command.imr_interface.s_addr = htonl(INADDR_ANY); + + if (setsockopt(_socketFd, + IPPROTO_IP, + IP_DROP_MEMBERSHIP, + &command, sizeof(command)) < 0) { + perror("setsockopt:IP_DROP_MEMBERSHIP"); + } + close(_socketFd); +} + +bool LinuxPlatform::sendBytes(uint8_t* buffer, uint16_t len) +{ + struct sockaddr_in address = { 0 }; + address.sin_family = AF_INET; + address.sin_addr.s_addr = htonl(_multicastAddr); + address.sin_port = htons(_port); + + ssize_t retVal = 0; + do + { + retVal = sendto(_socketFd, buffer, len, 0, (struct sockaddr *) &address, sizeof(address)); + if (retVal == -1) + { + if (errno != EAGAIN && errno != EWOULDBLOCK) + return false; + } + } while (retVal == -1); + return true; +} + +int LinuxPlatform::readBytes(uint8_t * buffer, uint16_t maxLen) +{ + uint32_t sin_len; + struct sockaddr_in sin; + + sin_len = sizeof(sin); + ssize_t len = recvfrom(_socketFd, buffer, maxLen, 0, (struct sockaddr *) &sin, &sin_len); + return len; +} + +uint8_t * LinuxPlatform::getEepromBuffer(uint16_t size) +{ + return _mappedFile + 2; +} + +void LinuxPlatform::commitToEeprom() +{ + fsync(_fd); +} + +#define FLASHSIZE 0x10000 +void LinuxPlatform::doMemoryMapping() +{ + _fd = open("flash.bin", O_RDWR | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH); + if (_fd < 0) + { + perror("Error in file opening"); + //exit(-1); + } + + struct stat st; + uint32_t ret = fstat(_fd, &st); + if (ret < 0) + { + perror("Error in fstat"); + //exit(-1); + } + + size_t len_file = st.st_size; + if (len_file < FLASHSIZE) + { + if (ftruncate(_fd, FLASHSIZE) != 0) + { + perror("Error extending file"); + //exit(-1); + } + len_file = FLASHSIZE; + } + unsigned char* addr = (unsigned char*)mmap(NULL, len_file, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0); + if (addr[0] != 0xAF || addr[1] != 0xFE) + { + memset(addr, 0, FLASHSIZE); + addr[0] = 0xAF; + addr[1] = 0xFE; + } + + if (addr == MAP_FAILED) + { + perror("Error in mmap"); + //exit(-1); + } + _mappedFile = addr; +} + +size_t LinuxPlatform::readBytesUart(uint8_t *buffer, size_t length) +{ + return 0; +} + + +int LinuxPlatform::readUart() +{ + return -1; +} + + +size_t LinuxPlatform::writeUart(const uint8_t *buffer, size_t size) +{ + return 0; +} + + +size_t LinuxPlatform::writeUart(const uint8_t data) +{ + return 0; +} + + +int LinuxPlatform::uartAvailable() +{ + return 0; +} + + +void LinuxPlatform::closeUart() +{ +} + + +void LinuxPlatform::setupUart() +{ +} +#endif \ No newline at end of file diff --git a/src/linux_platform.h b/src/linux_platform.h new file mode 100644 index 0000000..710b9fa --- /dev/null +++ b/src/linux_platform.h @@ -0,0 +1,51 @@ +#pragma once + +#ifdef __linux__ + +#include "knx/platform.h" + +class LinuxPlatform: public Platform +{ +public: + LinuxPlatform(); + + // ip stuff + uint32_t currentIpAddress(); + uint32_t currentSubnetMask(); + uint32_t currentDefaultGateway(); + void macAddress(uint8_t* addr); + + // basic stuff + uint32_t millis(); + void mdelay(uint32_t millis); + void restart(); + void fatalError(); + + //multicast + void setupMultiCast(uint32_t addr, uint16_t port); + void closeMultiCast(); + bool sendBytes(uint8_t* buffer, uint16_t len); + int readBytes(uint8_t* buffer, uint16_t maxLen); + + //uart + void setupUart(); + void closeUart(); + int uartAvailable(); + size_t writeUart(const uint8_t data); + size_t writeUart(const uint8_t *buffer, size_t size); + int readUart(); + size_t readBytesUart(uint8_t *buffer, size_t length); + + //memory + uint8_t* getEepromBuffer(uint16_t size); + void commitToEeprom(); +private: + uint32_t _multicastAddr; + uint16_t _port; + int _socketFd = -1; + void doMemoryMapping(); + uint8_t* _mappedFile; + int _fd; +}; + +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..d0094f0 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,116 @@ +#ifdef __linux__ + +#include "linux_platform.h" +#include "knx/bau57B0.h" +#include "knx/group_object_table_object.h" +#include +#include +#include + +LinuxPlatform platfrom; +Bau57B0 bau(platfrom); + +float currentValue = 0; +float maxValue = 0; +float minValue = RAND_MAX; +long lastsend = 0; + +GroupObject groupObjects[] +{ + GroupObject(2), + GroupObject(2), + GroupObject(2), + GroupObject(1) +}; +#define CURR groupObjects[0] +#define MAX groupObjects[1] +#define MIN groupObjects[2] +#define RESET groupObjects[3] + +void measureTemp() +{ + long now = platfrom.millis(); + if ((now - lastsend) < 2000) + return; + + lastsend = now; + int r = rand(); + currentValue = (r * 1.0) / (RAND_MAX * 1.0); + currentValue *= 100 * 100; + + CURR.objectWrite(currentValue); + + if (currentValue > maxValue) + { + maxValue = currentValue; + MAX.objectWrite(maxValue); + } + + if (currentValue < minValue) + { + minValue = currentValue; + MIN.objectWrite(minValue); + } +} + +void resetCallback(GroupObject& go) +{ + if (go.objectReadBool()) + { + maxValue = 0; + minValue = 10000; + } +} + +void appLoop() +{ + if (!bau.configured()) + return; + + measureTemp(); +} + +void setup() +{ + srand((unsigned int)time(NULL)); + bau.readMemory(); + + uint8_t hwType[] = { 0x0, 0x0, 0x8, 0x0, 0x0, 0x2 }; + GroupObjectTableObject& got(bau.groupObjectTable()); + got.groupObjects(groupObjects, 4); + + DeviceObject& devObj(bau.deviceObject()); + devObj.manufacturerId(0xfa); + devObj.bauNumber(0xdeadbeef); + devObj.orderNumber("Coolstuff"); + devObj.hardwareType(hwType); + devObj.version(0x0020); + + RESET.updateHandler = resetCallback; + + if (bau.deviceObject().induvidualAddress() == 0) + bau.deviceObject().progMode(true); + + if (bau.parameters().loadState() == LS_LOADED) + { + printf("Timeout: %d\n", bau.parameters().getWord(0)); + printf("Zykl. senden: %d\n", bau.parameters().getByte(2)); + printf("Min/Max senden: %d\n", bau.parameters().getByte(3)); + printf("Aenderung senden: %d\n", bau.parameters().getByte(4)); + printf("Abgleich %d\n", bau.parameters().getByte(5)); + } + bau.enabled(true); +} + +int main(int argc, char **argv) +{ + setup(); + + while (1) + { + bau.loop(); + appLoop(); + platfrom.mdelay(100); + } +} +#endif \ No newline at end of file diff --git a/src/nowifistate.cpp b/src/nowifistate.cpp index ddb6073..22feeb1 100644 --- a/src/nowifistate.cpp +++ b/src/nowifistate.cpp @@ -1,9 +1,11 @@ -#include - #include "nowifistate.h" #include "wpsstate.h" #include "runningstate.h" +#ifdef USE_STATES + +#include + NoWifiState noWifiState = NoWifiState(); void NoWifiState::shortButtonPress() @@ -32,4 +34,6 @@ void NoWifiState::enterState() Serial.printf("\nConnected successful to SSID '%s'\n", WiFi.SSID().c_str()); switchToSate(runningState); } -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/src/nowifistate.h b/src/nowifistate.h index f15d46e..f64892e 100644 --- a/src/nowifistate.h +++ b/src/nowifistate.h @@ -2,6 +2,8 @@ #include "state.h" +#ifdef USE_STATES + class NoWifiState : public State { public: @@ -13,4 +15,6 @@ public: virtual const char* name() { return "NoWifi"; } }; -extern NoWifiState noWifiState; \ No newline at end of file +extern NoWifiState noWifiState; + +#endif \ No newline at end of file diff --git a/src/programmingmodestate.cpp b/src/programmingmodestate.cpp index be52139..32ee313 100644 --- a/src/programmingmodestate.cpp +++ b/src/programmingmodestate.cpp @@ -2,6 +2,7 @@ #include "runningstate.h" #include "knx_facade.h" +#ifdef USE_STATES ProgramModeState programModeState = ProgramModeState(); void ProgramModeState::enterState() @@ -24,3 +25,4 @@ void ProgramModeState::loop() State::loop(); knx.knxLoop(); } +#endif \ No newline at end of file diff --git a/src/programmingmodestate.h b/src/programmingmodestate.h index 489fc8b..0167905 100644 --- a/src/programmingmodestate.h +++ b/src/programmingmodestate.h @@ -2,6 +2,8 @@ #include "state.h" +#ifdef USE_STATES + class ProgramModeState : public State { public: @@ -14,4 +16,6 @@ public: virtual const char* name() { return "ProgramMode"; } }; -extern ProgramModeState programModeState; \ No newline at end of file +extern ProgramModeState programModeState; + +#endif \ No newline at end of file diff --git a/src/runningstate.cpp b/src/runningstate.cpp index a13cc80..c97ef0a 100644 --- a/src/runningstate.cpp +++ b/src/runningstate.cpp @@ -3,6 +3,8 @@ #include "wpsstate.h" #include "knx_facade.h" +#ifdef USE_STATES + RunningState runningState = RunningState(); void RunningState::shortButtonPress() @@ -38,3 +40,4 @@ void RunningState::loop() State::loop(); knx.knxLoop(); } +#endif \ No newline at end of file diff --git a/src/runningstate.h b/src/runningstate.h index 374fb97..88d7b3e 100644 --- a/src/runningstate.h +++ b/src/runningstate.h @@ -1,7 +1,7 @@ #pragma once #include "state.h" - +#ifdef USE_STATES class RunningState : public State { public: @@ -17,4 +17,5 @@ private: bool _initialized = false; }; -extern RunningState runningState; \ No newline at end of file +extern RunningState runningState; +#endif \ No newline at end of file diff --git a/src/samd_platform.cpp b/src/samd_platform.cpp new file mode 100644 index 0000000..3e72a23 --- /dev/null +++ b/src/samd_platform.cpp @@ -0,0 +1,157 @@ +#include "samd_platform.h" + +#ifdef ARDUINO_ARCH_SAMD +#include + +#include +#include + +SamdPlatform::SamdPlatform() +{ +} + +uint32_t SamdPlatform::currentIpAddress() +{ + // not needed + return 0; +} + +uint32_t SamdPlatform::currentSubnetMask() +{ + // not needed + return 0; +} + +uint32_t SamdPlatform::currentDefaultGateway() +{ + // not needed + return 0; +} + +void SamdPlatform::macAddress(uint8_t * addr) +{ + // not needed +} + +uint32_t SamdPlatform::millis() +{ + return::millis(); +} + +void SamdPlatform::mdelay(uint32_t millis) +{ + delay(millis); +} + +void SamdPlatform::restart() +{ + SerialUSB.println("restart"); + NVIC_SystemReset(); +} + +void SamdPlatform::fatalError() +{ + const int period = 200; + while (true) + { + if ((millis() % period) > (period / 2)) + digitalWrite(LED_BUILTIN, HIGH); + else + digitalWrite(LED_BUILTIN, LOW); + } +} + +void SamdPlatform::setupMultiCast(uint32_t addr, uint16_t port) +{ + //not needed +} + +void SamdPlatform::closeMultiCast() +{ + //not needed +} + +bool SamdPlatform::sendBytes(uint8_t * buffer, uint16_t len) +{ + //not needed +} + +int SamdPlatform::readBytes(uint8_t * buffer, uint16_t maxLen) +{ + //not needed + return 0; +} + +uint8_t * SamdPlatform::getEepromBuffer(uint16_t size) +{ + //EEPROM.begin(size); + if(size > EEPROM_EMULATION_SIZE) + fatalError(); + + return EEPROM.getDataPtr(); +} + +void SamdPlatform::commitToEeprom() +{ + EEPROM.commit(); +} + + +void SamdPlatform::setupUart() +{ + SerialKNX.begin(19200, SERIAL_8E1); + while (!SerialKNX) + ; +} + + +void SamdPlatform::closeUart() +{ + SerialKNX.end(); +} + + +int SamdPlatform::uartAvailable() +{ + return SerialKNX.available(); +} + + +size_t SamdPlatform::writeUart(const uint8_t data) +{ + //printHex(" 0) + // printHex("p>", (uint8_t*)&val, 1); + return val; +} + + +size_t SamdPlatform::readBytesUart(uint8_t *buffer, size_t length) +{ + size_t toRead = length; + uint8_t* pos = buffer; + while (toRead > 0) + { + size_t val = SerialKNX.readBytes(pos, toRead); + pos += val; + toRead -= val; + } + //printHex("p>", buffer, length); + return length; +} + +#endif \ No newline at end of file diff --git a/src/samd_platform.h b/src/samd_platform.h new file mode 100644 index 0000000..df7acdb --- /dev/null +++ b/src/samd_platform.h @@ -0,0 +1,50 @@ +#include "knx/platform.h" + +#include "Arduino.h" + +#ifdef ARDUINO_ARCH_SAMD + +#define SerialDBG SerialUSB +#define SerialKNX Serial1 + +class SamdPlatform : public Platform +{ +public: + SamdPlatform(); + + // ip stuff + uint32_t currentIpAddress(); + uint32_t currentSubnetMask(); + uint32_t currentDefaultGateway(); + void macAddress(uint8_t* addr); + + // basic stuff + uint32_t millis(); + void mdelay(uint32_t millis); + void restart(); + void fatalError(); + + //multicast + void setupMultiCast(uint32_t addr, uint16_t port); + void closeMultiCast(); + bool sendBytes(uint8_t* buffer, uint16_t len); + int readBytes(uint8_t* buffer, uint16_t maxLen); + + //uart + virtual void setupUart(); + virtual void closeUart(); + virtual int uartAvailable(); + virtual size_t writeUart(const uint8_t data); + virtual size_t writeUart(const uint8_t *buffer, size_t size); + virtual int readUart(); + virtual size_t readBytesUart(uint8_t *buffer, size_t length); + + //memory + uint8_t* getEepromBuffer(uint16_t size); + void commitToEeprom(); +private: + uint32_t _mulitcastAddr; + uint16_t _mulitcastPort; +}; + +#endif \ No newline at end of file diff --git a/src/state.cpp b/src/state.cpp index bffae1d..4199f46 100644 --- a/src/state.cpp +++ b/src/state.cpp @@ -1,6 +1,8 @@ #include "state.h" #include "Arduino.h" +#ifdef USE_STATES + State* volatile currentState = 0; State* volatile nextState = 0; @@ -51,3 +53,5 @@ void State::loop() { checkStates(); } + +#endif \ No newline at end of file diff --git a/src/state.h b/src/state.h index a8b77a9..9b155b1 100644 --- a/src/state.h +++ b/src/state.h @@ -1,4 +1,7 @@ #pragma once +#include "arch_config.h" + +#ifdef USE_STATES class State { @@ -26,4 +29,6 @@ void switchToSate(State& state); void checkStates(); extern State* volatile currentState; -extern State* volatile nextState; \ No newline at end of file +extern State* volatile nextState; + +#endif \ No newline at end of file diff --git a/src/wpsstate.cpp b/src/wpsstate.cpp index 7c395a6..615f290 100644 --- a/src/wpsstate.cpp +++ b/src/wpsstate.cpp @@ -1,3 +1,6 @@ +#include "arch_config.h" + +#ifdef USE_STATES #include #include "wpsstate.h" @@ -26,3 +29,5 @@ void WpsState::enterState() } } } + +#endif diff --git a/src/wpsstate.h b/src/wpsstate.h index 5460bb4..3f985ab 100644 --- a/src/wpsstate.h +++ b/src/wpsstate.h @@ -2,6 +2,7 @@ #include "state.h" +#ifdef USE_STATES class WpsState : public State { public: @@ -12,3 +13,5 @@ public: }; extern WpsState wpsState; + +#endif diff --git a/visualstudio/ClassDiagram.cd b/visualstudio/ClassDiagram.cd new file mode 100644 index 0000000..fa67e07 --- /dev/null +++ b/visualstudio/ClassDiagram.cd @@ -0,0 +1,95 @@ + + + + + + IBAAAAAAQACAEAIAABAAAAgAAAAAAAAAAAAAAABAAEA= + knx\address_table_object.h + + + + + + AIAAAAAAAACAAAIAgCAAAAAgABAEAAAAAAAQQABAAAA= + knx\application_program_object.h + + + + + + AAAAAAAAAACAAgIAABAAQAgAAAEAAAAAAAAAAABAAEA= + knx\association_table_object.h + + + + + + AAACACEAAAGCIAKAQCAgAACgCECAAEIgAEgAAgJAAAA= + knx\device_object.h + + + + + + AAAAAEAACACAAgIAAhAATAgACAAAAAAAAAAAAABAAAA= + knx\group_object_table_object.h + + + + + + AAAAAAAAAAAAAAAAACAAAAAgAAAAAAAAAAAAABBAAAA= + knx\interface_object.h + + + + + + AAIACIAAYACAAKIAAGAQCAAgWAIAAAAGAAAAAABgAIA= + knx\ip_parameter_object.h + + + + + + AAIACIACBACAAIIAAGAASAgwyAAAAAAAAgAAAAJgAAA= + knx\table_object.h + + + + + + sKoIAAAAQIIxC4gUUEAIAAACiQEgAjQUFCCA5yEAIBw= + knx\bau.h + + + + + + ABIAAFAgAgIwCoAAUiCCQIDAiEBgADQQACAAAAKQABw= + knx\bau57B0.h + + + + + + BACCIBAAICAAICgAAABAgAAQAAAAAAgAAADAEAAAAhA= + linux_platform.h + + + + + + AAAAAAAAAACAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAA= + knx\save_restore.h + + + + + + AAACIBAAICAAIAAAAABAgAAAAAAAAAgAAADAEAAAAhA= + knx\platform.h + + + + \ No newline at end of file diff --git a/visualstudio/knx-bme680.vgdbproj b/visualstudio/knx-bme680.vgdbproj index 86b5086..81da2fc 100644 --- a/visualstudio/knx-bme680.vgdbproj +++ b/visualstudio/knx-bme680.vgdbproj @@ -10,7 +10,7 @@ 58afeecd-06e2-4bb7-a13f-e1d5dbaed13f true true - ..\examples\knx-esp-bme680 + ..\examples\knx-bme680 basic_config_state_ulp_plus.ino @@ -278,6 +278,63 @@ Sketch + + Arduino Genuino Zero (Native USB Port) + + + + + false + false + false + false + false + false + false + false + false + + false + false + false + false + false + false + true + false + None + false + false + main + true + false + false + false + 0 + + + true + Auto + 0 + false + false + true + false + false + + _estack + 0 + false + true + + + arduino:samd:arduino_zero_native + + + + Sketch + + \ No newline at end of file diff --git a/visualstudio/knx-esp.vgdbproj b/visualstudio/knx-demo.vgdbproj similarity index 74% rename from visualstudio/knx-esp.vgdbproj rename to visualstudio/knx-demo.vgdbproj index 4234096..0dc1c7e 100644 --- a/visualstudio/knx-esp.vgdbproj +++ b/visualstudio/knx-demo.vgdbproj @@ -10,12 +10,12 @@ 6165cd6a-91a4-49fa-977a-48f22086ca8e true true - ..\examples\knx-esp-demo + ..\examples\knx-demo Sketch.ino - knx-esp-demo.ino + knx-demo.ino @@ -82,6 +82,12 @@ 238 144 + + 255 + 169 + 169 + 169 + 16 @@ -275,6 +281,63 @@ Sketch + + Arduino Genuino Zero (Native USB Port) + + + + + false + false + false + false + false + false + false + false + false + + false + false + false + false + false + false + true + false + None + false + false + main + true + false + false + false + 0 + + + true + Auto + 0 + false + false + true + false + false + + _estack + 0 + false + true + + + arduino:samd:arduino_zero_native + + + + Sketch + + \ No newline at end of file diff --git a/visualstudio/knx-linux-Debug.vgdbsettings b/visualstudio/knx-linux-Debug.vgdbsettings new file mode 100644 index 0000000..d3e6100 --- /dev/null +++ b/visualstudio/knx-linux-Debug.vgdbsettings @@ -0,0 +1,148 @@ + + + Release + + + + RemoteUnix + + + localhost + LinuxSubsystem + Linux + + + false + + localhost + LinuxSubsystem + Linux + + $(ProjectDir) + /home/tkunze/vgdb/knx-linux + + *.cpp + *.h + *.hpp + *.c + *.cc + *.cxx + *.mak + Makefile + *.txt + *.cmake + CMakeLists.txt + *.cmake + + true + true + + true + true + + false + false + false + false + false + $(ProjectDir) + + + + com.sysprogs.toolchain.default-gcc + + 0 + + + knx-linux.vcxproj + 0 + true + + + + + + + + + + + + + Default + + + + true + + + + + Unknown + + true + false + + + + + false + + + + + + + + + false + false + false + false + false + false + false + false + false + + false + false + false + false + false + false + true + false + None + false + false + main + true + false + false + false + 0 + + + + + + LANG + en_US.UTF-8 + + + + + $(TargetPath) + 2000 + + + false + Local + false + false + Auto + true + false + + \ No newline at end of file diff --git a/visualstudio/knx-linux-Release.vgdbsettings b/visualstudio/knx-linux-Release.vgdbsettings new file mode 100644 index 0000000..d3e6100 --- /dev/null +++ b/visualstudio/knx-linux-Release.vgdbsettings @@ -0,0 +1,148 @@ + + + Release + + + + RemoteUnix + + + localhost + LinuxSubsystem + Linux + + + false + + localhost + LinuxSubsystem + Linux + + $(ProjectDir) + /home/tkunze/vgdb/knx-linux + + *.cpp + *.h + *.hpp + *.c + *.cc + *.cxx + *.mak + Makefile + *.txt + *.cmake + CMakeLists.txt + *.cmake + + true + true + + true + true + + false + false + false + false + false + $(ProjectDir) + + + + com.sysprogs.toolchain.default-gcc + + 0 + + + knx-linux.vcxproj + 0 + true + + + + + + + + + + + + + Default + + + + true + + + + + Unknown + + true + false + + + + + false + + + + + + + + + false + false + false + false + false + false + false + false + false + + false + false + false + false + false + false + true + false + None + false + false + main + true + false + false + false + 0 + + + + + + LANG + en_US.UTF-8 + + + + + $(TargetPath) + 2000 + + + false + Local + false + false + Auto + true + false + + \ No newline at end of file diff --git a/visualstudio/knx-linux.vcxproj b/visualstudio/knx-linux.vcxproj new file mode 100644 index 0000000..1e732b4 --- /dev/null +++ b/visualstudio/knx-linux.vcxproj @@ -0,0 +1,131 @@ + + + + + Debug + VisualGDB + + + Release + VisualGDB + + + + 15.0 + {819E55F9-05A8-454D-B771-4A99F775DD87} + + + + + GCC + + + + GCC + + + com.sysprogs.toolchain.default-gcc + + + + + + + + + + + + localhost-lxss + + + localhost-lxss + + + + /usr/include/x86_64-linux-gnu;%(ClCompile.AdditionalIncludeDirectories) + + + + + + + + /usr/include/x86_64-linux-gnu;%(ClCompile.AdditionalIncludeDirectories) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualstudio/knx-linux.vcxproj.filters b/visualstudio/knx-linux.vcxproj.filters new file mode 100644 index 0000000..5cfbad1 --- /dev/null +++ b/visualstudio/knx-linux.vcxproj.filters @@ -0,0 +1,217 @@ + + + + + {7612a532-0bb6-4a82-917a-48cfa6410e4f} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {842f6d29-354f-47a8-bfd9-0fccf0ddf144} + h;hpp;hxx;hm;inl;inc;xsd + + + {c46b2f8f-4105-4638-af5c-09a641257065} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + {c818187b-4f9f-4ee9-86c3-d26e56e49bf9} + *.vgdbsettings + + + {169b6f5b-b022-4422-ace2-819bf2f5e883} + + + {4054619f-7b60-405c-96e8-311c464cf8de} + + + + + + VisualGDB settings + + + VisualGDB settings + + + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + Header files\knx + + + + + Source files\knx + + + Source files + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + Source files + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + Source files\knx + + + \ No newline at end of file diff --git a/visualstudio/knx.sln b/visualstudio/knx.sln new file mode 100644 index 0000000..69aad4e --- /dev/null +++ b/visualstudio/knx.sln @@ -0,0 +1,57 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28010.2050 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "knx-linux", "knx-linux.vcxproj", "{819E55F9-05A8-454D-B771-4A99F775DD87}" +EndProject +Project("{803FD0C6-D64E-4E16-9DC3-1DAEC859A3D2}") = "knx-bme680", "knx-bme680.vgdbproj", "{58AFEECD-06E2-4BB7-A13F-E1D5DBAED13F}" +EndProject +Project("{803FD0C6-D64E-4E16-9DC3-1DAEC859A3D2}") = "knx-demo", "knx-demo.vgdbproj", "{6165CD6A-91A4-49FA-977A-48F22086CA8E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Arduino Genuino Zero (Native USB Port) = Debug|Arduino Genuino Zero (Native USB Port) + Debug|NodeMCU 1 0 (ESP-12E Module) = Debug|NodeMCU 1 0 (ESP-12E Module) + Debug|VisualGDB = Debug|VisualGDB + Release|Arduino Genuino Zero (Native USB Port) = Release|Arduino Genuino Zero (Native USB Port) + Release|NodeMCU 1 0 (ESP-12E Module) = Release|NodeMCU 1 0 (ESP-12E Module) + Release|VisualGDB = Release|VisualGDB + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {819E55F9-05A8-454D-B771-4A99F775DD87}.Debug|Arduino Genuino Zero (Native USB Port).ActiveCfg = Debug|VisualGDB + {819E55F9-05A8-454D-B771-4A99F775DD87}.Debug|NodeMCU 1 0 (ESP-12E Module).ActiveCfg = Debug|VisualGDB + {819E55F9-05A8-454D-B771-4A99F775DD87}.Debug|VisualGDB.ActiveCfg = Debug|VisualGDB + {819E55F9-05A8-454D-B771-4A99F775DD87}.Debug|VisualGDB.Build.0 = Debug|VisualGDB + {819E55F9-05A8-454D-B771-4A99F775DD87}.Release|Arduino Genuino Zero (Native USB Port).ActiveCfg = Release|VisualGDB + {819E55F9-05A8-454D-B771-4A99F775DD87}.Release|NodeMCU 1 0 (ESP-12E Module).ActiveCfg = Release|VisualGDB + {819E55F9-05A8-454D-B771-4A99F775DD87}.Release|VisualGDB.ActiveCfg = Release|VisualGDB + {819E55F9-05A8-454D-B771-4A99F775DD87}.Release|VisualGDB.Build.0 = Release|VisualGDB + {58AFEECD-06E2-4BB7-A13F-E1D5DBAED13F}.Debug|Arduino Genuino Zero (Native USB Port).ActiveCfg = Debug|Arduino Genuino Zero (Native USB Port) + {58AFEECD-06E2-4BB7-A13F-E1D5DBAED13F}.Debug|Arduino Genuino Zero (Native USB Port).Build.0 = Debug|Arduino Genuino Zero (Native USB Port) + {58AFEECD-06E2-4BB7-A13F-E1D5DBAED13F}.Debug|NodeMCU 1 0 (ESP-12E Module).ActiveCfg = Debug|NodeMCU 1 0 (ESP-12E Module) + {58AFEECD-06E2-4BB7-A13F-E1D5DBAED13F}.Debug|NodeMCU 1 0 (ESP-12E Module).Build.0 = Debug|NodeMCU 1 0 (ESP-12E Module) + {58AFEECD-06E2-4BB7-A13F-E1D5DBAED13F}.Debug|VisualGDB.ActiveCfg = Debug|Arduino Genuino Zero (Native USB Port) + {58AFEECD-06E2-4BB7-A13F-E1D5DBAED13F}.Release|Arduino Genuino Zero (Native USB Port).ActiveCfg = Release|Arduino Genuino Zero (Native USB Port) + {58AFEECD-06E2-4BB7-A13F-E1D5DBAED13F}.Release|Arduino Genuino Zero (Native USB Port).Build.0 = Release|Arduino Genuino Zero (Native USB Port) + {58AFEECD-06E2-4BB7-A13F-E1D5DBAED13F}.Release|NodeMCU 1 0 (ESP-12E Module).ActiveCfg = Release|NodeMCU 1 0 (ESP-12E Module) + {58AFEECD-06E2-4BB7-A13F-E1D5DBAED13F}.Release|NodeMCU 1 0 (ESP-12E Module).Build.0 = Release|NodeMCU 1 0 (ESP-12E Module) + {58AFEECD-06E2-4BB7-A13F-E1D5DBAED13F}.Release|VisualGDB.ActiveCfg = Release|Arduino Genuino Zero (Native USB Port) + {6165CD6A-91A4-49FA-977A-48F22086CA8E}.Debug|Arduino Genuino Zero (Native USB Port).ActiveCfg = Debug|Arduino Genuino Zero (Native USB Port) + {6165CD6A-91A4-49FA-977A-48F22086CA8E}.Debug|Arduino Genuino Zero (Native USB Port).Build.0 = Debug|Arduino Genuino Zero (Native USB Port) + {6165CD6A-91A4-49FA-977A-48F22086CA8E}.Debug|NodeMCU 1 0 (ESP-12E Module).ActiveCfg = Debug|NodeMCU 1 0 (ESP-12E Module) + {6165CD6A-91A4-49FA-977A-48F22086CA8E}.Debug|NodeMCU 1 0 (ESP-12E Module).Build.0 = Debug|NodeMCU 1 0 (ESP-12E Module) + {6165CD6A-91A4-49FA-977A-48F22086CA8E}.Debug|VisualGDB.ActiveCfg = Debug|Arduino Genuino Zero (Native USB Port) + {6165CD6A-91A4-49FA-977A-48F22086CA8E}.Release|Arduino Genuino Zero (Native USB Port).ActiveCfg = Release|Arduino Genuino Zero (Native USB Port) + {6165CD6A-91A4-49FA-977A-48F22086CA8E}.Release|Arduino Genuino Zero (Native USB Port).Build.0 = Release|Arduino Genuino Zero (Native USB Port) + {6165CD6A-91A4-49FA-977A-48F22086CA8E}.Release|NodeMCU 1 0 (ESP-12E Module).ActiveCfg = Release|NodeMCU 1 0 (ESP-12E Module) + {6165CD6A-91A4-49FA-977A-48F22086CA8E}.Release|NodeMCU 1 0 (ESP-12E Module).Build.0 = Release|NodeMCU 1 0 (ESP-12E Module) + {6165CD6A-91A4-49FA-977A-48F22086CA8E}.Release|VisualGDB.ActiveCfg = Release|Arduino Genuino Zero (Native USB Port) + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {721CAB98-83F8-4035-AC23-77AEA55B634D} + EndGlobalSection +EndGlobal