Hallo TE2,
die Sache ist einleseoffensiv.
Einen sehr einfachen Busmonitor für KNX/EIB auf Basis des TP-UART gibt es schon.
Zugegeben der Monsterthread im KNX-User-Forum ist sehr unübersichtlich, darin verborgen steckt aber der einfache Busmonitor. Ganz ohne Library.
Sketch für Busmonitor:
//KNX BUSMONITOR
#ifdef __AVR_ATmega32U4__ //Universal Flush Interface, ProMicro, Leonardo
#define DEBUGSERIAL Serial //USB
#define KNX_SERIAL Serial1 //D0,D1
//#define LED_PIN 13 //UFI STD, Aruino Leonardo
//#define LED_PIN 8 //UFI PWM
#define LED_PIN LED_BUILTIN_RX //ProMicro (Attention: LOW = ON, HIGH = OFF)
#elif __AVR_ATmega2560__ //Interface, Arduino Mega
#define DEBUGSERIAL Serial //D0,D1
#define KNX_SERIAL Serial1 //D18,D19
#define LED_PIN LED_BUILTIN //Arduino Mega
#elif __SAMD21G18A__ //Multi Interface, Arduino Zero
#define DEBUGSERIAL SerialUSB //USB
//#define KNX_SERIAL Serial //Multi Interface
#define KNX_SERIAL Serial1 //D0,D1
//#define LED_PIN A5 //Multi Interface
#define LED_PIN LED_BUILTIN //Arduino Zero
#endif
#define KNX_TELEGRAM_MAX_SIZE 23
long lastMicros = 0;
bool dataReceived = false;
byte telegram[KNX_TELEGRAM_MAX_SIZE];
byte counter = 0;
void setup() {
KNX_SERIAL.begin(19200, SERIAL_8E1);
DEBUGSERIAL.begin(115200);
pinMode(LED_PIN, OUTPUT);
clearBuffer();
}
void loop() {
if (KNX_SERIAL.available() > 0) {
lastMicros = (long)micros();
byte temp = KNX_SERIAL.read();
// if(temp<16) DEBUGSERIAL.print("0"); //print 0 for 2 digit HEX
// DEBUGSERIAL.print(temp,HEX);
// DEBUGSERIAL.print(" ");
telegram[counter] = temp;
counter++;
if (!dataReceived) {
dataReceived = true;
digitalWrite(LED_PIN, HIGH); //LED is ON is data is received
}
}
if ((long)micros() - lastMicros >= 2000 && dataReceived) {
//2000+ µs => end of telegram => new line
// DEBUGSERIAL.println("");
dataReceived = false;
//print usable array data
for (byte i = 0; i < counter; i++) {
if (telegram[i] < 16) DEBUGSERIAL.print("0"); //print 0 for 2 digit HEX
DEBUGSERIAL.print(telegram[i], HEX);
DEBUGSERIAL.print(" ");
}
DEBUGSERIAL.println("");
printData();
counter = 0;
clearBuffer();
digitalWrite(LED_PIN, LOW); //turn LED off
}
}
void clearBuffer() {
memset(telegram, 0, sizeof(telegram));
}
void printData() {
byte temp = telegram[1];
byte pa1 = telegram[1] >> 4;
byte pa2 = telegram[1] & B00001111;
byte ga1 = telegram[3] >> 3;
byte ga2 = telegram[3] & B00000111;
byte datalength = telegram[5] & B00001111;
byte firstDateByte = telegram[7] & B00111111; //use only last 6 bits
DEBUGSERIAL.print("PA: ");
DEBUGSERIAL.print(pa1, DEC);
DEBUGSERIAL.print(".");
DEBUGSERIAL.print(pa2, DEC);
DEBUGSERIAL.print(".");
DEBUGSERIAL.print(telegram[2], DEC);
DEBUGSERIAL.print(" GA: ");
DEBUGSERIAL.print(ga1, DEC);
DEBUGSERIAL.print("/");
DEBUGSERIAL.print(ga2, DEC);
DEBUGSERIAL.print("/");
DEBUGSERIAL.print(telegram[4], DEC);
DEBUGSERIAL.print(" Data length (bytes): ");
if (datalength == 1) {
DEBUGSERIAL.print(datalength, DEC); //if 1 then usable data max 6 bits, DPT 1.xxx, DPT 2.xxx, DPT 3.xxx, DPT 23.xxx ...
} else {
DEBUGSERIAL.print(datalength - 1, DEC); //ignore first byte because data doesn't fit in 6 bits
}
DEBUGSERIAL.print(" Data (HEX): ");
if (datalength == 1) {
if (firstDateByte < 16) DEBUGSERIAL.print("0"); //print 0 for 2 digit HEX
DEBUGSERIAL.print(firstDateByte, HEX);
DEBUGSERIAL.print(" ");
}
for (byte i = 1; i < datalength; i++) {
if (telegram[7 + i] < 16) DEBUGSERIAL.print("0"); //print 0 for 2 digit HEX
DEBUGSERIAL.print(telegram[7 + i], HEX);
DEBUGSERIAL.print(" ");
}
DEBUGSERIAL.println();
}
Ausgabe sieht so aus:
BC 11 DD 3F 02 E3 00 81 14 FD 39
PA: 1.1.221 GA: 7/7/2 Data length (bytes): 2 Data (HEX): 14 FD
BC 11 FC 2F FE E1 00 81 1F
PA: 1.1.252 GA: 5/7/254 Data length (bytes): 1 Data (HEX): 01
Brauchst das Rad nicht ganz neu erfinden. 