Go Down

Topic: Need advice on model train controller logic (Read 1 time) previous topic - next topic

Lawren5

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: [Select]

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
    }
  }
}   

Arrch

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

Code: [Select]
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: [Select]
if (dir == 1)  {                      // train in reverse direction
    ...
    if (spd > 0) {                     //  start timer when train stops
      directionTimer = millis() ;
    }
}


Then this part will fire:
Code: [Select]
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.

Lawren5

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: [Select]

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
    }
  }
}   


dxw00d

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.

AWOL

Quote
The spd function is called up in another void

spd is a variable, not a function.
"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.

Go Up