void displayMessages() { spiPoll(); if (znpBuf[SRSP_LENGTH_FIELD] > 0) { if (IS_AF_INCOMING_MESSAGE()) { setLed(1); //LED will blink to indicate a message was received #ifdef VERBOSE_MESSAGE_DISPLAY printAfIncomingMsgHeader(znpBuf); printf("\r\n"); #endif if (IS_INFO_MESSAGE_CLUSTER()) { struct infoMessage im = deserializeInfoMessage(znpBuf+20); #ifdef VERBOSE_MESSAGE_DISPLAY printInfoMessage(&im); #else printf("From:"); for (int j = 0; j<8; j++) { printf("%02X", im.header->mac[j]); } printf(",LQI=%02X", znpBuf[SRSP_HEADER_SIZE+9]); #endif if (im.numParameters > 0) { printf(";PanID:%04X", im.parameters[0]); if (im.numParameters == 3) //panId, vcc3v, light sensor (lux/10) { printf(",Vcc3=%umV,Light Sensor(lux)=%u,Cause=", im.parameters[1], im.parameters[2] * 10); switch (im.cause) { case CAUSE_SCHEDULED: printf("Timer"); break; case CAUSE_MOTION: printf("Motion"); break; case CAUSE_STARTUP: printf("Startup"); break; } } printf("\r\n"); } } else { printf("Rx: "); printHexBytes(znpBuf+SRSP_HEADER_SIZE+17, znpBuf[SRSP_HEADER_SIZE+16]); //print out message payload } clearLeds(); } else { //unknown message, just print out the whole thing printf("??: "); printHexBytes(znpBuf, (znpBuf[SRSP_LENGTH_FIELD] + SRSP_HEADER_SIZE)); } znpBuf[SRSP_LENGTH_FIELD] = 0; } }
void stateMachine() { while (1) { if (zigbeeNetworkStatus == NWK_ONLINE) { if(moduleHasMessageWaiting()) //wait until SRDY goes low indicating a message has been received. { getMessage(); displayMessage(); } } switch (state) { case STATE_IDLE: { if (stateFlags & STATE_FLAG_SEND_INFO_MESSAGE) //if there is a pending info message to be sent { state = STATE_SEND_INFO_MESSAGE; //then send the message and clear the flag stateFlags &= ~STATE_FLAG_SEND_INFO_MESSAGE; } /* Other flags (for different messages or events) can be added here */ break; } case STATE_MODULE_STARTUP: { #define MODULE_START_DELAY_IF_FAIL_MS 5000 // Must be greater than MODULE_START_FAIL_LED_ONTIME moduleResult_t result; struct moduleConfiguration defaultConfiguration = DEFAULT_MODULE_CONFIGURATION_END_DEVICE; /* Uncomment below to restrict the device to a specific PANID defaultConfiguration.panId = 0x1234; */ struct applicationConfiguration endDeviceConf; endDeviceConf.endPoint = 1; endDeviceConf.latencyRequested = LATENCY_NORMAL; endDeviceConf.profileId = 0xcc00; // the clock profile is 0xCC00 endDeviceConf.deviceId = 0x8866; endDeviceConf.deviceVersion = 0x01; endDeviceConf.numberOfBindingInputClusters = 4; // number of binding input cluster endDeviceConf.bindingInputClusters[0] = 0x0000; // basic cluster endDeviceConf.bindingInputClusters[1] = 0x0003; // identify cluster endDeviceConf.bindingInputClusters[2] = 0xfc01; // synchronise clock cluster endDeviceConf.bindingInputClusters[3] = 0xfc02; // send string message cluster endDeviceConf.numberOfBindingOutputClusters = 4; // number of binding output cluster endDeviceConf.bindingOutputClusters[0] = 0x0000; endDeviceConf.bindingOutputClusters[1] = 0x0003; endDeviceConf.bindingOutputClusters[2] = 0xfc01; endDeviceConf.bindingOutputClusters[3] = 0xfc02; struct applicationConfiguration ac; ac.endPoint = 1; ac.deviceVersion = 0x10; ac.profileId = 0xfafa; ac.latencyRequested = LATENCY_NORMAL; ac.numberOfBindingInputClusters = 2; ac.bindingInputClusters[0] = 0x0000; ac.bindingInputClusters[1] = 0x0900; ac.numberOfBindingOutputClusters = 2; ac.bindingOutputClusters[0] = 0x0000; ac.bindingOutputClusters[1] = 0x0900; /* Below is an example of how to restrict the device to only one channel: defaultConfiguration.channelMask = CHANNEL_MASK_17; printf("DEMO - USING CUSTOM CHANNEL 17\r\n"); */ //while ((result = startModule(&defaultConfiguration, GENERIC_APPLICATION_CONFIGURATION)) != MODULE_SUCCESS) while ((result = startModule(&defaultConfiguration, &ac)) != MODULE_SUCCESS) { SET_NETWORK_FAILURE_LED_ON(); // Turn on the LED to show failure printf("FAILED. Error Code 0x%02X. Retrying...\r\n", result); delayMs(MODULE_START_DELAY_IF_FAIL_MS/2); SET_NETWORK_FAILURE_LED_OFF(); delayMs(MODULE_START_DELAY_IF_FAIL_MS/2); } INIT_BOOSTER_PACK_LEDS(); SET_NETWORK_LED_ON(); SET_NETWORK_FAILURE_LED_OFF(); printf("Success\r\n"); /* Module is now initialized so store MAC Address */ zbGetDeviceInfo(DIP_MAC_ADDRESS); memcpy(hdr.mac, zmBuf+SRSP_DIP_VALUE_FIELD, 8); #define MESSAGE_PERIOD_SECONDS 4 int16_t timerResult = initTimer(MESSAGE_PERIOD_SECONDS); if (timerResult != 0) { printf("timerResult Error %d, STOPPING\r\n", timerResult); while (1); } state = STATE_DISPLAY_NETWORK_INFORMATION; break; } case STATE_DISPLAY_NETWORK_INFORMATION: { printf("~ni~"); /* On network, display info about this network */ displayNetworkConfigurationParameters(); displayDeviceInformation(); /* Set module GPIOs as output and turn them off */ if ((sysGpio(GPIO_SET_DIRECTION, ALL_GPIO_PINS) != MODULE_SUCCESS) || (sysGpio(GPIO_CLEAR, ALL_GPIO_PINS) != MODULE_SUCCESS)) { printf("ERROR\r\n"); } state = STATE_SEND_INFO_MESSAGE; break; } case STATE_SEND_INFO_MESSAGE: { printf("~im~"); struct infoMessage im; /* See infoMessage.h for description of these info message fields.*/ im.header = hdr; im.deviceType = DEVICETYPE_TESLA_CONTROLS_END_DEVICE_DEMO; im.header.sequence = sequenceNumber++; im.numParameters = getSensorValues(im.kvps); // Does two things: Loads infoMessage with sensor value KVPs and gets the number of them // now, add status message interval im.kvps[im.numParameters].oid = OID_STATUS_MESSAGE_INTERVAL; im.kvps[im.numParameters].value = MESSAGE_PERIOD_SECONDS; im.numParameters++; // add zigbee module information: if (sysVersion() != MODULE_SUCCESS) { printf("ERROR retriving module information\r\n"); } else { displaySysVersion(); // Product ID im.kvps[im.numParameters].oid = OID_MODULE_PRODUCT_ID; im.kvps[im.numParameters].value = zmBuf[SYS_VERSION_RESULT_PRODUCTID_FIELD]; im.numParameters++; // FW - Major im.kvps[im.numParameters].oid = OID_MODULE_FIRMWARE_MAJOR; im.kvps[im.numParameters].value = zmBuf[SYS_VERSION_RESULT_FW_MAJOR_FIELD]; im.numParameters++; // FW - Minor im.kvps[im.numParameters].oid = OID_MODULE_FIRMWARE_MINOR; im.kvps[im.numParameters].value = zmBuf[SYS_VERSION_RESULT_FW_MINOR_FIELD]; im.numParameters++; // FW - Build im.kvps[im.numParameters].oid = OID_MODULE_FIRMWARE_BUILD; im.kvps[im.numParameters].value = zmBuf[SYS_VERSION_RESULT_FW_BUILD_FIELD]; im.numParameters++; } printInfoMessage(&im); #define RESTART_DELAY_IF_MESSAGE_FAIL_MS 5000 uint8_t messageBuffer[MAX_INFO_MESSAGE_SIZE]; serializeInfoMessage(&im, messageBuffer); setLed(SEND_MESSAGE_LED); //indicate that we are sending a message moduleResult_t result = afSendData(DEFAULT_ENDPOINT, DEFAULT_ENDPOINT, 0, INFO_MESSAGE_CLUSTER, messageBuffer, getSizeOfInfoMessage(&im)); // and send it clearLed(SEND_MESSAGE_LED); if (result != MODULE_SUCCESS) { zigbeeNetworkStatus = NWK_OFFLINE; printf("afSendData error %02X; restarting...\r\n", result); delayMs(RESTART_DELAY_IF_MESSAGE_FAIL_MS); //allow enough time for coordinator to fully restart, if that caused our problem state = STATE_MODULE_STARTUP; } else { printf("Success\r\n"); state = STATE_IDLE; } break; } default: //should never happen { printf("UNKNOWN STATE\r\n"); state = STATE_MODULE_STARTUP; } break; } } }
/** Parse any received messages. If it's one of our OIDs then display the value on the RGB LED too. */ void parseMessages() { getMessage(); if ((zmBuf[SRSP_LENGTH_FIELD] > 0) && (IS_AF_INCOMING_MESSAGE())) { setLed(4); //LED will blink to indicate a message was received #ifdef VERBOSE_MESSAGE_DISPLAY printAfIncomingMsgHeader(zmBuf); printf("\r\n"); #endif if ((AF_INCOMING_MESSAGE_CLUSTER()) == INFO_MESSAGE_CLUSTER) { struct infoMessage im; deserializeInfoMessage(zmBuf+20, &im); // Convert the bytes into a Message struct int j = 0; #ifdef VERBOSE_MESSAGE_DISPLAY printInfoMessage(&im); displayZmBuf(); #else printf("From:"); // Display the sender's MAC address for (j = 7; j>(-1); j--) { printf("%02X", im.header.mac[j]); } int k; for (k = 0; k < NUM_DEVICES; k++) { int match = 1; for (j = 7; j>(-1); j--) { if (routers[k].MAC_address[j] != im.header.mac[j]) { match = 0; } } if (match == 1) { current_router_index = k; routers[current_router_index].LQI = zmBuf[AF_INCOMING_MESSAGE_LQI_FIELD]; } } printf(", LQI=%02X, ", zmBuf[AF_INCOMING_MESSAGE_LQI_FIELD]); // Display the received signal quality (Link Quality Indicator) //LQI = zmBuf[AF_INCOMING_MESSAGE_LQI_FIELD]; #endif printf("%u KVPs received:\r\n", im.numParameters); #define NO_VALUE_RECEIVED 0xFF uint8_t redIndex = NO_VALUE_RECEIVED; uint8_t blueIndex = NO_VALUE_RECEIVED; uint8_t greenIndex = NO_VALUE_RECEIVED; for (j=0; j<im.numParameters; j++) // Iterate through all the received KVPs { printf(" %s (0x%02X) = %d ", getOidName(im.kvps[j].oid), im.kvps[j].oid, im.kvps[j].value); // Display the Key & Value displayFormattedOidValue(im.kvps[j].oid, im.kvps[j].value); printf("\r\n"); // If the received OID was an IR temperature OID then we can just display it on the LED if ((rgbLedDisplayMode == RGB_LED_DISPLAY_MODE_TEMP_IR) && (im.kvps[j].oid == OID_TEMPERATURE_IR)) displayTemperatureOnRgbLed(im.kvps[j].value); // But for the color sensor we need to get all three values before displaying else if (im.kvps[j].oid == OID_COLOR_SENSOR_RED) redIndex = j; else if (im.kvps[j].oid == OID_COLOR_SENSOR_BLUE) blueIndex = j; else if (im.kvps[j].oid == OID_COLOR_SENSOR_GREEN) greenIndex = j; } // Now done iterating through all KVPs. If we received color then update RGB LED #define RED_VALUE (im.kvps[redIndex].value) #define BLUE_VALUE (im.kvps[blueIndex].value) #define GREEN_VALUE (im.kvps[greenIndex].value) if ((rgbLedDisplayMode == RGB_LED_DISPLAY_MODE_COLOR) && ((redIndex != NO_VALUE_RECEIVED) && (blueIndex != NO_VALUE_RECEIVED) && (greenIndex != NO_VALUE_RECEIVED))) { displayColorOnRgbLed(RED_VALUE, BLUE_VALUE, GREEN_VALUE); } printf("\r\n"); } else { printf("Rx: "); printHexBytes(zmBuf+SRSP_HEADER_SIZE+17, zmBuf[SRSP_HEADER_SIZE+16]); //print out message payload } clearLeds(0); } else if (IS_ZDO_END_DEVICE_ANNCE_IND()) { displayZdoEndDeviceAnnounce(zmBuf); } else { //unknown message, just print out the whole thing printf("MSG: "); printHexBytes(zmBuf, (zmBuf[SRSP_LENGTH_FIELD] + SRSP_HEADER_SIZE)); } zmBuf[SRSP_LENGTH_FIELD] = 0; }
/** Converts the message payload in zmBuf to a struct infoMessage and then displays it. In a more advanced application, you may want to store this or perform additional processing on the parameters in the message. */ static void processInfoMessage() { struct infoMessage im; deserializeInfoMessage(zmBuf+20, &im); // Convert the bytes into a Message struct printInfoMessage(&im); }
void stateMachine() { while (1) { switch (state) { case STATE_IDLE: { if (stateFlags & STATE_FLAG_SEND_INFO_MESSAGE) //if there is a pending info message to be sent { state = STATE_SEND_INFO_MESSAGE; //then send the message and clear the flag stateFlags &= ~STATE_FLAG_SEND_INFO_MESSAGE; } //note: other flags (for different messages or events) can be added here break; } case STATE_ZNP_STARTUP: { #define ZNP_START_DELAY_IF_FAIL_MS 5000 /* Start the network; if fails then wait a second and try again. */ signed int startResult = startZnp(END_DEVICE); while (startResult != ZNP_SUCCESS) { printf("FAILED. Error Code %i, ZNP Result %i. Retrying...\r\n", startResult, znpResult); delayMs(ZNP_START_DELAY_IF_FAIL_MS); startResult = startZnp(END_DEVICE); } printf("Success\r\n"); //ZNP Initialized so store MAC Address memcpy(hdr.mac, getMacAddress(), 8); #ifdef SEND_MESSAGE_ON_TIMER signed int timerResult = initTimer(4, WAKEUP_AFTER_TIMER); if (timerResult != 0) { printf("timerResult Error %i, STOPPING\r\n", timerResult); while (1); } #endif state = STATE_DISPLAY_NETWORK_INFORMATION; break; } case STATE_DISPLAY_NETWORK_INFORMATION: { printf("~ni~"); /* On network, display info about this network */ getNetworkConfigurationParameters(); getDeviceInformation(); state = STATE_SEND_INFO_MESSAGE; break; } case STATE_SEND_INFO_MESSAGE: { printf("~im~"); setLed(1); im.header->sequence = sequenceNumber++; im.cause = infoMessageCause; unsigned char* panid = getDeviceInformationProperty(DIP_PANID); im.parameters[0] = CONVERT_TO_INT(*panid, *(panid+1)); //PAN ID im.parameters[1] = getVcc3(); //VCC im.parameters[2] = getLightSensor(); //Light Sensor printInfoMessage(&im); #define ZNP_RESTART_DELAY_IF_MESSAGE_FAIL_MS 5000 unsigned char msgBuf[100]; serializeInfoMessage(&im, msgBuf); afSendData(DEFAULT_ENDPOINT,DEFAULT_ENDPOINT,0, INFO_MESSAGE_CLUSTER, msgBuf, getSizeOfInfoMessage(&im)); if (znpResult != ZNP_SUCCESS) { printf("afSendData error %i; restarting...\r\n", znpResult); delayMs(ZNP_RESTART_DELAY_IF_MESSAGE_FAIL_MS); //allow enough time for coordinator to fully restart, if that caused our problem state = STATE_ZNP_STARTUP; } else { state = STATE_IDLE; clearLeds(); HAL_SLEEP(); } break; } default: //should never happen { printf("UNKNOWN STATE\r\n"); state = STATE_ZNP_STARTUP; } break; } } }