Pages: [1]   Go Down
Author Topic: Need advice on model train controller logic  (Read 1207 times)
0 Members and 1 Guest are viewing this topic.
Washington State
Offline Offline
Newbie
*
Karma: 0
Posts: 37
View Profile
 Bigger Bigger  Smaller Smaller  Reset 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 Offline
Faraday Member
**
Karma: 82
Posts: 3123
View Profile
 Bigger Bigger  Smaller Smaller  Reset 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 Offline
Newbie
*
Karma: 0
Posts: 37
View Profile
 Bigger Bigger  Smaller Smaller  Reset 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 Offline
Faraday Member
**
Karma: 19
Posts: 3114
View Profile
 Bigger Bigger  Smaller Smaller  Reset 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 Offline
Brattain Member
*****
Karma: 240
Posts: 24424
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset 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." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Washington State
Offline Offline
Newbie
*
Karma: 0
Posts: 37
View Profile
 Bigger Bigger  Smaller Smaller  Reset 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 Offline
Jr. Member
**
Karma: 0
Posts: 96
Everything I am is classified under the official secreats act!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset 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 Offline
Newbie
*
Karma: 0
Posts: 37
View Profile
 Bigger Bigger  Smaller Smaller  Reset 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
Jump to: