====== ZigBee ====== //The necessary knowledge: [HW] [[en:hardware:homelab:controller]], [AVR] [[en:avr:usart]], [LIB] [[en:software:homelab:library:usart]], \\ [LIB] [[en:software:homelab:library:module:lcd_graphic]]// ===== Theory ===== [{{ ::examples:communication:xbee.jpg?220|XBee module.}}] ZigBee is a specification for high level communication protocols using small, low-power digital radios based on an IEEE 802.15.4-2003 standard for personal area networks. ZigBee is designed for devices which require simple wireless networking and don't need high data transfer rate. These devices might be for example sensor network, information displays, home- and industrial automatic systems, etc. Main benefit compared with Bluetooth is lower power demand, quick respond from sleep to awake and cost. ZigBee works in most cases at 2.4 GHz radio band frequency with data transmission rates from 20 to 900 kb/s. ZigBee protocol supports different types of network like star, tree and generic mesh. Network nodes can have different roles like coordinator, router or end device. Based on ZigBee wireless modules direct connection between two devices or more complicated network can be set up. In figure below a sensor network transferring measurement to user interface is illustrated. ===== Practice ===== Robotic HomeLab Communication board has a connector for wireless modules, including ZigBee module XBee from Maxtream. Communication between module and the controller is realized over UART interface. At first device is set to API mode by sending command "+++". Further configuration is done with standard AT command found on device manual. When communication between two modules has been established, device will be returned to transfer mode. Example code above is searching surroundings for other Zigbee devices and found device addresses devices are displayed on Homelab User Interface module LCD display. Global address 0000FFFF has a special meaning - info sent to this address is received by all available devices. In the example code, after searching other devices one is connected and devices start to sending a button pressing event to each other by showing the result on the other device LED. #include #include #include #include //Adding ZigBee module support #include // Determination of the USART interface usart port = USART(1); // LED and button pin setup pin leds[3] = { PIN(C, 5), PIN(C, 4), PIN(C, 3) }; pin buttons[3] = { PIN(C, 0), PIN(C, 1), PIN(C, 2) }; // Max numbers of ZigBee modules in network + broadcast address +1 #define ZIGBEE_MAX_NODES 4 int8_t wait_button(uint16_t ms); // Address array of other Zigbee modules found in network zigbee_node_t nodelist[ZIGBEE_MAX_NODES]; int main(void) { uint8_t adr = 0; //Acquired module order list // LED and buttons I/O ports configuration for (int i=0; i<3; i++) { pin_setup_output(leds[i]); pin_setup_input(buttons[i]); } // Configuration of USART interface for communication whit ZigBee module usart_init_async(port, USART_DATABITS_8, USART_STOPBITS_ONE, USART_PARITY_NONE, USART_BAUDRATE_ASYNC(9600)); // LCD display initalization lcd_gfx_init(); // Clear LCD lcd_gfx_clear(); // Turning back light ON lcd_gfx_backlight(true); //Wait until other ZigBee modules are searched from area near by lcd_gfx_clear(); lcd_gfx_goto_char_xy(0, 0); lcd_gfx_write_string(" ZigBee demo"); lcd_gfx_goto_char_xy(0, 1); lcd_gfx_write_string("Searching..."); // Searching other ZigBee modules // fills nodelist array with found modules info zigbee_find_nodes(port, nodelist, ZIGBEE_MAX_NODES); //lcd_gfx_clear(); lcd_gfx_goto_char_xy(0, 1); lcd_gfx_write_string("Found: "); // Displays the list of found modules on LCD // (on what line to write, where takes addr., how many max) zigbee_lcd_show_nodes(2, nodelist, ZIGBEE_MAX_NODES); hw_delay_ms(3000); lcd_gfx_clear(); // Displaying connecting on LCD lcd_gfx_goto_char_xy(0, 0); lcd_gfx_write_string("Connecting..."); lcd_gfx_goto_char_xy(0, 1); //Displays only 8 last digit form the address lcd_gfx_write_string((nodelist + adr)->address64l); // Confederate ZigBee to send info for chosen ZigBee module's node, // in this case to first [0] // (What port is using, where takes the address) zigbee_set_destination(port, &nodelist[adr]); // Displays info on LCD lcd_gfx_goto_char_xy(0, 0); lcd_gfx_write_string(" ZigBee demo"); lcd_gfx_goto_char_xy(0, 1); lcd_gfx_write_string("Button1: LED1"); lcd_gfx_goto_char_xy(0, 2); lcd_gfx_write_string("Button2: LED2"); // Save the state of previous button to avoid multiple button pushes at once. // At first is -1 ie none of the buttons is pushed. int8_t previousButton = -1; // Endles-loop for communicating between modules while (true) { int8_t button; //variable for saving button pushes // wait 1 millisecond for button button = wait_button(1); // if in last cycle button wasn't pressed but now is if (previousButton == -1 && button != -1) { // Convert button's index by adding A // and sent it to other modules // A is for first button, B for second and so on usart_send_char(port, 'A' + button); } // read from USART if (usart_has_data(port)) { // Read bait, convert to leds array index //and change the output. pin_toggle(leds[usart_read_char(port) - 'A']); } // remember what button was pressed previousButton = button; } } // Wait for button to be pressed for ms milliseconds. //If button is pressed returns the queue number of the button int8_t wait_button(uint16_t ms) { // By default -1 means, that no button is pressed. int8_t button_nr = -1; uint16_t counter = 0; do { // check if one of the buttons is pressed for (uint8_t i=0; i<3; i++) { if (!pin_get_value(buttons[i])) { button_nr = i; break; } } // wait for 1 millisecond hw_delay_ms(1); // increase millisecond counter counter++; } while (button_nr == -1 && (counter < ms)); return button_nr; }