Signals Over Light
With LiFi, we aim to transmit data using light. For that, we need a way to detect light and transform the measurements into a discrete signal.
Digitizing Light
A color sensor is a device that can detect the color of an object by measuring the light that is reflected off it. When light enters the sensor, it is detected by a photodiode, which converts the light energy into an electric current.
The current generated by the photodiodes is then amplified and filtered to remove any unwanted noise or interference. The filtered signal is then split into its component colors - red, green, and blue - using filters that only allow specific ranges of light wavelengths to pass through. The resulting signals for each color are analog, which means they have a continuously varying voltage level over time.
To turn these analog signals into discrete values that a computer can understand, the color sensor uses an analog-to-digital converter (ADC) to convert each analog signal into a series of binary numbers. The ADC works by measuring the voltage of the analog signal at specific intervals, and converting these measurements into binary numbers. These binary numbers represent the intensity of each color, ranging from 0 (no intensity) to 255 (maximum intensity).
Finally, the color sensor combines these discrete values to produce the RGB values that describe the color of the object. RGB stands for red, green, and blue - the three primary colors of light - and the combination of these three values can create a wide range of colors.
From Light to Signal
The goal of the LiFi project is to transmit data using light. Given that the color sensor returns the measured light values in RGB intensities, our task is to develop a protocol for data transmission based on these 3 intensity values. But how can we go about this?
Binary Colors
As you learned earlier in Binary Numbers, computers use the binary system because it is straightforward to distinguish between two different states (on/off) using electric circuits. The same reasoning can be applied to encoding information using light.
When communicating with light, it may be easiest to distinguish just two colors from the sensor readings. This would allow us to use binary numbers to represent information. For example, we could assign a white light the value 1 and black the value 0.
To implement binary data transmission using light, the LED could be turned on and off at a defined interval, and the sensor could measure the intensity of the light at the same interval. By interpreting the sensor readings, we can determine whether the LED is emitting light or not, and hence decode the transmitted binary data. We must make sure that the sender and receiver are both aware of the chosen interval and change the LED and read the values at the same pace to ensure proper synchronization.
However, using light to transmit binary data comes with its challenges. For example, external factors such as ambient light and distance can affect the reliability of the transmitted data. Knowing this, we cannot expect the signal to be as clear as it would be under perfect circumstances: All RGB values 0 for an LED that is turned off, and all at highest intensity for an LED with white light. We have to factor in the environment and the ambient light present when we communicate over light. You'll have the chance to hands-on experience and solve this problem when you tackle the exercise "Color Detector" from Exercise 4: Digitizing the Physical World.
Beyond Binary
In Why Do Computers Think Binary?, you learned that computers can use number systems other than binary to represent and process information. This means that computers don't just rely on the presence or absence of a voltage to perform their operations. Instead, using a number system larger than binary requires dividing the magnitude of the voltage into more than two classes, depending on how many symbols beyond 0 and 1 we want to represent. The same principle applies to light and has similar consequences.
Finding a solution for representing information with light might seem more straightforward than for electric current. Rather than relying on just two states of "on" and "off" (black/white), we could use the colors red, green, and blue as symbols to represent information using the LED. This approach may seem less prone to errors, as colors are discrete values that cannot be misclassified. The image below depicts how we might think about encoding the symbols 0, 1, and 2 using the LED's colors blue, green, and red.
However, it's important to note that the color sensor does not actually see colors in this way. Instead, it measures the intensities of red, green, and blue in a range of 0 - 255, and the task is to classify these intensities into the corresponding colors. Interference from other light sources can make this task more challenging and even impossible. Using even more symbols and adding colors such as yellow, which is a mix of green and blue, further increases the difficulty of the classification task. The image below illustrates how the sensor sees the colors in its 3 components. It is easy to imagine how an otherwise beautiful sunset could cause a redshift in the light and lead to inaccurate classifications of the signal.
Filtering Background Noise
So, how can we come up with a solution to recognize the signals in the light from a Python program? In a perfect environment, which we could create if we put both the sensor and the LED in a light-secure tube, the solution would be easier. In this case, the RGB values measured by the sensor should almost perfectly match those emitted by the LED. To distinguish between red, green, and blue, a simple control structure would do the trick.
However, external light sources such as the sun or a light bulb in the room can create noise that makes it difficult to distinguish between the colors. The type of noise and whether it is constant or appears abruptly determine the appropriate solution.
For constant noise, such as that produced by a light bulb in a room, a simple solution is to subtract the noise from the measurement to obtain the true signal. To achieve this, we first determine the level of noise by measuring the intensities of red, green, and blue when the LED is turned off and only the light bulb is measured.
Once we have the noise values, we remember them and subtract them from the measurements when receiving signals from the LED. To account for changing environments, we measure the background noise frequently, for example, every time before receiving data.
Unexpected Noise
However, unexpected noise is a much more difficult issue to handle, and filtering it out completely is nearly impossible. This type of noise can suddenly appear and interfere with our LiFi communication. While we cannot completely filter out this type of noise, we can be prepared to handle it. We can at least recognize when unexpected noise is interfering with the signal and inform the other side that we are having trouble understanding the signal. This can help prevent miscommunication and allow for a more efficient resolution of the issue.
How can we recognize unexpected noise? To identify when something unexpected happens, we must define what the set of expected events is. All other events are unexpected.
In our example with the 3 colors red, green and blue to encode 0, 1, and 2, the expected events are defined by the three colors we want to recognize.
An unexpected event would then be a color measurement that deviates too much from our definition of the three colors red, green, and blue. For example, orange, purple, pink, or gray would definitely fall into the set of unexpected colors.
To handle unexpected noise in our LiFi communication, we need to identify reliable rules to distinguish expected events from unexpected ones and code them into our Python program. However, our previous approach of simply checking which color intensity is largest no longer works. For any of the unexpected events, except for gray, one of the intensities will be larger than the other two, and our algorithm would not detect any irregularities.
To improve our algorithm, we can define expected values for red, green, and blue for all three colors and add some tolerance, resulting in intervals. Any events for which the red, green, and blue components do not fall within these intervals are treated as unexpected. By defining expected values and tolerances, we can create a more robust algorithm that is better equipped to handle unexpected noise and accurately identify when something is interfering with the signal.
Note that the measurements and intervals must always be adjusted for the measured background noise. In the exercise, you can try to find suiting intervals for your LiFi prototype and see if you can simulate and identify unexpected events.
Further Reading
I highly recommend you read (and view, it's highly illustrative) the chapter "Digital Cameras" from the book "How Technology Works". The chapter gives a great visual overview of how light is measured and converted into a digital form.
Last updated