Go Down

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

Lawren5

Oct 06, 2012, 07:11 pm
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

#1
Oct 06, 2012, 07:30 pm
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

#2
Oct 06, 2012, 07:52 pm
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

#3
Oct 06, 2012, 08:01 pm
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

#4
Oct 06, 2012, 08:02 pm
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.

Lawren5

#5
Oct 07, 2012, 12:49 am
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.

AJB2K3

#6
Oct 07, 2012, 12:12 pm
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?
Sorry for the noobish post but my knowledge is 10 years out of date!

Lawren5

#7
Oct 07, 2012, 07:00 pm
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.

Go Up

Please enter a valid email to subscribe

To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy