Project: MOWE Optical Relay - OUWECAD/MOWE GitHub Wiki

##Table of Contents

Team
Introduction
Project Summary
Hardware Design
Code Developed


Team

Will Nichols and Brian Gilder, Senior Electrical Engineering students at the University of Tulsa. This project was submitted for Spring 2016 Senior Design II class. The project final report can be downloaded here.

Introduction

One of the problems with free-space optics for communication is the relative ease for a channel to be blocked by external interference, such as fog or other physical barriers. Sending an identical transmission along multiple paths mitigates this risk, since if one transmission is interrupted the data can still be received by the target. This project developed relay modules capable of sending a transmission along multiple paths.

Project Summary

For this project, three specialized sets of modules (nodes) were developed. The first, and simplest, was the relay node, comprised of one receiver and one transmitter. This node simply retransmits the information it receives further along the network. This can both boost the signal strength of the transmission and redirect it. The second node developed is the splitter node, which is comprised of one receiver and two transmitters. This node sends the data it receives to two nodes further in the network, both nodes receiving identical copies of the data. The final node developed was the switch node, comprised of two receivers and one transmitter. This node detects if a stream is active or blocked (has not seen a high value for at least one second), and switches to an active stream accordingly.

Hardware Design

In the interest of simplicity and space minimization, our nodes were arranged 90° from each other. From the initial relay node, connected to a computer, the next downstream node is the splitter. The signal is split and sent to two simple relay nodes along the interruptible paths (the paths with greater lengths designed to test the switch’s functionality by giving the option of blocking the transmission path between nodes) and received by two more simple relays which then redirect their signals to the switch node at the end of the network. A topological image follows:

topology

Each node was constructed from the necessary number of receiver and transmitter modules, given the particular node configuration (relay, switch, splitter). The nodes were connected via wires between data ports, allowing for more flexibility in placement and reconfigurable options for redesigning or adapting each node. By using the wire attachments, physical nodes need not have the modules soldered to each other, but instead can have them spaced as closely or as far apart as needed. This also allowed for “impossible” configurations, such as directly back-to-back, which could not be achieved due to soldering restrictions with respect to data and ground ports on the backs of individual modules.

The modules we used have 6 ports on the front and 6 on the back. Each pair is called P1 – P6. By default, the pads on the front are Tx and the pads on the back are Rx for each port. As our project only had simplex operation, we were able to jump Tx pads on one module to Rx pads on adjacent modules to create each node without having to worry about communication in the opposite direction. For this reason, we were able to keep the default Tx/Rx configurations on each chip. For simple relays, the receiver modules were connected by the Tx pad on Port 1 to the Rx pad on Port 1 on the LED module. For the splitter, the receiver module had the Tx pad on Port 1 connected to the Rx pad on Port 1 of one of the LED modules, and the Tx pad on Port 2 connected to the Rx pad on Port 1 on the other LED module. Conversely, the switch node had both receiver modules connected with the Tx pads on their Port 1’s to the Rx pad on the LED module’s Port 1 and Port 2.

setup

For our project, we used cubic wood blocks as support for our nodes. This was convenient for the 90° orientation and for not having to 3D print custom or complicated support structures for each node. To elevate the blocks, we used 5 ¾” round-headed bolts screwed into wood blocks epoxied to a wooden board. All non-chip elements were painted with a matte black paint. The distance for non-interruptible links (that is, the default distance between nodes) was required for our project to be at least 8”, so the edges of each epoxied block were 9” from the adjacent blocks. The distance for interruptible links was required to be at least 14”, so the edges of the epoxied blocks were 15” from adjacent blocks. Since the holes in the MOWE modules were so small, screws that could fit in the holes could not be readily found. For this reason, nails were used to affix the chips to the blocks.

By using the threaded bolts, nodes could be rotationally aligned in order to ensure proper transmission. They also allowed the blocks to be “unscrewed” down the shafts in order to allow for vertical alignment as well. However, testing for the project showed that acceptable parallel lateral tolerance for maintaining adequate transmission (that is, no rotational alignment) was 2.5” for short links and 4” for long links. Since all transmitter and receiver centerlines were within half an inch of 5 ⅛” vertically, and practically 0° laterally, alignment was not a major concern (once acceptable threshold values were chosen, the importance of which is apparent in changing lighting conditions).

All wooden support blocks were roughly 1.25” cubes. The MOWE modules were affixed directly to the appropriate faces of the cubes by nails through the MOWE modules’ fastener holes. The wooden structural board is 30.5” by 24.5”. This gave us enough space to place all nodes with acceptable buffer distance to ensure the minimum distance requirements were met, while still allowing for portability of the project itself.

Code Developed

Files Created:

relay.c, relay.h, topology_relay.h

Modifications to existing files:

FreeRTOS.h: Timers are required for the switch module’s transmitter and the originating transmitter. Must configure timers in FreeRTOS.h using the following code:

#ifndef configUSE_TIMERS

#define configUSE_TIMERS 1

#endif

#ifndef configTIMER_TASK_PRIORITY

#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1)

#endif

//Not created by interrupts, should not be that large. Really should only be one at a time.

#ifndef configTIMER_QUEUE_LENGTH

#define configTIMER_QUEUE_LENGTH 3

#endif

#ifndef configTIMER_TASK_STACK_DEPTH

#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE

#endif

aos.h:

Add #include relay.h and the appropriate topology file for your project.

relay.h macro definitions:

THRESHOLD

Values used to set the threshold between a 1 and a 0. Two values were used since our project had links of multiple distances. This value may be changed freely to fit the required application.

MSDATARATE

Rate, in milliseconds, of transmission data. Used for both sending and receiving. Default value: 100

STREAM_TIMEOUT

Time, in milliseconds, before a stream times out. Only used by swtich Tx modules. If no signal is detected within this time, the active stream will switch. Default value: 1000

MESSAGE_LENGTH

Length, in characters (bytes) of the message being transmitted. Used by both the sending module and the switch Tx module.

MESSAGE

Text to be sent by the transmitting module

relay.c functions:

void relaySetup(void)

This function initializes the relay modules. This function automatically adjusts for the type of module and its position in the relay if TX,RX,SWITCH, and SPLITTER are properly defined for the current module. Uses P1 and possibly P2 by default (P2 used for splitter and switch).

  • A receiver will enter an infinite loop in this function, as will a switch.
  • A transmitter will exit this function, but the front-end LED will be in use, as will the P1 port.
  • A switch node will print status information to P1 if a computer is connected to the Tx side, which is otherwise unused.

void debugThreshold(void)

Available if _debug_threshold is defined. Repeatedly prints the current value of the receiver to P1 for debugging purposes. This should be used to determine the needed threshold values in the intended lighting conditions.

void vTimerCallbackSend( TimerHandle_t xTimer )

Available if _data_test is defined. Timer interrupt service routine for sending data bits at reliable intervals. Not strictly necessary for the operation of the relay system,but used to test data communications. Should only be called as an ISR. See http://www.freertos.org/RTOS-software-timer.html and http://www.freertos.org/FreeRTOS-Software-Timer-API-Functions.html for a more detailed explaination of the use of timers.

void dataTest(void)

Available if _data_test is defined. Initializes the timer to send data via the front-end LED. The rate of transmission is defined by MSDATARATE in relay.h. Enters an infinite loop and does not return. Used to test transmitting data, and is not required for the function of the relays.

void vTimerCallbackSwitch( TimerHandle_t xTimer )

Available if TX and SWITCH are defined. Timer interrupt service routine for changing active stream if the currently active stream has gone silent for some time. The amount of time is defined by STREAM_TIMEOUT in relay.h. This function is intended for internal use only, and is only intended to be called as an ISR. See http://www.freertos.org/RTOS-software-timer.html and http://www.freertos.org/FreeRTOS-Software-Timer-API-Functions.html for a more detailed explaination of the use of timers.

void vTimerCallbackReceive( TimerHandle_t xTimer )

Available if TX and SWITCH are defined. Timer interrupt service routine for receiving data at a constant rate defined by MSDATARATE in relay.h. This function is intended for internal use only, and is only intended to be called as an ISR. See http://www.freertos.org/RTOS-software-timer.html and http://www.freertos.org/FreeRTOS-Software-Timer-API-Functions.html for a more detailed explaination of the use of timers.

void relayDMASetup(UART_HandleTypeDef* huart, uint8_t * dest, uint16_t num)

Sets up a DMA stream from the specified port (huart) to the specified destination address (dest) of the specified size in bytes (num). Used internally to setup the DMA streams for the Tx modules.

void relayDMASetup2(UART_HandleTypeDef* huart, uint8_t * dest, uint16_t num)

Sets up a DMA stream from the specified port (huart) to the specified destination address (dest) of the specified size in bytes (num). Used internally to setup the DMA streams for the switch Tx module.