Pages: [1]   Go Down
 Author Topic: Need advice on model train controller logic  (Read 833 times) 0 Members and 1 Guest are viewing this topic.
Washington State
Offline
Newbie
Karma: 0
Posts: 37
 « on: October 06, 2012, 12:11:12 pm » Bigger Smaller Reset

I’m using an Arduino to control my train set. The plan is to have a programmed routine that the train follows. Being relatively new to programming, it appears to me that such a routine is best performed by sequential software. I’m somewhat freaked out by the Arduino software because the void loop keeps repeating so more conditions need to be set up to control events.

Anyway, what I’m trying to do at this point is simply run the train and have it reverse direction when it goes over a reed switch located under the track. Once it reverses, it goes over a second reed switch to send it forward again and the process repeats.

The code below is only partially working in that it detects the first reed switch and stops the train for 3 seconds as planned. However, when the train restarts, it does not reverse but continues in the forward direction. I can’t seem to get the correct logic figured out and was hoping someone could offer some suggestions on how best to accomplish this.

Code:
void loop() {

if (dir == 0)  {                // train in forward direction
if (bitRead(poll0,4))  {   // reed switch 4 activated
throttle = 0;             // train coasts to a stop
}
if (spd > 0) {               //  start timer when train stops
directionTimer = millis() ;
}
if  (millis() - directionTimer >= directionInterval){ // after 3 seconds
dir = 1;   // set direction to reverse
throttle = 50;           // at speed 50
}
}

if (dir == 1)  {                      // train in reverse direction
if (bitRead(poll0,5))  {         // reed switch 5  activated
throttle = 0;                   // train coasts to a stop
}
if (spd > 0) {                     //  start timer when train stops
directionTimer = millis() ;
}
if  (millis() - directionTimer >= directionInterval){  // after 3 seconds
dir = 0;                          // set direction to forward
throttle = 100;                // at speed 100
}
}
}
 Logged

California
Offline
Edison Member
Karma: 41
Posts: 1872
 « Reply #1 on: October 06, 2012, 12:30:47 pm » Bigger Smaller Reset

When and where is spd being updated? If it's not being updated between here:

Code:
if (dir == 0)  {                // train in forward direction
...
if  (millis() - directionTimer >= directionInterval){ // after 3 seconds
dir = 1;   // set direction to reverse
throttle = 50;           // at speed 50
}
}

and here:

Code:
if (dir == 1)  {                      // train in reverse direction
...
if (spd > 0) {                     //  start timer when train stops
directionTimer = millis() ;
}
}

Then this part will fire:
Code:
if  (millis() - directionTimer >= directionInterval){  // after 3 seconds
dir = 0;                          // set direction to forward
throttle = 100;                // at speed 100
}
Directly after you set dir to reverse.
 Logged

Washington State
Offline
Newbie
Karma: 0
Posts: 37
 « Reply #2 on: October 06, 2012, 12:52:20 pm » Bigger Smaller Reset

The spd function is called up in another void but my main focus here was on the logic for train direction. That being said, I just got this working by adding a variable called lastSwitch which identifies the last switch activated. The revised code is below and tested fine.
Anyway, I'm still somewhat confused by the looping characteristics of the Arduino software because it appears that it requires more variables and condition testing to implement in a model train routine as opposed to a sequential program. Am I correct in assuming this?  Is there a way around the void loop or is it desirable?
Code:
void loop() {

if (dir == 0)  {   // train in forward direction
if (bitRead(poll0,4))  {  // reed switch 4 activated
throttle = 0;     // train coasts to a stop
lastSwitch = 4;
}
if (spd > 0) {  //  start timer when train stops
directionTimer = millis() ;
}
if  (millis() - directionTimer >= directionInterval && lastSwitch == 4){ // after 3 seconds
dir = 1;   // set direction to reverse
throttle = 50;     // at speed 50
}
}

if (dir == 1)  {  // train in reverse direction
if (bitRead(poll0,5))  { // reed switch 5  activated
throttle = 0;   // train coasts to a stop
lastSwitch = 5;
}
if (spd > 0) {  //  start timer when train stops
directionTimer = millis() ;
}
if  (millis() - directionTimer >= directionInterval && lastSwitch == 5){  // after 3 seconds
dir = 0;   // set direction to forward
throttle = 100;     // at speed 100
}
}
}

 Logged

Gosport, UK
Offline
Karma: 19
Posts: 3117
 « Reply #3 on: October 06, 2012, 01:01:39 pm » Bigger Smaller Reset

If you don't need to run in an endless loop (it isn't always appropriate), put all your code in setup(), and just have an empty loop().

They are referred to as functions, not voids. A void function is one that doesn't return a value.
 Logged

Global Moderator
UK
Offline
Brattain Member
Karma: 138
Posts: 19067
I don't think you connected the grounds, Dave.
 « Reply #4 on: October 06, 2012, 01:02:56 pm » Bigger Smaller Reset

Quote
The spd function is called up in another void
spd is a variable, not a function.
 Logged

Pete, it's a fool looks for logic in the chambers of the human heart.

Washington State
Offline
Newbie
Karma: 0
Posts: 37
 « Reply #5 on: October 06, 2012, 05:49:37 pm » Bigger Smaller Reset

Thanks for the advice. I'll try making it work in the loop but if it gets too complex, I'll switch over to setup().
Also, thanks for educating me on proper vocabulary usage.
 Logged

2nd star on the right
Offline
Jr. Member
Karma: 0
Posts: 82
Everything I am is classified under the official secreats act!
 « Reply #6 on: October 07, 2012, 05:12:09 am » Bigger Smaller Reset

I may be missing something but as supply from the arduino to the track can only go in one direction wont you need additional electronics to change the polarity if the tracks?
 Logged

Sorry for the noobish post but my knowledge is 10 years out of date!

Washington State
Offline
Newbie
Karma: 0
Posts: 37
 « Reply #7 on: October 07, 2012, 12:00:07 pm » Bigger Smaller Reset

Yes, additional electronics are required to power the track. I'm using an L293D chip which can provide up to 600ma in either direction.
For the reed switches, a 4051 multiplexer is used to reduce the number of required to the Arduino.
 Logged

 Pages: [1]   Go Up