--- /dev/null
+<subtitle>Protocol Definitions</subtitle>
+<author>
+ <firstname>Keith</firstname>
+ <surname>Packard</surname>
+ <email>keithp@keithp.com</email>
+</author>
+<date>13 January 2012</date>
+<copyright>
+ <year>2012</year>
+ <holder>Keith Packard</holder>
+</copyright>
+<legalnotice>
+ <para>
+ This document is released under the terms of the
+ <ulink url="http://creativecommons.org/licenses/by-sa/3.0/">
+ Creative Commons ShareAlike 3.0
+ </ulink>
+ license.
+ </para>
+</legalnotice>
+<revhistory>
+ <revision>
+ <revnumber>0.1</revnumber>
+ <date>13 January 2012</date>
+ <revremark>Initial content</revremark>
+ </revision>
+</revhistory>
--- /dev/null
+= AltOS Companion Port
+:doctype: article
+:toc:
+
+== Companion Port
+
+ Many Altus Metrum products come with an eight pin Micro MaTch
+ connector, called the Companion Port. This is often used to
+ program devices using a programming cable. However, it can
+ also be used to connect TeleMetrum to external companion
+ boards (hence the name).
+
+ The Companion Port provides two different functions:
+
+ * Power. Both battery-level and 3.3V regulated power are
+ available. Note that the amount of regulated power is not
+ huge; TeleMetrum contains a 150mA regulator and uses, at
+ peak, about 120mA or so. For applications needing more than
+ a few dozen mA, placing a separate regulator on them and
+ using the battery for power is probably a good idea.
+
+
+ * SPI. The flight computer operates as a SPI master, using
+ a protocol defined in this document. Companion boards
+ provide a matching SPI slave implementation which supplies
+ telemetry information for the radio downlink during flight
+
+== Companion SPI Protocol
+
+ The flight computer implements a SPI master communications
+ channel over the companion port, and uses this to get
+ information about a connected companion board and then to get
+ telemetry data for transmission during flight.
+
+ At startup time, the flight computer sends a setup request
+ packet, and the companion board returns a board identifier,
+ the desired telemetry update period and the number of data
+ channels provided. The flight computer doesn't interpret the
+ telemetry data at all, simply packing it up and sending it
+ over the link. Telemetry packets are 32 bytes long, and
+ companion packets use 8 bytes as a header leaving room for a
+ maximum of 12 16-bit data values.
+
+ Because of the limits of the AVR processors used in the first
+ two companion boards, the SPI data rate is set to 187.5kbaud.
+
+== SPI Message Formats
+
+ This section first defines the command message format sent from
+ the flight computer to the companion board, and then the various
+ reply message formats for each type of command message.
+
+ .Companion Command Message
+ [options="border",cols="1,3,3,9"]
+ |====
+ |Offset
+ |Data Type
+ |Name
+ |Description
+
+ |0
+ |uint8_t
+ |command
+ |Command identifier
+
+ |1
+ |uint8_t
+ |flight_state
+ |Current flight computer state
+
+ |2
+ |uint16_t
+ |tick
+ |Flight computer clock (100 ticks/second)
+
+ |4
+ |uint16_t
+ |serial
+ |Flight computer serial number
+
+ |6
+ |uint16_t
+ |flight
+ |Flight number
+
+ |8
+ |
+ |
+ |
+
+ |====
+
+ .Companion Command Identifiers
+ [options="border",cols="1,3,9"]
+ |====
+ |Value
+ |Name
+ |Description
+
+ |1
+ |SETUP
+ |Supply the flight computer with companion
+ information
+
+ |2
+ |FETCH
+ |Return telemetry information
+
+ |3
+ |NOTIFY
+ |Tell companion board when flight state changes
+ |====
+
+ The flight computer will send a SETUP message shortly after
+ power-up and will then send FETCH messages no more often than
+ the rate specified in the SETUP reply. NOTIFY messages will be
+ sent whenever the flight state changes.
+
+ 'flight_state' records the current state of the flight,
+ whether on the pad, under power, coasting to apogee or
+ descending on the drogue or main chute.
+
+ 'tick' provides the current flight computer clock, which
+ be used to synchronize data recorded on the flight computer
+ with that recorded on the companion board in post-flight analysis.
+
+ 'serial' is the product serial number of the flight computer,
+ 'flight' is the flight sequence number. Together, these two
+ uniquely identify the flight and can be recorded with any
+ companion board data logging to associate the companion data
+ with the proper flight.
+
+ NOTIFY commands require no reply at all, they are used solely
+ to inform the companion board when the state of the flight, as
+ computed by the flight computer, changes. Companion boards can
+ use this to change data collection parameters, disabling data
+ logging until the flight starts and terminating it when the
+ flight ends.
+
+ === SETUP reply message
+
+ .SETUP reply contents
+ [options="border",cols="1,3,3,9"]
+ |====
+ |Offset
+ |Data Type
+ |Name
+ |Description
+
+ |0
+ |uint16_t
+ |board_id
+ |Board identifier
+
+ |2
+ |uint16_t
+ |board_id_inverse
+ |~board_id—used to tell if a board is present
+
+ |4
+ |uint8_t
+ |update_period
+ |Minimum time (in 100Hz ticks) between FETCH commands
+
+ |5
+ |uint8_t
+ |channels
+ |Number of data channels to retrieve in FETCH command
+
+ |6
+ |
+ |
+ |
+ |====
+
+ The SETUP reply contains enough information to uniquely
+ identify the companion board to the end user as well as for
+ the flight computer to know how many data values to expect in
+ reply to a FETCH command, and how often to fetch that data.
+
+ To detect the presence of a companion board, the flight
+ computer checks to make sure that board_id_inverse is the
+ bit-wise inverse of board_id. Current companion boards use
+ USB product ID as the board_id, but the flight computer does
+ not interpret this data and so it can be any value.
+
+ === FETCH reply message
+
+ .FETCH reply contents
+ [options="border",cols="1,3,3,9"]
+ |====
+ |Offset
+ |Data Type
+ |Name
+ |Description
+
+ |0
+ |uint16_t
+ |data0
+ |0th data item
+
+ |2
+ |uint16_t
+ |data1
+ |1st data item
+
+ |...
+ |
+ |
+ |
+ |====
+
+ The FETCH reply contains arbitrary data to be reported
+ over the flight computer telemetry link. The number of
+ 16-bit data items must match the 'channels' value
+ provided in the SETUP reply message.
+
+== History and Motivation
+
+ To allow cross-programming, the original TeleMetrum and
+ TeleDongle designs needed to include some kind of
+ connector. With that in place, adding the ability to connect
+ external cards to TeleMetrum was fairly simple. We set the
+ software piece of this puzzle aside until we had a companion
+ board to use.
+
+ The first companion board was TeleScience. Designed to collect
+ temperature data from the nose and fin of the airframe, the main
+ requirement for the companion port was that it be able to report
+ telemetry data during flight as a back-up in case the
+ TeleScience on-board data was lost.
+
+ The second companion board, TelePyro, provides 8 additional
+ channels for deployment, staging or other activities. To avoid
+ re-programming the TeleMetrum to use TelePyro, we decided to
+ provide enough information over the companion link for it to
+ independently control those channels.
+
+ Providing a standard, constant interface between the flight
+ computer and companion boards allows for the base flight
+ computer firmware to include support for companion boards.
+++ /dev/null
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"/usr/share/xml/docbook/schema/dtd/4.5/docbookx.dtd">
-
-<article>
- <articleinfo>
- <title>AltOS Companion Port</title>
- <subtitle>Protocol Definitions</subtitle>
- <author>
- <firstname>Keith</firstname>
- <surname>Packard</surname>
- </author>
- <copyright>
- <year>2012</year>
- <holder>Keith Packard</holder>
- </copyright>
- <legalnotice>
- <para>
- This document is released under the terms of the
- <ulink url="http://creativecommons.org/licenses/by-sa/3.0/">
- Creative Commons ShareAlike 3.0
- </ulink>
- license.
- </para>
- </legalnotice>
- <revhistory>
- <revision>
- <revnumber>0.1</revnumber>
- <date>13 January 2012</date>
- <revremark>Initial content</revremark>
- </revision>
- </revhistory>
- </articleinfo>
- <section>
- <title>Companion Port</title>
- <para>
- Many Altus Metrum products come with an eight pin Micro MaTch
- connector, called the Companion Port. This is often used to
- program devices using a programming cable. However, it can also
- be used to connect TeleMetrum to external companion boards
- (hence the name).
- </para>
- <para>
- The Companion Port provides two different functions:
- <itemizedlist>
- <listitem>
- <para>
- Power. Both battery-level and 3.3V regulated power are
- available. Note that the amount of regulated power is not
- huge; TeleMetrum contains a 150mA regulator and uses, at
- peak, about 120mA or so. For applications needing more than
- a few dozen mA, placing a separate regulator on them and
- using the battery for power is probably a good idea.
- </para>
- </listitem>
- <listitem>
- <para>
- SPI. The flight computer operates as a SPI master, using
- a protocol defined in this document. Companion boards
- provide a matching SPI slave implementation which supplies
- telemetry information for the radio downlink during flight
- </para>
- </listitem>
- </itemizedlist>
- </para>
- </section>
- <section>
- <title>Companion SPI Protocol</title>
- <para>
- The flight computer implements a SPI master communications
- channel over the companion port, and uses this to get
- information about a connected companion board and then to get
- telemetry data for transmission during flight.
- </para>
- <para>
- At startup time, the flight computer sends a setup request
- packet, and the companion board returns a board identifier, the
- desired telemetry update period and the number of data channels
- provided. The flight computer doesn't interpret the telemetry
- data at all, simply packing it up and sending it over the link.
- Telemetry packets are 32 bytes long, and companion packets use 8
- bytes as a header leaving room for a maximum of 12 16-bit data
- values.
- </para>
- <para>
- Because of the limits of the AVR processors used in the first
- two companion boards, the SPI data rate is set to 187.5kbaud.
- </para>
- </section>
- <section>
- <title>SPI Message Formats</title>
- <para>
- This section first defines the command message format sent from
- the flight computer to the companion board, and then the various
- reply message formats for each type of command message.
- </para>
- <section>
- <title>Command Message</title>
- <table frame='all'>
- <title>Companion Command Message</title>
- <tgroup cols='4' align='center' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='Offset'/>
- <colspec align='center' colwidth='3*' colname='Data Type'/>
- <colspec align='left' colwidth='3*' colname='Name'/>
- <colspec align='left' colwidth='9*' colname='Description'/>
- <thead>
- <row>
- <entry align='center'>Offset</entry>
- <entry align='center'>Data Type</entry>
- <entry align='center'>Name</entry>
- <entry align='center'>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>0</entry>
- <entry>uint8_t</entry>
- <entry>command</entry>
- <entry>Command identifier</entry>
- </row>
- <row>
- <entry>1</entry>
- <entry>uint8_t</entry>
- <entry>flight_state</entry>
- <entry>Current flight computer state</entry>
- </row>
- <row>
- <entry>2</entry>
- <entry>uint16_t</entry>
- <entry>tick</entry>
- <entry>Flight computer clock (100 ticks/second)</entry>
- </row>
- <row>
- <entry>4</entry>
- <entry>uint16_t</entry>
- <entry>serial</entry>
- <entry>Flight computer serial number</entry>
- </row>
- <row>
- <entry>6</entry>
- <entry>uint16_t</entry>
- <entry>flight</entry>
- <entry>Flight number</entry>
- </row>
- <row>
- <entry>8</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <table frame='all'>
- <title>Companion Command Identifiers</title>
- <tgroup cols='3' align='center' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='Value'/>
- <colspec align='left' colwidth='3*' colname='Name'/>
- <colspec align='left' colwidth='9*' colname='Description'/>
- <thead>
- <row>
- <entry>Value</entry>
- <entry>Name</entry>
- <entry>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>1</entry>
- <entry>SETUP</entry>
- <entry>Supply the flight computer with companion
- information</entry>
- </row>
- <row>
- <entry>2</entry>
- <entry>FETCH</entry>
- <entry>Return telemetry information</entry>
- </row>
- <row>
- <entry>3</entry>
- <entry>NOTIFY</entry>
- <entry>Tell companion board when flight state
- changes</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <para>
- The flight computer will send a SETUP message shortly after
- power-up and will then send FETCH messages no more often than
- the rate specified in the SETUP reply. NOTIFY messages will be
- sent whenever the flight state changes.
- </para>
- <para>
- 'flight_state' records the current state of the flight,
- whether on the pad, under power, coasting to apogee or
- descending on the drogue or main chute.
- </para>
- <para>
- 'tick' provides the current flight computer clock, which
- be used to synchronize data recorded on the flight computer
- with that recorded on the companion board in post-flight analysis.
- </para>
- <para>
- 'serial' is the product serial number of the flight computer,
- 'flight' is the flight sequence number. Together, these two
- uniquely identify the flight and can be recorded with any
- companion board data logging to associate the companion data
- with the proper flight.
- </para>
- <para>
- NOTIFY commands require no reply at all, they are used solely
- to inform the companion board when the state of the flight, as
- computed by the flight computer, changes. Companion boards can
- use this to change data collection parameters, disabling data
- logging until the flight starts and terminating it when the
- flight ends.
- </para>
- </section>
- <section>
- <title>SETUP reply message</title>
- <table frame='all'>
- <title>SETUP reply contents</title>
- <tgroup cols='4' align='center' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='Offset'/>
- <colspec align='center' colwidth='3*' colname='Data Type'/>
- <colspec align='left' colwidth='3*' colname='Name'/>
- <colspec align='left' colwidth='9*' colname='Description'/>
- <thead>
- <row>
- <entry align='center'>Offset</entry>
- <entry align='center'>Data Type</entry>
- <entry align='center'>Name</entry>
- <entry align='center'>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>0</entry>
- <entry>uint16_t</entry>
- <entry>board_id</entry>
- <entry>Board identifier</entry>
- </row>
- <row>
- <entry>2</entry>
- <entry>uint16_t</entry>
- <entry>board_id_inverse</entry>
- <entry>~board_id—used to tell if a board is present</entry>
- </row>
- <row>
- <entry>4</entry>
- <entry>uint8_t</entry>
- <entry>update_period</entry>
- <entry>Minimum time (in 100Hz ticks) between FETCH commands</entry>
- </row>
- <row>
- <entry>5</entry>
- <entry>uint8_t</entry>
- <entry>channels</entry>
- <entry>Number of data channels to retrieve in FETCH command</entry>
- </row>
- <row>
- <entry>6</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <para>
- The SETUP reply contains enough information to uniquely
- identify the companion board to the end user as well as for
- the flight computer to know how many data values to expect in
- reply to a FETCH command, and how often to fetch that data.
- </para>
- <para>
- To detect the presence of a companion board, the flight
- computer checks to make sure that board_id_inverse is the
- bit-wise inverse of board_id. Current companion boards use
- USB product ID as the board_id, but the flight computer does
- not interpret this data and so it can be any value.
- </para>
- </section>
- <section>
- <title>FETCH reply message</title>
- <table frame='all'>
- <title>FETCH reply contents</title>
- <tgroup cols='4' align='center' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='Offset'/>
- <colspec align='center' colwidth='3*' colname='Data Type'/>
- <colspec align='left' colwidth='3*' colname='Name'/>
- <colspec align='left' colwidth='9*' colname='Description'/>
- <thead>
- <row>
- <entry align='center'>Offset</entry>
- <entry align='center'>Data Type</entry>
- <entry align='center'>Name</entry>
- <entry align='center'>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>0</entry>
- <entry>uint16_t</entry>
- <entry>data0</entry>
- <entry>0th data item</entry>
- </row>
- <row>
- <entry>2</entry>
- <entry>uint16_t</entry>
- <entry>data1</entry>
- <entry>1st data item</entry>
- </row>
- <row>
- <entry>...</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <para>
- The FETCH reply contains arbitrary data to be reported over
- the flight computer telemetry link. The number of 16-bit data items
- must match the 'channels' value provided in the SETUP reply
- message.
- </para>
- </section>
- </section>
- <section>
- <title>History and Motivation</title>
- <para>
- To allow cross-programming, the original TeleMetrum and
- TeleDongle designs needed to include some kind of
- connector. With that in place, adding the ability to connect
- external cards to TeleMetrum was fairly simple. We set the
- software piece of this puzzle aside until we had a companion
- board to use.
- </para>
- <para>
- The first companion board was TeleScience. Designed to collect
- temperature data from the nose and fin of the airframe, the main
- requirement for the companion port was that it be able to report
- telemetry data during flight as a back-up in case the
- TeleScience on-board data was lost.
- </para>
- <para>
- The second companion board, TelePyro, provides 8 additional
- channels for deployment, staging or other activities. To avoid
- re-programming the TeleMetrum to use TelePyro, we decided to
- provide enough information over the companion link for it to
- independently control those channels.
- </para>
- <para>
- Providing a standard, constant interface between the flight
- computer and companion boards allows for the base flight
- computer firmware to include support for companion boards.
- </para>
- </section>
-</article>
--- /dev/null
+<subtitle>Packet Definitions</subtitle>
+<author>
+ <firstname>Keith</firstname>
+ <surname>Packard</surname>
+ <email>keithp@keithp.com</email>
+</author>
+<date>1 July 2011</date>
+<copyright>
+ <year>2011</year>
+ <holder>Keith Packard</holder>
+</copyright>
+<legalnotice>
+ <para>
+ This document is released under the terms of the
+ <ulink url="http://creativecommons.org/licenses/by-sa/3.0/">
+ Creative Commons ShareAlike 3.0
+ </ulink>
+ license.
+ </para>
+</legalnotice>
+<revhistory>
+ <revision>
+ <revnumber>0.1</revnumber>
+ <date>1 July 2011</date>
+ <revremark>Initial content</revremark>
+ </revision>
+</revhistory>
--- /dev/null
+= AltOS Telemetry
+:doctype: article
+:toc:
+:numbered:
+
+== Packet Format Design
+
+ AltOS telemetry data is split into multiple different packets,
+ all the same size, but each includs an identifier so that the
+ ground station can distinguish among different types. A single
+ flight board will transmit multiple packet types, each type on
+ a different schedule. The ground software need look for only a
+ single packet size, and then decode the information within the
+ packet and merge data from multiple packets to construct the
+ full flight computer state.
+
+ Each AltOS packet is 32 bytes long. This size was chosen based
+ on the known telemetry data requirements. The power of two
+ size allows them to be stored easily in flash memory without
+ having them split across blocks or leaving gaps at the end.
+
+ All packet types start with a five byte header which encodes
+ the device serial number, device clock value and the packet
+ type. The remaining 27 bytes encode type-specific data.
+
+== Packet Formats
+
+ This section first defines the packet header common to all packets
+ and then the per-packet data layout.
+
+ === Packet Header
+
+ .Telemetry Packet Header
+ [options="border",cols="2,3,3,9"]
+ |====
+ |Offset |Data Type |Name |Description
+ |0 |uint16_t |serial |Device serial Number
+ |2 |uint16_t |tick |Device time in 100ths of a second
+ |4 |uint8_t |type |Packet type
+ |5
+ |====
+
+ Each packet starts with these five bytes which serve to identify
+ which device has transmitted the packet, when it was transmitted
+ and what the rest of the packet contains.
+
+ === TeleMetrum v1.x, TeleMini and TeleNano Sensor Data
+
+ .Sensor Packet Type
+ [options="border",cols="1,3"]
+ |====
+ |Type |Description
+ |0x01 |TeleMetrum v1.x Sensor Data
+ |0x02 |TeleMini Sensor Data
+ |0x03 |TeleNano Sensor Data
+ |====
+
+ TeleMetrum v1.x, TeleMini and TeleNano share this same
+ packet format for sensor data. Each uses a distinct
+ packet type so that the receiver knows which data
+ values are valid and which are undefined.
+
+ Sensor Data packets are transmitted once per second on
+ the ground, 10 times per second during ascent and once
+ per second during descent and landing
+
+ .Sensor Packet Contents
+ [options="border",cols="2,3,3,9"]
+ |====
+ |Offset |Data Type |Name |Description
+ |5 |uint8_t |state |Flight state
+ |6 |int16_t |accel |accelerometer (TM only)
+ |8 |int16_t |pres |pressure sensor
+ |10 |int16_t |temp |temperature sensor
+ |12 |int16_t |v_batt |battery voltage
+ |14 |int16_t |sense_d |drogue continuity sense (TM/Tm)
+ |16 |int16_t |sense_m |main continuity sense (TM/Tm)
+ |18 |int16_t |acceleration |m/s² * 16
+ |20 |int16_t |speed |m/s * 16
+ |22 |int16_t |height |m
+ |24 |int16_t |ground_pres |Average barometer reading on ground
+ |26 |int16_t |ground_accel |TM
+ |28 |int16_t |accel_plus_g |TM
+ |30 |int16_t |accel_minus_g |TM
+ |32
+ |====
+
+ === TeleMega Sensor Data
+
+ .TeleMega Packet Type
+ [options="border",cols="1,3"]
+ |====
+ |Type |Description
+ |0x08 |TeleMega IMU Sensor Data
+ |0x09 |TeleMega Kalman and Voltage Data
+ |====
+
+ TeleMega has a lot of sensors, and so it splits the sensor
+ data into two packets. The raw IMU data are sent more often;
+ the voltage values don't change very fast, and the Kalman
+ values can be reconstructed from the IMU data.
+
+ IMU Sensor Data packets are transmitted once per second on the
+ ground, 10 times per second during ascent and once per second
+ during descent and landing
+
+ Kalman and Voltage Data packets are transmitted once per second on the
+ ground, 5 times per second during ascent and once per second
+ during descent and landing
+
+ The high-g accelerometer is reported separately from the data
+ for the 9-axis IMU (accel/gyro/mag). The 9-axis IMU is mounted
+ so that the X axis is "across" the board (along the short
+ axis0, the Y axis is "along" the board (along the long axis,
+ with the high-g accelerometer) and the Z axis is "through" the
+ board (perpendicular to the board). Rotation measurements are
+ around the respective axis, so Y rotation measures the spin
+ rate of the rocket while X and Z rotation measure the tilt
+ rate.
+
+ The overall tilt angle of the rocket is computed by first
+ measuring the orientation of the rocket on the pad using the 3
+ axis accelerometer, and then integrating the overall tilt rate
+ from the 3 axis gyroscope to compute the total orientation
+ change of the airframe since liftoff.
+
+ .TeleMega IMU Sensor Packet Contents
+ [options="border",cols="2,3,3,9"]
+ |====
+ |Offset |Data Type |Name |Description
+ |5 |uint8_t |orient |Angle from vertical in degrees
+ |6 |int16_t |accel |High G accelerometer
+ |8 |int32_t |pres |pressure (Pa * 10)
+ |12 |int16_t |temp |temperature (°C * 100)
+ |14 |int16_t |accel_x |X axis acceleration (across)
+ |16 |int16_t |accel_y |Y axis acceleration (along)
+ |18 |int16_t |accel_z |Z axis acceleration (through)
+ |20 |int16_t |gyro_x |X axis rotation (across)
+ |22 |int16_t |gyro_y |Y axis rotation (along)
+ |24 |int16_t |gyro_z |Z axis rotation (through)
+ |26 |int16_t |mag_x |X field strength (across)
+ |28 |int16_t |mag_y |Y field strength (along)
+ |30 |int16_t |mag_z |Z field strength (through)
+ |32
+ |====
+
+ .TeleMega Kalman and Voltage Data Packet Contents
+ [options="border",cols="2,3,3,9"]
+ |====
+ |Offset |Data Type |Name |Description
+ |5 |uint8_t |state |Flight state
+ |6 |int16_t |v_batt |battery voltage
+ |8 |int16_t |v_pyro |pyro battery voltage
+ |10 |int8_t[6] |sense |pyro continuity sense
+ |16 |int32_t |ground_pres |Average barometer reading on ground
+ |20 |int16_t |ground_accel |Average accelerometer reading on ground
+ |22 |int16_t |accel_plus_g |Accel calibration at +1g
+ |24 |int16_t |accel_minus_g |Accel calibration at -1g
+ |26 |int16_t |acceleration |m/s² * 16
+ |28 |int16_t |speed |m/s * 16
+ |30 |int16_t |height |m
+ |32
+ |====
+
+ === TeleMetrum v2 Sensor Data
+
+ .TeleMetrum v2 Packet Type
+ [options="border",cols="1,3"]
+ |====
+ |Type |Description
+ |0x0A |TeleMetrum v2 Sensor Data
+ |0x0B |TeleMetrum v2 Calibration Data
+ |====
+
+ TeleMetrum v2 has higher resolution barometric data than
+ TeleMetrum v1, and so the constant calibration data is
+ split out into a separate packet.
+
+ TeleMetrum v2 Sensor Data packets are transmitted once per second on the
+ ground, 10 times per second during ascent and once per second
+ during descent and landing
+
+ TeleMetrum v2 Calibration Data packets are always transmitted once per second.
+
+ .TeleMetrum v2 Sensor Packet Contents
+ [options="border",cols="2,3,3,9"]
+ |====
+ |Offset |Data Type |Name |Description
+ |5 |uint8_t |state |Flight state
+ |6 |int16_t |accel |accelerometer
+ |8 |int32_t |pres |pressure sensor (Pa * 10)
+ |12 |int16_t |temp |temperature sensor (°C * 100)
+ |14 |int16_t |acceleration |m/s² * 16
+ |16 |int16_t |speed |m/s * 16
+ |18 |int16_t |height |m
+ |20 |int16_t |v_batt |battery voltage
+ |22 |int16_t |sense_d |drogue continuity sense
+ |24 |int16_t |sense_m |main continuity sense
+ |26 |pad[6] |pad bytes |
+ |32
+ |====
+
+ .TeleMetrum v2 Calibration Data Packet Contents
+ [options="border",cols="2,3,3,9"]
+ |====
+ |Offset |Data Type |Name |Description
+ |5 |pad[3] |pad bytes |
+ |8 |int32_t |ground_pres |Average barometer reading on ground
+ |12 |int16_t |ground_accel |Average accelerometer reading on ground
+ |14 |int16_t |accel_plus_g |Accel calibration at +1g
+ |16 |int16_t |accel_minus_g |Accel calibration at -1g
+ |18 |pad[14] |pad bytes |
+ |32
+ |====
+
+ === Configuration Data
+
+ .Configuration Packet Type
+ [options="border",cols="1,3"]
+ |====
+ |Type |Description
+ |0x04 |Configuration Data
+ |====
+
+ This provides a description of the software installed on the
+ flight computer as well as any user-specified configuration data.
+
+ Configuration data packets are transmitted once per second
+ during all phases of the flight
+
+ .Configuration Packet Contents
+ [options="border",cols="2,3,3,9"]
+ |====
+ |Offset |Data Type |Name |Description
+ |5 |uint8_t |type |Device type
+ |6 |uint16_t |flight |Flight number
+ |8 |uint8_t |config_major |Config major version
+ |9 |uint8_t |config_minor |Config minor version
+ |10 |uint16_t |apogee_delay |Apogee deploy delay in seconds
+ |12 |uint16_t |main_deploy |Main deploy alt in meters
+ |14 |uint16_t |flight_log_max |Maximum flight log size (kB)
+ |16 |char |callsign[8] |Radio operator identifier
+ |24 |char |version[8] |Software version identifier
+ |32
+ |====
+
+ === GPS Location
+
+ .GPS Packet Type
+ [options="border",cols="1,3"]
+ |====
+ |Type |Description
+ |0x05 |GPS Location
+ |====
+
+ This packet provides all of the information available from the
+ GPS receiver—position, time, speed and precision
+ estimates.
+
+ GPS Location packets are transmitted once per second during
+ all phases of the flight
+
+ .GPS Location Packet Contents
+ [options="border",cols="2,3,3,9"]
+ |====
+ |Offset |Data Type |Name |Description
+ |5 |uint8_t |flags |See GPS Flags table below
+ |6 |int16_t |altitude |m
+ |8 |int32_t |latitude |degrees * 107
+ |12 |int32_t |longitude |degrees * 107
+ |16 |uint8_t |year |
+ |17 |uint8_t |month |
+ |18 |uint8_t |day |
+ |19 |uint8_t |hour |
+ |20 |uint8_t |minute |
+ |21 |uint8_t |second |
+ |22 |uint8_t |pdop |* 5
+ |23 |uint8_t |hdop |* 5
+ |24 |uint8_t |vdop |* 5
+ |25 |uint8_t |mode |See GPS Mode table below
+ |26 |uint16_t |ground_speed |cm/s
+ |28 |int16_t |climb_rate |cm/s
+ |30 |uint8_t |course |/ 2
+ |31 |uint8_t |unused[1] |
+ |32
+ |====
+
+ Packed into a one byte field are status flags and the
+ count of satellites used to compute the position
+ fix. Note that this number may be lower than the
+ number of satellites being tracked; the receiver will
+ not use information from satellites with weak signals
+ or which are close enough to the horizon to have
+ significantly degraded position accuracy.
+
+ .GPS Flags
+ [options="border",cols="1,2,7"]
+ |====
+ |Bits |Name |Description
+ |0-3 |nsats |Number of satellites in solution
+ |4 |valid |GPS solution is valid
+ |5 |running |GPS receiver is operational
+ |6 |date_valid |Reported date is valid
+ |7 |course_valid |ground speed, course and climb rates are valid
+ |====
+
+ Here are all of the valid GPS operational modes. Altus
+ Metrum products will only ever report 'N' (not valid),
+ 'A' (Autonomous) modes or 'E' (Estimated). The
+ remaining modes are either testing modes or require
+ additional data.
+
+ .GPS Mode
+ [options="border",cols="1,3,7"]
+ |====
+ |Mode |Name |Description
+ |N |Not Valid |All data are invalid
+ |A |Autonomous mode |
+ Data are derived from satellite data
+
+ |D |Differential Mode |
+ Data are augmented with differential data from a
+ known ground station. The SkyTraq unit in TeleMetrum
+ does not support this mode
+
+ |E |Estimated |
+ Data are estimated using dead reckoning from the
+ last known data
+
+ |M |Manual |
+ Data were entered manually
+
+ |S |Simulated |
+ GPS receiver testing mode
+
+ |====
+
+ === GPS Satellite Data
+
+ .GPS Satellite Data Packet Type
+ [options="border",cols="1,3"]
+ |====
+ |Type |Description
+ |0x06 |GPS Satellite Data
+ |====
+
+ This packet provides space vehicle identifiers and
+ signal quality information in the form of a C/N1
+ number for up to 12 satellites. The order of the svids
+ is not specified.
+
+ GPS Satellite data are transmitted once per second
+ during all phases of the flight.
+
+ .GPS Satellite Data Contents
+ [options="border",cols="2,3,3,9"]
+ |====
+ |Offset |Data Type |Name |Description
+ |5 |uint8_t |channels |Number of reported satellite information
+ |6 |sat_info_t |sats[12] |See Per-Satellite data table below
+ |30 |uint8_t |unused[2] |
+ |32
+ |====
+
+ .GPS Per-Satellite data (sat_info_t)
+ [options="border",cols="2,3,3,9"]
+ |====
+ |Offset |Data Type |Name |Description
+ |0 |uint8_t |svid |Space Vehicle Identifier
+ |1 |uint8_t |c_n_1 |C/N1 signal quality indicator
+ |2
+ |====
+
+ === Companion Data
+
+ .Companion Data Packet Type
+ [options="border",cols="1,3"]
+ |====
+ |Type |Description
+ |0x07 |Companion Data
+ |====
+
+ When a companion board is attached to TeleMega or
+ TeleMetrum, it can provide telemetry data to be
+ included in the downlink. The companion board can
+ provide up to 12 16-bit data values.
+
+ The companion board itself specifies the transmission
+ rate. On the ground and during descent, that rate is
+ limited to one packet per second. During ascent, that
+ rate is limited to 10 packets per second.
+
+ .Companion Data Contents
+ [options="border",cols="2,3,3,9"]
+ |====
+ |Offset |Data Type |Name |Description
+ |5 |uint8_t |board_id |Type of companion board attached
+ |6 |uint8_t |update_period |How often telemetry is sent, in 1/100ths of a second
+ |7 |uint8_t |channels |Number of data channels supplied
+ |8 |uint16_t[12] |companion_data |Up to 12 channels of 16-bit companion data
+ |32
+ |====
+
+== Data Transmission
+
+ Altus Metrum devices use Texas Instruments sub-GHz digital
+ radio products. Ground stations use parts with HW FEC while
+ some flight computers perform FEC in software. TeleGPS is
+ transmit-only.
+
+ .Altus Metrum Radio Parts
+ [options="border",cols="1,4,4"]
+ |====
+ |Part Number |Description |Used in
+
+ |CC1111
+ |10mW transceiver with integrated SoC
+ |TeleDongle v0.2, TeleBT v1.0, TeleMetrum v1.x, TeleMini
+
+ |CC1120
+ |35mW transceiver with SW FEC
+ |TeleMetrum v2, TeleMega
+
+ |CC1200
+ |35mW transceiver with HW FEC
+ |TeleDongle v3.0, TeleBT v3.0
+
+ |CC115L
+ |14mW transmitter with SW FEC
+ |TeleGPS
+
+ |====
+
+ === Modulation Scheme
+
+ Texas Instruments provides a tool for computing
+ modulation parameters given a desired modulation
+ format and basic bit rate.
+
+ While we might like to use something with better
+ low-signal performance like BPSK, the radios we use
+ don't support that, but do support Gaussian frequency
+ shift keying (GFSK). Regular frequency shift keying
+ (FSK) encodes the signal by switching the carrier
+ between two frequencies. The Gaussian version is
+ essentially the same, but the shift between
+ frequencies gently follows a gaussian curve, rather
+ than switching immediately. This tames the bandwidth
+ of the signal without affecting the ability to
+ transmit data.
+
+ For AltOS, there are three available bit rates,
+ 38.4kBaud, 9.6kBaud and 2.4kBaud resulting in the
+ following signal parmeters:
+
+ .Modulation Scheme
+ [options="border",cols="1,1,1"]
+ |====
+ |Rate |Deviation |Receiver Bandwidth
+ |38.4kBaud |20.5kHz |100kHz
+ |9.6kBaud |5.125kHz |25kHz
+ |2.4kBaud |1.5kHz |5kHz
+ |====
+
+ === Error Correction
+
+ The cc1111 and cc1200 provide forward error correction
+ in hardware; on the cc1120 and cc115l that's done in
+ software. AltOS uses this to improve reception of weak
+ signals. As it's a rate 1/2 encoding, each bit of data
+ takes two bits when transmitted, so the effective data
+ rate is half of the raw transmitted bit rate.
+
+ .Error Correction
+ [options="border",cols="1,1,1"]
+ |====
+ |Parameter |Value |Description
+
+ |Error Correction
+ |Convolutional coding
+ |1/2 rate, constraint length m=4
+
+ |Interleaving
+ |4 x 4
+ |Reduce effect of noise burst
+
+ |Data Whitening
+ |XOR with 9-bit PNR
+ |Rotate right with bit 8 = bit 0 xor bit 5, initial value 111111111
+
+ |====
+
+== TeleDongle serial packet format
+
+ TeleDongle does not do any interpretation of the packet data,
+ instead it is configured to receive packets of a specified
+ length (32 bytes in this case). For each received packet,
+ TeleDongle produces a single line of text. This line starts with
+ the string "TELEM " and is followed by a list of hexadecimal
+ encoded bytes.
+
+ ....
+ TELEM 224f01080b05765e00701f1a1bbeb8d7b60b070605140c000600000000000000003fa988
+ ....
+
+ The hexadecimal encoded string of bytes contains a length byte,
+ the packet data, two bytes added by the cc1111 radio receiver
+ hardware and finally a checksum so that the host software can
+ validate that the line was transmitted without any errors.
+
+ .TeleDongle serial Packet Format
+
+ [options="border",cols="2,1,1,5"]
+ |====
+ |Offset |Name |Example |Description
+
+ |0
+ |length
+ |22
+ |Total length of data bytes in the line. Note that
+ this includes the added RSSI and status bytes
+
+ |1 ·· length-3
+ |packet
+ |4f ·· 00
+ |Bytes of actual packet data
+
+ |length-2
+ |rssi
+ |3f
+ |Received signal strength. dBm = rssi / 2 - 74
+
+ |length-1
+ |lqi
+ |a9
+ |Link Quality Indicator and CRC status. Bit 7
+ is set when the CRC is correct
+
+ |length
+ |checksum
+ |88
+ |(0x5a + sum(bytes 1 ·· length-1)) % 256
+
+ |====
+
+== History and Motivation
+
+ The original AltoOS telemetry mechanism encoded everything
+ available piece of information on the TeleMetrum hardware into a
+ single unified packet. Initially, the packets contained very
+ little data—some raw sensor readings along with the current GPS
+ coordinates when a GPS receiver was connected. Over time, the
+ amount of data grew to include sensor calibration data, GPS
+ satellite information and a host of internal state information
+ designed to help diagnose flight failures in case of a loss of
+ the on-board flight data.
+
+ Because every packet contained all of the data, packets were
+ huge—95 bytes long. Much of the information was also specific to
+ the TeleMetrum hardware. With the introduction of the TeleMini
+ flight computer, most of the data contained in the telemetry
+ packets was unavailable. Initially, a shorter, but still
+ comprehensive packet was implemented. This required that the
+ ground station be pre-configured as to which kind of packet to
+ expect.
+
+ The development of several companion boards also made the
+ shortcomings evident—each companion board would want to include
+ telemetry data in the radio link; with the original design, the
+ packet would have to hold the new data as well, requiring
+ additional TeleMetrum and ground station changes.
+++ /dev/null
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"/usr/share/xml/docbook/schema/dtd/4.5/docbookx.dtd">
-
-<article>
- <articleinfo>
- <title>AltOS Telemetry</title>
- <subtitle>Packet Definitions</subtitle>
- <author>
- <firstname>Keith</firstname>
- <surname>Packard</surname>
- </author>
- <copyright>
- <year>2011</year>
- <holder>Keith Packard</holder>
- </copyright>
- <legalnotice>
- <para>
- This document is released under the terms of the
- <ulink url="http://creativecommons.org/licenses/by-sa/3.0/">
- Creative Commons ShareAlike 3.0
- </ulink>
- license.
- </para>
- </legalnotice>
- <revhistory>
- <revision>
- <revnumber>0.1</revnumber>
- <date>01 July 2011</date>
- <revremark>Initial content</revremark>
- </revision>
- </revhistory>
- </articleinfo>
- <section>
- <title>Packet Format Design</title>
- <para>
- AltOS telemetry data is split into multiple different packets,
- all the same size, but each includs an identifier so that the
- ground station can distinguish among different types. A single
- flight board will transmit multiple packet types, each type on a
- different schedule. The ground software need look for only a
- single packet size, and then decode the information within the
- packet and merge data from multiple packets to construct the
- full flight computer state.
- </para>
- <para>
- Each AltOS packet is 32 bytes long. This size was chosen based
- on the known telemetry data requirements. The power of two size
- allows them to be stored easily in flash memory without having
- them split across blocks or leaving gaps at the end.
- </para>
- <para>
- All packet types start with a five byte header which encodes the
- device serial number, device clock value and the packet
- type. The remaining 27 bytes encode type-specific data.
- </para>
- </section>
- <section>
- <title>Packet Formats</title>
- <para>
- This section first defines the packet header common to all packets
- and then the per-packet data layout.
- </para>
- <section>
- <title>Packet Header</title>
- <table frame='all'>
- <title>Telemetry Packet Header</title>
- <tgroup cols='4' align='center' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='Offset'/>
- <colspec align='center' colwidth='3*' colname='Data Type'/>
- <colspec align='left' colwidth='3*' colname='Name'/>
- <colspec align='left' colwidth='9*' colname='Description'/>
- <thead>
- <row>
- <entry align='center'>Offset</entry>
- <entry align='center'>Data Type</entry>
- <entry align='center'>Name</entry>
- <entry align='center'>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>0</entry>
- <entry>uint16_t</entry>
- <entry>serial</entry>
- <entry>Device serial Number</entry>
- </row>
- <row>
- <entry>2</entry>
- <entry>uint16_t</entry>
- <entry>tick</entry>
- <entry>Device time in 100ths of a second</entry>
- </row>
- <row>
- <entry>4</entry>
- <entry>uint8_t</entry>
- <entry>type</entry>
- <entry>Packet type</entry>
- </row>
- <row>
- <entry>5</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <para>
- Each packet starts with these five bytes which serve to identify
- which device has transmitted the packet, when it was transmitted
- and what the rest of the packet contains.
- </para>
- </section>
- <section>
- <title>TeleMetrum v1.x, TeleMini and TeleNano Sensor Data</title>
- <informaltable frame='none' label='' tocentry='0'>
- <tgroup cols='2' align='center' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='Offset'/>
- <colspec align='left' colwidth='3*' colname='Description'/>
- <thead>
- <row>
- <entry>Type</entry>
- <entry>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>0x01</entry>
- <entry>TeleMetrum v1.x Sensor Data</entry>
- </row>
- <row>
- <entry>0x02</entry>
- <entry>TeleMini Sensor Data</entry>
- </row>
- <row>
- <entry>0x03</entry>
- <entry>TeleNano Sensor Data</entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
- <para>
- TeleMetrum v1.x, TeleMini and TeleNano share this same packet
- format for sensor data. Each uses a distinct packet type so
- that the receiver knows which data values are valid and which
- are undefined.
- </para>
- <para>
- Sensor Data packets are transmitted once per second on the
- ground, 10 times per second during ascent and once per second
- during descent and landing
- </para>
- <table frame='all'>
- <title>Sensor Packet Contents</title>
- <tgroup cols='4' align='center' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='Offset'/>
- <colspec align='center' colwidth='3*' colname='Data Type'/>
- <colspec align='left' colwidth='3*' colname='Name'/>
- <colspec align='left' colwidth='9*' colname='Description'/>
- <thead>
- <row>
- <entry align='center'>Offset</entry>
- <entry align='center'>Data Type</entry>
- <entry align='center'>Name</entry>
- <entry align='center'>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>5</entry><entry>uint8_t</entry><entry>state</entry><entry>Flight state</entry>
- </row>
- <row>
- <entry>6</entry><entry>int16_t</entry><entry>accel</entry><entry>accelerometer (TM only)</entry>
- </row>
- <row>
- <entry>8</entry><entry>int16_t</entry><entry>pres</entry><entry>pressure sensor</entry>
- </row>
- <row>
- <entry>10</entry><entry>int16_t</entry><entry>temp</entry><entry>temperature sensor</entry>
- </row>
- <row>
- <entry>12</entry><entry>int16_t</entry><entry>v_batt</entry><entry>battery voltage</entry>
- </row>
- <row>
- <entry>14</entry><entry>int16_t</entry><entry>sense_d</entry><entry>drogue continuity sense (TM/Tm)</entry>
- </row>
- <row>
- <entry>16</entry><entry>int16_t</entry><entry>sense_m</entry><entry>main continuity sense (TM/Tm)</entry>
- </row>
- <row>
- <entry>18</entry><entry>int16_t</entry><entry>acceleration</entry><entry>m/s² * 16</entry>
- </row>
- <row>
- <entry>20</entry><entry>int16_t</entry><entry>speed</entry><entry>m/s * 16</entry>
- </row>
- <row>
- <entry>22</entry><entry>int16_t</entry><entry>height</entry><entry>m</entry>
- </row>
- <row>
- <entry>24</entry><entry>int16_t</entry><entry>ground_pres</entry><entry>Average barometer reading on ground</entry>
- </row>
- <row>
- <entry>26</entry><entry>int16_t</entry><entry>ground_accel</entry><entry>TM</entry>
- </row>
- <row>
- <entry>28</entry><entry>int16_t</entry><entry>accel_plus_g</entry><entry>TM</entry>
- </row>
- <row>
- <entry>30</entry><entry>int16_t</entry><entry>accel_minus_g</entry><entry>TM</entry>
- </row>
- <row>
- <entry>32</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </section>
- <section>
- <title>TeleMega Sensor Data</title>
- <informaltable frame='none' label='' tocentry='0'>
- <tgroup cols='2' align='center' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='Offset'/>
- <colspec align='left' colwidth='3*' colname='Description'/>
- <thead>
- <row>
- <entry>Type</entry>
- <entry>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>0x08</entry>
- <entry>TeleMega IMU Sensor Data</entry>
- </row>
- <row>
- <entry>0x09</entry>
- <entry>TeleMega Kalman and Voltage Data</entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
- <para>
- TeleMega has a lot of sensors, and so it splits the sensor
- data into two packets. The raw IMU data are sent more often;
- the voltage values don't change very fast, and the Kalman
- values can be reconstructed from the IMU data.
- </para>
- <para>
- IMU Sensor Data packets are transmitted once per second on the
- ground, 10 times per second during ascent and once per second
- during descent and landing
- </para>
- <para>
- Kalman and Voltage Data packets are transmitted once per second on the
- ground, 5 times per second during ascent and once per second
- during descent and landing
- </para>
- <para>
- The high-g accelerometer is reported separately from the data
- for the 9-axis IMU (accel/gyro/mag). The 9-axis IMU is mounted
- so that the X axis is "across" the board (along the short
- axis0, the Y axis is "along" the board (along the long axis,
- with the high-g accelerometer) and the Z axis is "through" the
- board (perpendicular to the board). Rotation measurements are
- around the respective axis, so Y rotation measures the spin
- rate of the rocket while X and Z rotation measure the tilt
- rate.
- </para>
- <para>
- The overall tilt angle of the rocket is computed by first
- measuring the orientation of the rocket on the pad using the 3
- axis accelerometer, and then integrating the overall tilt rate
- from the 3 axis gyroscope to compute the total orientation
- change of the airframe since liftoff.
- </para>
- <table frame='all'>
- <title>TeleMega IMU Sensor Packet Contents</title>
- <tgroup cols='4' align='center' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='Offset'/>
- <colspec align='center' colwidth='3*' colname='Data Type'/>
- <colspec align='left' colwidth='3*' colname='Name'/>
- <colspec align='left' colwidth='9*' colname='Description'/>
- <thead>
- <row>
- <entry align='center'>Offset</entry>
- <entry align='center'>Data Type</entry>
- <entry align='center'>Name</entry>
- <entry align='center'>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>5</entry><entry>uint8_t</entry><entry>orient</entry><entry>Angle from vertical in degrees</entry>
- </row>
- <row>
- <entry>6</entry><entry>int16_t</entry><entry>accel</entry><entry>High G accelerometer</entry>
- </row>
- <row>
- <entry>8</entry><entry>int32_t</entry><entry>pres</entry><entry>pressure (Pa * 10)</entry>
- </row>
- <row>
- <entry>12</entry><entry>int16_t</entry><entry>temp</entry><entry>temperature (°C * 100)</entry>
- </row>
- <row>
- <entry>14</entry><entry>int16_t</entry><entry>accel_x</entry><entry>X axis acceleration (across)</entry>
- </row>
- <row>
- <entry>16</entry><entry>int16_t</entry><entry>accel_y</entry><entry>Y axis acceleration (along)</entry>
- </row>
- <row>
- <entry>18</entry><entry>int16_t</entry><entry>accel_z</entry><entry>Z axis acceleration (through)</entry>
- </row>
- <row>
- <entry>20</entry><entry>int16_t</entry><entry>gyro_x</entry><entry>X axis rotation (across)</entry>
- </row>
- <row>
- <entry>22</entry><entry>int16_t</entry><entry>gyro_y</entry><entry>Y axis rotation (along)</entry>
- </row>
- <row>
- <entry>24</entry><entry>int16_t</entry><entry>gyro_z</entry><entry>Z axis rotation (through)</entry>
- </row>
- <row>
- <entry>26</entry><entry>int16_t</entry><entry>mag_x</entry><entry>X field strength (across)</entry>
- </row>
- <row>
- <entry>28</entry><entry>int16_t</entry><entry>mag_y</entry><entry>Y field strength (along)</entry>
- </row>
- <row>
- <entry>30</entry><entry>int16_t</entry><entry>mag_z</entry><entry>Z field strength (through)</entry>
- </row>
- <row>
- <entry>32</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <table frame='all'>
- <title>TeleMega Kalman and Voltage Data Packet Contents</title>
- <tgroup cols='4' align='center' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='Offset'/>
- <colspec align='center' colwidth='3*' colname='Data Type'/>
- <colspec align='left' colwidth='3*' colname='Name'/>
- <colspec align='left' colwidth='9*' colname='Description'/>
- <thead>
- <row>
- <entry align='center'>Offset</entry>
- <entry align='center'>Data Type</entry>
- <entry align='center'>Name</entry>
- <entry align='center'>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>5</entry><entry>uint8_t</entry><entry>state</entry><entry>Flight state</entry>
- </row>
- <row>
- <entry>6</entry><entry>int16_t</entry><entry>v_batt</entry><entry>battery voltage</entry>
- </row>
- <row>
- <entry>8</entry><entry>int16_t</entry><entry>v_pyro</entry><entry>pyro battery voltage</entry>
- </row>
- <row>
- <entry>10</entry><entry>int8_t[6]</entry><entry>sense</entry><entry>pyro continuity sense</entry>
- </row>
- <row>
- <entry>16</entry><entry>int32_t</entry><entry>ground_pres</entry><entry>Average barometer reading on ground</entry>
- </row>
- <row>
- <entry>20</entry><entry>int16_t</entry><entry>ground_accel</entry><entry>Average accelerometer reading on ground</entry>
- </row>
- <row>
- <entry>22</entry><entry>int16_t</entry><entry>accel_plus_g</entry><entry>Accel calibration at +1g</entry>
- </row>
- <row>
- <entry>24</entry><entry>int16_t</entry><entry>accel_minus_g</entry><entry>Accel calibration at -1g</entry>
- </row>
- <row>
- <entry>26</entry><entry>int16_t</entry><entry>acceleration</entry><entry>m/s² * 16</entry>
- </row>
- <row>
- <entry>28</entry><entry>int16_t</entry><entry>speed</entry><entry>m/s * 16</entry>
- </row>
- <row>
- <entry>30</entry><entry>int16_t</entry><entry>height</entry><entry>m</entry>
- </row>
- <row>
- <entry>32</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </section>
- <section>
- <title>TeleMetrum v2 Sensor Data</title>
- <informaltable frame='none' label='' tocentry='0'>
- <tgroup cols='2' align='center' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='Offset'/>
- <colspec align='left' colwidth='3*' colname='Description'/>
- <thead>
- <row>
- <entry>Type</entry>
- <entry>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>0x0A</entry>
- <entry>TeleMetrum v2 Sensor Data</entry>
- </row>
- <row>
- <entry>0x0B</entry>
- <entry>TeleMetrum v2 Calibration Data</entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
- <para>
- TeleMetrum v2 has higher resolution barometric data than
- TeleMetrum v1, and so the constant calibration data is
- split out into a separate packet.
- </para>
- <para>
- TeleMetrum v2 Sensor Data packets are transmitted once per second on the
- ground, 10 times per second during ascent and once per second
- during descent and landing
- </para>
- <para>
- TeleMetrum v2 Calibration Data packets are always transmitted once per second.
- </para>
- <table frame='all'>
- <title>TeleMetrum v2 Sensor Packet Contents</title>
- <tgroup cols='4' align='center' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='Offset'/>
- <colspec align='center' colwidth='3*' colname='Data Type'/>
- <colspec align='left' colwidth='3*' colname='Name'/>
- <colspec align='left' colwidth='9*' colname='Description'/>
- <thead>
- <row>
- <entry align='center'>Offset</entry>
- <entry align='center'>Data Type</entry>
- <entry align='center'>Name</entry>
- <entry align='center'>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>5</entry><entry>uint8_t</entry><entry>state</entry><entry>Flight state</entry>
- </row>
- <row>
- <entry>6</entry><entry>int16_t</entry><entry>accel</entry><entry>accelerometer</entry>
- </row>
- <row>
- <entry>8</entry><entry>int32_t</entry><entry>pres</entry><entry>pressure sensor (Pa * 10)</entry>
- </row>
- <row>
- <entry>12</entry><entry>int16_t</entry><entry>temp</entry><entry>temperature sensor (°C * 100)</entry>
- </row>
-
- <row>
- <entry>14</entry><entry>int16_t</entry><entry>acceleration</entry><entry>m/s² * 16</entry>
- </row>
- <row>
- <entry>16</entry><entry>int16_t</entry><entry>speed</entry><entry>m/s * 16</entry>
- </row>
- <row>
- <entry>18</entry><entry>int16_t</entry><entry>height</entry><entry>m</entry>
- </row>
-
- <row>
- <entry>20</entry><entry>int16_t</entry><entry>v_batt</entry><entry>battery voltage</entry>
- </row>
- <row>
- <entry>22</entry><entry>int16_t</entry><entry>sense_d</entry><entry>drogue continuity sense</entry>
- </row>
- <row>
- <entry>24</entry><entry>int16_t</entry><entry>sense_m</entry><entry>main continuity sense</entry>
- </row>
- <row>
- <entry>26</entry><entry>pad[6]</entry><entry>pad bytes</entry><entry></entry>
- </row>
- <row>
- <entry>32</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <table frame='all'>
- <title>TeleMetrum v2 Calibration Data Packet Contents</title>
- <tgroup cols='4' align='center' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='Offset'/>
- <colspec align='center' colwidth='3*' colname='Data Type'/>
- <colspec align='left' colwidth='3*' colname='Name'/>
- <colspec align='left' colwidth='9*' colname='Description'/>
- <thead>
- <row>
- <entry align='center'>Offset</entry>
- <entry align='center'>Data Type</entry>
- <entry align='center'>Name</entry>
- <entry align='center'>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>5</entry><entry>pad[3]</entry><entry>pad bytes</entry><entry></entry>
- </row>
- <row>
- <entry>8</entry><entry>int32_t</entry><entry>ground_pres</entry><entry>Average barometer reading on ground</entry>
- </row>
- <row>
- <entry>12</entry><entry>int16_t</entry><entry>ground_accel</entry><entry>Average accelerometer reading on ground</entry>
- </row>
- <row>
- <entry>14</entry><entry>int16_t</entry><entry>accel_plus_g</entry><entry>Accel calibration at +1g</entry>
- </row>
- <row>
- <entry>16</entry><entry>int16_t</entry><entry>accel_minus_g</entry><entry>Accel calibration at -1g</entry>
- </row>
- <row>
- <entry>18</entry><entry>pad[14]</entry><entry>pad bytes</entry><entry></entry>
- </row>
- <row>
- <entry>32</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </section>
- <section>
- <title>Configuration Data</title>
- <informaltable frame='none' label='' tocentry='0'>
- <tgroup cols='2' align='center' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='Offset'/>
- <colspec align='left' colwidth='3*' colname='Description'/>
- <thead>
- <row>
- <entry>Type</entry>
- <entry>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>0x04</entry>
- <entry>Configuration Data</entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
- <para>
- This provides a description of the software installed on the
- flight computer as well as any user-specified configuration data.
- </para>
- <para>
- Configuration data packets are transmitted once per second
- during all phases of the flight
- </para>
- <table frame='all'>
- <title>Sensor Packet Contents</title>
- <tgroup cols='4' align='center' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='Offset'/>
- <colspec align='center' colwidth='3*' colname='Data Type'/>
- <colspec align='left' colwidth='3*' colname='Name'/>
- <colspec align='left' colwidth='9*' colname='Description'/>
- <thead>
- <row>
- <entry align='center'>Offset</entry>
- <entry align='center'>Data Type</entry>
- <entry align='center'>Name</entry>
- <entry align='center'>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>5</entry><entry>uint8_t</entry><entry>type</entry><entry>Device type</entry>
- </row>
- <row>
- <entry>6</entry><entry>uint16_t</entry><entry>flight</entry><entry>Flight number</entry>
- </row>
- <row>
- <entry>8</entry><entry>uint8_t</entry><entry>config_major</entry><entry>Config major version</entry>
- </row>
- <row>
- <entry>9</entry><entry>uint8_t</entry><entry>config_minor</entry><entry>Config minor version</entry>
- </row>
- <row>
- <entry>10</entry><entry>uint16_t</entry><entry>apogee_delay</entry>
- <entry>Apogee deploy delay in seconds</entry>
- </row>
- <row>
- <entry>12</entry><entry>uint16_t</entry><entry>main_deploy</entry><entry>Main deploy alt in meters</entry>
- </row>
- <row>
- <entry>14</entry><entry>uint16_t</entry><entry>flight_log_max</entry>
- <entry>Maximum flight log size (kB)</entry>
- </row>
- <row>
- <entry>16</entry><entry>char</entry><entry>callsign[8]</entry><entry>Radio operator identifier</entry>
- </row>
- <row>
- <entry>24</entry><entry>char</entry><entry>version[8]</entry><entry>Software version identifier</entry>
- </row>
- <row>
- <entry>32</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </section>
- <section>
- <title>GPS Location</title>
- <informaltable frame='none' label='' tocentry='0'>
- <tgroup cols='2' align='center' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='Offset'/>
- <colspec align='left' colwidth='3*' colname='Description'/>
- <thead>
- <row>
- <entry>Type</entry>
- <entry>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>0x05</entry>
- <entry>GPS Location</entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
- <para>
- This packet provides all of the information available from the
- GPS receiver—position, time, speed and precision
- estimates.
- </para>
- <para>
- GPS Location packets are transmitted once per second during
- all phases of the flight
- </para>
- <table frame='all'>
- <title>GPS Location Packet Contents</title>
- <tgroup cols='4' align='center' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='Offset'/>
- <colspec align='center' colwidth='3*' colname='Data Type'/>
- <colspec align='left' colwidth='3*' colname='Name'/>
- <colspec align='left' colwidth='9*' colname='Description'/>
- <thead>
- <row>
- <entry align='center'>Offset</entry>
- <entry align='center'>Data Type</entry>
- <entry align='center'>Name</entry>
- <entry align='center'>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>5</entry><entry>uint8_t</entry><entry>flags</entry>
- <entry>See GPS Flags table below</entry>
- </row>
- <row>
- <entry>6</entry><entry>int16_t</entry><entry>altitude</entry><entry>m</entry>
- </row>
- <row>
- <entry>8</entry><entry>int32_t</entry><entry>latitude</entry><entry>degrees * 10<superscript>7</superscript></entry>
- </row>
- <row>
- <entry>12</entry><entry>int32_t</entry><entry>longitude</entry><entry>degrees * 10<superscript>7</superscript></entry>
- </row>
- <row>
- <entry>16</entry><entry>uint8_t</entry><entry>year</entry>
- </row>
- <row>
- <entry>17</entry><entry>uint8_t</entry><entry>month</entry>
- </row>
- <row>
- <entry>18</entry><entry>uint8_t</entry><entry>day</entry>
- </row>
- <row>
- <entry>19</entry><entry>uint8_t</entry><entry>hour</entry>
- </row>
- <row>
- <entry>20</entry><entry>uint8_t</entry><entry>minute</entry>
- </row>
- <row>
- <entry>21</entry><entry>uint8_t</entry><entry>second</entry>
- </row>
- <row>
- <entry>22</entry><entry>uint8_t</entry><entry>pdop</entry><entry>* 5</entry>
- </row>
- <row>
- <entry>23</entry><entry>uint8_t</entry><entry>hdop</entry><entry>* 5</entry>
- </row>
- <row>
- <entry>24</entry><entry>uint8_t</entry><entry>vdop</entry><entry>* 5</entry>
- </row>
- <row>
- <entry>25</entry><entry>uint8_t</entry><entry>mode</entry>
- <entry>See GPS Mode table below</entry>
- </row>
- <row>
- <entry>26</entry><entry>uint16_t</entry><entry>ground_speed</entry><entry>cm/s</entry>
- </row>
- <row>
- <entry>28</entry><entry>int16_t</entry><entry>climb_rate</entry><entry>cm/s</entry>
- </row>
- <row>
- <entry>30</entry><entry>uint8_t</entry><entry>course</entry><entry>/ 2</entry>
- </row>
- <row>
- <entry>31</entry><entry>uint8_t</entry><entry>unused[1]</entry>
- </row>
- <row>
- <entry>32</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <para>
- Packed into a one byte field are status flags and the count of
- satellites used to compute the position fix. Note that this
- number may be lower than the number of satellites being
- tracked; the receiver will not use information from satellites
- with weak signals or which are close enough to the horizon to
- have significantly degraded position accuracy.
- </para>
- <table frame='all'>
- <title>GPS Flags</title>
- <tgroup cols='3' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='bits'/>
- <colspec align='left' colwidth='2*' colname='name'/>
- <colspec align='left' colwidth='7*' colname='description'/>
- <thead>
- <row>
- <entry align='center'>Bits</entry>
- <entry align='center'>Name</entry>
- <entry align='center'>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>0-3</entry>
- <entry>nsats</entry>
- <entry>Number of satellites in solution</entry>
- </row>
- <row>
- <entry>4</entry>
- <entry>valid</entry>
- <entry>GPS solution is valid</entry>
- </row>
- <row>
- <entry>5</entry>
- <entry>running</entry>
- <entry>GPS receiver is operational</entry>
- </row>
- <row>
- <entry>6</entry>
- <entry>date_valid</entry>
- <entry>Reported date is valid</entry>
- </row>
- <row>
- <entry>7</entry>
- <entry>course_valid</entry>
- <entry>ground speed, course and climb rates are valid</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <para>
- Here are all of the valid GPS operational modes. Altus Metrum
- products will only ever report 'N' (not valid), 'A'
- (Autonomous) modes or 'E' (Estimated). The remaining modes
- are either testing modes or require additional data.
- </para>
- <table frame='all'>
- <title>GPS Mode</title>
- <tgroup cols='3' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='value'/>
- <colspec align='center' colwidth='3*' colname='name'/>
- <colspec align='left' colwidth='7*' colname='description'/>
- <thead>
- <row>
- <entry align='center'>Mode</entry>
- <entry align='center'>Name</entry>
- <entry align='center'>Decsription</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>N</entry>
- <entry>Not Valid</entry>
- <entry>All data are invalid</entry>
- </row>
- <row>
- <entry>A</entry>
- <entry>Autonomous mode</entry>
- <entry>Data are derived from satellite data</entry>
- </row>
- <row>
- <entry>D</entry>
- <entry>Differential Mode</entry>
- <entry>
- Data are augmented with differential data from a
- known ground station. The SkyTraq unit in TeleMetrum
- does not support this mode
- </entry>
- </row>
- <row>
- <entry>E</entry>
- <entry>Estimated</entry>
- <entry>
- Data are estimated using dead reckoning from the
- last known data
- </entry>
- </row>
- <row>
- <entry>M</entry>
- <entry>Manual</entry>
- <entry>Data were entered manually</entry>
- </row>
- <row>
- <entry>S</entry>
- <entry>Simulated</entry>
- <entry>GPS receiver testing mode</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </section>
- <section>
- <title>GPS Satellite Data</title>
- <informaltable frame='none' label='' tocentry='0'>
- <tgroup cols='2' align='center' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='Offset'/>
- <colspec align='left' colwidth='3*' colname='Description'/>
- <thead>
- <row>
- <entry>Type</entry>
- <entry>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>0x06</entry>
- <entry>GPS Satellite Data</entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
- <para>
- This packet provides space vehicle identifiers and signal
- quality information in the form of a C/N1 number for up to 12
- satellites. The order of the svids is not specified.
- </para>
- <para>
- GPS Satellite data are transmitted once per second during all
- phases of the flight.
- </para>
- <table frame='all'>
- <title>GPS Satellite Data Contents</title>
- <tgroup cols='4' align='center' colsep='1' rowsep='1'>
- <colspec align='right' colwidth='*' colname='Offset'/>
- <colspec align='center' colwidth='3*' colname='Data Type'/>
- <colspec align='left' colwidth='3*' colname='Name'/>
- <colspec align='left' colwidth='9*' colname='Description'/>
- <thead>
- <row>
- <entry align='center'>Offset</entry>
- <entry align='center'>Data Type</entry>
- <entry align='center'>Name</entry>
- <entry align='center'>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>5</entry><entry>uint8_t</entry><entry>channels</entry>
- <entry>Number of reported satellite information</entry>
- </row>
- <row>
- <entry>6</entry><entry>sat_info_t</entry><entry>sats[12]</entry>
- <entry>See Per-Satellite data table below</entry>
- </row>
- <row>
- <entry>30</entry><entry>uint8_t</entry><entry>unused[2]</entry>
- </row>
- <row>
- <entry>32</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <table frame='all'>
- <title>GPS Per-Satellite data (sat_info_t)</title>
- <tgroup cols='4' align='center' colsep='1' rowsep='1'>
- <colspec align='right' colwidth='*' colname='Offset'/>
- <colspec align='center' colwidth='3*' colname='Data Type'/>
- <colspec align='left' colwidth='3*' colname='Name'/>
- <colspec align='left' colwidth='9*' colname='Description'/>
- <thead>
- <row>
- <entry align='center'>Offset</entry>
- <entry align='center'>Data Type</entry>
- <entry align='center'>Name</entry>
- <entry align='center'>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>0</entry><entry>uint8_t</entry><entry>svid</entry>
- <entry>Space Vehicle Identifier</entry>
- </row>
- <row>
- <entry>1</entry><entry>uint8_t</entry><entry>c_n_1</entry>
- <entry>C/N1 signal quality indicator</entry>
- </row>
- <row>
- <entry>2</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </section>
- <section>
- <title>Companion Data Data</title>
- <informaltable frame='none' label='' tocentry='0'>
- <tgroup cols='2' align='center' colsep='1' rowsep='1'>
- <colspec align='center' colwidth='*' colname='Offset'/>
- <colspec align='left' colwidth='3*' colname='Description'/>
- <thead>
- <row>
- <entry>Type</entry>
- <entry>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>0x07</entry>
- <entry>Companion Data Data</entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
- <para>
- When a companion board is attached to TeleMega or TeleMetrum,
- it can provide telemetry data to be included in the
- downlink. The companion board can provide up to 12 16-bit data
- values.
- </para>
- <para>
- The companion board itself specifies the transmission rate. On
- the ground and during descent, that rate is limited to one
- packet per second. During ascent, that rate is limited to 10
- packets per second.
- </para>
- <table frame='all'>
- <title>Companion Data Contents</title>
- <tgroup cols='4' align='center' colsep='1' rowsep='1'>
- <colspec align='right' colwidth='*' colname='Offset'/>
- <colspec align='center' colwidth='3*' colname='Data Type'/>
- <colspec align='left' colwidth='3*' colname='Name'/>
- <colspec align='left' colwidth='9*' colname='Description'/>
- <thead>
- <row>
- <entry align='center'>Offset</entry>
- <entry align='center'>Data Type</entry>
- <entry align='center'>Name</entry>
- <entry align='center'>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>5</entry><entry>uint8_t</entry><entry>board_id</entry>
- <entry>Type of companion board attached</entry>
- </row>
- <row>
- <entry>6</entry><entry>uint8_t</entry><entry>update_period</entry>
- <entry>How often telemetry is sent, in 1/100ths of a second</entry>
- </row>
- <row>
- <entry>7</entry><entry>uint8_t</entry><entry>channels</entry>
- <entry>Number of data channels supplied</entry>
- </row>
- <row>
- <entry>8</entry><entry>uint16_t[12]</entry><entry>companion_data</entry>
- <entry>Up to 12 channels of 16-bit companion data</entry>
- </row>
- <row>
- <entry>32</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </section>
- </section>
- <section>
- <title>Data Transmission</title>
- <para>
- Altus Metrum devices use Texas Instruments sub-GHz digital radio
- products. Ground stations use parts with HW FEC while some
- flight computers perform FEC in software. TeleGPS is
- transmit-only.
- </para>
- <table>
- <title>Altus Metrum Radio Parts</title>
- <tgroup cols='3'>
- <colspec align="center" colwidth="*" colname="Part Number"/>
- <colspec align="center" colwidth="*" colname="Description"/>
- <colspec align="left" colwidth="*" colname="Used in"/>
- <thead>
- <row>
- <entry align="center">Part Number</entry>
- <entry align="center">Description</entry>
- <entry align="center">Used in</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>CC1111</entry><entry>10mW transceiver with integrated SoC</entry>
- <entry>TeleDongle v0.2, TeleBT v1.0, TeleMetrum v1.x, TeleMini</entry>
- </row>
- <row>
- <entry>CC1120</entry><entry>35mW transceiver with SW FEC</entry>
- <entry>TeleMetrum v2, TeleMega</entry>
- </row>
- <row>
- <entry>CC1200</entry><entry>35mW transceiver with HW FEC</entry>
- <entry>TeleDongle v3.0, TeleBT v3.0</entry>
- </row>
- <row>
- <entry>CC115L</entry><entry>14mW transmitter with SW FEC</entry>
- <entry>TeleGPS</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <section>
- <title>Modulation Scheme</title>
- <para>
- Texas Instruments provides a tool for computing modulation
- parameters given a desired modulation format and basic bit
- rate.
-
- While we might like to use something with better low-signal
- performance like BPSK, the radios we use don't support that,
- but do support Gaussian frequency shift keying (GFSK). Regular
- frequency shift keying (FSK) encodes the signal by switching
- the carrier between two frequencies. The Gaussian version is
- essentially the same, but the shift between frequencies gently
- follows a gaussian curve, rather than switching
- immediately. This tames the bandwidth of the signal without
- affecting the ability to transmit data.
-
- For AltOS, there are three available bit rates, 38.4kBaud,
- 9.6kBaud and 2.4kBaud resulting in the following signal
- parmeters:
-
- </para>
- <table>
- <title>Modulation Scheme</title>
- <tgroup cols='3'>
- <colspec align="center" colwidth="*" colname="rate"/>
- <colspec align="center" colwidth="*" colname="deviation"/>
- <colspec align="center" colwidth="*" colname="bandwidth"/>
- <thead>
- <row>
- <entry align='center'>Rate</entry>
- <entry align='center'>Deviation</entry>
- <entry align='center'>Receiver Bandwidth</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>38.4kBaud</entry>
- <entry>20.5kHz</entry>
- <entry>100kHz</entry>
- </row>
- <row>
- <entry>9.6kBaud</entry>
- <entry>5.125kHz</entry>
- <entry>25kHz</entry>
- </row>
- <row>
- <entry>2.4kBaud</entry>
- <entry>1.5kHz</entry>
- <entry>5kHz</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </section>
- <section>
- <title>Error Correction</title>
- <para>
- The cc1111 and cc1200 provide forward error correction in
- hardware; on the cc1120 and cc115l that's done in
- software. AltOS uses this to improve reception of weak
- signals. As it's a rate 1/2 encoding, each bit of data takes
- two bits when transmitted, so the effective data rate is half
- of the raw transmitted bit rate.
- </para>
- <table>
- <title>Error Correction</title>
- <tgroup cols='3'>
- <colspec align="center" colwidth="*" colname="parameter"/>
- <colspec align="center" colwidth="*" colname="value"/>
- <colspec align="center" colwidth="*" colname="description"/>
- <thead>
- <row>
- <entry align='center'>Parameter</entry>
- <entry align='center'>Value</entry>
- <entry align='center'>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>Error Correction</entry>
- <entry>Convolutional coding</entry>
- <entry>1/2 rate, constraint length m=4</entry>
- </row>
- <row>
- <entry>Interleaving</entry>
- <entry>4 x 4</entry>
- <entry>Reduce effect of noise burst</entry>
- </row>
- <row>
- <entry>Data Whitening</entry>
- <entry>XOR with 9-bit PNR</entry>
- <entry>Rotate right with bit 8 = bit 0 xor bit 5, initial
- value 111111111</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </section>
- </section>
- <section>
- <title>TeleDongle packet format</title>
- <para>
- TeleDongle does not do any interpretation of the packet data,
- instead it is configured to receive packets of a specified
- length (32 bytes in this case). For each received packet,
- TeleDongle produces a single line of text. This line starts with
- the string "TELEM " and is followed by a list of hexadecimal
- encoded bytes.
- </para>
- <programlisting>TELEM 224f01080b05765e00701f1a1bbeb8d7b60b070605140c000600000000000000003fa988</programlisting>
- <para>
- The hexadecimal encoded string of bytes contains a length byte,
- the packet data, two bytes added by the cc1111 radio receiver
- hardware and finally a checksum so that the host software can
- validate that the line was transmitted without any errors.
- </para>
- <table>
- <title>Packet Format</title>
- <tgroup cols='4'>
- <colspec align="center" colwidth="2*" colname="offset"/>
- <colspec align="center" colwidth="*" colname="name"/>
- <colspec align="center" colwidth="*" colname="value"/>
- <colspec align="center" colwidth="5*" colname="description"/>
- <thead>
- <row>
- <entry align='center'>Offset</entry>
- <entry align='center'>Name</entry>
- <entry align='center'>Example</entry>
- <entry align='center'>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>0</entry>
- <entry>length</entry>
- <entry>22</entry>
- <entry>Total length of data bytes in the line. Note that
- this includes the added RSSI and status bytes</entry>
- </row>
- <row>
- <entry>1 ·· length-3</entry>
- <entry>packet</entry>
- <entry>4f ·· 00</entry>
- <entry>Bytes of actual packet data</entry>
- </row>
- <row>
- <entry>length-2</entry>
- <entry>rssi</entry>
- <entry>3f</entry>
- <entry>Received signal strength. dBm = rssi / 2 - 74</entry>
- </row>
- <row>
- <entry>length-1</entry>
- <entry>lqi</entry>
- <entry>a9</entry>
- <entry>Link Quality Indicator and CRC status. Bit 7
- is set when the CRC is correct</entry>
- </row>
- <row>
- <entry>length</entry>
- <entry>checksum</entry>
- <entry>88</entry>
- <entry>(0x5a + sum(bytes 1 ·· length-1)) % 256</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- </section>
- <section>
- <title>History and Motivation</title>
- <para>
- The original AltoOS telemetry mechanism encoded everything
- available piece of information on the TeleMetrum hardware into a
- single unified packet. Initially, the packets contained very
- little data—some raw sensor readings along with the current GPS
- coordinates when a GPS receiver was connected. Over time, the
- amount of data grew to include sensor calibration data, GPS
- satellite information and a host of internal state information
- designed to help diagnose flight failures in case of a loss of
- the on-board flight data.
- </para>
- <para>
- Because every packet contained all of the data, packets were
- huge—95 bytes long. Much of the information was also specific to
- the TeleMetrum hardware. With the introduction of the TeleMini
- flight computer, most of the data contained in the telemetry
- packets was unavailable. Initially, a shorter, but still
- comprehensive packet was implemented. This required that the
- ground station be pre-configured as to which kind of packet to
- expect.
- </para>
- <para>
- The development of several companion boards also made the
- shortcomings evident—each companion board would want to include
- telemetry data in the radio link; with the original design, the
- packet would have to hold the new data as well, requiring
- additional TeleMetrum and ground station changes.
- </para>
- </section>
-</article>