Ankündigung

Einklappen
Keine Ankündigung bisher.

ARDUINO am KNX

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

  • JuMi2006
    antwortet
    Gibt es denn noch Interesse daran die Lib möglichst funktionsfähig zu machen?

    Ich sehe es nämlich genauso dass KONNEKTING zwar cool ist aber für eine Kleinigkeit einfach oversized (zumindest für mich). Daher wäre eine gut funktionierende Lib ohne Software-Overhead eigentlich ganz schön. Das kann sehr gut neben KONNEKTING existieren.

    Einen Kommentar schreiben:


  • dreamy1
    antwortet
    Nicht alles was ich in meiner Freizeit mache, hat unmittelbar mit Konnekting zu tun :-)

    Hintergrund ist einfach der:

    Für Kleinstanwendungen wie z.B. eine Temperatur alle 60s auf den Bus zu schreiben, ist Konnekting einfach oversized. Für komplexere Applikationen mit mehreren KO's, die man dann auch noch regelmäßig ändern möchte, hat Konnekting natürlich nach wie vor riesige Vorteile und da stehe ich auch nach wie vor voll dahinter...aber es gibt halt auch Fälle, wo man mit zwei Zeilen extra Code im Arduino-Sketch bereits am Ziel ist...

    Einen Kommentar schreiben:


  • tuxedo
    antwortet
    Darf man fragen was du vor hast? Als eigentliches Team-Mitglied von KONNEKTING hüllst du dich zeitweilen sehr in schweigen, bzw. lässt dir alles aus der Nase ziehen :-(

    Einen Kommentar schreiben:


  • dreamy1
    antwortet
    Danke Euch beiden! Die Debug-Ausgaben habe ich in der Lib gesehen, nur ob es schon jemand ausprobiert hat war mir unklar...dann werde ich mal wohl testen müssen :-)

    Einen Kommentar schreiben:


  • Mag Gyver
    antwortet
    Hallo dreamy1,

    die Library von ThorstenGehrig sollte eigentlich auf den von dir genannten Mikroprozessoren lauffähig sein. Ja, tuxedo war da etwas schneller.

    Erfahrungen habe ich nur mit den 8bit Mikroprozessoren gesammelt, wie dem Arduino Uno, Arduino Mega, Arduino Pro Mini und dem ATmega328pb, sowie dem ATmega1284p.

    Aber gerne freuen wir uns über Erfahrungsberichte von dir.
    Debug-port-Ausgaben sind für den Arduino Due in der Library von ThorstenGehrig schon vorgesehen.



    Mit freundlichen Grüßen

    Mag Gyver
    Zuletzt geändert von Mag Gyver; 07.02.2017, 19:13.

    Einen Kommentar schreiben:


  • tuxedo
    antwortet
    Zu Konnekting, siehe:

    http://www.konnekting.de/roadmap/ --> https://github.com/KONNEKTING/Konnek...equirements.md

    Die Thorsten-Lib sollte eigtl auch mit dem SAMD funktionieren. Probiert hab ich's aber noch nicht. Arduino Due... kein Plan.

    Einen Kommentar schreiben:


  • dreamy1
    antwortet
    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!

    Einen Kommentar schreiben:


  • Mag Gyver
    antwortet
    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.

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    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.

    Einen Kommentar schreiben:


  • Mag Gyver
    antwortet
    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.

    Einen Kommentar schreiben:


  • Eugenius
    antwortet
    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)

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    Ist denn wirklich niemand mehr mit GA_STRING unterwegs ?
    Oder hat jemand einen funktionierenden Sketch samt Library ?

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    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.

    Einen Kommentar schreiben:


  • tuxedo
    antwortet
    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?

    Einen Kommentar schreiben:


  • JuMi2006
    antwortet
    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

    Einen Kommentar schreiben:

Lädt...
X