IR Sensor operation

I am using an IR sensor to detect when a Model Railway train is detected in a block ...

This part of my sketch works fine ... BUT my issue is I have an IR sensor to detect when train has left the section but I dont want anything to happen till the Sensor goes HIGH...

So...

Operation is IR sensor detects train in block sensor goes LOW .. after I press a button signals and points are changed as required ...

As the Train leaves the section the second IR sensor goes LOW ... BUT ... I dont want signals and points to be changed back till IR sensor goes back to HIGH ...

Can anyone help with a few lines of code as I tried Millis() and a few other ways but I cant get to work...

Thanks very much

John

You should post your attempted code. It could be something simple.

Have you looked at the following example to detect specific state changes? StateChangeDetection

Hi, I have attached part of the sketch as was telling me I had uploaded over 9000 characters ...

So the issue is Whe I Enter the Block from SensorState 1 this changes LED and points ... now when I Exit via SensorState 6 the IR sensor goes LOW I want a delay on the pointswp4 thro to 7 until the IR sensor has gone back to HIGH ... i.e Train triggers to Enter Exit Block but if points are changed it will cause de-railment ...

//#################################### Sensor 1 Detection #############################

// Checking Sensor State 1 operation

   if (sensorState1 == LOW) {   // Start of Sensor 1 detection
   Serial.println(" Sensor State 1 ");//Reading IR Sensor 1
   
   digitalWrite (senseLed1, LOW);// Turns Mimic panel Sense 1 LED ON
   Serial.println(" Sense LED 1   ");
   Serial.print(senseLed1);


   

  }


   
   if (Buttonval1 == LOW) {
   Serial.println(" Button 101   ");
   Serial.print(Buttonval1);
   
   digitalWrite(signalPinsred1,LOW);// Turn Red Signal OFF
   digitalWrite(pointswp4, HIGH); // Operate Points 4,   as required
   digitalWrite(pointswp6, HIGH); // Operate Points   6,   as required
   digitalWrite(pointswp7, HIGH); // Operate Points  , 7 as required
   digitalWrite(signalPinsgreen1,HIGH);// Turn Green Signal ON
   
   Serial.print(" Point 4   ");
   Serial.println(pointswp4);
   }

 if (sensorState6 == LOW) {    //   From Sensor 1 detection of train Exiting section via Sensor 6
                              //   Wait for Sensor to go LOW before action
                              // Delay function here 
 // if((millis()- time) > 10000 ){ // Train still in sectio
 
   delay(100);
   digitalWrite(signalPinsred1,HIGH);// Turn Red Signal ON
   Serial.println("Red LED State");
   delay(100);
   Serial.println(signalPinsred1);//Check signal State Red
   digitalWrite(signalPinsgreen1,LOW);// Turn Green Signal OFF
   Serial.println("Green LED State");
   Serial.println(signalPinsgreen1);// Check signal state Green
   
   digitalWrite(pointswp4, LOW); // Operate Points 4, 6, 7 as required ... They are low so no change
   digitalWrite(pointswp6, LOW); // Operate Points 4, 6, 7 as required ... They are low so no change
   digitalWrite(pointswp7, LOW); // Operate Points 4, 6, 7 as required ... They are low so no change
   digitalWrite (senseLed1, HIGH); // Turn Mimic panel Sense LED off
  // time = millis();
   }

Try to avoid the use of delay. Create a timer with your millis code and use this to determine when the action you require takes place. There are lots of tutorials in the stickies on the use of millis.

Basically if you want event 2 to occur 500ms after event 1 you need to store the time that event 1 took place in a variable (event1Time = millis) then set your interval in a constant variable (const int interval1 = 500) then check if the required time has elapsed (if millis - event1Time >= interval1 do event 2). None of this is correct code, just the logic. You can have a timer doing for multiple events that are divisible e.g event 1 at 0ms, 2 at 500ms, 3 at 1000ms, 4 at 2000ms. All are divisible by 500 and so you can have a counter incrementing each time 500 is met so when the counter is 1 event 2 occus, when 2, event 3 and when 4 event 4.

In addition to what pmagowan said you are looking at the states of the inputs NOT the state changes of the inputs which is why I directed you to the StateChangeDetection example.

pmagowan:
Try to avoid the use of delay. Create a timer with your millis code and use this to determine when the action you require takes place. There are lots of tutorials in the stickies on the use of millis.

Basically if you want event 2 to occur 500ms after event 1 you need to store the time that event 1 took place in a variable (event1Time = millis) then set your interval in a constant variable (const int interval1 = 500) then check if the required time has elapsed (if millis - event1Time >= interval1 do event 2). None of this is correct code, just the logic. You can have a timer doing for multiple events that are divisible e.g event 1 at 0ms, 2 at 500ms, 3 at 1000ms, 4 at 2000ms. All are divisible by 500 and so you can have a counter incrementing each time 500 is met so when the counter is 1 event 2 occus, when 2, event 3 and when 4 event 4.

I cant really use a Delay or Millis() as the train could be anything from 1 mtrs to 3 mtrs so I really have to detect the beginning of the train and the end ... so just need a way of detecting the change of an IR sensor and then the End of the train so then all points would be changed back ... the only delay functions I had to put in was the Red/Green signal sometimes didnt light so a 100ms delay before seem to work not sure why ..

ToddL1962:
In addition to what pmagowan said you are looking at the states of the inputs NOT the state changes of the inputs which is why I directed you to the StateChangeDetection example.

That may work but not sure could try ... problem is in normal state IR sensor is HIGH ... so train comes along and trigger to LOW ... so dont do anything ... when the train passes the end IR sensor goes from LOW to HIGH ... so not sure if initial HIGH will think its a LOW to High operation ... but will certainly try ..

Is the State Change Detection a private page wont let me download so I just used Snipper

John40131:
That may work but not sure could try ... problem is in normal state IR sensor is HIGH ... so train comes along and trigger to LOW ... so dont do anything ... when the train passes the end IR sensor goes from LOW to HIGH ... so not sure if initial HIGH will think its a LOW to High operation ... but will certainly try ..

Is the State Change Detection a private page wont let me download so I just used Snipper

It is an Arduino.cc page.

You are checking for input states not transitions. Also, your code would be well represented by a state machine. You may want to also check out: State Machine

State 1: train in zone
State 0: train not in zone

That is state machine type thinking. But you also need state change for your sensor.

SensorPreviousState=High
SensorCurrentState=digitalread sensorpin
If sensorCurrentState is low and sensorPreviousState is high train has entered zone so set TrainState as above to 1.
Update sensorPreviousState to equal sensorCurrentState.
Check sensorCurrentState by digitalread sensorpin again
Now if sensorcurrentState is HIGH and sensorPreviousState is low you know the train has left zone and you can change trainstate to 0 and update previousSensorState

The rest of your code acts according to trainstate I.e if trainstate 1 don’t switch points and derail train

That is the gist of it but need to check states are

it is not really clear to me what the sensors do in relation to tain is entering block and leaving block. I try to describe in my own words what I'm guessing:

train enters block IR-Sensor1 changes from HIGH to LOW (What is the level of IR-Sensor2 in this moment? LOW or HIGH)

train stops in front of a signal. What output-levels do IR-Sensor1 / IR-Senor2 have in this moment?

You press a button to change signal from red to green ==> train passes signal

train starts to leaves block. If the locomotive of the train reaches IR-Sensor2 IR-sensor2 changes from HIGH to LOW
As long as wagons pass by IR-sensor2 IR-sensor2 stays LOW

When the last wagon of the train has passed by IR-sensor2 IR-sensor2 output-level goes HIGH and that is the moment where the signal shall change back to the state they were in the beginning?

Is this a correct description?
It would be helpful if you could draw a basic plan with free hands
that shows where is the signal and where are the IR-sensors 1 and IR-sensor 2

make two or three of these planes and add train entering
train is in block
train is leaving block
train has left th eblock and describe for each case how the signals and out-put-levels of the IR-sensors are.

So all different conditions can be seen easily. Me too I think a state-machine is the right program-structure to solve this control-problem

best regards Stefan
any newbee can apply the most professional habit from the first line of code they write on their own:
add only ONE thing at a time. Test/debug that ONE thing until that ONE thing works reliable - repeat.
The sad thing is: only the REAL professionals write code this way.

Let's say you have 3 states:

train_not_in_block,
train_in_block,
train_exiting_block

Train is initially not in the block (train_not_in_block). When the IR-Sensor1 transitions from HIGH to LOW (regardless of IR-Sensor2 state) then the train is in state train_in_block. When the IR-Sensor2 transitions from HIGH to LOW (regardless of IR-Sensor1 state) then the train is in state train_exiting_block.

Note that if the locomotive stops at a signal while in the block it will remain in the train_in_block state until the locomotive passes IR-Sensor2 in which case it will enter the train_exiting_block state. When IR-Sensor2 transitions from LOW to HIGH then the train will enter the train_not_in_block state and the process starts all over. When moving from state to state you can perform whatever actions you wish (like restoring signal states).

You can also check for invalid signals during your state processing. For example if the state is train_not_in_block you should not see a LOW on IR-Sensor2 because either 1) some other object is triggering the sensor, 2) you have a bad sensor, or 3) you have a wiring issue.

That is the nice thing about state machines. You know what the state of the inputs should be and therefore you can check for system faults.

StefanL38:
it is not really clear to me what the sensors do in relation to tain is entering block and leaving block. I try to describe in my own words what I’m guessing:

train enters block IR-Sensor1 changes from HIGH to LOW (What is the level of IR-Sensor2 in this moment? LOW or HIGH)

train stops in front of a signal. What output-levels do IR-Sensor1 / IR-Senor2 have in this moment?

You press a button to change signal from red to green ==> train passes signal

train starts to leaves block. If the locomotive of the train reaches IR-Sensor2 IR-sensor2 changes from HIGH to LOW
As long as wagons pass by IR-sensor2 IR-sensor2 stays LOW

When the last wagon of the train has passed by IR-sensor2 IR-sensor2 output-level goes HIGH and that is the moment where the signal shall change back to the state they were in the beginning?

Is this a correct description?
It would be helpful if you could draw a basic plan with free hands
that shows where is the signal and where are the IR-sensors 1 and IR-sensor 2

make two or three of these planes and add train entering
train is in block
train is leaving block
train has left th eblock and describe for each case how the signals and out-put-levels of the IR-sensors are.

So all different conditions can be seen easily. Me too I think a state-machine is the right program-structure to solve this control-problem

best regards Stefan
any newbee can apply the most professional habit from the first line of code they write on their own:
add only ONE thing at a time. Test/debug that ONE thing until that ONE thing works reliable - repeat.
The sad thing is: only the REAL professionals write code this way.

Your description is more or less correct … Train passes IR Sensor 1 which is normally HIGH (5V) so goes LOW this gives me indication with LED senseLED1 … so Train stops as signal is RED signalPinsRed1 … I then press button so SignalPinsGreen shows and various point motors are activated via Pointsw … train proceeds and then the second IR sensor on to the Exit of Block … now this is were the problem is as soon as IRSensor 2 is triggered it goes from HIGH to LOW and turns points back and Signal states back to RED … but the issue is because train is still passing over points and points change they will de-Rail so I need some way of delaying the points until say the Sensor 2 changes back from LOW to HIGH … i.e IR Sensor 2 triggers but just changes the signalPinsRed1 back to RED and points will only change after last Carraige has passed sensor 2…

I have tried IF and WHILE statements between where the Red signal change and were the Delay(100) is but it just causes problems for the rest of the process…

Look up state change detection. Your description is complicated by a lot of irrelevant stuff. Think of each individual situation on its own and create a function for it. You can have a function for detecting the IR1 signal or IR2 signal and it can have a number of outputs which you can use as required. eg with state change detection you can output on the change of state from high to low and also on the change from low to high. You can perform an action associated with each, either or none of these. You can set states within variables such as TrainInBlockState which can equal 1 or 0 which is determined by simple state machine code.

Your final sentence is simply inadequate for explaining anything other than that you have tried some vague stuff.

To be very simple. Look ONLY at the IR sensors. Write a small table of what they do when:
a) The train has not entered the zone of interest
b)The train is entering
c)the train is in
d)the train is leaving
e) the train has left

decide what bit you are interested in and how the IR sensors are operating. Then you just need to code what is happening

pmagowan:
Look up state change detection. Your description is complicated by a lot of irrelevant stuff. Think of each individual situation on its own and create a function for it. You can have a function for detecting the IR1 signal or IR2 signal and it can have a number of outputs which you can use as required. eg with state change detection you can output on the change of state from high to low and also on the change from low to high. You can perform an action associated with each, either or none of these. You can set states within variables such as TrainInBlockState which can equal 1 or 0 which is determined by simple state machine code.

Your final sentence is simply inadequate for explaining anything other than that you have tried some vague stuff.

My problem is I am a novice at sketch programs and can easily get in a hole and I dont know what I did wrong ... as it is at the moment all works apart from this Sensor Exit issue ...

people keep telling me to learn but this is a not quite one off as I do have other Arduino modules within my layout but I have other things to make on this Model Railway and I have spent 18 months and layout is not yet up and running and that is not an Arduino problem its just time and being nearly 73 its not easy to learn code ..

It is never easy to learn code but you need to get a basic understanding 1st of the actual situation in the real world that you want your code to interact with and 2nd of the basics of how the code can do this. Otherwise you will never understand your code and any problem will be lost in a pile of gibberish.

Code is just converting human level stuff to logic to computer level stuff. The microcontroller will invariably give you exactly what you ask for but you need to understand the question. The way to write code so that it is understandable is to break it down into manageable chunks, give each chunk a useful and intuitive name, get a chunk working and then move on to the next chunk.

With your train you have a 'train position sensing' chunk. All the other stuff like points and switches and leds should be in their own chunks of code. Work out what it is you want to detect with regards to your trains position and what the sensors will output in these circumstances as per the table above. Only once you know what you need will you, or any one else, be able to put it into code. This is often known as a minimal working example and you can do this in a separate, brand new, fresh sketch. You should only be looking at the stuff related to train position sensing. When you have that sorted then you can use that to affect all the other variables such as points, leds etc as you require because your code will 'know' when the train is entering, leaving, left or any number od such states that may be useful to you.

I think I understand the best way of doing this sketch correctly ...BUT ... I dont know how to create the loops ..

i.e Entry Loop to operate the Entry Sensor and Signal to RED..

LOOP to Wait Till Button is Pressed then Signal and points are Set..

Exit Loop IR Sensor HIGH to LOW to change Signal back to RED..

LOOP for IR Sensor Change from LOW to HIGH ...

I did first try something like this but didnt work so its setting the different Loops that I need to find ..

pmagowan:
It is never easy to learn code but you need to get a basic understanding 1st of the actual situation in the real world that you want your code to interact with and 2nd of the basics of how the code can do this. Otherwise you will never understand your code and any problem will be lost in a pile of gibberish.

Code is just converting human level stuff to logic to computer level stuff. The microcontroller will invariably give you exactly what you ask for but you need to understand the question. The way to write code so that it is understandable is to break it down into manageable chunks, give each chunk a useful and intuitive name, get a chunk working and then move on to the next chunk.

With your train you have a 'train position sensing' chunk. All the other stuff like points and switches and leds should be in their own chunks of code. Work out what it is you want to detect with regards to your trains position and what the sensors will output in these circumstances as per the table above. Only once you know what you need will you, or any one else, be able to put it into code. This is often known as a minimal working example and you can do this in a separate, brand new, fresh sketch. You should only be looking at the stuff related to train position sensing. When you have that sorted then you can use that to affect all the other variables such as points, leds etc as you require because your code will 'know' when the train is entering, leaving, left or any number od such states that may be useful to you.

The problem you can write as much about what I should and shouldnt be doing but that doesnt realy help me
people telling me to set this up and do this is not code so its a matter of saying scrap that idea and do it this way ... In even tried setting up with arrays but that didnt work for me ... basic is good ...
I am also a member of MERG and they have set up an Arduino SIG and they also have a forum which everyone looses interest ...

It is hard for us to understand your problem if you don't understand it or are unable to communicate it clearly. My suggestion is to forget everything except the IR sensors as this is what detects where the train is. I don't know what your setup is but you keep talking about signals and points etc. I would forget about these. Only deal with ONE thing at a time and, from my understanding, your current problem is detecting where the train is with your code (which then goes on to affect signals and points etc).

So! new bit of code for the IR sensors and ONLY the IR sensors.

You need to decide, as we can't see your setup, what the code has to do. You could draw it, or put it in a table etc

You need to decide what 'states' are the ones you are interested in eg
train arriving, train in zone, train leaving, train left etc and what these should look like

for instance, you have 2 sensors, is the train large enough to trigger both while in the zone or does it move through IR1 to IR2?

does train arriving state mean that IR1 is triggered only or can it still be 'arriving' after it has passed IR1 and still on way to IR2?

all you need is to work through these simple states one at a time. You can describe them in English rather than code but don't mix in anything else.

I will try and send the sketch as a Notepad++ document as when I tried to post as sketch was telling me over 9000 characters …

I have posted before how the process works including a picture as attachment …

Train triggers 1st IR HIGH 5 volts to LOW 0 volts sensor … this sets an LED on … I press a button to change the aspect signals from RED to GREEN also this sets points … this is via another module using a SG90 servos ( some points are switched via a MEGA and PCA9685 BUT not on this setup it is controlled via a SERVO4 module which powers 4 servos with a High to LOW input (MERG Module) … Train is then powered crossing points depending on direction … So there is a second IR sensor on Exiting Block … and this is triggered again from HIGH to LOW … so this is the issue … I want this Sensor to just turn the 2 Aspect Signal back to RED … NOT the POINT’s servos … once the whole of the Train has passed this Second Sensor it will go back to HIGH and thsi is when I want the outputs to the points that were originally changed to go back to there original state and that is all points in a straight ahead position but for this argument it doesnt matter so long as they go back to what was before the Train hit the first Sensor …

I hope this makes it clearer … there are 4 detections on this sketch all are the same except point and signal ID’s …

One addition for this circuit I will probably use a TOT detection ( Train on Track ) and that is an LM393 looking at the track current which in turn will operate an Opto Mosfet/Transistor which when connected to a 5 volt rail will give a HIGH to LOW when triggered to the Servo module … the circuit works from the DCC power of the tracks … NOT DC … this DCC is a PWM AC signal which a locomotive has a decoder chip so the controller can talk to it so the trigger circuit senses a current change in track and this triggers the LM393 comparator … reason for this IR sensors can be triggered by normal lights but the sense is still the same HIGH to LOW …

Darcy Loop Notepad.txt (13.3 KB)