Hello,
I am setting up an UNO R3 using IDE 1.8.9 for a student experiment. This is for a metal ball rolling down a slightly inclined one-meter-long guide. Rather than using a stopwatch or camera, I am trying to set-up a pair of IR emitters and receivers at either end of the guide. The difference in time between the two photogates is to be displayed on an OLED. I am stuck on the OLED displaying 'Time difference : 0' on testing. I have adjusted the code many times but cannot have a time displayed. Any troubleshooting ideas would be highly appreciated. Thank you.
const int photogate1Pin = 2; // Photogate sensor 1 connected to digital pin 2
const int photogate2Pin = 4; // Photogate sensor 2 connected to digital pin 3
unsigned long photogate1Time = 0;
unsigned long photogate2Time = 0;
unsigned long timeDifference = 0;
Please add code tags to your post, and post a hand drawn wiring diagram or schematic, with pins and parts clearly labeled. Post a link to the photogate product page.
Instructions can be found in the "How to get the best out of this forum" post.
Fritzing diagrams are generally not appreciated on this forum, because they are usually unclear or misleading, and often wrong, but yours does suggest that the circuit lacks the required current limiting resistor in series with each of the LEDs, which can result in destruction of Arduino output pins and the LEDs.
Hint: start with one photogate, properly wired, and write simple code to make sure it works correctly before adding another.
I don't think this is doing what you want. Both of those lines will wait for 1 second for the signal to go high and then time out and return a -1 value in microseconds. Do you ever set the pin to low before these two lines? Don't see it.
To do what your post says you want, you need to save the time in milliseconds or microseconds when the ball breaks the first beam and again to a different variable when the second beam is broken. Subtract the first from the second variable and that is the time to transit from the first to the second beam.
With the LED’s connected to pins 12 and13 of the Uno, those pins will have to be set to output and set high. Most likely you don’t need to turn the LED’s on an off so they can be powered directly from the 5 volt supply using the correct current limiting resistor as mentioned above by @jremington .
Depending on the timing required you ma want to use micros() funtion instead of millis().
Thank you for this information and quick response. I did a hand drawn version, but instead I did an online version as I felt my drawing was a bit unclear. Will do a hand drawing next time.
I read the 'how to post' info, and put the code between the code tags, but I will review again as I have done it wrong.
I will add a resistor, maybe I have damaged the IR emitters-receivers I have installed.
You can buy actual photogates, which consist of an IR LED and an IR phototransistor or IR photodiode.
IR phototransistors can be bought separately and should work with the LEDs you have (if the LEDs are still functional). They are easier than photodiodes to interface with Arduino.
Thank you to everyone who has helped me with this project so far.
After adjusting my code many times I am not outputting any response on the attached OLED or the Serial monitor. My code and (terribly) drawn schematic is attached.
Does anyone have an idea why I am not outputting anything?
I have connected 220 Ohm resistors to the IR emitters and 10 k Ohm to the IR receivers.
I have tested the OLED and board with a simple OLED output program and that showed output on the OLED.
I have removed and reinstalled the libraries, and checked the connections and replaced the wires.
The board is an Uno R3, the OLED is a DWEII OLED 128x64, running the IDE on a Windows desktop.
Code:
// add in all libraries
#include <Adafruit_GFX.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
// OLED screen size
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
// Setting up OLED initial paramters
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// declare variables for PGs
int IRDetectorStart = 2;
int IRDetectorFinish = 3;
int IRLEDStart = 13;
int IRLEDFinish = 12;
int IRDetectorVal;
bool photoGate1;
bool photoGate2;
float eventTime;
float rounded_up = ceilf(IRDetectorVal * 100) / 100; // restricts value to 2 decimal places, rounding up
void setup() {
//Set baud rate
Serial.begin(9600);
// connect arduino to OLED and set OLED state
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
delay (5000);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 10);
display.display();
// Initial state of pins starting low
pinMode(IRDetectorStart, INPUT_PULLUP);
pinMode(IRDetectorFinish, INPUT_PULLUP);
pinMode(IRDetectorStart, INPUT);
pinMode(IRDetectorFinish, INPUT);
pinMode(IRLEDStart, OUTPUT);
pinMode(IRLEDFinish, OUTPUT);
digitalWrite(IRLEDStart, LOW);
digitalWrite(IRLEDFinish, LOW);
// Reading and print IRDetector values
photoGate1 = digitalRead(IRDetectorStart);
digitalWrite(IRDetectorStart, HIGH);
IRDetectorStart = millis();
{
display.println("Start time");
display.println(photoGate1);
}
photoGate2 = digitalRead(IRDetectorFinish);
digitalWrite(IRDetectorFinish, HIGH);
IRDetectorFinish = millis();
{
display.println("Finish time");
display.println(IRDetectorFinish);
}
eventTime = IRDetectorFinish - IRDetectorStart;
eventTime = millis();
display.println(eventTime);
}
Another way to measure speed as distance over time is with a transceiver like a VL53L0X. As the object approaches, time is stored at two known distances. Delta T (measured) over delta D (known) gives average speed.