Arduino Encoded and Modulated Laser and Infrared Serial Communication

19K2750

Intro: Arduino Encoded and Modulated Laser and Infrared Serial Communication

Hey there! Do you want to learn how to communicate wirelessly between two computers using lasers / LED's and photo-receivers? Need to send a signal that is robust to noise? Here is the solution for you.

This is an arduino library which enables you to use a simple laser or LED to transmit characters between two arduinos (transmitter arduino with the laser to receiver arduino with a photodiode). Each byte of data is encoded (but not encrypted) to add some robustness to noise during the transmission and then modulated. I originally wrote this as part of a netduino robotics project for uni, but I've since modified it to work with an arduino. I've tested it and it works with an LED also, but the range is slightly better with the laser.

If you want to learn how the code works, read step 1. If you just want to test that it works or incorporate it into one of your projects, skip to step 2.

What you need can be found on eBay:

STEP 1: How It Works (In Chronological Order):

1. Hamming(7,4) Encoding:

  • each byte of data (in ASCII: D7 D6 D5...D1 D0, e.g. D3 is 3rd digit of the byte) typed into the serial window is split into its most significant and least significant 4 bits, AKA nibbles: D7...D4 and D3...D0
  • each nibble is encoded via hamming encoding, producing an unsigned 8 bit integer. The extra 4 bits contain information about the original nibble to help detect errors and recover the original nibble in case some of the data was scrambled due to noise in the transmission. The encoding / decoding algorithm has its limits on how much unscrambling it can do but it is certainly more efficient than sending multiple times to improve accuracy.
  • the encoding is as follows: y = x G, where x = (D0 D1 D2 D3) and G is a Hamming(7,4) matrix, producing y = (H0, H1, H2, D0, D1, D2, D3) and then we add an additional bit of even parity at the front y' = (P0, H0, H1, H2, D0, D1, D2, D3) where the parity bit P0 is just the XOR sum of the other bits.
  • the two encoded nibbles (now 8 bits each) are concatenated, least significant byte first to product a 16-bit integer

2. Manchester Modulation:

  • the 16-bit integer is then split into is least and most significant bytes
  • each byte is modulated via manchester modulation: 2 start bits to let the receiver know it is about to receive actual data and not just stray signals, then the byte followed by 1 stop bit, producing 11 bits. Each of those 11 bits is represented with two half-bits: first half-bit is the original XOR'ed with 1 and the second is XOR'ed with 0 instead, this adds a clock pulse into the signal. This produces 22 bits for each byte.
  • the pair of 22 bits are joined end on end, least significant first, producing 44 bits of data

3. Transmission:

The 44-bit data is sent via the laser or LED, 1's are on and 0's are off

4. Manchester De-Modulation:

The 44-bit signal is received by the photo-detector and manchester-demodulated (reverse algorithm of modulation) to reconstruct the 16-bit encoded signal

5. Hamming Decoding:

The 16-bit demodulated signal is then hamming decoded to reproduce the original byte

6. Printing Message:

The byte is then printed on the serial window

STEP 2: Install the Library

The library I wrote, LumenWire, can be found on my github repository here. Download it to your computer, you won't need the README.md file though. Just add the HT_LumenWire folder to your libraries folder in the arduino folder on your two computers.

If you come across bugs in the code or have simple recommendations on how to improve the performance or add extra functionality / features, you're more than welcome to let me know in the comments section. Thanks!

STEP 3: Test the Setup:

  1. open the arduino application
  2. open File -> Examples -> HT_LumenWire and select either the photoreceiver or transmitter examples
  3. plug in the arduino and select the appropriate COM port, then upload the transmitter / receiver sketches to their respective arduinos
  4. connect the laser as follows: laser VCC pin to pin 6, - pin to ground
  5. connect the photodiode as follows: photodiode signal on pin 7, power pins as normal
  6. open the serial window (spyglass symbol in the IDE) on both computers
  7. point the laser or LED to the photodiode
  8. enter a character or phrase in the serial window on the computer doing the transmitting and press enter to send
  9. you should receive the message on the receiver serial window automatically

Now that you've verified the setup works, what you can do with it is up to your imagination. Do you want to further refine or modify the library to add extra features? Are you planning to incorporate it into a bigger project? Have fun.

If you enjoyed this instructable or found it educational, why not stay tuned for future projects by following me on Instructables and on Facebook / Twitter / Google+.

If you enjoyed this instructable and would like to see more like this, please consider supporting me by purchasing your materials for this project through the affiliate links in the materials section or donating below:

PayPal: https://www.paypal.me/HobbyTransform

Bitcoin: 1Mqe7et24Lz4DY1RUN4iAQVHkvJsdFArKR

Ethereum: 0x6d8248db1cdea6a783cb6b41ae67bb8e6144f479

Litecoin: LW6PWESqsr8xHw6EJ9WLbsQsAyTvPnwnxJ

Dash: Xemv7jud697v8tQmKfNFoMxfkd17ZayH2t

Your support is greatly appreciated! Happy DIY'ing!

37 Comments

can iw ork with raspberry pico and could you guide me ?
After constructing both the Tx and Rx circuits, it seems like the receiver does detect the transmission but only prints reverse question marks and other symbols, not at all what I set as the input string. I am using the default example code for both the receiver and the transmitter, so please let me know if I am doing something wrong or if this is what normally occurs.
Hi, no those question marks shouldn't be printing out. Make sure that your baud rate on the serial window matches the one set on the line of receiver code with Serial.begin, i.e. in the unedited example code it is Serial.begin(9600). Also, for good measure, double check that you have the latest version of the Arduino IDE as older versions can mess up your results or be glitchy.
I was able to get the system to function perfectly! Thanks for the help. I was looking to attempt to use a blue Laser instead of a red one as I want to see the effects of using a system like this in an underwater channel as opposed to air. Blue/Violet LEDs/Lasers have the lowest attenuation by water of any visible light. I was wondering if you have any suggestions or have done any work in this regard?
Good to hear you've got it working. I haven't tried blue lasers, but that would be an interesting direction to go with this project. A suggestion to try, instead of the library and circuit setup as in this instructable try the serial communication that is natively available on the uno, so the rx and tx pins already on the uno; i.e. the transmitting uno's tx pin goes to the laser and the receiving uno's rx pin goes to the photodiode. The code would be different too, if you haven't used the arduino serial communication before, find some tutorials online for that. Compare the results you get from that with the results from using my library and see which one is more reliable for your purposes. I was helping someone use this library once and it turned out that the built in serial communication of the uno was more reliable in his case.
Hello, I am having some trouble with the receiver and I'm struggling to figure out what is the problem. The transmitter seems to be working, but the receiver does not print anything at all. All the pins are correct and the photodiode is working (the LED that indicates signal flashes whenever the turns on), so I'm guessing the problem is with the demodulating and decoding process. Do you know what the problem might be and how to fix it? Any help is appreciated. Thanks in advance!
i think his receiver code is incomplete, cant say for sure, because i didn't read the library files, but looking at overall receiver code, it looks incomplete.
Hello, the receiver code is actually complete, it just doesn't have many lines of code because most of the work is done in the library files (which are quite lengthy actually).
Hi, please double check that your baud rate on the serial window matches the one set on the line of receiver code with Serial.begin, i.e. in the unedited example code it is Serial.begin(9600), that can affect the results. Also, for good measure, check that you have the latest version of the Arduino IDE as older versions can mess up your results or be glitchy. Let me know if that fixes the problem.
Has anyone succcesfully tested the serial example code? if yes please share details
Cool work Hobby Transform!
The main body of this is C++ right? did you ever experiment putting it onto a pi (zero)? Ive been playing around with this as part as a project for a bit now and am looking at using a board with a little more umpf than just a nano or uno.
I noticed I get bad data fairly often I am using 2 nanos but I was wondering if you played around with the speed of the transmission and if that had an effect on the quality of transmission?
I was also thinking about using red coloured filters, the lasers are 650nm which is red so I figure this might help... but I am unsure actually about the bandwidth range of the photodiode seems to be very hard to find exact information of what component it is, yet alone a datasheet! XD
Hi pieboy.dave, the code is actually c, which is a subset of c++, so you could rename the .cpp files to .c and it should work fine with a c compiler I think. I haven't tested it with any raspberry pi's but that sounds like a cool project idea, just make sure the laser slew rate can handle the higher bit-rate of transfer as that will affect the accuracy. The photodiode module part number is IS0103 I believe, so you should be able to find a datasheet for that.
Hello, I have a question about transfering data stored in SD cards in the ethernet shield module w5100 between them. Your project works fine with the same equipment but only for short strings. If the trasfering data is longer, I have bad symbols. How can I change the code to transfer using SD ?
hi sir, thanks for the project.
is laser sensor module, non-modulated necessary, if i use led instead of leaser led?
and when using photodiode you said to connect the photodiode signal on pin 7, power pins as normal, photodiodes have 2 pins so what are the power pins? or is it the laser sensor module?
Hi, yes the laser sensor module is necessary because the resistor and capacitor that come with it form a low pass filter to filter out noise I believe. Normal photodiodes have 3 pins: ground, vcc and a signal pin. The laser sensor module also has 3 pins because it has the photodiode on it.
Nice.

Now a little a suggestion, to make the use more flexible, two new functions:
set_send_pin() and set_receive_pin()
to avoid modify HT_light_modulator.h
#define LIGHT_SEND_PIN 6
#define LIGHT_RECEIVE_PIN 7

hey..!!
how are you sir.,?!!
i am using (photo resistor) (LDR) instead of (photo diode) but i could not receive any thing..
is (photo diode) so important for the receiving operation or i can use (LDR) instead of it..?!!
and what is the maximum bits rate and baud rate for the laser..?!!
thanks for reading my comment and i am looking forward to your reply..
Yes only use the recommended photodiode. A LDR works differently, based on different frequency of light I think. The maximum bit rate for the specific laser you use can be determined by experimenting with different values of bit rate in the code to see how high of a value you can set before it stops sending meaningful data. Baud rate can be calculated from bit rate, I think it this case it would be 44 bits = 1 baud, so divide bit rate by 44 to get baud rate.
hey..!!
how are you sir.,?!!
i am using (photo resistor) (LDR) instead of (photo diode) but i could not receive any thing..
is (photo diode) so important for the receiving operation or i can use (LDR) instead of it..?!!
and what is the maximum bits rate and baud rate for the laser..?!!
thanks for reading my comment and i am looking forward to your reply..

2nd Question: Hey i was wondering if it is possible to use one arduino as the transmitter and reciever. I understand that both codes are using the same timers so perhaps i could change one of them within the library? How would i go about combining both programs? Thank you

More Comments