Which sensor registered a difference first?

Thread Starter

John A Bonilla

Joined Mar 11, 2017
92
Hello everyone,

I am programming a robot to register a line using two line sensors. The robot will be moving forward, and there are lines perpendicular to it. I am using two sensors on either side of the robot so that it can self correct itself if it starts drifting off in either direction. So if one sensor sees the line before the other then it needs to turn a little to correct its heading. It seems simple enough but I don't know how to code which sensor read the value first. I am using the arduino IDE to do this. I am grateful for any suggestions you have, and if you have any questions I would be happy to answer them.

upload_2018-3-31_9-34-47.png

-John
 

AlbertHall

Joined Jun 4, 2014
12,346
The Arduino has two interrupt inputs and can generate an interrupt when either of these inputs falls/rises/changes.
When one sensor sees the line the code will then jump to the interrupt routine for the pin that sensor is connected to.

[Edit] Additionally, you could then wait for the other sensor to see the line and measure the time between the two. That will give you some measure of how far out the direction is.
 

Thread Starter

John A Bonilla

Joined Mar 11, 2017
92
The Arduino has two interrupt inputs and can generate an interrupt when either of these inputs falls/rises/changes.
When one sensor sees the line the code will then jump to the interrupt routine for the pin that sensor is connected to.

[Edit] Additionally, you could then wait for the other sensor to see the line and measure the time between the two. That will give you some measure of how far out the direction is.
Thank you! However, how would I measure the time between the two?
 
Thank you! However, how would I measure the time between the two?
If you use an interrupt scheme, realize that the interrupts are prioritized...so one will be detected before the other even if they are "hit" at the same time. I don't think you have to worry about that at all and attaching the sensor output to an interrupt may work just fine (see attachInterrupt()).

One way that might work for you is to make use of a running time meter that is built in to the Arduino. Take a look at the millis() function. When called, this function will return an unsigned long value representing the time, in milliseconds, since the Arduino powered up (and it will rollover after ~50 days). This seems like a good tool to assist you in determining which sensor crossed the line first and get you to a value of "by how much".

So, you could get the time value when each of the two sensors were triggered, store those values to be accessed by your main() (see volatile data type).

Your two interrupt routines would just store the time stamp of when the line was seen by each one. But, how does your main program "know" that both interrupts have fired? In other words, you need the timestamp as well as a way of detecting that both sensors have seen the line. One way to do that is to add another variable to each interrupt routine.

Now all that the interrupt routines do is set the timestamp variable and another variable to 1, for example, when it has executed.

Your main program looks at the "fired" variable for each and if both are 1, proceeds to first reset the fired variables to 0, and then compare the two times and determine if and how much correction is needed. Again, how long before the line is encountered and the assumption that both sensors will always fire at each line is a consideration (see below).

Before you jump into a bunch of code, think about a few things:

What is the GREATEST steering error that is possible? Is it possible that a steering error could be so great that only one sensor will fire?

How long before the lines are encountered by either sensor? This will depend on the speed of the robot, distance between lines and direction of the robot. Your program needs to always catch those line crossings.

Think about the minimum and maximum steering corrections that you want to use. You want to avoid over correcting such that the robot is wildly zig-zagging from line to line.

Finally, think about a hardware solution, I don't think you need one, but it is worth thinking about. There are tons of "who buzzed first" circuits and you could probably adapt one pretty easily. This might be easier to implement, would only tell you which line was crossed first, so all of the above will need to be reconsidered.

An interesting challenge.

Hope this helps.
 
Last edited:

Thread Starter

John A Bonilla

Joined Mar 11, 2017
92
If you use an interrupt scheme, realize that the interrupts are prioritized...so one will be detected before the other even if they are "hit" at the same time. I don't think you have to worry about that at all and attaching the sensor output to an interrupt may work just fine (see attachInterrupt()).

One way that might work for you is to make use of a running time meter that is built in to the Arduino. Take a look at the millis() function. When called, this function will return an unsigned long value representing the time, in milliseconds, since the Arduino powered up (and it will rollover after ~50 days). This seems like a good tool to assist you in determining which sensor crossed the line first and get you to a value of "by how much".

So, you could get the time value when each of the two sensors were triggered, store those values to be accessed by your main() (see volatile data type).

Your two interrupt routines would just store the time stamp of when the line was seen by each one. But, how does your main program "know" that both interrupts have fired? In other words, you need the timestamp as well as a way of detecting that both sensors have seen the line. One way to do that is to add another variable to each interrupt routine.

Now all that the interrupt routines do is set the timestamp variable and another variable to 1, for example, when it has executed.

Your main program looks at the "fired" variable for each and if both are 1, proceeds to first reset the fired variables to 0, and then compare the two times and determine if and how much correction is needed. Again, how long before the line is encountered and the assumption that both sensors will always fire at each line is a consideration (see below).

Before you jump into a bunch of code, think about a few things:

What is the GREATEST steering error that is possible? Is it possible that a steering error could be so great that only one sensor will fire?

How long before the lines are encountered by either sensor? This will depend on the speed of the robot, distance between lines and direction of the robot. Your program needs to always catch those line crossings.

Think about the minimum and maximum steering corrections that you want to use. You want to avoid over correcting such that the robot is wildly zig-zagging from line to line.

Finally, think about a hardware solution, I don't think you need one, but it is worth thinking about. There are tons of "who buzzed first" circuits and you could probably adapt one pretty easily. This might be easier to implement, would only tell you which line was crossed first, so all of the above will need to be reconsidered.

An interesting challenge.

Hope this helps.
Thank you for your help, I will try that! Theoretically it should work, however my luck with electronics isn't always the best .
 

MrSoftware

Joined Oct 29, 2013
2,200
The idea of doing very little inside the interrupt routines is a good one. If you're using clock tick functions like millis(), just be aware that at some point the clock counter will rollover, and if it happens at a bad time then you'll get some unexpected results. Unless you code to handle it! Google millis rollover and you'll get tons of info. Good luck!
 

AlbertHall

Joined Jun 4, 2014
12,346
If you record the value of millis() at some event (m1) and then again at a second event (m2) then providing millis() has not rolled over more than once, the time between the two events is m2 - m1 even if a rollover occured berween the two events.
 
Top