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))