LDR sensor issues - using it to automated model railroad!

Hi guys, bit of a noob with Arduino, not a massive electronics whizz, but here is what I have created... its an automated toy train set

The track is powered with a dedicated 12v, through a bridge driver controlled by the Arduino. All I want to do so far (and have made a bit of headway :slight_smile: ) is have the train run from one end of the track to the other and pass over an LDR photocell which slows the train reverses direction and sends it back to the other end of the track, which I am pleased to say more or less works with this code.

Problem is, the LDR gives a high-value of 1023, which drops to below 500 when the train passes over. As the train comes back it looks like it is triggering the LDR sequence again and re-stops the train. This doesn't always happen just once, but sometimes 2 or 3 times when the LDR values fluctuate for some reason back to 1023 even when the sensor is dark (noise maybe?). Using a longer train, so the LDR is covered for the whole time the train is stopped does not do the trick, either the gaps in the coaches causes the value to jump or just the fluctuations.

I am wondering what the best solution might be for this? Have the Arduino ignore the LDR values for a few seconds after the first drop?

Only the ground is connected together between the 5v Arduino and 12v DC adapter, but perhaps there is some PWM interference or other noise created in the circuit.

Is there no way to use the LDR as a 'trigger once' sort of deal, where once the value has dropped below 500 then further values are ignored until the next cycle?

Any help really appreciated here guys!

VIDEO HERE

const int r1Positive = 2;
const int r1Negative = 3;
const int r1Speed = 4;
int LDR5 = A12; // select the input pin for LDR
int LDR7 = A14; // select the input pin for LDR

bool trainRunning = false; 

int sensorValue = 0; // variable to store the value coming from the sensor



void setup() {

pinMode(r1Positive, OUTPUT);
pinMode(r1Negative, OUTPUT);
pinMode(r1Speed, OUTPUT);
pinMode(26, OUTPUT);
pinMode(27, OUTPUT);

digitalWrite(2, LOW);
digitalWrite(3, HIGH);
analogWrite(r1Speed, 200);
  
Serial.begin(9600); //sets serial port for communication
}



void loop() {
  

sensorValue = analogRead(LDR7); // read the value from the sensor
Serial.println(sensorValue); //prints the values coming from the sensor on the screen

  if(sensorValue < 500) //setting a threshold value
  {  for (int i=255; i>=0; i--){
    analogWrite(r1Speed, i);
    delay(5);
   }
  trainRunning = false;
  // wait for two seconds after stopping the train  
  delay(2000);
  digitalWrite(2, HIGH);
  digitalWrite(3, LOW);
  analogWrite(r1Speed, 200);
  }


 
sensorValue = analogRead(LDR5); // read the value from the sensor
Serial.println(sensorValue); //prints the values coming from the sensor on the screen

  if(sensorValue < 500) //setting a threshold value
  {  for (int i=255; i>=0; i--){
    analogWrite(r1Speed, i);
    delay(5);
   }
  trainRunning = false;
  // wait for two seconds after stopping the train  
  delay(2000);
  digitalWrite(2, LOW);
  digitalWrite(3, HIGH);
  analogWrite(r1Speed, 200);
  }
  
}

Keep track of whether you're going forward or back. Based on that, only check the ldr at the far end of the track.

Hi,
When you have detected the train, you then need to ONLY look for the other LDR to trigger.
At the moment crossing over the same LDR when reversing is causing the stopping.
You need to have a variable that indicates which way the train is running, this way you can ONLY look for the other LDR once you have reached the track end.

If travelling EAST, stop if EASTERN LDR is triggered.
Change direction.
then
If travelling WEST, stop if WESTERN LDR is triggered.
Change direction.

Hint, read both LDRs in the first lines of your loop.
This means you have a snapshot of your system, use those stored readings in the rest of your code.

Tom... :slight_smile:

Karma++ for posting so nicely!

the LDR gives a high-value of 1023, which drops to below 500 when the train passes over

Reduce the values of R1 and R2 to something more reasonable, perhaps between 1K and 10K. That should give you a wider range of light/dark values to work with and make it easier to deal with variations in the "covered" phase.