dump xbee stats =============== read rf-errors read good-packets read tx-errors read tx-ack-errors # does not work read rx-signal-strength read duty-cycle read rssi-for-channel # does not work configure xbee module ===================== write bcast-multi-xmit 0 write unicast-retries 0 write power-level 0 radio protocol ============== - tout en network order - avoir le paquet le plus petit possible - grouper les informations en un paquet si possible. certaines infos non critiques pourraient attendre en file qu'un paquet de même puissance sorte Octet 1: type - si type est < 0x3f, alors il s'agit du bitmask des servos qui seront présents dans le corps. Les servos sont présents par blocs de 10bits. la puissance d'émission est également embarquée sur 3 bits. Cette commande doit être bien compacte car c'est celle qui va être envoyée le plus souvent. Exemple, on veut envoyer le servo 0 (=0x123) et 4 (=0x234). Puissance = 2. type = 0x5 seq_num sur 5 bits puis pow sur 3 bits puis val[0] sur 10 bits puis val[2] sur 10 bits padding à 0 pour arondir sur un octet -> 0x11 0x9 0x1c 0x68 - sinon, type correspond à la commande qui est mappée sur une structure rc_command ---------- - on récupère l'état du PPM provenant de la télécommande en tache de fond (période 20ms pour chaque servo, et les servos arrivent les uns après les autres) - toutes les 1 à 5ms - on compare les valeurs ppm aux dernières valeurs envoyées: si elles sont différentes: - on les stoque en mémoire dans "valeurs à envoyer" - on incrémente un numéro de séquence de cette structure sauf si le dernier numéro d'acquitement reçu est trop ancien - si le numéro de séquence est différent du numéro de seq reçu, et que le dernier paquet a été émis il y a plus de 30ms, on émet les nouvelles valeurs et le numéro de séquence local - lorsqu'on reçoit un paquet d'acquitement, on stoque le numéro de séquence - lorsqu'on reçoit un paquet de stats, on le traite (affichage, beep, log, osd) - lorsqu'on reçoit un paquet de "ping", on note le RSSI et la puissance à laquelle il a été émis. - la puissance d'émission est choisi avec l'algorithme suivant: - si on n'a pas reçu d'acquitement ou de ping depuis 500ms, alors on émet alternativement à 0 et 4. - sinon, on émet à la puissance la plus faible qui a un RSSI supérieur à un seuil, ce que l'on peut déterminer grâce au ping. wing ---- - lorsqu'on reçoit un paquet de commande - on met à jour les valeurs des servos - si le dernier paquet d'acquitement a été émis il y a plus de 200ms on émet un paquet d'acquitement. La puissance d'émission du paquet d'acquitement est la même que la puissance du paquet reçu. - toutes les 500ms, on émet un paquet de "ping" à une puissance différente (0 à 4). La puissance est contenue dans le message. - toutes les 100ms, on émet un paquet de stats à la puissance du dernier paquet reçu. interrupt, software interrupts and background tasks =================================================== problem description ------------------- Today, both command line code, xbee char reception and callout events are handled in the main loop, with the lowest priority. Therefore, the command line cannot block, else the timers + xbee rx won't be executed. A typical example where the command line blocks is the completion with many choices. solution -------- xbee rx and timers should be executed in a low prio scheduler event. With this modification, the command line can block. However we must prevent a xbee transmission to be interrupted by a task doing another xbee transmission. For that, we will use scheduler_set_prio(). The problem with that is that we can loose precision for low prio events if the scheduler interrupt occurs when the scheduler priority is low. It could be fixed in scheduler, but maybe we don't need it. Priorities ---------- From highest to lowest priority. - Interrupts: - timer - uart - spi - i2c - Events, called from timer interrupt after a call to sei(): - LED_PRIO: led blink - BEEP_PRIO: process beep requests and modifies the beep_mask - SPI_PRIO: send and receive SPI data to the atmega168p - CS_PRIO: do the control system of the wing, reading infos from a structure updated by i2c, and writing commands using spi_set_servo() - XBEE_PRIO: read pending chars on xbee serial line and process xbee commands, send xbee commands. - I2C_PRIO: send requests and read answers on i2c slaves - CALLOUT_PRIO: calls low priority events using the callout code. This method allows to execute timers with a fixed period without drift. Even if the event cannot be executed during some time, periodical events will keep the proper period. - Main loop: - command line Rules ----- Calling a xbee function needs to set prio to XBEE_PRIO only. Calling i2c_send_command must be done from a lower prio than I2C_PRIO. libxbee / xbee module ===================== Library ------- xbee_dev = structure describing an xbee device xbee_channel = structure describing a channel, used to associates a req with its answer xbee.[ch]: main interface to libxbee, creation of dev, registeration of channels xbee_atcmd.[ch]: get an AT command from its name or small id string xbee_buf.[ch]: not used xbee_neighbor.[ch]: helper to add/delete neighbors, use malloc()/free() xbee_rxtx.[ch]: parse rx frames, provides xbee_proto_xmit() xbee_stats.[ch]: helper to maintain stats App --- move this in library ? xbeeapp_send(addr, data, len, timeout, cb, arg) XXX to detail Timeout for xbee commands ========================= - send_atcmd or send_msg (xbee_prio) - allocate a channel and a context - fill the context with info - send the message - load a timeout (xbee_prio) - on timeout (xbee_prio) - log error - call the cb with retcode == TIMEOUT - unregister channel - remove timer - this could be a critical error - if it's a comm error, it's ok - but if the channel is registered again and 1st callback finally occurs... - on rx (xbee_prio) - if there is a context, it's related to a query: - remove the timeout - unregister channel - do basic checks on the frame - log (hexdump) - the frame must be checked in the cb, we can provide helpers Tests to do =========== :: Radio Controller ))) xbee ((( WING / / PC with command line (through serial) Test 1: send data, unidirectional --------------------------------- Periodically send data from RC to WING (every 20 to 100 ms). The WING sends its statistics every second. Variables: - period: from 20ms to 200ms - packet size: from 1 byte to 20 bytes - total number of packets: 1K for short tests, 100K for robustness If the test is long, take care about maximum duty cycles (10%). Output: - local and peer statistics for each test (packet size, pps, number of packets) - at the end we will know what is the highest speed we can support for a given packet size, and how reliable is the xbee Test 2: send data, bidirectional -------------------------------- Same than above, except that the WING replies to each received packet with a packet of same size. Same kind of output, ans also measure latency. Test 3: test wing control on ground ----------------------------------- On the ground, try to control the wing with the RC board. We also use the 2.4 Ghz controller as a fallback (bypass mode). Check that the bypass mode is enabled when we ask it (for instance on the channnel 5 switch) or when we switch off the RC board. Test 4: embed in WING and send hello ------------------------------------ The WING board is embeded during a flight. The RC board sends hello message at a specified rate (choosen from results of test 1 and 2). The WING sends statistics. Check how the wing distance impacts: - the statistics - the RX DB Maybe check with and without the 433Mhz beacon. Test 5: embed in WING and send dummy servo commands --------------------------------------------------- Test in real conditions: the WING board is embeded during a flight. The RC board sends dummy servo values at a specified rate (choosen from results of test 1 and 2). The WING sends statistics and "power probes" allowing the RC board to choose its tx power level. Check how the wing distance impacts: - the tx power level of the RC board - the statistics - the RX DB Maybe check with and without the 433Mhz beacon. Output: After this test, we should be confident that xbee is useable in real conditions. Test 6: control the wing with the RC board ------------------------------------------ Same than test 3, but in real flight conditions. ----------------------- test report =========== test1 ===== no stats sent from wing (except if contrary specified) don't forget to run read duty-cycle to reset duty-cycle, use "write soft-reset" Be careful, some packets are dropped even with power level = 0 due to over power. Need to use a faraday cage. 50ms ------- 1 byte per msg 20B/s (160b/s) of useful bandwidth mainboard > rc_proto_hello wing 50 1000 x 1000/1000 1000/1000 1000/1000 each test (50s) eats ~5% of duty cycle 10 bytes per msg 200B/s (1.6Kb/s) of useful bandwidth mainboard > rc_proto_hello wing 50 1000 0123456789 with stats send every second: 950/1000 994/1000 950/1000 1000/1000 999/1000 without stats: 1000/1000 1000/1000 1000/1000 20 bytes per msg 400B/s (3.2Kb/s) of useful bandwidth mainboard > rc_proto_hello wing 50 1000 01234567890123456789 1000/1000 1000/1000 40 ms ------- 1 byte per msg 25B/s (200b/s) of useful bandwidth mainboard > rc_proto_hello wing 40 1000 x 1000/1000 1000/1000 1000/1000 10 bytes per msg 250B/s (2Kb/s) of useful bandwidth mainboard > rc_proto_hello wing 40 1000 0123456789 998/1000 1000/1000 1000/1000 20 bytes per msg 500B/s (4Kb/s) of useful bandwidth mainboard > rc_proto_hello wing 40 1000 01234567890123456789 1000/1000 1000/1000 1000/1000 30 ms ------- 1 byte per msg 33B/s (300b/s) of useful bandwidth mainboard > rc_proto_hello wing 30 1000 x 1000/1000 1000/1000 1000/1000 10 bytes per msg 333B/s (3Kb/s) of useful bandwidth mainboard > rc_proto_hello wing 30 1000 0123456789 1000/1000 1000/1000 1000/1000 20 bytes per msg 666B/s (6Kb/s) of useful bandwidth mainboard > rc_proto_hello wing 30 1000 01234567890123456789 1000/1000 1000/1000 1000/1000 20 ms ------- 1 byte per msg 50B/s (400b/s) of useful bandwidth mainboard > rc_proto_hello wing 20 1000 x 991/1000 991/1000 991/1000 10 bytes per msg 500B/s (4Kb/s) of useful bandwidth mainboard > rc_proto_hello wing 20 1000 0123456789 863/1000 864/1000 864/1000 20 bytes per msg 1000B/s (8Kb/s) of useful bandwidth mainboard > rc_proto_hello wing 20 1000 01234567890123456789 763/1000 763/1000 763/1000 25 ms ------- 1 byte per msg 40B/s (320b/s) of useful bandwidth mainboard > rc_proto_hello wing 25 1000 x 1000/1000 1000/1000 1000/1000 10 bytes per msg 400B/s (3.2Kb/s) of useful bandwidth mainboard > rc_proto_hello wing 25 1000 0123456789 1000/1000 1000/1000 1000/1000 20 bytes per msg 800B/s (6.4Kb/s) of useful bandwidth mainboard > rc_proto_hello wing 25 1000 01234567890123456789 950/1000 950/1000 950/1000 With stats =============== 25 ms ------- 1 byte per msg 40B/s (320b/s) of useful bandwidth mainboard > rc_proto_hello wing 25 1000 x 1000/1000 952/1000 1000/1000 10 bytes per msg 400B/s (3.2Kb/s) of useful bandwidth mainboard > rc_proto_hello wing 25 1000 0123456789 966/1000 974/1000 964/1000 20 bytes per msg 800B/s (6.4Kb/s) of useful bandwidth mainboard > rc_proto_hello wing 25 1000 01234567890123456789 898/1000 898/1000