KONNEKTING Device Library
Hardware Requirements
- Atmel SAMD21G18J
- Atmel ATMega 328P (*deprecated)
- Atmel ATMega 32U4 (*deprecated)
- Espressif ESP8266 (experimental)
(*)deprecated = will be sonner or later "dropped" and not actively supported/maintained
Other (Arduino compatible) controllers might work as well. But don't expect that they work flawlessly without adapting our library code. We try to keep the number of directly supported controllers short, so that the overall maintenance is easy. We don't want to add dozens of if-else-compiler-flags to support each and every available microcontroller. You can do this by yourself. But please accept that this will not be merged in the public code (maintenance ...)
You need at least two free pins on the microcontroller for
- Programming Button
- Programming LED
It is required, that the programming button is connected to a pin on the microcontroller which is capable of a real harwdare interrupt. Internally we use the attachInterrupt() Arduino function (https://www.arduino.cc/en/Reference/attachInterrupt). So make sure your button is connected to a pin that is supported by this function.
The pin on the microcontroller for the LED can be any digital output pin.
KONNEKTING XML Device Description ".kdevice.xml"
KONNEKTING Device Library
The device library enables the Arduino to connect to the KNX bus.
Example Sketch Explained
1// include KnxDevice library
2#include <KnxDevice.h>
3
4// Set the device identification
5#define MANUFACTURER_ID 12345
6#define DEVICE_ID 123
7#define Revision 0
8
9// Set Prog-LED Pin and Prog-Button Pin
10#define PROG_LED_PIN LED_BUILTIN
11#define PROG_BUTTON_PIN 3
12
13// Set KNX Transceiver serial port
14#ifdef __AVR_ATmega328P__
15#define KNX_SERIAL Serial // Nano/ProMini etc. use Serial
16#else
17#define KNX_SERIAL Serial1 // Leonardo/Micro etc. use Serial1
18#endif
19
20// ----------------------------
21
22// Definition of the Communication Objects attached to the device
23KnxComObject KnxDevice::_comObjectsList[] = {
24
25 /* ComObject ID 0 : Your first com object, referenced in your device XML */
26 KnxComObject(KNX_DPT_1_001, COM_OBJ_LOGIC_IN),
27
28 /* ComObject ID 1 */
29 KnxComObject(KNX_DPT_1_001, COM_OBJ_SENSOR),
30
31 // more com objects if you need ...
32};
33const byte KnxDevice::_numberOfComObjects = sizeof (_comObjectsList) / sizeof (KnxComObject); // do no change this code
34
35// Definition of parameter size / type ...
36// Ensure that this matches your parameter configuration in your device XML
37byte KonnektingDevice::_paramSizeList[] = {
38
39 /* Param Index 0 */ PARAM_UINT8,
40 /* Param Index 1 */ PARAM_INT16,
41 /* Param Index 2 */ PARAM_UINT32,
42
43 // more parameters if you need
44};
45const byte KonnektingDevice::_numberOfParams = sizeof (_paramSizeList); // do no change this code
46
47
48
49// Callback function to handle com objects updates
50void knxEvents(byte index) {
51
52 // index will contain the com-object which received a telegram
53 // Do what ever is needed
54
55};
56
57void setup() {
58
59 // Initialize KNX enabled Arduino Board
60 Konnekting.init(KNX_SERIAL,
61 PROG_BUTTON_PIN,
62 PROG_LED_PIN,
63 MANUFACTURER_ID,
64 DEVICE_ID,
65 REVISION);
66
67 if (!Konnekting.isFactorySetting()) {
68
69 // you can access your parameters by callig
70 byte paramId0 = Konnekting.getUINT8Param(0);
71
72 // There's a getXXXXParam method for each known parameter type
73 }
74}
75
76void loop() {
77 // handle KNX stuff
78 Knx.task();
79 if (Konnekting.isReadyForApplication()) {
80 // do device related stuff
81 }
82}
API
Instead of explaining method by method without any context, we try to explain the code and the API with an step by step approach.
Define the communication objects
First of all, define the KNX communication objects of your bus device. For each object, define its datapoint type, and its flags. Theoritically, you can define up to 255 objects, even if in practical you are limited by the quantity of RAM (it would be worth measuring the max allowed number of objects depending on the memory available).
KnxComObject KnxDevice::_comObjectsList[];
Description: list of the communication objects (group objects) that are attached to your KNX device. Define this variable in your Arduino sketch (but outside all function bodies).
Parameters: for each object in the list, you shall provide the group address (word, use G_ADDR() function), the datapoint type (check "_e_KnxDPT_ID_" enum in KnxDPT.h file), and the flags (byte, check KnxComObject.h for more details).
Example:
1// DataPointType flags
2KnxComObject{KNX_DPT_1_001 /* 1.001 B1 DPT_Switch */ , COM_OBJ_LOGIC_IN_INIT }
3KnxComObject{KNX_DPT_5_010 /* 5.010 U8 DPT_Value_1_Ucount */ , COM_OBJ_SENSOR }
4KnxComObject{KNX_DPT_1_003 /* 1.003 B1 DPT_Enable*/ , 0x30 /* C+R */ }
const byte KnxDevice::_comObjectsNb = sizeof(_comObjectsList) / sizeof(KnxComObject);
Description: Define the number of group objects in the list. Simply copy the above code as is in your Arduino sketch!
Init KNX device
void init(HardwareSerial& serial, int progButtonPin, int progLedPin, word manufacturerID, byte deviceID, byte revisionID);
Description: Start the KNX Device. Place this function call in the setup() function of your Arduino sketch
Parameters: serial = serial port that is connected to the KNX TPUART Transceiver, progButtonPin = arduino pin which is connected to the prog button and **is capable of an real interrupt**, progLedPin = arduino pin which is connected to the programming LED, [manufacturerID = your manufacturer ID](konnekting_manufacturers.md), deviceID = ID identifying your device, revision = revision of your firmware (increment if new version is no longer backwards-compatible)
Example:
1Konnekting.init(KNX_SERIAL,
2 PROG_BUTTON_PIN,
3 PROG_LED_PIN,
4 MANUFACTURER_ID,
5 DEVICE_ID,
6 REVISION);
void task(void);
Description: KNX device execution task. This function call shall be placed in the "loop()" Arduino function.
WARNING: this function shall be called periodically (400us max period) meaning usage of functions stopping the execution (like delay(), visit http://playground.arduino.cc/Code/AvoidDelay for more info) is FORBIDDEN.
Example:
1Knx.task();
Interact with the communication objects
The API allows you to interact with objects that you have defined : you can read and modify their values, force their value to be updated with the value on the bus. You are also notified each time objects get their value changed following a bus access :
void knxEvents(byte objectIndex);
Description: callback function that is called by the KnxDevice library every time a group object is updated by the bus. Define this function in your Arduino sketch.
Parameters : "objectIndex" is the index (in the list) of the object updated by the bus
Example:
1// Callback function to treat object updates
2void knxEvents(byte index) {
3 switch (index)
4 {
5 case 0 : // we arrive here when object index 0 has been updated
6 // code to treat index 0 object update
7 break;
8
9 case 1 : // we arrive here when object index 1 has been updaed
10 // code to treat index 1 object update
11 break;
12
13// ...
14
15 default:
16 // code to treat remaining objects updates
17 break;
18 }
19};
Quick method to get the value of a short object:
byte Knx.read(byte objectIndex);
Description: Get the current value of a short group object. This function is relevant for _short_ objects only, see table below. The returned value will be hazardous in case of use with _long_ objects.
Parameters: "objectIndex" is the index (in the list) of the object to be read.
Return: the current value of the object.
Example:
1Knx.read(0); // return index 0 object value
Byte no#: | 0 | 1 | 2 | ... | 13 |
---|---|---|---|---|---|
Used for: | Header, 2 bytes | Body, 12 Bytes | |||
Description: | Protocolversion | Message-Type-ID | depends on Message-Type-ID | ||
Range: | 0x00..0xFF | 0x00..0xFF |
Supported KNX DPT formats | Remark |
---|---|
KNX_DPT_FORMAT_B1 | |
KNX_DPT_FORMAT_B2 | |
KNX_DPT_FORMAT_B1U3 | bit fields to be computed by user application |
KNX_DPT_FORMAT_A8 | |
KNX_DPT_FORMAT_U8 | |
KNX_DPT_FORMAT_V8 | |
KNX_DPT_FORMAT_B5N3 | bit fields to be computed by user application |
Read an usual format com object
e_KnxDeviceStatus Knx.read(byte objectIndex, <any standard C type>& returnedValue);
Description: Get the current value of a group object. This function is relevant for objects with usual format, see table below.
Parameters: "objectIndex" is the index (in the list) of the object to be read. "returnedValue" is the read com object value. "returnedValue" can be any standard C type (boolean, uchar, char, uint, int, ulong, long, float, double types).
Return: KNX_DEVICE_OK (0) when everything went well, KNX_DEVICE_NOT_IMPLEMENTED (254) in case of F32 conversion, KNX_DEVICE_ERROR (255) in case of unsupported group object format.
Examples:
1byte i; Knx.read(0,i); // read index 0 object (short object)
2unsigned int j; Knx.read(1,j); // read index 1 object (U16 format)
3int k; Knx.read(2,k); // read index 2 object (V16 format)
4unsigned long l; Knx.read(3,l); // read index 3 object (U32 format)
5long m; Knx.read(4,m); // read index 4 object (V32 format)
6float n; Knx.read(5,n); // read index 5 object (F16/F32 format)
| supported KNX DPT formats | Remark | |:---------------------------:|:----------------------------------------------------:| | KNX_DPT_FORMAT_B1 | | | KNX_DPT_FORMAT_B2 | | | KNX_DPT_FORMAT_B1U3 | bit fields to be computed by user application | | KNX_DPT_FORMAT_A8 | | | KNX_DPT_FORMAT_U8 | | | KNX_DPT_FORMAT_V8 | | | KNX_DPT_FORMAT_B5N3 | bit fields to be computed by user application | | KNX_DPT_FORMAT_U16 | | | KNX_DPT_FORMAT_V16 | | | KNX_DPT_FORMAT_F16 | | | KNX_DPT_FORMAT_U32 | | | KNX_DPT_FORMAT_V32 | | | KNX_DPT_FORMAT_F32 | **!!not yet implemented!!** |
Read ANY format com object (advised to advanced users only)
e_KnxDeviceStatus Knx.read(byte objectIndex, byte returnedValue[]);
Description: read the value of a group object. This function supports ALL the DPT formats, the returned value has a rough DPT format.
Update any usual format com object
e_KnxDeviceStatus Knx.write(byte objectIndex, <any standard C type> value);
Description: update the value of a group object. This function is relevant for objects with usual format, see table below. In case the object has COMMUNICATION and TRANSMIT flags set, then a telegram is emitted on the EIB bus, thus the new value is propagated to the other devices.
Parameters: "objectIndex" is the index (in the list) of the object to be updated. "value" is the new value. value can be any standard C type (boolean, uchar, char, uint, int, ulong, long, float, double types).
Return: KNX_DEVICE_OK (0) when everything went well, KNX_DEVICE_NOT_IMPLEMENTED (254) in case of F32 conversion, KNX_DEVICE_ERROR (255) in case of unsupported group object format.
Examples:
1byte i=100; Knx.write(0,i); // the object with index 0 gets value 100
2int j=-1000; Knx.write(1,j); // the object with index 1 gets value -1000
3float k=1234.56; Knx.write(2,k); // the object with index 3 gets value 1234.56
| supported KNX DPT formats | Remark | |:---------------------------:|:----------------------------------------------------:| | KNX_DPT_FORMAT_B1 | | | KNX_DPT_FORMAT_B2 | | | KNX_DPT_FORMAT_B1U3 | bit fields to be computed by user application | | KNX_DPT_FORMAT_A8 | | | KNX_DPT_FORMAT_U8 | | | KNX_DPT_FORMAT_V8 | | | KNX_DPT_FORMAT_B5N3 | bit fields to be computed by user application | | KNX_DPT_FORMAT_U16 | | | KNX_DPT_FORMAT_V16 | | | KNX_DPT_FORMAT_F16 | | | KNX_DPT_FORMAT_U32 | | | KNX_DPT_FORMAT_V32 | | | KNX_DPT_FORMAT_F32 | **!!not yet implemented!!** |
Update ANY format com object (advised to advanced users only)
e_KnxDeviceStatus Knx.write(byte objectIndex, byte value[]);
Description: update the value of a group object. This function supports ALL the DPT formats, but a rough DPT format value (previously computed by user application) shall be provided.
void Knx.update(byte objectIndex);
_Request the local object value to be updated via the bus_
Description: request the (local) group object value to be updated with the value from the bus. Note that this function is _asynchroneous_, the update completion is notified by the knxEvents() callback. This function is relevant only for objects with UPDATE and TRANSMIT flags set.
Parameters: "objectIndex" is the index (in the list) of the object to be updated.
Example: Knx.update(0); // request the update of the object with index 0.
Working with the device
bool isFactorySetting();
Description: Returns the current device state. Use this before asking for device parameters. If is factory setting, parameters are not yet initialized and do not contain valid values!
Example:
1if (!Konnekting.isFactorySetting()) {
2 // now you can be sure that device params contain valid values
3}
1uint8_t getUINT8Param(byte index);
2int8_t getINT8Param(byte index);
3uint16_t getUINT16Param(byte index);
4int16_t getINT16Param(byte index);
5uint32_t getUINT32Param(byte index);
6int32_t getINT32Param(byte index);
Description: Returns the parameter value which has been programmed via the KONNEKTING Suite. You have to make sure you use the method that matches the parameter type (UINT8, INT8, UNINT16, ...). Otherwise you will get an 0-value. Parameters: "index" is the ID of your parameter, as it is defined in the [.knxdevice.xml](/konnekting_xml_device_description.md).
Example:
1byte myUINT8Param = Konnekting.getUINT8Param(0);
2signed int myINT8Param = Konnekting.getINT8Param(1);
3
4int myINT16Param = Konnekting.getINT16Param(2);
5unsigned int myUINT16Param = Konnekting.getUINT16Param(3);
6
7long myINT32Param = Konnekting.getINT32Param(4);
8unsigned long myUINT32Param = Konnekting.getUINT32Param(5);
bool isReadyForApplication();
Description: Returns the current ready state of the device. You should use this to suspend sketch action (reading sensors etc.) while device is not ready for application (e.g. in programming mode, ...).
Example:
1if (Konnekting.isReadyForApplication()) {
2 // do whatever is required for your device, reading sensors, procession I/O, ...
3}
int getFreeEepromOffset();
Description: Returns an EEPROM index offset, at which it is save to read/store your device related data.
WARNING: Don't write in the area in front of this index. YOU WILL BREAK YOUR COM-OBJECTS AND DEVICE PARAMETER DATA!!!
Example:
1// writing a 4-byte value to EEPROM
2int freeEepromOffset = Konnekting.getFreeEepromOffset();
3EEPROM.write(freeEepromOffset, myData[0]);
4EEPROM.write(freeEepromOffset+1, myData[1]);
5EEPROM.write(freeEepromOffset+2, myData[2]);
6EEPROM.write(freeEepromOffset+3, myData[3]);