Merge pull request #1 from thelsing/master

test
This commit is contained in:
zelogik 2021-02-08 21:04:07 +01:00 committed by GitHub
commit c4cf475839
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 912 additions and 182 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
*.knxprod binary

1
.gitignore vendored
View File

@ -31,6 +31,7 @@ _build
# Visual Studio 2015 cache/options directory # Visual Studio 2015 cache/options directory
.vs/ .vs/
.vscode/
# Uncomment if you have tasks that create the project's static files in wwwroot # Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/ #wwwroot/

View File

@ -11,7 +11,7 @@ void buttonUp()
if (millis() - lastpressed > 200) if (millis() - lastpressed > 200)
{ {
KnxFacade<CC1310Platform, Bau27B0> &knx = *pKnx; KnxFacade<CC1310Platform, Bau27B0> &knx = *pKnx;
knx._toogleProgMode = true; knx.toggleProgMode();
lastpressed = millis(); lastpressed = millis();
} }
} }

5
examples/knx-demo-diy/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

Binary file not shown.

View File

@ -0,0 +1,133 @@
<?xml version="1.0" encoding="utf-8"?>
<KNX xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" CreatedBy="KNX MT" ToolVersion="5.6.407.26745" xmlns="http://knx.org/xml/project/11">
<ManufacturerData>
<Manufacturer RefId="M-00FA">
<Catalog>
<CatalogSection Id="M-00FA_CS-1" Name="Geräte" Number="1" DefaultLanguage="en-US">
<CatalogItem Id="M-00FA_H-0124-0_HP-ABCE-79-0000_CI-IA4313-1" Name="Temperatursensor TP" Number="1" ProductRefId="M-00FA_H-0124-0_P-IA4313" Hardware2ProgramRefId="M-00FA_H-0124-0_HP-ABCE-79-0000" DefaultLanguage="en-US" />
</CatalogSection>
</Catalog>
<ApplicationPrograms>
<ApplicationProgram Id="M-00FA_A-ABCE-79-0000" ApplicationNumber="43982" ApplicationVersion="121" ProgramType="ApplicationProgram" MaskVersion="MV-07B0" Name="TK TEMP TP" LoadProcedureStyle="MergedProcedure" PeiType="0" DefaultLanguage="en-US" DynamicTableManagement="false" Linkable="false" MinEtsVersion="4.0">
<Static>
<Code>
<RelativeSegment Id="M-00FA_A-ABCE-79-0000_RS-04-00000" Name="Parameters" Offset="0" Size="8" LoadStateMachine="4" />
</Code>
<ParameterTypes>
<ParameterType Id="M-00FA_A-ABCE-79-0000_PT-startupTimeout" Name="startupTimeout">
<TypeRestriction Base="Value" SizeInBit="8">
<Enumeration Text="0 s" Value="0" Id="M-00FA_A-ABCE-79-0000_PT-startupTimeout_EN-0" />
<Enumeration Text="1 s" Value="1" Id="M-00FA_A-ABCE-79-0000_PT-startupTimeout_EN-1" />
<Enumeration Text="2 s" Value="2" Id="M-00FA_A-ABCE-79-0000_PT-startupTimeout_EN-2" />
<Enumeration Text="3 s" Value="3" Id="M-00FA_A-ABCE-79-0000_PT-startupTimeout_EN-3" />
<Enumeration Text="4 s" Value="4" Id="M-00FA_A-ABCE-79-0000_PT-startupTimeout_EN-4" />
<Enumeration Text="5 s" Value="5" Id="M-00FA_A-ABCE-79-0000_PT-startupTimeout_EN-5" />
<Enumeration Text="6 s" Value="6" Id="M-00FA_A-ABCE-79-0000_PT-startupTimeout_EN-6" />
</TypeRestriction>
</ParameterType>
<ParameterType Id="M-00FA_A-ABCE-79-0000_PT-TempChange" Name="TempChange">
<TypeRestriction Base="Value" SizeInBit="8">
<Enumeration Text="Disabled" Value="0" Id="M-00FA_A-ABCE-79-0000_PT-TempChange_EN-0" />
<Enumeration Text="0.1 K" Value="1" Id="M-00FA_A-ABCE-79-0000_PT-TempChange_EN-1" />
<Enumeration Text="0.2 K" Value="2" Id="M-00FA_A-ABCE-79-0000_PT-TempChange_EN-2" />
<Enumeration Text="0.3 K" Value="3" Id="M-00FA_A-ABCE-79-0000_PT-TempChange_EN-3" />
</TypeRestriction>
</ParameterType>
<ParameterType Id="M-00FA_A-ABCE-79-0000_PT-TempCycle" Name="TempCycle">
<TypeRestriction Base="Value" SizeInBit="8">
<Enumeration Text="Disabled" Value="0" Id="M-00FA_A-ABCE-79-0000_PT-TempCycle_EN-0" />
<Enumeration Text="1 min" Value="1" Id="M-00FA_A-ABCE-79-0000_PT-TempCycle_EN-1" />
<Enumeration Text="2 min" Value="2" Id="M-00FA_A-ABCE-79-0000_PT-TempCycle_EN-2" />
<Enumeration Text="3 min" Value="3" Id="M-00FA_A-ABCE-79-0000_PT-TempCycle_EN-3" />
</TypeRestriction>
</ParameterType>
<ParameterType Id="M-00FA_A-ABCE-79-0000_PT-TempAbgleich" Name="TempAbgleich">
<TypeNumber SizeInBit="32" Type="signedInt" minInclusive="-50" maxInclusive="50" />
</ParameterType>
<ParameterType Id="M-00FA_A-ABCE-79-0000_PT-TempSendMinMax" Name="TempSendMinMax">
<TypeRestriction Base="Value" SizeInBit="8">
<Enumeration Text="Disabled" Value="0" Id="M-00FA_A-ABCE-79-0000_PT-TempSendMinMax_EN-0" />
<Enumeration Text="Send Enable" Value="1" Id="M-00FA_A-ABCE-79-0000_PT-TempSendMinMax_EN-1" />
</TypeRestriction>
</ParameterType>
</ParameterTypes>
<Parameters>
<Parameter Id="M-00FA_A-ABCE-79-0000_P-1" Name="startupTimeout" ParameterType="M-00FA_A-ABCE-79-0000_PT-startupTimeout" Text="Startup delaytime" Value="0">
<Memory CodeSegment="M-00FA_A-ABCE-79-0000_RS-04-00000" Offset="0" BitOffset="0" />
</Parameter>
<Parameter Id="M-00FA_A-ABCE-79-0000_P-2" Name="Aender Senden" ParameterType="M-00FA_A-ABCE-79-0000_PT-TempChange" Text="Send actual value after change of" Value="0">
<Memory CodeSegment="M-00FA_A-ABCE-79-0000_RS-04-00000" Offset="1" BitOffset="0" />
</Parameter>
<Parameter Id="M-00FA_A-ABCE-79-0000_P-3" Name="ZyklSenden" ParameterType="M-00FA_A-ABCE-79-0000_PT-TempCycle" Text="Send actual temperature cyclically" Value="0">
<Memory CodeSegment="M-00FA_A-ABCE-79-0000_RS-04-00000" Offset="2" BitOffset="0" />
</Parameter>
<Parameter Id="M-00FA_A-ABCE-79-0000_P-4" Name="MinMaxSenden" ParameterType="M-00FA_A-ABCE-79-0000_PT-TempSendMinMax" Text="Send min/max value" Value="0">
<Memory CodeSegment="M-00FA_A-ABCE-79-0000_RS-04-00000" Offset="3" BitOffset="0" />
</Parameter>
<Parameter Id="M-00FA_A-ABCE-79-0000_P-5" Name="Abgleich" ParameterType="M-00FA_A-ABCE-79-0000_PT-TempAbgleich" Text="Internal sensor correction value (value * 0.1 K)" Value="0">
<Memory CodeSegment="M-00FA_A-ABCE-79-0000_RS-04-00000" Offset="4" BitOffset="0" />
</Parameter>
</Parameters>
<ParameterRefs>
<ParameterRef Id="M-00FA_A-ABCE-79-0000_P-1_R-1" RefId="M-00FA_A-ABCE-79-0000_P-1" />
<ParameterRef Id="M-00FA_A-ABCE-79-0000_P-2_R-2" RefId="M-00FA_A-ABCE-79-0000_P-2" />
<ParameterRef Id="M-00FA_A-ABCE-79-0000_P-3_R-3" RefId="M-00FA_A-ABCE-79-0000_P-3" />
<ParameterRef Id="M-00FA_A-ABCE-79-0000_P-4_R-4" RefId="M-00FA_A-ABCE-79-0000_P-4" />
<ParameterRef Id="M-00FA_A-ABCE-79-0000_P-5_R-5" RefId="M-00FA_A-ABCE-79-0000_P-5" />
</ParameterRefs>
<ComObjectTable>
<ComObject Id="M-00FA_A-ABCE-79-0000_O-1" Name="Current temperature value" Text="Current temperature value" Number="1" FunctionText="Transmit temperature value" ObjectSize="2 Bytes" ReadFlag="Enabled" WriteFlag="Disabled" CommunicationFlag="Enabled" TransmitFlag="Enabled" UpdateFlag="Disabled" ReadOnInitFlag="Disabled" DatapointType="" />
<ComObject Id="M-00FA_A-ABCE-79-0000_O-2" Name="Max memory value" Text="Max memory value" Number="2" FunctionText="Read memory" ObjectSize="2 Bytes" ReadFlag="Enabled" WriteFlag="Disabled" CommunicationFlag="Enabled" TransmitFlag="Enabled" UpdateFlag="Disabled" ReadOnInitFlag="Disabled" DatapointType="" />
<ComObject Id="M-00FA_A-ABCE-79-0000_O-3" Name="Min memory value" Text="Min memory value" Number="3" FunctionText="Read memory" ObjectSize="2 Bytes" ReadFlag="Enabled" WriteFlag="Disabled" CommunicationFlag="Enabled" TransmitFlag="Enabled" UpdateFlag="Disabled" ReadOnInitFlag="Disabled" DatapointType="" />
<ComObject Id="M-00FA_A-ABCE-79-0000_O-4" Name="Min/max memory reseet" Text="Min/max memory reseet" Number="4" FunctionText="Reset memory" ObjectSize="1 Bit" ReadFlag="Disabled" WriteFlag="Enabled" CommunicationFlag="Enabled" TransmitFlag="Disabled" UpdateFlag="Disabled" ReadOnInitFlag="Disabled" DatapointType="" />
</ComObjectTable>
<ComObjectRefs>
<ComObjectRef Id="M-00FA_A-ABCE-79-0000_O-1_R-1" RefId="M-00FA_A-ABCE-79-0000_O-1" />
<ComObjectRef Id="M-00FA_A-ABCE-79-0000_O-2_R-2" RefId="M-00FA_A-ABCE-79-0000_O-2" />
<ComObjectRef Id="M-00FA_A-ABCE-79-0000_O-3_R-3" RefId="M-00FA_A-ABCE-79-0000_O-3" />
<ComObjectRef Id="M-00FA_A-ABCE-79-0000_O-4_R-4" RefId="M-00FA_A-ABCE-79-0000_O-4" />
</ComObjectRefs>
<AddressTable MaxEntries="65000" />
<AssociationTable MaxEntries="65000" />
<LoadProcedures>
<LoadProcedure MergeId="2">
<LdCtrlRelSegment AppliesTo="full" LsmIdx="4" Size="8" Mode="0" Fill="0" />
</LoadProcedure>
<LoadProcedure MergeId="4">
<LdCtrlWriteRelMem ObjIdx="4" Offset="0" Size="8" Verify="true" />
</LoadProcedure>
</LoadProcedures>
<Options />
</Static>
<Dynamic>
<ChannelIndependentBlock>
<ParameterBlock Id="M-00FA_A-ABCE-79-0000_PB-1" Name="ParameterPage" Text="Allgemeine Parameter">
<ParameterRefRef RefId="M-00FA_A-ABCE-79-0000_P-1_R-1" />
<ParameterRefRef RefId="M-00FA_A-ABCE-79-0000_P-2_R-2" />
<ParameterRefRef RefId="M-00FA_A-ABCE-79-0000_P-3_R-3" />
<ParameterRefRef RefId="M-00FA_A-ABCE-79-0000_P-4_R-4" />
<ParameterRefRef RefId="M-00FA_A-ABCE-79-0000_P-5_R-5" />
<ComObjectRefRef RefId="M-00FA_A-ABCE-79-0000_O-1_R-1" />
<ComObjectRefRef RefId="M-00FA_A-ABCE-79-0000_O-2_R-2" />
<ComObjectRefRef RefId="M-00FA_A-ABCE-79-0000_O-3_R-3" />
<ComObjectRefRef RefId="M-00FA_A-ABCE-79-0000_O-4_R-4" />
</ParameterBlock>
</ChannelIndependentBlock>
</Dynamic>
</ApplicationProgram>
</ApplicationPrograms>
<Hardware>
<Hardware Id="M-00FA_H-0124-0" Name="SAMD Random" SerialNumber="0124" VersionNumber="0" BusCurrent="10" HasIndividualAddress="true" HasApplicationProgram="true">
<Products>
<Product Id="M-00FA_H-0124-0_P-IA4313" Text="Temperatursensor TP" OrderNumber="IA4313" IsRailMounted="false" DefaultLanguage="en-US" />
</Products>
<Hardware2Programs>
<Hardware2Program Id="M-00FA_H-0124-0_HP-ABCE-79-0000" MediumTypes="MT-0">
<ApplicationProgramRef RefId="M-00FA_A-ABCE-79-0000" />
</Hardware2Program>
</Hardware2Programs>
</Hardware>
</Hardware>
</Manufacturer>
</ManufacturerData>
</KNX>

View File

@ -0,0 +1,138 @@
#include <knx.h>
#include <knx/bau07B0.h>
#ifdef ARDUINO_ARCH_ESP8266
#include <WiFiManager.h>
#endif
// create named references for easy access to group objects
#define goCurrent knx.getGroupObject(1)
#define goMax knx.getGroupObject(2)
#define goMin knx.getGroupObject(3)
#define goReset knx.getGroupObject(4)
// If you don't want a global knx object, for example because you want
// to more finely control it's construction, this is an example
// of how to do so. Define KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
// and then you can DIY a knx object as shown below. In this case we use
// the ESP32's secondary UART and late-bind the ISR function in setup().
Esp32Platform knxPlatform(&Serial2);
Bau07B0 knxBau(knxPlatform);
KnxFacade<Esp32Platform, Bau07B0> knx(knxBau);
ICACHE_RAM_ATTR void myButtonPressed()
{
// Debounce
static uint32_t lastpressed=0;
if (millis() - lastpressed > 200)
{
knx.toggleProgMode();
lastpressed = millis();
}
}
float currentValue = 0;
float maxValue = 0;
float minValue = RAND_MAX;
long lastsend = 0;
void measureTemp()
{
long now = millis();
if ((now - lastsend) < 2000)
return;
lastsend = now;
int r = rand();
currentValue = (r * 1.0) / (RAND_MAX * 1.0);
currentValue *= 100 * 100;
// write new value to groupobject
goCurrent.value(currentValue);
if (currentValue > maxValue)
{
maxValue = currentValue;
goMax.value(maxValue);
}
if (currentValue < minValue)
{
minValue = currentValue;
goMin.value(minValue);
}
}
// callback from reset-GO
void resetCallback(GroupObject& go)
{
if (go.value())
{
maxValue = 0;
minValue = 10000;
}
}
void setup()
{
knx.setButtonISRFunction(myButtonPressed);
Serial.begin(115200);
ArduinoPlatform::SerialDebug = &Serial;
Serial2.begin(19200); // KNX, pin 16,17 on EPS32
randomSeed(millis());
#ifdef ARDUINO_ARCH_ESP8266
WiFiManager wifiManager;
wifiManager.autoConnect("knx-demo");
#endif
// read adress table, association table, groupobject table and parameters from eeprom
knx.readMemory();
// print values of parameters if device is already configured
if (knx.configured())
{
// register callback for reset GO
goReset.callback(resetCallback);
goReset.dataPointType(DPT_Trigger);
goCurrent.dataPointType(DPT_Value_Temp);
goMin.dataPointType(DPT_Value_Temp);
goMax.dataPointType(DPT_Value_Temp);
Serial.print("Timeout: ");
Serial.println(knx.paramByte(0));
Serial.print("Zykl. senden: ");
Serial.println(knx.paramByte(1));
Serial.print("Min/Max senden: ");
Serial.println(knx.paramByte(2));
Serial.print("Aenderung senden: ");
Serial.println(knx.paramByte(3));
Serial.print("Abgleich: ");
Serial.println(knx.paramByte(4));
}
// pin or GPIO the programming led is connected to. Default is LED_BUILTIN
// knx.ledPin(LED_BUILTIN);
// is the led active on HIGH or low? Default is LOW
// knx.ledPinActiveOn(HIGH);
// pin or GPIO programming button is connected to. Default is 0
// knx.buttonPin(0);
// start the framework.
knx.start();
}
void loop()
{
// don't delay here to much. Otherwise you might lose packages or mess up the timing with ETS
knx.loop();
// only run the application code if the device was configured with ETS
if (!knx.configured())
return;
measureTemp();
}

View File

@ -0,0 +1,24 @@
;PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
;
;--- ESP32 -----------------------------------------------
[env:esp32dev_tp]
platform = espressif32
board = esp32dev
framework = arduino
lib_deps =
knx
build_flags =
-DMASK_VERSION=0x07B0
-Wno-unknown-pragmas
-DKNX_NO_AUTOMATIC_GLOBAL_INSTANCE

View File

@ -0,0 +1,33 @@
;PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[platformio]
; We have to keep libdeps dir out the project directory otherwise,
; library scanner seems to have issues so compilation fails
libdeps_dir = /tmp/libdeps
src_dir = .
;--- ESP32 -----------------------------------------------
[env:esp32dev_tp]
platform = espressif32
board = esp32dev
framework = arduino
; We consider that the this projects is opened within its project directory
; while working with VS Code.
lib_extra_dirs = ../../../
lib_deps =
knx
build_flags =
-DMASK_VERSION=0x07B0
-Wno-unknown-pragmas
-DKNX_NO_AUTOMATIC_GLOBAL_INSTANCE

View File

@ -59,6 +59,7 @@ framework = arduino
lib_extra_dirs = ../../../ lib_extra_dirs = ../../../
lib_deps = lib_deps =
WifiManager
knx knx
build_flags = build_flags =

View File

@ -46,10 +46,10 @@ KnxFacade<LinuxPlatform, Bau07B0> knx;
long lastsend = 0; long lastsend = 0;
#define CURR knx.getGroupObject(1) #define GO_CURR knx.getGroupObject(1)
#define MAX knx.getGroupObject(2) #define GO_MAX knx.getGroupObject(2)
#define MIN knx.getGroupObject(3) #define GO_MIN knx.getGroupObject(3)
#define RESET knx.getGroupObject(4) #define GO_RESET knx.getGroupObject(4)
void measureTemp() void measureTemp()
{ {
@ -65,22 +65,22 @@ void measureTemp()
// currentValue *= (670433.28 + 273); // currentValue *= (670433.28 + 273);
// currentValue -= 273; // currentValue -= 273;
println(currentValue); println(currentValue);
CURR.value(currentValue); GO_CURR.value(currentValue);
double max = MAX.value(); double max = GO_MAX.value();
if (currentValue > max) if (currentValue > max)
MAX.value(currentValue); GO_MAX.value(currentValue);
if (currentValue < (double)MIN.value()) if (currentValue < (double)GO_MIN.value())
MIN.value(currentValue); GO_MIN.value(currentValue);
} }
void resetCallback(GroupObject& go) void resetCallback(GroupObject& go)
{ {
if (go.value()) if (go.value())
{ {
MAX.valueNoSend(-273.0); GO_MAX.valueNoSend(-273.0);
MIN.valueNoSend(670433.28); GO_MIN.valueNoSend(670433.28);
} }
} }
@ -102,13 +102,13 @@ void setup()
if (knx.configured()) if (knx.configured())
{ {
CURR.dataPointType(Dpt(9, 1)); GO_CURR.dataPointType(Dpt(9, 1));
MIN.dataPointType(Dpt(9, 1)); GO_MIN.dataPointType(Dpt(9, 1));
MIN.value(670433.28); GO_MIN.value(670433.28);
MAX.dataPointType(Dpt(9, 1)); GO_MAX.dataPointType(Dpt(9, 1));
MAX.valueNoSend(-273.0); GO_MAX.valueNoSend(-273.0);
RESET.dataPointType(Dpt(1, 15)); GO_RESET.dataPointType(Dpt(1, 15));
RESET.callback(resetCallback); GO_RESET.callback(resetCallback);
printf("Timeout: %d\n", knx.paramWord(0)); printf("Timeout: %d\n", knx.paramWord(0));
printf("Zykl. senden: %d\n", knx.paramByte(2)); printf("Zykl. senden: %d\n", knx.paramByte(2));
printf("Min/Max senden: %d\n", knx.paramByte(3)); printf("Min/Max senden: %d\n", knx.paramByte(3));

View File

@ -0,0 +1,352 @@
#include <knx.h>
#include <PZEM004Tv30.h>
#include "wiring_private.h" // pinPeripheral() function
#include <TimeLib.h>
//Sercom Stuff
#define PIN_SERIAL2_RX (34ul) // Pin description number for PIO_SERCOM on D12 (34ul)
#define PIN_SERIAL2_TX (36ul) // Pin description number for PIO_SERCOM on D10 (36ul)
#define PAD_SERIAL2_TX (UART_TX_PAD_2) // SERCOM pad 2
#define PAD_SERIAL2_RX (SERCOM_RX_PAD_3) // SERCOM pad 3
Uart Serial2(&sercom1, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX); //TX D10, RX D12
void SERCOM1_Handler()
{
Serial2.IrqHandler();
}
//PZEM stuff
#define PZEM004_NO_SWSERIAL
#define PZEM_DEFAULT_ADDR 0xF8
//knx stuff
#define goReset knx.getGroupObject(1)
#define goDateTime knx.getGroupObject(2)
#define goProgMode knx.getGroupObject(9)
// Global Const
const uint16_t ets_timePeriod[7] = {0, 1, 5, 15, 1 * 60, 5 * 60, 15 * 60};
const uint8_t ets_startupTimeout[7] = {0, 1, 2, 3, 4, 5, 6};
const uint8_t ets_percentCycle[6] = {0, 5, 10, 15, 20, 30}; //need knxprod update... ?
const uint8_t ledPin = LED_BUILTIN;// the number of the LED pin
const uint8_t physicalCount = 6; // voltage,current,power_factor,power,energy,frequency
// Global Variable
uint8_t percentCycle = 0; // better to define a global or read knx.paramByte each time... ?
uint32_t timePeriod = 0; // same here,
uint8_t resetPeriod = 0; //same here ...
uint8_t resetEnergy = 0; // and here... disabled/day/week/month
bool progMode = true;
// Issue on https://github.com/mandulaj/PZEM-004T-v30/issues/43
PZEM004Tv30 pzem(Serial2, PZEM_DEFAULT_ADDR);
struct Physical {
void init(uint8_t GOaddr, Dpt type_dpt){
_GOaddr = GOaddr;
_dpt = type_dpt;
}
void loop(){
// unsigned long currentMillis = millis();
// Delta Change update as defined in ETS
int32_t deltaPercent = ( 100 * ( _value - _lastValue ) / _value );
if ( percentCycle != 0 && abs(deltaPercent) >= percentCycle )
{
_trigger = true;
_lastValue = _value;
}
// Refresh groupAddress value as defined in ETS since last update
if ( timePeriod != 0 && millis() - _lastMillis >= timePeriod )
{
_trigger = true;
}
// UpdateGO but send to bus only if triggered by time or value change percentage
if (_trigger){
knx.getGroupObject(_GOaddr).value(_value, _dpt);
_lastMillis = millis();
_trigger = false;
}else{
knx.getGroupObject(_GOaddr).valueNoSend(_value, _dpt);
}
}
void setValue(float value){
if (value != _value)
{
_value = value;
}
}
private:
Dpt _dpt;
float _value = 0;
float _lastValue = 0;
uint32_t _lastMillis = 0;
uint8_t _GOaddr;
bool _trigger = false;
// bool isUpdated = false;
public:
} Physical[physicalCount];
class Blinker
{
private:
uint8_t ledPin_; // the number of the LED pin
uint32_t OnTime = 1000; // milliseconds of on-time
uint32_t OffTime = 1000; // milliseconds of off-time
bool ledState = LOW; // ledState used to set the LED
uint32_t previousMillis; // will store last time LED was updated
void setOutput(bool state_, uint32_t currentMillis_){
ledState = state_;
previousMillis = currentMillis_;
digitalWrite(ledPin_, state_);
}
public:
Blinker(uint8_t pin)
{
ledPin_ = pin;
pinMode(ledPin_, OUTPUT);
previousMillis = 0;
}
void set(uint32_t on, uint32_t off){
OnTime = on;
OffTime = off;
}
void loop(){
uint32_t currentMillis = millis();
if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
{
setOutput(LOW, currentMillis);
}
else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
{
setOutput(HIGH, currentMillis);
}
}
};
Blinker led = Blinker(ledPin);
void callBackProgMode(GroupObject& go){
progMode = (bool)go.value();
}
void callBackDateTime(GroupObject& go){
static uint32_t lastUpdate = 0;
const uint32_t interval = (1000 * 60 * 60 * 24); // 1day
struct tm myTime;
myTime = go.value();
unsigned short tmp_sec = myTime.tm_sec;
unsigned short tmp_min = myTime.tm_min;
unsigned short tmp_hour = myTime.tm_hour;
unsigned short tmp_mday = myTime.tm_mday;
unsigned short tmp_month = myTime.tm_mon;
unsigned short tmp_year = myTime.tm_year;
if (millis() - lastUpdate >= interval && !timeStatus() == timeSet)
{
setTime(tmp_hour, tmp_min, tmp_sec, tmp_mday, tmp_month, tmp_year);
lastUpdate = millis();
}
}
void resetCallback(GroupObject& go)
{
if (go.value())
{
resetEnergy = true;
goReset.value(false);
}
}
void setup() {
pinPeripheral(PIN_SERIAL2_RX, PIO_SERCOM);
pinPeripheral(PIN_SERIAL2_TX, PIO_SERCOM);
SerialUSB.begin(9600);
Serial2.begin(9600);
ArduinoPlatform::SerialDebug = &SerialUSB;
randomSeed(millis());
knx.readMemory();
// led.set(5000, 5000);
if (knx.configured())
{
int confStartupTime = ets_startupTimeout[knx.paramByte(0)] * 1000;
delay(confStartupTime); // the only delay used, why make a withoutDelay function for that?
percentCycle = ets_percentCycle[knx.paramByte(1)];
timePeriod = ets_timePeriod[knx.paramByte(2)] * 1000;
resetPeriod = knx.paramByte(3);
goReset.callback(resetCallback);
goReset.dataPointType(DPT_Trigger);
goDateTime.dataPointType(DPT_DateTime);
goProgMode.dataPointType(DPT_Trigger);
goProgMode.callback(callBackProgMode);
uint8_t GOaddr = 3;
Physical[0].init(GOaddr, DPT_Value_Electric_Potential); // voltage
Physical[1].init(GOaddr += 1, DPT_Value_Electric_Current);
Physical[2].init(GOaddr += 1, DPT_Value_Power_Factor);
Physical[3].init(GOaddr += 1, DPT_Value_Power);
Physical[4].init(GOaddr += 1, DPT_Value_Energy);
Physical[5].init(GOaddr += 1, DPT_Value_Frequency);
led.set(2000, 1000);
}
// is the led active on HIGH or low? Default is LOW
knx.ledPinActiveOn(HIGH);
// pin or GPIO programming button is connected to. Default is 0
knx.ledPin(5);
knx.buttonPin(9);
knx.start();
// while (!SerialUSB) { //wait for DEBUGING
// ; // wait for serial port to connect. Needed for native USB port only
// }
}
void loop() {
knx.loop();
if (knx.configured() && !progMode)
{
refreshValueLoop();
resetEnergyLoop();
for (uint8_t i=0; i< physicalCount; i++)
{
Physical[i].loop();
}
}
else if (progMode)
{
prodModeLoop();
}
}
void refreshValueLoop(){
static const uint16_t pzemInterval = 500; // interval at which to blink (milliseconds)
static uint32_t lastPzemUpdate = 0;
if (millis() - lastPzemUpdate >= pzemInterval)
{
for (uint8_t i=0; i< physicalCount; i++)
{
float isaValue;
switch (i) { //maybe a pointer or reference could be nicer...
case 0:
isaValue = pzem.voltage();
break;
case 1:
isaValue = pzem.current();
break;
case 2:
isaValue = pzem.pf();
break;
case 3:
isaValue = pzem.power();
break;
case 4:
isaValue = pzem.energy();
break;
case 5:
isaValue = pzem.frequency();
break;
default:
break;
}
if(!isnan(isaValue))
{
Physical[i].setValue(isaValue);
}
}
}
}
void resetEnergyLoop(){
static time_t lastTime;
time_t samdTime = now();
if (timeStatus() == timeSet)
{
switch (resetPeriod)
{
case 1: //day
if (day(samdTime) != day(lastTime))
{
lastTime = samdTime;
pzem.resetEnergy();
}
break;
case 2: //week
if (weekday(samdTime) != weekday(lastTime) && weekday(samdTime) == 2) //monday
{
lastTime = samdTime;
pzem.resetEnergy();
}
break;
case 3: // month
if (month(samdTime) != month(lastTime))
{
lastTime = samdTime;
pzem.resetEnergy();
}
break;
case 4: // year
if (year(samdTime) != year(lastTime))
{
lastTime = samdTime;
pzem.resetEnergy();
}
default:
break;
}
}
}
void prodModeLoop(){ // run Only if progMode triggered ( at start or callback)
static uint32_t timerProgPrevMillis = 0;
const uint32_t timerProgMode = ( 15 * 60 * 1000 ) ; // 15min
if (!knx.progMode())
{
knx.progMode(true);
timerProgPrevMillis = millis();
led.set(500, 250);
}
else
{
if (millis() - timerProgPrevMillis > timerProgMode) {
knx.progMode(false);
goProgMode.value(false);
progMode = 0;
}
}
}

View File

@ -12,11 +12,12 @@ ArduinoPlatform::ArduinoPlatform(HardwareSerial* knxSerial) : _knxSerial(knxSeri
void ArduinoPlatform::fatalError() void ArduinoPlatform::fatalError()
{ {
const int period = 200;
while (true) while (true)
{ {
#ifdef LED_BUILTIN #ifdef LED_BUILTIN
if ((millis() % period) > (period / 2)) static const long LED_BLINK_PERIOD = 200;
if ((millis() % LED_BLINK_PERIOD) > (LED_BLINK_PERIOD / 2))
digitalWrite(LED_BUILTIN, HIGH); digitalWrite(LED_BUILTIN, HIGH);
else else
digitalWrite(LED_BUILTIN, LOW); digitalWrite(LED_BUILTIN, LOW);

View File

@ -10,7 +10,7 @@ Esp32Platform::Esp32Platform() : ArduinoPlatform(&Serial1)
{ {
} }
Esp32Platform::Esp32Platform( HardwareSerial* s) : ArduinoPlatform(s) Esp32Platform::Esp32Platform(HardwareSerial* s) : ArduinoPlatform(s)
{ {
} }
@ -58,10 +58,9 @@ void Esp32Platform::closeMultiCast()
bool Esp32Platform::sendBytesMultiCast(uint8_t * buffer, uint16_t len) bool Esp32Platform::sendBytesMultiCast(uint8_t * buffer, uint16_t len)
{ {
//printHex("<- ",buffer, len); //printHex("<- ",buffer, len);
int result = 0; _udp.beginMulticastPacket();
result = _udp.beginMulticastPacket(); _udp.write(buffer, len);
result = _udp.write(buffer, len); _udp.endPacket();
result = _udp.endPacket();
return true; return true;
} }

View File

@ -8,7 +8,7 @@ class Esp32Platform : public ArduinoPlatform
{ {
public: public:
Esp32Platform(); Esp32Platform();
Esp32Platform( HardwareSerial* s); Esp32Platform(HardwareSerial* s);
// ip stuff // ip stuff
uint32_t currentIpAddress() override; uint32_t currentIpAddress() override;

View File

@ -61,10 +61,9 @@ void EspPlatform::closeMultiCast()
bool EspPlatform::sendBytesMultiCast(uint8_t * buffer, uint16_t len) bool EspPlatform::sendBytesMultiCast(uint8_t * buffer, uint16_t len)
{ {
//printHex("<- ",buffer, len); //printHex("<- ",buffer, len);
int result = 0; _udp.beginPacketMulticast(_mulitcastAddr, _mulitcastPort, WiFi.localIP());
result = _udp.beginPacketMulticast(_mulitcastAddr, _mulitcastPort, WiFi.localIP()); _udp.write(buffer, len);
result = _udp.write(buffer, len); _udp.endPacket();
result = _udp.endPacket();
return true; return true;
} }

View File

@ -8,7 +8,7 @@ class EspPlatform : public ArduinoPlatform
{ {
public: public:
EspPlatform(); EspPlatform();
EspPlatform( HardwareSerial* s); EspPlatform(HardwareSerial* s);
// ip stuff // ip stuff
uint32_t currentIpAddress() override; uint32_t currentIpAddress() override;

View File

@ -13,6 +13,18 @@
#define ntohl(x) htonl(x) #define ntohl(x) htonl(x)
#endif #endif
#ifndef MIN
#define MIN(a, b) ((a < b) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) ((a > b) ? (a) : (b))
#endif
#ifndef ABS
#define ABS(x) ((x > 0) ? (x) : (-x))
#endif
#if defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_STM32) #if defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_STM32)
#include <Arduino.h> #include <Arduino.h>
#elif defined(ARDUINO_ARCH_ESP8266) #elif defined(ARDUINO_ARCH_ESP8266)
@ -106,4 +118,4 @@ enum ParameterFloatEncodings
#undef max #undef max
#undef min #undef min
// end of temporary undef // end of temporary undef
#endif #endif

View File

@ -2,10 +2,6 @@
#include <string.h> #include <string.h>
#include "bits.h" #include "bits.h"
#ifndef KNX_FLASH_SIZE
# define KNX_FLASH_SIZE 8192
#endif
Memory::Memory(Platform& platform, DeviceObject& deviceObject) Memory::Memory(Platform& platform, DeviceObject& deviceObject)
: _platform(platform), _deviceObject(deviceObject) : _platform(platform), _deviceObject(deviceObject)
{ {

View File

@ -9,6 +9,10 @@
#define MAXSAVE 5 #define MAXSAVE 5
#define MAXTABLEOBJ 4 #define MAXTABLEOBJ 4
#ifndef KNX_FLASH_SIZE
# define KNX_FLASH_SIZE 1024
#endif
class MemoryBlock class MemoryBlock
{ {
public: public:

View File

@ -12,10 +12,6 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#define MIN(a, b) ((a < b) ? (a) : (b))
#define MAX(a, b) ((a > b) ? (a) : (b))
#define ABS(x) ((x > 0) ? (x) : (-x))
// Table for encoding 4-bit data into a 8-bit Manchester encoding. // Table for encoding 4-bit data into a 8-bit Manchester encoding.
const uint8_t RfPhysicalLayerCC1101::manchEncodeTab[16] = {0xAA, // 0x0 Manchester encoded const uint8_t RfPhysicalLayerCC1101::manchEncodeTab[16] = {0xAA, // 0x0 Manchester encoded
0xA9, // 0x1 Manchester encoded 0xA9, // 0x1 Manchester encoded

View File

@ -2,72 +2,72 @@
#include "knx/bits.h" #include "knx/bits.h"
#ifdef ARDUINO_ARCH_SAMD #ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
// predefined global instance for TP or RF or TP/RF coupler
#if MASK_VERSION == 0x07B0 #if (defined(ARDUINO_ARCH_STM32) || \
KnxFacade<SamdPlatform, Bau07B0> knx; defined(ARDUINO_ARCH_ESP32) || \
#elif MASK_VERSION == 0x27B0 defined(ARDUINO_ARCH_ESP8266) || \
KnxFacade<SamdPlatform, Bau27B0> knx; defined(ARDUINO_ARCH_SAMD))
#elif MASK_VERSION == 0x2920
KnxFacade<SamdPlatform, Bau2920> knx; // Only ESP8266 and ESP32 have this define. For all other platforms this is just empty.
#else #ifndef ICACHE_RAM_ATTR
#error Mask version not supported on ARDUINO_ARCH_SAMD #define ICACHE_RAM_ATTR
#endif
ICACHE_RAM_ATTR void buttonUp()
{
static uint32_t lastpressed=0;
if (millis() - lastpressed > 200){
knx.toggleProgMode();
lastpressed = millis();
}
}
#endif #endif
#elif defined(ARDUINO_ARCH_ESP8266) #ifdef ARDUINO_ARCH_SAMD
// predefined global instance for TP or IP or TP/IP coupler // predefined global instance for TP or RF or TP/RF coupler
#if MASK_VERSION == 0x07B0 #if MASK_VERSION == 0x07B0
KnxFacade<EspPlatform, Bau07B0> knx; KnxFacade<SamdPlatform, Bau07B0> knx(buttonUp);
#elif MASK_VERSION == 0x57B0 #elif MASK_VERSION == 0x27B0
KnxFacade<EspPlatform, Bau57B0> knx; KnxFacade<SamdPlatform, Bau27B0> knx(buttonUp);
#elif MASK_VERSION == 0x091A #elif MASK_VERSION == 0x2920
KnxFacade<EspPlatform, Bau091A> knx; KnxFacade<SamdPlatform, Bau2920> knx(buttonUp);
#else #else
#error Mask version not supported on ARDUINO_ARCH_ESP8266 #error "Mask version not supported on ARDUINO_ARCH_SAMD"
#endif
#elif defined(ARDUINO_ARCH_ESP8266)
// predefined global instance for TP or IP or TP/IP coupler
#if MASK_VERSION == 0x07B0
KnxFacade<EspPlatform, Bau07B0> knx(buttonUp);
#elif MASK_VERSION == 0x57B0
KnxFacade<EspPlatform, Bau57B0> knx(buttonUp);
#elif MASK_VERSION == 0x091A
KnxFacade<EspPlatform, Bau091A> knx(buttonUp);
#else
#error "Mask version not supported on ARDUINO_ARCH_ESP8266"
#endif
#elif defined(ARDUINO_ARCH_ESP32)
// predefined global instance for TP or IP or TP/IP coupler
#if MASK_VERSION == 0x07B0
KnxFacade<Esp32Platform, Bau07B0> knx(buttonUp);
#elif MASK_VERSION == 0x57B0
KnxFacade<Esp32Platform, Bau57B0> knx(buttonUp);
#elif MASK_VERSION == 0x091A
KnxFacade<Esp32Platform, Bau091A> knx(buttonUp);
#else
#error "Mask version not supported on ARDUINO_ARCH_ESP32"
#endif
#elif defined(ARDUINO_ARCH_STM32)
#if MASK_VERSION == 0x07B0
KnxFacade<Stm32Platform, Bau07B0> knx(buttonUp);
#else
#error "Mask version not supported on ARDUINO_ARCH_STM32"
#endif
#else // Non-Arduino platforms and Linux platform
// no predefined global instance
#endif #endif
#elif defined(ARDUINO_ARCH_ESP32) #endif // KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
// predefined global instance for TP or IP or TP/IP coupler
#if MASK_VERSION == 0x07B0
KnxFacade<Esp32Platform, Bau07B0> knx;
#elif MASK_VERSION == 0x57B0
KnxFacade<Esp32Platform, Bau57B0> knx;
#elif MASK_VERSION == 0x091A
KnxFacade<Esp32Platform, Bau091A> knx;
#else
#error Mask version not supported on ARDUINO_ARCH_ESP8266
#endif
#elif defined(ARDUINO_ARCH_STM32)
#if MASK_VERSION == 0x07B0
KnxFacade<Stm32Platform, Bau07B0> knx;
#else
#error Mask version not supported on ARDUINO_ARCH_STM32
#endif
#else // Non-Arduino platforms and Linux platform
// no predefined global instance
#endif
// Only ESP8266 and ESP32 have this define. For all other platforms this is just empty.
#ifndef ICACHE_RAM_ATTR
#define ICACHE_RAM_ATTR
#endif
#if (defined(ARDUINO_ARCH_STM32) || \
defined(ARDUINO_ARCH_ESP32) || \
defined(ARDUINO_ARCH_ESP8266) || \
defined(ARDUINO_ARCH_SAMD))
ICACHE_RAM_ATTR void buttonUp()
{
static uint32_t lastpressed=0;
if (millis() - lastpressed > 200){
knx._toogleProgMode = true;
lastpressed = millis();
}
}
#elif defined(__linux__)
void buttonUp()
{
// no de-bounce on linux platform, just satisfy the compiler
}
#endif

View File

@ -10,33 +10,41 @@
#ifdef ARDUINO_ARCH_SAMD #ifdef ARDUINO_ARCH_SAMD
#include "samd_platform.h" #include "samd_platform.h"
void buttonUp(); #ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
void buttonUp();
#endif
#elif defined(ARDUINO_ARCH_ESP8266) #elif defined(ARDUINO_ARCH_ESP8266)
#include "esp_platform.h" #include "esp_platform.h"
void buttonUp(); #ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
void buttonUp();
#endif
#elif defined(ARDUINO_ARCH_ESP32) #elif defined(ARDUINO_ARCH_ESP32)
#define LED_BUILTIN 13 #define LED_BUILTIN 13
#include "esp32_platform.h" #include "esp32_platform.h"
void buttonUp(); #ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
void buttonUp();
#endif
#elif defined(ARDUINO_ARCH_STM32) #elif defined(ARDUINO_ARCH_STM32)
#include "stm32_platform.h" #include "stm32_platform.h"
void buttonUp(); #ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
void buttonUp();
#endif
#elif __linux__ #elif __linux__
#define LED_BUILTIN 0 #define LED_BUILTIN 0
#include "linux_platform.h" #include "linux_platform.h"
void buttonUp();
#else #else
#define LED_BUILTIN 5 // see GPIO_PinConfig gpioPinConfigs[] #define LED_BUILTIN 5 // see GPIO_PinConfig gpioPinConfigs[]
#include "cc1310_platform.h" #include "cc1310_platform.h"
extern void buttonUp(); #ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
extern void buttonUp();
#endif
#endif #endif
typedef uint8_t* (*SaveRestoreCallback)(uint8_t* buffer); typedef uint8_t* (*SaveRestoreCallback)(uint8_t* buffer);
typedef void (*IsrFunctionPtr)();
template <class P, class B> class KnxFacade : private SaveRestore template <class P, class B> class KnxFacade : private SaveRestore
{ {
friend void buttonUp();
public: public:
KnxFacade() : _platformPtr(new P()), _bauPtr(new B(*_platformPtr)), _bau(*_bauPtr) KnxFacade() : _platformPtr(new P()), _bauPtr(new B(*_platformPtr)), _bau(*_bauPtr)
{ {
@ -44,6 +52,19 @@ template <class P, class B> class KnxFacade : private SaveRestore
_bau.addSaveRestore(this); _bau.addSaveRestore(this);
} }
KnxFacade(B& bau) : _bau(bau)
{
manufacturerId(0xfa);
_bau.addSaveRestore(this);
}
KnxFacade(IsrFunctionPtr buttonISRFunction) : _platformPtr(new P()), _bauPtr(new B(*_platformPtr)), _bau(*_bauPtr)
{
manufacturerId(0xfa);
_bau.addSaveRestore(this);
setButtonISRFunction(buttonISRFunction);
}
virtual ~KnxFacade() virtual ~KnxFacade()
{ {
if (_bauPtr) if (_bauPtr)
@ -53,12 +74,6 @@ template <class P, class B> class KnxFacade : private SaveRestore
delete _platformPtr; delete _platformPtr;
} }
KnxFacade(B& bau) : _bau(bau)
{
manufacturerId(0xfa);
_bau.addSaveRestore(this);
}
P& platform() P& platform()
{ {
return *_platformPtr; return *_platformPtr;
@ -89,6 +104,14 @@ template <class P, class B> class KnxFacade : private SaveRestore
_bau.deviceObject().progMode(value); _bau.deviceObject().progMode(value);
} }
/**
* To be called by ISR handling on button press.
*/
void toggleProgMode()
{
_toggleProgMode = true;
}
bool configured() bool configured()
{ {
return _bau.configured(); return _bau.configured();
@ -181,10 +204,10 @@ template <class P, class B> class KnxFacade : private SaveRestore
digitalWrite(ledPin(), HIGH - _ledPinActiveOn); digitalWrite(ledPin(), HIGH - _ledPinActiveOn);
} }
} }
if (_toogleProgMode) if (_toggleProgMode)
{ {
progMode(!progMode()); progMode(!progMode());
_toogleProgMode = false; _toggleProgMode = false;
} }
_bau.loop(); _bau.loop();
} }
@ -216,21 +239,30 @@ template <class P, class B> class KnxFacade : private SaveRestore
void start() void start()
{ {
pinMode(_ledPin, OUTPUT); pinMode(ledPin(), OUTPUT);
digitalWrite(_ledPin, HIGH - _ledPinActiveOn); digitalWrite(ledPin(), HIGH - _ledPinActiveOn);
pinMode(_buttonPin, INPUT_PULLUP); pinMode(buttonPin(), INPUT_PULLUP);
if (_progButtonISRFuncPtr)
{
// Workaround for https://github.com/arduino/ArduinoCore-samd/issues/587
#if (ARDUINO_API_VERSION >= 10200)
attachInterrupt(_buttonPin, _progButtonISRFuncPtr, (PinStatus)_buttonPinInterruptOn);
#else
attachInterrupt(_buttonPin, _progButtonISRFuncPtr, _buttonPinInterruptOn);
#endif
}
// Workaround for https://github.com/arduino/ArduinoCore-samd/issues/587
#if (ARDUINO_API_VERSION >= 10200)
attachInterrupt(_buttonPin, buttonUp, (PinStatus)_buttonPinInterruptOn);
#else
attachInterrupt(_buttonPin, buttonUp, _buttonPinInterruptOn);
#endif
enabled(true); enabled(true);
} }
void setButtonISRFunction(IsrFunctionPtr progButtonISRFuncPtr)
{
_progButtonISRFuncPtr = progButtonISRFuncPtr;
}
void setSaveCallback(SaveRestoreCallback func) void setSaveCallback(SaveRestoreCallback func)
{ {
_saveCallback = func; _saveCallback = func;
@ -303,9 +335,10 @@ template <class P, class B> class KnxFacade : private SaveRestore
uint32_t _buttonPin = 0; uint32_t _buttonPin = 0;
SaveRestoreCallback _saveCallback = 0; SaveRestoreCallback _saveCallback = 0;
SaveRestoreCallback _restoreCallback = 0; SaveRestoreCallback _restoreCallback = 0;
bool _toogleProgMode = false; volatile bool _toggleProgMode = false;
bool _progLedState = false; bool _progLedState = false;
uint16_t _saveSize = 0; uint16_t _saveSize = 0;
IsrFunctionPtr _progButtonISRFuncPtr = 0;
uint8_t* save(uint8_t* buffer) uint8_t* save(uint8_t* buffer)
{ {
@ -334,46 +367,48 @@ template <class P, class B> class KnxFacade : private SaveRestore
} }
}; };
#ifdef ARDUINO_ARCH_SAMD #ifndef KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
// predefined global instance for TP or RF or TP/RF coupler #ifdef ARDUINO_ARCH_SAMD
#if MASK_VERSION == 0x07B0 // predefined global instance for TP or RF or TP/RF coupler
extern KnxFacade<SamdPlatform, Bau07B0> knx; #if MASK_VERSION == 0x07B0
#elif MASK_VERSION == 0x27B0 extern KnxFacade<SamdPlatform, Bau07B0> knx;
extern KnxFacade<SamdPlatform, Bau27B0> knx; #elif MASK_VERSION == 0x27B0
#elif MASK_VERSION == 0x2920 extern KnxFacade<SamdPlatform, Bau27B0> knx;
extern KnxFacade<SamdPlatform, Bau2920> knx; #elif MASK_VERSION == 0x2920
#else extern KnxFacade<SamdPlatform, Bau2920> knx;
#error "Mask version not supported on ARDUINO_ARCH_SAMD" #else
#error "Mask version not supported on ARDUINO_ARCH_SAMD"
#endif
#elif defined(ARDUINO_ARCH_ESP8266)
// predefined global instance for TP or IP or TP/IP coupler
#if MASK_VERSION == 0x07B0
extern KnxFacade<EspPlatform, Bau07B0> knx;
#elif MASK_VERSION == 0x57B0
extern KnxFacade<EspPlatform, Bau57B0> knx;
#elif MASK_VERSION == 0x091A
extern KnxFacade<EspPlatform, Bau091A> knx;
#else
#error "Mask version not supported on ARDUINO_ARCH_ESP8266"
#endif
#elif defined(ARDUINO_ARCH_ESP32)
// predefined global instance for TP or IP or TP/IP coupler
#if MASK_VERSION == 0x07B0
extern KnxFacade<Esp32Platform, Bau07B0> knx;
#elif MASK_VERSION == 0x57B0
extern KnxFacade<Esp32Platform, Bau57B0> knx;
#elif MASK_VERSION == 0x091A
extern KnxFacade<Esp32Platform, Bau091A> knx;
#else
#error "Mask version not supported on ARDUINO_ARCH_ESP32"
#endif
#elif defined(ARDUINO_ARCH_STM32)
// predefined global instance for TP only
#if MASK_VERSION == 0x07B0
extern KnxFacade<Stm32Platform, Bau07B0> knx;
#else
#error "Mask version not supported on ARDUINO_ARCH_STM32"
#endif
#else // Non-Arduino platforms and Linux platform
// no predefined global instance
#endif #endif
#elif defined(ARDUINO_ARCH_ESP8266) #endif // KNX_NO_AUTOMATIC_GLOBAL_INSTANCE
// predefined global instance for TP or IP or TP/IP coupler
#if MASK_VERSION == 0x07B0
extern KnxFacade<EspPlatform, Bau07B0> knx;
#elif MASK_VERSION == 0x57B0
extern KnxFacade<EspPlatform, Bau57B0> knx;
#elif MASK_VERSION == 0x091A
extern KnxFacade<EspPlatform, Bau091A> knx;
#else
#error "Mask version not supported on ARDUINO_ARCH_ESP8266"
#endif
#elif defined(ARDUINO_ARCH_ESP32)
// predefined global instance for TP or IP or TP/IP coupler
#if MASK_VERSION == 0x07B0
extern KnxFacade<Esp32Platform, Bau07B0> knx;
#elif MASK_VERSION == 0x57B0
extern KnxFacade<Esp32Platform, Bau57B0> knx;
#elif MASK_VERSION == 0x091A
extern KnxFacade<Esp32Platform, Bau091A> knx;
#else
#error "Mask version not supported on ARDUINO_ARCH_ESP32"
#endif
#elif defined(ARDUINO_ARCH_STM32)
// predefined global instance for TP only
#if MASK_VERSION == 0x07B0
extern KnxFacade<Stm32Platform, Bau07B0> knx;
#else
#error Mask version not supported on ARDUINO_ARCH_STM32
#endif
#else // Non-Arduino platforms and Linux platform
// no predefined global instance
#endif