Infrared Sensor

With QikEasy EV3 Spike Prime Adapter, you may use your EV3 Infrared Sensor and Remote Control, and have functionalities that you don’t get with your standard Spike Prime or Robot Inventor kit.

A Wireless Remote with Physical Buttons

  • Control your robot with a handy physical remote control.  The tactile controls is much easier to use than your smart phone’s touch screen.
  • Great for wirelessly controlling your model race car or other robotic projects.

The Beacon Follower

  • The EV3 IR sensor has the ability to estimate the general direction (heading) of and the distance (proximity) to the IR Beacon.
  • This enables your robot to  track and follow another moving object (i.e. the IR Beacon).

Proximity Distance Estimation

  • This is similar to the functionality provided by your Spike Prime Ultrasonic Distance Sensor.
  • It is another mean to perform approximate distance measurement.
  • Note that in practice, an ultrasonic distance sensor provides more accurate measurement than the IR counterpart.
  • Similar to ultrasonic distance sensor, this could be useful for obstacle avoidance.

How to use them on Spike Prime or Robot Inventor?

  1. Connect your EV3 Infrared (IR) sensor to the bigger socket on the QikEasy Adapter.
  2. Connect one end of a Spike Prime cable to the smaller socket on the QikEasy Adapter.
  3. Connect the other end of the Spike Prime cable to one of the 6 ports on the Spike Prime (or Robot Inventor) hub.
  4. Your Spike Prime or Mindstorms hub will detect the EV3 IR sensor as a Spike Prime Color Sensor.

 

Programming in Word Blocks:

 

Detecting IR Remote Control Button Presses with Discrete Color values:

 

With EV3 IR Sensor being recognized as Color Sensor, to detect the IR Remote Control’s button presses, one can use the Color Value reading change events. This data reading detects one of the 9 different button press patterns of the IR Remote as illustrated below.

E.g. When your program detects a color value of 10 (White), it means the user has pressed both the Red Down and Blue Down buttons.  And, you would probably program the logic to interpret that as “going backwards” or “going downwards”.

 

Note that using this method, you will not get any channel information for the button press.

 

The following Word Block example program demonstrates how one would perform this discrete color value detection.  The program will light up your hub’s dot matrix LEDs at locations based on the button pattern you pressed.

 

Note: We could have used the Color Sensor – “when color is” event block for this detection.  However, during our development, we found that for whenever the sensor detects a color that matches blue (3) or Teal (4), the “when color is” block would fire both color events.  This would not be acceptable for our use case.  That’s why we use the “when” event block with condition based on the numeric value of the color being read.


The resulting app will run as follows:

Detecting IR Remote Button Presses with Channel Information:

 

To retrieve full information (including Channel) for the IR Remote Control’s button presses, one may use the Reflected Light Value data reading. This data reading provides full information for the IR physical remote button press including information about the selected channel on your remote control.  It value ranges from 0 to 47.  The following formulas may be used to decode the value into Channel and Button Press Code:

      • Channel =  Reflected Light Value /12 + 1
      • Button Code = Reflected Light Value  MOD  12

 

The following example Word Block program shows how one would perform such detection using the formulas above.

 

Note:

  • This program requires the following variables to be created:   Channel_To_detect, Current_Reflect, IR_Remote_Channel, IR_Remote_Code
  • This check for channel information, and will only respond to a IR Remote Control set to Channel = 3.


The defined code values for the Button Presses are as follows:

Distance Proximity Estimation:

 

One can use the Red channel of the RGB Raw value to access the distance proximity feature. This data reading is in the range from 0 to 255, representing the object’s approximate distance from the sensor.

 

The following example Word Block program shows how one would perform such detection.  This program draws a horizontal bar on the LED Matrix of the hub based on the distance of the object from the sensor.  In this program, we defined a custom block “Draw_light_bar” that takes a number in the range of 0 to 5 as a parameter to draw the bar. In the main program, we stored the scaled distance value into the variable “Distance_0_to_5”.  This distance is calculated with the formula:

 

( Log ( IR Sensor reading ) – 1 ) * 5

 

This formula scales the proximity distance value (ranged from 0 to 255) down in log scale to a range of 0 to 5.   The formula is derived by “Trial and Error” such that all values >= 80 will light up 5 lights.  Then, as the object gets closer, the program would progressively light up less number of lights.


 

Programming in Python:

 

Detecting IR Remote Button Presses with Channel Information:

With Python, user may use the Reflected Light Value change events for detecting IR Remote Control’s button presses. This data reading detects button press patterns of the IR Remote as well as channel information.  The formulas for decoding the IR channel and IR code are:

 

      • Channel =  Reflected Light Value /12 + 1
      • Button Code = Reflected Light Value  MOD  12

 

The Button Code is defined as in the table on the right.

 

The following Python example program shows how one would perform such detection.  This example program will light up the LED matrix at locations based on the button pattern you pressed.  The resulting app will work exactly the same as the example program in Word Blocks.

 

Note: This program will only respond to an IR Remote Control that is set to Channel 3.  You may change the program accordingly to detect for other channels.

# On Spike Prime, use the following as first 3 lines instead:
#    from spike import PrimeHub, ColorSensor
#    import math
#    hub = PrimeHub()
from mindstorms import MSHub, ColorSensor
import math
hub = MSHub()

irSensor = ColorSensor('E')

# Function to draw pixel based on remote code
def Draw_Pixel_from_Remote_Code( remote_code ):
    hub.light_matrix.off()  # when remote_code==0, nothing else would
                            #   happen, the matrix would be off.
    # Red Up
    if remote_code == 1:
        hub.light_matrix.set_pixel(0, 0, 100)
    # Red Up & Blue Up
    elif remote_code == 5:
        hub.light_matrix.set_pixel(2, 0, 100)
    # Blue Up
    elif remote_code == 3:
        hub.light_matrix.set_pixel(4, 0, 100)
    # Red Up & Blue Down 
    elif remote_code == 6:
        hub.light_matrix.set_pixel(0, 2, 100)
    # Red Down & Blue Up
    elif remote_code == 7:
        hub.light_matrix.set_pixel(4, 2, 100)
    # Red Down
    elif remote_code == 2:
        hub.light_matrix.set_pixel(0, 4, 100)
    # Red Down & Blue Down
    elif remote_code == 8:
        hub.light_matrix.set_pixel(2, 4, 100)
    # Blue Down
    elif remote_code == 4:
        hub.light_matrix.set_pixel(4, 4, 100)


last_remote_code = -1
while 1:
    current_reflect = irSensor.get_reflected_light()
    ir_remote_channel = math.floor( current_reflect / 12 ) + 1
    ir_remote_code =  current_reflect % 12

    # Confirm that the button press is for the Channel we are looking for
    if ir_remote_channel == 3:
        # Only need to redraw if the button code changes
        if last_remote_code != ir_remote_code:
            Draw_Pixel_from_Remote_Code( ir_remote_code )
    else:
        hub.light_matrix.off()
    
    # Remember the last remote code
    last_remote_code = ir_remote_code
Proximity Distance Estimation:

 

User may use the Red channel of the RGB Raw value to decode the proximity distance information. This data reading is in the range from 0 to 1024.

 

The following example program is to demonstrate how one performs this proximity distance decoding in Python.  This program draws a horizontal bar on the LED Matrix of the hub based on the distance of the object from the IR sensor.  In the program, we defined a function that takes a number in the range of 0 to 5 as parameter to draw the bar.  Similar to the equivalent Word Block example, we use the following formula to scaled the RGB Red value down to a value in the range of 0 to 5, and store the value into the variable “Distance_0_to_5”:

 

( Log ( IR Sensor reading /4 ) – 1 ) * 5

# On Spike Prime, use the following as first two lines instead:
#    from spike import PrimeHub, ColorSensor
#    hub = PrimeHub()
from mindstorms import MSHub, ColorSensor
hub = MSHub()

import math
# Function to draw the horizontal light bar on the LED Matrix of the hub
def Draw_Light_Bar_of_Length(length):
    for i in range(5):
        if i>=length:
            hub.light_matrix.set_pixel(i, 2, 0)
        else:
            hub.light_matrix.set_pixel(i, 2, 100)

irSensor = ColorSensor('A')

# Forever loop that repeatedly draw the light bar based on RGB Red value
while 1:
    sensorReading = irSensor.get_red() / 4
    if ( sensorReading != 0 and sensorReading != 256 ):
        Distance_0_to_5 = round ( ( math.log10( sensorReading ) - 1 ) * 5 )
        Draw_Light_Bar_of_Length( Distance_0_to_5 )
IR Beacon Seek:

 

The EV3 IR Sensor has the ability to estimate the general direction (heading) of and the distance (proximity) to the IR Beacon.  One can use this functionality to implement a robotic vehicle that follows the IR Beacon.  It is important to note that even with the QikEasy Adapter, this feature is only available to Spike Prime and Robotic Inventor when you program in Python.

 

To use the channel, heading direction and distance information, the user program has to read the sensor’s data value array in Mode 7. This data array contains 3 values as described below:

 

  • Channel:
    The 1st data value is in the range of 0 to 3.  This value is equal to  ( Channel # of physical remote – 1 ).  This means that if the physical channel is 4, you would get a data value of 3.
  • Heading Direction:
    The 2nd value is in the range of 0 to 50.  In practice, one should use the formula: ( heading – 25 ), to transform the data’s range to (-25, 25).  The transformed value should be as below:

    When the beacon is on the left side of the sensor-25
    When the beacon is on the right side of the sensor25
    When the beacon is directly in front of the sensor0
  • Distance:
    The 3rd value is in the range from 0 to 100. When no beacon is detected, this value would be 1024.

 

Below is an example program that demonstrates this IR Beacon Seek functionality in Python.  The program will simply repeatedly print the channel, heading and distance information in the console area.

import hub
from utime import sleep_ms

# See https://lego.github.io/MINDSTORMS-Robot-Inventor-hub-API/class_device.html for documentation on hub API
ir_sensor = hub.port.A.device

# IR-SEEK mode data is returned in Mode 7
ir_sensor.mode(7)
while (1):
    sleep_ms(500)
    ir_seek_data = ir_sensor.get(0)

    # Channel: 1 ot 4
    channel = ir_seek_data[0] + 1

    # Heading: -25 to 25
    heading = ir_seek_data[1] - 25

    # Distance: 0 to 100,  or 1024 when beacon is not detected
    distance = ir_seek_data[2]

    print("Channel=", channel, ", Heading=", heading, ", Dist=", distance)