HiTechnic Infrared Seeker library for Arduino

Today I have created a class allowing you to connect a HiTechnic IR Seeker V2, which is originally designed for use with a LEGO Mindstorms NXT robot, to an Arduino Due board with a 9V battery. I struggled a bit with the the different sensor pins but I could finally manage to connect the sensor correctly.

  1. white -> battery +9V (Vcc)
  2. black -> Arduino GND
  3. red -> battery – (GND)
  4. green -> Arduino +3.3V (Vcc)
  5. yellow -> Arduino SCL
  6. blue -> Arduino SDA

The following code is executed by the Arduino:

#include <Wire.h>

/*
  IRSeeker.ino - A library/class for the HiTechnic IRSeeker V2 infrared sensor.
  Created by B. Blechschmidt, August 1, 2013.
  Released into the public domain.
*/

struct InfraredResult
{
  byte Direction;
  byte Strength;
};

class InfraredSeeker
{
  public:
    static void Initialize();
    static boolean Test();
    static void ReadACRaw(byte* buffer);
    static void ReadDCRaw(byte* buffer);
    static InfraredResult ReadAC();
    static InfraredResult ReadDC();
    static int DirectionAngle(byte Direction);
  private:
    static InfraredResult PopulateValues(byte* buffer);
    static void ReadValues(byte OffsetAddress, byte* buffer);
    static const int Address = 0x10 / 2; //Divide by two as 8bit-I2C address is provided
};

void InfraredSeeker::Initialize()
{
  Wire.begin();
  Wire.beginTransmission(InfraredSeeker::Address);
  Wire.write(0x00);
  Wire.endTransmission();
  while(Wire.available() > 0)
    Wire.read();
}

boolean InfraredSeeker::Test()
{
  Wire.beginTransmission(InfraredSeeker::Address);
  Wire.write(0x08);
  Wire.endTransmission();
  Wire.requestFrom(InfraredSeeker::Address, 16);
  char Manufacturer_Model[16];
  while(Wire.available() < 16);
  for(byte i=0; i < 16; i++)
  {
    Manufacturer_Model[i] = Wire.read();
  }
  while(Wire.available() > 0)
    Wire.read();
  return strncmp(Manufacturer_Model, "HiTechncNewIRDir", 16)==0;
}

void InfraredSeeker::ReadValues(byte OffsetAddress, byte* buffer)
{
  Wire.beginTransmission(InfraredSeeker::Address);
  Wire.write(OffsetAddress);
  Wire.endTransmission();
  Wire.requestFrom(InfraredSeeker::Address, 6);
  while(Wire.available() < 6);
  for(byte i = 0; i < 6; i++)
  {
    buffer[i] = Wire.read();
  }
  while(Wire.available() > 0)
    Wire.read();
}

void InfraredSeeker::ReadACRaw(byte* buffer)
{
  ReadValues(0x49, buffer);
}

void InfraredSeeker::ReadDCRaw(byte* buffer)
{
  ReadValues(0x42, buffer);
}

InfraredResult InfraredSeeker::PopulateValues(byte* buffer)
{
  InfraredResult Data;
  Data.Direction = buffer[0];
  if(buffer[0] != 0)
  {
    if(buffer[0] % 2 == 0)
    {
      Data.Strength = (buffer[buffer[0] / 2] + buffer[buffer[0] / 2 + 1]) / 2;
    }
    else
    {
      Data.Strength = buffer[buffer[0] / 2 + 1];
    }
  }
  else
  {
    Data.Strength = 0;
  }
  return Data;
}

InfraredResult InfraredSeeker::ReadAC()
{
  byte buffer[6];
  ReadACRaw(buffer);
  return PopulateValues(buffer);
}

InfraredResult InfraredSeeker::ReadDC()
{
  byte buffer[6];
  ReadDCRaw(buffer);
  return PopulateValues(buffer);
}

int DirectionAngle(byte Direction)
{
  return Direction * 30 - 150;
}

void setup()
{
  Serial.begin(9600);
  Serial.println("HiTechnic IRSeeker V2");
  Serial.println();
  Serial.println();
  Serial.println("Dir\tAngle\tStrength");
  Serial.println();
  InfraredSeeker::Initialize();
}

void loop()
{   
  InfraredResult InfraredBall = InfraredSeeker::ReadAC();
  Serial.print(InfraredBall.Direction);
  Serial.print("\t");
  Serial.print(DirectionAngle(InfraredBall.Direction));
  Serial.print("\t");
  Serial.print(InfraredBall.Strength);
  Serial.println();
  delay(100); //optional
}

To download the compressed zip-archive of the library just go to https://blog.blechschmidt.saarland/wp-content/uploads/2013/08/HTInfraredSeeker.zip. This archive can be imported using the “Sketch” menu of your Arduino IDE. Just click “Import library” and choose “Add library…”. Then just #include <HTInfraredSeeker.h> and use it as shown above in the loop- and main function.

Bookmark the permalink.

31 Responses to HiTechnic Infrared Seeker library for Arduino

  1. MisterG says:

    Great stuff ! We are playing around with custom digital sensors on our Arduino soccerbots and will give this a try as well. Do you have a sample code that we could modify for testing?

    I am assuming ReadAC and DirectionAngle will give us what we need. Is direction angle returned as 0-9?

    Neil

    • admin says:

      Thank you for your feedback 🙂

      The code sample provided above is already code which can be used for testing. It outputs direction (0 to 9), angle (-135° to +135°) and strength (0 to 255) of your infrared ball to the serial console.
      ReadAC() will give you the necessary information since it returns an InfraredResult. You would assign the return value of InfraredSeeker::ReadAC() to a variabke of the InfraredResult-type.

      Example:
      InfraredResult InfraredBall = InfraredSeeker::ReadAC();
      byte Strength = InfraredBall.Strength; //0 to 255
      byte Direction = InfraredBall.Direction; //0 to 9
      int Angle = DirectionAngle(InfraredBall.Direction); //simply calculates the angle of the infrared ball clockwise based on the direction (A direction value of two would return -90 degrees, a direction value of five would return 0 degrees, a direction value of 8 would return +90 degrees)

      Kind regards

  2. Trong Luong says:

    Hello,
    May I ask what connector/cable did you use to connect your IR Seeker V2 to the Arduino please? I just bought the sensor, but didn’t realize that it didn’t come with any cable or any instruction on the cable

    Thank you,
    Trong

    • admin says:

      Hello Trong,

      I use the cables which came with the LEGO Mindstorms customer set: http://www.amazon.de/Lego-LEGO-MINDSTORMS-NXT-Verbindungskabelset/dp/B0054WTFN2
      Since they are relatively expensive you might try to use RJ-12 plugs which are compatible with the NXT as far as I know.

      Actually I had to cut the off the plastic isolation of the six different cables which are inside the black mantle. You might need to use a wire stripper. Then you can solder them to regular Arduino cables or try to directly connect them to your breadboard/Arduino.

      Kind regards

  3. Lukas says:

    Hi nice stuff!!!
    This works great!
    I’m also using the sensor in our school project, a soccerbot for the robocup
    I’m from Austria

    Keep up the good work!!!

    • admin says:

      Hi 🙂

      Thank you for your comment since I really appreciate your feedback. I also want to participate in the RoboCup German Open with my team and this library was exactly designed for this purpose.

      Kind regards

  4. andrea duchi says:

    Hi ! I need a help ! could you suggest me a infrared sensor instead of IRSEEKER V2(HItechnic) to use on Arduino board ?
    Thank you
    Andrea Duchi

    • admin says:

      Hi Andrea,

      you might use some TSOP infrared receivers by Vishay Semiconductors (http://www.vishay.com). They just need to have appropriate frequency filters matching your application. Since those receivers are digital sensors, you will have to buy a bunch of them and maybe arrange them in a circle to detect the direction of your infrared signals.

      Best regards

  5. MJ says:

    Hey
    Nice work!
    But, how to do this in a library?

    Marco

  6. Oscar says:

    Hi, I’m a student in America using the NXT IRSeeker V2 to compete in a robotics college challenge, and I’m using an Arduino.

    How portable is this code to the Arduino Mega? What modifications would I have to make to the code to have it work on a mega?

    • admin says:

      Hi Oscar,

      you would not need to modify the library at all to use it on an Arduino Mega. Like Arduino Uno and Arduino Due, the Arduino Mega has got two I²C-pins (SCL and SCA) to which you would need to connect the IR-Seeker. The Wire-Library which my code is based on should work on the Mega as well as on any other Arduino having an I²C-bus.

      Kind regards

  7. andrea duchi says:

    HI! I bught ir 2334 vishay infrared sensor and I have tried to connect directly with Arduino robot Kit K1 port but the sensor becomes hot . What Can i Do ? I have to put a resistence?and Could you suggest me a right code (C) in order to detect infrareed signal from the ball soccer ?
    thank you
    Andrea

    • admin says:

      Hi Andrea,

      I have looked for your Vishay sensor 2334 on Google but I did not find any appropriate results concerning an infrared sensor, not to mention a datasheet. If you can provide me with a datasheet of that sensor I might be able to help you.

      Kind regards

  8. Crock101 says:

    Hello, I am currently trying to make a robot that will follow me by using a HiTechnic inferred LED beacon and this sensor. What i want it to do is if the beacon is in sectors 0 or 1 it would turn left until it’s in sector 2, and if the beacon in sectors 3 or 4 it would turn right till it’s in sector 2, and if it’s in sector 2 it does nothing except detect if I am farther than 2 ft using an Ultrasonic distance sensor. Would i have to modify this code in order to do that, and if so how?

    May robots always be our friends!

    • Crock101 says:

      Sorry i ment to right between sectors 1-4 (for the left), between sectors 6-9 (for the right) and sector 5 (for the distance sensor).

  9. Isaac says:

    Hi,

    I’m trying to this library with an Arduino Robot, but am experiencing problems.

    The code is working well, until I add
    InfraredResult InfraredBall = InfraredSeeker::ReadAC();

    When I add that line into my loop function, the code just holts and nothing will happen.

    Any ideas?

    • Joe says:

      Hey, I have no idea if you’re still trying to fix this, but I ran into the same problem (using an Arduino Mega). Instead of using a nine volt and the 3.3V from the Arduino, I had to use the 5V instead.

      My wiring ended up being:
      White -> Arduino +5V
      Black -> Arduino ground
      Red -> Arduino ground
      Green -> Arduino +5V
      Yellow -> Arduino SCL (port 21)
      Blue -> Arduino SDA (port 20)

      Hope that helps!

  10. Eric says:

    hello

    Where I can find this library ?

    • Admin says:

      Well, the above code actually contains the library. Just copy the class to a C++-header file (with inline definitions) in order to regularly include it.

  11. Pedrole says:

    Hey.

    We are trying to use the Infrared Seeker V1, and was woundering if this code works for that aswell.

  12. Pedrole says:

    And can it follow any IR-emitters, or does it have to be an IR-ball?

    • Admin says:

      Hello Pedrole,

      it should be able to follow most IR emitters as described on the HiTechnic product website. I had a quick look at the first version of the seeker and can tell you that you have to at least exchange the I2C address as you can see on http://botbench.com/driversuite/hitechnic-irseeker-v1_8h_source.html. The rest of the code might work fine. As there is no detailed datasheet available for the old version of the seeker unfortunately, I cannot give you more specific information about the support of other IR emitters than the HiTechnic ball.

      Kind regards

  13. Zac says:

    I’m having issues downloading the library. When I go to the link on the page, I get a 404 error. Could you please explain how I am supposed to implement this based on the code on this page?

    • Admin says:

      The library classes are already part of the code posted here, so you should be fine by just copying and pasting them to your own implementation. However, I have fixed the link.

  14. jbape says:

    my arduino is attached to a toy boat, if i use this code for the bot to follow an ir emitter, does it mean i need to use another program for it to follow the ir?

    • Admin says:

      Well, I am not sure whether I got your question right, but the code provided above can only tell you where the signal of the infrared emitter is coming from. You would have to add code which controls the motors of your boat according to the signal which you have received (e.g. turn right when the signal angle is greater than 0° and turn left when it is less than 0°).

  15. Joseph says:

    Hello…i have a problem…the code and ir seeker work fine during 30 seconds…later the robot stop totally…what is the problem?..is hardware or software?

    Thank you.

    • B. Blechschmidt says:

      Unfortunately, without a more precise description of the problem, I will not be able to help you. Try to find out which instructions cause the program to get stuck in order to distinguish hardware from software errors. If the program gets stuck performing a read operation from the sensor which used to work fine before, it is likely to be a hardware error. But it might also the case that the program is stuck e.g. in some while loop outside the IR seeker class. Maybe consider asking at forum.arduino.cc.

  16. Jack says:

    Will this work without a with a 40khz ir receiver instead of a Lego One?

    • B. Blechschmidt says:

      No, this code will only work with the Lego receiver. You would need multiple single TSOP infrared receiver modules to obtain similar results to the Lego receiver. These receivers will usually not work via I²C.

Leave a Reply

Your email address will not be published.