Test program to send MAX!-Messages with a RFM22-Module

Dependencies:   RF22 TextLCD TextLCDScroll mbed RF22Max

Files at this revision

API Documentation at this revision

Comitter:
charly
Date:
Tue Oct 22 19:43:01 2013 +0000
Parent:
3:4254b4c3557e
Commit message:
Work in progrss version of sending code

Changed in this revision

RF22Max.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/RF22Max.lib	Tue Oct 22 19:43:01 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/charly/code/RF22Max/#f75e51ce001b
--- a/main.cpp	Mon Sep 09 19:47:45 2013 +0000
+++ b/main.cpp	Tue Oct 22 19:43:01 2013 +0000
@@ -1,21 +1,21 @@
-// Testprogramm for RFM22B with RF22-Library to read ELV MAX! window Shutter-Contacts and PushBottons
-// Quick and dirty code!!!!!!
-// needs refactoring
+// Testprogramm for RFM22B with RF22Max-Library to read ELV MAX! window Shutter-Contacts and PushBottons
 
+//show debug output on Serial pc
+#define DEBUG
 
 #include "mbed.h"
-#include <RF22.h>
+#include <RF22Max.h>
 #include "TextLCDScroll.h"
 
-
-#define lengthof(x) (sizeof(x) / sizeof(*x))
+// show debug-output on console
+//#define DEBUG
 
 Serial pc(USBTX, USBRX);
 
-//Freebus-RS-Interface connected to serial
-Serial knxrs(p9, p10);  // tx, rx
+Ticker SendTicker;
 
-//TextLCDScroll lcd(p30, p29, p28, p27, p26, p25, TextLCD::LCD16x2); // rs, e, d4-d7
+volatile int doSend = 0;     // set to 1 by Ticker-Interrupt and read in main-loop
+
 TextLCDScroll lcd(p30, p29, p28, p27, p26, p25, TextLCD::LCD16x2); // rs, e, d4-d7
 
 // mbed LEDs
@@ -24,585 +24,100 @@
 DigitalOut led3(LED3);
 DigitalOut led4(LED4);
 
-struct max_knx_mapping_t {
-    uint32_t         device_id;
-    char             knx_adr[255];
-};
-
-#define MAX_KNX_MAPPINGS 10
-
-// a message from the max!-Device
-struct max_message {
-    uint8_t    len;                //message-length
-    uint8_t    cnt;                //message-counter
-    uint8_t    flags;              // ??
-    uint8_t    type;               //message-type
-    char       type_str[50];       // type in text
-    uint32_t   frm_adr;            // unique address of device
-    uint32_t   to_adr;             // unique address of device
-    uint8_t    groupid;            //groupid
-    uint8_t    payload[50];        // data
-    uint16_t   crc;                // crc fro the message
-    char       state[50];          // state of the device: open, closed, auto, eco,...
-    char       battery_state[50];  // Battery-state of the device : good, low
-};
-
-
-
 // Singleton instance of the radio
 //rf22(PinName slaveSelectPin , PinName mosi, PinName miso, PinName sclk, PinName interrupt );
-RF22 rf22(p14,p11,p12,p13,p15);
-
-
-const RF22::ModemConfig config = { // for MAX! protocol
-    .reg_1c = 0x01,
-    .reg_1f = 0x03,
-    .reg_20 = 0x90,
-    .reg_21 = 0x20,
-    .reg_22 = 0x51,
-    .reg_23 = 0xea,
-    .reg_24 = 0x00,
-    .reg_25 = 0x58,
-    /* 2c - 2e are only for OOK */
-    .reg_2c = 0x00,
-    .reg_2d = 0x00,
-    .reg_2e = 0x00,
-    .reg_58 = 0x80, /* Copied from RF22 defaults */
-    .reg_69 = 0x60, /* Copied from RF22 defaults */
-    .reg_6e = 0x08,
-    .reg_6f = 0x31,
-    .reg_70 = 0x24,
-    .reg_71 = RF22_DTMOD_FIFO | RF22_MODTYP_FSK,
-    .reg_72 = 0x1e,
-};
-
-/* Sync words to send / check for. Don't forget to update RF22_SYNCLEN
-* below if changing the length of this array. */
-const uint8_t sync_words[] = {
-    0xc6,
-    0x26,
-    0xc6,
-    0x26,
-};
-
-enum modes {MODE_AUTO, MODE_MANUAL, MODE_TEMPORARY, MODE_BOOST};
-const char *mode_str[] = {
-    [MODE_AUTO] = "auto",
-    [MODE_MANUAL] = "manual",
-    [MODE_TEMPORARY] = "temporary",
-    [MODE_BOOST] = "boost"
-};
-
-char *type_str(uint8_t type)
-{
-    switch(type) {
-        case 0x00:
-            return "PairPing";
-        case 0x01:
-            return "PairPong";
-        case 0x02:
-            return "Ack";
-        case 0x03:
-            return "TimeInformation";
-        case 0x10:
-            return "ConfigWeekProfile";
-        case 0x11:
-            return "ConfigTemperatures";
-        case 0x12:
-            return "ConfigValve";
-        case 0x20:
-            return "AddLinkPartner";
-        case 0x21:
-            return "RemoveLinkPartner";
-        case 0x22:
-            return "SetGroupId";
-        case 0x23:
-            return "RemoveGroupId";
-        case 0x30:
-            return "ShutterContactState";
-        case 0x40:
-            return "SetTemperature";
-        case 0x42:
-            return "WallThermostatState";
-        case 0x43:
-            return "SetComfortTemperature";
-        case 0x44:
-            return "SetEcoTemperature";
-        case 0x50:
-            return "PushButtonState";
-        case 0x60:
-            return "ThermostatState";
-        case 0x82:
-            return "SetDisplayActualTemperature";
-        case 0xF1:
-            return "WakeUp";
-        case 0xF0:
-            return "Reset";
-    }
-    return "Unknown";
-}
-
-
-/* First 255 bytes of PN9 sequence used for data whitening by the CC1101
-* chip. The RF22 chip is documented to support the same data whitening
-* algorithm, but in practice seems to use a different sequence.
-*
-* Data was generated using the following python snippet:
-*
-import itertools
-def pn9(state):
-    while True:
-        yield hex(state & 0xff)
-        # The pn9 generator is clocked 8 times while shifting in the
-        # next data byte
-        for i in range(8):
-            state = (state >> 1) + (((state & 1) ^ (state >> 5) & 1) << 8)
-print(list(itertools.islice(pn9(0x1ff), 255)))
-*/
-
-const uint8_t pn9[] = {
-    0xff, 0xe1, 0x1d, 0x9a, 0xed, 0x85, 0x33, 0x24,
-    0xea, 0x7a, 0xd2, 0x39, 0x70, 0x97, 0x57, 0x0a,
-    0x54, 0x7d, 0x2d, 0xd8, 0x6d, 0x0d, 0xba, 0x8f,
-    0x67, 0x59, 0xc7, 0xa2, 0xbf, 0x34, 0xca, 0x18,
-    0x30, 0x53, 0x93, 0xdf, 0x92, 0xec, 0xa7, 0x15,
-    0x8a, 0xdc, 0xf4, 0x86, 0x55, 0x4e, 0x18, 0x21,
-    0x40, 0xc4, 0xc4, 0xd5, 0xc6, 0x91, 0x8a, 0xcd,
-    0xe7, 0xd1, 0x4e, 0x09, 0x32, 0x17, 0xdf, 0x83,
-    0xff, 0xf0, 0x0e, 0xcd, 0xf6, 0xc2, 0x19, 0x12,
-    0x75, 0x3d, 0xe9, 0x1c, 0xb8, 0xcb, 0x2b, 0x05,
-    0xaa, 0xbe, 0x16, 0xec, 0xb6, 0x06, 0xdd, 0xc7,
-    0xb3, 0xac, 0x63, 0xd1, 0x5f, 0x1a, 0x65, 0x0c,
-    0x98, 0xa9, 0xc9, 0x6f, 0x49, 0xf6, 0xd3, 0x0a,
-    0x45, 0x6e, 0x7a, 0xc3, 0x2a, 0x27, 0x8c, 0x10,
-    0x20, 0x62, 0xe2, 0x6a, 0xe3, 0x48, 0xc5, 0xe6,
-    0xf3, 0x68, 0xa7, 0x04, 0x99, 0x8b, 0xef, 0xc1,
-    0x7f, 0x78, 0x87, 0x66, 0x7b, 0xe1, 0x0c, 0x89,
-    0xba, 0x9e, 0x74, 0x0e, 0xdc, 0xe5, 0x95, 0x02,
-    0x55, 0x5f, 0x0b, 0x76, 0x5b, 0x83, 0xee, 0xe3,
-    0x59, 0xd6, 0xb1, 0xe8, 0x2f, 0x8d, 0x32, 0x06,
-    0xcc, 0xd4, 0xe4, 0xb7, 0x24, 0xfb, 0x69, 0x85,
-    0x22, 0x37, 0xbd, 0x61, 0x95, 0x13, 0x46, 0x08,
-    0x10, 0x31, 0x71, 0xb5, 0x71, 0xa4, 0x62, 0xf3,
-    0x79, 0xb4, 0x53, 0x82, 0xcc, 0xc5, 0xf7, 0xe0,
-    0x3f, 0xbc, 0x43, 0xb3, 0xbd, 0x70, 0x86, 0x44,
-    0x5d, 0x4f, 0x3a, 0x07, 0xee, 0xf2, 0x4a, 0x81,
-    0xaa, 0xaf, 0x05, 0xbb, 0xad, 0x41, 0xf7, 0xf1,
-    0x2c, 0xeb, 0x58, 0xf4, 0x97, 0x46, 0x19, 0x03,
-    0x66, 0x6a, 0xf2, 0x5b, 0x92, 0xfd, 0xb4, 0x42,
-    0x91, 0x9b, 0xde, 0xb0, 0xca, 0x09, 0x23, 0x04,
-    0x88, 0x98, 0xb8, 0xda, 0x38, 0x52, 0xb1, 0xf9,
-    0x3c, 0xda, 0x29, 0x41, 0xe6, 0xe2, 0x7b
-};
-
-/**
-* CRC code based on example from Texas Instruments DN502, matches
-* CC1101 implementation
-*/
-#define CRC16_POLY 0x8005
-uint16_t calc_crc_step(uint8_t crcData, uint16_t crcReg)
-{
-    uint8_t i;
-    for (i = 0; i < 8; i++) {
-        if (((crcReg & 0x8000) >> 8) ^ (crcData & 0x80))
-            crcReg = (crcReg << 1) ^ CRC16_POLY;
-        else
-            crcReg = (crcReg << 1);
-        crcData <<= 1;
-    }
-    return crcReg;
-} // culCalcCRC
-
-#define CRC_INIT 0xFFFF
-uint16_t calc_crc(uint8_t *buf, size_t len)
-{
-    uint16_t checksum;
-    checksum = CRC_INIT;
-    // Init value for CRC calculation
-    for (size_t i = 0; i < len; i++)
-        checksum = calc_crc_step(buf[i], checksum);
-    return checksum;
-}
-
-void printHex(uint8_t *buf, size_t len, bool nl)
-{
-    for (size_t i = 0; i < len; i++) {
-        pc.printf("%02X ",buf[i]);
-    }
-    if (nl)
-        pc.printf("\n\r");
-}
-
-void printUntil(uint8_t *buf)
-{
-    uint8_t year = buf[1] & 0x3f;
-    uint8_t month = ((buf[0] & 0xE0) >> 4) | (buf[1] >> 7);
-    uint8_t day = buf[0] & 0x1f;
-    /* In 30-minute increments */
-    uint8_t time = buf[2] & 0x3f;
-
-    pc.printf("Until:         20");
-    if (year < 10) pc.printf("0");
-    pc.printf("%i",year);
-    pc.printf(".");
-    if (month < 10) pc.printf("0");
-    pc.printf("%i",month);
-    pc.printf(".");
-    if (day < 10) pc.printf("0");
-    pc.printf("%i",day);
-    pc.printf(" ");
-    if (time < 20) pc.printf("0");
-    pc.printf("%i",time / 2);
-    if (time % 2)
-        pc.printf(":30");
-    else
-        pc.printf(":00");
-    pc.printf("\n\r");
-}
-
-
-max_message max_rx_msg()
-{
-    uint8_t buf[RF22_MAX_MESSAGE_LEN];
-
-    uint8_t len = sizeof(buf);
-    uint8_t sbuf[RF22_MAX_MESSAGE_LEN];
-    uint8_t slen = 0;
-
-    max_message message;               // holds a message from the max device
-
-    message.len = 0;
+RF22Max rf22(p14,p11,p12,p13,p15);
 
-    if (rf22.recv(buf, &len)) {
-        pc.printf("Recv: ");
-        pc.printf("len: %i\n\r",len);
-        len = 50;  // limit message to 50 Bytes as device receives all 255 Bytes
-
-        //pc.printf("buf: >%s<\n\r",(char*)buf);
-        printHex(buf, len, true);
-
-        /* Dewhiten data */
-        for (int i = 0; i < len; i++)
-            buf[i] ^= pn9[i];
-
-        // now read the real length
-        len = buf[0]+3; // 1 length-Byte + 2 CRC
-        pc.printf("len: %i\n\r",len);
-
-        if (len < 3 || len > lengthof(pn9)) {
-            pc.printf("Packet length too short/long (%i)\n\r",len);
-            return message;
-        }
-        pc.printf("dewhiten: ");
-        printHex(buf, len, true);
-
-        /* Calculate CRC (but don't include the CRC itself) */
-        uint16_t crc = calc_crc(buf, len - 2);
-        if (buf[len - 1] != (crc & 0xff) || buf[len - 2] != (crc >> 8)) {
-            pc.printf("CRC error: CRC: %04X\n\r",crc);
-            //return;
-        }
-
-        /* Don't use the CRC as data */
-        len -= 2;
-
-        uint8_t type = buf[3];
-
-        message.len     = len;                   //message-length
-        message.cnt     = buf[1];                //message-counter
-        message.flags   = buf[2];
-        message.type    = type;
-        strcpy(message.type_str,type_str(type));
-        message.frm_adr = buf[4]<<16 | buf[5]<<8| buf[6];            // unique address of device
-        message.to_adr  = buf[7]<<16 | buf[8]<<8| buf[9]; ;             // unique address of device
-        message.groupid = buf[10];            //groupid
-        memcpy( (void *) message.payload, (void *) buf[11],len-11);               // data
-        message.crc     = buf[len-2]<<8 | buf[len-1];                // crc for the message
-
-
-        pc.printf("Message count: ");
-        printHex(buf + 1, 1, true);
-        pc.printf("Flags:         ");
-        printHex(buf + 2, 1, true);
-        pc.printf("Packet type:   ");
-        printHex(&type, 1, false);
-        pc.printf(" (");
-        pc.printf(type_str(type));
-        pc.printf(")\n\r");
-        pc.printf("Packet from:   ");
-        printHex(buf + 4, 3, true);
-        pc.printf("Packet to:     ");
-        printHex(buf + 7, 3, true);
-        pc.printf("GroupID:       ");
-        printHex(buf + 10, 1, true);
-        pc.printf("Payload:       ");
-        printHex(buf + 11, len-11, true);
-        //pc.printf("Payload:      >%s<\n\r",(char*)buf+11);
-
-        lcd.setLine(1,"");
-        if (type == 0x30 && len >= 11) { //ShutterContactState
-            bool baterry_low = (buf[11] >> 7) & 0x1;
-            bool state = (buf[11]>>1) & 0x1;
-
-            pc.printf("State:      ");
-            if (state) {
-                strcpy(message.state,"open");
-                pc.printf("open\n\r");
-                lcd.setLine(1,"open   ");
-            } else {
-                strcpy(message.state,"closed");
-                pc.printf("closed\n\r");
-                lcd.setLine(1,"closed ");
-            }
-            pc.printf("Battery:    ");
-            if (baterry_low) {
-                pc.printf("low\n\r");
-                strcpy(message.battery_state,"low");
-            } else {
-                pc.printf("good\n\r");
-                strcpy(message.battery_state,"good");
-            }
-        }
-
-        if (type == 0x50 && len >= 11) { //PushButtonState
-            bool baterry_low = (buf[11] >> 7) & 0x1;    // to validate!!!
-            bool state = (buf[12]) & 0x1;
-
-            pc.printf("State:      ");
-            if (state) {
-                strcpy(message.state,"auto");
-                pc.printf("auto\n\r");
-                lcd.setLine(1,"auto");
-            } else {
-                strcpy(message.state,"eco");
-                pc.printf("eco\n\r");
-                lcd.setLine(1,"eco");
-            }
-            pc.printf("Battery:    ");
-            if (baterry_low) {
-                pc.printf("low\n\r");
-                strcpy(message.battery_state,"low");
-            } else {
-                pc.printf("good\n\r");
-                strcpy(message.battery_state,"good");
-            }
-
-        }
-
-
-
-#if 0
-        if (type == 0x00 && len >= 11) { //PairPing
-            char serial[20]="";
-            strncpy(serial,(char*)buf+14,10); //10 Characters for Seial Number
-            serial[11] = '\0';
-            pc.printf("Serial:        %s\n\r",serial);
-
-            // try to send PairPong
-            // wait some time
-            wait_ms(10);
-            sbuf[0] = 11; // MsgLen
-            sbuf[1] = buf[1]+1 &0xFF; // MsgCount ??
-            sbuf[2] = 0x00; // Flag
-            sbuf[3] = 0x01; // Type = Cmd = PairPong
-            sbuf[4] = 0x11; // From Fake Address
-            sbuf[5] = 0x11; // From
-            sbuf[6] = 0x11; // From
-            sbuf[7] = buf[4] ; // To Address = From address of Windowcontact
-            sbuf[8] = buf[5] ;
-            sbuf[9] = buf[6] ;
-            sbuf[10] = 0x00; // GroupId
-            sbuf[11] = 0x00;  //Payload is 0x00 for pairpong?
-            slen = 12+2; //+2Byte CRC????
-            /* Calculate CRC */
-            uint16_t scrc = calc_crc(sbuf, slen - 2);
-            sbuf[12] = crc >> 8;
-            sbuf[13] = crc & 0xff;
-
-
-            if (rf22.send(sbuf,slen)) {
-                pc.printf("Send PairPong OK\n\r");
-            } else {
-                pc.printf("Send PairPong NOT OK\n\r");
-            }
-
-        }
-#endif
-        /*
-                else if (type == 0x60 && len >= 13) { // ThermostatState
-                    uint8_t mode = buf[11] & 0x3;
-                    bool dst = (buf[11] >> 2) & 0x1;
-                    bool locked = (buf[11] >> 5) & 0x1;
-                    bool baterry_low = (buf[11] >> 7) & 0x1;
-                    // 0 - 64
-                    uint8_t valve = buf[12];
-                    uint8_t set_temp = buf[13];
-
-                    pc.printf("Mode:          ");
-                    pc.printf(mode_str[mode]);
-
-                    pc.printf("Valve pos:     %i%",100 * valve / 64);
-
-                    pc.printf("Set temp:      %2.1i",set_temp / 2);
-
-                    if (len > 15 && mode != MODE_TEMPORARY) {
-                        // In tenths of degrees
-                        uint8_t actual_temp = ((buf[14] & 0x1) << 8) + buf[15];
-                        pc.printf("Actual temp:   ");
-                        pc.printf(actual_temp / 10);
-                        pc.printf(".");
-                        pc.printf(actual_temp % 10);
-                    }
-                    if (len > 16 && mode == MODE_TEMPORARY) {
-                        printUntil(buf + 14);
-                    }
-                } else if (type == 0x40 && len >= 11) { // SetTemperature
-                    uint8_t set_temp = buf[11] & 0x3f;
-                    uint8_t mode = buf[11] >> 6;
-
-                    pc.printf("Mode:          ");
-                    pc.printf(mode_str[mode]);
-
-                    pc.print("Set temp:      ");
-                    pc.printf(set_temp / 2);
-                    pc.printf(set_temp % 2 ? ".5" : ".0");
-                    if (len > 14) {
-                        printUntil(buf + 12);
-                    }
-                }
-
-                // Print the data
-                int i, j;
-                for (i = 0; i < len; i += 16) {
-                    // Hex
-                    for (j = 0; j < 16 && i+j < len; j++) {
-                        if (buf[i+j] < 16)
-                            pc.print("0"); // Sigh, pc.print does not know how to pad hex
-                        pc.print(buf[i+j], HEX);
-                        pc.print(" ");
-                    }
-                    // Padding on last block
-                    while (j++ < 16)
-                        pc.print("   ");
-
-                    pc.print("   ");
-                    // ASCII
-                    for (j = 0; j < 16 && i+j < len; j++)
-                        pc.write(isprint(buf[i+j]) ? buf[i+j] : '.');
-                    pc.println("");
-                }
-        */
-
-        pc.printf("\n\r");
-    }
-    return message;
+void Ticker_isr()
+{
+    led1 = !led1;
+    doSend = 1;
 }
 
 
 int main()
 {
 
-    char group[255];                          // the KNX-Group-address
-    char command[255];                        // a command to send to the freebus rs-interface
-    char lcdline[255];
 
-    max_message MyMessage;
+    char lcdline[500];
+
+    RF22Max::max_message MyMessage;
     int  i;
 
-
-
-    max_knx_mapping_t max_knx_map[MAX_KNX_MAPPINGS];
+    uint8_t sbuf[RF22_MAX_MESSAGE_LEN];
 
-    //Mapping of MAX!-Device-IDs to KNX-Group-addresses
-    max_knx_map[0].device_id = 0x04B5F7;      // MAX!-Pushbutton
-    strcpy(max_knx_map[0].knx_adr,"3/1/1");   // PushButton01 = Licht Büro
-
-    max_knx_map[1].device_id = 0x04B5B9;      // MAX!-Pushbutton
-    sprintf(max_knx_map[1].knx_adr, "3/1/2"); // Pushbutton 02 = Licht Carina
-
-
+    uint8_t slen = sizeof(sbuf);
 
     pc.baud(115200);
 
     pc.printf("\n\rConnected to mbed\n\r");
 
 
-    char version_str [80] = "RF22-MAX!-V2.5";
+    char version_str [80] = "RF22-Send-Test!-V1.0";
     lcd.cls();
     lcd.setLine(0,version_str);
     pc.printf("%s\n\r",version_str);
 
 
-    // initialize freebus-rs-interface
-    // 115.200 Baud,n,8,1
-    knxrs.baud(115200);
-
-    knxrs.printf("fbecho=0\r");   //switch off echo
-
-
     pc.printf("Pre-init|");
     if (!rf22.init())
-        pc.printf("RF22 init failed\n\r");
+        pc.printf("RF22Max init failed\n\r");
     pc.printf("Post-init\n\r");
 
 
-    // try to detect Window-Shutter
-
-    rf22.setModemRegisters(&config);
-    rf22.setFrequency(868.3, 0.035);
-    /* Disable TX packet control, since the RF22 doesn't do proper
-     * whitening so can't read the length header or CRC. We need RX packet
-     * control so the RF22 actually sends pkvalid interrupts when the
-     * manually set packet length is reached. */
-    rf22.spiWrite(RF22_REG_30_DATA_ACCESS_CONTROL, RF22_MSBFRST | RF22_ENPACRX);
-    /* No packet headers, 4 sync words, fixed packet length */
-    rf22.spiWrite(RF22_REG_32_HEADER_CONTROL1, RF22_BCEN_NONE | RF22_HDCH_NONE);
-    rf22.spiWrite(RF22_REG_33_HEADER_CONTROL2, RF22_HDLEN_0 | RF22_FIXPKLEN | RF22_SYNCLEN_4);
-    rf22.setSyncWords(sync_words, lengthof(sync_words));
-    /* Detect preamble after 4 nibbles */
-    rf22.spiWrite(RF22_REG_35_PREAMBLE_DETECTION_CONTROL1, (0x4 << 3));
-    /* Send 8 bytes of preamble */
-    rf22.setPreambleLength(8); // in nibbles
-    rf22.spiWrite(RF22_REG_3E_PACKET_LENGTH, 30); // maximum length of a MAX!-packet
-
-
     rf22.setModeRx();
 
 
+    SendTicker.attach(&Ticker_isr, 5.0); // Send every 5 seconds
 
     //wait forever and see what comes in
     while (1) {
 
-        // look for a message
-        MyMessage = max_rx_msg();
         // did we get a MAX!-Message?
-        if (MyMessage.len > 0) {
+        if (rf22.recv_max(&MyMessage)) {
             // we got a message
-            pc.printf("Got Message type: %s Msg-Nr:%i from Device-ID:%06X State:%s Battery %s\n\r", MyMessage.type_str,MyMessage.cnt, MyMessage.frm_adr, MyMessage.state, MyMessage.battery_state);
+            led2 = !led2;
+            sprintf(lcdline,"Got Message type: %s Msg-Nr:%i from Device-ID:%06X State:%s Battery %s", MyMessage.type_str,MyMessage.cnt, MyMessage.frm_adr, MyMessage.state, MyMessage.battery_state);
+            pc.printf("%s\n\r",lcdline);
+            lcd.setLine(0,lcdline);
 
-            // should we send an KNX-command?
-            strcpy(group ,"");
-            for (i=0; i< MAX_KNX_MAPPINGS; i++) {
-                if (max_knx_map[i].device_id == MyMessage.frm_adr) {
-                    strcpy(group ,max_knx_map[i].knx_adr);
-                }
-            }
+        }
 
-            if (strlen(group) > 0) {
-                sprintf(command, "fbs01/%s=%s\r",group,(strcmp(MyMessage.state,"auto")) ? "0" : "1");  // EIS01 on Group-address group : auto=1 eco=0
-                // Send a KNX-Telegramm
-                knxrs.printf("%s",command);
-                pc.printf("%s\n\r",command);
-                sprintf(lcdline,"Got Message type: %s Msg-Nr:%i from Device-ID:%06X State:%s Battery %s. Sending to KNX:%s",
-                              MyMessage.type_str,MyMessage.cnt, MyMessage.frm_adr, MyMessage.state, MyMessage.battery_state,command);
-                lcd.setLine(1,lcdline);
+        if (doSend) {
+            //we should send something
+            doSend = 0;
+            led4=1;
+            // try to send a simulated window-shutterContact-message
+            // wait some time
+            sbuf[0] = 11; // MsgLen
+            sbuf[1] = 0x21; // MsgCount ??
+            sbuf[2] = 0x00; // Flag
+            sbuf[3] = 0x30; // Type = Cmd = ShutterContactState
+            sbuf[4] = 0x11; // From Fake Address
+            sbuf[5] = 0x11; // From
+            sbuf[6] = 0x11; // From
+            sbuf[7] = 0x00; // To Address : broadcast
+            sbuf[8] = 0x00;
+            sbuf[9] = 0x00;
+            sbuf[10] = 0x00; // GroupId
+            sbuf[11] = 0x02;  //Payload is 0x02: State Open, Battery: good
+            slen = 12+2; //+2Byte CRC????
+            /* Calculate CRC */
+            uint16_t scrc = rf22.calc_crc(sbuf, slen - 2);
+            sbuf[12] = scrc >> 8;
+            sbuf[13] = scrc & 0xff;
+
+
+            if (rf22.send(sbuf,slen)) {
+#ifdef DEBUG
+                pc.printf("Send window-shutterContact-message OK\n\r");
+#endif
             } else {
-                // device not found in mapping
-                pc.printf("new unknown device!\n\r");
-                sprintf(lcdline,"Got Message type: %s Msg-Nr:%i from Device-ID:%06X State:%s Battery %s. Unknown New Device",
-                              MyMessage.type_str,MyMessage.cnt, MyMessage.frm_adr, MyMessage.state, MyMessage.battery_state);
-                lcd.setLine(1,lcdline);
+#ifdef DEBUG
+                pc.printf("Send window-shutterContact-message NOT OK\n\r");
+#endif
             }
+            led4 = 0;
 
         }
 
--- a/mbed.bld	Mon Sep 09 19:47:45 2013 +0000
+++ b/mbed.bld	Tue Oct 22 19:43:01 2013 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/9c8f0e3462fb
\ No newline at end of file
+http://mbed.org/users/mbed_official/code/mbed/builds/a9913a65894f
\ No newline at end of file