diff --git a/Arduino.ino b/Arduino.ino
new file mode 100644
index 0000000000000000000000000000000000000000..7a219ecd995d5a603eadd81b23b6c65c2449fffc
--- /dev/null
+++ b/Arduino.ino
@@ -0,0 +1,424 @@
+/*!
+ * @file Arduino.ino
+ *
+ * This Arduino sketch is designed for an Arduino Nano, with which two NeoPixel 
+ * rings from Adafruit are connected. It is assumed that both rings have 16 LEDs 
+ * each. 
+ * 
+ * This code uses Adafruit's Neopixel library, which is released under a GNU Lesser 
+ * General Public License.
+ * 
+ * Objective:
+   This sketch should make it possible to use the Arduino Nano to play animation on 
+   the two connected NeoPixel rings. Since the memory of the Nano is very limited, 
+   there is the functionality to load animations via the serial interface.
+ *
+ * Let the left NeoPixel ring be abbreviated to:  lR 
+ * Let the right NeoPixel ring be abbreviated to: rR
+ * 
+ * Wiring:
+   Arduino pin 6   -> lR Data Input
+   Arduino pin 7   -> rR Data Input
+   Arduino pin 5V  -> lR Power
+   Arduino pin 5V  -> rR Power
+   Arduino pin GND -> lR Ground
+   Arduino pin GND -> rR Ground
+ */
+
+#include <Adafruit_NeoPixel.h>
+
+#define MSG_SIZE 50   // Expected size of a received message in bytes.
+#define BUF_SIZE 16   // Maximum number of frames that can be stored in either frame 
+                      // buffer.
+#define L_PIN     6   // Arduino pin that is connected to the left NeoPixel ring.
+#define R_PIN     7   // Arduino pin that is connected to the right NeoPixel ring.
+#define PIXELS   16   // Number of pixels on either NeoPixel ring.
+
+/*
+* To make the serial communication a little more robust, all serial requests are 
+* answered by the Nano. Furthermore, the Nano only receives 50-bit messages and 
+* only sends 8-bit messages. The serial buffer is also emptied before each written 
+* message in order to be able to react to the following incoming message.
+*
+* There are two types of messages, data messages and instruction messages. Data 
+* messages are used to convey the animation frames, while instruction messages are 
+* used to convey instructions, which the Nano then executes.
+*/
+
+// Variables used for communication.
+
+uint8_t msg[MSG_SIZE];    // Holds a received message.
+int     msg_size;         // Determines how many bits of a message are received.
+bool    rcvd_msg;         // Determines if all 50 bits of a message are received.
+bool    rcvg_animation;   // Determines if an animation is currently been received.
+int     msgs_to_rcv;      // If an animation is received: Determines the number of 
+                          // (data) messages that still have to be received.
+
+/*
+* Every animation consists of frames. A frame describes the colors of all 16 
+* pixels on one NeoPixel ring. Since two NeoPixel rings are connected to the 
+* Arduino, each animation consists of at least two frames, one frame for the left 
+* ring and one frame for the right ring. To play an animation, two frames are 
+* displayed in parallel. The term frame ensemble or ensemble is used to refer to 
+* these two frames that play in parallel.
+*/
+
+// Variables used for animation storage.
+
+int values_per_frame;   // Number of bytes that are needed to store an entire 
+                        // frame. 
+
+uint8_t **    l_frame_buffer;   // Stores all animation frames for the left 
+                                // NeoPixel ring.
+uint8_t **    r_frame_buffer;   // Stores all animation frames for the right 
+                                // NeoPixel ring.
+uint8_t       num_ensembles;    // Number of frame ensembles in the animation.
+uint8_t       num_iterations;   // Number of times the animation is repeated.
+unsigned long frame_time;       // Delay in milliseconds between each displayed 
+                                // frame ensemble.
+
+// Variables used for animation playback.
+
+bool    animation_loaded;   // Determine if an animation is loaded. 
+bool    playback;           // Determine if animation should be played.
+long    start_time;         // Time at which each individual frame ensemble 
+                            // started to be displayed.
+uint8_t curr_ensemble;      // Frame ensemble that is currently displayed.
+uint8_t curr_iteration;     // Animation iteration that is currently played.
+
+// Variables used for NeoPixel ring.
+
+Adafruit_NeoPixel l_pixels(PIXELS, L_PIN, NEO_GRB + NEO_KHZ800);
+Adafruit_NeoPixel r_pixels(PIXELS, R_PIN, NEO_GRB + NEO_KHZ800);
+
+void setup()
+{
+  msg_size       = 0;
+  rcvd_msg       = false;
+  rcvg_animation = false;
+  msgs_to_rcv    = 0;
+  
+  // Three color values (red, green, blue) ​​must be saved for each pixel. 
+  values_per_frame = PIXELS * 3;
+
+  animation_loaded = false;
+  playback         = false;
+  start_time       = 0;
+  curr_ensemble    = 0;
+  curr_iteration   = 0;
+  
+  init_frame_buffers();
+
+  l_pixels.begin();
+  r_pixels.begin();
+
+  Serial.begin(57600);
+}
+
+/*!
+  @brief  Allocates memory for the two frame buffers.
+
+  @note   The two frame buffers each have the structure of a 2D array in which 
+          16 frames are stored. Each frame consists of 48 bytes of color 
+          information. A total of 1536 bytes are allocated in this function.
+*/
+void init_frame_buffers()
+{
+  l_frame_buffer = (uint8_t **) malloc(sizeof(uint8_t *) * BUF_SIZE);
+  r_frame_buffer = (uint8_t **) malloc(sizeof(uint8_t *) * BUF_SIZE);
+  
+  for (int i = 0; i < BUF_SIZE; i++)
+  {
+    l_frame_buffer[i] = (uint8_t *) malloc(sizeof(uint8_t) * values_per_frame);
+    r_frame_buffer[i] = (uint8_t *) malloc(sizeof(uint8_t) * values_per_frame);
+  }
+}
+
+/*!
+  @brief  Sends a 8-bit message via the serial connection. The serial buffer 
+          is emptied beforehand in order to react to following incoming messages.
+  
+  @param  msg   8-bit message from Arduino.
+
+  @note   This function is used to respond to incomming messages.
+*/
+void respond(uint8_t msg)
+{
+  while (Serial.available() > 0) Serial.read(); // Flush serial buffer.
+  Serial.write(msg);
+}
+
+/*!
+  @brief  This function sends the color information in the two frame buffers to the 
+          NeoPixel rings. The frame ensembles are shown delayed depending on the 
+          animation speed. In addition, the animation is repeated depending on the 
+          desired iterations. 
+*/
+void play_animation()
+{  
+  if (curr_ensemble < num_ensembles)
+  {
+    if (millis() > frame_time + start_time)
+    {   
+      for (int i = 0; i < PIXELS; i++) 
+      { 
+        int pixel = i * 3;
+        
+        uint8_t r; 
+        uint8_t g;
+        uint8_t b;
+
+        r = l_frame_buffer[curr_ensemble][pixel + 0];
+        g = l_frame_buffer[curr_ensemble][pixel + 1];
+        b = l_frame_buffer[curr_ensemble][pixel + 2];
+        l_pixels.setPixelColor(i, l_pixels.Color(r, g, b));
+
+        r = r_frame_buffer[curr_ensemble][pixel + 0];
+        g = r_frame_buffer[curr_ensemble][pixel + 1];
+        b = r_frame_buffer[curr_ensemble][pixel + 2];
+        r_pixels.setPixelColor(i, r_pixels.Color(r, g, b)); 
+      }
+    
+      l_pixels.show();
+      r_pixels.show();
+
+      start_time = millis();
+      curr_ensemble++;
+    }
+  }
+  
+  if (curr_ensemble >= num_ensembles)
+  {
+    if (millis() > frame_time + start_time) 
+    {
+      if (num_iterations != 0xFF) curr_iteration++; // Animation is looped indefenitly.
+      if (curr_iteration >= num_iterations)
+      {
+        reset_playback();
+        respond(0x4F); // Animation successfully played!
+      }
+      else curr_ensemble = 0;
+    }
+  }
+}
+
+/*!
+  @brief  Executes the appropriate function depending on the instruction read 
+          from a received instruction message.
+*/
+void handle_instruction()
+{
+  switch ((char) msg[1])
+  {
+    case 'A':
+      load_animation();
+      break;
+    case 'B':
+      start_playback();
+      break;
+    case 'C':
+      pause_playback();
+      break;
+    case 'D':
+      resume_playback();
+      break;
+    case 'E':
+      reset_display();
+      break;
+    default:
+      respond(0xF2); // Instruction was not recognized.
+      break;
+  }
+}
+
+/*!
+  @brief  Breaks down an instruction message into its individual components.
+*/
+void load_animation()
+{
+  if (msg[2] % 2 != 0)              respond(0xF7); // Unequal number of frames for the 
+                                                   // left and right NeoPixel ring.
+  else if (msg[2] * 0.5 > BUF_SIZE) respond(0xF0); // Animation has to many frame ensembles.
+  else if (msg[2] * 0.5 == 0x00)    respond(0xF8); // Animation has no frame ensemble.
+  else if (msg[7] == 0x00)          respond(0xF6); // Animation has no iteration.
+  else
+  {
+    reset_playback();
+
+    num_ensembles  = msg[2] * 0.5;
+    frame_time     = msg[3];
+    frame_time     = (frame_time << 8) + msg[4];
+    frame_time     = (frame_time << 8) + msg[5];
+    frame_time     = (frame_time << 8) + msg[6];
+    num_iterations = msg[7]; 
+
+    animation_loaded = false;
+    rcvg_animation   = true;
+    msgs_to_rcv      = msg[2];
+
+    respond(0x0F); // Waiting for frames to be send.
+  }
+}
+
+/*!
+  @brief  Starts animation playback.
+*/
+void start_playback()
+{
+  if (animation_loaded)
+  {
+    playback      = true;
+    start_time    = millis() - frame_time;
+    curr_ensemble = 0;
+
+    respond(0x1F); // Animation playback has been started.
+  }
+  else respond(0xF1); // No animation is loaded.
+}
+
+/*!
+  @brief  Pauses animation playback
+*/
+void pause_playback()
+{
+  if (animation_loaded)
+  {
+    playback = false;
+
+    respond(0x5F); // Animation playback has been paused.
+  }
+  else respond(0xF1); // No animation is loaded.
+}
+
+/*!
+  @brief  Resumes animation playback.
+*/
+void resume_playback()
+{
+  if (animation_loaded && !playback)
+  {
+    playback  = true;
+    start_time = millis() - frame_time;
+        
+    respond(0x6F); // Animation playback has been resumed.
+  }
+  else if (playback) respond(0xF5); // Animation is playing.
+  else               respond(0xF1); // No animation is loaded.
+}
+
+/*!
+  @brief  Resets all animation playback parameters. 
+*/
+void reset_playback()
+{
+  playback       = false;
+  start_time     = 0;
+  curr_ensemble  = 0;
+  curr_iteration = 0;
+}
+
+/*!
+  @brief  Clears both NeoPixel rings.
+*/
+void reset_display()
+{
+  l_pixels.clear();
+  r_pixels.clear();
+  l_pixels.show();
+  r_pixels.show();
+
+  respond(0x7F); // Displays have been cleared.
+}
+
+/*!
+  @brief  Loads receiving data messages into one of the frame buffers. 
+
+  @note   Each animation consists of an even number of frames. All even frames in an 
+          animation are stored in the left frame buffer and all odd frames in the 
+          right one.
+*/
+void handle_data()
+{
+  if (rcvg_animation && msgs_to_rcv > 0)
+  {
+    int frame = 0.5 * (2 * num_ensembles - msgs_to_rcv); // Data type int always rounds 
+                                                         // off a floating point number.
+    for (int i = 0; i < values_per_frame; i++)
+    {
+      if (msgs_to_rcv % 2 == 0) l_frame_buffer[frame][i] = msg[i + 1];
+      else                      r_frame_buffer[frame][i] = msg[i + 1];
+    }
+    
+    msgs_to_rcv--;
+    
+    if (msgs_to_rcv == 0)
+    {
+      rcvg_animation   = false;
+      animation_loaded = true;
+      respond(0x3F); // Last frame successfully received.
+    }
+    else respond(0x2F); // Frame successfully received.
+  }
+  else respond(0xF3); // No data message expected.
+}
+
+/*!
+  @brief  Responds to wrong formated message.
+*/
+void handle_wrong_format()
+{  
+  respond(0xF4); // Message has wrong format.
+}
+
+/*!
+  @brief  Loades a received message form the serial buffer into memmory.
+
+  @note   Data messages as well as instruction messages always have a length 
+          of 50 bits.
+*/ 
+void read_serial() 
+{
+  while (Serial.available() > 0) 
+  {
+    if (msg_size < MSG_SIZE) 
+    {
+      msg[msg_size] = Serial.read();
+      msg_size++;
+    }
+    if (msg_size >= MSG_SIZE)
+    {
+      rcvd_msg = true;
+      break;
+    }
+  }
+}
+
+/*!
+  @brief  First, checks if a message is received. If thats the case determines if the
+          message is a data or an instruction message and preecedes accordingly. If the 
+          received message is neither one of the two, informs the communication partner.
+          Secondly, checks if a message is currently beeing send to the Nano. If thats 
+          the case, writes the message to memory.
+          Thirdly, if an animation is loaded and if the animaiton should be played, 
+          plays the loaded animation.
+  
+  @note   Data messages beginn and end with ascii encoded curling brackets.
+          Instruction messages beginn and end with ascii encoded square brackets. 
+*/
+void loop() 
+{
+  if (rcvd_msg) 
+  {
+    char startMarker = msg[0];
+    char endMarker   = msg[MSG_SIZE - 1];
+
+    if      (startMarker == '[' && endMarker == ']') handle_instruction();
+    else if (startMarker == '{' && endMarker == '}') handle_data();
+    else                                             handle_wrong_format();
+
+    rcvd_msg = false;
+    msg_size = 0;
+  }   
+  else if (Serial.available() > 0)       read_serial();
+  else if (playback && animation_loaded) play_animation();
+}