1 ELP - Etherled Protocol (protocolo de comunicación del dispositivo etherled)
2 ============================================================================
8 El objetivo del protocolo de comunicación con el dispositivo etherled es que sea
9 de lo más simple para el dispositivo, dejando la mayor responsabilidad posible
10 en el cliente (PC que se conecta al dispositivo). Además tiene como objetivo la
11 simplicidad y la minimización de los datos a enviar (requerimientos de buffer).
17 Este protocolo está pensado para funcionar sobre UDP, es por esto que posee
18 algunos mecanismos básicos para confirmación de entrega.
19 Para esto utiliza un identificador de paquete pequeño por cada tipo de operación
20 que se utiliza para saber a que paquete pertenece una respuesta (ACK).
21 No se realiza control de errores ya que la capa de transporte (UDP) nos provee
24 El protocolo, como se dijo anteriormente diferencia bien entre el dispositivo
25 etherled (servidor) y la PC u otro dispositivo que le envía comandos (cliente).
26 Es por esto que un mismo comando puede tener distinta semántica según su
27 dirección (cliente->servidor o servidor->cliente). Incluso cambia la
28 conformación del paquete según su dirección.
30 El protocolo se trata básicamente de un mecanismo para establecer u obtener el
31 valor de ciertas variables del dispositivo (servidor). Por tanto define esas
32 variables e indica que tipo de operación se está llevando a cabo sobre ellas:
33 GET o SET. GET indica que el cliente va a obtener el valor de la variable y SET
34 que va a establecerlo. Las operaciones de GET no tienen parámetros extra (Datos)
35 cuando van en dirección cliente->servidor pero sí cuando van en dirección
36 inversa (servidor->cliente). Las operaciones SET se comportan exactamente de
39 Toda operación tiene una respuesta idéntica (excepto por los datos). Es decir,
40 si el cliente envía un SET de una variable VAR al servidor, con los datos DATA
41 y con identificador ID, el servidor responderá con otro paquete SET con la
42 variable VAR, con identificador ID pero sin datos. Es decir, se utiliza como
43 ACK al mismo paquete recibido (sólo que sin los datos).
49 +----------------+--------------------------------+
50 | CABECERA | DATOS (opcional) |
51 +----------------+--------------------------------+
52 /---- 1 byte ----/----------- Variable -----------/
57 La cabecera está compuesta por los siguientes campos:
60 +-----+-----------------------+-----------------+
62 +-----+-----------------------+-----------------+
63 /- 1 -/------- 4 bits --------/---- 3 bits -----/
66 Este bit indica si la operación es GET (0) o SET (1).
69 Es un número de 0 a 15 que indica la variable sobre la cual se está
70 operando. Ver sección Variables Definidas.
73 Es un número de 0 a 7 que indentifica al paquete. Para extender la
74 cantidad de identificadores efectivos disponibles, se utiliza un
75 contador por cada tupla (GS,Variable), por lo tanto, en el caso ideal de
76 que las operaciones estén perfectamente distribuidas entre todas las
77 variables y GET y SET, se tendría una cantidad de indentificadores
78 efectivos de 8 bits completo (256 posibilidades).
83 Los datos se envían para cada operación SET en sentido cliente->servidor y para
84 cada operación GET en sentido contrario (servidor->cliente). Pueden haber
85 variables que no posean datos en absoluto (una variable booleana tipo switch,
86 que active algo si estaba desactivado o a la inversa).
87 Los datos no son codificados de ninguna manera en particular ni requiere (en
88 términos generales) un campo de longitud, ya que la cantidad de datos enviados
89 está predefinido para cada VARiable (ver sección Variables Definidas).
91 La máxima cantidad de bytes que se pueden enviar está determinada por la
92 implementación del dispositivo.
98 Id | Nombre | Descripción | Datos
99 ----+-------------+------------------+------------------------------------------
100 0 | OFF | Apaga el | Ninguno, esta operación sólo tiene
101 | | dispositivo | sentido haciendo un SET
102 ----+-------------+------------------+------------------------------------------
103 1 | MATRIX | Matriz a dibujar | 1 byte para la cantidad de columnas
104 | | | (ancho) más 2*ancho bytes con el
105 | | | contenido de la matriz organizado
106 | | | como se indica en la sección Matriz
107 ----+-------------+------------------+------------------------------------------
108 2 | PAUSE | Pausa el dibuja- | 1 byte contenido 0x00 para reanudar el
109 | | do de la matriz | dibujado, cualquier otro para pausarlo
110 ----+-------------+------------------+------------------------------------------
111 3 | DELAY | Tiempo de retar- | 1 byte sin signo con la cantidad de 0.05
112 | | do del dibujado | ms a esperar entre refresco de columnas
113 ----+-------------+------------------+------------------------------------------
115 El resto de las variables quedan para futuras extensiones.
121 Para convertir la matriz a un array de bits se utiliza el siguiente esquema:
123 Suponemos una matriz chica, de 4x4 para simplificar el ejemplo. Para organizar
124 dicha matriz como un array de bits, simplemente hay que rotarla en sentido
125 horario y recorrer por filas de arriba hacia abajo (agrupando por bytes).
132 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 fila 0
133 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 fila 1
134 0 1 1 1 0 0 0 0 0 0 0 0 1 1 1 0 fila 2
135 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 fila 3
136 1 1 0 0 0 1 1 0 0 1 1 0 0 0 1 1 fila 4
137 1 1 0 0 0 1 1 0 0 1 1 0 0 0 1 1 fila 5
138 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 fila 6
139 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 fila 7
140 1 1 0 0 1 0 0 0 0 0 0 1 0 0 1 1 fila 8
141 1 1 0 0 1 1 0 0 0 0 1 1 0 0 1 1 fila 9
142 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 fila 10
143 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 fila 11
144 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 fila 12
145 0 1 1 1 0 0 0 0 0 0 0 0 1 1 1 0 fila 13
146 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 fila 14
147 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 fila 15
154 /--------------/--------------/
157 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 columna 0
158 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 columna 1
159 0 1 1 1 0 0 0 0 0 0 0 0 1 1 1 0 columna 2
160 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 columna 3
161 1 1 0 0 0 0 1 1 0 0 0 0 0 0 1 1 columna 4
162 1 1 0 0 0 1 1 0 0 0 1 1 0 0 1 1 columna 5
163 1 1 0 0 1 1 0 0 0 0 1 1 0 0 1 1 columna 6
164 1 1 0 0 1 1 0 0 0 0 0 0 0 0 1 1 columna 7
165 1 1 0 0 1 1 0 0 0 0 0 0 0 0 1 1 columna 8
166 1 1 0 0 1 1 0 0 0 0 1 1 0 0 1 1 columna 9
167 1 1 0 0 0 1 1 0 0 0 1 1 0 0 1 1 columna 10
168 1 1 0 0 0 0 1 1 0 0 0 0 0 0 1 1 columna 11
169 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 columna 12
170 0 1 1 1 0 0 0 0 0 0 0 0 1 1 1 0 columna 13
171 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 columna 14
172 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 columna 15
175 Para serializarlo se convierte en este stream de bytes (fila;columna):
177 /-------------------------- byte 0 -----------------------------/
178 +-------+-------+-------+-------+-------+-------+-------+-------+
179 | cols7 | cols6 | cols5 | cols4 | cols3 | cols2 | cols1 | cols0 | == cant. cols
180 +-------+-------+-------+-------+-------+-------+-------+-------+
182 /-------------------------- byte 1 -----------------------------/
183 +-------+-------+-------+-------+-------+-------+-------+-------+
184 | 8;0 | 9;0 | 10;0 | 11;0 | 12;0 | 13;0 | 14;0 | 15;0 | == HIGH(col0)
185 +-------+-------+-------+-------+-------+-------+-------+-------+
187 /-------------------------- byte 2 -----------------------------/
188 +-------+-------+-------+-------+-------+-------+-------+-------+
189 | 0;0 | 1;0 | 2;0 | 3;0 | 4;0 | 5;0 | 6;0 | 7;0 | == LOW(col0)
190 +-------+-------+-------+-------+-------+-------+-------+-------+
194 /-------------------------- byte 31 ----------------------------/
195 +-------+-------+-------+-------+-------+-------+-------+-------+
196 | 8; 5 | 9;15 | 10;15 | 11;15 | 12;15 | 13;15 | 14;15 | 15;15 | == HIGH(col15)
197 +-------+-------+-------+-------+-------+-------+-------+-------+
199 /-------------------------- byte 32 ----------------------------/
200 +-------+-------+-------+-------+-------+-------+-------+-------+
201 | 0;15 | 1;15 | 2;15 | 3;15 | 4;15 | 5;15 | 6;15 | 7;15 | == LOW(col15)
202 +-------+-------+-------+-------+-------+-------+-------+-------+
205 En el protocolo la cantidad de filas es _SIEMPRE_ 16, ya que está limitada
206 físicamente por la cantidad de leds del dispositivo. Por lo tanto, siempre
207 tendremos agrupada cada columna en 2 bytes.
209 Es decir, el stream de bits será:
211 HIGH(col0), LOW(col0), HIGH(col1), LOW(col1), ... , HIGH(colN), LOW(colN)
213 Siendo HIGH(colI) la parte alta de la columan I y LOW(colI) su parte baja.
215 Finalmente, los DATOS de una matriz tienen la siguiente estructura:
216 +----------------+------------------------------------------------+
217 | LEN | HIGH(col0) LOW(col0) ... HIGH(colN) LOW(colN) |
218 +----------------+------------------------------------------------+
219 /---- 1 byte ----/------------------- variable -------------------/
221 Siendo LEN la cantidad columnas de la matriz.
226 vim: set encoding=iso-8859-1 :