Go Down

Topic: Library for measuring distance using unexpensive IR reflective sensors (As CNY7) (Read 27535 times) previous topic - next topic


Hello, I'm new to this forum, and actually just initiated with ARDUINO, although not new to programming. I have been teaching some people basic stuff for ARDUINO programming, aiming to do some art robots and, further on, developing animatronics. During the last (and first) workshop, not familiarized with this H-S/W students were trying to develop a proximity sensor using the cheapest sensor they could find, yep, that is the CNY70. Although it presented several problems with environmental light and noise, they were eager to use it, so, I decided to develop a lib where they could easily use it, and it turned out in this library I am posting today.
What it does is taking an environment sample (that means, it turns off the IR led and measures), and then, it is compared with the current measure. Up to there it is rather simple, what this library offers is the possibility to also filter such signal, you can choose if just sampling it as it is, or taking an average (from as many samples as you wish), or running a simple RC filter (predictive type),
So, it is an (I hope) easy to use library, which I called SensorOp. I assume some of the ppl reading this post is already familiarized with the use of libraries, but anyway I will give you some hints on its use. First you will have to un-ZIP the attached file into your ARDUINO - library folder.
you can get started with the included example,which is located on the Sensor folder.
For this example you will need to connect the sensor as follows (Mainly, the led control pin to the led's anode +, the cathode to a 220ohm resistor, the  phototransistor collector to Vcc, the emitter to the analog input and to a 100K resistor, which goes to ground) :

Then, upload the code to your ARDUINO board (tested on ARDUINO UNO R3) and, open the Serial Monitor, and you will be able to see the different types of measuring methodes the library is able to perform (To do a better check just copy the data yielded at the sensor monitor and paste it into a spreadsheet (Like excel) program (or whichever you prefer), and graph it.

Now, for using it, you must include the library into your own code (preferably before all your code starts):

Code: [Select]
#include <SensorOp.h>

and then declare the object:

Code: [Select]
SensorOp MySensorOp(int ledControl, int sensorPin, int samples)

ledControl is the pin where your IR led will be connected (in the attached example is 2 (digital I/O 2)),
sensorPin, the pin where your sensor is (in example A0)
samples (the number of samples you wish to take, if any, anyway, always has to be declared)

Now, you will be able to use the same function for three different methods, all of them will result in an integer reading between 0 and 1023; deppending on your inpu,t the method will be selected, lets start with the easy one:

Code: [Select]

In this one, all the process is to take the measure from the environment an then the sensor reading, this method is really fast, but not very accurate, although the light induced noise/interference is reduced, the measure will still noisy.

Code: [Select]
MySensorOp.readSensor(int value)

this input for the method will read [sample] times and will average them, it is necessary that the input value [value] is the same output. for making it clear, if I want my result to be stored in a variable called Read, then the function input must be Read>
Code: [Select]
Read = MySensorOp.readSensor(Read);

Code: [Select]
MySensorOp.readSensor(int value,int filter)

Well this is the function I like the most, it has a simple predictive algorithm (an RC digital filter), the input is the previous reading (the same as explained in the one before), and a number which indicates the RC filter level (making it simple, the bigger the number, the less the noise, but the change on the reading will be slower).

I hope you enjoy it, any comment or suggestion just post, hope it is useful, your comments would encourage me to do more libraries like this one. Remember lot of samples is lot of time...


It worked for me. Thank you very much.

Giorgos Epitidios
Athens Greece



I have some questions about how to set up a basic test environment for OPTO sensors.

Project Goals
I am building a MIDI controller for music and need to measure the velocity of the keys.  I have tried piezo sensors but the fidelity (trueness to touch) is very low and the results are unpredictable.  I'm still pursuing the use of piezos with RC filters, etc but would like to test some opto sensors.  In particular I am comparing the vishay CNY70; the vishay TCRT5000; and the Rohn RPR-220.  All low cost sensors that are readily available and which I would like to share the test results with others - including a basic circuit.  But back to the CNY70.

Hardware checks
I assume that I can't see the LED with the naked eye because it is infrared.  Should I be able to see it with a camera such as the one on my iphone?   I see nothing.    I could measure the current too - is there another way?

Initial bottleneck
So, I've downloaded your libraries and looked through them.  I tried this simple test script to work with analog pin 0 (A0) first and that isn't happening.   When I run the below code I gets a value of 0 for the A0 on the arduino serial console   Removing the 100K ohm from the photo transistor though gives me a range of 0 - 83 on the console.

When I get this going then I'll try your libraries - and then think about how to scan 48 analog values using a mayhew mux shield- and return the velocity of each key.


--------------------------------------------- cut here -----------------------------------------   optocheck.ino

  Analog Input test for cyn70 - drc dec 2012

int sensorPin = A0;    // select the input pin for the potentiometer
int sensorValue = 0;  // variable to store the value coming from the sensor

void setup() {
  Serial.begin (9600);

void loop() {
  // read the value from the sensor:
  sensorValue = analogRead(sensorPin);   
Serial.print ("Opto returning: ");


ok - i got it going.  it turns out i smoked the diode in the CNY70.  So i replaced it and wiggled some wires.  now to try your libraries but i really need a good way to measure the velocity.


thanks for the tip.  i bought a pair of thee HC-SR04  and they plugged right onto the arduino board and worked - no brainer.   These are a little large (I need 96 sensors) too.  What I am looking for is something to sense velocity.   

I think that a library can be written for opto (infra red) sensors which are around $1.20 each.   I'm looking at the vishay CNY70; the vishay TCRT5000; rohM RPR-220.My idea was to test each of these and publish the result with a basic arduino circuit and ino sketch so that others could also do this.

The trick with measuring velocity is counting the number of cycles between high and low.   The smaller the count the faster the key was pushed.   But doing this efficiently for 98 poses a different question.


Hi, I'm kinda new to arduino interfacing from the micro-controller to the computer. So, I'm sorry if I have said anything unrelated to it. Okay, straight to the point, I'm using an arduino uno with a ready made LCD with keypads (LCD keypad shield) which it is compatible with the microcontroller. The problem is that analog pin A0 and digital pins D4 and D7 are occupied and utilized by the LCD keypad shield. So, I wonder whether it is possible to replace pin A0 to pin A1, pin D4 to pin D12 , and pin D7 to pin D13 respectively?




I'm doing a similar thing with the CNY70.  Actually compared these with several other sensors on the market. One problem with IR is drift from ambient IR sources (not necessarily light).  Currently trying to understand how to use a differentiator (http://en.wikipedia.org/wiki/Differentiator) which is typically a capacitor across the sensor that limits drift.    In my case the sensors will be located inside an aluminum enclosure.

And IR sensors generally only work for about 5mm distance.    They are great for things like wheel encoders (to measure the speed of a robot wheel).  Remember that IR is reflected, absorbed, or transmitted through materials.  Two plastics that look alike may have totally different properties.  An encoder wheel printed on an ink-jet printer will not work; one printed on a laser will work better.  Aluminum and gold are good reflectors.  Wood is pretty good.  The plastics i'm working with don't reflect well at all.

My project is a midi controller and I need to measure 96 inputs to measure the position of the keys.  I'm either going do to this with a pair of mayhew muxs, or use an array.  I've spent quite a few months noodling on this and would be curious to know what you find out.


thanks for the tip.  i bought a pair of thee HC-SR04  and they plugged right onto the arduino board and worked - no brainer.   These are a little large (I need 96 sensors) too.  What I am looking for is something to sense velocity.  

I think that a library can be written for opto (infra red) sensors which are around $1.20 each.   I'm looking at the vishay CNY70; the vishay TCRT5000; rohM RPR-220.My idea was to test each of these and publish the result with a basic arduino circuit and ino sketch so that others could also do this.

The trick with measuring velocity is counting the number of cycles between high and low.   The smaller the count the faster the key was pushed.   But doing this efficiently for 98 poses a different question.

Hey, I am really sorry for the late reply. Well, sensing for 98 keys is really hard, and it depends as well of what are you actually trying to do, if you are expecting how many keys to be played at the same time and which is the average speed of a key press, as well as which your boundaries are, meaning what: you can use a single key, and if speed is too high you won't get any data, now u can be multiplexing for... a loooooot of keys, if they are slow enought they will work.. even all at the same time. I hope I didn't come too late with these, good luck!
ps. regarding the ambient light.. or IR interference (you are right,even heat sources can produce IR radiation) the posted library try to deals with such a problem, it reads the received light with the IR-LED OFF, and the it turns it ON and compares both meassures, it has the ability to do some filtering routines, using mathematical cumulative, and non-cumulative methods... hope this helps better!!


well i have decided to go digital (on/off)and not measure the speed of the key.  the existing 128 channel mux that i built in 1990 works fine with this on an arduino.  but i'm considering using a different approach; namely a switched array.   so i'm pretty confident this will work with the arduino.

good point about the separate IR sensor and turning on and OFF and ON the IR sensor.  In my case all 96 sensors (the second board is smaller) are enclosed in a metal cabinet so the IR will be limited by the enclosure (i know of someone sensing guitar string vibrations with IR and that is much different because the human hand is right on the sensor).

What do you mean filters?

any how i'm hoping to post the final design and other notes on a website for others.  started with piezos which didn't work at all - and then to sp/st switches which don't have the feel (or the 5/16" travel of a piano key) and now working on IR sensors. 

Hope to get it done by maker faire in may 2013.



I want to make a line follower robot and I need to use Cny70. Which one of those functions above do you recommend me to use for line follower robot?


This is a very interesting topic indeed. many thanks to initiator and commentators...especially if we want to make an interactive machine or robot that responds at a set distance. A robot for example saying: " you are 5 inches close to me, please don t come any closer"..can upload this phrase in a WT588D little audio shield or similar...

not trying to divert the topic, but can anyone contribute a sketch( or a link to code) to use this 3-sensor array to make a servo follow a moving object ?

Live to learn & make


Hey there

There is some way to connect CNY70 to an ESP board to send some info to the internet?

Go Up