Test program to send MAX!-Messages with a RFM22-Module
Dependencies: RF22 TextLCD TextLCDScroll mbed RF22Max
Diff: main.cpp
- Revision:
- 3:4254b4c3557e
- Parent:
- 2:941c46d37d7e
- Child:
- 4:6c72714f5886
--- a/main.cpp Tue Aug 20 20:22:43 2013 +0000 +++ b/main.cpp Mon Sep 09 19:47:45 2013 +0000 @@ -1,8 +1,10 @@ -// Testprogramm for RFM22B with RF22-Library to read ELV MAX! window Shutter-Contacts +// Testprogramm for RFM22B with RF22-Library to read ELV MAX! window Shutter-Contacts and PushBottons +// Quick and dirty code!!!!!! +// needs refactoring + #include "mbed.h" #include <RF22.h> - #include "TextLCDScroll.h" @@ -10,6 +12,9 @@ Serial pc(USBTX, USBRX); +//Freebus-RS-Interface connected to serial +Serial knxrs(p9, p10); // tx, rx + //TextLCDScroll lcd(p30, p29, p28, p27, p26, p25, TextLCD::LCD16x2); // rs, e, d4-d7 TextLCDScroll lcd(p30, p29, p28, p27, p26, p25, TextLCD::LCD16x2); // rs, e, d4-d7 @@ -19,6 +24,30 @@ 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 ); @@ -232,15 +261,22 @@ } -void max_rx_loop() +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; if (rf22.recv(buf, &len)) { pc.printf("Recv: "); pc.printf("len: %i\n\r",len); - len = 30; // limit message to 30 Bytes as device receives all 255 Bytes + 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); @@ -255,7 +291,7 @@ if (len < 3 || len > lengthof(pn9)) { pc.printf("Packet length too short/long (%i)\n\r",len); - return; + return message; } pc.printf("dewhiten: "); printHex(buf, len, true); @@ -263,15 +299,27 @@ /* 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\n\r"); - return; + pc.printf("CRC error: CRC: %04X\n\r",crc); + //return; } /* Don't use the CRC as data */ len -= 2; uint8_t type = buf[3]; -#if 1 + + 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: "); @@ -289,27 +337,97 @@ 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; @@ -374,24 +492,54 @@ pc.println(""); } */ + pc.printf("\n\r"); -#endif } + return message; } + 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; + int i; + + + + max_knx_mapping_t max_knx_map[MAX_KNX_MAPPINGS]; + + //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 + + + pc.baud(115200); pc.printf("\n\rConnected to mbed\n\r"); - char version_str [80] = "RF22-MAX!-V1.1"; + char version_str [80] = "RF22-MAX!-V2.5"; 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"); @@ -415,18 +563,50 @@ 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, 20); + rf22.spiWrite(RF22_REG_3E_PACKET_LENGTH, 30); // maximum length of a MAX!-packet rf22.setModeRx(); - //wait forever and see if interrrupt occurs(led1) + //wait forever and see what comes in while (1) { - max_rx_loop(); - }; + // look for a message + MyMessage = max_rx_msg(); + // did we get a MAX!-Message? + if (MyMessage.len > 0) { + // 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); + + // 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); + } 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); + } + + } + + } }