I use the Transmit Request frame (0x10). A real life Arduino example that I constructed recently includes the following code snippet:
static uint8_t frame_id = 1;
uint8_t xbee_frame[ 17 + 9 + 1];
int pos = 0;
/* Compose the frame header for a transmit request (0x10). */
xbee_frame[ pos++ ] = 0x7e;
xbee_frame[ pos++ ] = ( ( sizeof( xbee_frame ) - 4 ) >> 8 ) & 0x00ff;
xbee_frame[ pos++ ] = ( sizeof( xbee_frame ) - 4 ) & 0x00ff;
xbee_frame[ pos++ ] = 0x10;
/* Setup destination address and transmit options. */
xbee_frame[ pos++ ] = frame_id++;
if( frame_id == 0 )
{
frame_id = 1;
}
for ( int i = 0; i < 8; i++ )
{
xbee_frame[ pos++ ] = xbee_address_64[ i ];
}
xbee_frame[ pos++ ] = xbee_address_16[ 0 ];
xbee_frame[ pos++ ] = xbee_address_16[ 1 ];
/* Options: retry/repair enabled, encryption enabled, no extended timeout. */
xbee_frame[ pos++ ] = 0;
xbee_frame[ pos++ ] = 0x20;
/* Add payload. */
pos = pos + add_16_bits_to_payload( &xbee_frame[ pos ], temperature );
pos = pos + add_24_bits_to_payload( &xbee_frame[ pos ], pressure );
pos = pos + add_16_bits_to_payload( &xbee_frame[ pos ], soil_temperature );
pos = pos + add_8_bits_to_payload( &xbee_frame[ pos ], soil_humidity );
pos = pos + add_8_bits_to_payload( &xbee_frame[ pos ], water_barrel_indicators );
/* Compute the checksum. */
uint8_t checksum = 0x00;
for( int i = 3; i < sizeof( xbee_frame ) - 1; i++ )
{
checksum += xbee_frame[ i ];
}
checksum = 0xff - checksum;
xbee_frame[ pos ] = checksum;
/* Copy the frame to the XBee. */
XBEE_SERIAL_PORT.write( xbee_frame, sizeof( xbee_frame ) );