With this project ending, future students at Worcester Polytechnic Institute will have the opportunity to develop an even better system on the foundation this team has laid. The VLC system created currently transmits small text messages at a relatively high speed. Future projects will have the option of continuing from where we have left off, using this technology to transmit data in forms such as live streams of audio or video files.
Another problem that future teams are likely to encounter is in the way their system’s ADC functions.
As mentioned in previous sections of this paper, the functionality of the ADC is what eventually caused us to realize that it was not feasible to transmit an audio file successfully. As mentioned previously, the problem is solvable, but given the amount of time that the team had left when the issue was discovered, there was not enough time. WWhen choosing a microcontroller for the transmitter and especially the receiver is to choose the board that has good documentation andgives you the ability to accessthe registers directly for more flexibility when programming.
In the coming years, we can expect that VLC technology will vastly improve and become ubiquitous worldwide because of its advantages. It is important that future students investigate this promising new technology, as VLC systems will play a major role in the world of wireless communications since the Internet of Things becomes closer to reality.
50
References
[1] http://www.cisco.com/c/en/us/solutions/service-provider/visual-networking-index-vni/index.html#~forecast
[2] http://www.ntia.doc.gov/files/ntia/publications/2003-allochrt.pdf [3] FCC 2014
[4] https://www.wpi.edu/Pubs/E-project/Available/E-project-032814- 001416/unrestricted/MQP_Report_Final_Draft_3_27_14.pdf
[5] http://www.theengineer.co.uk/in-depth/the-big-story/light-reading-visible-light-communications/1007419.article
[6] http://ronja.twibright.com/
[7] http://axrtek.com/momo/
[8] http://www.bluehaze.com.au/modlight/GrothArticle1.htm
[9] S. Louvros, D. Fuschelberger, N. Sklavosm M. Hübner, D. Goehringer, and P. Kitsos, “VLC Technology for LTE Indoor Planning,” System-Level Design Methodologies for
Telecommunication. NY: Springer, 2014, pp. 23.
[10] http://www.siemens.com/innovation/en/news/2010/500-megabits-second-with-white-led-light.htm
[11] http://www.ted.com/talks/harald_haas_wireless_data_from_every_light_bulb
[12] http://www.techthefuture.com/technology/using-visible-light-frequencies-for-wireless-data-transfer/
[13] http://www.ieee802.org/15/pub/TG7.html - IEEE 802.15.7
51
Appendix A: Parts List
Component Model
Number Quantity
Microcontroller
Unit STM32F401RE 2
Op-Amp AD848JN 1
Transistor 2N2222A 1
LED LW514 10
Photodiode SFH 213 5
52
Appendix B: Matlab Code
%in_buf = 2^ 18; %this is for testing timeout = 30;
%Open Serial Port s = serial('COM6');
%serial port settings
set(s,'BaudRate', 19200, 'InputBufferSize', frame_size, 'Timeout', timeout, 'Terminator', 'CR');
fopen(s);
%Read in data from serial port out = fread(s, frame_size, 'uchar')
match_filter.m
function [match_data, index] = match_filter(received_data, header, frame_size)
%Match Filter Function:
% This function will take binary data received from the MCU and will
% compare it to the known preamble or header to determine
% where the start of the transmission is
%Find where in the array, the message should be converted from
%performs correlation on the received data and the preamble corr = xcorr(received_data, header);
%finds the peak of the correlation maxCorr = max(corr);
%determine which index has a value that is equal to maxCorr index = find(corr == maxCorr);
frames = length(index);
%calculates the index that is the start of the actual data for n = 1:frames
index(n) = index(n) - length(received_data) + length(header) + 1;
end
%uses the index calculated above to get the appropriate starting point
%match_data = zeros(length(index)*frame); %used in none frame by frame
%transmission
match_data = received_data(index(1):index(1)+frame_size-1);
%added for frame by frame transmission for n = 2:frames
%match_data((n-1)*frame+1:n*frame) = received_data(index(n):index(n)+frame-1);
match_data = horzcat(match_data,
received_data(index(n):index(n)+frame_size-1));
end end
54
downsample.m
function down_data = downsample(data)
%Downsampling Function:
% This function will take binary data received from the MCU and will
% compare 10 bits to determine if they represent a 1 or a 0
% it will output an array of the data that is the binary representation
% of the message that was sent to the receiver
% if half of the set of 10 bits is a 1, it will default to a 1
%Changed to deal with a varaible sample_rate, set the sample rate below sample_rate = 12;
len2 = length(data);
%makes an empty array of zeros
down_data = zeros(1,ceil(len2/sample_rate));
%creates the result array which should be the same as the one sent from the
%Tx side counter = 0;
binary_val = 0;
%loop to traverse the match_data array and downsample it for i = 1:1:len2
%if the counter is less than the number of samples taken if data(i) == 1
%down_data is the output of this function.
55
Appendix C: C# Code
private void button1_Click(object sender, EventArgs e) {
private void button2_Click(object sender, EventArgs e) {
StopBits.One); //setup COM port
private void btnSave_Click(object sender, EventArgs e) {
Appendix D: MCU C code
Transmitter Code
#include "mbed.h"
#define END 519
//max number of bits in block array **change to how long the message (change accordingly with c# program)
//we are sending through matlab [512 bytes per frame + 7 or more bytes for preamble] (4152 bits)**
//519 bytes
Serial pc(SERIAL_TX, SERIAL_RX);
Ticker interrupt; //call interrupt into program DigitalOut my_pwm(D8); // IO used by pwm_io function void interpret();
char buffer[519]; //buffer array to hold the data frame coming from the PC int i=0;
interrupt.attach_us(&interpret, 832); //interrupt to send out bit to LEDs every 832us (1/1200)
if (buffer[i] & ( 0x80 >> k )) //check only one specific bit
// Calculate the corresponding acquisition measure for a given value in mV
#define MV(x) (x)/3300 void sample();
float meas;
int i = 0; //bit shift counter
char byte = 0x00; //temp sample byte int k = 0; //interrupt buffer counter int j = 0;
char byte_array[512]; //serial buffer
int main() {
pc.baud(19200); //serial out at 9.6 kbps
//initialize serial buffer for(j=0;j<MAX;j++){
interrupt.attach_us(&sample, 52); //enable sample interrupt every 52us (1/19200)
wait_us(1600); //let a few bytes of the buffer fill up before sending it out
while(1) {
for(j=0;j<MAX;j++){ //automatically loops back around
pc.putc(byte_array[j]); //send next element of serial buffer }
59
} }
void sample() {
meas = analog_value.read(); // Converts and read the analog input value if (meas > MV(1600)) { // If the value is greater than 80 mV toggle the LED
//op-amp inverts signal } else {
byte |= 0x01 << i; //bit mask }
i++;
if (i == 8) { //if temp byte fills up
byte_array[k] = byte; //store temp byte in serial buffer byte = 0x00; //reset temp byte
i = 0; //loop bit counter back around k++;
if (k == MAX) { //if reached end of serial buffer k = 0; //loop buffer counter back around }
} }
60