1

I am working on a project that is supposed to record the time difference between two photoresistors that are 4in apart. The photoresistors are sensing the passing of water or other liquids on a chute/ramp.

The liquids range from water to milkshakes so the time difference shouldn't be more than 2 or 3 seconds at most (I would think). I'm okay with the accuracy being off by a a few tenths of a second.

I am using Photo cell (CdS photoresistor) for my project.

I have looked online and haven't seen a similar project. I want to be able to display the time difference on a lcd.

I have my lcd up and running but I'm not sure how to code the time difference. My photoresistors are connected to A0 and A1 and I am using digital pins 7-12 for the lcd. If anyone has any advice that would be very appreciated!

I'm sure I missed something so ask any clarifying questions

1
  • 1
    Please edit your question (click "edit") to answer the following: Is the time difference a few tenths of seconds, milliseconds, or what? How accurate does your measurement need to be? What is your photoresistor part number? Can you read it via a digital comparison, or does it need to be analog input for some reason? How frequently do measurements need to be made? Jun 26, 2017 at 16:41

3 Answers 3

1

You are asking about

the time difference between two photoresistors

This, to start with, makes little sense. Photoresistors are analog devices. Their resistance, and thus the voltage you measure, is a continuously varying quantity. The first thing you have to do is to turn them into logic (i.e. either “off” or “on”) devices. The simplest approach is to compare your analog reading to a threshold:

  • if the reading is above the threshold, you will say LDR is in the HIGH state
  • if it is below the threshold, the LDR is in the LOW state.

There is a problem with this simple approach though: when the reading is close to the threshold, the ambient noise can make many spurious transitions between LOW and HIGH. The simplest solution is to have not one, but two thresholds. This is called “hysteresis” and is something you definitely should have whenever you are using thresholds against analog readings. This can be coded as follows:

const int THRESHOLD_LOW  = 400;  // dummy value
const int THRESHOLD_HIGH = 600;  // dummy value

int HystereticRead(uint8_t pin, int previousState)
{
    int reading = analogRead(pin);
    if (previousState == LOW && reading >= THRESHOLD_HIGH) {
        return HIGH;
    } else if (previousState == HIGH && reading < THRESHOLD_LOW) {
        return LOW;
    } else {
        return previousState;
    }
}

Obviously, the thresholds you will use will not be these dummy values: you will determine them from experiment.

Next thing is to record transitions. You do not want to look for a particular state of the LDR, but for the moment it moves from one state (say LOW) to the other. This is done by comparing the new state you read to the previous one, as in:

static int state0;  // state of the LDR 0
int new_state = HystereticRead(A0, state0);
if (state0 == LOW && new_state == HIGH) {
    // LDR 0 went from LOW to HIGH.
}
state0 = new_state;  // save for next time

Last thing, and really the simplest, is to record times. You just have to call millis() to get a timestamp, and compute a difference between timestamps to get a duration in milliseconds. Here is how you could write it:

void loop()
{
    static int state0, state1;  // states of the LDRs
    static uint32_t time0;      // last time LDR 0 went HIGH

    // Check for LDR 0 going HIGH.
    int new_state = HystereticRead(A0, state0);
    if (state0 == LOW && new_state == HIGH) {
        time0 = millis();
    }
    state0 = new_state;

    // Check for LDR 1 going HIGH.
    new_state = HystereticRead(A1, state1);
    if (state1 == LOW && new_state == HIGH) {
        uint32_t time1 = millis();
        Serial.print(time1 - time0);
        Serial.println(" ms");
    }
    state1 = new_state;
}
1
  • Thank you, Edgar! This was very comprehensive and, better yet, worked! Jun 28, 2017 at 16:18
1

The most accurate approach is via In out capture on your timer.

Alternatively you can use an interrupt to start and stop the timer.

The worst approach is to poll

However, phtoresistors are slow and generally inconsistent. This can lead to errors in reading. S phototransistor or diode works better.

Edit: it is crazy to try to read the signal in analog. Instead design the circuitry so that it breaches the digital low or high thresholds so you can use digitalRead instead.

You can simply use millis or micros to time stamp the events and calculate the difference.

If you want more precise timing measurements, Google ticks implementation.

edit 2:

here is what I tried:

if (dtime_running==0) {             //event 1 has not arrived
    if (EVENT_ON(EVENT1_PIN)) {     //event 1 has arrived
        dtime = time_now();         //time stamp the event
        dtime_available = 0;        //data not yet available
        dtime_running = 1;          //time measurement running
    }
} else {                            //event 1 has arrived and now wait for event 2
    if (EVENT_ON(EVENT2_PIN)) {     //and event 2 has arrived
        dtime = time_now() - dtime; //calculate the timing difference
        dtime_available = 1;        //data now available
        dtime_running = 0;          //stop taking measurement
    } 
}

On two pulses that are 500ms apart, here is the measurement: enter image description here

Notice that in the box on the upper right, dtime has a value of 500, just as we expected.

the risk with this approach is that if the loop has other tasks, jitters to the measurement will show up. but for slow events, or long time measurements, it may not matter that much.

2
  • Polling is more than fine if you are after a resolution in the 100 ms range. Jun 26, 2017 at 17:52
  • +1 for highly relevant point about CdS response times.
    – dandavis
    Jun 26, 2017 at 19:30
0

I assume you want to measure the difference in time between drops or a change in the resistance of the photo resistors?

Measure every x ms the values of the photo resistors. You can use a sleep for this (or maybe you can just continuously measure).

You have to store the measurements probably, to calculate, when a signal is changing. Also you have to store the times.

E.g.

      Resistor 1    Resistor 2
 0 ms          10            20
10 ms          10            20
20 ms          30           600     Drop at resistor 2
30 ms          30           620     Drop at resistor 2
40 ms          45            20     Drop passed resistor 2
50 ms         400            20     Drop arrived at resistor 1

So you know that the drop (delay) is 50 - 20 = 30 ms

You have to make an algorithm that will see this change, and also you might have to take into account multiple drops (so counting of drops/signal changes).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.