Transmitting data over light with USB

communicationlightmicrocontroller

I'm working on a project that uses light as a medium for data transmission. I would like to achieve about 2-3 MB/s. It suppose to virtually behave like any LAN cable. I would want to know if it is suitable to build a device around a microcontroller like Arduino? I have been searching around the stack and found about how 32-bit ARM processor is favored over 8-bit Arduino in WiFi technology (here). I am not sure if this applies to light communication too.

By the way, I have experimented with FTDI microcontroller before, and it cannot achieve above 200 KHz without generating a lot of errors. I tried to connect a loopback (output directly to input), and found out that there are still reading errors at 300 KHz. Therefore, I assume that microcontroller is not suitable for this experiment. Thus, what would be the suitable hardware for this experiment?

Best Answer

Well an easy solution for you could be not to use a microcontroller. Instead, you can use a USB to UART device that goes up to 3 MB/s such as an FTDI chip. Then, all you have to do is modulate your UART signal on a higher frequency carrier. Finally, you have to send your modulated signal over the air.

In order to perform your modulation, you can refer to this post of mine. The circuit was for a simple IR transmitter, but the circuit could work with your FTDI chip without MCU.

What you can do in order to achieve very high data rates is to use an analog circuit to generate your carrier wave. It doesn't even have to be a sinewave if you don't care much about polluting a large amount of spectrum: with a square wave, your signal would pollute all harmonics of your carrier frequency. With electromagnetic wave this would be problematic/illegal in some countries, but with visible light, no one cares, since you need a line of sight in order receive the data.

Assuming a square wave, you can use a very simple oscillator such as a logic multivibrator, which may be obtained from a basic HEF4047B logic chip mounted as an astable oscillator.

In the first reference I posted, the "carrier" would be your astable oscillator's output and your "data" stream would be the FTDI chip's TX line.

In order to receive data, you need a demodulator. That will will be conceptually easy, but harder in practice: you need to multiply your carrier with the inbound signal obtained from a phototransistor with high sensitivity to your emitter diode's wavelength. As I don't know your technical background, I won't enter much into details, but the analog multiplication will cause a frequency shift of your carrier, so that you will be able to filter it out with a low pass filter.

The higher the carrier's frequency, the easier it is to remove it from your inbound data stream. A carrier frequency that is 8 times higher than your data stream looks appropriate in your situation, since you have to expect a lot of collision. The filter will smooth out your data, so it might be a good idea to recover your signal with a schmitt triggered inverter. You may ask why an inverter? Because UART has a high logic level when inactive, which is undesirable, because it would cause your circuit to always transmit blank. The circuit I first proposed in the other post managed to reverse the signal, so you have to invert it back to normal UART at the receiver side.

As specified by Deamon, it is good to use a laser diode, but definitely not necessary. I achieved such speeds as yours with standard IR diode. It requires a good reception circuit, but it is doable. Though, the range was quite short : ~3m max for a very high power directional IR diode.

As for the bad reception you experience, always take into consideration that wired connections such as USB or LAN do have to cope with noise, disturbances, etc. that causes transmission errors. It is quite common. On electromagnetic wireless (WiFi et al.) it is very very common to experience such problems. You have to cope with the following elements:

  1. Signal interruption: your transmitted signal may not reach the receiver at all times, especially if you are transmitting in the visible spectrum, since even dust may disrupt the signal if it is too weak.

  2. You can see objects around you because of light reflection. This may and will occur. As such, not only your signal may "jump" from your transmitter to your receiver, but your own signal may corrupt later signal because of bouncing. This is pretty unlikely at such low speed, but still possible.

  3. Your communication is probably full-duplex if you expect USB/UART/LAN-like transmission. That means that two or more device may communicate at once (two one-to-one setups, but also one-to-many or many-to-many) , so your protocol stack has to handle that. If you really have full-duplex communication, you cannot simply disable the receiver when transmitting to avoid #2, so you need more complex demodulation circuitry.

  4. Your circuit will probably not float in perfect ideal vacuum: there is a lot of stuff that "emits" in the spectrum that you have chosen. Depending on the wavelength that you will select, your receiver will be polluted by a lot of stuff that you may not even see. By example, a fluorescent lamp emits both a little amount of IR and UV alongside visible light. While you feel like the fluorescent has constant "DC" emission, it is not the case. It is much more wave-like and full of harmonics, so that may pollute a very large part of visible spectrum. Cheap IR receivers (38 kHz or the like) include large circuitry to circumvent such issues.

Now that you have a good overview of all the issues that you will encounter, I would just add a final comment about your microcontroller issue:

Your AVR chip is probably fast enough to handle your 3MB/s data stream if it is only routing from FTDI chip to the IR transceiver circuitry. Your issue is probably that the Arduino framework is too much user friendly and therefore very slow. I actually achieved 2 MB/s (peek) 750kHz (continuous) speed with an MSP430 (SPI) which is mostly in the same class (performance/MHz/features) and I still had time to perform little processing. I was receiving commands at that speed, decoding them with my 2-level protocol stack and using the data. It was very tight, so you may not have the skill set required to code highly optimized assembly routines, but even for poorly optimized C code, 200kHz is quite sluggish performance.