VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

131
VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED INDEPENDIENTES BASADOS EN POSICIONAMIENTO RELATIVO. JUAN CAMILO GÓMEZ ECHEVERRÍA PROYECTO: TRABAJO DE GRADO No. 1613 INGENIERÍA ELECTRÓNICA DIRECTOR DEL TRABAJO DE GRADO ING. GUSTAVO ADOLFO RAMÍREZ ESPINOSA M. SC PONTIFICIA UNIVERSIDAD JAVERIANA FACULTAD DE INGENIERÍA DEPARTAMENTO DE ELECTRÓNICA BOGOTÁ D.C. 2016

Transcript of VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

Page 1: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED INDEPENDIENTES BASADOS

EN POSICIONAMIENTO RELATIVO.

JUAN CAMILO GÓMEZ ECHEVERRÍA

PROYECTO: TRABAJO DE GRADO

No. 1613

INGENIERÍA ELECTRÓNICA

DIRECTOR DEL TRABAJO DE GRADO

ING. GUSTAVO ADOLFO RAMÍREZ ESPINOSA M. SC

PONTIFICIA UNIVERSIDAD JAVERIANA

FACULTAD DE INGENIERÍA

DEPARTAMENTO DE ELECTRÓNICA

BOGOTÁ D.C.

2016

Page 2: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

2

CONTENIDO

1. INTRODUCCIÓN…………………………………………………………………………………… 3

2. MARCO TEÓRICO…………………………………………………………………………………. 4

3. OBJETIVO DEL PROYECTO……………………………………………………………………... 7

4. DESARROLLO……………………………………………………………………………………... 8

4.1 COMPRENSIÓN DEL ALGORITMO…………………………………………………… 8

4.2 DISEÑO SISTEMA EMBEBIDO………………………………………………………… 12

4.2.1 TRANSCEPTOR INFRARROJO…………………………………………….... 12

4.2.2 HARDWARE DE SENSADO…………………………………………………. 16

4.2.3 MATRIZ LED 8X8…………………………………………………………….. 16

4.2.4 DISEÑO DEL CIRCUITO IMPRESO………………………………………… 18

5. PROTOCOLO DE PRUEBAS……………………………………………………………………... 19

5.1 PRUEBAS DE TRANSMISIÓN…………………………………………………………. 19

5.2 PRUEBAS DEL ALGORITMO…………………………………………………….……. 21

6. ANÁLISIS DE RESULTADOS……………………………………………………………………. 25

7. CONCLUSIONES Y RECOMENDACIONES……………………………………………………. 27

8. REFERENCIAS…………………………………………………………………………………….. 28

Page 3: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

3

1. INTRODUCCION

Actualmente el uso de sistemas de comunicación inalámbrica está en aumento a nivel mundial. Este

fenómeno se debe a la facilidad que hay de comunicarse entre dispositivos sin la necesidad de utilizar

cables, lo que permite establecer interacción entre una o varias personas de forma remota e inclusive de

forma autónoma entre diferentes dispositivos a determinadas distancias. Además, permanentemente se

busca desarrollar aplicaciones o proyectos donde se pueda implementar la comunicación inalámbrica, así

como también se busca la evolución de ésta en aspectos como cobertura, capacidad de transmisión, ancho

de banda, entre otros, con el fin de mejorar la experiencia de los usuarios y reducir el uso de cables, ya que

la implementación de algunos de éstos puede llegar a ser costosa y dificultosa dependiendo de la distancia

y la zona en donde se quiere instalar, y esto es debido a que requiere gran planificación para su correcto

funcionamiento. El principal objetivo de la comunicación es transmitir información de un lugar a otro, y la

forma de hacerlo es a partir de una señal transmitida por un emisor y recibida por un receptor. Esta señal

básicamente tiene dos estados que tan pronto puedan ser detectados la capacidad de mover información

existe, ya que una combinación de estos estados puede representar caracteres alfabéticos o numéricos. En

comunicación inalámbrica el canal por el cual viajan las señales que llevan la información es el aire y cada

tecnología utiliza una frecuencia específica dentro del espectro de frecuencias.

Debido al avance en el desarrollo de las comunicaciones inalámbricas, hay un concepto el cual se ha

convertido en uno de los más populares actualmente y que seguramente será parte fundamental de las

comunicaciones en el futuro, el ‘Internet de las Cosas’ (IoT). IoT es un concepto que dando una definición

muy por encima, tiene como principal objetivo comunicar objetos dentro de una red [1]. A partir de lo

anterior, también surge un concepto conocido como ‘comunicación colaborativa’ el cual permite que

dispositivos conectados a una red sean capaces de desarrollar varias tareas al tiempo. Una definición

inicial de CONET establece: “Los objetos colaborativos consisten en sistemas embebidos equipados con

habilidades para comunicar, así como también para sensar y actuar, y que son capaces de cooperar y

organizarse autónomamente en redes con el fin de realizar una tarea en común” [2].

Este trabajo se enfoca en el desarrollo de un sistema de dispositivos embebidos capaces de realizar

comunicación colaborativa implementando una de las tecnologías de comunicación inalámbrica. Estos

dispositivos, por medio del intercambio de mensajes entre sí, llegan a la detección de su propia posición lo

cual se verá reflejado por medio de una matriz LED de tamaño 8x8.

En este informe se muestra tanto el desarrollo teórico como el desarrollo práctico de la aplicación descrita

anteriormente, abarcando temas desde el entendimiento del algoritmo hasta el diseño del sistema

embebido que sea capaz de ejecutar dicho algoritmo.

Page 4: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

4

2. MARCO TEÓRICO

Los rápidos avances en la parte computacional y de comunicación en los sistemas embebidos están

formando el camino hacia dispositivos capaces de realizar una variedad de tareas y actividades

autónomamente, teniendo en cuenta información dinámica y de contexto específico. Estos objetos son

capaces de cooperar, compartir información, y hacer parte una comunidad.

El tema principal en el que se enfoca el desarrollo de este proyecto es la posición de los bloques dentro de

la red. Esta identificación se logra por medio de una interacción que hay entre un módulo con sus

respectivos vecinos de cada interfaz. Esta interacción es básicamente un intercambio de mensajes los

cuales proporcionan información que se debe analizar con el objetivo de identificar bloques cercanos. Los

mensajes pertenecientes a esta interacción hacen parte del protocolo de comunicación implementado.

Figura 1. Idea principal del proyecto.

Figura 2. Diagrama de Bloques.

La Figura 2 muestra los principales bloques que describen el desarrollo del sistema general. Se pueden

observar bloques tanto principales como secundarios, pero todos con una cierta importancia para cumplir

con el objetivo principal.

Page 5: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

5

El bloque ‘Batería’ corresponde a la alimentación que tiene el módulo. Es el bloque que se encarga de

proporcionar la energía necesaria para el funcionamiento de la CPU, y, por ende, para el funcionamiento

de la Matriz LED y los transceptores infrarrojos.

El bloque ‘Sensores Magnéticos’ hace referencia al conjunto de sensores que utiliza el bloque para sensar

los cambios que hay en la organización de los módulos. Los sensores magnéticos son sencillos de utilizar

ya que se usan como interruptores los cuales se activan en la presencia de algún campo magnético.

El bloque ‘Matriz LED 8x8’ es el bloque donde se refleja el resultado del algoritmo desarrollado. Después

del intercambio de mensajes entre los bloques para detectar su propia posición, cada módulo refleja su

posición en la matriz LED de tamaño 8x8.

El bloque ‘CPU’ es uno de los más importantes dentro del sistema en general. Este bloque es el encargado

de generar los mensajes que se transmiten, y analizar los que se reciben, para después poder calcular la

posición espacial que ocupa el módulo dentro de la organización. Básicamente este bloque es un

microprocesador el cual cuenta con varios periféricos que son de gran utilidad para cumplir con el

objetivo. Algunos de estos periféricos son: Los puertos seriales UART (Universal Asynchronous Receiver

– Transmitter), SPI (Serial Peripheral Interface) y pines digitales con los cuales se desarrollan diferentes

tareas.

Por último, el bloque ‘Emisor/Receptor Infrarrojo’ es otro de los bloques importantes dentro del sistema

en general. Este bloque es el medio por el cual se transmiten los mensajes generados por el CPU, y recibir

los mensajes transmitidos por otros módulos para luego analizarlos.

Como se puede observar, la comunicación inalámbrica entre los módulos es parte fundamental en el

desarrollo del proyecto. Actualmente son varias las tecnologías que se utilizan para realizar comunicación

inalámbrica, cada una con diferentes características las cuales hay que adaptar a la situación y al tipo de

aplicación en el que se quieren implementar. Dentro del variado grupo de tecnologías se encuentran los

rayos de luz infrarroja. La comunicación por medio de rayos infrarrojos está basada en rayos luminosos

que se mueven en el espectro infrarrojo, permiten la comunicación bidireccional entre dos extremos que

requieren línea de vista, y pueden enviar información a velocidades que oscilan entre 9,6 kbps y 4 Mbps.

La comunicación entre los bloques se realiza de forma serial. Esta comunicación utiliza puertos seriales

los cuales reciben bytes de información y envían un bit a la vez. Típicamente, la comunicación serial se

utiliza para transmitir datos en formato ASCII. Debido a que la transmisión es asíncrona, es posible enviar

datos por una línea (Tx) mientras se reciben datos por otra (Rx). Las características más importantes de la

comunicación serial son la velocidad de transmisión, los bits de datos, los bits de parada, y la paridad.

Para que dos puertos se puedan comunicar, es necesario que las características sean iguales [3].

Velocidad de transmisión: Indica el número de bits por segundo que se transfieren, y se mide en baudios.

Bits de datos: Se refiere a la cantidad de bits en la transmisión. No necesariamente son 8 bits. Las

cantidades más comunes de bits por paquete son 5, 7 y 8 bits. El número de bits en el paquete depende de

los datos que se quieres transmitir.

Bits de parada; Usado para indicar el fin de la comunicación de un solo paquete. Debido a la manera

como se transfiere la información a través de las líneas de comunicación y que cada dispositivo tiene su

propio reloj, es posible que los dos dispositivos no estén sincronizados. Por lo tanto, los bits de parada no

solo indican el fin de la transmisión sino además dan un margen de tolerancia para esa diferencia entre los

relojes.

Page 6: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

6

Paridad: Es una forma sencilla de verificar si hay errores en la transmisión serial. Esto permite al

dispositivo receptor conocer si hay ruido que esté afectando de manera negativa la transmisión de los

datos.

Como se mencionó, la transmisión se realiza por medio de los puertos UART de la tarjeta de desarrollo. El

puerto UART es responsable del envío y la recepción de los bits; cuentan con registros de desplazamiento

con el fin de realizar la conversión de los datos de serie a paralelo para la recepción y de paralelo a serie

para la transmisión. El método de transmisión de las UART hace referencia a la tecnología TTL

(Transistor-Transistor Logic). Los bits de salida en el puerto se representan con niveles de voltaje

definidos. Para TTL estos voltajes tienen límites desde 0V hasta 3,3V o 5V. Un uno lógico (1) se

representa por 3,3V o 5V, y un cero lógico (0) se representa con 0V. El estándar de comunicación serial

RS232 es similar a las señales de transmisión de las UART en el sentido de que transmiten un bit a la vez,

a cierta velocidad de transmisión, y con ciertos bits de inicio y parada. La diferencia entre estos son los

niveles de voltaje que representan los bits. Para RS232 un uno lógico (1) se representa con voltajes

negativos entre -3V y -15V, mientras que un cero lógico (0) se representa con voltajes positivos entre 3V

y 15V. Debido a los altos voltajes de RS232, este estándar es más utilizado para transmisión a grandes

distancias, haciendo la comunicación menos susceptible a interferencias y pérdidas [4]. En la Figura 2 se

muestra la diferencia entre las tramas de bits que manejan los puertos UART y el estándar RS232.

Figura 3. Trama UART (TTL) y RS232 [4].

Page 7: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

7

3. OBJETIVO DEL PROYECTO

El objetivo planteado al principio de este proyecto fue:

Diseñar e implementar un dispositivo embebido capaz de detectar su posición específica dentro de un

conjunto de dispositivos, basándose en la organización que estos generen.

Para cumplir con este objetivo, fue necesario desarrollar y cumplir unos objetivos específicos:

- Diseñar e implementar un protocolo de comunicación y de sensado que les permita a los módulos

identificar su posición espacial con la de los demás módulos.

- Diseñar e implementar un embebido que ejecute el protocolo de comunicación y sensado

previamente propuesto.

- Diseñar y evaluar mediante un protocolo de pruebas el funcionamiento del algoritmo y el sistema

embebido a través de visualización de imágenes sobre una matriz LED de 8x8.

Al finalizar el desarrollo de este proyecto se logró diseñar e implementar el protocolo de comunicación y

sensado que permite a los módulos identificar su posición respecto a la de los demás. El funcionamiento

del protocolo se logró bajo la implementación de un prototipo de rápida ejecución en una tarjeta de

desarrollo de Arduino.

La comprensión del algoritmo se logró a partir del desarrollo de pseudocódigos, diagramas de flujo,

diagramas de estado y diagramas de secuencia.

Luego de la implementación del algoritmo, el siguiente aspecto a solucionar fue la parte del hardware, que

consta primordialmente del transceptor infrarrojo con el cual los módulos realizan la comunicación. Se

tuvo que tener en cuenta aspectos como la potencia de transmisión y la distancia entre los bloques. La

escogencia de la plataforma para la implementación final del protocolo se realizó a partir de

requerimientos de diseño encontrados en el proceso de validación del algoritmo. Lo que al final terminó

en la utilización de la tarjeta de desarrollo Beaglebone Black.

Por otro lado, a parte de la comunicación serial e inalámbrica, el sistema embebido final posee sensores

magnéticos, los cuales actúan como interruptores y con los cuales se cumple la función de sensado en las

interfaces del bloque.

Page 8: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

8

4. DESARROLLO

Para la realización del proyecto es necesario especificar un problema general el cual es el punto de partida

de desarrollo de todos los objetivos propuestos. Debido a que el objetivo general es el diseño e

implementación de un sistema embebido capaz de detectar su posición, la base de esto es principalmente

el algoritmo que se va a implementar. Es por esto que la primera parte para el desarrollo del proyecto es el

entendimiento y comprensión del mencionado algoritmo.

Un algoritmo es una serie ordenada de instrucciones, pasos o procesos que llevan a la solución de un

determinado problema. En este caso, el algoritmo implementado debe contener las instrucciones

necesarias para la comunicación y el envío de mensajes entre los módulos con las cuales cada uno de éstos

determina su respectiva posición, y con las cuales también se tienen en cuenta los problemas y las

restricciones que se puedan presentar. De acuerdo a lo anterior, el objetivo del algoritmo de localización

es proporcionarle a cada módulo una posición específica a partir de la organización en conjunto que

tengan lo módulos, haciendo uso de protocolos de sensado y comunicación.

4.1 COMPRENSIÓN ALGORITMO DE LOCALIZACIÓN

Primero que todo, es necesario conocer los mensajes que hacen parte del protocolo de comunicación, ya

que el algoritmo se basa en la interacción del módulo con sus vecinos más cercanos, es decir, los bloques

que están directamente en sus interfaces (norte, este, sur y oeste). Cada mensaje tiene sus respectivos

parámetros los cuales son los datos propios que cada bloque conoce y que sirven para ser analizados

dentro del algoritmo y determinar las instrucciones que se deben seguir. Dentro del sistema, es necesario

que haya un módulo que brinde una dirección en común, una sincronización entre los bloques, y una

posición inicial de referencia, para lo cual se decide implementar la elección de un líder tomando como

referencia los antecedentes [5].

Cada bloque conoce los siguientes parámetros:

- Su propio ID

- El ID del líder

- Su dirección

- El número de miembros en su red

- El ID de sus vecinos más cercanos

Además de estos parámetros, cada bloque tiene tres tablas de información.

- Tabla de Interfaz

- Tabla de Red

- Tabla de Elección

La Tabla de Interfaz es una tabla que brinda información de las cuatro interfaces de un bloque. Muestra si

alguna interfaz está ocupada o no, y el bloque que tiene ocupada esa interfaz.

La Tabla de Red brinda la información de toda la red en la que se encuentra un bloque. Como información

importante, dentro de esta tabla se encuentran las coordenadas de posición de cada bloque.

La Tabla de Elección es una tabla que muestra el estado en el que esta cada bloque en el momento en el

que se está llevando a cabo una Elección.

Page 9: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

9

Cada mensaje planteado dentro del protocolo de comunicación sirve para llevar a cabo una función dentro

del algoritmo de localización. Por ejemplo, para realizar una identificación se utilizan los siguientes

mensajes:

- PING

- PONG (suID, MiembrosSuRed, suInterfaz)

Al inciar el algoritmo cada bloque envía un mensaje PING a las cuatro interfaces cuya respuesta es un

mensaje PONG con los parámetros mencionados anteriormente los cuales sirven para realizar una

comprobación. Esta comprobación tiene como objetivo verificar si hay un cambio dentro de la

organización de la red. Los cambios que se verifican son la llegada de un nuevo vecino o la presencia de

una rotación. Como se mencionó anteriormente, en el algoritmo propuesto se implementó la elección de

un bloque líder. Esta elección se lleva a cabo en el caso de que se presente la llegada de un nuevo vecino,

y se realiza por medio del envío de los siguientes mensajes:

- START

- CANDIDATE (miLiderID, MiembrosMiRed)

- REJECTED (suLiderID, MiembrosSuRed)

- ELECTED (miLiderID, MiembrosMiRed)

START indica el inicio de una nueva elección, CANDIDATE contiene la información de los bloques con

opciones de ganar la elección, REJECTED se le envía al bloque que pierde la elección y ELECTED se

envía una vez elegido el líder. Los criterios de elección se explicarán más adelante.

Si, por el contrario, no hubo un nuevo vecino sino hubo una rotación, la manera de notificar ésta es por

medio del mensaje:

- TURN (miRotacion)

Mensaje que se le envía a los vecinos más cercanos presentes en las interfaces. El parámetro miRotación

se calcula comparando la información de la Tabla de Interfaz antes de hacer la rotación con la Tabla de

Interfaz luego de hacer la rotación.

Los parámetros de los mensajes anteriores son los que definen el camino que debe seguir un bloque dentro

del algoritmo. Esto significa que los módulos pueden tener varias instrucciones que ejecutar

simultáneamente. En consecuencia, los bloques tienen diferentes instrucciones para ejecutar dependiendo

de la información que obtengan de los vecinos que tienen en sus interfaces. Lo anterior se puede ver más

claro en la Figura 4 donde se muestra un diagrama de flujo que tiene como objetivo mostrar los posibles

‘caminos’ que puede seguir un bloque dentro del algoritmo.

Para poder acoplar el diagrama de flujo de la Figura 4 con el código del algoritmo, fue necesario

desarrollar e implementar un diagrama de estados concurrente. En programación, la concurrencia hace

referencia a la ejecución de dos o más procesos simultáneamente por el mismo procesador. En la Figura 4

se pueden observar tres estados relevantes dentro del sistema, estos son, la Identificación, la Elección y la

Rotación. La concurrencia toma importancia en los estados de Elección y Rotación que son los estados en

donde el bloque analiza toda la información de los mensajes que se envían y se reciben en estos estados.

Page 10: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

10

Figura 4. Diagrama de flujo

La razón por la cual es necesario un diagrama de estados concurrente es porque el módulo necesita

analizar la información de las cuatro interfaces (norte, este, sur, oeste) simultáneamente para que toda la

red esté actualizada al mismo tiempo en cuanto al ID del líder y las coordenadas que indican la posición

del bloque.

Además de los estados mencionados anteriormente, el diagrama de estados tiene otros dos secundarios,

pero no menos importantes. Uno de ellos es el estado de Inicialización, en el cual se inicializan, valga la

redundancia, la información de las cuatro interfaces y las tablas de información de red, interfaz y estados.

El otro estado es el de Visualización, en el cual el módulo procede a ejecutar la parte de sensado y muestra

en la matriz LED el resultado del análisis del algoritmo. A continuación, en la Figura 5 se muestra el

diagrama de estados implementado.

Figura 5. Diagrama de Estados

Page 11: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

11

Como se mencionó anteriormente, los estados tres y cuatro (Elección y Rotación) son los estados en los

que se implementa la concurrencia. Debido a que estos son los estados principales del sistema, y que son

los encargados de la mayor interacción entre los módulos, se procede a analizar el orden de transmisión de

mensajes para diferentes posibles casos relevantes en la organización de todos los dispositivos. Es por esto

que se desarrollaron diagramas de secuencia para casos específicos que se puedan presentar durante el

proceso para verificar cómo sería el comportamiento del bloque. Cabe aclarar que se pueden presentar

más casos a parte de los presentados, pero se escogen estos como relevantes ya que los demás son

combinaciones de los mencionados a continuación.

Caso # 1: Sin vecinos

Es el caso más sencillo de analizar, y uno de los muchos que pueden ocurrir durante el funcionamiento del

sistema. En la Figura 5 se muestra el diagrama de secuencia que hace referencia a este caso.

Caso # 2: Rotación en una interfaz cualquiera

Para este caso, se hace la suposición que el bloque ubicado en la interfaz ‘sur’ realiza una rotación, la cual

tiene que ser notificada a todos los bloques a su alrededor. Después de recibido un mensaje con la rotación

que hizo algún bloque, se procede a actualizar la información de dicha interfaz, así como también la tabla

de interfaz y también se calcula la nueva dirección. En la Figura 6 se muestra el diagrama de secuencia

que hace referencia a este caso. Por cuestiones de visualización, se omitieron los mensajes PING que

llegan a ‘Bloque’ y los mensajes PONG que ‘Bloque’ envía.

Caso # 3: Nuevo vecino en una interfaz cualquiera

Para este caso, se hace la suposición que un nuevo bloque se ubico en la interfaz ‘este’. Este caso conlleva

al proceso más largo dentro del algoritmo de posicionamiento ya que cuando hay la presencia de un nuevo

vecino significa que tiene que haber una Elección. Cuando hay una Elección, lo que se hace es comparar

dos parámetros de los bloques implicados, el ID y el número de miembros en la red de cada uno.

Anteriormente, se mencionó que para la sincronización de los bloques y para tener una dirección en

común a la hora de visualizar una imagen en la matriz LED, se implementó la elección de un líder. Dicha

elección es la que se hace en el estado número tres del diagrama mostrado en la Figura 4.

En cualquier situación, siempre que hay una elección, debe haber algún criterio de selección con el fin de

decidir quién gana dicha elección. Para este proyecto y esta aplicación el criterio de selección es muy

sencillo, el bloque con mayor número de miembros en su red es el ganador de la elección y por ende, es

elegido líder del grupo. Si se llega a dar el caso en que este criterio no es suficiente para elegir al líder, el

segundo criterio de selección es el ID. El bloque con menor ID es elegido líder del grupo. Dada la

información anterior, y volviendo a la suposición hecha para este caso, en la Figura 7 se puede observar el

proceso de envío y recepción de mensajes que hace referencia a este caso. Al igual que en el caso anterior,

por cuestiones de visualización se omitieron los mensajes PING y PONG de recepción y transmisión

respectivamente de ‘Bloque’.

Una vez comprendida la interacción que hay entre los módulos respecto a la transmisión y recepción de

los mensajes, se realizó una validación del diseño del algoritmo mediante la implementación de éste en la

tarjeta Arduino Mega 2560. La validación realizada fue útil para comprobar el funcionamiento del

algoritmo así como también para obtener criterios de selección de la plataforma final en la que se

implementaría el módulo final y requerimientos de hardware para el embebido.

Page 12: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

12

Figura 6. Diagrama secuencia Caso # 1.

4.2 DISEÑO SISTEMA EMBEBIDO

Una vez entendido el protocolo de comunicación y la interacción entre los bloques con el envío y la

recepción de todos los mensajes, se pasa al desarrollo del diseño e implementación del sistema embebido

capaz de ejecutar el algoritmo de posicionamiento. Para la implementación del hardware primero se deben

enlistar los componentes principales que éste debe contener como los transceptores infrarojos, el hardware

de sensado, entre otros.

4.2.1 TRANSCEPTOR INFRARROJO

Como ya se ha mencionado a lo largo de este documento, la comunicación entre los módulos se realizó

mediante transceptores infrarrojo. La implementación de esta parte del hardware se realizó a partir de la

utilización del TSOP1838, el cual es un receptor miniaturizado de luz infrarroja para sistemas de control

remoto. La señal de salida demodulada puede ser directamente decodificada por un microporcesador. Este

receptor está diseñado para la supresión de cualquier señal de interferencia. Las condiciones que debe

cumplir la señal de información para poder ser recibida correctamente son:

Page 13: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

13

Figura 7. Diagrama secuencia Caso # 2.

Page 14: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

14

Figura 8. Diagrama secuencia Caso # 3.

Page 15: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

15

- Frecuencia de la señal portadora cercana a la frecuencia central del filtro pasabanda (38 kHz).

- El formato de la señal de transmisión no debe enviar datos continuamente. Debe haber un tiempo

de espera de al menos 15 ms. (Ver Figura 9)

Figura 9. Formato señal de transmisión para el TSOP1838 [6].

En la Figura 9 se puede observar un ejemplo del formato de la señal de transmisión que requiere el

receptor TSOP1838. En esa señal se puede ver un tiempo de espera de 20 ms.

En cuanto al transmisor infrarrojo, no se utilizó un emisor estándar de luz infrarroja. Debido a la

aplicación, restricciones y requerimientos que hubo durante la implementación del transmisor, se decidió

hacer uso de la parte emisora de luz de un optointerruptor ya que la potencia requerida es muy poca y éste

optoacoplador está optimizado para distancias pequeñas. Como se mencionó anteriormente, el receptor

TSOP1838 solo recibe señales con frecuencia de portadora cercana a la frecuencia central de su filtro

pasabanda. Es por esto que fue necesario la implementación de un circuito que montara sobre una

portadora de 38 kHz la señal de salida del puerto serial UART, es decir, modular la señal de transmisión y

así tener la información sobre dicha portadora para la correcta recepción de ésta en el TSOP1838. Lo

anterior se logró mediante el esquemático mostrado en la Figura 10.

Figura 10. Señal de transmisión modulada.

El resultado de implementar el esquemático anterior es una señal modulada en ASK (Amplitude Shift

Keying), la cual con el ejemplo mostrado a continuación se entenderá mejor la forma de la señal de

transmisión.

Page 16: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

16

Figura 11. Ejemplo de señal modulada por ASK.

4.2.2 HARDWARE DE SENSADO

El sistema emebebido diseñado e implementado para este proyecto se definió anteriormente como un

dispositivo capaz de comunicar y sensar para realizar alguna tarea específica. La forma de realizar el

sensado se logró mediando la utilización de un dispositivo magnético llamado “Reed Switch”. Este

dispositivo electromecánico se comporta como un interruptor que se activa ante la presencia de un imán y

tiene la gran ventaja de no necesitar corriente para su funcionamiento. Otra de las ventajas que es muy útil

para la aplicación en cuestión es que su tiempo de conmutación es demasiado alto, del orden de 1 [ms] a 5

[ms], ya que los bloques tienen que sensar lo más rápido posible algún cambio dentro de la organización

del sistema para así ejecutar un nuevo proceso de localización y poder visualizar la imagen casi que

permanentemente.

La implementación del Reed Switch con la tarjeta escogida se realizó mediante pines digitales, los cuales

simplemente leen el valor del interruptor. El resultado de esta lectura se controla en el algoritmo de

localización y sirve para cambiar de estado en el Diagrama de Estados mostrado en la Figura 5. Se puede

observar que la condición para volver al Estado 2 (Identificación), es que haya algún cambio en la

organización de lo bloques, para lo cual el módulo tiene que repetir todo el proceso de verificar si hay un

nuevo vecino o si hubo una rotación.

4.2.3 MATRIZ LED 8x8

Para la visualización de las imágenes estáticas, en este caso imágenes numéricas que indican la posición

encontrada, se utilizó una matriz LED de tamaño 8x8. La implementación de ésta se hizo mediante un

módulo que contiene el circuito integrado MAX7219, el cual funciona como driver para conectar la matriz

LED con el microprocesador, es compatible con la interfaz serial SPI y ahorra el uso de muchos cables de

conexión.

Page 17: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

17

Figura 12. Matriz LED implementada.

Una vez conocidos los principales componentes del emebido, se pueden obtener los requerimientos que

debe tener la tarjeta a implementar para el óptimo desarrollo del proyecto. Estos requerimientos son:

- Debido a que el bloque debe comunicarse por cuatro interfaces se hace necesario el uso de

mínimo cuatro (4) puertos seriales UART.

- Para la comunicación con la matriz LED se necesita una Interfaz Serial (SPI).

- Pines de PWM para generar la señal portadora en la modulación ASK.

- Pines de propósito general (GPIO) para los sensores magnéticos.

Dadas las condiciones anteriores, se decidió implementar el proyecto en la tarjeta de desarrollo

Beaglebone Black, la cual posee un microprocesador ARM Cortez-A8 llamado AM3358. ¿Por qué se

eligió la Beaaglebone Black? Dado el contexto del proyecto en que el propósito es la identificación de la

posición física del bloque dentro de una red, y dado que el módulo tiene que analizar toda la información

recibida de las cuatro interfaces, es necesario que el bloque ejecute varias tareas simultáneamente. Debido

a esto, se decidió cambiar la implementación de un microcontrolador como el de Arduino a un

microprocesador como el de la Beaglebone Black. No está de más aclarar que el desarrollo del proyecto se

hubiera podido realizar por completo en la placa de Arduino pero para contextulizar el proyecto en todos

los aspectos se decidió hacer el cambio. Con respecto a las condiciones, en la Figura 13 se muestra una

imagen donde se observa que la tarjeta escogida cumple con los requerimientos de hardware planteados

anteriormente.

Por defecto, esta tarjeta viene con los puertos UART y la interfaz SPI cerrados, por lo que por medio de

comandos de Linux hay que habilitarlos para poder usarlos.

En total, la tarjeta cuenta con seis puertos seriales, de los cuales cuatro son accesibles por el usuario

(UART1, UART2, UART4, UART5). En un caso particular, para poder acceder al puerto UART5 es

necesario deshabilitar la entrada HDMI que viene habilitada por defecto debido a que éstos comparten los

mismos pines. Además de los puertos UART, cuenta también con la interfaz serial SPI, la cual es la

encargada de enviar la información pertinente a la matriz LED a la hora de realizar la visualización de las

imágenes.

Page 18: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

18

Figura 13. Pines de la tarjeta Beaglebone Black.

4.2.4 DISEÑO DEL CIRCUITO IMPRESO

Para finalizar el diseño y la implementación del sistema embebido, se diseñó un ciruito impreso en el que

quedó agrupado todas las caracteríticas previamente mencionadas. La idea del circuito impreso fue

utilizarlo como un ‘shield’ para la placa Beaglebone Black. Los shields son placas de circuitos que se

montan unas encima de otras para dar funcionalidad extra a otra placa, es decir, ampliar aspectos como el

hardware o las capacidades de la tarjeta. Los shields se pueden comunicar con la tarjeta por medio de

pines digitales o pines analógicos. Normalmente los shields se alimentan de la placa a la que están

conectados, pero en este caso la placa y el shield se alimentaron por medio de un regulador conectado a

una batería de 9V. Una de las razones por las cuales no se alimentó la tarjeta por medio del cable USB fue

porque los componentes extras con los que se implementó el embebido tienen voltaje de operación

mínimo de 4.5V según las hojas de especificaciones, y la tarjeta al ser alimentada por este medio no tiene

la capacidad de entregar 5V por los pines de VDD. La otra razón fundamental es porque debido a la

aplicación en cuestión, los módulos deben tener plena libertad de movimiento en el espacio y alimentarlos

por el cable USB impide esa libertad.

En la Anexo 2 se muestra la capa superior del circuito impreso implementado para el desarrollo del

proyecto. Como se puede observar, lo más relevante dentro del circuito son los receptores y transmisores

infrarrojo ubicados en los cuatro costados del diseño. La medición de su ubicación tuvo que ser demasiado

exacta ya que como se explicó anteriormente la comunicación vía infrarrojo necesita línea de vista, por lo

que el acople de los dispositivos tiene que ser bastante exacta para que los transceptores queden lo más

enfrentados posible.

Otra de las mediciones que requería gran exactitud fue la ubicación de los ‘headers’ con los cuales el

circuito se conecta con la placa Beaglebone Black. Esto se llevó a cabo tomando como referencia las

medidas de la tarjeta que se pueden encontrar en el manuel de usuario encontrado en [7]. A continuación

se muestra una figura con las medidas más relevantes de la tarjeta.

Page 19: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

19

Figura 14. Dimensiones de la tarjeta Beaglebone Black [7].

Hay que tener en cuenta que las medidas mostradas en la Figura 11 están en ‘mils’. Un mil es la unidad de

longitud más pequeña del sistema inglés de medidas y equivale a 0,0254 milímetros.

5. PROTOCOLO DE PRUEBAS

5.1 PRUEBAS DE TRANSMISIÓN

Luego de diseñado e implementado el sistema embebido, el paso a seguir fue la realización de las

respectivas pruebas para verificar el funcionamiento del proyecto. Lo primero en verificar antes de probar

el algoritmo de localización fue la transmisión inalámbrica. Se tuvo que determinar si efectivamente el

envío de los mensajes por medio de luz infrarroja se realizaba correctamente. En el capítulo de

Desarrollo, en el numeral 4.2.1, se mencionaron algunas de las condiciones que se requieren para que la

transmisión sea correcta. Dentro de esas condiciones se explicó que la señal de transmisión debía tener

una señal portadora aproximadamente de 38 kHz para que el receptor TSOP1838 pudiera indentificarla y

recibirla. Igualmente, en el numeral 4.2 se mencionó la alta disponibilidad de pines que tiene la tarjeta

Beaglebone Black, lo cual es una ventaja. Dentro de los pines que hay en la tarjeta están los pines de

PWM, la Beaglebone Black cuenta con un total de 8 pines de PWM de los cuales para el desarrollo de este

proyecto se utilizaron cuatro. El objetivo de los pines fue generar la señal portadora para la transmisión de

los mensajes. A continuación se muestran una serie de imágenes en las cuales se quiere mostrar las formas

de la señal de transmisión. La señal moduladora, la señal portadora y la señal modulada.

Como se puede observar en las Figuras 15, 16 y 17, la información se envía de forma correcta. Para

demostrar esto, se puede realizar una comparación remitiendo al lector a la Figura 11 en donde se ve una

forma estándar de modulación ASK.

Page 20: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

20

Ya comprobada la correcta transmisión de la información, lo siguiente es la verificación de la señal de

recepción del TSOP1838. En la Figura 18 se observa simultáneamente la señal de transmisión y la señal

de recepción las cuales resultan ser iguales. Hay que mencionar que estas pruebas de transmisión se

hicieron enviando un simple carácter de una tarjeta a otra sin enviar los mensajes del protocolo.

Figura 15. Señal de salida del puerto UART.

Figura 16. Señal de 38kHz del PWM.

Page 21: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

21

Figura 17. Señal modulada en ASK.

Figura 18. Señal de transmisión y recepción de los mensajes.

5.2 PRUEBAS DEL ALGORITMO

Después de revisar el funcionamiento de la transmisión de los mensajes, se realiza ahora las pruebas del

algoritmo propuesto. Como se menciona en uno de los objetivos específicos (capítulo Objetivos), la

verificación del funcionamiento en la tarjeta Beaglebone Black se intentó realizar mediante la

visualización de imágenes en un matriz LED 8x8, mientras que la comprobación del funcionamiento en el

primer prototipo de Arduino se realizó observando las tablas de información del bloque. Para este caso en

específico, las imágenes mencionadas en el objetivo son números, los cuales muestran la posición actual

del bloque dentro de la organización. Las pruebas que se realizaron fueron las mismas explicadas en el

capítulo de Desarrollo en la sección 4.1, donde se mencionaron tres de los casos más relevantes dentro del

funcionamiento del proyecto.

Page 22: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

22

Para recordar, estos casos son:

- El bloque sin ningún vecino en las interfaces.

- La rotación de un vecino en alguna de las interfaces.

- La llegada de un nuevo vecino a alguna interfaz.

Antes de ir con las pruebas, cabe aclarar que la ejecución del algoritmo se implementó en lenguaje C++.

Debido a que la tarjeta usada para este fin fue la Beaglebone Black, y que ésta viene pre cargada con un

Sistema Operativo Linux Debian, por practicidad, en este proyecto se decicdió trabajar con la tarjeta como

esclavo mediante SSH (Secure Shell) a través del puerto USB mini que tiene. Esto implicó la instalación

de los drivers respectivos de la tarjeta para Windows. Para habilitar la conexión SSH con la tarjeta se hizo

uso de un programa llamado PuTTY (Port Unique Terminal Type, que es un cliente SSH con licencia

libre, y que basta con configurar la IP (192.168.7.2) del dispositivo para crear la sesión con la terminal de

Linux de la tarjeta.

Una vez aclarado lo anterior se procede a explicar la realización de las pruebas. Para comenzar, el primer

caso con el que se experimentó fue la organización de un bloque solitario, sin vecinos en sus interfaces.

En éste, las intrucciones que sigue el módulo en la ejecución del algoritmo se pueden observar en el

Diagrama de Secuencia realizado para este caso el cual se muestra en la Figura 6. Al finalizar la ejecución,

el resultado de esto permite al bloque proyectar en su matriz LED de 8x8 una ‘X’ que une las cuatro

esquinas de la martiz como se ve a continuación.

Figura 19. Proyección de un módulo cuando no hay vecinos en sus interfaces.

La forma de evaluar este caso se muestra en la Figura 20 donde se observa que el bloque utilizado no tiene

otros bloques conectados a sus puertos seriales.

En la prueba para el segundo caso el módulo debe ejecutar las instrucciones del algoritmo que envía los

mensajes representados en la Figura 7. Luego de ejecutado el algoritmo cada módulo muestra en su matriz

LED de 8x8 su respectiva posición con su respectiva dirección. Cabe aclarar que cuando un módulo

realiza una rotación, las posiciones de los bloques no cambian, simplemente cambia su dirección de

proyección excepto si la rotación la hace el líder. Si el bloque que hace la rotación es el bloque líder, la

dirección de todos los módulos cambian respecto a la del líder. Pero si el que hace la rotación no fue el

Page 23: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

23

líder, la única dirección que cambia es la del módulo que hace la rotación. En las Figuras 20 y 21 se

muestra un ejemplo de cómo se realiza una rotación.

Figura 20. Prueba del Caso#1.

Figura 21. Ejemplo de rotación.

Figura 22. Ejemplo de rotación.

Page 24: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

24

La forma de evaluar este caso se hizo por medio de las conexiones mostradas a continuación.

Figura 23. Prueba Caso#2.

Para el tercer caso, se lleva a cabo la elección del líder. Luego de ejecutar el algortimo y enviar los

mensajes mostrados en la Figura 8, el bloque elegido, en su rol de líder, toma la posición inicial de la

organización. Es decir, sus coordenadas X y Y toman el valor de (0,0). A partir de estas coordenadas de

referencia el líder envía la posición a cada bloque de la red por medio de una propagación. A continuación

se muestra cómo se realiza el calculo de las cordenadas X y Y.

Como se observa en la Figura 24, la propagación de la información con la posición del bloque nace desde

el módulo líder. Dependiendo de las interfaces que estén conectadas entre sí, se realiza el cálculo de la

posición.

Figura 24. Propagación de la posición.

- Si el bloque está conectado en la interfaz ‘0’, se resta una unidad a la coordenada X.

- Si el bloque está conectado en la interfaz ‘1’, se suma una unidad a la coordenada Y.

Page 25: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

25

- Si el bloque está conectado en la interfaz ‘2’, se suma una unidad a la coordenada X.

- Si el bloque está conectado en la interfaz ‘3’, se resta una unidad a la coordenada Y.

La forma de evaluar este caso se realizó conectando los puertos seriales de las dos tarjetas simulando que

llegó un nuevo vecino a dicha interfaz.

Figura 25. Prueba Caso#3.

6. ANÁLISIS DE RESULTADOS

Al final no se obtuvieron los resultados esperados bajo la implementación del algoritmo en la plataforma

Beaglebone Black. Las primeras pruebas del desarrollo del proyecto se realizaron con la tarjeta Arduino

Mega 2560, la cual cuenta con funciones simples para implementar comunicación serial. Estas funciones

cuentan con información detallada y ejemplos claros de aplicación que son de mucha ayuda para los

usuarios de estas tarjetas [10]. Las pruebas que se hicieron con el Arduino Mega tuvieron el objetivo de

aclarar aspectos del algoritmo que no se entendían por medio del proceso teórico explicado en el capítulo

de Desarrollo, lo cual sirvió como proceso de validación del diseño. Durante la implementación con

Arduino, el funcionamiento del algoritmo fue el esperado. Al final de la ejecución, los bloques que se

comunicaron entre sí obtuvieron el valor de sus coordenadas X y Y. Los resultados obtenidos por medio

de Arduino se muestran a continuación en las tablas de información.

Para el primer caso (Sin Vecinos) se observa la Tabla de Interfaz para verificar que las interfaces

permanecen vacías.

Figura 26. Tabla de Interfaz cuando no hay vecinos.

En la Figura 26 se ve la Tabla de Interfaz para un caso donde no hay vecinos. Así es el formato de la tabla

mencionada en el capítulo de Desarrollo, donde se ven las interfaces que están ocupadas, y los IDs de los

bloques que ocupan las interfaces.

Page 26: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

26

Para el segundo caso, en el que se realiza la rotación cambiando la conexión de los puertos seriales, se

observa la Tabla de Interfaz nuevamente.

Figura 27. Tabla de Interfaz antes y después de la rotación.

DIRECCION = 0 DIRECCION = 3

En la Figura 27 se muestra la actualización que tiene la Tabla de Interfaz luego de haber una rotación.

Como se observa el bloque con ID igual a uno pasa de estar en la interfaz Oeste a estar en la interfaz Sur.

Además de cambiar la información de la tabla hay que cambiar también la Dirección del bloque por lo

explicado en el capítulo 5.2.

Para el último caso, en el que se presenta un nuevo vecino en una interfaz, lo que se observa son las tablas

de Interfaz y de Red.

Figura 28. Tabla de Red y Tabla de Interfaz cuando hay un nuevo vecino.

En la Figura 28 se ve la actualización que tienen las tablas de información cuando llega un nuevo vecino

en la prueba realizada. La Tabla de Interfaz guarda el nuevo vecino que llega a la interfaz Norte y luego de

realizar la Elección e interactuar con los mensajes del protocolo cada bloque queda con sus respectivas

coordenadas. En la Tabla de Red se ve que el bloque con ID igual a dos es el líder de la red y tiene

Page 27: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

27

coordenadas (0,0). El bloque con ID igual a 3 tiene coordenadas (-1,0) debido a que se encuentran

comunicándose por la interfaz norte, es decir, la interfaz ‘0’.

En el Anexo 3 se muestra el código implementado en la tarjeta Arduino Mega 2560. Cabe aclarar que en

este código no se encuentra desarrollado el código correspondiente al diagrama de estados concurrente

debido a que solo se hicieron pruebas con dos tarjetas. También se aclara que en las pruebas con Arduino

no se implementó la visualización de imágenes por medio de la matriz LED, debido a que no estaba

presupuestado presentar el proyecto en estas tarjetas y por eso la coprobación de funcionamiento se llevó a

cabo por medio de las tablas de información de los bloques.

A diferencia del proceso en Arduino, el realizado con la Beaglebone fue más complicado primero, por la

poca información acerca de las funciones para comunicación serial que tiene la librería usada (BlackLib)

[8], y segundo, la implementación de los transceptores infrarrojos para la comunicación inalámbrica tuvo

muchas fallas. Por un lado, esta librería fue escogida por ser la más común y completa para realizar

programas en lenguaje C++ en la tarjeta Beaglebone Black. Por otro lado, el problema en la

implementación del protocolo fue la comunicación inalámbrica por el puerto UART más exactamente en

la recepción del mensaje. El bloque que recibía la información lo hacía de forma incorrecta en el sentido

que la función utilizada no leía la información completamente. Para solucionar esto, se propuso

implementar un proceso de checksum, en el que en cada mensaje se enviara un parámetro con el valor de

checksum, el cual el receptor hacía un proceso de comparación con el valor que recibía y el valor que éste

calculaba. Checksum, en comunicaciones, tiene como propósito general detectar cambios en una

secuencia de datos. En dado caso de coincidir la comparación, se respondía el mensaje recibido con un

ACK para informarle al bloque transmisor la correcta recepción del mensaje. Si por el contrario la

comparación es errónea, no habría mensaje ACK, con lo cual el módulo transmisor reenvía el mensaje

después de cierto tiempo. El dato importante que se debe recibir sin errores es el ‘Modo’ del mensaje

enviado, es deicr, saber qué mensaje fue el que llegó para así conocer que proceso debe seguir el bloque

que lo recibió.

En cuanto a lo explicado en 4.2, sobre la habilitación de los puertos para poder utilizarlos, se descarta la

opción de que los puertos estén cerrados, ya que la transmisión se logró hacer correctamente, y algunos

datos se reciben de forma satisfactoria. No hubo funcionamiento del protocolo debido a problemas con la

librería implementada en el programa y la manera de implementar la transmisión inalámbrica, no hubo un

entendimiento claro de la inicialización de los puertos seriales, los cuales como se ha repetido en varias

ocasiones son parte fundamental del desarrollo y funcionamiento del proyecto.

7. CONCLUSIONES Y RECOMENDACIONES

La transmisión por medio de luz infrarroja sigue siendo la mejor opción para aplicar en este tipo de

proyectos, aunque sería recomendable investigar sobre algún mecanismo que se le pueda asignar al canal

en caso de haber un medio problemático con la transmisión.

Implementar un primer prototipo de prueba para validación del diseño resulta muy útil a la hora de

detectar posibles errores que no se detectan en el desarrollo teórico. Con esto, se logra comprobar el

funcionamiento del protocolo de comunicación y conocer los requerimientos de hardware para obtener los

criterios de selección de la plataforma indicada, lo que permite avanzar al diseño del embebido. Además

sirvió para tener presente la necesidad de tener una sincronización en la ejecución del algoritmo. Para la

implementación de comunicación por medio puertos seriales, es muy importante que en el código

ejecutado por un modulo se lean los datos al mismo tiempo en que se envían por otro módulo. Cabe

Page 28: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

28

aclarar que la sincronización mencionada no es en el envío de los datos, debido a que son puertos

asíncronos, sino en la ejecución del algoritmo.

Para grandes proyectos se recomienda el uso de tarjetas con gran número de periféricos, ya que en el

desarrollo de algún proyecto se puede requerir de alguna función que se pueda suplir con las

características de la tarjeta. Para este caso, el uso de un pin de PWM, disminuyó considerablemente el

tamaño del circuito impreso, lo que ayudó a la manipulación de los módulos.

8. REFERENCIAS

[1] Lu Tan and Neng Wang, "Future internet: The Internet of Things," Advanced Computer Theory and

Engineering (ICACTE), 2010 3rd International Conference on, Chengdu, 2010, pp. V5-376-V5-380.

[2] Karnouskos, S. (2010, June). The cooperative internet of things enabled smart grid. In Proceedings of

the 14th IEEE international symposium on consumer electronics (ISCE2010), June (pp. 07-10).

[3] <<National Instruments>> [En línea]. Available:

http://digital.ni.com/public.nsf/allkb/039001258CEF8FB686256E0F005888D1

[4] <<Sparkfun>> [En línea]. Available: https://www.sparkfun.com/tutorials/215

[5] <<MB led>> [En línea]. Available: https://mbled.wordpress.com/

[6] <<Hoja de especificaciones de TSOP1838>> [En línea]. Available

http://www.doyoung.net/DOC/TSOP1838_DS.pdf

[7] <<Manual de usuario de la tarjeta Beaglebone Black>> [En línea]. Available:

http://www.farnell.com/datasheets/1701090.pdf

[8] <<BlackLib>> [En línea]. Available: http://blacklib.yigityuce.com/index.html

[9] Wanasinghe, T. R., Mann, G. K., & Gosine, R. G. (2014, May). “Distributed collaborative localization

for heterogeneus multi-robot system. In Electrical and Computer Engineering (CCECE), 2014 IEEE 27

Canadian Conference on (pp.1-6). IEEE.

[10] <<Arduino Serial>> [En línea]. Available: https://www.arduino.cc/en/Reference/Serial

Page 29: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

29

ANEXO 1

// TRABAJO DE GRADO

#include <iostream>

#include <stdio.h>

#include <stdlib.h>

#include "BlackGPIO.h"

#include "BlackPWM.h"

#include "BlackUART.h"

#include "BlackSPI.h"

using namespace std;

#define Nbloques 4

#define Dentro 0

#define cX 1

#define cY 2

#define Lider 3

// Estados

#define EstadoNulo 16

#define EstadoInicial 17

#define EstadoCandidato 18

#define EstadoRechazado 19

#define EstadoElegido 20

// Modos

#define Ping 0

#define Pong 10

#define Start 20

#define Candidate 30

#define Rejected 40

#define Elected 50

#define Network 60

#define Position 70

#define Turn 80

#define Missing 90

#define Ack 100

struct EstructuraInterfaz{

int8_t Ocupado[4];

int8_t Id[4];

int8_t suInterfaz[4];

}Interfaz, InterfazGuardada;

struct Paquete{

uint8_t Emisor;

uint8_t IDpaquete;

uint8_t Prioridad;

Page 30: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

30

uint8_t Receptor;

uint8_t ttl;

uint8_t pDatos[15];

uint8_t pInterfaz;

uint8_t pModo;

uint8_t TamPaquete;

uint8_t Check;

}paquete[4], PONGrecibido[4], NuevoPaquete, PaqueteRecibido[4];

struct Coor{

int8_t X;

int8_t Y;

}Coordenadas;

int8_t minX,minY,maxX,maxY;

int8_t QuienEstaAqui[3];

int ConscienteFaltaBloque;

int ConscienteDeRotacion;

uint8_t EnvioPING, DireccionID, suDireccionID[4];

int8_t TablaRed[Nbloques][4], TablaDireccion[4];

uint8_t PaqueteID, Estados[Nbloques];

int8_t miID = 2;

int8_t miLiderID, MiembrosMiRed;

int8_t suID[4], suLiderID[4], MiembrosSuRed[4];

int8_t miRotacion, suRotacion[4];

int8_t miInterfaz, suInter[4];

int8_t x,y;

int8_t Direccion, suDireccion[4];

uint8_t TodaviaEnEleccion;

int DiagramaEstado = 1;

int InterfazRecibida = 0;

unsigned long previo, actual;

int Llego = 0;

int Control = 0;

int k = 0;

int InterfazRev = 0;

int VecRot[4] = {0,0,0,0};

int Control1 = 0;

int Control2 = 0;

int Control3 = 0;

int Control4 = 0;

int t = 0;

int ControlInt[4] = {0,0,0,0};

int ControlIntA[4] = {0,0,0,0};

int b = 0;

int uart;

bool EstadoPrevioNorte;

bool EstadoPrevioEste;

bool EstadoPrevioSur;

Page 31: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

31

bool EstadoPrevioOeste;

void TransmisionPaquete(Paquete,int);

void RecepcionPP1(Paquete);

void RecepcionPP2(Paquete);

void RecepcionPP3(Paquete);

void RecepcionPP4(Paquete);

void RecepcionPaquete(Paquete);

void InicializacionAlgoritmo(int);

void TareaReinicioRed();

void EnviarPING(int);

void RecibirPING(int,Paquete);

int PINGrecib(Paquete);

void EnviarPONG(int);

void RecibirPONG(int,Paquete);

void PONGnoRecibido(int);

int EsVecino(int);

int EraVecino(int);

void NuevoVecino(int,int,int,int,int,Paquete,int);

void RevisionEleccion(int,int,int,int,Paquete,int);

void EleccionEnvioRed(int,int,int,int,int);

void PrincipalEleccion(Paquete,int);

void InicioEleccion(int);

void EleccionCandidato(Paquete,int);

void FinalEleccion(int);

void EnvioRed(int);

void RecibirRed(Paquete,int);

void ReinicioRed(int,int);

void EnvioRedVecinos();

void ValoresMaximosRed();

void RecibirMissingRed(Paquete);

void RedCambiaLider(int);

void Rotacion(int,int,int,int,int,Paquete,int);

void EnvioRotacion(int);

void RecibirRotacion(Paquete,int);

void EnviarPosicionRed(int);

void EnvioPosicion(int,int);

Coor CalculoPosicion(Coor,int);

void PropagacionPosicion(int,int);

void RecibirPosicion(Paquete,int);

void RecibirACK(Paquete,int);

void QuitarBloque(int);

int HayUnLider();

int ContarMiembros();

void InicioPaquete(Paquete);

Paquete

ConstruccionPaquete(Paquete,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_

t,uint8_t,uint8_t,uint8_t);

void Enviar(Paquete,int);

Page 32: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

32

void EnviarPaquete(uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,int);

void EnviarBroadcast(Paquete);

void EnviarPropagacion(Paquete);

int

CheckSum(uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,uint8_t,ui

nt8_t,uint8_t){

int RevisarCheck(Paquete,int)

int main(){

// SENSORES MAGNETICOS

BlackLib::BlackGPIO Sm1(BlackLib::GPIO_20, BlackLib::input); //Interfaz 0

BlackLib::BlackGPIO Sm2(BlackLib::GPIO_60, BlackLib::input); //Interfaz 1

BlackLib::BlackGPIO Sm3(BlackLib::GPIO_44, BlackLib::input); //Interfaz 2

BlackLib::BlackGPIO Sm4(BlackLib::GPIO_61, BlackLib::input); //Interfaz 3

// PWMs

BlackLib::BlackPWM Pwm1(BlackLib::P9_14);

Pwm1.setDutyPercent(100.0);

Pwm1.setPeriodTime(26314,BlackLib::nanosecond);

Pwm1.setDutyPercent(50.0);

BlackLib::BlackPWM Pwm2(BlackLib::P9_16);

Pwm2.setDutyPercent(100.0);

Pwm2.setPeriodTime(26314,BlackLib::nanosecond);

Pwm2.setDutyPercent(50.0);

BlackLib::BlackPWM Pwm3(BlackLib::P8_13);

Pwm3.setDutyPercent(100.0);

Pwm3.setPeriodTime(26314,BlackLib::nanosecond);

Pwm3.setDutyPercent(50.0);

BlackLib::BlackPWM Pwm4(BlackLib::P8_19);

Pwm4.setDutyPercent(100.0);

Pwm4.setPeriodTime(26314,BlackLib::nanosecond);

Pwm4.setDutyPercent(50.0);

// UARTS

BlackLib::BlackUART uart1(BlackLib::UART1,

BlackLib::Baud2400,

BlackLib::ParityEven,

BlackLib::StopOne,

BlackLib::Char8);

uart1.open(BlackLib::ReadWrite | BlackLib::NonBlock);

uart1.flush(BlackLib::bothDirection);

BlackLib::BlackUART uart2(BlackLib::UART2,

BlackLib::Baud2400,

BlackLib::ParityEven,

Page 33: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

33

BlackLib::StopOne,

BlackLib::Char8);

uart2.open(BlackLib::ReadWrite | BlackLib::NonBlock);

uart2.flush(BlackLib::bothDirection);

BlackLib::BlackUART uart3(BlackLib::UART4,

BlackLib::Baud2400,

BlackLib::ParityEven,

BlackLib::StopOne,

BlackLib::Char8);

uart3.open(BlackLib::ReadWrite | BlackLib::NonBlock);

uart3.flush(BlackLib::bothDirection);

BlackLib::BlackUART uart4(BlackLib::UART5,

BlackLib::Baud2400,

BlackLib::ParityEven,

BlackLib::StopOne,

BlackLib::Char8);

uart4.open(BlackLib::ReadWrite | BlackLib::NonBlock);

uart4.flush(BlackLib::bothDirection);

// SPI1

BlackLib::BlackSPI spi(BlackLib::SPI1_0);

spi1.open(BlackLib::ReadWrite | BlackLib::NonBlock);

uint8_t Solo[8] = {0x81,0x42,0x24,0x18,0x18,0x24,0x42,0x81};

uint8_t Norte1[8] = {0x08,0x18,0x08,0x08,0x08,0x08,0x08,0x1c};

uint8_t Este1[8] = {0x00,0x00,0x00,0x82,0xff,0x80,0x00,0x00};

uint8_t Sur1[8] = {0x38,0x10,0x10,0x10,0x10,0x10,0x18,0x10};

uint8_t Oeste1[8] = {0x00,0x00,0x01,0xff,0x41,0x00,0x00,0x00};

uint8_t Norte2[8] = {0x18,0x24,0x04,0x08,0x10,0x20,0x20,0x3c};

uint8_t Este2[8] = {0x00,0x00,0xe2,0x91,0x89,0x86,0x00,0x00};

uint8_t Sur2[8] = {0x3c,0x04,0x04,0x08,0x10,0x20,0x24,0x18};

uint8_t Oeste2[8] = {0x00,0x00,0x61,0x91,0x89,0x47,0x00,0x00};

uint8_t Norte3[8] = {0x3c,0x04,0x08,0x18,0x04,0x04,0x04,0x38};

uint8_t Este3[8] = {0x00,0x00,0x81,0x89,0x8d,0x73,0x00,0x00};

uint8_t Sur3[8] = {0x1c,0x20,0x20,0x20,0x18,0x10,0x20,0x3c};

uint8_t Oeste3[8] = {0x00,0x00,0xce,0xb1,0x91,0x81,0x00,0x00};

uint8_t Norte4[8] = {0x04,0x0c,0x14,0x24,0x3e,0x04,0x04,0x04};

uint8_t Este4[8] = {0x00,0x00,0x18,0x14,0x12,0xff,0x10,0x00};

uint8_t Sur4[8] = {0x20,0x20,0x20,0x7c,0x24,0x28,0x30,0x20};

uint8_t Oeste4[8] = {0x00,0x08,0xff,0x48,0x28,0x18,0x00,0x00};

//-------------------------------------------------------------------------------------

while(1){

switch(DiagramaEstado){

case 1: // Inicializacipon de todas las variables de control, y de las tablas de información

Page 34: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

34

cout << "ESTADO 1 INICIALIZACION" << endl;

sleep(0.05);

InicializacionAlgoritmo(miID);

TareaReinicioRed();

DiagramaEstado = 2;

break;

case 2: //Envio de los mensajes PING para identificar bloques vecinos

cout << "ESTADO 2 INDENTIFICACION" << endl;

sleep(0.05);

if(Control == 0){

EnviarPING(k);

k++;

if(k == 4){

Control = 1;

k = 0;

}

}

// Recibir el PING y Enviar el PONG

if(Control == 1){

paquete[0].TamPaquete = 0;

RecepcionPP1(paquete[0]);

paquete[1].TamPaquete = 0;

RecepcionPP2(paquete[1]);

paquete[2].TamPaquete = 0;

RecepcionPP3(paquete[2]);

paquete[3].TamPaquete = 0;

RecepcionPP4(paquete[3]);

if(Control1 == 20 && Control2 == 20 && Control3 == 20 && Control4 == 20){

DiagramaEstado = 4;

}else{

Control = 2;

DiagramaEstado = 3;

}

}

// Si Control1,2,3,4 = 0 recibió PING y envió PONG

break;

case 3: // Se define si hubo una rotación en la organización o hubo un nuevo vecino en el grupo

cout << "ESTADO 3 ELECCION/ROTACION" << endl;

sleep(0.05);

// Recibir el PONG

if(Control == 2){

paquete[InterfazRev].TamPaquete = 2;

if(InterfazRev == 0){

if(Control1 != 20){

Page 35: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

35

RecepcionPP1(paquete[InterfazRev]);

}

if(VecRot[0] == 0){

Control1 = 40;

ControlInt[InterfazRev] = 40;

ControlIntA[InterfazRev] = 40;

}

}

if(InterfazRev == 1){

if(Control2 != 20){

RecepcionPP2(paquete[InterfazRev]);

}

if(VecRot[1] == 0){

Control2 = 40;

ControlInt[InterfazRev] = 40;

ControlIntA[InterfazRev] = 40;

}

}

if(InterfazRev == 2){

if(Control3 != 20){

RecepcionPP3(paquete[InterfazRev]);

}

if(VecRot[2] == 0){

Control3 = 40;

ControlInt[InterfazRev] = 40;

ControlIntA[InterfazRev] = 40;

}

}

if(InterfazRev == 3){

if(Control4 != 20){

RecepcionPP4(paquete[InterfazRev]);

}

if(VecRot[3] == 0){

Control4 = 40;

ControlInt[InterfazRev] = 40;

ControlIntA[InterfazRev] = 40;

}

}

}

// El vector VecRot está lleno con sus respectivos valores

// El vector ControlInt esta lleno y sera la variable de control en NuevoVecino

// Si VecRot[] = 0 => Control1,2,3,4 = 40 y esa interfaz queda lista para ir al estado 4

// Si VecRot[] != 0 => Control1,2,3,4 = 0;

if(Interfaz.Ocupado[t] == 1){

if(VecRot[t] == 1){

if(Control != 5 || Control != 6)

Page 36: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

36

NuevoVecino(suID[t],MiembrosSuRed[t],miInterfaz,suInter[t],ControlInt[t],paquete[t],ControlIntA[t]);

if(Control == 5){

if(miID == miLiderID && MiembrosMiRed == 1){

FinalEleccion(t);

}else{

if(MiembrosMiRed == 1){

if(ControlInt[t] == 3){

ControlInt[t] = 4;

break;

}

if(ControlInt[t] == 4){

sleep(0.3);

paquete[t].TamPaquete = 2;

Control = 6;

RecepcionPaquete(paquete[t]); // Recibe ELECTED de FinalEleccion.

ControlInt[t] = 5;

Control = 5;

break;

}

if(ControlInt[t] == 5){

sleep(0.5);

paquete[t].TamPaquete = 4;

RecepcionPaquete(paquete[t]); // Recibe NETWORK de FinalEleccion.

if(b != 1){

sleep(1);

}else{

b = 0;

}

ControlInt[t] = 6;

break;

}

if(ControlInt[t] == 6){

sleep(1);

paquete[t].TamPaquete = 6;

RecepcionPaquete(paquete[t]); // Recibe POSITION de FinalEleccion.

sleep(1);

Control = 6;

}

}

}

}

if(Control == 6){

ValoresMaximosRed();

Page 37: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

37

EnvioRedVecinos();

if(t == 0){

Control1 = 40;

}

if(t == 1){

Control2 = 40;

}

if(t == 2){

Control3 = 40;

}

if(t == 3){

Control4 = 40;

}

VecRot[t] = 0;

}

}

if(VecRot[t] == 2){

// Aqui dentro se envía y se recibe la información de una Rotación.

Rotacion(suID[t],MiembrosSuRed[t],miInterfaz,suInter[t],ControlInt[t],paquete[t],ControlIntA[t]);

if(t == 0){

Control1 = 40;

}

if(t == 1){

Control2 = 40;

}

if(t == 2){

Control3 = 40;

}

if(t == 3){

Control4 = 40;

}

VecRot[t] = 0;

}

}

if(t == 3){

t = 0;

}else{

t++;

}

if(Control1 == 40 && Control2 == 40 && Control3 == 40 && Control4 == 40){

DiagramaEstado = 4;

InterfazRev = 0;

Control = 0;

EstadoPrevioNorte = SM1.isHigh();

EstadoPrevioEste = SM2.isHigh();

EstadoPrevioSur = SM3.isHigh();

Page 38: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

38

EstadoPrevioOeste = SM4.isHigh();

}else{

DiagramaEstado = 3;

InterfazRev++;

if(InterfazRev < 4)

Control = 2;

}

break;

case 4: // Visualización de la posición encontrada en la matriz LED.

cout << "ESTADO 4 VISUALIZACION" << endl;

sleep(0.05);

// Cuando el sensor está activado, lee un LOW

if(Interfaz.Ocupado[0] == 0 && Interfaz.Ocupado[1] == 0 && Interfaz.Ocupado[2] == 0 &&

Interfaz.Ocupado[3] == 0){

if(Sm1.isHigh() && Sm2.isHigh() && Sm3.isHigh() && Sm4.isHigh()){

for(int i=0;i<8;i++){

spi.transfer(Solo[i],100);

}

}else{

DiagramaEstado = 2;

}

}else{

if((Sm1.isHigh()==EstadoPrevioNorte) && (Sm2.isHigh()==EstadoPrevioEste) &&

(Sm3.isHigh()==EstadoPrevioSur) & (Sm4.isHigh()==EstadoPrevioOeste)){

if(miID == miLiderID){

if(Interfaz.Ocupado[1] == 1 && Interfaz.Ocupado[2] == 1){

for(int i=0;i<8;i++){

spi.transfer(Norte1[i],100);

}

}

if(Interfaz.Ocupado[2] == 1 && Interfaz.Ocupado[3] == 1){

for(int i=0;i<8;i++){

spi.transfer(Norte2[i],100);

}

}

if(Interfaz.Ocupado[0] == 1 && Interfaz.Ocupado[1] == 1){

for(int i=0;i<8;i++){

spi.transfer(Norte3[i],100);

}

}

if(Interfaz.Ocupado[0] == 1 && Interfaz.Ocupado[3] == 1){

for(int i=0;i<8;i++){

spi.transfer(Norte4[i],100);

}

}

}else{

Page 39: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

39

if(TablaRed[miID][cX] == 0 && TablaRed[miID][cY] == 1 && Interfaz.Ocupado[2] == 1 &&

Direccion == 0){

for(int i=0;i<8;i++){

spi.transfer(Norte2[i],100);

}

}

if(TablaRed[miID][cX] == 0 && TablaRed[miID][cY] == 1 && Interfaz.Ocupado[2] == 1 &&

Direccion == 1){

for(int i=0;i<8;i++){

spi.transfer(Este2[i],100);

}

}

if(TablaRed[miID][cX] == 0 && TablaRed[miID][cY] == 1 && Interfaz.Ocupado[2] == 1 &&

Direccion == 2){

for(int i=0;i<8;i++){

spi.transfer(Sur2[i],100);

}

}

if(TablaRed[miID][cX] == 0 && TablaRed[miID][cY] == 1 && Interfaz.Ocupado[2] == 1 &&

Direccion == 3){

for(int i=0;i<8;i++){

spi.transfer(Oeste2[i],100);

}

}

if(TablaRed[miID][cX] == 1 && TablaRed[miID][cY] == 0 && Interfaz.Ocupado[1] == 1 &&

Direccion == 0){

for(int i=0;i<8;i++){

spi.transfer(Norte3[i],100);

}

}

if(TablaRed[miID][cX] == 1 && TablaRed[miID][cY] == 0 && Interfaz.Ocupado[1] == 1 &&

Direccion == 1){

for(int i=0;i<8;i++){

spi.transfer(Este3[i],100);

}

}

if(TablaRed[miID][cX] == 1 && TablaRed[miID][cY] == 0 && Interfaz.Ocupado[1] == 1 &&

Direccion == 2){

for(int i=0;i<8;i++){

spi.transfer(Sur3[i],100);

}

}

if(TablaRed[miID][cX] == 1 && TablaRed[miID][cY] == 0 && Interfaz.Ocupado[1] == 1 &&

Direccion == 3){

for(int i=0;i<8;i++){

spi.transfer(Oeste3[i],100);

}

}

Page 40: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

40

if(TablaRed[miID][cX] == 1 && TablaRed[miID][cY] == 1 && Direccion == 0){

for(int i=0;i<8;i++){

spi.transfer(Norte4[i],100);

}

}

if(TablaRed[miID][cX] == 1 && TablaRed[miID][cY] == 1 && Direccion == 1){

for(int i=0;i<8;i++){

spi.transfer(Este4[i],100);

}

}

if(TablaRed[miID][cX] == 1 && TablaRed[miID][cY] == 1 && Direccion == 2){

for(int i=0;i<8;i++){

spi.transfer(Sur4[i],100);

}

}

if(TablaRed[miID][cX] == 1 && TablaRed[miID][cY] == 1 && Direccion == 3){

for(int i=0;i<8;i++){

spi.transfer(Oeste4[i],100);

}

}

if(TablaRed[miID][cX] == 0 && TablaRed[miID][cY] == -1 && Interfaz.Ocupado[2] == 1 &&

Direccion == 0){

for(int i=0;i<8;i++){

spi.transfer(Norte1[i],100);

}

}

if(TablaRed[miID][cX] == 0 && TablaRed[miID][cY] == -1 && Interfaz.Ocupado[2] == 1 &&

Direccion == 1){

for(int i=0;i<8;i++){

spi.transfer(Este1[i],100);

}

}

if(TablaRed[miID][cX] == 0 && TablaRed[miID][cY] == -1 && Interfaz.Ocupado[2] == 1 &&

Direccion == 2){

for(int i=0;i<8;i++){

spi.transfer(Sur1[i],100);

}

}

if(TablaRed[miID][cX] == 0 && TablaRed[miID][cY] == -1 && Interfaz.Ocupado[2] == 1 &&

Direccion == 3){

for(int i=0;i<8;i++){

spi.transfer(Oeste1[i],100);

}

}

if(TablaRed[miID][cX] == 1 && TablaRed[miID][cY] == -1 && Direccion == 0){

for(int i=0;i<8;i++){

Page 41: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

41

spi.transfer(Norte3[i],100);

}

}

if(TablaRed[miID][cX] == 1 && TablaRed[miID][cY] == -1 && Direccion == 1){

for(int i=0;i<8;i++){

spi.transfer(Este3[i],100);

}

}

if(TablaRed[miID][cX] == 1 && TablaRed[miID][cY] == -1 && Direccion == 2){

for(int i=0;i<8;i++){

spi.transfer(Sur3[i],100);

}

}

if(TablaRed[miID][cX] == 1 && TablaRed[miID][cY] == -1 && Direccion == 3){

for(int i=0;i<8;i++){

spi.transfer(Oeste3[i],100);

}

}

if(TablaRed[miID][cX] == 1 && TablaRed[miID][cY] == 0 && Interfaz.Ocupado[3] == 1 &&

Direccion == 0){

for(int i=0;i<8;i++){

spi.transfer(Norte4[i],100);

}

}

if(TablaRed[miID][cX] == 1 && TablaRed[miID][cY] == 0 && Interfaz.Ocupado[3] == 1 &&

Direccion == 1){

for(int i=0;i<8;i++){

spi.transfer(Este4[i],100);

}

}

if(TablaRed[miID][cX] == 1 && TablaRed[miID][cY] == 0 && Interfaz.Ocupado[3] == 1 &&

Direccion == 2){

for(int i=0;i<8;i++){

spi.transfer(Sur4[i],100);

}

}

if(TablaRed[miID][cX] == 1 && TablaRed[miID][cY] == 0 && Interfaz.Ocupado[3] == 1 &&

Direccion == 3){

for(int i=0;i<8;i++){

spi.transfer(Oeste4[i],100);

}

}

if(TablaRed[miID][cX] == -1 && TablaRed[miID][cY] == 0 && Interfaz.Ocupado[1] == 1 &&

Direccion == 0){

for(int i=0;i<8;i++){

spi.transfer(Norte1[i],100);

}

Page 42: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

42

}

if(TablaRed[miID][cX] == -1 && TablaRed[miID][cY] == 0 && Interfaz.Ocupado[1] == 1 &&

Direccion == 1){

for(int i=0;i<8;i++){

spi.transfer(Este1[i],100);

}

}

if(TablaRed[miID][cX] == -1 && TablaRed[miID][cY] == 0 && Interfaz.Ocupado[1] == 1 &&

Direccion == 2){

for(int i=0;i<8;i++){

spi.transfer(Sur1[i],100);

}

}

if(TablaRed[miID][cX] == -1 && TablaRed[miID][cY] == 0 && Interfaz.Ocupado[1] == 1 &&

Direccion == 3){

for(int i=0;i<8;i++){

spi.transfer(Oeste1[i],100);

}

}

if(TablaRed[miID][cX] == -1 && TablaRed[miID][cY] == 1 && Direccion == 0){

for(int i=0;i<8;i++){

spi.transfer(Norte2[i],100);

}

}

if(TablaRed[miID][cX] == -1 && TablaRed[miID][cY] == 1 && Direccion == 1){

for(int i=0;i<8;i++){

spi.transfer(Este2[i],100);

}

}

if(TablaRed[miID][cX] == -1 && TablaRed[miID][cY] == 1 && Direccion == 2){

for(int i=0;i<8;i++){

spi.transfer(Sur2[i],100);

}

}

if(TablaRed[miID][cX] == -1 && TablaRed[miID][cY] == 1 && Direccion == 3){

for(int i=0;i<8;i++){

spi.transfer(Oeste2[i],100);

}

}

if(TablaRed[miID][cX] == 0 && TablaRed[miID][cY] == 1 && Interfaz.Ocupado[0] == 1 &&

Direccion == 0){

for(int i=0;i<8;i++){

spi.transfer(Norte4[i],100);

}

}

if(TablaRed[miID][cX] == 0 && TablaRed[miID][cY] == 1 && Interfaz.Ocupado[0] == 1 &&

Direccion == 1){

Page 43: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

43

for(int i=0;i<8;i++){

spi.transfer(Este4[i],100);

}

}

if(TablaRed[miID][cX] == 0 && TablaRed[miID][cY] == 1 && Interfaz.Ocupado[0] == 1 &&

Direccion == 2){

for(int i=0;i<8;i++){

spi.transfer(Sur4[i],100);

}

}

if(TablaRed[miID][cX] == 0 && TablaRed[miID][cY] == 1 && Interfaz.Ocupado[0] == 1 &&

Direccion == 3){

for(int i=0;i<8;i++){

spi.transfer(Oeste4[i],100);

}

}

if(TablaRed[miID][cX] == -1 && TablaRed[miID][cY] == -1 && Direccion == 0){

for(int i=0;i<8;i++){

spi.transfer(Norte1[i],100);

}

}

if(TablaRed[miID][cX] == -1 && TablaRed[miID][cY] == -1 && Direccion == 1){

for(int i=0;i<8;i++){

spi.transfer(Este1[i],100);

}

}

if(TablaRed[miID][cX] == -1 && TablaRed[miID][cY] == -1 && Direccion == 2){

for(int i=0;i<8;i++){

spi.transfer(Sur1[i],100);

}

}

if(TablaRed[miID][cX] == -1 && TablaRed[miID][cY] == -1 && Direccion == 3){

for(int i=0;i<8;i++){

spi.transfer(Oeste1[i],100);

}

}

if(TablaRed[miID][cX] == -1 && TablaRed[miID][cY] == 0 && Interfaz.Ocupado[3] == 1 &&

Direccion == 0){

for(int i=0;i<8;i++){

spi.transfer(Norte2[i],100);

}

}

if(TablaRed[miID][cX] == -1 && TablaRed[miID][cY] == 0 && Interfaz.Ocupado[3] == 1 &&

Direccion == 1){

for(int i=0;i<8;i++){

spi.transfer(Este2[i],100);

}

Page 44: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

44

}

if(TablaRed[miID][cX] == -1 && TablaRed[miID][cY] == 0 && Interfaz.Ocupado[3] == 1 &&

Direccion == 2){

for(int i=0;i<8;i++){

spi.transfer(Sur2[i],100);

}

}

if(TablaRed[miID][cX] == -1 && TablaRed[miID][cY] == 0 && Interfaz.Ocupado[3] == 1 &&

Direccion == 3){

for(int i=0;i<8;i++){

spi.transfer(Oeste2[i],100);

}

}

if(TablaRed[miID][cX] == 0 && TablaRed[miID][cY] == -1 && Interfaz.Ocupado[0] == 1 &&

Direccion == 0){

for(int i=0;i<8;i++){

spi.transfer(Norte3[i],100);

}

}

if(TablaRed[miID][cX] == 0 && TablaRed[miID][cY] == -1 && Interfaz.Ocupado[0] == 1 &&

Direccion == 1){

for(int i=0;i<8;i++){

spi.transfer(Este3[i],100);

}

}

if(TablaRed[miID][cX] == 0 && TablaRed[miID][cY] == -1 && Interfaz.Ocupado[0] == 1 &&

Direccion == 2){

for(int i=0;i<8;i++){

spi.transfer(Sur3[i],100);

}

}

if(TablaRed[miID][cX] == 0 && TablaRed[miID][cY] == -1 && Interfaz.Ocupado[0] == 1 &&

Direccion == 3){

for(int i=0;i<8;i++){

spi.transfer(Oeste3[i],100);

}

}

}

}else{

DiagramaEstado = 2;

}

}

break;

}

}

}

// ----------------------------------------------

Page 45: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

45

// Función que transmite todos los paquetes. Tiene como parámetros el paquete que se va a enviar y el

puerto

// por el que se quiere enviar.

void TransmisionPaquete(Paquete paquete, int uart){

cout << "TransmisionPaquete" << endl;

sleep(0.05);

int8_t Envio[9+(paquete.TamPaquete)];

if(paquete.pModo == Ping){

cout << "Transmision de un PING" << endl;

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.ttl;

Envio[5] = (int8_t)paquete.pInterfaz;

Envio[6] = (int8_t)paquete.pModo;

Envio[7] = (int8_t)paquete.TamPaquete;

Envio[8] = (int8_t)paquete.check;

}

if(paquete.pModo == Pong){

cout << "Transmision de un PONG" << endl;

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.ttl;

Envio[5] = (int8_t)paquete.pDatos[0];

Envio[6] = (int8_t)paquete.pDatos[1];

Envio[7] = (int8_t)paquete.pInterfaz;

Envio[8] = (int8_t)paquete.pModo;

Envio[9] = (int8_t)paquete.TamPaquete;

Envio[10] = (int8_t)paquete.check;

}

if(paquete.pModo == Start){

cout << "Transmision de un START" << endl;

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.ttl;

Envio[5] = (int8_t)paquete.pInterfaz;

Envio[6] = (int8_t)paquete.pModo;

Envio[7] = (int8_t)paquete.TamPaquete;

Envio[8] = (int8_t)paquete.check;

}

if(paquete.pModo == Candidate){

cout << "Transmision de un CANDIDATE" << endl;

Envio[0] = (int8_t)paquete.Emisor;

Page 46: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

46

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.ttl;

Envio[5] = (int8_t)paquete.pDatos[0];

Envio[6] = (int8_t)paquete.pDatos[1];

Envio[7] = (int8_t)paquete.pInterfaz;

Envio[8] = (int8_t)paquete.pModo;

Envio[9] = (int8_t)paquete.TamPaquete;

Envio[10] = (int8_t)paquete.check;

}

if(paquete.pModo == Rejected){

cout << "Transmision de un REJECTED" << endl;

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.ttl;

Envio[5] = (int8_t)paquete.pDatos[0];

Envio[6] = (int8_t)paquete.pDatos[1];

Envio[7] = (int8_t)paquete.pInterfaz;

Envio[8] = (int8_t)paquete.pModo;

Envio[9] = (int8_t)paquete.TamPaquete;

Envio[10] = (int8_t)paquete.check;

}

if(paquete.pModo == Elected){

cout << "Transmision de un ELECTED" << endl;

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.ttl;

Envio[5] = (int8_t)paquete.pDatos[0];

Envio[6] = (int8_t)paquete.pDatos[1];

Envio[7] = (int8_t)paquete.pInterfaz;

Envio[8] = (int8_t)paquete.pModo;

Envio[9] = (int8_t)paquete.TamPaquete;

Envio[10] = (int8_t)paquete.check;

}

if(paquete.pModo == Network){

cout << "Transmision de un NETWORK" << endl;

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.ttl;

Envio[5] = (int8_t)paquete.pDatos[0];

Envio[6] = (int8_t)paquete.pDatos[1];

Envio[7] = (int8_t)paquete.pDatos[2];

Page 47: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

47

Envio[8] = (int8_t)paquete.pDatos[3];

Envio[9] = (int8_t)paquete.pInterfaz;

Envio[10] = (int8_t)paquete.pModo;

Envio[11] = (int8_t)paquete.TamPaquete;

Envio[12] = (int8_t)paquete.check;

}

if(paquete.pModo == Position){

cout << "Transmision de un POSITION" << endl;

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.ttl;

Envio[5] = (int8_t)paquete.pDatos[0];

Envio[6] = (int8_t)paquete.pDatos[1];

Envio[7] = (int8_t)paquete.pDatos[2];

Envio[8] = (int8_t)paquete.pDatos[3];

Envio[9] = (int8_t)paquete.pDatos[4];

Envio[10] = (int8_t)paquete.pDatos[5];

Envio[11] = (int8_t)paquete.pInterfaz;

Envio[12] = (int8_t)paquete.pModo;

Envio[13] = (int8_t)paquete.TamPaquete;

Envio[14] = (int8_t)paquete.check;

}

if(paquete.pModo == Turn){

cout << "Transmision de un TURN" << endl;

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.ttl;

Envio[5] = (int8_t)paquete.pDatos[0];

Envio[6] = (int8_t)paquete.pInterfaz;

Envio[7] = (int8_t)paquete.pModo;

Envio[8] = (int8_t)paquete.TamPaquete;

Envio[9] = (int8_t)paquete.check;

}

if(paquete.pModo == Missing){

cout << "Transmision de un MISSING" << endl;

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.ttl;

Envio[5] = (int8_t)paquete.pDatos[0];

Envio[6] = (int8_t)paquete.pInterfaz;

Envio[7] = (int8_t)paquete.pModo;

Envio[8] = (int8_t)paquete.TamPaquete;

Envio[9] = (int8_t)paquete.check;

Page 48: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

48

}

if(paquete.pModo == Ack){

cout << "Transmision de un ACK" << endl;

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.ttl;

Envio[5] = (int8_t)paquete.pDatos[0];

Envio[6] = (int8_t)paquete.pInterfaz;

Envio[7] = (int8_t)paquete.pModo;

Envio[8] = (int8_t)paquete.TamPaquete;

Envio[9] = (int8_t)paquete.check;

}

if(uart == 0){

char byteEnviado[8+(paquete.TamPaquete)];

for(int w=0;w<(8+(paquete.TamPaquete));w++){

sprintf(byteEnviado,"%d",Envio[w]);

uart1.write(byteEnviado,sizeof(byteEnviado));

cout << byteEnviado << endl;

sleep(0.2);

}

}

if(uart == 1){

char byteEnviado[8+(paquete.TamPaquete)];

for(int w=0;w<(8+(paquete.TamPaquete));w++){

sprintf(byteEnviado,"%d",Envio[w]);

uart2.write(byteEnviado,sizeof(byteEnviado));

cout << byteEnviado << endl;

sleep(0.2);

}

}

if(uart == 2){

char byteEnviado[8+(paquete.TamPaquete)];

for(int w=0;w<(8+(paquete.TamPaquete));w++){

sprintf(byteEnviado,"%d",Envio[w]);

uart3.write(byteEnviado,sizeof(byteEnviado));

cout << byteEnviado << endl;

sleep(0.2);

}

}

if(uart == 3){

char byteEnviado[8+(paquete.TamPaquete)];

for(int w=0;w<(8+(paquete.TamPaquete));w++){

sprintf(byteEnviado,"%d",Envio[w]);

uart4.write(byteEnviado,sizeof(byteEnviado));

cout << byteEnviado << endl;

sleep(0.2);

}

Page 49: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

49

}

cout << "FinTransmisionPaquete" << endl;

sleep(0.05);

}

// RecepcionPP1,2,3,4 recibe los mensajes PING y PONG con los cuales se identifica los cambios en la

// organización.

void RecepcionPP1(Paquete paquete){

cout << "RecepcionPaquete" << endl;

sleep(0.05);

int a = 9+(paquete.TamPaquete);

int paqueteRX1[a];

char z1[a];

for(int j=0;j<a;j++){

z1[j] = 255;

}

if(Control == 1){

if(uart1.isOpen()){

InterfazRecibida = 1;

for(int w=0;w<a;w++){

if(uart1.read(z1, sizeof(z1))){

paqueteRX1[w] = atoi(z1)

cout << paqueteRX1 << endl;

sleep(0.2);

}

}

}

}

if(Control == 2){

previo = clock();

actual = clock();

while((actual - previo < 10000) || (Llego == 0)){

if(uart1.isOpen()){

InterfazRecibida = 1;

for(int w=0;w<a;w++){

if(uart1.read(z1, sizeof(z1))){

paqueteRX1[w] = atoi(z1);

cout << paqueteRX1 << endl;

sleep(0.2);

}

}

if(paqueteRX1[a-3] == Pong){

Llego = 1;

}else{

actual = clock();

}

}

if(Llego == 0){

PONGnoRecibido(0);

Page 50: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

50

}

}

if(paqueteRX1[a-3] == Ping){

cout << "Recibio un mensaje PING" << endl;

PaqueteRecibido[0].Emisor = (uint8_t)paqueteRX1[0];

PaqueteRecibido[0].IDpaquete = (uint8_t)paqueteRX1[1];

PaqueteRecibido[0].Prioridad = (uint8_t)paqueteRX1[2];

PaqueteRecibido[0].Receptor = (uint8_t)paqueteRX1[3];

PaqueteRecibido[0].TTL = (uint8_t)paqueteRX1[4];

PaqueteRecibido[0].pInterfaz = (uint8_t)paqueteRX1[5];

PaqueteRecibido[0].pModo = (uint8_t)paqueteRX1[6];

PaqueteRecibido[0].TamPaquete = (uint8_t)paqueteRX1[7];

paquete[0] = PaqueteRecibido[0];

RecibirPING(0,PaqueteRecibido[0]);

}

if(paqueteRX1[a-3] == Pong){

cout << "Recibio un mensaje PONG" << endl;

PaqueteRecibido[0].Emisor = (uint8_t)paqueteRX1[0];

PaqueteRecibido[0].IDpaquete = (uint8_t)paqueteRX1[1];

PaqueteRecibido[0].Prioridad = (uint8_t)paqueteRX1[2];

PaqueteRecibido[0].Receptor = (uint8_t)paqueteRX1[3];

PaqueteRecibido[0].TTL = (uint8_t)paqueteRX1[4];

PaqueteRecibido[0].pDatos[0] = (uint8_t)paqueteRX1[5];

PaqueteRecibido[0].pDatos[1] = (uint8_t)paqueteRX1[6];

PaqueteRecibido[0].pInterfaz = (uint8_t)paqueteRX1[7];

PaqueteRecibido[0].pModo = (uint8_t)paqueteRX1[8];

PaqueteRecibido[0].TamPaquete = (uint8_t)paqueteRX1[9];

paquete[0] = PaqueteRecibido[0];

RecibirPONG(0,PaqueteRecibido[0]);

}

if(Control == 1 && paqueteRX1[a-3] != Ping){

Control1 = 20;

}

cout << "FinRecepcionPaquete" << endl;

sleep(0.05);

}

void RecepcionPP2(Paquete paquete){

cout << "RecepcionPaquete" << endl;

sleep(0.05);

int a = 9+(paquete.TamPaquete);

int paqueteRX2[a];

char z2[a];

for(int j=0;j<a;j++){

z2[j] = 255;

}

if(Control == 1){

if(uart2.isOpen()){

InterfazRecibida = 2;

Page 51: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

51

for(int w=0;w<a;w++){

if(uart2.read(z2, sizeof(z2))){

PaqueteRX2[w] = atoi(z2)

cout << paqueteRX2 << endl;

sleep(0.2);

}

}

}

}

if(Control == 2){

previo = clock();

actual = clock();

while((actual - previo < 10000) || (Llego == 0)){

if(uart2.isOpen()){

InterfazRecibida = 2;

for(int w=0;w<a;w++){

if(uart1.read(z2, sizeof(z2))){

PaqueteRX2[w] = atoi(z2);

cout << paqueteRX2 << endl;

sleep(0.2);

}

}

if(paqueteRX2[a-3] == Pong){

Llego = 1;

}else{

actual = clock();

}

}

if(Llego == 0){

PONGnoRecibido(1);

}

}

if(paqueteRX2[a-3] == Ping){

cout << "Recibio un mensaje PING" << endl;

PaqueteRecibido[1].Emisor = (uint8_t)paqueteRX2[0];

PaqueteRecibido[1].IDpaquete = (uint8_t)paqueteRX2[1];

PaqueteRecibido[1].Prioridad = (uint8_t)paqueteRX2[2];

PaqueteRecibido[1].Receptor = (uint8_t)paqueteRX2[3];

PaqueteRecibido[1].TTL = (uint8_t)paqueteRX2[4];

PaqueteRecibido[1].pInterfaz = (uint8_t)paqueteRX2[5];

PaqueteRecibido[1].pModo = (uint8_t)paqueteRX2[6];

PaqueteRecibido[1].TamPaquete = (uint8_t)paqueteRX2[7];

paquete[1] = PaqueteRecibido[1];

RecibirPING(1,PaqueteRecibido[1]);

}

if(paqueteRX2[a-3] == Pong){

cout << "Recibio un mensaje PONG" << endl;

PaqueteRecibido[1].Emisor = (uint8_t)paqueteRX2[0];

PaqueteRecibido[1].IDpaquete = (uint8_t)paqueteRX2[1];

Page 52: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

52

PaqueteRecibido[1].Prioridad = (uint8_t)paqueteRX2[2];

PaqueteRecibido[1].Receptor = (uint8_t)paqueteRX2[3];

PaqueteRecibido[1].TTL = (uint8_t)paqueteRX2[4];

PaqueteRecibido[1].pDatos[0] = (uint8_t)paqueteRX2[5];

PaqueteRecibido[1].pDatos[1] = (uint8_t)paqueteRX2[6];

PaqueteRecibido[1].pInterfaz = (uint8_t)paqueteRX2[7];

PaqueteRecibido[1].pModo = (uint8_t)paqueteRX2[8];

PaqueteRecibido[1].TamPaquete = (uint8_t)paqueteRX2[9];

paquete[1] = PaqueteRecibido[1];

RecibirPONG(1,PaqueteRecibido[1]);

}

if(Control == 1 && paqueteRX2[a-3] != Ping){

Control2 = 20;

}

cout << "FinRecepcionPaquete" << endl;

sleep(0.05);

}

void RecepcionPP3(Paquete paquete){

cout << "RecepcionPaquete" << endl;

sleep(0.05);

int a = 9+(paquete.TamPaquete);

int paqueteRX3[a];

char z3[a];

for(int j=0;j<a;j++){

z3[j] = 255;

}

if(Control == 1){

if(uart3.isOpen()){

InterfazRecibida = 3;

for(int w=0;w<a;w++){

if(uart3.read(z3, sizeof(z3))){

PaqueteRX3[w] = atoi(z3)

cout << paqueteRX3 << endl;

sleep(0.2);

}

}

}

}

if(Control == 2){

previo = clock();

actual = clock();

while((actual - previo < 10000) || (Llego == 0)){

if(uart3.isOpen()){

InterfazRecibida = 3;

for(int w=0;w<a;w++){

if(uart3.read(z3, sizeof(z3))){

PaqueteRX3[w] = atoi(z3);

cout << paqueteRX3 << endl;

Page 53: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

53

sleep(0.2);

}

}

if(paqueteRX3[a-3] == Pong){

Llego = 1;

}else{

actual = clock();

}

}

if(Llego == 0){

PONGnoRecibido(2);

}

}

if(paqueteRX3[a-3] == Ping){

cout << "Recibio un mensaje PING" << endl;

PaqueteRecibido[2].Emisor = (uint8_t)paqueteRX3[0];

PaqueteRecibido[2].IDpaquete = (uint8_t)paqueteRX3[1];

PaqueteRecibido[2].Prioridad = (uint8_t)paqueteRX3[2];

PaqueteRecibido[2].Receptor = (uint8_t)paqueteRX3[3];

PaqueteRecibido[2].TTL = (uint8_t)paqueteRX3[4];

PaqueteRecibido[2].pInterfaz = (uint8_t)paqueteRX3[5];

PaqueteRecibido[2].pModo = (uint8_t)paqueteRX3[6];

PaqueteRecibido[2].TamPaquete = (uint8_t)paqueteRX3[7];

paquete[2] = PaqueteRecibido[2];

RecibirPING(2,PaqueteRecibido[2]);

}

if(paqueteRX3[a-3] == Pong){

cout << "Recibio un mensaje PONG" << endl;

PaqueteRecibido[2].Emisor = (uint8_t)paqueteRX3[0];

PaqueteRecibido[2].IDpaquete = (uint8_t)paqueteRX3[1];

PaqueteRecibido[2].Prioridad = (uint8_t)paqueteRX3[2];

PaqueteRecibido[2].Receptor = (uint8_t)paqueteRX3[3];

PaqueteRecibido[2].TTL = (uint8_t)paqueteRX3[4];

PaqueteRecibido[2].pDatos[0] = (uint8_t)paqueteRX3[5];

PaqueteRecibido[2].pDatos[1] = (uint8_t)paqueteRX3[6];

PaqueteRecibido[2].pInterfaz = (uint8_t)paqueteRX3[7];

PaqueteRecibido[2].pModo = (uint8_t)paqueteRX3[8];

PaqueteRecibido[2].TamPaquete = (uint8_t)paqueteRX3[9];

paquete[2] = PaqueteRecibido[2];

RecibirPONG(2,PaqueteRecibido[2]);

}

if(Control == 1 && paqueteRX3[a-3] != Ping){

Control3 = 20;

}

cout << "FinRecepcionPaquete" << endl;

sleep(0.05);

}

void RecepcionPP4(Paquete paquete){

Page 54: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

54

cout << "RecepcionPaquete" << endl;

sleep(0.05);

int a = 9+(paquete.TamPaquete);

int paqueteRX4[a];

char z4[a];

for(int j=0;j<a;j++){

z4[j] = 255;

}

if(Control == 1){

if(uart4.isOpen()){

InterfazRecibida = 4;

for(int w=0;w<a;w++){

if(uart4.read(z4, sizeof(z4))){

PaqueteRX4[w] = atoi(z4)

cout << paqueteRX4 << endl;

sleep(0.2);

}

}

}

}

if(Control == 2){

previo = clock();

actual = clock();

while((actual - previo < 10000) || (Llego == 0)){

if(uart1.isOpen()){

InterfazRecibida = 4;

for(int w=0;w<a;w++){

if(uart4.read(z4, sizeof(z4))){

PaqueteRX4[w] = atoi(z4);

cout << paqueteRX4 << endl;

sleep(0.2);

}

}

if(paqueteRX4[a-3] == Pong){

Llego = 1;

}else{

actual = clock();

}

}

if(Llego == 0){

PONGnoRecibido(3);

}

}

if(paqueteRX4[a-3] == Ping){

cout << "Recibio un mensaje PING" << endl;

PaqueteRecibido[3].Emisor = (uint8_t)paqueteRX4[0];

PaqueteRecibido[3].IDpaquete = (uint8_t)paqueteRX4[1];

PaqueteRecibido[3].Prioridad = (uint8_t)paqueteRX4[2];

PaqueteRecibido[3].Receptor = (uint8_t)paqueteRX4[3];

Page 55: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

55

PaqueteRecibido[3].TTL = (uint8_t)paqueteRX4[4];

PaqueteRecibido[3].pInterfaz = (uint8_t)paqueteRX4[5];

PaqueteRecibido[3].pModo = (uint8_t)paqueteRX4[6];

PaqueteRecibido[3].TamPaquete = (uint8_t)paqueteRX4[7];

paquete[3] = PaqueteRecibido[3];

RecibirPING(3,PaqueteRecibido[3]);

}

if(paqueteRX4[a-3] == Pong){

cout << "Recibio un mensaje PONG" << endl;

PaqueteRecibido[3].Emisor = (uint8_t)paqueteRX4[0];

PaqueteRecibido[3].IDpaquete = (uint8_t)paqueteRX4[1];

PaqueteRecibido[3].Prioridad = (uint8_t)paqueteRX4[2];

PaqueteRecibido[3].Receptor = (uint8_t)paqueteRX4[3];

PaqueteRecibido[3].TTL = (uint8_t)paqueteRX4[4];

PaqueteRecibido[3].pDatos[0] = (uint8_t)paqueteRX4[5];

PaqueteRecibido[3].pDatos[1] = (uint8_t)paqueteRX4[6];

PaqueteRecibido[3].pInterfaz = (uint8_t)paqueteRX4[7];

PaqueteRecibido[3].pModo = (uint8_t)paqueteRX4[8];

PaqueteRecibido[3].TamPaquete = (uint8_t)paqueteRX4[9];

paquete[3] = PaqueteRecibido[3];

RecibirPONG(3,PaqueteRecibido[3]);

}

if(Control == 1 && paqueteRX4[a-3] != Ping){

Control4 = 20;

}

cout << "FinRecepcionPaquete" << endl;

sleep(0.05);

}

// En RecepcionPaquete se reciben el resto de mensajes del algoritmo.

void RecepcionPaquete(Paquete paquete){

cout << "RecepcionPaquete" << endl;

sleep(0.05);

int a = 9+(paquete.TamPaquete);

//int8_t paqueteRX[a][4];

char paqueteRX[a][4];

for(int i=0;i<4;i++){

for(int j=0;j<a;j++){

paqueteRX[j][i] = 255;

}

}

if(openUart1){

InterfazRecibida = 1;

for(int w=0;w<a;w++){

paqueteRX[w][0] = (int8_t)uart1.read();

cout << paqueteRX[w][0] << endl;

sleep(0.05);

}

}

Page 56: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

56

if(openUart2){

InterfazRecibida = 2;

for(int w=0;w<a;w++){

paqueteRX[w][1] = (int8_t)uart2.read();

cout << paqueteRX[w][1] << endl;

sleep(0.05);

}

}

if(openUart3){

InterfazRecibida = 3;

for(int w=0;w<a;w++){

paqueteRX[w][2] = (int8_t)uart3.read();

cout << paqueteRX[w][2] << endl;

sleep(0.05);

}

}

if(openUart4){

InterfazRecibida = 4;

for(int w=0;w<a;w++){

paqueteRX[w][3] = (int8_t)uart4.read();

cout << paqueteRX[w][3] << endl;

sleep(0.05);

}

}

if(!RevisarCheck(paqueteRX),a){

return;

}else{

EnviarPaquete(Ack,miLiderID,0,0,0,0,0,0,j);

}

for(int j=0;j<4;j++){

if(paqueteRX[a-3][j] == Start){

cout << "Recibio un mensaje START" << endl;

PaqueteRecibido[j].Emisor = (uint8_t)paqueteRX[0][j];

PaqueteRecibido[j].IDpaquete = (uint8_t)paqueteRX[1][j];

PaqueteRecibido[j].Prioridad = (uint8_t)paqueteRX[2][j];

PaqueteRecibido[j].Receptor = (uint8_t)paqueteRX[3][j];

PaqueteRecibido[j].TTL = (uint8_t)paqueteRX[4][j];

PaqueteRecibido[j].pInterfaz = (uint8_t)paqueteRX[5][j];

PaqueteRecibido[j].pModo = (uint8_t)paqueteRX[6][j];

PaqueteRecibido[j].TamPaquete = (uint8_t)paqueteRX[7][j];

paquete[j] = PaqueteRecibido[j];

PrincipalEleccion(PaqueteRecibido[j],j);

}

if(paqueteRX[a-3][j] == Candidate){

cout << "Recibio un mensaje CANDIDATE" << endl;

PaqueteRecibido[j].Emisor = (uint8_t)paqueteRX[0][j];

PaqueteRecibido[j].IDpaquete = (uint8_t)paqueteRX[1][j];

PaqueteRecibido[j].Prioridad = (uint8_t)paqueteRX[2][j];

PaqueteRecibido[j].Receptor = (uint8_t)paqueteRX[3][j];

Page 57: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

57

PaqueteRecibido[j].TTL = (uint8_t)paqueteRX[4][j];

PaqueteRecibido[j].pDatos[0] = (uint8_t)paqueteRX[5][j];

PaqueteRecibido[j].pDatos[1] = (uint8_t)paqueteRX[6][j];

PaqueteRecibido[j].pInterfaz = (uint8_t)paqueteRX[7][j];

PaqueteRecibido[j].pModo = (uint8_t)paqueteRX[8][j];

PaqueteRecibido[j].TamPaquete = (uint8_t)paqueteRX[9][j];

paquete[j] = PaqueteRecibido[j];

PrincipalEleccion(PaqueteRecibido[j],j);

}

if(paqueteRX[a-3][j] == Rejected){

cout << "Recibio un mensaje REJECTED" << endl;

PaqueteRecibido[j].Emisor = (uint8_t)paqueteRX[0][j];

PaqueteRecibido[j].IDpaquete = (uint8_t)paqueteRX[1][j];

PaqueteRecibido[j].Prioridad = (uint8_t)paqueteRX[2][j];

PaqueteRecibido[j].Receptor = (uint8_t)paqueteRX[3][j];

PaqueteRecibido[j].TTL = (uint8_t)paqueteRX[4][j];

PaqueteRecibido[j].pDatos[0] = (uint8_t)paqueteRX[5][j];

PaqueteRecibido[j].pDatos[1] = (uint8_t)paqueteRX[6][j];

PaqueteRecibido[j].pInterfaz = (uint8_t)paqueteRX[7][j];

PaqueteRecibido[j].pModo = (uint8_t)paqueteRX[8][j];

PaqueteRecibido[j].TamPaquete = (uint8_t)paqueteRX[9][j];

paquete[j] = PaqueteRecibido[j];

PrincipalEleccion(PaqueteRecibido[j],j);

}

if(paqueteRX[a-3][j] == Elected){

cout << "Recibio un mensaje ELECTED" << endl;

PaqueteRecibido[j].Emisor = (uint8_t)paqueteRX[0][j];

PaqueteRecibido[j].IDpaquete = (uint8_t)paqueteRX[1][j];

PaqueteRecibido[j].Prioridad = (uint8_t)paqueteRX[2][j];

PaqueteRecibido[j].Receptor = (uint8_t)paqueteRX[3][j];

PaqueteRecibido[j].TTL = (uint8_t)paqueteRX[4][j];

PaqueteRecibido[j].pDatos[0] = (uint8_t)paqueteRX[5][j];

PaqueteRecibido[j].pDatos[1] = (uint8_t)paqueteRX[6][j];

PaqueteRecibido[j].pInterfaz = (uint8_t)paqueteRX[7][j];

PaqueteRecibido[j].pModo = (uint8_t)paqueteRX[8][j];

PaqueteRecibido[j].TamPaquete = (uint8_t)paqueteRX[9][j];

paquete[j] = PaqueteRecibido[j];

PrincipalEleccion(PaqueteRecibido[j],j);

}

if(paqueteRX[a-3][j] == Network){

cout << "Recibio un mensaje NETWORK" << endl;

PaqueteRecibido[j].Emisor = (uint8_t)paqueteRX[0][j];

PaqueteRecibido[j].IDpaquete = (uint8_t)paqueteRX[1][j];

PaqueteRecibido[j].Prioridad = (uint8_t)paqueteRX[2][j];

PaqueteRecibido[j].Receptor = (uint8_t)paqueteRX[3][j];

PaqueteRecibido[j].TTL = (uint8_t)paqueteRX[4][j];

PaqueteRecibido[j].pDatos[0] = (uint8_t)paqueteRX[5][j];

PaqueteRecibido[j].pDatos[1] = (uint8_t)paqueteRX[6][j];

PaqueteRecibido[j].pDatos[2] = (uint8_t)paqueteRX[7][j];

Page 58: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

58

PaqueteRecibido[j].pDatos[3] = (uint8_t)paqueteRX[8][j];

PaqueteRecibido[j].pInterfaz = (uint8_t)paqueteRX[9][j];

PaqueteRecibido[j].pModo = (uint8_t)paqueteRX[10][j];

PaqueteRecibido[j].TamPaquete = (uint8_t)paqueteRX[11][j];

paquete[j] = PaqueteRecibido[j];

RecibirRed(PaqueteRecibido[j],j);

EnviarPaquete(Ack,miLiderID,0,0,0,0,0,0,j);

sleep(0.8);

}

if(paqueteRX[a-3][j] == Position){

cout << "Recibio un mensaje POSITION" << endl;

PaqueteRecibido[j].Emisor = (uint8_t)paqueteRX[0][j];

PaqueteRecibido[j].IDpaquete = (uint8_t)paqueteRX[1][j];

PaqueteRecibido[j].Prioridad = (uint8_t)paqueteRX[2][j];

PaqueteRecibido[j].Receptor = (uint8_t)paqueteRX[3][j];

PaqueteRecibido[j].TTL = (uint8_t)paqueteRX[4][j];

PaqueteRecibido[j].pDatos[0] = (uint8_t)paqueteRX[5][j];

PaqueteRecibido[j].pDatos[1] = (uint8_t)paqueteRX[6][j];

PaqueteRecibido[j].pDatos[2] = (uint8_t)paqueteRX[7][j];

PaqueteRecibido[j].pDatos[3] = (uint8_t)paqueteRX[8][j];

PaqueteRecibido[j].pDatos[4] = (uint8_t)paqueteRX[9][j];

PaqueteRecibido[j].pDatos[5] = (uint8_t)paqueteRX[10][j];

PaqueteRecibido[j].pInterfaz = (uint8_t)paqueteRX[11][j];

PaqueteRecibido[j].pModo = (uint8_t)paqueteRX[12][j];

PaqueteRecibido[j].TamPaquete = (uint8_t)paqueteRX[13][j];

paquete[j] = PaqueteRecibido[j];

RecibirPosicion(PaqueteRecibido[j],j);

}

if(paqueteRX[a-3][j] == Turn){

cout << "Recibio un mensaje TURN" << endl;

PaqueteRecibido[j].Emisor = (uint8_t)paqueteRX[0][j];

PaqueteRecibido[j].IDpaquete = (uint8_t)paqueteRX[1][j];

PaqueteRecibido[j].Prioridad = (uint8_t)paqueteRX[2][j];

PaqueteRecibido[j].Receptor = (uint8_t)paqueteRX[3][j];

PaqueteRecibido[j].TTL = (uint8_t)paqueteRX[4][j];

PaqueteRecibido[j].pDatos[0] = (uint8_t)paqueteRX[5][j];

PaqueteRecibido[j].pInterfaz = (uint8_t)paqueteRX[6][j];

PaqueteRecibido[j].pModo = (uint8_t)paqueteRX[7][j];

PaqueteRecibido[j].TamPaquete = (uint8_t)paqueteRX[8][j];

paquete[j] = PaqueteRecibido[j];

RecibirRotacion(PaqueteRecibido[j],j);

}

if(paqueteRX[a-3][j] == Missing){

cout << "Recibio un mensaje MISSING" << endl;

PaqueteRecibido[j].Emisor = (uint8_t)paqueteRX[0][j];

PaqueteRecibido[j].IDpaquete = (uint8_t)paqueteRX[1][j];

PaqueteRecibido[j].Prioridad = (uint8_t)paqueteRX[2][j];

PaqueteRecibido[j].Receptor = (uint8_t)paqueteRX[3][j];

PaqueteRecibido[j].TTL = (uint8_t)paqueteRX[4][j];

Page 59: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

59

PaqueteRecibido[j].pDatos[0] = (uint8_t)paqueteRX[5][j];

PaqueteRecibido[j].pInterfaz = (uint8_t)paqueteRX[6][j];

PaqueteRecibido[j].pModo = (uint8_t)paqueteRX[7][j];

PaqueteRecibido[j].TamPaquete = (uint8_t)paqueteRX[8][j];

paquete[j] = PaqueteRecibido[j];

RecibirMissingRed(PaqueteRecibido[j]);

}

if(paqueteRX[a-3][j] == Ack){

cout << "Recibio un mensaje ACK" << endl;

PaqueteRecibido[j].Emisor = (uint8_t)paqueteRX[0][j];

PaqueteRecibido[j].IDpaquete = (uint8_t)paqueteRX[1][j];

PaqueteRecibido[j].Prioridad = (uint8_t)paqueteRX[2][j];

PaqueteRecibido[j].Receptor = (uint8_t)paqueteRX[3][j];

PaqueteRecibido[j].TTL = (uint8_t)paqueteRX[4][j];

PaqueteRecibido[j].pDatos[0] = (uint8_t)paqueteRX[5][j];

PaqueteRecibido[j].pInterfaz = (uint8_t)paqueteRX[6][j];

PaqueteRecibido[j].pModo = (uint8_t)paqueteRX[7][j];

PaqueteRecibido[j].TamPaquete = (uint8_t)paqueteRX[8][j];

paquete[j] = PaqueteRecibido[j];

RecibirACK(PaqueteRecibido[j],j);

}

}

cout << "FinRecepcionPaquete" << endl;

sleep(0.05);

}

// Inicialización de las variables del algoritmo.

void IncializacionAlgoritmo(int8_t miID){

cout << "InicializacionAlgoritmo" << endl;

sleep(0.05);

miLiderID = miID;

Direccion = 0;

for(int i=0;i<4;i++){

Interfaz.Ocupado[i] = 0;

Interfaz.Id[i] = -1;

Interfaz.suInterfaz[i] = -1;

}

for(int i=0;i<4;i++){

InterfazGuardada.Ocupado[i] = 0;

InterfazGuardada.ID[i] = -1;

InterfazGuardada.suInterfaz[i] = -1;

}

for(int i=0;i<Nbloques;i++){

Estados[i] = EstadoNulo; // EstadoNulo (16 = 10000)

}

for(int i=0;i<Nbloques;i++){

TablaRed[i][Lider] = -1;

TablaRed[i][Dentro] = 0;

}

Page 60: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

60

MiembrosMiRed = 0;

for(int i=0;i<Nbloques;i++){

if(i>=0 && i<Nbloques){

TablaRed[i][cX] = 0;

TablaRed[i][cY] = 0;

}

}

if(miID>=0 && miID<Nbloques){

if(TablaRed[miID][Dentro] == 0){

TablaRed[miID][Dentro] = 1;

MiembrosMiRed = MiembrosMiRed + 1;

}

TablaRed[miID][Lider] = miID;

}

for(int i=0;i<4;i++){

TablaDireccion[i] = (4+i)%4;

if(TablaDireccion[i]<0){

TablaDireccion[i] = TablaDireccion[i] + 4;

}

}

DireccionID = 0;

ConscienteDeRotacion = 0; // No consciente = 0 , Consciente = 1 , Consciente y Revisar = 2

EnvioPING = 1; // Cuando EnvioPING = 0 los bloques no envían PING ni PONG

cout << "FinInicializacionAlgoritmo" << endl;

sleep(0.05);

}

void TareaReinicioRed(){

cout << "TareaReinicioRed" << endl;

sleep(0.05);

int nVecinos = 0;

for(int i=0;i<4;i++){

if(i>=0 && i<4){

if(Interfaz.Ocupado[i] == 1){

nVecinos = nVecinos + 1;

}

}

}

if(nVecinos == 0){

for(int i=0;i<Nbloques;i++){

Estados[i] = EstadoNulo;

}

for(int i=0;i<Nbloques;i++){

TablaRed[i][Lider] = -1;

TablaRed[i][Dentro] = 0;

}

MiembrosMiRed = 0;

if(miID>=0 && miID<Nbloques){

if(TablaRed[miID][Dentro] == 0){

Page 61: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

61

TablaRed[miID][Dentro] = 1;

MiembrosMiRed = MiembrosMiRed + 1;

}

}

if(miID>=0 && miID<Nbloques){

TablaRed[miID][cX] = 0;

TablaRed[miID][cY] = 0;

TablaRed[miID][Lider] = miID;

}

miLiderID = miID;

}

ConscienteFaltaBloque = 0;

cout << "FinTareaReinicioRed" << endl;

sleep(0.05);

}

void EnviarPING(int interfaz){

cout << "EnviarPING" << endl;

sleep(0.05);

if(EnvioPING == 1){

EnviarPaquete(Ping,NULL,NULL,NULL,NULL,NULL,NULL,NULL,interfaz);

}

cout << "FinEnviarPaquete" << endl;

sleep(0.05);

}

void RecibirPING(int8_t miInterfaz, Paquete paquete){

cout << "RecibirPING" << endl;

sleep(0.05);

if(PINGrecib(paquete)){

EnviarPONG(miInterfaz);

}

cout << "FinRecibirPING" << endl;

sleep(0.05);

}

int PINGrecib(Paquete paquete){

if(paquete.pModo == Ping){

return 1;

}else{

return 0;

}

}

void EnviarPONG(int8_t interfaz){

cout << "EnviarPONG" << endl;

sleep(0.05);

if(EnvioPING == 1){

EnviarPaquete(PONG,MiembrosMiRed,interfaz,0,0,0,0,0,interfaz);

Page 62: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

62

}

cout << "FinEnviarPONG" << endl;

sleep(0.05);

}

// En esta función se analiza el PONG enviado por un vecino. Se decide si ese vecino hizo una rotación, o

// es un nuevo vecino.

void RecibirPONG(int8_t mi_interfaz, Paquete paquete){

cout << "RecibirPONG" << endl;

sleep(0.05);

miInterfaz = mi_Interfaz;

PONGrecibido[miInterfaz] = paquete;

suID[miInterfaz] = PONGrecibido[miInterfaz].Emisor;

MiembrosSuRed[miInterfaz] = PONGrecibido[miInterfaz].pDatos[0];

suInter[miInterfaz] = PONGrecibido[miInterfaz].pDatos[1];

if(suInter[miInterfaz]>=0 && suInter[miInterfaz]<4){

if(miInterfaz>=0 && miInterfaz<4){

if(Interfaz.Ocupado[miInterfaz] == 0){

VecRot[miInterfaz] = 1; // Nuevo Vecino

for(int i=0;i<Nbloques;i++){

TablaRed[i][cX] = 0;

TablaRed[i][cY] = 0;

}

}else{

if(suInter[miInterfaz] != Interfaz.suInterfaz[miInterfaz]){

VecRot[miInterfaz] = 2; // Rotacion

}

}

}

}

cout << "FinRecibirPONG" << endl;

sleep(0.05);

}

// Si no ser recibe un PONG significa que no hay vecino, se procede a cambiar la información de las

interfaces

// y a actualizar las tablas de información.

void PONGnoRecibido(uint8_t mi_Interfaz){

cout << "PONGnoRecibido" << endl;

sleep(0.05);

miInterfaz = mi_Interfaz;

if(miInterfaz>= 0 && miInterfaz<4){

suID[miInterfaz] = Interfaz.Id[miInterfaz];

}else{

suID[miInterfaz] = -1;

Page 63: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

63

}

if(suID[miInterfaz] == -1){

cout << "FinPONGnoRecibido" << endl;

sleep(0.05);

return;

}

if(ConscienteFaltaBloque == 0){

for(int i=0;i<4;i++){

InterfazGuardada.Ocupado[i] = Interfaz.Ocupado[i];

InterfazGuardada.Id[i] = Interfaz.Id[i];

InterfazGuardada.suInterfaz[i] = Interfaz.suInterfaz[i];

}

}

Interfaz.Ocupado[miInterfaz] = 0;

Interfaz.Id[miInterfaz] = -1;

Interfaz.suInterfaz[miInterfaz] = -1;

if(!EsVecino(suID[miInterfaz])){

ReinicioRed(suID[miInterfaz],miInterfaz);

}

cout << "FinPONGnoRecibido" << endl;

sleep(0.05);

}

int EsVecino(int suID){

cout << "EsVecino" << endl;

sleep(0.05);

for(int i=0;i<4;i++){

if(Interfaz.Id[i] == suID){

cout << "FinEsVecino" << endl;

sleep(0.05);

return 1;

}

}

cout << "FinNoEsVecino" << endl;

delay(300);

return 0;

}

int EraVecino(int suID){

cout << "EraVecino" << endl;

sleep(0.05);

for(int i=0;i<4;i++){

if(InterfazGuardada.ID[i] == suID){

cout << "FinEraVecino" << endl;

sleep(0.05);

return 1;

}

}

cout << "FinNoEraVecino" << endl;

Page 64: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

64

sleep(0.05);

return 0;

}

// Si hay un nuevo vecino, en esta función se capturan sus datos.

void NuevoVecino(uint8_t suID, uint8_t MiembrosSuRed, uint8_t miInterfaz, uint8_t suInter,int Con,

Paquete paquete, int ConA){

cout << "NuevoVecino" << endl;

sleep(0.05);

if(!EsVecino(suID) && !EraVecino(suID)){

if(Con == 0){

if(miInterfaz>=0 && miInterfaz<4){

if(suID != -1){

Interfaz.Ocupado[miInterfaz] = 1;

}else{

Interfaz.Ocupado[miInterfaz] = 0;

}

Interfaz.suInterfaz[miInterfaz] = suInter;

Interfaz.Id[miInterfaz] = suID;

}

}

RevisionEleccion(suID,MiembrosSuRed,miInterfaz,Con,paquete,ConA);

}else{

VecRot[miInterfaz] = 2; // Rotacion

}

cout << "FinNuevoVecino" << endl;

sleep(0.05);

}

// En esta función se verifica el primer criterio de selección de un líder, el cual es el número de miembros

// en la red.

void RevisionEleccion(uint8_t suID, uint8_t MiembrosSuRed, uint8_t miInterfaz, int Con, Paquete

paquete, int ConA){

cout << "RevisionEleccion" << endl;

sleep(0.05);

if(MiembrosSuRed < MiembrosMiRed){

EleccionEnvioRed(suID,MiembrosSuRed,miInterfaz,Con,ConA);

}else{

if(MiembrosSuRed == MiembrosMiRed){

if(Con == 0 || Con == 1 || ConA == 0 || ConA == 1)

Control = 3;

Page 65: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

65

if(Con == 0 || ConA == 0){

if((TablaRed[miInterfaz][Dentro] == 0) && (Interfaz.Ocupado[miInterfaz] == 1)){

Estados[miID] = EstadoInicial;

EnviarPaquete(Start,NULL,NULL,NULL,NULL,NULL,NULL,NULL,miInterfaz);

}

}else{

PrincipalEleccion(paquete,miInterfaz);

}

}else{

if(Con == 0){

sleep(0.5);

Control = 5;

paquete.TamPaquete = 2;

RecepecionPaquete(paquete); // Recibe REJECTED de EleccionEnvioRed

ControlInt[miInterfaz] == 1;

Control = 10;

return;

}

if(Con == 1){

sleep(0.5);

Control = 6;

paquete.TamPaquete = 2;

RecepecionPaquete(paquete); // Recibe ELECTED de EleccionEnvioRed

ControlInt[miInterfaz] = 2;

Control = 10;

return;

}

if(Con == 2){

sleep(1);

paquete.TamPaquete = 4;

RecepcionPaquete(paquete); // Recibe NETWORK de EleccionEnvioRed

ControlInt[miInterfaz] = 3;

Control = 10;

return;

}

if(Con == 3){

sleep(1.2);

paquete.TamPaquete = 6;

RecepcionPaquete(paquete); // Recibe POSITION de EleccionEnvioRed

Control = 6;

}

}

cout << "FinRevisionEleccion" << endl;

Page 66: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

66

sleep(0.05);

}

// Dependiendo del resultado de la funcion anterior, en ésta se envían los respectivos mensajes

// a un bloque que perdió la Elección.

void EleccionEnvioRed(int suID,int MiembrosSuRed,int miInterfaz, int Con, int ConA){

cout << "EleccionEnvioRed" << endl;

sleep(0.05);

if(miLiderID == -1){

cout << "EleccionEnvioRed" << endl;

sleep(0.05);

return;

}

if(Con == 0 || ConA == 2){

if(suID != miLiderID){

Estados[suID] = EstadoRechazado;

EnviarPaquete(Rejected,suID,MiembrosSuRed,0,0,0,0,0,miInterfaz);

sleep(0.8);

}

ControlInt[miInterfaz] = 1;

ControlIntA[miInterfaz] = 3;

Control = 10;

return;

}

if(Con == 1 || ConA == 3){

EnviarPaquete(Elected,miLiderID,MiembrosMiRed,0,0,0,0,0,miInterfaz);

sleep(1);

if((miLiderID>=0) && (miLiderID<Nbloques)){

for(int i=0;i<Nbloques;i++){

if(Estados[i] > EstadoInicial){

Estados[i] = EstadoRechazado;

}

}

Estados[miLiderID] = EstadoElegido;

}

ControlInt[miInterfaz] = 2;

ControlIntA[miInterfaz] = 4;

Control = 10;

return;

}

if(Con == 2 || ConA == 4){

EnvioRed(miInterfaz);

sleep(1);

ControlInt[miInterfaz] = 3;

ControlIntA[miInterfaz] = 5;

Control = 10;

Page 67: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

67

return;

}

if(Con == 3 || ConA == 5){

EnvioPosicion(miInterfaz,15);

Estados[suID] = EstadoRechazado;

Control = 6;

}

cout << "FinEleccionEnvioRed" << endl;

sleep(0.05);

}

// En esta función se analizan los datos de los mensajes recibidos por pérdida de una Elección.

void PrincipalEleccion(Paquete paquete, int miInterfaz){

cout << "PrincipalEleccion" << endl;

sleep(0.05);

uint8_t modo = paquete.pModo;

uint8_t EstadoBloque;

if(ControlInt[miInterfaz] == 0 || ControlIntA[miInterfaz] == 0){

if(modo > Start){

suID[miInterfaz] = paquete.pDatos[0];

MiembrosSuRed[miInterfaz] = paquete.pDatos[1];

}else{

suID[miInterfaz] = 0;

MiembrosSuRed[miInterfaz] = 0;

}

if(suID[miInterfaz] != -1){

cout << "FinPrincipalEleccion" << endl;

sleep(0.05);

return;

}

EstadoBloque = Estados[suID[miInterfaz]];

}

if(Control == 3){

if(modo == Start){

InicioEleccion(miInterfaz);

}

return;

}

if(Control == 4){

if(modo == Candidate){

if(EstadoBloque < 18){

EleccionCandidato(paquete,miInterfaz);

Page 68: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

68

}

}

return;

}

if(Control == 5){

if(modo == Rejected){

if(EstadoBloque < 19 || suID[miInterfaz] == miLiderID){

if(suID[miInterfaz] == miLiderID){

TodaviaEnEleccion = 0;

miLiderID = -1;

}

// EnviarPropagacion(paquete,paquete.pInterfaz);

EnviarPropagacion(paquete,(InterfazRecibida-1)); // Propaga el mensaje REJECTED.

Estados[suID[miInterfaz]] = 19; // Cambio mi estado a Rechazado.

if(b != 1){

sleep(0.8);

}else{

b = 0;

}

}

}

return;

}

if(Control == 6){

if(modo == Elected){

if(EstadoBloque != EstadoRechazado){

miLiderID = suID[miInterfaz];

DireccionID = 0;

// EnviarPropagacion(paquete,paquete.pInterfaz);

EnviarPropagacion(paquete,(InterfazRecibida-1)); // Propaga el mensaje ELECTED.

if((suID[miInterfaz]>=0) && (suID[miInterfaz]<Nbloques)){

for(int i=0;i<Nbloques;i++){

if(Estados[i] > EstadoInicial){

Estados[i] = EstadoRechazado;

}

}

Estados[suID[miInterfaz]] = EstadoElegido;

if(b != 1){

sleep(1);

}else{

b = 0;

}

}

}

}

}

Page 69: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

69

cout << "FinPrincipalEleccion" << endl;

sleep(0.05);

}

// Cuando hay una Elección cada bloque debe enviar un mensaje con el Candidato a ganar la Elección.

void InicioEleccion(int miInterfaz){

cout << "InicioEleccion" << endl;

sleep(0.05);

int8_t Para;

if(ControlInt[miInterfaz] == 0 || ControlIntA[miInterfaz] == 0){

ControlInt[miInterfaz] = 1;

ControlInt[miInterfaz] = 1;

return;

}

if((Estados[miID] == EstadoInicial) && (MiembrosMiRed == 1)){

if(miLider != -1){

Control = 4;

EnviarPaquete(Candidate,miLiderID,MiembrosMiRed,0,0,0,0,0,miInterfaz);

Estados[miID] = EstadoCandidato;

}else{

TodaviaEnEleccion = 0;

}

}else{

if(MiembrosMiRed > 1){

for(int mi_Interfaz=0;mi_Interfaz<4;mi_Interfaz++){

if(mi_Interfaz>=0 && mi_Interfaz<4){

Para = Interfaz.Id[mi_Interfaz];

}

if(Para != -1){

if(TablaRed[Para][Dentro] == 0){

if(miLiderID != -1){

Control = 4;

EnviarPaquete(Candidate,miLiderID,MiembrosMiRed,0,0,0,0,0,mi_Interfaz);

}else{

TodaviaEnEleccion = 0;

}

}

}

}

}

}

cout << "FinInicioEleccion" << endl;

sleep(0.05);

}

Page 70: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

70

// Se analiza la información del Candidato, si no cumple con los criterios de selección, pierde la Elección.

void EleccionCandidato(Paquete paquete, int miInterfaz){

cout << "EleccionCandidato" << endl;

sleep(0.05);

if(ControlInt[miInterfaz] == 1 || ControlIntA[miInterfaz] == 1){

suLiderID[miInterfaz] = paquete.pDatos[0];

MiembrosSuRed[miInterfaz] = paquete.pDatos[1];

if(suLiderID[miInterfaz]>=0 && suLiderID[miInterfaz]<Nbloques){

Estados[suLiderID[miInterfaz]] = EstadoCandidato;

}

ControlInt[miInterfaz] = 2;

ControlIntA[miInterfaz] = 2;

return;

}

if(MiembrosMiRed > 1){

if(MiembrosMiRed > MiembrosSuRed[miInterfaz]){

EleccionEnvioRed(suLiderID[miInterfaz],MiembrosSuRed[miInterfaz],miInterfaz,ControlInt[miInterfaz],

ControlIntA[miInterfaz]);

}else{

if((MiembrosMiRed == MiembrosSuRed[miInterfaz]) && (miLiderID < suLiderID[miInterfaz]) &&

(miLiderID >= 0)){

EleccionEnvioRed(suLiderID[miInterfaz],MiembrosSuRed[miInterfaz],miInterfaz,ControlInt[miInterfaz],

ControlIntA[miInterfaz]);

}else{

if(ControlIntA[miInterfaz] == 2){

sleep(0.5);

Control = 5;

paquete.TamPaquete = 2;

RecepcionPaquete(paquete); // Recibe REJECTED de EleccionEnvioRed

ControlIntA[miInterfaz] = 3;

Control = 10;

return;

}

if(ControlIntA[miInterfaz] == 3){

sleep(0.5);

Control = 6;

paquete.TamPaquete = 2;

RecepcionPaquete(paquete); // Recibe ELECTED de EleccionEnvioRed

ControlIntA[miInterfaz] = 4;

Page 71: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

71

Control = 10;

return;

}

if(ControlIntA[miInterfaz] == 4){

sleep(1);

paquete.TamPaquete = 4;

RecepcionPaquete(paquete); // Recibe NETWORK de EleccionEnvioRed

ControlIntA[miInterfaz] = 5;

Control = 10;

return;

}

if(ControlIntA[miInterfaz] == 5){

sleep(1.2);

paquete.TamPaquete = 6;

RecepcionPaquete(paquete); // Recibe POSITION de EleccionEnvioRed

Control = 6;

}

}

}

}else{

if(MiembrosSuRed[miInterfaz] == 1){

if((suLiderID[miInterfaz] > miLiderID) && (miLiderID >= 1)){

if(ControlInt[miInterfaz] == 2){

Control = 5;

sleep(0.8); // Espera a que el otro bloque propague el mensaje CANDIDATE

EnviarPaquete(Rejected,suLiderID[miInterfaz],MiembrosSuRed[miInterfaz],0,0,0,0,0,miInterfaz);

Estados[suLiderID[miInterfaz]] = EstadoRechazado;

sleep(0.8); // Espera a que el otro bloque propague el mensaje REJECTED

ControlInt[miInterfaz] = 3;

}

}else{

if(ControlInt[miInterfaz] == 2){

// EnviarPropagacion(paquete,paquete.pInterfaz); // Se envia en propagación el mensaje CANDIDATE.

Control = 5;

EnviarPropagacion(paquete,(InterfazRecibida-1));

if(b != 1){

sleep(0.8);

}else{

b = 0;

}

ControlInt[miInterfaz] = 3;

}

}

}

Page 72: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

72

}

cout << " FinEleccionCandidato" << endl;

sleep(0.05);

}

// Esta función solo la ejecuta el bloque seleccionado como líder. Envía los mensajes de red y e inicia la

// propagación de la posición.

void FinalEleccion(int miInterfaz){

cout << "FinalEleccion" << endl;

sleep(0.05);

if(ControlInt[miInterfaz] == 3){

ControlInt[miInterfaz] = 4;

return;

}

if(ControlInt[miInterfaz] == 4){

if((miLiderID != -1)){

sleep(0.3);

EnviarPaquete(Elected,miLiderID,MiembrosMiRed,0,0,0,0,0,miInterfaz);

if((miLiderID>=0) && (miLiderID<Nbloques)){

for(int i=0;i<Nbloques;i++){

if(Estados[i] > EstadoInicial){

Estados[i] = EstadoRechazado;

}

}

Estados[miLiderID] = EstadoElegido;

}

}

ControlInt[miInterfaz] = 5;

sleep(1);

return;

}

if(ControlInt[miInterfaz] == 5){

if(miID == miLiderID){

if((miID>=0) && (miID<Nbloques)){

TablaRed[miID][cX] = 0;

TablaRed[miID][cY] = 0;

}

}

//for(int mi_Interfaz=0;mi_Interfaz<4;mi_Interfaz++){

//EnvioRed(mi_Interfaz);

//}

EnvioRed(miInterfaz);

ControlInt[miInterfaz] = 6;

return;

Page 73: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

73

}

if(ControlInt[miInterfaz] == 6){

PropagacionPosicion(-1,15);

Control = 6;

}

cout << "FinFinalEleccion" << endl;

sleep(0.05);

}

void EnvioRed(int mi_Interfaz){

cout << "EnvioRed" << endl;

sleep(0.05);

int8_t Para;

if((mi_Interfaz>=0) && (mi_Interfaz<4)){

Para = Interfaz.Id[mi_Interfaz];

}else{

Para = -1;

}

if(miLiderID != -1){

if(Para != -1){

for(int i=0;i<Nbloques;i++){

if((TablaRed[i][Dentro] == 1) && (TablaRed[i][Lider] == miLiderID)){

EnviarPaquete(Network,i,TablaRed[i][cX],TablaRed[i][cY],miLiderID,0,0,0,mi_Interfaz);

sleep(1);

}

}

}

}

cout << "FinEnvioRed" << endl;

sleep(0.05);

}

void RecibirRed(Paquete paquete, miInterfaz){

cout << "RecibirRed" << endl;

sleep(0.05);

int nb = 0;

int Cambios = 0;

suID[miInterfaz] = paquete.pDatos[0];

x = paquete.pDatos[1];

y = paquete.pDatos[2];

suLiderID[miInterfaz] = paquete.pDatos[3];

if((suLiderID[miInterfaz] == miLiderID) && (suID[miInterfaz] != miID)){

if((suID[miInterfaz]>=0) && (suID[miInterfaz]<Nbloques)){

if(TablaRed[suID[miInterfaz]][Dentro] == 0){

TablaRed[suID[miInterfaz]][Dentro] = 1;

Page 74: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

74

MiembrosMiRed = MiembrosMiRed + 1;

Cambios = Cambios + 1;

}

if((TablaRed[suID[miInterfaz]][cX] != x) || (TablaRed[suID[miInterfaz]][cY] != y)){

TablaRed[suID[miInterfaz]][cX] = x;

TablaRed[suID[miInterfaz]][cY] = y;

Cambios = Cambios + 1;

}

TablaRed[suID[miInterfaz]][Lider] = suLiderID[miInterfaz];

if(Cambios > 0){

// EnviarPropagacion(paquete,paquete.pInterfaz);

EnviarPropagacion(paquete,(InterfazRecibida-1)); // Propaga la información de NETWORK.

if(b != 1){

sleep(1);

}else{

b = 0;

}

}

}else{

if(TablaRed[miID][Dentro] == 0){

TablaRed[miID][Dentro] = 1;

MiembrosMiRed = MiembrosMiRed + 1;

Cambios = Cambios + 1;

}

if((TablaRed[miID][cX] != x) || (TablaRed[miID][cY] != y)){

TablaRed[miID][cX] = x;

TablaRed[miID][cY] = y;

Cambios = Cambios + 1;

}

TablaRed[miID][Lider] = miLiderID;

if(Cambios > 0){

EnviarPropagacion(paquete,(InterfazRecibida-1)); // Propaga la información de NETWORK.

if(b != 1){

sleep(1);

}else{

b = 0;

}

}

}

}

cout << "FinRecibirRed" << endl;

sleep(0.05);

}

void ReinicioRed(uint8_t suID, int miInterfaz){

cout << "ReinicioRed" << endl;

sleep(0.05);

if(ConscienteFaltaBloque == 0){

ConscienteFaltaBloque = 1;

Page 75: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

75

QuitarBloque(suID);

EnviarPaquete(Missing,suID,0,0,0,0,0,0,(8+miInterfaz));

}

cout << "FinReinicioRed" << endl;

sleep(0.05);

}

void EnvioRedVecinos(){

cout << "EnvioRedVecinos" << endl;

sleep(0.05);

for(int mi_Interfaz=0;mi_Interfaz<4;mi_Interfaz++){

if(mi_Interfaz>=0 && mi_Interfaz<4){

if(Interfaz.Ocupado[mi_Interfaz] == 1){

suID[mi_Interfaz] = Interfaz.Id[mi_Interfaz];

if((suID[mi_Interfaz]>=0) && (suID[mi_Interfaz]<Nbloques)){

if(TablaRed[suID[mi_Interfaz]][Lider] == miLiderID){

EnviarPaquete(Network,suID[mi_Interfaz],TablaRed[suID[mi_Interfaz]][cX],TablaRed[suID[mi_Interfaz

]][cY],miLiderID,0,0,0,(8+mi_Interfaz));

}

}else{

if(TablaRed[miID][Lider] == miLiderID){

EnviarPaquete(Network,suID[mi_Interfaz],TablaRed[miID][cX],TablaRed[miID][cY],miLiderID,0,0,0,(8

+mi_Interfaz));

}

}

}

}

}

cout << "FinEnvioRedVecinos" << endl;

sleep(0.05);

}

void ValoresMaximosRed(){

cout << "ValoresMaximosRed" << endl;

sleep(0.05);

minX = TablaRed[miID][cX];

minY = TablaRed[miID][cY];

maxX = TablaRed[miID][cX];

maxY = TablaRed[miID][cY];

for(int i=0;i<Nbloques;i++){

if((TablaRed[i][Dentro] == 1) && (TablaRed[i][Lider] == miLiderID)){

if(TablaRed[i][cX] > maxX){

maxX = TablaRed[i][cX];

}

if(TablaRed[i][cY] > maxY){

maxY = TablaRed[i][cY];

}

Page 76: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

76

if(TablaRed[i][cX] < minX){

minX = TablaRed[i][cX];

}

if(TablaRed[i][cY] < minY){

minY = TablaRed[i][cY];

}

}

}

cout << "FinValoresMaximosRed" << endl;

sleep(0.05);

}

void RecibirMissingRed(Paquete paquete){

cout << "RecibirMissingRed" << endl;

sleep(0.05);

uint8_t BloquePerdido = paquete.pDatos[0];

if(EsVecino(BloquePerdido)){

cout << "FinRecibirMissingRed" << endl;

sleep(0.05);

return;

}

if(BloquePerdido>=0 && BloquePerdido<Nbloques){

QuitarBloque(BloquePerdido);

// EnviarPropagacion(paquete,paquete.pInterfaz);

EnviarPropagacion(paquete,(InterfazRecibida-1)); // Propaga informacion de MISSING

}

cout << "FinRecibirMissingRed" << endl;

sleep(0.05);

}

void RedCambiaLider(int minID){

cout << "RedCambiaLider" << endl;

sleep(0.05);

for(int i=0;i<Nbloques;i++){

if(TablaRed[i][Dentro] == 1){

if((i>=0) && (i<Nbloques)){

TablaRed[i][Lider] = minID;

Estados[i] = EstadoRechazado;

}

}

}

miLiderID = minID;

Estados[minID] = EstadoElegido;

cout << "FinRedCambiaLider" << endl;

sleep(0.05);

}

// En esta función se calcula la rotación. Esto se hace comparando las tablas de interfaz que el bloque tiene

Page 77: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

77

// guardadas. Dependiendo de la diferencia entre los índices se halla la rotación.

void Rotacion(uint8_t suID, uint8_t MiembrosSuRed, uint8_t miInterfaz, uint8_t suInter, int Con, Paquete

paquete, int ConA){

cout << "Rotacion" << endl;

sleep(0.05);

EstructuraInterfaz GuardarInterfaces;

int ViejaInterfaz,seFue;

if(ConscienteDeRotacion == 0){

ConscienteDeRotacion = 1;

if(EsVecino(suID)){

GuardarInterfaces = Interfaz; // Ocupado, ID, suInter

}else{

if(EraVecino(suID)){

GuardarInterfaces = InterfazGuardada; // Ocupado, ID, suInter

}else{

cout << "FinRotacion" << endl;

sleep(0.05);

return;

}

}

}

if(EsVecino(suID)){

for(int i=0;i<4;i++){

if(Interfaz.Id[i] == suID){

ViejaInterfaz = i;

}else{

ViejaInterfaz = -1;

}

}

seFue = 0;

}else{

for(int i=0;i<4;i++){

if(InterfazGuardada.ID[i] == suID){

ViejaInterfaz = i;

}else{

ViejaInterfaz = -1;

}

}

seFue = 1;

}

if(ViejaInterfaz != -1){

Interfaz.Ocupado[ViejaInterfaz] = 0;

Interfaz.suInterfaz[ViejaInterfaz] = -1;

Interfaz.Id[ViejaInterfaz] = -1;

}

if((miInterfaz>=0) && (miInterfaz<4)){

if(suID != -1){

Interfaz.Ocupado[miInterfaz] = 1;

}else{

Page 78: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

78

Interfaz.Ocupado[miInterfaz] = 0;

}

Interfaz.suInterfaz[miInterfaz] = suInter;

Interfaz.Id[miInterfaz] = suID;

}

if(ConscienteDeRotacion == 1){

ConscienteDeRotacion = 2;

int i=0;

while(i<4){

// for(int i=0;i<4;i++){

int InterfacesIguales = 1;

for(int j=0;j<4;j++){

if(GuardarInterfaces.ID[(i+j)%4] != Interfaz.Id[j]){

InterfacesIguales = 0;

}

}

if(InterfacesIguales == 1){

miRotacion = i;

i=4;

}else{

miRotacion = -1

i++;

}

}

if(seFue == 1){

RevisionEleccion(suID,MiembrosSuRed,miInterfaz,Con,paquete,ConA);

}

if(miRotacion>0){

EnvioRotacion(miRotacion);

}else{

if(miRotacion == 0){

paquete.TamPaquete = 1;

sleep(0.3);

RecepcionPaquete(paquete); // Recepcion de la Rotación.

}

}

}

cout << "FinRotacion" << endl;

sleep(0.05);

}

void EnvioRotacion(int8_t miRotacion){

cout << "EnvioRotacion" << endl;

sleep(0.05);

int8_t NuevaDireccion;

EnviarPaquete(Turn,miRotacion,0,0,0,0,0,0,15);

if(miID != miLiderID){

NuevaDireccion = ((Direccion + (4 - miRotacion))%4)%4;

if(NuevaDireccion<0){

Page 79: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

79

NuevaDireccion = NuevaDireccion + 4;

}

Direccion = NuevaDireccion;

for(int i=0;i<4;i++){

TablaDireccion[i] = (4 + i - Direccion)%4;

if(TablaDireccion[i] < 0){

TablaDireccion[i] = TablaDireccion[i] + 4;

}

}

}

cout << "FinEnvioRotacion" << endl;

sleep(0.05);

}

void RecibirRotacion(Paquete paquete, int miInterfaz){

cout << "RecibirRotacion" << endl;

sleep(0.05);

suRotacion[miInterfaz] = paquete.pDatos[0];

Interfaz.suInterfaz[InterfazRecibida - 1] = paquete.pInterfaz;

if(paquete.Emisor == miLiderID){

NuevaDireccion = ((Direccion + (4 - suRotacion[miInterfaz]))%4)%4;

if(NuevaDireccion<0){

NuevaDireccion = NuevaDireccion + 4;

}

Direccion = NuevaDireccion;

for(int i=0;i<4;i++){

TablaDireccion[i] = (4 + i - Direccion)%4;

if(TablaDireccion[i] < 0){

TablaDireccion[i] = TablaDireccion[i] + 4;

}

}

}

cout << "FinRecibirRotacion" << endl;

sleep(0.05);

}

void EnviarPosicionRed(int miInterfaz){

cout << "EnviarPosicionRed" << endl;

sleep(0.05);

if(miLiderID != -1){

EnviarPaquete(Network,miID,TablaRed[miID][cX],TablaRed[miID][cY],miLiderID,0,0,0,miInterfaz);

}

cout << "FinEnviarPosicionRed" << endl;

sleep(0.05);

}

void EnvioPosicion(uint8_t miInterfaz, uint8_t ttl){

cout << "EnvioPosicion" << endl;

sleep(0.05);

Page 80: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

80

Coordenadas.X = TablaRed[miID][cX];

Coordenadas.Y = TablaRed[miID][cY];

Coor Coordenadas1 = CalculoPosicion(Coordenadas,TablaDireccion[miInterfaz]);

if(miLiderID != -1){

EnviarPaquete(Position,DireccionID,miLiderID,Direccion,Coordenadas1.X,Coordenadas1.Y,miInterfaz,tt

l,miInterfaz);

}

cout << "FinEnvioPosicion" << endl;

sleep(0.05);

}

// En esta función se calculan las coordenadas que se le enviarán a cada vecino. Tomando como referencia

las

// coordenadas del líder que son (0,0)

Coor CalculoPosicion(Coor Coord,int8_t DireccionInterfaz){

cout << "CalculoPosicion" << endl;

sleep(0.05);

if(DireccionInterfaz == 0){

Coord.X = Coord.X - 1;

}else{

if(DireccionInterfaz == 1){

Coord.Y = Coord.Y + 1;

}else{

if(DireccionInterfaz == 2){

Coord.X = Coord.X + 1;

}else{

if(DireccionInterfaz == 3){

Coord.Y = Coord.Y - 1;

}

}

}

}

cout << "FinCalculoPosicion" << endl;

sleep(0.05);

return Coord;

}

void PropagacionPosicion(uint8_t InterfazProhibida, uint8_t ttl){

cout << "PropagacionPosicion" << endl;

sleep(0.05);

if(miID == miLiderID){

DireccionID = DireccionID + 1;

}

for(int interfaz=0;interfaz<4;interfaz++){

if(Interfaz.Ocupado[interfaz] == 1){

if(interfaz != InterfazProhibida){

EnvioPosicion(interfaz,ttl);

sleep(1);

Page 81: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

81

}

}

}

cout << "FinPropagacionPosicion" << endl;

sleep(0.05);

}

void RecibirPosicion(Paquete paquete, int miInterfaz){

cout << "RecibirPosicion" << endl;

sleep(0.05);

int nb;

int8_t difDireccion;

suDireccionID[miInterfaz] = paquete.pDatos[0];

suLiderID[miInterfaz] = paquete.pDatos[1];

suDireccion[miInterfaz] = paquete.pDatos[2];

x = paquete.pDatos[3];

y = paquete.pDatos[4];

suInter[miInterfaz] = paquete.pDatos[5];

if(suLiderID[miInterfaz] != miLiderID){

cout << "FinRecibirPosicion" << endl;

sleep(0.05);

return;

}

if(!EsVecino(paquete.Emisor)){

cout << "FinRecibirPosicion" << endl;

sleep(0.05);

return;

}

if(suInter[miInterfaz] != Interfaz.suInterfaz[(InterfazRecibida-1)]){

cout << "FinRecibirPosicion" << endl;

sleep(0.05);

return;

}

if((MiembrosMiRed > 1) && (miID == miLiderID) && (x != TablaRed[miID][cX]) && (y !=

TablaRed[miID][cY])){

PropagacionPosicion(-1,15);

cout << "FinRecibirPosicion" << endl;

sleep(0.05);

return;

}

if(DireccionID < suDireccionID[miInterfaz])

DireccionID = suDireccionID[miInterfaz] ;

difDireccion = ((suDireccion[miInterfaz] - Direccion) - (suInter[miInterfaz] - (InterfazRecibida-1) +

2))%4;

if(difDireccion != 0){

int8_t NuevaDireccion = (Direccion + difDireccion)%4;

Page 82: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

82

if(NuevaDireccion < 0){

NuevaDireccion = NuevaDireccion + 4;

}

Direccion = NuevaDireccion;

}

if((miID>=0) && (miID<Nbloques)){

TablaRed[miID][cX] = x;

TablaRed[miID][cY] = y;

TablaRed[miID][Lider] = suLiderID[miInterfaz];

}

PropagacionPosicion((InterfazRecibida-1),((paquete.ttl)-1));

if(b != 1){

sleep(1.3);

}else{

b = 0;

}

for(int interfaz=0;interfaz<4;interfaz++){

if((interfaz != (InterfazRecibida-1)) && (Interfaz.Ocupado[interfaz] == 1)){

EnvioRed(interfaz);

}else{

EnviarPosicionRed(InterfazRecibida-1);

}

}

cout << "FinRecibirPosicion" << endl;

sleep(0.05);

}

void RecibirACK(Paquete paquete, int miInterfaz){

cout << "RecibirACK" << endl;

sleep(0.05);

suLiderID[miInterfaz] = paquete.pDatos[0];

if(miID == miLiderID){

if(TablaRed[paquete.Emisor][Dentro] == 0){

TablaRed[paquete.Emisor][Dentro] = 1;

MiembrosMiRed = MiembrosMiRed + 1;

}

TablaRed[paquete.Emisor][Lider] = paquete.Emisor;

}

cout << "FinRecibirACK" << endl;

sleep(0.05);

}

void QuitarBloque(int suID){

cout << "QuitarBloque" << endl;

sleep(0.05);

if((suID>=0) && (suID<Nbloques)){

if(TablaRed[suID][Dentro] == 1){

TablaRed[suID][Dentro] = 0;

Page 83: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

83

TablaRed[suID][Lider] = -1;

Estados[suID] = EstadoNulo;

MiembrosMiRed = MiembrosMiRed - 1;

}

}

MiembrosMiRed = ContarMiembros();

if(MiembrosMiRed == 1){

Estados[miID] = EstadoNulo;

miLiderID = miID;

}else{

if(!HayUnLider()){

int8_t minID = miID;

for(int i=minID-1;i>=1;i--){

if(TablaRed[i][Dentro] == 1){

minID = i;

}

}

RedCambiaLider(minID);

}

}

cout << "FinQuitarBloque" endl;

sleep(0.05);

}

int HayUnLider(){

cout << "HayUnLider" << endl;

sleep(0.05);

for(int i=0;i<Nbloques;i++){

if(TablaRed[i][Dentro] == 1){

if(TablaRed[i][Lider] == miLiderID){

cout << "FinHayUnLider" << endl;

sleep(0.05);

return 1;

}else{

cout << "FinNoHayUnLider" << endl;

sleep(0.05);

return 0;

}

}

}

}

int ContarMiembros(){

cout << "ContarMiembros" << endl;

sleep(0.05);

int cont = 0;

for(int i=0;i<Nbloques;i++){

if(TablaRed[i][Dentro] == 1){

cont = cont + 1;

Page 84: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

84

}

}

cout << "FinContarMiembros" << endl;

sleep(0.05);

return cont;

}

int CheckSum(uint8_t paquete.IDpaquete,uint8_t paquete.Emisor,uint8_t paquete.ttl,uint8_t

paquete.pModo,uint8_t paquete.Receptor,uint8_t paquete.pInterfaz,uint8_t paquete.pDatos[0],uint8_t

paquete.pDatos[1],uint8_t paquete.pDatos[2],uint8_t paquete.pDatos[3],uint8_t paquete.pDatos[4],uint8_t

paquete.pDatos[5],uint8_t paquete.pDatos[6],uint8_t paquete.TamPaquete){

int suma =

paquete.IDpaquete+paquete.Emisor+paquete.ttl+paquete.pModo+paquete.Receptor+paquete.pInterfaz+pa

quete.pDatos[0]+paquete.pDatos[1]+paquete.pDatos[2]+paquete.pDatos[3]+paquete.pDatos[4]+paquete.p

Datos[5]+paquete.pDatos[6]+paquete.TamPaquete;

return suma;

}

int RevisarCheck(Paquete paqueteRX, int a){

int suma = 0;

for(int i=0;i<a-1;i++){

suma = suma + paqueteRX[i];

}

if(suma == paqueteRX[a]){

return 1;

}else{

return 0;

}

}

void InicioPaquete(Paquete paquete){

paquete.Emisor = 0;

paquete.IDpaquete = 0;

paquete.Prioridad = 0;

paquete.Receptor = 0;

paquete.ttl = 0;

paquete.pInterfaz = 0;

paquete.pModo = 0;

paquete.TamPaquete = 0;

for(int i=0;i<paquete.TamPaquete;i++){

paquete.pDatos[i] = 0;

}

}

// En esta función se construye el paquete que se le envía a los demás bloques.

Paquete ConstruccionPaquete(Paquete paquete, uint8_t PaqueteID, uint8_t xEmisor, uint8_t interfaz,

uint8_t xTTL, uint8_t modo, uint8_t Dato1,uint8_t Dato2,uint8_t Dato3,uint8_t Dato4,uint8_t

Dato5,uint8_t Dato6,uint8_t Dato7, uint8_t TamanoPaquete){

if(PaqueteID == 0){

Page 85: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

85

paquete.IDpaquete = PaqueteID;

PaqueteID = PaqueteID + 1;

}else{

paquete.IDpaquete = PaqueteID;

}

paquete.Emisor = xEmisor;

paquete.ttl = xTTL;

paquete.pModo = modo;

if(interfaz>=0 && interfaz<4){

paquete.Receptor = Interfaz.Id[interfaz];

}else{

paquete.Receptor = interfaz;

}

paquete.pInterfaz = interfaz;

paquete.pDatos[0] = Dato1;

paquete.pDatos[1] = Dato2;

paquete.pDatos[2] = Dato3;

paquete.pDatos[3] = Dato4;

paquete.pDatos[4] = Dato5;

paquete.pDatos[5] = Dato6;

paquete.pDatos[6] = Dato7;

paquete.TamPaquete = TamanoPaquete;

paquete.Check =

CheckSum(paquete.IDpaquete,paquete.Emisor,paquete.ttl,paquete.pModo,paquete.Receptor,paquete.pInte

rfaz,paquete.pDatos[0],paquete.pDatos[1],paquete.pDatos[2],paquete.pDatos[3],paquete.pDatos[4],paquet

e.pDatos[5],paquete.pDatos[6],paquete.TamPaquete);

return paquete;

}

// En esta función se define si el paquete se envía a un solo vecino o se envía en modo de propagación o

// se envía en modo broadcast.

void Enviar(Paquete paquete, uint8_t interfaz){

if(interfaz == 15){

EnviarBroadcast(paquete);

}else{

if(interfaz >= 8 && interfaz < 12){

EnviarPropagacion(paquete,(interfaz-8));

}else{

if(Interfaz.Ocupado[interfaz] == 1){

TransmisionPaquete(paquete,interfaz);

if(paquete.pModo == Start){

paquete.TamPaquete = 0;

RecepcionPaquete(paquete);

}

if(paquete.pModo == Candidate){

sleep(0.3);

paquete.TamPaquete = 2;

RecepcionPaquete(paquete); // Recibe CANDIDATE.

Page 86: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

86

}

if(paquete.pModo == Position){

sleep(1.5);

paquete.TamPaquete = 4;

RecepcionPaquete(paquete); // Recibe NETWORK.

}

if(paquete.pModo == Network){

sleep(1);

paquete.TamPaquete = 1;

RecepcionPaquete(paquete); // Recibe ACK

}

}

}

}

}

// En esta función se reciben todos los parámetros que se enviarán a los demás bloques.

void EnviarPaquete(uint8_t modo, uint8_t Dato1,uint8_t Dato2,uint8_t Dato3,uint8_t Dato4,uint8_t

Dato5,uint8_t Dato6,uint8_t Dato7,uint8_t interfaz){

cout << "EnviarPaquete" << endl;

sleep(0.05);

uint8_t ttl, TamanoPaquete;

InicioPaquete(paquete);

if(modo == Ping){

NuevoPaquete =

ConstruccionPaquete(paquete,0,miID,15,1,modo,Dato1,Dato2,Dato3,Dato4,Dato5,Dato6,Dato7,0);

NuevoPaquete.pInterfaz = interfaz;

TransmisionPaquete(NuevoPaquete,interfaz);

return;

}else{

if(modo == Pong){

NuevoPaquete =

ConstruccionPaquete(paquete,0,miID,interfaz,1,modo,Dato1,Dato2,Dato3,Dato4,Dato5,Dato6,Dato7,2);

TransmisionPaquete(NuevoPaquete,interfaz);

return;

}else{

if(modo == Start){

ttl = 1;

TamanoPaquete = 0;

}else{

if(modo == Candidate){

ttl = 15;

TamanoPaquete = 2;

}else{

if(modo == Rejected){

ttl = 15;

TamanoPaquete = 2;

}else{

if(modo == Elected){

Page 87: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

87

ttl = 15;

TamanoPaquete = 2;

}else{

if(modo == Network){

ttl = 15;

TamanoPaquete = 4;

}else{

if(modo == Position){

ttl = Dato7;

TamanoPaquete = 6;

}else{

if(modo == Turn){

ttl = 15;

TamanoPaquete = 1;

}else{

if(modo == Missing){

ttl = 15;

TamanoPaquete = 1;

}else{

if(modo == Ack){

ttl = 15;

TamanoPaquete = 1;

}else{

ttl = 15;

TamanoPaquete = 0;

}

}

}

}

}

}

}

}

}

}

}

NuevoPaquete =

ConstruccionPaquete(paquete,0,miID,interfaz,ttl,modo,Dato1,Dato2,Dato3,Dato4,Dato5,Dato6,Dato7,Ta

manoPaquete);

Enviar(NuevoPaquete,interfaz);

cout << "FinEnviarPaquete" << endl;

sleep(0.05);

}

void EnviarBroadcast(Paquete paquete){

cout << "EnviarBroadcast" << endl;

sleep(0.05);

paquete.Receptor = 15;

for(int interfaz=0;interfaz<4;interfaz++){

Page 88: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

88

if(Interfaz.Ocupado[interfaz] == 1){

paquete.pInterfaz = interfaz;

TransmisionPaquete(paquete,interfaz);

}

}

if(paquete.pModo == Candidate){

sleep(0.3);

paquete.TamPaquete = 2;

RecepcionPaquete(paquete); // Recibe CANDIDATE.

}

if(paquete.pModo == Turn){

sleep(0.3);

paquete.TamPaquete = 1;

RecepcionPaquete(paquete);

}

cout << "FinEnviarBroadcast" << endl;

sleep(0.05);

}

void EnviarPropagacion(Paquete paquete, uint8_t NoInterfaz){

cout << "EnviarPropagacion" << endl;

sleep(0.05);

if(paquete.Emisor != miID){

paquete.ttl = paquete.ttl - 1;

}

for(int interfaz=0;interfaz<4;interfaz++){

if(Interfaz.Ocupado[interfaz] == 1){

if(interfaz != NoInterfaz){

b = 1;

paquete.pInterfaz = interfaz;

TransmisionPaquete(paquete,interfaz);

}else{

b = 0;

}

}

}

if(paquete.pModo == Candidate){

paquete.TamPaquete = 2;

RecepcionPaquete(paquete); // Recibe REJECTED.

}

cout << "FinEnviarPropagacion" << endl;

sleep(0.05);

}

Page 89: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

89

ANEXO 2

Page 90: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

90

ANEXO 3

// PRUEBA ARDUINO

#include <SoftwareSerial.h>

#define Nbloques 4

#define TamMaximo 40

int8_t minX,minY,maxX,maxY;

int8_t QuienEstaAqui[3];

int ConscienteFaltaBloque;

int8_t ConscienteDeRotacion;

uint8_t EnvioPING;

uint8_t DireccionID;

uint8_t suDireccionID;

int8_t TablaRed[Nbloques][4];

int8_t TablaDireccion[4];

uint8_t PaqueteID;

uint8_t Estados[Nbloques];

#define Dentro 0

#define cX 1

#define cY 2

#define Lider 3

int8_t miID = 2;

int8_t miLiderID;

int8_t MiembrosMiRed;

int8_t suID;

int8_t suLiderID;

int8_t MiembrosSuRed;

int8_t miRotacion;

uint8_t suRotacion;

int8_t miInterfaz;

int8_t suInterfaz;

int8_t x,y;

int8_t Direccion;

int8_t suDireccion;

uint8_t TodaviaEnEleccion;

int DiagramaEstado = 1;

int R;

int IntControl = 0;

int UartControl;

int InterfazRecibida = 0;

const int sw = 6;

int lect=0;

SoftwareSerial Serial4(22,24); // Rx: 22; Tx: 24

// UARTS

uint8_t TXuarts[4] = {18,16,14,24};

uint8_t RXuarts[4] = {19,17,15,22};

Page 91: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

91

// Estados

#define EstadoNulo 16

#define EstadoInicial 17

#define EstadoCandidato 18

#define EstadoRechazado 19

#define EstadoElegido 20

// Modos

#define PING 0

#define PONG 10

#define START 20

#define CANDIDATE 30

#define REJECTED 40

#define ELECTED 50

#define NETWORK 60

#define POSITION 70

#define TURN 80

#define MISSING 90

#define ACK 100

struct EstructuraInterfaz{

int8_t Ocupado[4];

int8_t ID[4];

int8_t suInterfaz[4];

};

struct Paquete{

uint8_t Emisor;

uint8_t IDpaquete;

uint8_t Prioridad;

uint8_t Receptor;

uint8_t TTL;

uint8_t pDatos[TamMaximo];

uint8_t pInterfaz;

uint8_t pModo;

uint8_t TamPaquete;

};

struct COO{

int8_t X;

int8_t Y;

};

EstructuraInterfaz Interfaz,InterfazGuardada;

Paquete paquete,PONGrecibido[4],NuevoPaquete,PaqueteRecibido[4];

COO Coordenadas;

void setup() {

// put your setup code here, to run once:

Serial.begin(115200);

Page 92: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

92

Serial1.begin(115200);

Serial2.begin(115200);

Serial3.begin(115200);

Serial4.begin(115200);

pinMode(sw, INPUT);

}

void loop() {

// put your main code here, to run repeatedly:

switch(DiagramaEstado){

case 1:

Serial.println("ESTADO 1 INCIALIZACION");

delay(300);

InicializacionAlgoritmo(miID);

TareaReinicioRed();

DiagramaEstado = 2;

break;

case 2:

Serial.println("ESTADO 2 IDENTIFICACION");

delay(300);

for(int k=0;k<4;k++){

EnviarPING(k);

}

RecepcionPaquete(paquete);

if(DiagramaEstado != 3 && DiagramaEstado != 4){

DiagramaEstado = 5;

}

break;

case 3:

Serial.println("ESTADO 3 ELECCION");

delay(300);

// Es nuevo vecino

NuevoVecino(suID,MiembrosSuRed,miInterfaz,suInterfaz);

ValoresMaximosRed();

EnvioRedVecinos();

if((miID == miLiderID) && (MiembrosMiRed == 1)){

FinalEleccion();

paquete.TamPaquete = 4;

RecepcionPaquete(paquete); // Recibe NETWORK de RecibirPosicion.

}else{

if(MiembrosMiRed == 1){

delay(3000);

paquete.TamPaquete = 2;

RecepcionPaquete(paquete); // Recibe ELECTED de FinalEleccion.

delay(10000);

Page 93: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

93

paquete.TamPaquete = 4;

RecepcionPaquete(paquete); // Recibe NETWORK de FinalEleccion.

delay(16000);

paquete.TamPaquete = 6;

RecepcionPaquete(paquete); // Recibe POSITION de FinalEleccion.

delay(10000);

}

}

if(DiagramaEstado != 4){

DiagramaEstado = 5;

}

break;

case 4:

Serial.println("ESTADO 4 LOCALIZACION");

delay(300);

// Hubo rotación

Rotacion(suID,MiembrosSuRed,miInterfaz,suInterfaz);

DiagramaEstado = 5;

break;

case 5:

Serial.println("ESTADO 5 VISUALIZACION");

delay(300);

Serial.print("Norte Ocupado: ");

Serial.println(Interfaz.Ocupado[0]);

Serial.print("Norte ID: ");

Serial.println(Interfaz.ID[0]);

Serial.print("Norte suInterfaz: ");

Serial.println(Interfaz.suInterfaz[0]);

Serial.print("Este Ocupado: ");

Serial.println(Interfaz.Ocupado[1]);

Serial.print("Este ID: ");

Serial.println(Interfaz.ID[1]);

Serial.print("Este suInterfaz: ");

Serial.println(Interfaz.suInterfaz[1]);

Serial.print("Sur Ocupado: ");

Serial.println(Interfaz.Ocupado[2]);

Serial.print("Sur ID: ");

Serial.println(Interfaz.ID[2]);

Serial.print("Sur suInterfaz: ");

Serial.println(Interfaz.suInterfaz[2]);

Serial.print("Oeste Ocupado: ");

Serial.println(Interfaz.Ocupado[3]);

Serial.print("Oeste ID: ");

Serial.println(Interfaz.ID[3]);

Serial.print("Oeste suInterfaz: ");

Serial.println(Interfaz.suInterfaz[3]);

Serial.println("----------");

Page 94: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

94

Serial.println("Tabla de Red bloque con ID 0:");

Serial.print("Dentro de red: ");

Serial.println(TablaRed[0][Dentro]);

Serial.print("Coordenada X:");

Serial.println(TablaRed[0][cX]);

Serial.print("Coordenada Y:");

Serial.println(TablaRed[0][cY]);

Serial.print("Lider de la organización:");

Serial.println(TablaRed[0][Lider]);

Serial.println("Tabla de Red bloque con ID 1:");

Serial.print("Dentro de red: ");

Serial.println(TablaRed[1][Dentro]);

Serial.print("Coordenada X:");

Serial.println(TablaRed[1][cX]);

Serial.print("Coordenada Y:");

Serial.println(TablaRed[1][cY]);

Serial.print("Lider de la organización:");

Serial.println(TablaRed[1][Lider]);

Serial.println("Tabla de Red bloque con ID 2:");

Serial.print("Dentro de red: ");

Serial.println(TablaRed[2][Dentro]);

Serial.print("Coordenada X:");

Serial.println(TablaRed[2][cX]);

Serial.print("Coordenada Y:");

Serial.println(TablaRed[2][cY]);

Serial.print("Lider de la organización:");

Serial.println(TablaRed[2][Lider]);

Serial.println("Tabla de Red bloque con ID 3:");

Serial.print("Dentro de red: ");

Serial.println(TablaRed[3][Dentro]);

Serial.print("Coordenada X:");

Serial.println(TablaRed[3][cX]);

Serial.print("Coordenada Y:");

Serial.println(TablaRed[3][cY]);

Serial.print("Lider de la organización:");

Serial.println(TablaRed[3][Lider]);

Serial.println("----------");

Serial.print("Direccion: ");

Serial.println(Direccion);

lect = digitalRead(sw);

if(lect == HIGH){

DiagramaEstado = 2;

}

break;

default:

break;

Page 95: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

95

}

}

// Funciones

/////////////////////////////////////////////////ESTADO 1/////////////////////////////////////////////////////////////////

void InicializacionAlgoritmo(int8_t miID){

Serial.println("InicializacionAlgoritmo");

delay(300);

miLiderID = miID;

Direccion = 0;

for(int i=0;i<4;i++){

Interfaz.Ocupado[i] = 0;

Interfaz.ID[i] = -1;

Interfaz.suInterfaz[i] = -1;

}

for(int i=0;i<4;i++){

InterfazGuardada.Ocupado[i] = 0;

InterfazGuardada.ID[i] = -1;

InterfazGuardada.suInterfaz[i] = -1;

}

for(int i=0;i<Nbloques;i++){

Estados[i] = EstadoNulo; // EstadoNulo (16 = 10000)

}

for(int i=0;i<Nbloques;i++){

TablaRed[i][Lider] = -1;

TablaRed[i][Dentro] = 0;

}

MiembrosMiRed = 0;

for(int i=0;i<Nbloques;i++){

if(i>=0 && i<Nbloques){

TablaRed[i][cX] = 0;

TablaRed[i][cY] = 0;

}

}

if(miID>=0 && miID<Nbloques){

if(TablaRed[miID][Dentro] == 0){

TablaRed[miID][Dentro] = 1;

MiembrosMiRed = MiembrosMiRed + 1;

}

TablaRed[miID][Lider] = miID;

}

for(int i=0;i<4;i++){

TablaDireccion[i] = (4+i)%4;

if(TablaDireccion[i]<0){

TablaDireccion[i] = TablaDireccion[i] + 4;

}

}

DireccionID = 0;

Page 96: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

96

ConscienteDeRotacion = 0; // No consciente = 0 , Consciente = 1 , Consciente y Revisar = 2

EnvioPING = 1; // Cuando EnvioPING = 0 los bloques no envían PING ni PONG

Serial.println("FinInicializacionAlgoritmo");

delay(300);

}

void TareaReinicioRed(){

Serial.println("TareaReinicioRed");

delay(300);

int nVecinos = 0;

for(int i=0;i<4;i++){

if(i>=0 && i<4){

if(Interfaz.Ocupado[i] == 1){

nVecinos = nVecinos + 1;

}

}

}

if(nVecinos == 0){

for(int i=0;i<Nbloques;i++){

Estados[i] = EstadoNulo;

}

for(int i=0;i<Nbloques;i++){

TablaRed[i][Lider] = -1;

TablaRed[i][Dentro] = 0;

}

MiembrosMiRed = 0;

if(miID>=0 && miID<Nbloques){

if(TablaRed[miID][Dentro] == 0){

TablaRed[miID][Dentro] = 1;

MiembrosMiRed = MiembrosMiRed + 1;

}

}

if(miID>=0 && miID<Nbloques){

TablaRed[miID][cX] = 0;

TablaRed[miID][cY] = 0;

TablaRed[miID][Lider] = miID;

}

miLiderID = miID;

}

ConscienteFaltaBloque = 0;

Serial.println("FinTareaReinicioRed");

delay(300);

}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////ESTADO 2/////////////////////////////////////////////////////////////////

void EnviarPING(int interfaz){

Page 97: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

97

Serial.println("EnviarPING");

delay(300);

if(EnvioPING == 1){

// Enviar PING a la interfaz indicada

EnviarPaquete(PING,NULL,NULL,NULL,NULL,NULL,NULL,NULL,interfaz);

}

Serial.println("FinEnviarPING");

delay(300);

}

void RecibirPING(int8_t miInterfaz, Paquete paquete){

Serial.println("RecibirPING");

delay(300);

if(PINGrecib(paquete)){

EnviarPONG(miInterfaz);

}else{

return;

}

Serial.println("FinRecibirPING");

delay(300);

}

int PINGrecib(Paquete paquete){

Serial.println("PINGrecib");

delay(300);

if(paquete.pModo == PING){

Serial.println("FinPINGrecib");

delay(300);

return 1;

}else{

Serial.println("FinNoPINGrecib");

delay(300);

return 0;

}

}

void EnviarPONG(int8_t interfaz){

Serial.println("EnviarPONG");

delay(300);

if(EnvioPING == 1){

// Enviar PONG a la interfaz indicada

EnviarPaquete(PONG,MiembrosMiRed,interfaz,0,0,0,0,0,interfaz);

}

Serial.println("FinEnviarPONG");

delay(300);

}

void RecibirPONG(int8_t mi_Interfaz,Paquete paquete){

Serial.println("RecibirPONG");

Page 98: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

98

delay(300);

miInterfaz = mi_Interfaz;

PONGrecibido[miInterfaz] = paquete;

suID = PONGrecibido[miInterfaz].Emisor;

MiembrosSuRed = PONGrecibido[miInterfaz].pDatos[0];

suInterfaz = PONGrecibido[miInterfaz].pDatos[1];

// Serial.print("suID: ");

// Serial.println(suID);

// Serial.print("MiembrosSuRed: ");

// Serial.println(MiembrosSuRed);

// Serial.print("suInterfaz: ");

// Serial.println(suInterfaz);

// Serial.print("miInterfaz: ");

// Serial.println(miInterfaz);

// delay(300);

// Revisar la información

if(suInterfaz>=0 && suInterfaz<4){

if(miInterfaz>=0 && miInterfaz<4){

if(Interfaz.Ocupado[miInterfaz] == 0){

// Es nuevo vecino

DiagramaEstado = 3;

}else{

if(suInterfaz != Interfaz.suInterfaz[miInterfaz]){

// Hubo rotación

DiagramaEstado = 4;

}

}

}

}

Serial.println("FinRecibirPONG");

delay(300);

}

void PONGnoRecibido(uint8_t mi_Interfaz){

Serial.println("PONGnoRecibido");

delay(300);

miInterfaz = mi_Interfaz;

if(miInterfaz>=0 && miInterfaz<4){

suID = Interfaz.ID[miInterfaz];

}else{

suID = -1;

}

if(suID == -1){

Serial.println("FinPONGnoRecibido");

delay(300);

return;

}

if(ConscienteFaltaBloque == 0){

Page 99: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

99

for(int i=0;i<4;i++){

InterfazGuardada.Ocupado[i] = Interfaz.Ocupado[i];

InterfazGuardada.ID[i] = Interfaz.ID[i];

InterfazGuardada.suInterfaz[i] = Interfaz.suInterfaz[i];

}

}

Interfaz.Ocupado[miInterfaz] = 0;

Interfaz.ID[miInterfaz] = -1;

Interfaz.suInterfaz[miInterfaz] = -1;

if(!EsVecino(suID)){

// Reiniciar red

ReinicioRed(suID,miInterfaz);

}

Serial.println("FinPONGnoRecibido");

delay(300);

}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////ESTADO 3/////////////////////////////////////////////////////////////////

int EsVecino(int suID){

Serial.println("EsVecino");

delay(300);

for(int i=0;i<4;i++){

// Serial.print("Interfaz.ID: ");

// Serial.println(Interfaz.ID[i]);

if(Interfaz.ID[i] == suID){

Serial.println("FinEsVecino");

delay(300);

return 1;

}

}

Serial.println("FinNoEsVecino");

delay(300);

return 0;

}

int EraVecino(int suID){

Serial.println("EraVecino");

delay(300);

for(int i=0;i<4;i++){

// Serial.print("InterfazGuardada.ID: ");

// Serial.println(InterfazGuardada.ID[i]);

if(InterfazGuardada.ID[i] == suID){

Serial.println("FinEraVecino");

delay(300);

return 1;

}

Page 100: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

100

}

Serial.println("FinNoEraVecino");

delay(300);

return 0;

}

void NuevoVecino(uint8_t suID, uint8_t MiembrosSuRed, uint8_t miInterfaz, uint8_t suInterfaz){

Serial.println("NuevoVecino");

delay(300);

// Serial.print("suID: ");

// Serial.println(suID);

// Serial.print("MiembrosSuRed: ");

// Serial.println(MiembrosSuRed);

// Serial.print("miInterfaz: ");

// Serial.println(miInterfaz);

// Serial.print("suInterfaz: ");

// Serial.println(suInterfaz);

if(!EsVecino(suID) && !EraVecino(suID)){

if(miInterfaz>=0 && miInterfaz<4){

if(suID != -1){

Interfaz.Ocupado[miInterfaz] = 1;

}else{

Interfaz.Ocupado[miInterfaz] = 0;

}

Interfaz.suInterfaz[miInterfaz] = suInterfaz;

Interfaz.ID[miInterfaz] = suID;

}

// Serial.print("Interfaz.Ocupado: ");

// Serial.println(Interfaz.Ocupado[miInterfaz]);

// Serial.print("Interfaz.suInterfaz: ");

// Serial.println(Interfaz.suInterfaz[miInterfaz]);

// Serial.print("Interfaz.ID: ");

// Serial.println(Interfaz.ID[miInterfaz]);

// Se revisa si hay que hacer elección

RevisionEleccion(suID,MiembrosSuRed,miInterfaz);

}else{

// Hubo rotación

DiagramaEstado = 4;

}

Serial.println("FinNuevoVecino");

delay(300);

}

void RevisionEleccion(uint8_t suID, uint8_t MiembrosSuRed, uint8_t miInterfaz){

Serial.println("RevisionEleccion");

delay(300);

// Serial.print("MiembrosSuRed: ");

// Serial.println(MiembrosSuRed);

// Serial.print("MiembrosMiRed: ");

Page 101: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

101

// Serial.println(MiembrosMiRed);

// delay(300);

if(MiembrosSuRed < MiembrosMiRed){

// Elección envío de red

EleccionEnvioRed(suID,MiembrosSuRed,miInterfaz); // Se decide si el vecino es Rechazado o no.

}else{

if(MiembrosSuRed == MiembrosMiRed){

for(int i=0;i<4;i++){

// Serial.print("TablaRed[Dentro]: ");

// Serial.println(TablaRed[i+1][Dentro]);

if((TablaRed[i][Dentro] == 0) && (Interfaz.Ocupado[i] == 1)){

// Inicio Elección

Estados[miID] = EstadoInicial;

// InicioEleccion();

EnviarPaquete(START,NULL,NULL,NULL,NULL,NULL,NULL,NULL,i);

}

}

}else{

delay(7000);

paquete.TamPaquete = 2;

RecepcionPaquete(paquete); // Recibe REJECTED de EleccionEnvioRed

delay(7000);

paquete.TamPaquete = 2;

RecepcionPaquete(paquete); // Recibe ELECTED de EleccionEnvioRed

delay(10000);

paquete.TamPaquete = 4;

RecepcionPaquete(paquete); // Recibe NETWORK de EleccionEnvioRed

delay(12000);

paquete.TamPaquete = 6;

RecepcionPaquete(paquete); // Recibe POSITION de EleccionEnvioRed

}

}

Serial.println("FinRevisionEleccion");

delay(300);

}

void EleccionEnvioRed(int suID,int MiembrosSuRed,int miInterfaz){

Serial.println("EleccionEnvioRed");

delay(300);

// Serial.print("suID: ");

// Serial.println(suID);

// Serial.print("MiembrosSuRed: ");

// Serial.println(MiembrosSuRed);

if(miLiderID == -1){

return;

}

if(suID != miLiderID){

Estados[suID] = EstadoRechazado;

// Enviar nuevo paquete (REJECTED)

Page 102: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

102

EnviarPaquete(REJECTED,suID,MiembrosSuRed,0,0,0,0,0,miInterfaz);

}

delay(8000);

// Enviar nuevo paquete (ELECTED)

EnviarPaquete(ELECTED,miLiderID,MiembrosMiRed,0,0,0,0,0,miInterfaz);

if((miLiderID>=0) && (miLiderID<Nbloques)){

for(int i=0;i<Nbloques;i++){

if(Estados[i] > EstadoInicial){

Estados[i] = EstadoRechazado;

}

}

Estados[miLiderID] = EstadoElegido;

}

delay(5000);

// Envio de red

EnvioRed(miInterfaz);

delay(3000);

// Envio de la posicion

EnvioPosicion(miInterfaz,15);

Estados[suID] = EstadoRechazado;

Serial.println("FinEleccionEnvioRed");

delay(300);

}

void PrincipalEleccion(Paquete paquete){

Serial.println("PrincipalEleccion");

delay(300);

uint8_t modo = paquete.pModo;

uint8_t EstadoBloque;

if(modo > START){

suID = paquete.pDatos[0];

MiembrosSuRed = paquete.pDatos[1];

}else{

suID = 0;

MiembrosSuRed = 0;

// Serial.print("suID: ");

// Serial.println(suID);

// Serial.print("MiembrosSuRed: ");

// Serial.println(MiembrosSuRed);

}

if(suID == -1){

return;

}

EstadoBloque = Estados[suID];

// Serial.print("EstadoBloque: ");

// Serial.println(EstadoBloque);

if(modo == START){

// Inicio de elección

InicioEleccion();

Page 103: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

103

}

if(modo == CANDIDATE){

if(EstadoBloque < 18){

// Eleccion candidato

EleccionCandidato(paquete);

}

}

if(modo == REJECTED){

if(EstadoBloque < 19 || suID == miLiderID){

if(suID == miLiderID){

TodaviaEnEleccion = 0;

miLiderID = -1;

}

// Enviar propagación

EnviarPropagacion(paquete,(InterfazRecibida-1)); // Propaga el mensaje REJECTED.

Estados[suID] = 19; // Cambio mi estado a Rechazado.

}

}

if(modo == ELECTED){

if(EstadoBloque != EstadoRechazado){

miLiderID = suID;

DireccionID = 0;

// Enviar propagacion

EnviarPropagacion(paquete,(InterfazRecibida-1)); // Propaga el mensaje ELECTED.

if((suID>=0) && (suID<Nbloques)){

for(int i=0;i<Nbloques;i++){

if(Estados[i] > EstadoInicial){

Estados[i] = EstadoRechazado;

}

}

Estados[suID] = EstadoElegido;

}

}

}

Serial.println("FinPrincipalEleccion");

delay(300);

}

void InicioEleccion(){

Serial.println("InicioEleccion");

delay(300);

int8_t Para;

// Serial.print("Estados[miID]: ");

// Serial.println(Estados[miID]);

if((Estados[miID] == EstadoInicial) && (MiembrosMiRed == 1)){

// Serial.print("miLiderID: ");

// Serial.println(miLiderID);

// Serial.print("MiembrosMiRed: ");

// Serial.println(MiembrosMiRed);

Page 104: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

104

if(miLiderID != -1){

// Enviar nuevo paquete (CANDIDATE)

EnviarPaquete(CANDIDATE,miLiderID,MiembrosMiRed,0,0,0,0,0,15);

Estados[miID] = EstadoCandidato;

}else{

TodaviaEnEleccion = 0;

}

}else{

// Serial.print("MiembrosMiRed: ");

// Serial.println(MiembrosMiRed);

if(MiembrosMiRed > 1){

for(int mi_Interfaz=0;mi_Interfaz<4;mi_Interfaz++){

if(mi_Interfaz>=0 && mi_Interfaz<4){

Para = Interfaz.ID[mi_Interfaz];

}

if(Para != -1){

if(TablaRed[Para][Dentro] == 0){

if(miLiderID != -1){

// Enviar nuevo paquete (CANDIDATE)

EnviarPaquete(CANDIDATE,miLiderID,MiembrosMiRed,0,0,0,0,0,mi_Interfaz);

}else{

TodaviaEnEleccion = 0;

}

}

}

}

}

}

Serial.println("FinInicioEleccion");

delay(300);

}

void EleccionCandidato(Paquete paquete){

Serial.println("EleccionCandidato");

delay(300);

suLiderID = paquete.pDatos[0];

MiembrosSuRed = paquete.pDatos[1];

// Serial.print("suLiderID: ");

// Serial.println(suLiderID);

// Serial.print("MiembrosSuRed: ");

// Serial.println(MiembrosSuRed);

if(suLiderID>=0 && suLiderID<Nbloques){

Estados[suLiderID] = EstadoCandidato;

}

// Serial.print("MiembrosMiRed: ");

// Serial.println(MiembrosMiRed);

if(MiembrosMiRed > 1){

if(MiembrosMiRed > MiembrosSuRed){

// Elección envío de red

Page 105: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

105

EleccionEnvioRed(suLiderID,MiembrosSuRed,(InterfazRecibida - 1));

}else{

if((MiembrosMiRed == MiembrosSuRed) && (miLiderID < suLiderID) && (miLiderID >= 0)){

// Elección envío de red

EleccionEnvioRed(suLiderID,MiembrosSuRed,(InterfazRecibida - 1));

}else{

delay(7000);

paquete.TamPaquete = 2;

RecepcionPaquete(paquete); // Recibe REJECTED de EleccionEnvioRed

delay(7000);

paquete.TamPaquete = 2;

RecepcionPaquete(paquete); // Recibe ELECTED de EleccionEnvioRed

delay(10000);

paquete.TamPaquete = 4;

RecepcionPaquete(paquete); // Recibe NETWORK de EleccionEnvioRed

delay(12000);

paquete.TamPaquete = 6;

RecepcionPaquete(paquete); // Recibe POSITION de EleccionEnvioRed

}

}

}else{

if(MiembrosSuRed == 1){

if((suLiderID > miLiderID) && (miLiderID >= 1)){

// Enviar nuevo paquete (REJECTED)

EnviarPaquete(REJECTED,suLiderID,MiembrosSuRed,0,0,0,0,0,15);

// RecepcionPaquete();

Estados[suLiderID] = EstadoRechazado; // Cambio el estado del otro bloque a rechazado.

}else{

// Enviar propagación

EnviarPropagacion(paquete,(InterfazRecibida-1)); // Se envia en propagación el mensaje

CANDIDATE.

}

}

}

Serial.println("FinEleccionCandidato");

delay(300);

}

void FinalEleccion(){

Serial.println("FinalEleccion");

delay(300);

// Serial.print("miLiderID: ");

// Serial.println(miLiderID);

// Serial.print("MiembrosMiRed: ");

// Serial.println(MiembrosMiRed);

if((miLiderID != -1)){

delay(3000);

// Enviar nuevo paquete (ELECTED)

EnviarPaquete(ELECTED,miLiderID,MiembrosMiRed,0,0,0,0,0,15);

Page 106: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

106

if((miLiderID>=0) && (miLiderID<Nbloques)){

for(int i=0;i<Nbloques;i++){

if(Estados[i] > EstadoInicial){

Estados[i] = EstadoRechazado;

}

}

Estados[miLiderID] = EstadoElegido;

}

}

if(miID == miLiderID){

if((miID>=0) && (miID<Nbloques)){

TablaRed[miID][cX] = 0;

TablaRed[miID][cY] = 0;

}

}

delay(5000);

for(int mi_Interfaz=0;mi_Interfaz<4;mi_Interfaz++){

// Envío de la red

EnvioRed(mi_Interfaz);

}

delay(5000);

// BROADCAST DE LA POSICION

PropagacionPosicion(-1,15);

Serial.println("FinFinalEleccion");

delay(300);

}

void EnvioRed(int mi_Interfaz){

Serial.println("EnvioRed");

delay(300);

int8_t Para;

// Serial.print("miInterfaz: ");

// Serial.println(mi_Interfaz);

if((mi_Interfaz>=0) && (mi_Interfaz<4)){

Para = Interfaz.ID[mi_Interfaz];

}else{

Para = -1;

}

// Serial.print("Para: ");

// Serial.println(Para);

if(miLiderID != -1){

if(Para != -1){

for(int i=0;i<Nbloques;i++){

if((TablaRed[i][Dentro] == 1) && (TablaRed[i][Lider] == miLiderID)){

// Enviar nuevo paquete (NETWORK)

EnviarPaquete(NETWORK,i,TablaRed[i][cX],TablaRed[i][cY],miLiderID,0,0,0,mi_Interfaz);

delay(10000);

}

}

Page 107: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

107

}

}

Serial.println("FinEnvioRed");

delay(300);

}

void RecibirRed(Paquete paquete){

Serial.println("RecibirRed");

delay(300);

int nb = 0;

int Cambios = 0;

suID = paquete.pDatos[0];

x = paquete.pDatos[1];

y = paquete.pDatos[2];

suLiderID = paquete.pDatos[3];

// Serial.print("suID: ");

// Serial.println(suID);

// Serial.print("x: ");

// Serial.println(x);

// Serial.print("y: ");

// Serial.println(y);

// Serial.print("suLiderID: ");

// Serial.println(suLiderID);

// ¿Quién está en esta posición?

if((suLiderID == miLiderID) && (suID != miID)){

if((suID>=0) && (suID<Nbloques)){

if(TablaRed[suID][Dentro] == 0){

TablaRed[suID][Dentro] = 1;

MiembrosMiRed = MiembrosMiRed + 1;

Cambios = Cambios + 1;

}

if((TablaRed[suID][cX] != x) || (TablaRed[suID][cY] != y)){

TablaRed[suID][cX] = x;

TablaRed[suID][cY] = y;

Cambios = Cambios + 1;

}

TablaRed[suID][Lider] = suLiderID;

if(Cambios > 0){

// Enviar propagación

EnviarPropagacion(paquete,(InterfazRecibida-1)); // Propaga la información de NETWORK.

}

}else{

if(TablaRed[miID][Dentro] == 0){

TablaRed[miID][Dentro] = 1;

MiembrosMiRed = MiembrosMiRed + 1;

Cambios = Cambios + 1;

}

if((TablaRed[miID][cX] != x) || (TablaRed[miID][cY] != y)){

Page 108: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

108

TablaRed[miID][cX] = x;

TablaRed[miID][cY] = y;

Cambios = Cambios + 1;

}

TablaRed[miID][Lider] = miLiderID;

if(Cambios > 0){

// Enviar propagación

EnviarPropagacion(paquete,(InterfazRecibida-1)); // Propaga la información de NETWORK.

}

}

}

Serial.println("FinRecibirRed");

delay(300);

}

void ReinicioRed(uint8_t suID, int miInterfaz){

Serial.println("ReinicioRed");

delay(300);

if(ConscienteFaltaBloque == 0){

ConscienteFaltaBloque = 1;

// Quitar bloque

QuitarBloque(suID);

// Enviar nuevo paquete (MISSING)

EnviarPaquete(MISSING,suID,0,0,0,0,0,0,(8+miInterfaz));

}

Serial.println("FinReinicioRed");

delay(300);

}

void EnvioRedVecinos(){

Serial.println("EnvioRedVecinos");

delay(300);

for(int mi_Interfaz=0;mi_Interfaz<4;mi_Interfaz++){

if(mi_Interfaz>=0 && mi_Interfaz<4){

if(Interfaz.Ocupado[mi_Interfaz] == 1){

suID = Interfaz.ID[mi_Interfaz];

// Serial.print("suID: ");

// Serial.println(suID);

if((suID>=0) && (suID<Nbloques)){

// Serial.print("TablaRed[suID][Lider]: ");

// Serial.println(TablaRed[suID][Lider]);

// Serial.print("miLiderID: ");

// Serial.println(miLiderID);

if(TablaRed[suID][Lider] == miLiderID){

// Enviar nuevo paquete (NETWORK)

EnviarPaquete(NETWORK,suID,TablaRed[suID][cX],TablaRed[suID][cY],miLiderID,0,0,0,(8+mi_Interf

az));

}

Page 109: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

109

}else{

if(TablaRed[miID][Lider] == miLiderID){

// Enviar nuevo paquete (NETWORK)

EnviarPaquete(NETWORK,suID,TablaRed[miID][cX],TablaRed[miID][cY],miLiderID,0,0,0,(8+mi_Inter

faz));

}

}

}

}

}

Serial.println("FinEnvioRedVecinos");

delay(300);

}

void ValoresMaximosRed(){

Serial.println("ValoresMaximosRed");

delay(300);

minX = TablaRed[miID][cX];

minY = TablaRed[miID][cY];

maxX = TablaRed[miID][cX];

maxY = TablaRed[miID][cY];

for(int i=0;i<Nbloques;i++){

if((TablaRed[i][Dentro] == 1) && (TablaRed[i][Lider] == miLiderID)){

if(TablaRed[i][cX] > maxX){

maxX = TablaRed[i][cX];

}

if(TablaRed[i][cY] > maxY){

maxY = TablaRed[i][cY];

}

if(TablaRed[i][cX] < minX){

minX = TablaRed[i][cX];

}

if(TablaRed[i][cY] < minY){

minY = TablaRed[i][cY];

}

}

}

// Serial.print("MaxX: ");

// Serial.println(maxX);

// Serial.print("MaxY: ");

// Serial.println(maxY);

// Serial.print("MinX: ");

// Serial.println(minX);

// Serial.print("MinY: ");

// Serial.println(minY);

Serial.println("FinValoresMaximosRed");

delay(300);

}

Page 110: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

110

void RecibirMissingRed(Paquete paquete){

Serial.println("RecibirMissingRed");

delay(300);

uint8_t BloquePerdido = paquete.pDatos[0];

// Serial.print("BloquePerdido: ");

// Serial.println(BloquePerdido);

if(EsVecino(BloquePerdido)){

return;

}

if(BloquePerdido>=0 && BloquePerdido<Nbloques){

// Quitar bloque

QuitarBloque(BloquePerdido);

// Enviar propagación

EnviarPropagacion(paquete,(InterfazRecibida-1)); // Propaga informacion de MISSING

}

Serial.println("FinRecibirMissingRed");

delay(300);

}

void RedCambiaLider(int minID){

Serial.println("RedCambiaLider");

delay(300);

for(int i=0;i<Nbloques;i++){

if(TablaRed[i][Dentro] == 1){

if((i>=0) && (i<Nbloques)){

TablaRed[i][Lider] = minID;

Estados[i] = EstadoRechazado;

}

}

}

miLiderID = minID;

Estados[minID] = EstadoElegido;

// Serial.print("miLiderID: ");

// Serial.println(miLiderID);

Serial.println("FinRedCambiaLider");

delay(300);

}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////ESTADO 4/////////////////////////////////////////////////////////////////

void Rotacion(uint8_t suID, uint8_t MiembrosSuRed, uint8_t miInterfaz, uint8_t suInterfaz){

Serial.println("Rotacion");

delay(300);

EstructuraInterfaz GuardarInterfaces;

int ViejaInterfaz,seFue;

if(ConscienteDeRotacion == 0){

Page 111: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

111

ConscienteDeRotacion = 1;

if(EsVecino(suID)){

GuardarInterfaces = Interfaz; // Ocupado, ID, suInterfaz

}else{

if(EraVecino(suID)){

GuardarInterfaces = InterfazGuardada; // Ocupado, ID, suInterfaz

}else{

return;

}

}

}

if(EsVecino(suID)){

for(int i=0;i<4;i++){

if(Interfaz.ID[i] == suID){

ViejaInterfaz = i;

}else{

ViejaInterfaz = -1;

}

}

seFue = 0;

}else{

for(int i=0;i<4;i++){

if(InterfazGuardada.ID[i] == suID){

ViejaInterfaz = i;

}else{

ViejaInterfaz = -1;

}

}

seFue = 1;

}

if(ViejaInterfaz != -1){

Interfaz.Ocupado[ViejaInterfaz] = 0;

Interfaz.suInterfaz[ViejaInterfaz] = -1;

Interfaz.ID[ViejaInterfaz] = -1;

}

if((miInterfaz>=0) && (miInterfaz<4)){

if(suID != -1){

Interfaz.Ocupado[miInterfaz] = 1;

}else{

Interfaz.Ocupado[miInterfaz] = 0;

}

Interfaz.suInterfaz[miInterfaz] = suInterfaz;

Interfaz.ID[miInterfaz] = suID;

}

if(ConscienteDeRotacion == 1){

ConscienteDeRotacion = 2;

int i=0;

while(i<4){

// for(int i=0;i<4;i++){

Page 112: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

112

int InterfacesIguales = 1;

for(int j=0;j<4;j++){

if(GuardarInterfaces.ID[(i+j)%4] != Interfaz.Id[j]){

InterfacesIguales = 0;

}

}

if(InterfacesIguales == 1){

miRotacion = i;

i=4;

}else{

miRotacion = -1

i++;

}

}

// Serial.print("miRotacion: ");

// Serial.println(miRotacion);

if(seFue == 1){

// Se revisa si hay que hacer elección

RevisionEleccion(suID,MiembrosSuRed,miInterfaz);

}

if(miRotacion>0){

// Enviar rotación

EnvioRotacion(miRotacion);

}else{

if(miRotacion == 0){

paquete.TamPaquete = 1;

sleep(0.3);

RecepcionPaquete(paquete); // Recepcion de la Rotación.

DiagramaEstado = 5;

}

}

}

Serial.println("FinRotacion");

delay(300);

}

void EnvioRotacion(int8_t miRotacion){

Serial.println("EnvioRotacion");

delay(300);

int8_t NuevaDireccion;

uint8_t laRotacion = (uint8_t)miRotacion;

// Enviar nuevo paquete (TURN)

EnviarPaquete(TURN,laRotacion,0,0,0,0,0,0,15);

if(miID != miLiderID){

NuevaDireccion = ((Direccion + (4 - miRotacion))%4)%4;

// Serial.print("NuevaDireccion: ");

// Serial.println(NuevaDireccion);

if(NuevaDireccion<0){

NuevaDireccion = NuevaDireccion + 4;

Page 113: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

113

}

Direccion = NuevaDireccion;

// Serial.print("Direccion: ");

// Serial.println(Direccion);

for(int i=0;i<4;i++){

TablaDireccion[i] = (4 + i - Direccion)%4;

if(TablaDireccion[i] < 0){

TablaDireccion[i] = TablaDireccion[i] + 4;

}

}

}

Serial.println("FinEnvioRotacion");

delay(300);

}

void RecibirRotacion(Paquete paquete){

Serial.println("RecibirRotacion");

delay(300);

suRotacion = paquete.pDatos[0];

// Serial.print("suRotacion: ");

// Serial.println(suRotacion);

Interfaz.suInterfaz[InterfazRecibida - 1] = paquete.pInterfaz;

if(paquete.Emisor == miLiderID){

NuevaDireccion = ((Direccion + (4 - suRotacion))%4)%4;

if(NuevaDireccion<0){

NuevaDireccion = NuevaDireccion + 4;

}

Direccion = NuevaDireccion;

for(int i=0;i<4;i++){

TablaDireccion[i] = (4 + i - Direccion)%4;

if(TablaDireccion[i] < 0){

TablaDireccion[i] = TablaDireccion[i] + 4;

}

}

}

Serial.println("FinRecibirRotacion");

delay(300);

}

void EnviarPosicionRed(int miInterfaz){

Serial.println("EnviarPosicionRed");

delay(300);

if(miLiderID != -1){

// Enviar nuevo paquete (NETWORK)

EnviarPaquete(NETWORK,miID,TablaRed[miID][cX],TablaRed[miID][cY],miLiderID,0,0,0,miInterfaz)

;

}

Serial.println("FinEnviarPosicionRed");

Page 114: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

114

delay(300);

}

void EnvioPosicion(uint8_t miInterfaz, uint8_t ttl){

Serial.println("EnvioPosicion");

delay(300);

Coordenadas.X = TablaRed[miID][cX];

Coordenadas.Y = TablaRed[miID][cY];

// Cálculo de la posición

COO Coordenadas1 = CalculoPosicion(Coordenadas,TablaDireccion[miInterfaz]);

if(miLiderID != -1){

// Enviar nuevo paquete (POSITION)

EnviarPaquete(POSITION,DireccionID,miLiderID,Direccion,Coordenadas1.X,Coordenadas1.Y,miInterfa

z,ttl,miInterfaz);

}

Serial.println("FinEnvioPosicion");

delay(300);

}

COO CalculoPosicion(COO Coor,int8_t DireccionInterfaz){

Serial.println("CalculoPosicion");

delay(300);

// Serial.print("DireccionInterfaz: ");

// Serial.println(DireccionInterfaz);

if(DireccionInterfaz == 0){

Coor.X = Coor.X - 1;

}else{

if(DireccionInterfaz == 1){

Coor.Y = Coor.Y + 1;

}else{

if(DireccionInterfaz == 2){

Coor.X = Coor.X + 1;

}else{

if(DireccionInterfaz == 3){

Coor.Y = Coor.Y - 1;

}

}

}

}

// Serial.print("Coor.X: ");

// Serial.println(Coor.X);

// Serial.print("Coor.Y: ");

// Serial.println(Coor.Y);

Serial.println("FinCalculoPosicion");

delay(300);

return Coor;

}

Page 115: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

115

void PropagacionPosicion(uint8_t InterfazProhibida, uint8_t ttl){

Serial.println("PropagacionPosicion");

delay(300);

// Serial.print("InterfazProhibida: ");

// Serial.println(InterfazProhibida);

if(miID == miLiderID){

DireccionID = DireccionID + 1;

}

// Serial.print("DireccionID: ");

// Serial.println(DireccionID);

for(int interfaz=0;interfaz<4;interfaz++){

if((Interfaz.Ocupado[interfaz] == 1)){

if((interfaz != InterfazProhibida)){

// Envio posición

EnvioPosicion(interfaz,ttl);

delay(10000);

}

}

}

Serial.println("FinPropagacionPosicion");

delay(300);

}

void RecibirPosicion(Paquete paquete){

Serial.println("RecibirPosicion");

delay(300);

int nb;

int8_t difDireccion;

suDireccionID = paquete.pDatos[0];

suLiderID = paquete.pDatos[1];

suDireccion = paquete.pDatos[2];

x = paquete.pDatos[3];

y = paquete.pDatos[4];

suInterfaz = paquete.pDatos[5];

// Serial.print("suDireccionID: ");

// Serial.println(suDireccionID);

// Serial.print("suLiderID: ");

// Serial.println(suLiderID);

// Serial.print("suDireccion: ");

// Serial.println(suDireccion);

// Serial.print("x: ");

// Serial.println(x);

// Serial.print("y: ");

// Serial.println(y);

// Serial.print("suInterfaz: ");

// Serial.println(suInterfaz);

if(suLiderID != miLiderID){

return;

}

Page 116: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

116

if(!EsVecino(paquete.Emisor)){

return;

}

if(suInterfaz != Interfaz.suInterfaz[(InterfazRecibida-1)]){

return;

}

if((MiembrosMiRed > 1) && (miID == miLiderID) && (x != TablaRed[miID][cX]) && (y !=

TablaRed[miID][cY])){

// BROADCAST DE LA POSICION

PropagacionPosicion(-1,15);

return;

}

if(DireccionID < suDireccionID)

DireccionID = suDireccionID;

difDireccion = ((suDireccion - Direccion) - (suInterfaz - (InterfazRecibida-1) + 2))%4;

if(difDireccion != 0){

int8_t NuevaDireccion = (Direccion + difDireccion)%4;

if(NuevaDireccion < 0){

NuevaDireccion = NuevaDireccion + 4;

}

Direccion = NuevaDireccion;

}

if((miID>=0) && (miID<Nbloques)){

TablaRed[miID][cX] = x;

TablaRed[miID][cY] = y;

TablaRed[miID][Lider] = suLiderID;

}

// Propagación de la posición

PropagacionPosicion((InterfazRecibida-1),(paquete.TTL)-1);

for(int interfaz=0;interfaz<4;interfaz++){

if(interfaz != (InterfazRecibida-1) && Interfaz.Ocupado[interfaz] == 1){

// Envío de la red

EnvioRed(interfaz);

}else{

// Enviar mi posición a la red

EnviarPosicionRed(InterfazRecibida-1);

}

}

Serial.println("FinRecibirPosicion");

delay(300);

}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void RecibirACK(Paquete paquete){

Serial.println("RecibirACK");

delay(300);

suLiderID = paquete.pDatos[0];

Page 117: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

117

if(miID == miLiderID){

if(TablaRed[paquete.Emisor][Dentro] == 0){

TablaRed[paquete.Emisor][Dentro] = 1;

MiembrosMiRed = MiembrosMiRed + 1;

}

TablaRed[paquete.Emisor][Lider] = paquete.Emisor;

}

Serial.println("FinRecibirACK");

delay(300);

}

void QuitarBloque(int suID){

Serial.println("QuitarBloque");

delay(300);

if((suID>=0) && (suID<Nbloques)){

if(TablaRed[suID][Dentro] == 1){

TablaRed[suID][Dentro] = 0;

TablaRed[suID][Lider] = -1;

Estados[suID] = EstadoNulo;

MiembrosMiRed = MiembrosMiRed - 1;

}

}

MiembrosMiRed = ContarMiembros();

if(MiembrosMiRed == 1){

Estados[miID] = EstadoNulo;

miLiderID = miID;

}else{

if(!HayUnLider()){

int8_t minID = miID;

for(int i=minID-1;i>=1;i--){

if(TablaRed[i][Dentro] == 1){

minID = i;

}

}

// Red cambia de líder

RedCambiaLider(minID);

}

}

Serial.println("FinQuitarBloque");

delay(300);

}

int HayUnLider(){

Serial.println("HayUnLider");

delay(300);

for(int i=0;i<Nbloques;i++){

if(TablaRed[i][Dentro] == 1){

if(TablaRed[i][Lider] == miLiderID){

Serial.println("FinHayUnLider");

Page 118: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

118

delay(300);

return 1;

}else{

Serial.println("FinNoHayUnLider");

delay(300);

return 0;

}

}

}

}

int ContarMiembros(){

Serial.println("ContarMiembros");

delay(300);

int cont = 0;

for(int i=0;i<Nbloques;i++){

if(TablaRed[i][Dentro] == 1){

cont = cont + 1;

}

}

Serial.println("FinContarMiembros");

delay(300);

return cont;

}

void InicioPaquete(Paquete paquete){

// Serial.println("InicioPaquete");

// delay(300);

paquete.Emisor = 0;

paquete.IDpaquete = 0;

paquete.Prioridad = 0;

paquete.Receptor = 0;

paquete.TTL = 0;

paquete.pInterfaz = 0;

paquete.pModo = 0;

paquete.TamPaquete = 0;

for(int i=0;i<TamMaximo;i++){

paquete.pDatos[i] = 0;

}

// Serial.println("FinInicioPaquete");

// delay(300);

}

Paquete ConstruccionPaquete(Paquete paquete, uint8_t PaqueteID, uint8_t xEmisor, uint8_t interfaz,

uint8_t xTTL, uint8_t modo, uint8_t Dato1,uint8_t Dato2,uint8_t Dato3,uint8_t Dato4,uint8_t

Dato5,uint8_t Dato6,uint8_t Dato7, uint8_t TamanoPaquete){

// Serial.println("ConstruccionPaquete");

// delay(300);

if(PaqueteID == 0){

Page 119: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

119

paquete.IDpaquete = PaqueteID;

PaqueteID = PaqueteID + 1;

}else{

paquete.IDpaquete = PaqueteID;

}

paquete.Emisor = xEmisor;

paquete.TTL = xTTL;

paquete.pModo = modo;

if(interfaz>=0 && interfaz<4){

paquete.Receptor = Interfaz.ID[interfaz];

}else{

paquete.Receptor = interfaz;

}

paquete.pInterfaz = interfaz;

paquete.pDatos[0] = Dato1;

paquete.pDatos[1] = Dato2;

paquete.pDatos[2] = Dato3;

paquete.pDatos[3] = Dato4;

paquete.pDatos[4] = Dato5;

paquete.pDatos[5] = Dato6;

paquete.pDatos[6] = Dato7;

paquete.TamPaquete = TamanoPaquete;

// Serial.println("FinConstruccionPaquete");

// delay(300);

return paquete;

}

void Enviar(Paquete paquete, uint8_t interfaz){

// Serial.println("Enviar");

// delay(300);

// Serial.print("Interfaz: ");

// Serial.println(interfaz);

if(interfaz == 15){

// Enviar BROADCAST

EnviarBroadcast(paquete);

}else{

if(interfaz >= 8 && interfaz < 12){

// Enviar propagación

EnviarPropagacion(paquete,(interfaz-8));

}else{

if(Interfaz.Ocupado[interfaz] == 1){

// Transmisión del paquete a la interfaz indicada

TransmisionPaquete(paquete,TXuarts[interfaz]);

if(paquete.pModo == START){

paquete.TamPaquete = 0;

RecepcionPaquete(paquete);

}

if(paquete.pModo == CANDIDATE){

Page 120: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

120

delay(3000);

paquete.TamPaquete = 2;

RecepcionPaquete(paquete); // Recibe CANDIDATE.

}

if(paquete.pModo == POSITION){

delay(8000);

paquete.TamPaquete = 4;

RecepcionPaquete(paquete); // Recibe NETWORK.

}

if(paquete.pModo == NETWORK){

delay(14000);

paquete.TamPaquete = 1;

RecepcionPaquete(paquete);

}

}

}

}

// Serial.println("FinEnviar");

// delay(300);

}

void EnviarPaquete(uint8_t modo, uint8_t Dato1,uint8_t Dato2,uint8_t Dato3,uint8_t Dato4,uint8_t

Dato5,uint8_t Dato6,uint8_t Dato7,uint8_t interfaz){

Serial.println("EnviarPaquete");

delay(300);

uint8_t ttl, TamanoPaquete;

// Inicio del paquete

InicioPaquete(paquete);

if(modo == PING){

// Construcción del paquete

NuevoPaquete =

ConstruccionPaquete(paquete,0,miID,15,1,modo,Dato1,Dato2,Dato3,Dato4,Dato5,Dato6,Dato7,0);

NuevoPaquete.pInterfaz = interfaz;

// Transmisión del paquete a la interfaz indicada

TransmisionPaquete(NuevoPaquete,TXuarts[interfaz]);

return;

}else{

if(modo == PONG){

// Construcción del paquete

NuevoPaquete =

ConstruccionPaquete(paquete,0,miID,interfaz,1,modo,Dato1,Dato2,Dato3,Dato4,Dato5,Dato6,Dato7,2);

// Transmisión del paquete a la interfaz indicada

TransmisionPaquete(NuevoPaquete,TXuarts[interfaz]);

RecepcionPaquete(NuevoPaquete);

return;

}else{

if(modo == START){

ttl = 1;

TamanoPaquete = 0;

Page 121: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

121

}else{

if(modo == CANDIDATE){

ttl = 15;

TamanoPaquete = 2;

}else{

if(modo == REJECTED){

ttl = 15;

TamanoPaquete = 2;

}else{

if(modo == ELECTED){

ttl = 15;

TamanoPaquete = 2;

}else{

if(modo == NETWORK){

ttl = 15;

TamanoPaquete = 4;

}else{

if(modo == POSITION){

ttl = Dato7;

TamanoPaquete = 6;

}else{

if(modo == TURN){

ttl = 15;

TamanoPaquete = 1;

}else{

if(modo == MISSING){

ttl = 15;

TamanoPaquete = 1;

}else{

if(modo == ACK){

ttl = 15;

TamanoPaquete = 1;

}else{

ttl = 15;

TamanoPaquete = 0;

}

}

}

}

}

}

}

}

}

}

}

// Construcción del paquete

Page 122: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

122

NuevoPaquete =

ConstruccionPaquete(paquete,0,miID,interfaz,ttl,modo,Dato1,Dato2,Dato3,Dato4,Dato5,Dato6,Dato7,Ta

manoPaquete);

// Enviar a:

Enviar(NuevoPaquete,interfaz);

Serial.println("FinEnviarPaquete");

delay(300);

}

void EnviarBroadcast(Paquete paquete){

Serial.println("EnviarBroadcast");

delay(300);

paquete.Receptor = 15;

for(int interfaz=0;interfaz<4;interfaz++){

if(Interfaz.Ocupado[interfaz] == 1){

paquete.pInterfaz = interfaz;

// Transmisión del paquete

TransmisionPaquete(paquete,TXuarts[interfaz]);

}

}

if(paquete.pModo == CANDIDATE){

delay(3000);

paquete.TamPaquete = 2;

RecepcionPaquete(paquete); // Recibe CANDIDATE.

}

if(paquete.pModo == TURN){

delay(3000);

paquete.TamPaquete = 1;

RecepcionPaquete(paquete);

}

Serial.println("FinEnviarBroadcast");

delay(300);

}

void EnviarPropagacion(Paquete paquete, uint8_t NoInterfaz){

Serial.println("EnviarPropagacion");

delay(300);

// Serial.print("NoInterfaz: ");

// Serial.println(NoInterfaz);

if(paquete.Emisor != miID){

paquete.TTL = paquete.TTL - 1;

}

for(int interfaz=0;interfaz<4;interfaz++){

if(Interfaz.Ocupado[interfaz] == 1){

if(interfaz != NoInterfaz){

paquete.pInterfaz = interfaz;

// Transmisión del paquete

TransmisionPaquete(paquete,TXuarts[interfaz]);

}

Page 123: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

123

}

}

if(paquete.pModo == CANDIDATE){

delay(3000);

paquete.TamPaquete = 2;

RecepcionPaquete(paquete); // Recibe REJECTED.

}

Serial.println("FinEnviarPropagacion");

delay(300);

}

void TransmisionPaquete(Paquete paquete, int uart){

Serial.println("TransmisionPaquete");

delay(300);

int8_t Envio[8+(paquete.TamPaquete)];

if(paquete.pModo == PING){

Serial.println("Transmision de un PING");

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.TTL;

Envio[5] = (int8_t)paquete.pInterfaz;

Envio[6] = (int8_t)paquete.pModo;

Envio[7] = (int8_t)paquete.TamPaquete;

IntControl = 1;

R = millis()/1000;

UartControl = uart;

}

if(paquete.pModo == PONG){

Serial.println("Transmision de un PONG");

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.TTL;

Envio[5] = (int8_t)paquete.pDatos[0];

Envio[6] = (int8_t)paquete.pDatos[1];

Envio[7] = (int8_t)paquete.pInterfaz;

Envio[8] = (int8_t)paquete.pModo;

Envio[9] = (int8_t)paquete.TamPaquete;

}

if(paquete.pModo == START){

Serial.println("Transmision de un START");

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.TTL;

Page 124: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

124

Envio[5] = (int8_t)paquete.pInterfaz;

Envio[6] = (int8_t)paquete.pModo;

Envio[7] = (int8_t)paquete.TamPaquete;

}

if(paquete.pModo == CANDIDATE){

Serial.println("Transmision de un CANDIDATE");

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.TTL;

Envio[5] = (int8_t)paquete.pDatos[0];

Envio[6] = (int8_t)paquete.pDatos[1];

Envio[7] = (int8_t)paquete.pInterfaz;

Envio[8] = (int8_t)paquete.pModo;

Envio[9] = (int8_t)paquete.TamPaquete;

}

if(paquete.pModo == REJECTED){

Serial.println("Transmision de un REJECTED");

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.TTL;

Envio[5] = (int8_t)paquete.pDatos[0];

Envio[6] = (int8_t)paquete.pDatos[1];

Envio[7] = (int8_t)paquete.pInterfaz;

Envio[8] = (int8_t)paquete.pModo;

Envio[9] = (int8_t)paquete.TamPaquete;

}

if(paquete.pModo == ELECTED){

Serial.println("Transmision de un ELECTED");

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.TTL;

Envio[5] = (int8_t)paquete.pDatos[0];

Envio[6] = (int8_t)paquete.pDatos[1];

Envio[7] = (int8_t)paquete.pInterfaz;

Envio[8] = (int8_t)paquete.pModo;

Envio[9] = (int8_t)paquete.TamPaquete;

}

if(paquete.pModo == NETWORK){

Serial.println("Transmision de un NETWORK");

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Page 125: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

125

Envio[4] = (int8_t)paquete.TTL;

Envio[5] = (int8_t)paquete.pDatos[0];

Envio[6] = (int8_t)paquete.pDatos[1];

Envio[7] = (int8_t)paquete.pDatos[2];

Envio[8] = (int8_t)paquete.pDatos[3];

Envio[9] = (int8_t)paquete.pInterfaz;

Envio[10] = (int8_t)paquete.pModo;

Envio[11] = (int8_t)paquete.TamPaquete;

}

if(paquete.pModo == POSITION){

Serial.println("Transmision de un POSITION");

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.TTL;

Envio[5] = (int8_t)paquete.pDatos[0];

Envio[6] = (int8_t)paquete.pDatos[1];

Envio[7] = (int8_t)paquete.pDatos[2];

Envio[8] = (int8_t)paquete.pDatos[3];

Envio[9] = (int8_t)paquete.pDatos[4];

Envio[10] = (int8_t)paquete.pDatos[5];

Envio[11] = (int8_t)paquete.pInterfaz;

Envio[12] = (int8_t)paquete.pModo;

Envio[13] = (int8_t)paquete.TamPaquete;

}

if(paquete.pModo == TURN){

Serial.println("Transmision de un TURN");

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.TTL;

Envio[5] = (int8_t)paquete.pDatos[0];

Envio[6] = (int8_t)paquete.pInterfaz;

Envio[7] = (int8_t)paquete.pModo;

Envio[8] = (int8_t)paquete.TamPaquete;

}

if(paquete.pModo == MISSING){

Serial.println("Transmision de un MISSING");

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.TTL;

Envio[5] = (int8_t)paquete.pDatos[0];

Envio[6] = (int8_t)paquete.pInterfaz;

Envio[7] = (int8_t)paquete.pModo;

Envio[8] = (int8_t)paquete.TamPaquete;

Page 126: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

126

}

if(paquete.pModo == ACK){

Serial.println("Transmision de un ACK");

Envio[0] = (int8_t)paquete.Emisor;

Envio[1] = (int8_t)paquete.IDpaquete;

Envio[2] = (int8_t)paquete.Prioridad;

Envio[3] = (int8_t)paquete.Receptor;

Envio[4] = (int8_t)paquete.TTL;

Envio[5] = (int8_t)paquete.pDatos[0];

Envio[6] = (int8_t)paquete.pInterfaz;

Envio[7] = (int8_t)paquete.pModo;

Envio[8] = (int8_t)paquete.TamPaquete;

}

if(uart == TXuarts[0]){

for(int w=0;w<(8+(paquete.TamPaquete));w++){

int BytesEnviados = Serial1.write(Envio[w]);

// Serial.print("Dato enviado: ");

Serial.println(Envio[w]);

// Serial.println("Transmision por UART 1");

delay(300);

}

}

if(uart == TXuarts[1]){

for(int w=0;w<(8+paquete.TamPaquete);w++){

int BytesEnviados1 = Serial2.write(Envio[w]);

// Serial.print("Dato enviado: ");

Serial.println(Envio[w]);

// Serial.println("Transmision por UART 2");

delay(300);

}

}

if(uart == TXuarts[2]){

for(int w=0;w<(8+paquete.TamPaquete);w++){

int BytesEnviados2 = Serial3.write(Envio[w]);

// Serial.print("Dato enviado: ");

Serial.println(Envio[w]);

// Serial.println("Transmision por UART 3");

delay(300);

}

}

if(uart == TXuarts[3]){

for(int w=0;w<(8+paquete.TamPaquete);w++){

int BytesEnviados3 = Serial4.write(Envio[w]);

// Serial.print("Dato enviado: ");

Serial.println(Envio[w]);

// Serial.println("Transmision por UART 4");

delay(300);

}

}

Page 127: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

127

Serial.println("FinTransmisionPaquete");

delay(300);

}

void RecepcionPaquete(Paquete paquete){

Serial.println("RecepcionPaquete");

delay(300);

int a = 8+(paquete.TamPaquete);

int8_t paqueteRX[a][4];

for(int i=0;i<4;i++){

for(int j=0;j<a;j++){

paqueteRX[j][i] = 255;

}

}

if(Serial1.available()){

InterfazRecibida = 1;

for(int w=0;w<a;w++){

paqueteRX[w][0] = Serial1.read();

// Serial.println("Recepcion por UART 1");

// Serial.print("Dato recibido ");

Serial.println(paqueteRX[w][0]);

delay(300);

}

}

if(Serial2.available()){

InterfazRecibida = 2;

for(int w=0;w<a;w++){

paqueteRX[w][1] = Serial2.read();

// Serial.println("Recepcion por UART 2");

// Serial.print("Dato recibido ");

Serial.println(paqueteRX[w][1]);

delay(300);

}

}

if(Serial3.available()){

InterfazRecibida = 3;

for(int w=0;w<a;w++){

paqueteRX[w][2] = Serial3.read();

// Serial.println("Recepcion por UART 3");

// Serial.print("Dato recibido ");

Serial.println(paqueteRX[w][2]);

delay(300);

}

}

if(Serial4.available()){

InterfazRecibida = 4;

for(int w=0;w<a;w++){

paqueteRX[w][3] = Serial4.read();

// Serial.println("Recepcion por UART 4");

Page 128: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

128

// Serial.print("Dato recibido ");

Serial.println(paqueteRX[w][3]);

delay(300);

}

}

for(int j=0;j<4;j++){

if(paqueteRX[a-2][j] == START){

Serial.println("Recibio un mensaje START");

PaqueteRecibido[j].Emisor = (uint8_t)paqueteRX[0][j];

PaqueteRecibido[j].IDpaquete = (uint8_t)paqueteRX[1][j];

PaqueteRecibido[j].Prioridad = (uint8_t)paqueteRX[2][j];

PaqueteRecibido[j].Receptor = (uint8_t)paqueteRX[3][j];

PaqueteRecibido[j].TTL = (uint8_t)paqueteRX[4][j];

PaqueteRecibido[j].pInterfaz = (uint8_t)paqueteRX[5][j];

PaqueteRecibido[j].pModo = (uint8_t)paqueteRX[6][j];

PaqueteRecibido[j].TamPaquete = (uint8_t)paqueteRX[7][j];

PrincipalEleccion(PaqueteRecibido[j]);

}

if(paqueteRX[a-2][j] == CANDIDATE){

Serial.println("Recibio un mensaje CANDIDATE");

PaqueteRecibido[j].Emisor = (uint8_t)paqueteRX[0][j];

PaqueteRecibido[j].IDpaquete = (uint8_t)paqueteRX[1][j];

PaqueteRecibido[j].Prioridad = (uint8_t)paqueteRX[2][j];

PaqueteRecibido[j].Receptor = (uint8_t)paqueteRX[3][j];

PaqueteRecibido[j].TTL = (uint8_t)paqueteRX[4][j];

PaqueteRecibido[j].pDatos[0] = (uint8_t)paqueteRX[5][j];

PaqueteRecibido[j].pDatos[1] = (uint8_t)paqueteRX[6][j];

PaqueteRecibido[j].pInterfaz = (uint8_t)paqueteRX[7][j];

PaqueteRecibido[j].pModo = (uint8_t)paqueteRX[8][j];

PaqueteRecibido[j].TamPaquete = (uint8_t)paqueteRX[9][j];

PrincipalEleccion(PaqueteRecibido[j]);

}

if(paqueteRX[a-2][j] == REJECTED){

Serial.println("Recibio un mensaje REJECTED");

PaqueteRecibido[j].Emisor = (uint8_t)paqueteRX[0][j];

PaqueteRecibido[j].IDpaquete = (uint8_t)paqueteRX[1][j];

PaqueteRecibido[j].Prioridad = (uint8_t)paqueteRX[2][j];

PaqueteRecibido[j].Receptor = (uint8_t)paqueteRX[3][j];

PaqueteRecibido[j].TTL = (uint8_t)paqueteRX[4][j];

PaqueteRecibido[j].pDatos[0] = (uint8_t)paqueteRX[5][j];

PaqueteRecibido[j].pDatos[1] = (uint8_t)paqueteRX[6][j];

PaqueteRecibido[j].pInterfaz = (uint8_t)paqueteRX[7][j];

PaqueteRecibido[j].pModo = (uint8_t)paqueteRX[8][j];

PaqueteRecibido[j].TamPaquete = (uint8_t)paqueteRX[9][j];

PrincipalEleccion(PaqueteRecibido[j]);

}

if(paqueteRX[a-2][j] == ELECTED){

Serial.println("Recibio un mensaje ELECTED");

PaqueteRecibido[j].Emisor = (uint8_t)paqueteRX[0][j];

Page 129: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

129

PaqueteRecibido[j].IDpaquete = (uint8_t)paqueteRX[1][j];

PaqueteRecibido[j].Prioridad = (uint8_t)paqueteRX[2][j];

PaqueteRecibido[j].Receptor = (uint8_t)paqueteRX[3][j];

PaqueteRecibido[j].TTL = (uint8_t)paqueteRX[4][j];

PaqueteRecibido[j].pDatos[0] = (uint8_t)paqueteRX[5][j];

PaqueteRecibido[j].pDatos[1] = (uint8_t)paqueteRX[6][j];

PaqueteRecibido[j].pInterfaz = (uint8_t)paqueteRX[7][j];

PaqueteRecibido[j].pModo = (uint8_t)paqueteRX[8][j];

PaqueteRecibido[j].TamPaquete = (uint8_t)paqueteRX[9][j];

PrincipalEleccion(PaqueteRecibido[j]);

}

if(paqueteRX[a-2][j] == NETWORK){

Serial.println("Recibio un mensaje NETWORK");

PaqueteRecibido[j].Emisor = (uint8_t)paqueteRX[0][j];

PaqueteRecibido[j].IDpaquete = (uint8_t)paqueteRX[1][j];

PaqueteRecibido[j].Prioridad = (uint8_t)paqueteRX[2][j];

PaqueteRecibido[j].Receptor = (uint8_t)paqueteRX[3][j];

PaqueteRecibido[j].TTL = (uint8_t)paqueteRX[4][j];

PaqueteRecibido[j].pDatos[0] = (uint8_t)paqueteRX[5][j];

PaqueteRecibido[j].pDatos[1] = (uint8_t)paqueteRX[6][j];

PaqueteRecibido[j].pDatos[2] = (uint8_t)paqueteRX[7][j];

PaqueteRecibido[j].pDatos[3] = (uint8_t)paqueteRX[8][j];

PaqueteRecibido[j].pInterfaz = (uint8_t)paqueteRX[9][j];

PaqueteRecibido[j].pModo = (uint8_t)paqueteRX[10][j];

PaqueteRecibido[j].TamPaquete = (uint8_t)paqueteRX[11][j];

RecibirRed(PaqueteRecibido[j]);

EnviarPaquete(ACK,miLiderID,0,0,0,0,0,0,j);

delay(8000);

}

if(paqueteRX[a-2][j] == POSITION){

Serial.println("Recibio un mensaje POSITION");

PaqueteRecibido[j].Emisor = (uint8_t)paqueteRX[0][j];

PaqueteRecibido[j].IDpaquete = (uint8_t)paqueteRX[1][j];

PaqueteRecibido[j].Prioridad = (uint8_t)paqueteRX[2][j];

PaqueteRecibido[j].Receptor = (uint8_t)paqueteRX[3][j];

PaqueteRecibido[j].TTL = (uint8_t)paqueteRX[4][j];

PaqueteRecibido[j].pDatos[0] = (uint8_t)paqueteRX[5][j];

PaqueteRecibido[j].pDatos[1] = (uint8_t)paqueteRX[6][j];

PaqueteRecibido[j].pDatos[2] = (uint8_t)paqueteRX[7][j];

PaqueteRecibido[j].pDatos[3] = (uint8_t)paqueteRX[8][j];

PaqueteRecibido[j].pDatos[4] = (uint8_t)paqueteRX[9][j];

PaqueteRecibido[j].pDatos[5] = (uint8_t)paqueteRX[10][j];

PaqueteRecibido[j].pInterfaz = (uint8_t)paqueteRX[11][j];

PaqueteRecibido[j].pModo = (uint8_t)paqueteRX[12][j];

PaqueteRecibido[j].TamPaquete = (uint8_t)paqueteRX[13][j];

RecibirPosicion(PaqueteRecibido[j]);

}

if(paqueteRX[a-2][j] == TURN){

Serial.println("Recibio un mensaje TURN");

Page 130: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

130

PaqueteRecibido[j].Emisor = (uint8_t)paqueteRX[0][j];

PaqueteRecibido[j].IDpaquete = (uint8_t)paqueteRX[1][j];

PaqueteRecibido[j].Prioridad = (uint8_t)paqueteRX[2][j];

PaqueteRecibido[j].Receptor = (uint8_t)paqueteRX[3][j];

PaqueteRecibido[j].TTL = (uint8_t)paqueteRX[4][j];

PaqueteRecibido[j].pDatos[0] = (uint8_t)paqueteRX[5][j];

PaqueteRecibido[j].pInterfaz = (uint8_t)paqueteRX[6][j];

PaqueteRecibido[j].pModo = (uint8_t)paqueteRX[7][j];

PaqueteRecibido[j].TamPaquete = (uint8_t)paqueteRX[8][j];

RecibirRotacion(PaqueteRecibido[j]);

}

if(paqueteRX[a-2][j] == MISSING){

Serial.println("Recibio un mensaje MISSING");

PaqueteRecibido[j].Emisor = (uint8_t)paqueteRX[0][j];

PaqueteRecibido[j].IDpaquete = (uint8_t)paqueteRX[1][j];

PaqueteRecibido[j].Prioridad = (uint8_t)paqueteRX[2][j];

PaqueteRecibido[j].Receptor = (uint8_t)paqueteRX[3][j];

PaqueteRecibido[j].TTL = (uint8_t)paqueteRX[4][j];

PaqueteRecibido[j].pDatos[0] = (uint8_t)paqueteRX[5][j];

PaqueteRecibido[j].pInterfaz = (uint8_t)paqueteRX[6][j];

PaqueteRecibido[j].pModo = (uint8_t)paqueteRX[7][j];

PaqueteRecibido[j].TamPaquete = (uint8_t)paqueteRX[8][j];

RecibirMissingRed(PaqueteRecibido[j]);

}

if(paqueteRX[a-2][j] == ACK){

Serial.println("Recibio un mensaje ACK");

PaqueteRecibido[j].Emisor = (uint8_t)paqueteRX[0][j];

PaqueteRecibido[j].IDpaquete = (uint8_t)paqueteRX[1][j];

PaqueteRecibido[j].Prioridad = (uint8_t)paqueteRX[2][j];

PaqueteRecibido[j].Receptor = (uint8_t)paqueteRX[3][j];

PaqueteRecibido[j].TTL = (uint8_t)paqueteRX[4][j];

PaqueteRecibido[j].pDatos[0] = (uint8_t)paqueteRX[5][j];

PaqueteRecibido[j].pInterfaz = (uint8_t)paqueteRX[6][j];

PaqueteRecibido[j].pModo = (uint8_t)paqueteRX[7][j];

PaqueteRecibido[j].TamPaquete = (uint8_t)paqueteRX[8][j];

RecibirACK(PaqueteRecibido[j]);

}

if(paqueteRX[a-2][j] == PONG){

Serial.println("Recibio un mensaje PONG");

IntControl = 0;

PaqueteRecibido[j].Emisor = (uint8_t)paqueteRX[0][j];

PaqueteRecibido[j].IDpaquete = (uint8_t)paqueteRX[1][j];

PaqueteRecibido[j].Prioridad = (uint8_t)paqueteRX[2][j];

PaqueteRecibido[j].Receptor = (uint8_t)paqueteRX[3][j];

PaqueteRecibido[j].TTL = (uint8_t)paqueteRX[4][j];

PaqueteRecibido[j].pDatos[0] = (uint8_t)paqueteRX[5][j];

PaqueteRecibido[j].pDatos[1] = (uint8_t)paqueteRX[6][j];

PaqueteRecibido[j].pInterfaz = (uint8_t)paqueteRX[7][j];

PaqueteRecibido[j].pModo = (uint8_t)paqueteRX[8][j];

Page 131: VISUALIZACIÓN DE IMÁGENES MEDIANTE MÓDULOS LED ...

131

PaqueteRecibido[j].TamPaquete = (uint8_t)paqueteRX[9][j];

RecibirPONG(j,PaqueteRecibido[j]);

}

if(paqueteRX[a-2][j] == PING){

Serial.println("Recibio un mensaje PING");

PaqueteRecibido[j].Emisor = (uint8_t)paqueteRX[0][j];

PaqueteRecibido[j].IDpaquete = (uint8_t)paqueteRX[1][j];

PaqueteRecibido[j].Prioridad = (uint8_t)paqueteRX[2][j];

PaqueteRecibido[j].Receptor = (uint8_t)paqueteRX[3][j];

PaqueteRecibido[j].TTL = (uint8_t)paqueteRX[4][j];

PaqueteRecibido[j].pInterfaz = (uint8_t)paqueteRX[5][j];

PaqueteRecibido[j].pModo = (uint8_t)paqueteRX[6][j];

PaqueteRecibido[j].TamPaquete = (uint8_t)paqueteRX[7][j];

RecibirPING(j,PaqueteRecibido[j]);

}else{

PONGnoRecibido(j);

}

}

Serial.println("FinRecepcionPaquete");

delay(300);

}