diff --git a/docs/hepialight.md b/docs/hepialight.md
new file mode 100644
index 0000000000000000000000000000000000000000..6f4a0bb71c016e16adf5b59166bf7fce85b99d29
--- /dev/null
+++ b/docs/hepialight.md
@@ -0,0 +1,49 @@
+# Documentation hepialight
+
+## Programmation de la carte hepialight
+
+Pour programmer les cartes hepialight, il faut appuyer sur le bouton reset (situé à l'arrière de la carte) en même temps de la brancher à un pc. Ou alors, appuyer longuement sur le bouton lorsqu'elle est déjà branchée. La carte va ensuite apparaitre comme une carte mémoire. Il faut ensuite glisser les 3 fichiers présents dans `src/hepialight` dans la carte. Une fois que les fichiers sont copiés, il suffit d'ejecter la carte, et d'attendre le tick vert sur les LEDs.
+
+NOTE: Les cartes bugs très souvent lors de la programmation. Il faut utiliser une machine windows.
+
+## Pinout des cartes
+
+Chaque carte possède 4 ports nommés Nord, Est, Sud, Ouest. Chaque port a le même pinout : 
+
+1. CAN_L
+2. CAN_H
+3. **TXD**
+4. GND
+5. VCC
+6. VCC
+7. GND
+8. **RXD**
+9. CAN_H
+10. CAN_L
+
+La pin 1 est notée d'un point blanc sur le pcb.
+
+
+## Communication entre hepialight
+
+Les cartes hepialight communiquent en UART entre elles. Afin d'envoyer des commandes entre les cartes, nous avons mis en place des commandes. Voici les commandes : 
+
+- **PING** - vérification de présence
+- **SET_ID** - Set l'id d'une carte
+- **DISP_ID** - Demande à une carte d'afficher son ID sur la matrice
+- **TEXT** - Demande à une carte d'afficher du texte
+- **MOVING** - Demande à une carte d'afficher du texte sur plusieurs matrices
+- **IMAGE** - Demande à une carte d'afficher un buffer
+- **PT** - *PassThrough* Indique que la commande doit être transmise à une autre carte
+
+Pour envoyer les commandes, il suffit d'utiliser les commandes appropriées. Les fonctions sont les suivantes : 
+
+- **check_presence** - Envoie la commande PING
+- **send_text_xy** - Envoie du text à afficher sur une matrice spécifique
+- **send_moving_xy** - Envoie du text à afficher sur plusieurs matrices (le texte commence à la matrice x,y et déroule de droite à gauche).
+
+## Clusters de carte
+
+Nous appelons un cluster, plusieurs cartes hepialight connectées ensemble, avec un esp. Nous avons défini que la carte avec l'esp est la carte en bas à gauche, et l'ESP est connecté au Sud ou à L'Ouest. Au démarage chaque carte va chercher l'ESP en lui envoyant une commande `ESP`. Si il est présent il répond par `OK`.
+
+La carte connectée à l'ESP a l'ID 0,0. Cette carte va ensuite update l'ID de ses voisins, qui vont eux aussi update l'ID de leurs voisins. De cette manière, nous pouvons attribuer un ID à toutes les matrices présentes.
\ No newline at end of file
diff --git a/src/hepialight/main.py b/src/hepialight/main.py
index 32ba92e2668ac66a9be2b3f2544e284912039184..26e388e96b1bde975e0c27c8745acdfa48411e1f 100644
--- a/src/hepialight/main.py
+++ b/src/hepialight/main.py
@@ -1,22 +1,46 @@
+# Global variables
+
 id = [0,0]
 matsize = [0, 0]
 esp_dir = 0
  
 
-# Display and images functions
 def color16_to_32(color):
+    """transform a 16 bits color (565) into a 24 bits color
+
+    Args:
+        color (int): 16 bits color in 565 format
+
+    Returns:
+        int: 24 bits color (8 bits per component)
+    """
+
     color = int(color)
     r = ((color >> 11) & 0x1F) * 2**3
     g = ((color >> 5) & 0x3F) * 2**2
     b = (color & 0x1F) * 2**3
     return r << 16 | g << 8 | b
 
+
 def disp_img_data(data):
+    """Displays a buffer on the LEDs
+
+    Args:
+        data (List(int)): List of 24 bits colors to be displayed on each pixels
+    """
     for i in range(NBR_LIGNES):
         for j in range(NBR_COLONNES):
             allumer_led(j, NBR_LIGNES-1-i, data[i * NBR_COLONNES + j])
 
 def data_to_color16(data):
+    """Transform the bytes received in usable 24 bits colors
+
+    Args:
+        data (bytes): Bytes received by the UART transmission
+
+    Returns:
+        List(int): List of 24 bits colors
+    """
     d_color16 = []
 
     for i in range(0, len(data), 2):
@@ -25,13 +49,29 @@ def data_to_color16(data):
     return list(map(color16_to_32, d_color16))
 
 def display_id():
+    """Display the matrix's ID on it's LEDs
+    """
     afficher_texte("{}, {}".format(id[0], id[1]), speed=0.01)
  
 def msg_to_str(msg):
+    """Transform a byte array received via uart to a string array
+
+    Args:
+        msg (Bytes): Bytes received via uart
+
+    Returns:
+        str: Message as a string
+    """
     return str(msg)[2:-1]
  
-# Used by the send_xy functions
 def send_passthrough_str(msg, x, y):
+    """Send a passthrough command to a specific matrix, this function only work with text
+
+    Args:
+        msg (str): command to send to the x,y matrix
+        x (int): x pos of the matrix
+        y (int): y pos of the matrix
+    """
     x = int(x)
     y = int(y)
 
@@ -46,8 +86,15 @@ def send_passthrough_str(msg, x, y):
 
     envoyer_msg(d, "PT;{},{};{}".format(x, y, msg))
 
-# Not meant to be used by the user
 def send_passthrough_bytes(msg, x, y):
+    """Send a passthrough command to a specific matrix. This function should not be called by the user,
+    it's only used when the hepialight received a PT that still needs to be transmitted 
+
+    Args:
+        msg (Bytes): Bytes received via uart
+        x (int): x pos of the matrix
+        y (int): y pos of the matrix
+    """
     x = int(x)
     y = int(y)
 
@@ -62,19 +109,53 @@ def send_passthrough_bytes(msg, x, y):
 
     envoyer_msg(d, msg)
 
-# Send commands to a specific matrix
+
 def send_xy(x, y, msg):
+    """Send a command to a matrix in the x, y position, this function is a wrapper for send_passthrough
+
+    Args:
+        x (int): x pos of the matrix
+        y (int): y pos of the matrix
+        msg (str): command to send
+    """
     send_passthrough_str(msg, x, y)
 
+
 def send_text_xy(x, y, text, color=ROUGE, speed=0.1):
+    """Tells a matrix to display text. The text will move on the matrix but not on neighbours
+
+    Args:
+        x (int): x pos of the matrix
+        y (int): y pos of the matrix
+        text (str): text to be displayed
+        color (int, optional): 24 bits color of the text. Defaults to ROUGE.
+        speed (float, optional): speed of the scrolling text. Defaults to 0.1.
+    """
     send_xy(x, y, "TEXT;{};{};{}".format(color, speed, text))
 
 def send_moving_xy(x, y, text, color=ROUGE, speed=0.1):
+    """Tells a matrix to display moving text, it makes the text move on a matrix and continue
+    on it's western neighbours
+
+    Args:
+        x (int): x pos of the matrix
+        y (int): y pos of the matrix
+        text (str): text to be displayed
+        color (int, optional): 24 bits color of the text. Defaults to ROUGE.
+        speed (float, optional): speed of the scrolling text. Defaults to 0.1.
+    """
     send_xy(x, y, "MOVING;{};{};{}".format(color, speed, text))
 
 
-# Check if there is a connected matrix in the d direction
 def check_presence(d):
+    """Check if an hepialight is present at direction d
+
+    Args:
+        d (int): Direction in which we want to check for the presence of an hepialight
+
+    Returns:
+        bool: True if an hepialight is present else False
+    """
     envoyer_msg(d, "PING")
 
     for x in range(10):
@@ -85,8 +166,12 @@ def check_presence(d):
 
     return False
 
-# Update the ID of the current matrix, and update the id of the neighbours
 def update_id(new_id):
+    """Update the matrix ID, and propagate the message to it's neighbours
+
+    Args:
+        new_id (List(int)): List which contains x and y coordinates ex : [x, y]
+    """
     global id
 
     id[0] = int(new_id[0])
@@ -106,8 +191,14 @@ def update_id(new_id):
 
 
 
-# Handle the commands received via UART
 def handle_receive(msg, msg_bytes, d):
+    """Handles the commands received via UART
+
+    Args:
+        msg (str): Message received as a string
+        msg_bytes (bytes): Message received as a bytes
+        d (int): Direction from which the message was received
+    """
     global esp_dir
  
     print("Received from {} : {}".format(d, msg))