Ankündigung

Einklappen
Keine Ankündigung bisher.

ARDUINO am KNX

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Zitat von sx3 Beitrag anzeigen
    Do you still think it would work with Arduino->KNX?
    The connection between your arduino and your third-party-device is totally independant from the arduino<->knx connection.

    You are free to adapt the arduino uart that is used to communicate with your third-party device as needed. Keep in mind, that you use two independant uarts.. one for knx with BCU and and for your third-party device which uses different logic levels.

    Kommentar


      I understand.
      But I was thinking weither the schematic that was posted earlier, would apply as a galvanic separation between the Arduino <-> KNX aswell.
      Because that schematic lookes like it inverts the signals. I don't know if that would make in difference, because I'm not that good at electronic.
      But given that I have earlier connected a Pro Mini to the KNX without optocouplers, probably using none-inverted signal I thought that schematic won't work as galvanic separation between the MEGA and the KNX.

      Because I will power the MEGA from external power supply, I would want to galvanic separate both the KNX and the third party device from the Arduino external power supply.
      Ofcourse I will use separate HW serial/UART, hence using the MEGA.
      Zuletzt geändert von sx3; 07.09.2016, 19:47.

      Kommentar


        The best way to have a galvanic separation between bcu and arduino: Use ADUM1201 chip (http://www.analog.com/media/en/techn...M1200_1201.pdf). Works like a charm.

        Kommentar


          alright, no need of resistors or something like using optocouplers?, just connect Tx to encode and Rx to decode and, VCC+GND on each side and look happy I guess?

          Kommentar


            Exactly. That's it. Very easy, very reliable. The only downside: adum1201 is "very tiny". So take your time when soldering the SO8 package. For experimenting on breadboard: Check out ebay. There are SO8 adapter PCBs available.

            Kommentar


              Perfect, I ordered the parts needed, just sit down and wait now.

              Kommentar


                Ich krame das hier mal wieder aus.

                Ich habe, vielleicht auch eine alte Library, aber das Problem dass ich GA_STRING nicht mehr verwenden kann.
                Also habe ich um das zu debuggen auf GA_INTEGER geschaut (das funktioniert) und mir das angesehen.

                Irgendwie verstehe ich aber nicht warum das eine funktioniert und das andere nicht. Hat jemand einen Plan ?

                Code:
                        String address = "5/5/5";
                        Serial.println (String(address).substring(0,String(address).indexOf('/')).toInt(),DEC);
                        Serial.println (String(address).substring(String(address).indexOf('/')+1,String(address).lastIndexOf('/')).toInt(),DEC);
                        Serial.println (String(address).substring(String(address).lastIndexOf('/')+1,String(address).length()).toInt(),DEC);
                
                [B]###FUNKTIONIERT NICHT###[/B]
                        knx.groupWrite2ByteFloat(GA_INTEGER(String(address).substring(0,String(address).indexOf('/')).toInt(),
                                                            String(address).substring(String(address).indexOf('/')+1,String(address).lastIndexOf('/')).toInt(),
                                                            String(address).substring(String(address).lastIndexOf('/')+1,String(address).length()).toInt()),
                                                            22.22);
                        Serial.println("Send !");
                        delay(100);
                
                [B]###FUNKTIONIERT NICHT###[/B]
                        String five = "5";
                        knx.groupWrite2ByteFloat(GA_INTEGER(five.toInt(),
                                                            five.toInt(),
                                                            five.toInt()),
                                                            22.22);
                       Serial.println("Send !");
                       delay(100);
                
                [B]###FUNKTIONIERT ###[/B]
                       knx.groupWrite2ByteFloat(GA_INTEGER(5,
                                                           5,
                                                           5),
                                                           22.22);
                       Serial.println("Send !");
                       delay(100);
                Der Fehler muss irgendwo bei den Macros in der KnxTpUart.cpp liegen, denn ich komme bei den nicht funktionierenden Aufrufen nicht bis KnxTpUart::groupWrite2ByteFloat.
                Beim letzten Aufruf wird mir aber die Debug-Ausgabe in KnxTpUart::groupWrite2ByteFloat angezeigt.


                Ich steige nicht auf Konnekting um weil ich noch Hardware hier liegen habe, aber vielleicht kann jemand helfen ?
                Wie bekomme ich GA_STRING wieder ans laufen ?

                Code:
                #define GA_ARRAY(area, line, member) {((area << 3) | line), member}
                #define GA_INTEGER(area, line, member) (byte*)(const byte[2]){(area << 3) | line, member}
                #define GA_STRING(address) (byte*)(const byte[2]){((String(address).substring(0, String(address).indexOf('/')).toInt()) << 3) | String(address).substring(String(address).indexOf('/')+1, String(address).lastIndexOf('/')).toInt(), String(address).substring(String(address).lastIndexOf('/')+1,String(address).length()).toInt()}
                Grüße
                Umgezogen? Ja! ... Fertig? Nein!
                Baustelle 2.0 !

                Kommentar


                  Solange du nen progbutton an deine HW bekommst kannst du umsteigen. Auf die ProgLed kannst du ggf. verzichten.

                  Das Macro stammt glaub ich von mir?!

                  Vllt. hilft ein casten nach int?

                  Kommentar


                    Also eigentlich sollte toInt() das ganze ja erledigen. Ein zusätzliches int() hat auch nix gebracht.

                    Ich verstehe das auch nicht. Es ist auf jeden Fall int was da rauskommt ... ich kann die 5+5+5 zu 15 im Code addieren.


                    Ich will mich jetzt nicht noch extra in Konnekting einarbeiten müssen. Das frisst mir jetzt zu viele Ressourcen, zumal der restliche Code zu 90% fertig ist - echt ärgerlich, ich verstehe das wirklich nicht. Prog-Button/LED hat meine Hardware ja.
                    Umgezogen? Ja! ... Fertig? Nein!
                    Baustelle 2.0 !

                    Kommentar


                      Ist denn wirklich niemand mehr mit GA_STRING unterwegs ?
                      Oder hat jemand einen funktionierenden Sketch samt Library ?
                      Umgezogen? Ja! ... Fertig? Nein!
                      Baustelle 2.0 !

                      Kommentar


                        Hallo zusammen,

                        ich möchte alle Telegramme die aufm BUS rumlaufen im RAW Format in der Seriellenkonsole anzeigen.
                        Wie kann ich das am besten bewerkstelligen?
                        (ich möchte so eine Art BUS-Monitor haben)

                        Kommentar


                          Hallo JuMi2006,

                          getestet mit Arduino IDE 1.0.5-r2. Library und Testsketch ist die erste überarbeite Version, dies ist aber nicht die in GitHub von tuxedo hinterlegte Version. Wünsche dir viel Erfolg, vielleicht hilft dir das ja!

                          Code:
                          #include <KnxTpUart.h>
                          
                          KnxTpUart knx(&Serial1, PA_STRING("15.15.20"));
                          
                          void setup() {
                            Serial.begin(9600);
                            Serial.println("TP-UART Test");
                          
                            Serial1.begin(19200);
                            UCSR1C = UCSR1C | B00100000;
                          
                            Serial.print("UCSR1A: ");
                            Serial.println(UCSR1A, BIN);
                          
                            Serial.print("UCSR1B: ");
                            Serial.println(UCSR1B, BIN);
                          
                            Serial.print("UCSR1C: ");
                            Serial.println(UCSR1C, BIN);
                          
                            knx.uartReset();
                          }
                          
                          
                          void loop() {
                            knx.groupWrite2ByteFloat(GA_STRING("5/5/5"), 22.22);
                          //  knx.groupWrite2ByteFloat(GA_INTEGER(5,5,5), 22.22);
                            Serial.println("Send !");
                            delay(1000);
                          }
                          
                          void serialEvent1() {
                            KnxTpUartSerialEventType eType = knx.serialEvent();
                            if (eType == KNX_TELEGRAM) {
                              Serial.println("Event KNX_TELEGRAM");
                            }
                          }
                          KnxTpUart.h

                          Code:
                          #ifndef KnxTpUart_h
                          #define KnxTpUart_h
                          
                          #include "HardwareSerial.h"
                          #include "Arduino.h"
                          
                          #include "KnxTelegram.h"
                          
                          // Services from TPUART
                          #define TPUART_RESET_INDICATION_BYTE B11
                          
                          // Services to TPUART
                          #define TPUART_DATA_START_CONTINUE B10000000
                          #define TPUART_DATA_END B01000000
                          
                          // Debugging
                          // uncomment the following line to enable debugging
                          //#define TPUART_DEBUG true
                          #define TPUART_DEBUG_PORT Serial
                          
                          #define TPUART_SERIAL_CLASS Stream
                          
                          // Delay in ms between sending of packets to the bus
                          // set to 0 if you keep care of that by yourself
                          #define SERIAL_WRITE_DELAY_MS 0
                          
                          // Timeout for reading a byte from TPUART
                          #define SERIAL_READ_TIMEOUT_MS 10
                          
                          // Maximum number of group addresses that can be listened on
                          #define MAX_LISTEN_GROUP_ADDRESSES 48
                          
                          // Macros for converting PA and GA to 2-byte
                          #define PA_INTEGER(area, line, member) (byte[]){(area << 4) | line, member}
                          #define PA_STRING(address) (byte[]){(String(address).substring(0, String(address).indexOf('.')).toInt() << 4) | String(address).substring(String(address).indexOf('.')+1, String(address).lastIndexOf('.')).toInt(), String(address).substring(String(address).lastIndexOf('.')+1,String(address).length()).toInt()}
                          
                          #define GA_ARRAY(area, line, member) {((area << 3) | line), member}
                          #define GA_INTEGER(area, line, member) (byte[]){(area << 3) | line, member}
                          #define GA_STRING(address) (byte[]){(String(address).substring(0, String(address).indexOf('/')).toInt() << 3) | String(address).substring(String(address).indexOf('/')+1, String(address).lastIndexOf('/')).toInt(), String(address).substring(String(address).lastIndexOf('/')+1,String(address).length()).toInt()}
                          
                          
                          enum KnxTpUartSerialEventType {
                              TPUART_RESET_INDICATION,
                              KNX_TELEGRAM,
                              IRRELEVANT_KNX_TELEGRAM,
                              UNKNOWN
                          };
                          
                          class KnxTpUart {
                          public:
                              KnxTpUart(TPUART_SERIAL_CLASS*, byte*);
                              void uartReset();
                              void uartStateRequest();
                              KnxTpUartSerialEventType serialEvent();
                              KnxTelegram* getReceivedTelegram();
                          
                              void setIndividualAddress(byte*);
                          
                              void sendAck();
                              void sendNotAddressed();
                          
                              bool groupWriteBool(byte* groupAddress, bool);
                              bool groupWrite2ByteFloat(byte* groupAddress, float);
                              bool groupWrite1ByteInt(byte* groupAddress, int);
                              bool groupWrite2ByteInt(byte* groupAddress, int);
                              bool groupWrite4ByteFloat(byte* groupAddress, float);
                              bool groupWrite14ByteText(byte* groupAddress, String);
                          
                              bool groupAnswerBool(byte* groupAddress, bool);
                              bool groupAnswer2ByteFloat(byte* groupAddress, float);
                              bool groupAnswer1ByteInt(byte* groupAddress, int);
                              bool groupAnswer2ByteInt(byte* groupAddress, int);
                              bool groupAnswer4ByteFloat(byte* groupAddress, float);
                              bool groupAnswer14ByteText(byte* groupAddress, String);
                          
                              bool groupWriteTime(byte* groupAddress, int, int, int, int);
                          
                              void addListenGroupAddress(byte* groupAddress);
                              bool isListeningToGroupAddress(byte* groupAddress);
                          
                              bool individualAnswerAddress();
                              bool individualAnswerMaskVersion(int, int, int);
                              bool individualAnswerAuth(int, int, int, int, int);
                          
                              bool sendPropertyResponse(byte* /*address (PA of origin)*/, int /*object*/, int /*propertyid*/, int /*start*/, int /*size of data*/, byte* /*data array*/);
                          
                              void setListenToBroadcasts(bool);
                          
                              void groupBytesToInt(byte*, int*);
                          
                          
                          private:
                              Stream* _serialport;
                              KnxTelegram* _tg;       // for normal communication
                              KnxTelegram* _tg_ptp;   // for PTP sequence confirmation
                              byte _individualAddress[2];
                              byte _listen_group_addresses[MAX_LISTEN_GROUP_ADDRESSES][2];
                              byte _listen_group_address_count;
                              bool _listen_to_broadcasts;
                          
                              bool isKNXControlByte(int);
                              void checkErrors();
                              void printByte(int);
                              bool readKNXTelegram();
                              void createKNXMessageFrame(int, KnxCommandType, byte* targetGroupAddress, int);
                              void createKNXMessageFrameIndividual(int, KnxCommandType, byte* targetIndividualAddress, int);
                              bool sendMessage();
                              bool sendNCDPosConfirm(int, byte* targetIndividualAddress);
                              int serialRead();
                          
                          };
                          #endif
                          KnxTpUart.cpp

                          Code:
                          #include "KnxTpUart.h"
                          
                          KnxTpUart::KnxTpUart(TPUART_SERIAL_CLASS* sport, byte address[2]) {
                              _serialport = sport;
                          
                              _individualAddress[0] = address[0];
                              _individualAddress[1] = address[1];
                          
                              _listen_group_address_count = 0;
                              _tg = new KnxTelegram();
                              _tg_ptp = new KnxTelegram();
                              _listen_to_broadcasts = false;
                          }
                          
                          void KnxTpUart::setListenToBroadcasts(bool listen) {
                              _listen_to_broadcasts = listen;
                          }
                          
                          void KnxTpUart::uartReset() {
                              byte sendByte = 0x01;
                              _serialport->write(sendByte);
                          }
                          
                          void KnxTpUart::uartStateRequest() {
                              byte sendByte = 0x02;
                              _serialport->write(sendByte);
                          }
                          
                          void KnxTpUart::setIndividualAddress(byte address[2]) {
                              _individualAddress[0] = address[0];
                              _individualAddress[1] = address[1];
                          }
                          
                          KnxTpUartSerialEventType KnxTpUart::serialEvent() {
                              while (_serialport->available() > 0) {
                                  checkErrors();
                          
                                  int incomingByte = _serialport->peek();
                                  printByte(incomingByte);
                          
                                  if (isKNXControlByte(incomingByte)) {
                                      bool interested = readKNXTelegram();
                                      if (interested) {
                          #if defined(TPUART_DEBUG)
                                          TPUART_DEBUG_PORT.println("Event KNX_TELEGRAM");
                          #endif
                                          return KNX_TELEGRAM;
                                      } else {
                          #if defined(TPUART_DEBUG)
                                          TPUART_DEBUG_PORT.println("Event IRRELEVANT_KNX_TELEGRAM");
                          #endif
                                          return IRRELEVANT_KNX_TELEGRAM;
                                      }
                                  } else if (incomingByte == TPUART_RESET_INDICATION_BYTE) {
                                      serialRead();
                          #if defined(TPUART_DEBUG)
                                      TPUART_DEBUG_PORT.println("Event TPUART_RESET_INDICATION");
                          #endif
                                      return TPUART_RESET_INDICATION;
                                  } else {
                                      serialRead();
                          #if defined(TPUART_DEBUG)
                                      TPUART_DEBUG_PORT.println("Event UNKNOWN");
                          #endif
                                      return UNKNOWN;
                                  }
                              }
                          #if defined(TPUART_DEBUG)
                              TPUART_DEBUG_PORT.println("Event UNKNOWN");
                          #endif
                              return UNKNOWN;
                          }
                          
                          
                          bool KnxTpUart::isKNXControlByte(int b) {
                              return ( (b | B00101100) == B10111100 ); // Ignore repeat flag and priority flag
                          }
                          
                          void KnxTpUart::checkErrors() {
                          #if defined(TPUART_DEBUG)
                          #if defined(_SAM3XA_)  // For DUE
                              if (USART1->US_CSR & US_CSR_OVRE) {
                                  TPUART_DEBUG_PORT.println("Overrun");
                              }
                          
                              if (USART1->US_CSR & US_CSR_FRAME) {
                                  TPUART_DEBUG_PORT.println("Frame Error");
                              }
                          
                              if (USART1->US_CSR & US_CSR_PARE) {
                                  TPUART_DEBUG_PORT.println("Parity Error");
                              }
                          #elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) // for UNO
                              if (UCSR0A & B00010000) {
                                  TPUART_DEBUG_PORT.println("Frame Error");
                              }
                          
                              if (UCSR0A & B00000100) {
                                  TPUART_DEBUG_PORT.println("Parity Error");
                              }
                          #else
                              if (UCSR1A & B00010000) {
                                  TPUART_DEBUG_PORT.println("Frame Error");
                              }
                          
                              if (UCSR1A & B00000100) {
                                  TPUART_DEBUG_PORT.println("Parity Error");
                              }
                          #endif
                          #endif
                          }
                          
                          void KnxTpUart::printByte(int incomingByte) {
                          #if defined(TPUART_DEBUG)
                              TPUART_DEBUG_PORT.print("Incoming Byte: ");
                              TPUART_DEBUG_PORT.print(incomingByte, DEC);
                              TPUART_DEBUG_PORT.print(" - ");
                              TPUART_DEBUG_PORT.print(incomingByte, HEX);
                              TPUART_DEBUG_PORT.print(" - ");
                              TPUART_DEBUG_PORT.print(incomingByte, BIN);
                              TPUART_DEBUG_PORT.println();
                          #endif
                          }
                          
                          bool KnxTpUart::readKNXTelegram() {
                              // Receive header
                              for (int i = 0; i < 6; i++) {
                                  _tg->setBufferByte(i, serialRead());
                              }
                          
                          #if defined(TPUART_DEBUG)
                              TPUART_DEBUG_PORT.print("Payload Length: ");
                              TPUART_DEBUG_PORT.println(_tg->getPayloadLength());
                          #endif
                              int bufpos = 6;
                              for (int i = 0; i < _tg->getPayloadLength(); i++) {
                                  _tg->setBufferByte(bufpos, serialRead());
                                  bufpos++;
                              }
                          
                              // Checksum
                              _tg->setBufferByte(bufpos, serialRead());
                          
                          #if defined(TPUART_DEBUG)
                              // Print the received telegram
                              _tg->print(&TPUART_DEBUG_PORT);
                          #endif
                          
                              // get targetaddress if telegram
                              byte target[2];
                              _tg->getTarget(target);
                          
                              // Verify if we are interested in this message:
                              // GroupAddress
                              bool interestedGA = _tg->isTargetGroup() && isListeningToGroupAddress(target);
                          
                              // Physical address
                              bool interestedPA = ((!_tg->isTargetGroup()) && target[0] == _individualAddress[0] && target[1] == _individualAddress[1]);
                          
                              // Broadcast (Programming Mode)
                              bool interestedBC = (_listen_to_broadcasts && _tg->isBroadcast());
                          
                              TPUART_DEBUG_PORT.print("Interested GA: ");
                              TPUART_DEBUG_PORT.println(interestedGA);
                              TPUART_DEBUG_PORT.print("Interested PA: ");
                              TPUART_DEBUG_PORT.println(interestedPA);
                              TPUART_DEBUG_PORT.print("Interested BC: ");
                              TPUART_DEBUG_PORT.println(interestedBC);
                          
                              TPUART_DEBUG_PORT.print("target: [0]=");
                              TPUART_DEBUG_PORT.print(target[0]);
                              TPUART_DEBUG_PORT.print(" [1]=");
                              TPUART_DEBUG_PORT.print(target[1]);
                              TPUART_DEBUG_PORT.println();
                          
                              bool interested = interestedGA || interestedPA ||interestedBC;
                          
                              if (interested) {
                                  sendAck();
                              } else {
                                  sendNotAddressed();
                              }
                          
                              if (_tg->getCommunicationType() == KNX_COMM_UCD) {
                          #if defined(TPUART_DEBUG)
                                TPUART_DEBUG_PORT.println("UCD Telegram received");
                          #endif
                              } else if (_tg->getCommunicationType() == KNX_COMM_NCD) {
                          #if defined(TPUART_DEBUG)
                                  TPUART_DEBUG_PORT.print("NCD Telegram ");
                                  TPUART_DEBUG_PORT.print(_tg->getSequenceNumber());
                                  TPUART_DEBUG_PORT.println(" received");
                          #endif
                                  if (interested) {
                                      sendNCDPosConfirm(_tg->getSequenceNumber(), PA_INTEGER(_tg->getSourceArea(), _tg->getSourceLine(), _tg->getSourceMember()));
                                  }
                              }
                          
                              // Returns if we are interested in this diagram
                              return interested;
                          }
                          
                          KnxTelegram* KnxTpUart::getReceivedTelegram() {
                              return _tg;
                          }
                          
                          bool KnxTpUart::groupWriteBool(byte groupAddress[2], bool value) {
                              int valueAsInt = 0;
                              if (value) {
                                  valueAsInt = B00000001;
                              }
                          
                              createKNXMessageFrame(2, KNX_COMMAND_WRITE, groupAddress, valueAsInt);
                              return sendMessage();
                          }
                          
                          bool KnxTpUart::groupWrite2ByteFloat(byte groupAddress[2], float value) {
                              createKNXMessageFrame(2, KNX_COMMAND_WRITE, groupAddress, 0);
                              _tg->set2ByteFloatValue(value);
                              _tg->createChecksum();
                              return sendMessage();
                          }
                          
                          bool KnxTpUart::groupWrite2ByteInt(byte groupAddress[2], int value) {
                              createKNXMessageFrame(2, KNX_COMMAND_WRITE, groupAddress, 0);
                              _tg->set2ByteFloatValue(value);
                              _tg->createChecksum();
                              return sendMessage();
                          }
                          
                          bool KnxTpUart::groupWrite1ByteInt(byte groupAddress[2], int value) {
                              createKNXMessageFrame(2, KNX_COMMAND_WRITE, groupAddress, 0);
                              _tg->set1ByteIntValue(value);
                              _tg->createChecksum();
                              return sendMessage();
                          }
                          
                          bool KnxTpUart::groupWrite4ByteFloat(byte groupAddress[2], float value) {
                              createKNXMessageFrame(2, KNX_COMMAND_WRITE, groupAddress, 0);
                              _tg->set4ByteFloatValue(value);
                              _tg->createChecksum();
                              return sendMessage();
                          }
                          
                          bool KnxTpUart::groupWrite14ByteText(byte groupAddress[2], String value) {
                              createKNXMessageFrame(2, KNX_COMMAND_WRITE, groupAddress, 0);
                              _tg->set14ByteValue(value);
                              _tg->createChecksum();
                              return sendMessage();
                          }
                          
                          bool KnxTpUart::groupAnswerBool(byte groupAddress[2], bool value) {
                              int valueAsInt = 0;
                              if (value) {
                                  valueAsInt = B00000001;
                              }
                          
                              createKNXMessageFrame(2, KNX_COMMAND_ANSWER, groupAddress, valueAsInt);
                              return sendMessage();
                          }
                          
                          bool KnxTpUart::groupAnswer1ByteInt(byte groupAddress[2], int value) {
                              createKNXMessageFrame(2, KNX_COMMAND_ANSWER, groupAddress, 0);
                              _tg->set1ByteIntValue(value);
                              _tg->createChecksum();
                              return sendMessage();
                          }
                          
                          bool KnxTpUart::groupAnswer2ByteFloat(byte groupAddress[2], float value) {
                              createKNXMessageFrame(2, KNX_COMMAND_ANSWER, groupAddress, 0);
                              _tg->set2ByteFloatValue(value);
                              _tg->createChecksum();
                              return sendMessage();
                          }
                          
                          bool KnxTpUart::groupAnswer2ByteInt(byte groupAddress[2], int value) {
                              createKNXMessageFrame(2, KNX_COMMAND_ANSWER, groupAddress, 0);
                              _tg->set2ByteFloatValue(value);
                              _tg->createChecksum();
                              return sendMessage();
                          }
                          
                          bool KnxTpUart::groupAnswer4ByteFloat(byte groupAddress[2], float value) {
                              createKNXMessageFrame(2, KNX_COMMAND_ANSWER, groupAddress, 0);
                              _tg->set4ByteFloatValue(value);
                              _tg->createChecksum();
                              return sendMessage();
                          }
                          
                          bool KnxTpUart::groupAnswer14ByteText(byte groupAddress[2], String value) {
                              createKNXMessageFrame(2, KNX_COMMAND_ANSWER, groupAddress, 0);
                              _tg->set14ByteValue(value);
                              _tg->createChecksum();
                              return sendMessage();
                          }
                          
                          bool KnxTpUart::groupWriteTime(byte groupAddress[2], int day, int hours, int minutes, int seconds) {
                              createKNXMessageFrame(2, KNX_COMMAND_WRITE, groupAddress, 0);
                              _tg->setKNXTime(day, hours, minutes, seconds);
                              _tg->createChecksum();
                              return sendMessage();
                          }
                          
                          bool KnxTpUart::individualAnswerAddress() {
                              createKNXMessageFrame(2, KNX_COMMAND_INDIVIDUAL_ADDR_RESPONSE, PA_INTEGER(0,0,0), 0);
                              _tg->createChecksum();
                              return sendMessage();  
                          }
                          
                          bool KnxTpUart::individualAnswerMaskVersion(int area, int line, int member) {
                              createKNXMessageFrameIndividual(4, KNX_COMMAND_MASK_VERSION_RESPONSE, PA_INTEGER(area, line, member), 0);
                              _tg->setCommunicationType(KNX_COMM_NDP);
                              _tg->setBufferByte(8, 0x07); // Mask version part 1 for BIM M 112
                              _tg->setBufferByte(9, 0x01); // Mask version part 2 for BIM M 112
                              _tg->createChecksum();
                              return sendMessage();
                          }
                          
                          bool KnxTpUart::individualAnswerAuth(int accessLevel, int sequenceNo, int area, int line, int member) {
                              createKNXMessageFrameIndividual(3, KNX_COMMAND_ESCAPE, PA_INTEGER(area, line, member), KNX_EXT_COMMAND_AUTH_RESPONSE);
                              _tg->setCommunicationType(KNX_COMM_NDP);
                              _tg->setSequenceNumber(sequenceNo);
                              _tg->setBufferByte(8, accessLevel);
                              _tg->createChecksum();
                              return sendMessage();
                          }
                          
                          void KnxTpUart::createKNXMessageFrame(int payloadlength, KnxCommandType command, byte groupAddress[2], int firstDataByte) {
                              _tg->clear();
                              _tg->setSourceAddress(_individualAddress);
                              _tg->setTargetGroupAddress(groupAddress);
                              _tg->setFirstDataByte(firstDataByte);
                              _tg->setCommand(command);
                              _tg->setPayloadLength(payloadlength);
                              _tg->createChecksum();
                          }
                          
                          void KnxTpUart::createKNXMessageFrameIndividual(int payloadlength, KnxCommandType command, byte targetIndividualAddress[2], int firstDataByte) {
                              _tg->clear();
                              _tg->setSourceAddress(_individualAddress);
                              _tg->setTargetIndividualAddress(targetIndividualAddress);
                              _tg->setFirstDataByte(firstDataByte);
                              _tg->setCommand(command);
                              _tg->setPayloadLength(payloadlength);
                              _tg->createChecksum();
                          }
                          
                          bool KnxTpUart::sendNCDPosConfirm(int sequenceNo, byte targetIndividualAddress[2]) {
                              _tg_ptp->clear();
                              _tg_ptp->setSourceAddress(_individualAddress);
                              _tg_ptp->setTargetIndividualAddress(targetIndividualAddress);
                              _tg_ptp->setSequenceNumber(sequenceNo);
                              _tg_ptp->setCommunicationType(KNX_COMM_NCD);
                              _tg_ptp->setControlData(KNX_CONTROLDATA_POS_CONFIRM);
                              _tg_ptp->setPayloadLength(1);
                              _tg_ptp->createChecksum();
                          
                          
                              int messageSize = _tg_ptp->getTotalLength();
                          
                              uint8_t sendbuf[2];
                              for (int i = 0; i < messageSize; i++) {
                                  if (i == (messageSize - 1)) {
                                      sendbuf[0] = TPUART_DATA_END;
                                  } else {
                                      sendbuf[0] = TPUART_DATA_START_CONTINUE;
                                  }
                          
                                  sendbuf[0] |= i;
                                  sendbuf[1] = _tg_ptp->getBufferByte(i);
                          
                                  _serialport->write(sendbuf, 2);
                              }
                          
                          
                              int confirmation;
                              while(true) {
                                  confirmation = serialRead();
                                  if (confirmation == B10001011) {
                                      return true; // Sent successfully
                                  } else if (confirmation == B00001011) {
                                      return false;
                                  } else if (confirmation == -1) {
                                      // Read timeout
                                      return false;
                                  }
                              }
                          
                              return false;
                          }
                          
                          bool KnxTpUart::sendMessage() {
                              int messageSize = _tg->getTotalLength();
                          
                              uint8_t sendbuf[2];
                              for (int i = 0; i < messageSize; i++) {
                                  if (i == (messageSize - 1)) {
                                      sendbuf[0] = TPUART_DATA_END;
                                  } else {
                                      sendbuf[0] = TPUART_DATA_START_CONTINUE;
                                  }
                          
                                  sendbuf[0] |= i;
                                  sendbuf[1] = _tg->getBufferByte(i);
                          
                                  _serialport->write(sendbuf, 2);
                              }
                          
                          
                              int confirmation;
                              while(true) {
                                  confirmation = serialRead();
                                  if (confirmation == B10001011) {
                                      delay (SERIAL_WRITE_DELAY_MS);
                                      return true; // Sent successfully
                                  } else if (confirmation == B00001011) {
                                      delay (SERIAL_WRITE_DELAY_MS);
                                      return false;
                                  } else if (confirmation == -1) {
                                      // Read timeout
                                      delay (SERIAL_WRITE_DELAY_MS);
                                      return false;
                                  }
                              }
                          
                              return false;
                          }
                          
                          void KnxTpUart::sendAck() {
                              TPUART_DEBUG_PORT.print("Send ACK");
                              byte sendByte = B00010001;
                              _serialport->write(sendByte);
                              delay(SERIAL_WRITE_DELAY_MS);
                          }
                          
                          void KnxTpUart::sendNotAddressed() {
                              byte sendByte = B00010000;
                              _serialport->write(sendByte);
                              delay(SERIAL_WRITE_DELAY_MS);
                          }
                          
                          int KnxTpUart::serialRead() {
                              unsigned long startTime = millis();
                          #if defined(TPUART_DEBUG)
                              TPUART_DEBUG_PORT.print("Available: ");
                              TPUART_DEBUG_PORT.println(_serialport->available());
                          #endif
                          
                              while (! (_serialport->available() > 0)) {
                                  if (abs(millis() - startTime) > SERIAL_READ_TIMEOUT_MS) {
                                      // Timeout
                          #if defined(TPUART_DEBUG)
                                      TPUART_DEBUG_PORT.println("Timeout while receiving message");
                          #endif
                                      return -1;
                                  }
                                  delay(1);
                              }
                          
                              int inByte = _serialport->read();
                              checkErrors();
                              printByte(inByte);
                          
                              return inByte;
                          }
                          
                          void KnxTpUart::addListenGroupAddress(byte address[]) {
                              if (_listen_group_address_count >= MAX_LISTEN_GROUP_ADDRESSES) {
                          #if defined(TPUART_DEBUG)
                                  TPUART_DEBUG_PORT.println("Already listening to MAX_LISTEN_GROUP_ADDRESSES, cannot listen to another");
                          #endif
                                  return;
                              }
                          
                              _listen_group_addresses[_listen_group_address_count][0]=address[0];
                              _listen_group_addresses[_listen_group_address_count][1]=address[1];
                              _listen_group_address_count++;
                          
                          /*
                          #if defined(TPUART_DEBUG)
                          
                              for (int i = 0; i < _listen_group_address_count; i++) {
                          
                                  TPUART_DEBUG_PORT.print("Listen for: [");
                                  TPUART_DEBUG_PORT.print(i);
                                  TPUART_DEBUG_PORT.print("] -> ");
                                  TPUART_DEBUG_PORT.print(_listen_group_addresses[i][0]);
                                  TPUART_DEBUG_PORT.print("/");
                                  TPUART_DEBUG_PORT.print(_listen_group_addresses[i][1]);
                                  TPUART_DEBUG_PORT.print("/");
                                  TPUART_DEBUG_PORT.print(_listen_group_addresses[i][2]);
                                  TPUART_DEBUG_PORT.println("");
                              }
                          
                          #endif
                          */
                          
                          }
                          
                          bool KnxTpUart::isListeningToGroupAddress(byte address[2]) {
                          
                          
                              for (int i = 0; i < _listen_group_address_count; i++) {
                          
                                  if ( (_listen_group_addresses[i][0] == address[0])
                                          && (_listen_group_addresses[i][1] == address[1])) {
                                      return true;
                                  }
                              }
                          
                              return false;
                          }
                          KnxTelegram.h

                          Code:
                          #ifndef KnxTelegram_h
                          #define KnxTelegram_h
                          
                          #include "Arduino.h"
                          
                          #define MAX_KNX_TELEGRAM_SIZE 23
                          #define KNX_TELEGRAM_HEADER_SIZE 6
                          
                          #define TPUART_SERIAL_CLASS Stream
                          
                          // KNX priorities
                          enum KnxPriorityType {
                              KNX_PRIORITY_SYSTEM = B00,
                              KNX_PRIORITY_ALARM = B10,
                              KNX_PRIORITY_HIGH = B01,
                              KNX_PRIORITY_NORMAL = B11
                          };
                          
                          // KNX commands / APCI Coding
                          // see: http://www.mikrocontroller.net/attachment/151008/KNX_Twisted_Pair_Protokollbeschreibung.pdf
                          enum KnxCommandType {
                              KNX_COMMAND_READ                     = B0000,
                              KNX_COMMAND_ANSWER                   = B0001,
                              KNX_COMMAND_WRITE                    = B0010,
                              KNX_COMMAND_INDIVIDUAL_ADDR_WRITE    = B0011,
                              KNX_COMMAND_INDIVIDUAL_ADDR_REQUEST  = B0100,
                              KNX_COMMAND_INDIVIDUAL_ADDR_RESPONSE = B0101,
                              KNX_COMMAND_MASK_VERSION_READ        = B1100,
                              KNX_COMMAND_MASK_VERSION_RESPONSE    = B1101,
                              KNX_COMMAND_RESTART                  = B1110,
                              KNX_COMMAND_ESCAPE                   = B1111
                          };
                          
                          // Extended (escaped) KNX commands
                          // see: http://www.mikrocontroller.net/attachment/151008/KNX_Twisted_Pair_Protokollbeschreibung.pdf
                          enum KnxExtendedCommandType {
                              KNX_EXT_COMMAND_PROP_READ        = B010101, // requires KNX_COMMAND_ESCAPE
                              KNX_EXT_COMMAND_PROP_ANSWER      = B010110, // requires KNX_COMMAND_ESCAPE
                              KNX_EXT_COMMAND_PROP_WRITE       = B010111, // requires KNX_COMMAND_ESCAPE
                              KNX_EXT_COMMAND_PROP_DESC_READ   = B011000, // requires KNX_COMMAND_ESCAPE
                              KNX_EXT_COMMAND_PROP_DESC_ANSWER = B011001, // requires KNX_COMMAND_ESCAPE
                              KNX_EXT_COMMAND_AUTH_REQUEST     = B010001, // requires KNX_COMMAND_ESCAPE
                              KNX_EXT_COMMAND_AUTH_RESPONSE    = B010010  // requires KNX_COMMAND_ESCAPE
                          };
                          
                          // KNX Transport Layer Communication Type
                          enum KnxCommunicationType {
                              KNX_COMM_UDP = B00, // Unnumbered Data Packet
                              KNX_COMM_NDP = B01, // Numbered Data Packet
                              KNX_COMM_UCD = B10, // Unnumbered Control Data
                              KNX_COMM_NCD = B11  // Numbered Control Data
                          };
                          
                          // KNX Control Data (for UCD / NCD packets)
                          enum KnxControlDataType {
                              KNX_CONTROLDATA_CONNECT = B00,      // UCD
                              KNX_CONTROLDATA_DISCONNECT = B01,   // UCD
                              KNX_CONTROLDATA_POS_CONFIRM = B10,  // NCD
                              KNX_CONTROLDATA_NEG_CONFIRM = B11   // NCD
                          };
                          
                          class KnxTelegram {
                              public:
                                  KnxTelegram();
                          
                                  void clear();
                                  void setBufferByte(int index, int content);
                                  int getBufferByte(int index);
                                  void setPayloadLength(int size);
                                  int getPayloadLength();
                                  void setRepeated(bool repeat);
                                  bool isRepeated();
                                  void setPriority(KnxPriorityType prio);
                                  KnxPriorityType getPriority();
                          
                                  void setSourceAddress(byte* sourceAddress);
                                  int getSourceArea();
                                  int getSourceLine();
                                  int getSourceMember();
                          
                                  void setTargetGroupAddress(byte* targetGroupAddress);
                                  int getTargetMainGroup();
                                  int getTargetMiddleGroup();
                                  int getTargetSubGroup();
                          
                                  void setTargetIndividualAddress(byte* targetIndividualAddress);
                                  int getTargetArea();
                                  int getTargetLine();
                                  int getTargetMember();
                          
                                  void getTarget(byte* target); // returns individualaddress target style
                                  void getTargetGroup(byte* target); // returns groupaddress target style
                          
                                  bool isTargetGroup();
                                  bool isBroadcast();
                          
                                  void setRoutingCounter(int counter);
                                  int getRoutingCounter();
                          
                                  void setCommand(KnxCommandType command);
                                  KnxCommandType getCommand();
                          
                                  void setExtendedCommand(KnxExtendedCommandType command);
                                  KnxExtendedCommandType getExtendedCommand();
                          
                                  void createChecksum();
                                  bool verifyChecksum();
                                  int getChecksum();
                                  void print(TPUART_SERIAL_CLASS*);
                                  int getTotalLength();
                                  KnxCommunicationType getCommunicationType();
                                  void setCommunicationType(KnxCommunicationType);
                          
                                  int getSequenceNumber();
                                  void setSequenceNumber(int);
                          
                                  void setControlData(KnxControlDataType);
                                  KnxControlDataType getControlData();
                          
                          
                                  // Getter+Setter for DPTs
                                  void setFirstDataByte(int data);
                                  int getFirstDataByte();
                                  bool getBool();
                          
                                  void set2ByteFloatValue(float value);
                                  float get2ByteFloatValue();
                          
                                  void set2ByteIntValue(float value);
                                  int get1ByteIntValue();
                          
                                  void set1ByteIntValue(int value);
                                  float get2ByteIntValue();
                          
                                  void set4ByteFloatValue(float value);
                                  float get4ByteFloatValue();
                          
                                  void setKNXTime(int day, int hours, int minutes, int seconds);
                          
                                  void set14ByteValue(String value);
                                  String get14ByteValue(String value);
                          
                                  // Getter+Setter for Properties/Memory Access
                          //    int curr_object;
                          //    int curr_property;
                          //    int curr_length = 2;
                          //    byte curr_data[curr_length];
                                  int getPropertyObject();
                                  int getPropertyId();
                                  int getPropertyCount();
                                  void getPropertyData(byte* data);
                          
                          
                              private:
                                  int buffer[MAX_KNX_TELEGRAM_SIZE];
                                  int calculateChecksum();
                          
                          };
                          
                          #endif
                          KnxTelegram.cpp

                          Code:
                          #include "KnxTelegram.h"
                          
                          KnxTelegram::KnxTelegram() {
                              clear();
                          }
                          
                          void KnxTelegram::clear() {
                              for (int i = 0; i < MAX_KNX_TELEGRAM_SIZE; i++) {
                                  buffer[i] = 0;
                              }
                          
                              // Control Field, Normal Priority, No Repeat
                              buffer[0] = B10111100;
                          
                              // Target Group Address, Routing Counter = 6, Length = 1 (= 2 Bytes)
                              buffer[5] = B11100001;
                          }
                          
                          int KnxTelegram::getBufferByte(int index) {
                              return buffer[index];
                          }
                          
                          void KnxTelegram::setBufferByte(int index, int content) {
                              buffer[index] = content;
                          }
                          
                          bool KnxTelegram::isRepeated() {
                              // Parse Repeat Flag
                              if (buffer[0] & B00100000) {
                                  return false;
                              } else {
                                  return true;
                              }
                          }
                          
                          void KnxTelegram::setRepeated(bool repeat) {
                              if (repeat) {
                                  buffer[0] = buffer[0] & B11011111;
                              } else {
                                  buffer[0] = buffer[0] | B00100000;
                              }
                          }
                          
                          void KnxTelegram::setPriority(KnxPriorityType prio) {
                              buffer[0] = buffer[0] & B11110011;
                              buffer[0] = buffer[0] | (prio << 2);
                          }
                          
                          KnxPriorityType KnxTelegram::getPriority() {
                              // Priority
                              return (KnxPriorityType) ((buffer[0] & B00001100) >> 2);
                          }
                          
                          void KnxTelegram::setSourceAddress(byte sourceAddress[2]) {
                              buffer[1] = sourceAddress[0];
                              buffer[2] = sourceAddress[1];
                          }
                          
                          int KnxTelegram::getSourceArea() {
                              return (buffer[1] >> 4);
                          }
                          
                          int KnxTelegram::getSourceLine() {
                              return (buffer[1] & B00001111);
                          }
                          
                          int KnxTelegram::getSourceMember() {
                              return buffer[2];
                          }
                          
                          void KnxTelegram::setTargetGroupAddress(byte targetGroupAddress[2]) {
                              buffer[3] = targetGroupAddress[0];
                              buffer[4] = targetGroupAddress[1];
                              buffer[5] = buffer[5] | B10000000;
                          }
                          
                          void KnxTelegram::setTargetIndividualAddress(byte targetIndividualAddress[2]) {
                              buffer[3] = targetIndividualAddress[0];
                              buffer[4] = targetIndividualAddress[1];
                              buffer[5] = buffer[5] & B01111111;
                          }
                          
                          // Is the target a GA? If not, it's a PA
                          bool KnxTelegram::isTargetGroup() {
                              return buffer[5] & B10000000;
                          }
                          
                          bool KnxTelegram::isBroadcast() {
                              return isTargetGroup() && buffer[3] == 0 && buffer[4] == 0;
                          }
                          
                          /*
                           * Returns target address as 2bytes
                           * Depends on "isTargetGroup" how to interpret it: GA or PA
                           */
                          void KnxTelegram::getTarget(byte target[2]) {
                              target[0] = buffer[3];
                              target[1] = buffer[4];
                          }
                          
                          int KnxTelegram::getTargetMainGroup() {
                              return ((buffer[3] & B01111000) >> 3);
                          }
                          
                          int KnxTelegram::getTargetMiddleGroup() {
                              return (buffer[3] & B00000111);
                          }
                          
                          int KnxTelegram::getTargetSubGroup() {
                              return buffer[4];
                          }
                          
                          int KnxTelegram::getTargetArea() {
                              return ((buffer[3] & B11110000) >> 4);
                          }
                          
                          int KnxTelegram::getTargetLine() {
                              return (buffer[3] & B00001111);
                          }
                          
                          int KnxTelegram::getTargetMember() {
                              return buffer[4];
                          }
                          
                          void KnxTelegram::setRoutingCounter(int counter) {
                              buffer[5] = buffer[5] & B10000000;
                              buffer[5] = buffer[5] | (counter << 4);
                          }
                          
                          int KnxTelegram::getRoutingCounter() {
                              return ((buffer[5] & B01110000) >> 4);
                          }
                          
                          void KnxTelegram::setPayloadLength(int length) {
                              buffer[5] = buffer[5] & B11110000;
                              buffer[5] = buffer[5] | (length - 1);
                          }
                          
                          int KnxTelegram::getPayloadLength() {
                              int length = (buffer[5] & B00001111) + 1;
                              return length;
                          }
                          
                          void KnxTelegram::setCommand(KnxCommandType command) {
                              buffer[6] = buffer[6] & B11111100; // erase first two bits
                              buffer[7] = buffer[7] & B00111111; // erase last two bits
                          
                              buffer[6] = buffer[6] | (command >> 2); // Command first two bits
                              buffer[7] = buffer[7] | (command << 6); // Command last two bits
                          }
                          
                          KnxCommandType KnxTelegram::getCommand() {
                              return (KnxCommandType) (((buffer[6] & B00000011) << 2) | ((buffer[7] & B11000000) >> 6));
                          }
                          
                          void KnxTelegram::setExtendedCommand(KnxExtendedCommandType extCommand) {
                              buffer[7] = buffer[7] & B11000000; // erase last six bits
                              buffer[7] = buffer[7] | (extCommand >> 6); // ExtCommand first six bits
                          }
                          
                          KnxExtendedCommandType KnxTelegram::getExtendedCommand() {
                              return (KnxExtendedCommandType) (buffer[7] & B00111111); // get only first six bits
                          }
                          
                          void KnxTelegram::setControlData(KnxControlDataType cd) {
                              buffer[6] = buffer[6] & B11111100;
                              buffer[6] = buffer[6] | cd;
                          }
                          
                          KnxControlDataType KnxTelegram::getControlData() {
                              return (KnxControlDataType) (buffer[6] & B00000011);
                          }
                          
                          KnxCommunicationType KnxTelegram::getCommunicationType() {
                              return (KnxCommunicationType) ((buffer[6] & B11000000) >> 6);
                          }
                          
                          void KnxTelegram::setCommunicationType(KnxCommunicationType type) {
                              buffer[6] = buffer[6] & B00111111;
                              buffer[6] = buffer[6] | (type << 6);
                          }
                          
                          int KnxTelegram::getSequenceNumber() {
                              return (buffer[6] & B00111100) >> 2;
                          }
                          
                          void KnxTelegram::setSequenceNumber(int number) {
                              buffer[6] = buffer[6] & B11000011;
                              buffer[6] = buffer[6] | (number << 2);
                          }
                          
                          void KnxTelegram::setFirstDataByte(int data) {
                              buffer[7] = buffer[7] & B11000000;
                              buffer[7] = buffer[7] | data;
                          }
                          
                          int KnxTelegram::getFirstDataByte() {
                              return (buffer[7] & B00111111);
                          }
                          
                          void KnxTelegram::createChecksum() {
                              int checksumPos = getPayloadLength() + KNX_TELEGRAM_HEADER_SIZE;
                              buffer[checksumPos] = calculateChecksum();
                          }
                          
                          int KnxTelegram::getChecksum() {
                              int checksumPos = getPayloadLength() + KNX_TELEGRAM_HEADER_SIZE;
                              return buffer[checksumPos];
                          }
                          
                          bool KnxTelegram::verifyChecksum() {
                              int calculatedChecksum = calculateChecksum();
                              return (getChecksum() == calculatedChecksum);
                          }
                          
                          void KnxTelegram::print(TPUART_SERIAL_CLASS* serial) {
                          //#if defined(TPUART_DEBUG)
                              serial->print("Repeated: ");
                              serial->println(isRepeated());
                          
                              serial->print("Priority: ");
                              serial->println(getPriority());
                          
                              serial->print("Source: ");
                              serial->print(getSourceArea());
                              serial->print(".");
                              serial->print(getSourceLine());
                              serial->print(".");
                              serial->println(getSourceMember());
                          
                              if (isTargetGroup()) {
                                  serial->print("Target Group: ");
                                  serial->print(getTargetMainGroup());
                                  serial->print("/");
                                  serial->print(getTargetMiddleGroup());
                                  serial->print("/");
                                  serial->println(getTargetSubGroup());
                              } else {
                                  serial->print("Target Physical: ");
                                  serial->print(getTargetArea());
                                  serial->print(".");
                                  serial->print(getTargetLine());
                                  serial->print(".");
                                  serial->println(getTargetMember());
                              }
                          
                              serial->print("Routing Counter: ");
                              serial->println(getRoutingCounter());
                          
                              serial->print("Payload Length: ");
                              serial->println(getPayloadLength());
                          
                              serial->print("Command: ");
                              serial->println(getCommand());
                          
                              serial->print("First Data Byte: ");
                              serial->println(getFirstDataByte());
                          
                              for (int i = 2; i < getPayloadLength(); i++) {
                                  serial->print("Data Byte ");
                                  serial->print(i);
                                  serial->print(": ");
                                  serial->println(buffer[6+i], BIN);
                              }
                          
                          
                              if (verifyChecksum()) {
                                  serial->println("Checksum matches");
                              } else {
                                  serial->println("Checksum mismatch");
                                  serial->println(getChecksum(), BIN);
                                  serial->println(calculateChecksum(), BIN);
                              }
                          //#endif
                          }
                          
                          int KnxTelegram::calculateChecksum() {
                              int bcc = 0xFF;
                              int size = getPayloadLength() + KNX_TELEGRAM_HEADER_SIZE;
                          
                              for (int i = 0; i < size; i++) {
                                  bcc ^= buffer[i];
                              }
                          
                              return bcc;
                          }
                          
                          int KnxTelegram::getTotalLength() {
                              return KNX_TELEGRAM_HEADER_SIZE + getPayloadLength() + 1;
                          }
                          
                          /*
                           * DPT 1
                           * 1 bit
                           */
                          bool KnxTelegram::getBool() {
                              if (getPayloadLength() != 2) {
                                  // Wrong payload length
                                  return 0;
                              }
                          
                              return(getFirstDataByte() & B00000001);
                          }
                          
                          /*
                           * DPT 3
                           * 3 bit controlled
                           * 3 bit
                           */
                          /*byte KnxTelegram::get3Bit() {
                              if (getPayloadLength() != 2) {
                                  // Wrong payload length
                                  return 0;
                              }
                          
                              return(getFirstDataByte() & B00001111);
                          }
                          */
                          /*
                           * DPT 4 / DPT 5
                           */
                          void KnxTelegram::set1ByteIntValue(int value) {
                              setPayloadLength(3);
                              buffer[8]=value;
                          }
                          
                          /*
                           * DPT 4 / DPT 5
                           */
                          int KnxTelegram::get1ByteIntValue() {
                              if (getPayloadLength() != 3) {
                                  // Wrong payload length
                                  return 0;
                              }
                          
                              return(buffer[8]);
                          }
                          
                          /*
                           * DPT 9
                           * 2 byte float value
                           * 2 byte
                           */
                          void KnxTelegram::set2ByteFloatValue(float value) {
                              setPayloadLength(4);
                          
                              float v = value * 100.0f;
                              int exponent = 0;
                              for (; v < -2048.0f; v /= 2) exponent++;
                              for (; v > 2047.0f; v /= 2) exponent++;
                              long m = round(v) & 0x7FF;
                              short msb = (short) (exponent << 3 | m >> 8);
                              if (value < 0.0f) msb |= 0x80;
                              buffer[8] = msb;
                              buffer[9] = (byte)m;
                          }
                          
                          /*
                           * DPT 9
                           * 2 byte float value
                           * 2 byte
                           */
                          float KnxTelegram::get2ByteFloatValue() {
                              if (getPayloadLength() != 4) {
                                  // Wrong payload length
                                  return 0;
                              }
                          
                              int exponent = (buffer[8] & B01111000) >> 3;
                              int mantissa = ((buffer[8] & B00000111) << 8) | (buffer[9]);
                          
                              int sign = 1;
                          
                              if (buffer[8] & B10000000) {
                                  sign = -1;
                              }
                          
                              return (mantissa * 0.01) * pow(2.0, exponent);
                          }
                          
                          /*
                           * DPT 14
                           * 4 byte float value
                           * 4 byte
                           */
                          void KnxTelegram::set4ByteFloatValue(float value) {
                            setPayloadLength(6);
                          
                            byte b[4];
                            float *f = (float*)(void*)&(b[0]);
                            *f=value;
                          
                            buffer[8+3]=b[0];
                            buffer[8+2]=b[1];
                            buffer[8+1]=b[2];
                            buffer[8+0]=b[3];
                          }
                          
                          /*
                           * DPT 14
                           * 4 byte float value
                           * 4 byte
                           */
                          float KnxTelegram::get4ByteFloatValue() {
                              if (getPayloadLength() != 6) {
                                  // Wrong payload length
                                  return 0;
                              }
                            byte b[4];
                            b[0]=buffer[8+3];
                            b[1]=buffer[8+2];
                            b[2]=buffer[8+1];
                            b[3]=buffer[8+0];
                            float *f=(float*)(void*)&(b[0]);
                            float  r=*f;
                            return r;
                          }
                          
                          /*
                           * DPT 16
                           * Character string
                           * 14 byte
                           */
                          void KnxTelegram::set14ByteValue(String value) {
                            // load definieren
                            char _load[15];
                          
                            // load mit space leeren/initialisieren
                            for (int i=0; i<14; ++i)
                            {_load[i]= 0;}
                            setPayloadLength(16);
                            //mache aus Value das CharArray
                            value.toCharArray(_load,15); // muss 15 sein - weil mit 0 abgeschlossen wird
                            buffer[8+0]=_load [0];
                            buffer[8+1]=_load [1];
                            buffer[8+2]=_load [2];
                            buffer[8+3]=_load [3];
                            buffer[8+4]=_load [4];
                            buffer[8+5]=_load [5];
                            buffer[8+6]=_load [6];
                            buffer[8+7]=_load [7];
                            buffer[8+8]=_load [8];
                            buffer[8+9]=_load [9];
                            buffer[8+10]=_load [10];
                            buffer[8+11]=_load [11];
                            buffer[8+12]=_load [12];
                            buffer[8+13]=_load [13];
                          }
                          
                          /*
                           * DPT 16
                           * Character string
                           * 14 byte
                           */
                          String KnxTelegram::get14ByteValue(String value) {
                          if (getPayloadLength() != 16) {
                                  // Wrong payload length
                                  return "";
                              }
                              char _load[15];
                              _load[0]=buffer[8+0];
                              _load[1]=buffer[8+1];
                              _load[2]=buffer[8+2];
                              _load[3]=buffer[8+3];
                              _load[4]=buffer[8+4];
                              _load[5]=buffer[8+5];
                              _load[6]=buffer[8+6];
                              _load[7]=buffer[8+7];
                              _load[8]=buffer[8+8];
                              _load[9]=buffer[8+9];
                              _load[10]=buffer[8+10];
                              _load[11]=buffer[8+11];
                              _load[12]=buffer[8+12];
                              _load[13]=buffer[8+13];
                              return (_load);
                          }
                          
                          void KnxTelegram::setKNXTime(int day, int hours, int minutes, int seconds) {
                              // Payload (3 byte) + 2
                              setPayloadLength(5);
                          
                              // Day um 5 byte nach links verschieben
                              day = day << 5;
                              // Buffer[8] füllen: die ersten 3 Bits day, die nächsten 5 hour
                              buffer[8] = (day & B11100000) + (hours & B00011111);
                          
                              // buffer[9] füllen: 2 bits leer dann 6 bits für minuten
                              buffer[9] =  minutes & B00111111;
                          
                              // buffer[10] füllen: 2 bits leer dann 6 bits für sekunden
                              buffer[10] = seconds & B00111111;
                          }
                          
                          /*
                           * Property / Memory Access stuff
                           */
                          
                          int KnxTelegram::getPropertyObject(){
                              return 0;
                          }
                          
                          int KnxTelegram::getPropertyId() {
                              return 0;
                          }
                          
                          int KnxTelegram::getPropertyCount() {
                              return 1;
                          }
                          
                          void KnxTelegram::getPropertyData(byte* data) {
                              for (int i=0;i<getPropertyCount();i++){
                                  data[i] = 0xff;
                              }
                          }

                          Mit freundlichen Grüßen

                          Mag Gyver
                          Zuletzt geändert von Mag Gyver; 22.01.2017, 11:54.

                          Kommentar


                            Werde ich mal testen. Vielen Dank!

                            Ich muss ja mal eine funktionierende Library gehabt haben, ansonsten würde mein Sketch auf dem Schlüsselbrett Arduino nicht seit 1,5 Jahren laufen .
                            Ich gebe Rückmeldung sobald ich das ausprobiert habe.
                            Umgezogen? Ja! ... Fertig? Nein!
                            Baustelle 2.0 !

                            Kommentar


                              Hallo JuMi2006,

                              kein Problem. Musste nach deiner Anfrage hier auch erst im Archiv auf die Suche gehen. Benütze eigentlich die Library von ThorstenGehrig.

                              Ach bevor ich es vergesse, habe für die Library von ThorstenGehrig eine kleine Änderung auf Bitbucket abgelegt.
                              Bezieht sich auf das Beispiel "GroupRead" habe eine kleine Notiz hinzugefügt.

                              Bin vor kurzen selber darüber gestolpert, wenn man nicht alles gleich dokumentiert, dann geht das meisten schief.



                              Mit freundlichen Grüßen

                              Mag Gyver
                              Zuletzt geändert von Mag Gyver; 22.01.2017, 16:21.

                              Kommentar


                                Kann mir jemand kurz Rückmeldung geben, auf welcher Arduino-Hardware die Lib mittlerweile problemlos läuft?

                                Ich denke da insbesondere an den SAMD21 (Arduino Zero und M0) und den SAM3X8E (Arduino Due)...läuft die Lib da out-of-the-box? Mag Gyver hast Du da vielleicht schon Erfahrung?

                                Vielen Dank schonmal!
                                Viele Grüße,
                                Stefan

                                DIY-Bastelprojekte: || >> Smelly One << || >> BURLI << ||

                                Kommentar

                                Lädt...
                                X