Model Railroad Xing Gates

Im slowly trying to develope a program to take ir inputs and based on those inputs make the xing lights flash and then wait 5 seconds and then the gates will come down. So far i have the lights flashing at the rate i want them. Ive tried making the servos move but havent had any luck.

I will have 4 ir sensors like this:


| |
| RR |
--------IR1-------------------IR2-----------------------------IR3----------------------------------IR4
| |
| XING |


Another thing im trying to do is have the gates timeout (go back up)if the conditions require.
Meaning if the train trips IR1 the lights will flash then wait the 5 seconds and then the gates go down. If the train doesnt hit the IR2 sensor within 15 seconds, the gates will go back up and the lights will shut off. Im not quite sure if i should try the millis() or the while function since i havent used that function before. And the same goes for the other directions starting with IR4.
I didnt make any arrays figuring there wasnt that many reasons to use it. Also trying to work the speaker and make it DING DING but have never done anything like that before. Any help would be appreciated. Thanx in Advance.

Harrison

LowMTXing.ino (7.08 KB)

hbingham86:
Im slowly trying to develope a program to take ir inputs and based on those inputs make the xing lights flash and then wait 5 seconds and then the gates will come down. So far i have the lights flashing at the rate i want them. Ive tried making the servos move but havent had any luck.

I will have 4 ir sensors like this:


| |
| RR |
--------IR1-------------------IR2-----------------------------IR3----------------------------------IR4
| |
| XING |


Another thing im trying to do is have the gates timeout (go back up)if the conditions require.
Meaning if the train trips IR1 the lights will flash then wait the 5 seconds and then the gates go down. If the train doesnt hit the IR2 sensor within 15 seconds, the gates will go back up and the lights will shut off. Im not quite sure if i should try the millis() or the while function since i havent used that function before. And the same goes for the other directions starting with IR4.
I didnt make any arrays figuring there wasnt that many reasons to use it. Also trying to work the speaker and make it DING DING but have never done anything like that before. Any help would be appreciated. Thanx in Advance.
Harrison

Post your code and the schematic. Don't use while(), as it's blocking code. Your Arduino won't do anything else while it's running.

From a quick look at your code, you don't seem to update currentMillis anywhere.

You should probably have currentMillis = millis(); as the first line in loop()

Please don't write horrendously long comment lines in your code. Keeping line length below about 60 chars makes life much easier - especially for code posted here.

There is no need for scale length distances in a diagram that illustrates where sensors are :slight_smile:

...R

Alright. I just wanting to fully explain what I intend to do before it might go in the wrong direction. So if I shouldn't use the while would millis () be the way to go?

hbingham86:
Alright. I just wanting to fully explain what I intend to do before it might go in the wrong direction. So if I shouldn't use the while would millis () be the way to go?

I'm lost. There is no WHILE in the code attached to your earlier post - at least my editor couldn't find it.

Have you looked at the absence of currentMillis(). What happens if you sort that out?

Really you should write down the logical steps line by line on a sheet of paper before you try to figure out the way to code it.

For example

Start - no train nearby
train detected at X
next step
next step

etc etc.

You might want to look at this demo for timing with millis() several things at a time and this Thread about Planning and Implementing a Program.

...R

The lights do flash perfectly. But I'll put that in if need be.
So here's the order

No train detected
Train hits sensor 1
Lights flash and bell starts
Wait 5 seconds
Gates go down.
If the train hits sensor 2 within 15 seconds that lights stay on and the gates stay down.
If it doesn't hit the second sensor within 15 seconds the gates go up and the lights go off after the gates are fully up and the bell shuts off.

Thanx
Harrison

hbingham86:
So here's the order ....

That list you gave should be easy to turn into code.

I think you are the person who had this looonnnng Thread

I thought we went through similar logical stuff in that Thread?

...R

Yea that was me. I had finally finished that and wanted to do something different. I really appreciate all the help you have given me. It's helped out alot.

Thanx
Harrison

  if (IR1 == HIGH){digitalWrite(IR1Led, HIGH);} else {}  
  if (IR2 == HIGH){digitalWrite(IR2Led, HIGH);} else {}
  if (IR3 == HIGH){digitalWrite(IR3Led, HIGH);} else {}
  if (IR4 == HIGH){digitalWrite(IR4Led, HIGH);} else {}

What is the point of all this "else do nothing"? It just clutters up your code.

What's wrong with:

  if (IR1 == HIGH)
    digitalWrite(IR1Led, HIGH);
  if (IR2 == HIGH)
    digitalWrite(IR2Led, HIGH);
  if (IR3 == HIGH)
    digitalWrite(IR3Led, HIGH);
  if (IR4 == HIGH)
    digitalWrite(IR4Led, HIGH);

byte IR1 = A2;
byte IR2 = A3;

...

  if (IR1 && IR4 == LOW){

Well, that will never happen, right?
IR1 == A2.
IR2 == A3.

So they will never == LOW.


  IR1 = analogRead(IR1);
  IR2 = analogRead(IR2);
  IR3 = analogRead(IR3);
  IR4 = analogRead(IR4);

Now I'm totally confused.

I strongly suggest you read a tutorial on the C language. That code there is just going to do more-or-less random things every time it is executed.

Say IR1 is currently 3.

  IR1 = analogRead(IR1);

So that reads analog pin 3. Say that gives you 962. Then next time around you read pin 962. Do you not see how that won't work?

Code:
  if (IR1 == HIGH){digitalWrite(IR1Led, HIGH);} else {}  
  if (IR2 == HIGH){digitalWrite(IR2Led, HIGH);} else {}
  if (IR3 == HIGH){digitalWrite(IR3Led, HIGH);} else {}
  if (IR4 == HIGH){digitalWrite(IR4Led, HIGH);} else {}

Im not quite sure why i did that. I guess the habit of using if else.

Code:
byte IR1 = A2;
byte IR2 = A3;

...

  if (IR1 && IR4 == LOW){

Im not quite sure what you mean. IR1 and IR4 are a part of 1 code logic and IR2 and IR3 are a part of another.

Code:
  IR1 = analogRead(IR1);
  IR2 = analogRead(IR2);
  IR3 = analogRead(IR3);
  IR4 = analogRead(IR4);

So what you are saying is change that to digitalRead so itll see a high and low instead of a numerical reading?
This is the first time ever working with ir sensors so i do need to look more into them.

Thanx
Harrison

hbingham86:

Code:

byte IR1 = A2;
...
byte IR4 = A5;

...

if (IR1 && IR4 == LOW){




Im not quite sure what you mean. IR1 and IR4 are a part of 1 code logic and IR2 and IR3 are a part of another.

No I'm not saying that. Look, if you said "Fluffy is a cat, and Fido is a dog, so what should I do if Fluffy is a gorilla and Fido is a fish?".

You have just said they are neither so the question is meaningless.

 IR1 = analogRead(IR1);

So what you are saying is change that to digitalRead so itll see a high and low instead of a numerical reading?

No I'm not saying that. analogRead reads a pin, for example pin 5. It returns a number in the range 0 to 1023. So the very next time you execute this statement it won't read pin 5 any more.

Did you read my link? Gammon Forum : Electronics : Microprocessors : Arduino programming traps, tips and style guide

Closer would be:

 IR1value = analogRead(IR1);

That way you are not corrupting the pin number you are reading with the value you got.

byte IR1 = A2;
...
byte IR4 = A5;

...

if (IR1 && IR4 == LOW){

Im not quite sure what you mean. IR1 and IR4 are a part of 1 code logic and IR2 and IR3 are a part of another.

No I'm not saying that. Look, if you said "Fluffy is a cat, and Fido is a dog, so what should I do if Fluffy is a gorilla and Fido is a fish?".

You have just said they are neither so the question is meaningless.

H~ I have no idea where you are going with this.

Closer would be:

Code:
IR1value = analogRead(IR1);

That way you are not corrupting the pin number you are reading with the value you got.

H~ All i need is a high or low reading. i dont actually need the numerical value.

Thanx
Harrison

H~ I have no idea where you are going with this.

What are IR1 and IR2? They look like pin numbers. What are you comparing in the if statement? It looks you want the body of the if statement to be executed if the STATE OF the pin in IR1 is LOW AND the STATE OF the pin in IR4 is low. The statement itself is incorrectly written, performing a different comparison than what it seems you want to do, and operating on pin numbers, rather than pin states.

hbingham86:
Im slowly trying to develope a program to take ir inputs and based on those inputs make the xing lights flash and then wait 5 seconds and then the gates will come down. So far i have the lights flashing at the rate i want them. Ive tried making the servos move but havent had any luck.

I will have 4 ir sensors like this:


| |
| RR |
--------IR1-------------------IR2-----------------------------IR3----------------------------------IR4
| |
| XING |


Another thing im trying to do is have the gates timeout (go back up)if the conditions require.
Meaning if the train trips IR1 the lights will flash then wait the 5 seconds and then the gates go down. If the train doesnt hit the IR2 sensor within 15 seconds, the gates will go back up and the lights will shut off. Im not quite sure if i should try the millis() or the while function since i havent used that function before. And the same goes for the other directions starting with IR4.
I didnt make any arrays figuring there wasnt that many reasons to use it. Also trying to work the speaker and make it DING DING but have never done anything like that before. Any help would be appreciated. Thanx in Advance.

Harrison

Harrison,
I am working on bidirectional green wave / block control. Pretty much same basic principle. Send me PM if you want to swap coding ideas.
Cheers Vaclav

hbingham86:
H~ I have no idea where you are going with this.

Did you read my link? Gammon Forum : Electronics : Microprocessors : Arduino programming traps, tips and style guide

Don't say "yes" if you did not.

If you did, what do you believe it was telling you?

H~ I have no idea where you are going with this.

Did you read my link? Gammon Forum : Electronics : Microprocessors : Arduino programming traps, tips and style guide

Don't say "yes" if you did not.

If you did, what do you believe it was telling you?

Yes i did. Thats why i suggested changing it to digitalRead. I have no idea where your comparison comes into play.

H~ I have no idea where you are going with this.
What are IR1 and IR2? They look like pin numbers. What are you comparing in the if statement? It looks you want the body of the if statement to be executed if the STATE OF the pin in IR1 is LOW AND the STATE OF the pin in IR4 is low. The statement itself is incorrectly written, performing a different comparison than what it seems you want to do, and operating on pin numbers, rather than pin states.

IR1,IR2,IR3 and IR4 are the infrared sensors i am using for the inputs. The only reason i made the ifIR1 and IR4 == LOW is to set its state as unoccupied. I wasnt sure what all needed to be added as far as the millis delay so the IR code isnt complete.

Thanx
Harrison

IR1,IR2,IR3 and IR4 are the infrared sensors i am using for the inputs.

They are not.

byte IR1 = A2;

They are pin numbers where the sensors might be connected.

The only reason i made the ifIR1 and IR4 == LOW is to set its state as unoccupied.

You can't SET the state of a sensor. Or a pin number. You MUST read the state of the sensor connected to the pin.

You can't invent shortcuts. if(IR1 && IR4 == LOW) does not mean "if IR1 is LOW and IR4 is LOW". It means "if IR1 is true and IR4 is LOW". And, of course IR4 is NOT low. It is A5. The state of the pin whose number is in IR4 might be LOW, and IR1 is true, since it is not zero, but it is more likely that you mean if(digitalRead(IR1 ) == LOW && digitalRead(IR4) == LOW).

I wasnt sure what all needed to be added as far as the millis delay so the IR code isnt complete.

Irrelevant until you fix all the logic errors.

You can't SET the state of a sensor. Or a pin number. You MUST read the state of the sensor connected to the pin.

You can't invent shortcuts. if(IR1 && IR4 == LOW) does not mean "if IR1 is LOW and IR4 is LOW". It means "if IR1 is true and IR4 is LOW". And, of course IR4 is NOT low. It is A5. The state of the pin whose number is in IR4 might be LOW, and IR1 is true, since it is not zero, but it is more likely that you mean if(digitalRead(IR1 ) == LOW && digitalRead(IR4) == LOW).

It was to set the state of the circuit and island to unoccupied. I know you cant set sensor states. Would it just be easier to say A2 and A3. I am still newer the the whole arduino platform and i understand I have alot to learn. I didnt know you had to have 2 full digitalRead statements.

Anyone able to come up with a solution to the problem. I did some messing around and this is where im at.
Once again I am by no means the greatest just wanting to learn as much as i can. My next step would be I2c master and slave operation. But thats down the road.

if (circuit == occ){
if(currentMillis3 - previousMillis3 > timeout) { //**Not sure about this. This should be the wait 15 seconds then double check
previousMillis3 = currentMillis3;
if (island == unoccupied){
trainsAllGone();
}
}
}

Thanx
Harrison

LowMTXing.ino (8.35 KB)