The main PCB carries an ATxmega384C3 microcontroller that is responsible for reading the various sensors, sending telemetry data, accepting telecommands, storing the data on an SD card, and some other house-keeping tasks.

The software is written primarily in C with some parts being optimized in assembly language. It is licensed under GPLv3+ and can be found on GitLab.

Among many other components, the software is a critical part for the experiment: there are hard real-time constraints, e.g. the sampling time has to be accurate and syncronous, and events and signals must be processed in time. Furthermore, the software has to continue operation without influencing other tasks, even if a peripheral component fails.

We do not use an operating system, because it would increase the complexity to verify and implement the timing constraints. Instead, we implement static scheduling and tasking ourself using a single timer interrupt. This is the only allowed interrupt in our system. This time triggered approach is used instead of events/interrupts to again simplify the verification. In an event triggered system, it is very difficult to determine if deadlines are met under overload conditions, whereas a time triggered system is static in what action is done when. To proove or verify that a task fits in its assigned CPU time slot, a simple but effective method is used: counting assembler instructions.


The microcontroller has to compute a couple of tasks that have to run quasi-parallel. The list below gives an overview over the top level tasks:

  1. Acceleration from Fibers
    Triggers the 16-bit ADCs to sample the photocurrents of the optical channels, each with a primary and a secondary light path. The trigger signal is given via a PWM output from a hardware timer and therefore is very accurate throughout the experiment (basically the accuracy of a CPU cycle). After sampling, the values are read from the ADCs one after the other via SPI and bufferd in RAM.
  2. Acceleration from Reference Sensor
    Besides the optical acceleration sensors, also a classic, electrical MEMS acceleration sensor is used. Its measurement data is later evalueated to check the plausibility of the optical measurements.
  3. High Resolution Temperature
    Attached to each optical chip, an NTC measures the temperature which is sampled via a 16-bit ADC.
  4. Low Resolution Temperature
    There are some more sensors that are less accurate than the before mentioned ones. This includes two 12-bit temperature sensors, one close to the microcontroller on the main PCB and another one at the reference acceleration sensor PCB. Furthermore, we also measure the supply and reference voltages of the fiber ADCs, and also try to use the internal temperature sensor in the microcontroller. As using the microcontroller’s ADC is a bit difficult due to how the ATxmega ADCs are built, we do not rely on these values, but it is nice to have them.
  5. Telemetry
    Before and during the flight, a tiny fraction of our experiment data is sent to the groundstation (downlink) via the telemetry interface provided by the Rexus Service Module. The downlink speed is very limited (38k4 baud with some milliseconds delay between every 24 bytes) so the flight time would not be long enough to transmit all the samples in full accuracy.
  6. Telecommand
    When the rocket is at the launchpad, it is connected to the groundstation via a so called umbilical. During that time, it is also possible to send data to the experiment (uplink), which in our case are commands, for example, to perform a software reset, repeat the selftest, or switch on/off the light source. The umbilical automatically disconnects at lift-off, so we cannot send commands to the experiment during flight – it has to run on its own.
  7. SD Card
    As we cannot send all our scientific data via downlink to the groundstation, we need another data storage, which is an SD card in our case. It is connected to a separate off-the-shelf PCB with an SD card controller that handles the FAT filesystem and file writing.
  8. RXSM Signal Sample
    Samples the LO, SOE, and SODS (lift-off, start of experiment, and stop of data storage) signals from the Rexus Service Module three times, and then does majority voting on which signal to be used. This increases the robustness against glitches on the signal wires that could be mistaken for valid signals otherwise, e.g. compared to when using an edge triggered hardware interrupt.
  9. Task Loader
    All tasks provide a similar interface, e.g. to be started or stopped, which task handlers (functions) to call when etc. The Task Loader can be seen as a meta-task, or a task that monitors and controls the other tasks. For example, data is written to the SD card only if the SOE signal is given, but not when SODS is given. In case a task is blocked because of failure of a peripheral component, it will reset the task and associated periphery a couple of times and retry to execute it. If this repair mechanism does not succeed, the task is deactivated and the experiment runs in a degraded mode, but still runs and other tasks are not degraded.


Scheduling is the process of assigning a task to the CPU for a specific amount of time. The order when a task is executed is static and follows the scheduling plan shown below:

Assignment of CPU time slots to tasks.

Assignment of CPU time slots to tasks.

The microcontroller runs through the table left-to-right and top-to-bottom. The table is implemented as a two dimensional function pointer array with the function being called from the timer interrupt service routine (ISR). This ensures almost constant call times of the functions: including the loading of the ISR, the jitter is only a couple of clock cycles.

While a task slot is 21.7us long, it is not the available time for a task, because it includes the time for the scheduler ISR to load and call the function. Therefore, the effective time for a task is about 18us.