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.
- white -> battery +9V (Vcc)
- black -> Arduino GND
- red -> battery – (GND)
- green -> Arduino +3.3V (Vcc)
- yellow -> Arduino SCL
- 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.
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
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 anInfraredResult
. You would assign the return value ofInfraredSeeker::ReadAC()
to a variabke of theInfraredResult
-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
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
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
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!!!
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
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
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
Hey
Nice work!
But, how to do this in a library?
Marco
Hi Marco,
thank you for your feedback.
You can download the library at https://public.blechschmidt.saarland/Programming/Arduino/libraries/HTInfraredSeeker.zip. You can just import it now using the “Sketch” menu (“Import library” -> “Add library…”) in your Arduino IDE.
Best wishes
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?
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
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
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
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!
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).
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?
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!
hello
Where I can find this library ?
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.
Hey.
We are trying to use the Infrared Seeker V1, and was woundering if this code works for that aswell.
And can it follow any IR-emitters, or does it have to be an IR-ball?
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
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?
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.
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?
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°).
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.
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.
Will this work without a with a 40khz ir receiver instead of a Lego One?
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.