Clone wiki

alagna / HowTo

This is a step-by-step guide to using COSMOS_64x64.png with an embedded platform, in this case, an Arduino Uno.
This should only take a few minutes to get started, then the fun begins.

Let's assume you've already installed COSMOS.

  • The installation comes with a demo to let you play around with COSMOS in a sandbox.
  • The GettingStarted page shows you how to create commands and telemetry.
  • Make sure you've seen the 5 minute introduction video to get a drift of each of the COSMOS tools.

COSMOS was designed to support any kind of project and can support multiple projects from a single installation. The best way to use COSMOS is as a generic application to talk to your embedded device, with a project specific configuration. Let's build that project specific configuration now.

Configuring COSMOS

First, make a directory to hold a project.

C:\>mkdir C:\data\blink
C:\>cd C:\data\blink

Blink is the typical "Hello World!" program for Arduino. This time it will have a command to change the blink delay and telemetry indicating the current blink delay. COSMOS will send the command and display the telemetry. In order to do that we need to tell COSMOS about the packets that act as the command and telemetry.

COSMOS is installed as an application (for example my COSMOS is installed in C:\apps\cosmos) and is available to any project on your system. The blink directory is a local configuration to hold the project specific stuff. This directory has many files, but is pretty small and only contains stuff specific to your project. Tell COSMOS to make a project specific configuration folder for your setup.

C:\data\blink>ruby C:\apps\cosmos\Vendor\Ruby\bin\cosmos install blink
Attempting COSMOS  Installation to: blink
mkdir -p blink
cp -r C:/apps/cosmos/Vendor/Ruby/lib/ruby/gems/2.2.0/gems/cosmos-3.7.0/install/. blink

This will create a directory called blink for the cosmos config under C:\data\blink\blink.

 Volume in drive C is OSDisk
 Volume Serial Number is 961E-E870

 Directory of C:\data\blink

2015-11-13  08:42 AM    <DIR>          .
2015-11-13  08:42 AM    <DIR>          ..
2015-11-13  08:42 AM    <DIR>          blink
               0 File(s)              0 bytes
               3 Dir(s)  165,144,932,352 bytes free

I like to think of COSMOS and the Arduino as two sides of a transmission link, so I put my src directory and my COSMOS config side-by-side under my project folder. Let's change this directory structure to something more meaningful.

C:\data\blink>rename blink cosmos

C:\data\blink>mkdir src

 Volume in drive C is OSDisk
 Volume Serial Number is 961E-E870

 Directory of C:\data\blink

2015-11-13  09:11 AM    <DIR>          .
2015-11-13  09:11 AM    <DIR>          ..
2015-11-13  09:11 AM    <DIR>          cosmos
2015-11-13  09:11 AM    <DIR>          src
               0 File(s)              0 bytes
               4 Dir(s)  165,138,911,232 bytes free

Now you can run C:\data\blink\cosmos\Launcher.bat to start COSMOS. Right now it's got a few commands and telemetry for the COSMOS server. In Launcher, start the Command and Telemetry Server and surf around the tabs to see what's going on. There isn't much to see, but that's ok. We'll fix that in a minute.

Launcher.png CTSrvrInterfaces.png

When you're done looking around, close the COSMOS Command and Telemetry Server.

Now to our specific info. This is where we define the actual bits of the commands and telemetry packets specific to our device.

Commands and Telemetry Configuration

C:\data\blink>cd cosmos\config\targets

C:\data\blink\cosmos\config\targets>mkdir blink

C:\data\blink\cosmos\config\targets>cd blink

C:\data\blink\cosmos\config\targets\blink>mkdir cmd_tlm

C:\data\blink\cosmos\config\targets\blink>cd cmd_tlm

Configure Commands

Edit cmd.txt

C:\data\blink\cosmos\config\targets\blink\cmd_tlm>notepad cmd.txt


COMMAND blink delay BIG_ENDIAN "Command to change how fast to blink the LED."
  APPEND_PARAMETER delay 8 uint 0 255 1 "Delay (ms) between LED blinks."

Configure Telemetry

Edit tlm.txt:

C:\data\blink\cosmos\config\targets\blink\cmd_tlm>notepad tlm.txt


TELEMETRY blink soh BIG_ENDIAN "State of health of the blink application."
  APPEND_ITEM length 8 UINT "Packet size so COSMOS can read the serial port."
  APPEND_ID_ITEM pktid 8 UINT 1 "Packet id so COSMOS can identify the packet and store it."
  APPEND_ITEM delay 8 UINT "Current delay value (ms) between LED blinks."


Make multiple packets to be written to the serial port. Both for commands (from COSMOS to the Arduino) and for telemetry (from the Arduino to COSMOS). Each should have a unique ID_ITEM so COSMOS can differentiate between packet contents. Hint: The 1 in "APPEND_ID_ITEM pktid 8 UINT 1" is a hard-coded value indicating the id number of the SOH packet. The command in this example doesn't have an ID_ITEM yet and the processCmds function below doesn't parse it either. That's left for the reader.

The default system configuration comes out of the box automatically decoding the targets directory. Any configuration in the targets directory is available to attach to with an interface. Now we have to tell COSMOS about the protocol we'll use to communicate with our device. The cmd_tlm_server configuration configures parameters about that interface connection.

Configure the Input / Output interface

COSMOS comes with the following interface types:

  • tcp-ip
  • udp
  • serial - this is what we'll use. Notice the "serial_interface.rb" below.

or you can write your own (eg: xBee, Bluetooth LE, etc.)

Edit config/targets/blink/cmd_tlm_server.txt

INTERFACE BLINKINT serial_interface.rb com5 com5 9600 NONE 1 10.0 nil LENGTH 0 8 0 1

NOTE: com5 is where the Arduino lives in my setup. You'll need to use the Arduino IDE to find where yours lives. Pull down the Tools menu, select Port, and find the port that says "comX (Arduino <YOUR BOARD>)."

NOTE: COSMOS is written in an interpreted language, Ruby, so a lot of using it is reading its code. The parameters for the serial_interface are in the COSMOS installation folder. /path/to/cosmos/Vendor/Ruby/lib/ruby/gems/<rubyversion>/gems/cosmos-<cosmosversion>/lib/cosmos/interfaces/serial_interface.rb.

That finishes the configuration of COSMOS for now. We have a definition for 1 command and 1 telemetry packet. Remember, this is a trivial example. COSMOS installations routinely have dozens of interfaces, each with hundreds of packets, to all sorts of devices, like power supplies, simulations, and whole spacecraft worth of commands and telemetry in the same project folder. A single installation can easily have many hundreds of commands, many thousands of telemetry points, and can flow data at GBs/s.

As you work with the configuration and begin operating your device, you'll become familiar with the COSMOS directory structure. You'll find telemetry logs that were recorded while you were testing. They are useful for post-processing your device's telemetry to find issues. There are command and telemetry handbooks in HTML or PDF (click Handbook Creator on the Launcher) that are automatically generated. Etc.

When you run COSMOS, it opens these config files, parses the configuration into its internal database, and the Command and Telemetry server will start processing packets when you open it.

Next, we need to have a piece of hardware that can read the serial line, decode the command packet, run the normal blink Loop, and output the telemetry packet that contains the delay value as commanded (or the default).

That happens inside the Arduino...

Once we get the Arduino blinking the LED we'll setup tlm display screens and do some graphing.

Programming the Arduino

Now that COSMOS is ready let's build the Sketch. Running from the familiar blink sketch gives a great starting point and only needs to be changed to add:

  • A function to read the serial line and process the delay command
  • A function to send the State Of Health packet to the control interface.

Note: COSMOS must identify the tlm packet and our defined interface uses length as the method to determine when packets are complete, so our tlm needs to contain an id and a length field. That means we need to jump right past a lot of the normal "Hello World!" stuff and write multiple bytes to the serial and declare a struct to hold the data.

I've modified the Blink example with these necessary functions.

  Turns on an LED on for one second, then off for one second, repeatedly.

  Most Arduinos have an on-board LED you can control. On the Uno and
  Leonardo, it is attached to digital pin 13. If you're unsure what
  pin the on-board LED is connected to on your Arduino model, check
  the documentation at

  This example code is in the public domain.

  modified 8 May 2014
  by Scott Fitzgerald

struct soh_t
  byte length;
  byte id;
  byte delay;

// Global variable to hold State of Health tlm packet.
soh_t mySoh;

// the setup function runs once when you press reset or power the board
void setup()
{ = 1;
  mySoh.delay = 250;
  pinMode(13, OUTPUT); // initialize digital pin 13 as an output.
  Serial.begin(9600);  // initialize serial:

// the loop function runs over and over again forever
void loop()
  digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(mySoh.delay);              // wait for a second
  digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW

void processCmds()
  while (Serial.available())
    // get the new byte:
    mySoh.delay =;  

void sendTlm()
  mySoh.length = sizeof(mySoh);
  writeTlm((const char*)&mySoh, sizeof(mySoh));

void writeTlm(const char* pkt, byte size)
  for(int i=0; i<size; i++)

Upload the sketch and you'll see the LED start flashing at 2 Hz (250ms on, 250ms off for a total of 500ms per cycle).

Running COSMOS

Start COSMOS by double clicking on C:\data\blink\cosmos\Launcher.bat and accepting the legal dialog.


The Command and Telemetry Server is the heart of COSMOS

Start the Cmd&Tlm server by clicking the button and then click the "OK" button on the Command and Telemetry Server Options dialog. You should see two interfaces. One for BLINKINT and one for COSMOSINT. Notice that Bytes Rx and Tlm Pkts are both counting up.


Move to the Tlm Packets tab and see Packet Count is increasing.


Packet Viewer

Click the "View in Packet Viewer" button beside the BLINK SOH packet. This brings up a generic tool to display all the fields of a tlm packet. It's a built in tool you get right out of the box with COSMOS and any packet defined shows up in the pull-down menus at the top.


Telemetry Grapher

Right click on the Delay value: 250 and select "Graph BLINK SOH DELAY." You should see a real-time graphical display of the delay value that's being produced in state of health tlm.


That's pretty nifty, but until it changes it doesn't really mean that much. Let's change it.

Command Sender

Go back to the Launcher and click on "Command Sender."


Because there is only one cmd defined in the system, the BLINK DELAY command comes up already selected. Change the Value beside DELAY to 50 and click the Send button. You should see the graph change to 50 and now look at the Arduino. See how fast the LED is blinking?


Also note: Since the LED blink delay determines how fast Loop runs, look at the difference in how fast the tlm is coming in. The graph now looks like a solid line instead of a bunch of little squares on a line.

Ok, let's run over one more COSMOS tool before we wrap up this section of the HowTo.

Script Runner

Go back to Launcher and start Script Runner.


Script runner interprets Ruby to create automated test scripts. Let's make one now.

4.upto(255) do |i|
  cmd("BLINK DELAY with DELAY #{i}")

This script starts sending commands to Blink with delay of 4 up to 255. Get your Tlm Grapher ready before we start. Watch the graph and watch your LED.

And... click Start.

The LED started out so fast it looked like a solid light and then slowed down as commands modified the blink delay.




The script ran so fast some of the commands were probably missed.


Add 2 tlm points to SOH: cmds_accepted and cmds_received. Increment them during ProcessCmds().

void processCmds()
  bool gotOne=false;

  while (Serial.available())
    // get the new byte:
    mySoh.delay =;  
    mySoh.cmds_accepted++; // Since we only use the last value received,
                           // each call to processCmds() is only 1 cmd accepted.

Add the tlm points to both the sketch (upload it) and to tlm.txt (restart C&T svr). Do that first script again to see that there is actually a problem. Look for a difference between cmds_accepted and cmds_received by plotting them both in TlmGrapher or by viewing the values in PacketViewer.


Since blink is such a simple example and the cmd processing rate is tied to the delay value, solving it isn't important here. Updating the script is a quick fix but shows how cmds and tlm are tied together.


The Arduino IDE can't upload a modified sketch to the board while COSMOS is attached to the serial port. In the C&T Server go back to the "Interfaces" tab and click "Disconnect" before trying to upload to your board. Of course, you'll also have to reconnect after the upload before you'll be able to send commands or receive telemetry.

Let's slow that down a little and check soh tlm in between each cmd.

4.upto(255) do |i|
  cmd("BLINK DELAY with DELAY #{i}")
  wait_check("BLINK SOH DELAY == #{i}", 5)

Now run it again and notice the delay starts out small and fast and then slows down as the script runs.


Now, use the "Context Window" at the bottom of TlmGrapher to zoom out on the view of these two plots.


Next up: Telemetry screens and Limits