This is the photo interrupter also known as photogate, photodiode, or phototransistor. Phototransistors are specially designed transistors with the base region exposed these transistors are light sensitive, especially when an infrared source of light is being used. Phototransistors it has two leads a collector and emitter. When the light is absent the phototransistor is closed and does not allow a collector-emitter current to pass through the phototransistor open only with the presence of sufficient light.
On this illustration, we will demonstrate using a dc motor with flat slotted disk attach to the motor when the motor spins the slotted disk interfere with the beam from the led to the phototransistor. The width blade affects the efficiency of the motor as it determines how long the electromagnet stays on. If you want to make your own slotted disk keep in mind that it should be dense as paper or cardboard might be semi-transparent for infrared light. Opto interrupter is a small U-shaped black plastic package which has four pins two for infrared LED on one side pin for light sensitive transistor and external connection is required. The infrared light and the photo diode are in a single package the photo-interrupter employs trans missive technology to sense obstacles existence, act as on/off switch or sense a low-resolution rotary or linear motions. The principle states that object opaque to the infrared will interrupt the transmission of light between an infrared emitting diode and a photo sensor switching from the output of HIGH state to LOW state.
Required Components
- Arduino Microcontroller, ESP8266 12, 12E, ESP8266 NodeMCU, ESPDuino, WeMos, ATMEGA328 16/12, ATMEGA32u4 16/8/ MHz, ESP8266, ATMEGA250 16 MHz, ATSAM3x8E, ATSAM21D, ATTINY85 16/8 MHz (Note: The Diagram below is using NANO. If your using other MCU please refer to the respective pin-outs
- MOC78XX / H206 / GP1A57HRJOOF Opto Interrupter or Module
- Solder Less Bread Board
- Jumper Wire / DuPont Wire
Wiring Guide
Source Code for Digital IO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
int PinOut = 2; //Set assign digital pin 2 int myDelay = 500; void setup() { Serial.begin(9600); //Set Serial Communication pinMode(PinOut, INPUT); //Set as INPUT Serial.println("14CORE | Opto Interrupter Digital Out Test Code") Serial.println("-----------------------------------------------") } void loop(){ if (digitalRead(PinOut)==LOW){ Serial.println("HIGH - ON"); }else{ Serial.println("LOW - OFF"); } delay(myDelay); } |
Source Code for Analog IO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
int PinOut = A0; //Set assign digital pin 2 int myDelay = 50; int val; void setup() { Serial.begin(9600); //Set Serial Communication pinMode(PinOut, INPUT); //Set as INPUT Serial.println("14CORE | Opto Interrupter Analog Out Test Code") Serial.println("-----------------------------------------------") } void loop(){ val = analogRead(PinOut); Serial.print("Sensor Value:") Serial.print(val); delay(myDelay); } |
Source Code for Speed Detection
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
int PinIn = 5; //Set assign digital pin 5 int PinLed = 13 //Set led status indicator pin 13 int myDelay = 500; //Delay 13 volatile int position = 0; volatile boolean direction = false; void setup() { Serial.begin(9600); //Set Serial Communication pinMode(PinIn, INPUT); //Set as INPUT pinMode(PinLed, OUTPUT); //Set as OUTPUT Serial.println("14CORE | Opto Interrupter Speed Detection Test Code") Serial.println("----------------------------------------------") /* attachInterrupt (<interrupPin>,<interrupServiceRoutine>,<trigger>); interrupPin is 0 or 1, for digital 3 or 5, interrupServiceRoutine functioin to run trigger ISR to run can be LOW, RISING, or CHANGE */ attachInterrupt(0, currentPosition, FALLING); } void currentPosition(){ if(digitalRead(PinIn == HIGH){position ++;} //Set moving in positive direction, increment position else {position--;} //Set moving in nigative direction, decrement position } void loop(){ Serial.println("Starting Direction Detection"); digitalWrite(PinLed, HIGH); delay(myDelay); digitalWrite(PinLed, LOW); delay(myDelay); } |
Source Code for Direction Detection
In order to detect the speed of the motor, the time must be taken into account if time is recorded at each pulse from the photo-interrupter then compared to the time of the previous pulse, the motor revolutions per minute can be calculated.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
int PinIn = 5; //Set assign digital pin 5 int PinLed = 13 //Set led status indicator pin 13 int myDelay = 500; //Delay 13 volatile int position = 0; volatile boolean direction = false; volatile unsigned long time = 0; volatile unsigned int inTime; volatile int revPerMin; const int spokes = 2; void setup() { Serial.begin(9600); //Set Serial Communication pinMode(PinIn, INPUT); //Set as INPUT pinMode(PinLed, OUTPUT); //Set as OUTPUT Serial.println("14CORE | Opto Interrupter Direction Test Code") Serial.println("----------------------------------------------") /* attachInterrupt (<interrupPin>,<interrupServiceRoutine>,<trigger>); interrupPin is 0 or 1, for digital 3 or 5, interrupServiceRoutine functioin to run trigger ISR to run can be LOW, RISING, or CHANGE */ attachInterrupt(0, currentPosition, FALLING); } void currentPosition(){ if (digitalRead(PinIn == HIGH){position++}; }else{position--}; inTime = millis()-time; //retun the time is millis since the board was turn on time = time + inTime; revPerMin = 1/spokes * 1/inTime * 1000 * 60 //Time calculation & number of spokes to calculate the RPM of the motor } void loop(){ Serial.println("Starting Direction Detection"); digitalWrite(PinLed, HIGH); delay(myDelay); digitalWrite(PinLed, LOW); delay(myDelay); } |
Source Code for Interrupts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
int PinIn = 5; //Set assign digital pin 5 int PinLed = 13 //Set led status indicator pin 13 int myDelay = 500; //Delay 13 volatile int position = 0; volatile boolean direction = false; void setup() { Serial.begin(9600); //Set Serial Communication pinMode(PinIn, INPUT); //Set as INPUT pinMode(PinLed, OUTPUT); //Set as OUTPUT Serial.println("14CORE | Opto Interrupter Interrupts Test Code") Serial.println("----------------------------------------------") /* attachInterrupt (<interrupPin>,<interrupServiceRoutine>,<trigger>); interrupPin is 0 or 1, for digital 3 or 5, interrupServiceRoutine functioin to run trigger ISR to run can be LOW, RISING, or CHANGE */ attachInterrupt(0, currentPosition, FALLING); } void currentPosition(){ if (direction = true){position++} else{position--;} } void loop(){ digitalWrite(PinLed, HIGH); delay(myDelay); digitalWrite(PinLed, LOW); delay(myDelay); } |
Downloads