visualizaciÓn de imÁgenes mediante mÓdulos led
TRANSCRIPT
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
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
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.
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.
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.
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].
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.
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.
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.
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
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.
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:
13
Figura 7. Diagrama secuencia Caso # 2.
14
Figura 8. Diagrama secuencia Caso # 3.
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.
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.
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.
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.
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.
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.
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.
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
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.
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.
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.
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
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
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
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;
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;
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);
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,
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
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){
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)
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();
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();
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{
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);
}
}
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++){
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);
}
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){
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);
}
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;
}
}
}
// ----------------------------------------------
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;
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];
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;
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);
}
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);
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;
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];
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;
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){
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];
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);
}
}
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];
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];
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];
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;
}
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){
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);
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;
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;
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;
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;
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;
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);
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;
}
}
}
}
}
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);
}
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;
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;
}
}
}
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;
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;
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;
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];
}
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
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{
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){
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);
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);
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;
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;
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;
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){
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.
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){
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++){
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);
}
89
ANEXO 2
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};
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);
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);
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("----------");
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;
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;
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){
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");
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){
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;
}
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: ");
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)
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();
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);
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
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);
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);
}
}
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)){
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));
}
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);
}
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){
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++){
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;
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");
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;
}
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;
}
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];
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");
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){
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){
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;
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
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]);
}
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;
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;
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;
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);
}
}
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");
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];
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");
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];
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);
}