I am new to this need advice

pfroment

New Member
Here is what I am trying to do. I want to use picaxe to do many different types of tasks on my railroad.
I am having issues with this one.
A track comes to a turnout. I want to toggle a momentary up to change from track one to two. Here is the sequence:
LED 1 GOES TO RED
I PULSE A RELAY OF “X” AMOUNT OF TIME TO TURN A DC MOTOR A CERTAIN DISTANCE AND STOP
PUSH THE TOGGLE SWITCH DOWN
LED GOES TO GREEN
PULSE A SECOND RELAY TO REVERSE THE DC POLARITY TO BRING BACK THE MOTOR TO its ORIGINAL POSITION.

I have been writing code to do the above, but it is not doing what I want

How do I wire the spst toggle switch to say pin c1. Have the pin stay off, toggle the led (which I can do), turn on the relay for x amount of time and then have the sequence stoop until the toggle is thrown down.

I want to go from track 1 to 2 and then have a second turnout to go from 2 to 3.

Paul f
 

pfroment

New Member
what i have so far

BASIC converted from file:
'C:\Users\paul\Documents\PICAXE Editor\Documents\this turnout one.xml
'Converted 2017-02-10 at 10:44:36

Code:
main:
	

      pinC.1 = 1
	high C.6
    	low B.7
    	toggle B.5
    	pause 2000
    	toggle B.5
    	GOSUB tr2a 
	return
	
 tr2a:   	 
    	if pinB.2 = 1 then
    	low C.2
    	high C.7
    	toggle B.0
    	pause 2000
    	toggle B.0
    	high C.6
	pinB.2 = 1 
	gosub tr3a
	pinC.1 = 0 
	gosub tr1a
	return
	
 tr3a: 
       pinB.2 = 0
      endif
      pinB.2 = 0
    	high C.2
    	low C.7
    	toggle B.1
    	pause 2000
    	toggle B.1
    	high C.6
	gosub tr2a
	return
   	 
 tr1a:
  	if pinC.1 = 0 then
    	low C.6
    	high B.7
    	toggle B.3
    	pause 2000
    	toggle B.3
      endif
     goto main
 
Last edited by a moderator:

pfroment

New Member
here is a IC converted from file:
'C:\Users\paul\Documents\PICAXE Editor\Documents\this turnout one.xml
'Converted 2017-02-10 at 10:44:36
Code:
main:
	

      pinC.1 = 1   momentary sw on
	high C.6      red led on
    	low B.7        green led off
    	toggle B.5     start relay track 1 to tr2
	pause 2000
    	toggle B.5
    	GOSUB tr2a 
	return
	
 tr2a:   	 
    	if pinB.2 = 1 then  second  momentary sw is toggled up
    	low C.2      green led off
    	high C.7      red led on
    	toggle B.0     relay on, track 2 to 3
    	pause 2000
    	toggle B.0
    	high C.6        tr1 led red
	pinB.2 = 1 
	gosub tr3a
	pinC.1 = 0 
	gosub tr1a
	return
	
 tr3a: 
       pinB.2 = 0  second sw is toggled down
      endif          
      pinB.2 = 0
    	high C.2
    	low C.7
    	toggle B.1       starts relay to reverse above task  tr3 to tr2
    	pause 2000
    	toggle B.1
    	high C.6
	gosub tr2a
	return
   	 
 tr1a:
  	if pinC.1 = 0 then
    	low C.6
    	high B.7
    	toggle B.3  starts another relay to put tr1 to tr1
    	pause 2000
    	toggle B.3
      endif
     goto main

better explanation
 
Last edited by a moderator:

lbenson

Senior Member
I didn't go over it in any detail, but at the very least, "main:" should end with a GOTO MAIN instead of RETURN (where would it return to?), and "tr1a:" should end with RETURN (as should all sections of code called with GOSUB).

In "tr3a:", what does the ENDIF end?

The comments in your code should begin with the single quote character: '

After you have fixed those things, what happens when you use the picaxe simulator to walk through the code step by step, turning on inputs as needed and looking at the outputs. How does it differ from what you expect?
 

pfroment

New Member
i did what what you suggested, it runs throught the program and loops where it should. i get a "stack overflow - more gosubs than returns" error. I am going to wire it to a breadboard to get a better look. how do i start the show by turning on turning c.1 =1. I want it in a holding pattern until the toggle is thrown, then c.1 =1 unit toggle is thrown to retrun track 1 to track 1. Can I use a spst switch 0v to .,1 = 1, to make make c.1 =0?
 

Buzby

Senior Member
Don't put it on a breadboard yet !.

The simulator is telling you that there is a problem in your code, too many gosubs. ( This is usually caused by a missing 'return' statement, or a subroutine being called from within itself. )

If you put it on a 'real' PICAXE before you fix this problem you will have a real nightmare trying to figure it out.

Stick with the simulator, it's the best tool there is for getting code right.

Cheers,

Buzby
 

pfroment

New Member
walked away for a while and took a deep look at the flow, made many changes. will let you know how it goes. think i got the start set up...???????
 

lbenson

Senior Member
If you made changes, post your code again. If you learn to use the simulator, you will fix many problems before they reach the breadboard
 

lbenson

Senior Member
I don't think your pdf showed what you intended it to.

Please include your code as text in your posts, preferably within the tags, [ code]...[ /code] (without the spaces after "[").

This will preserve any formatting (for example, indentation) which you may have.
 

westaust55

Moderator
In addition to posting your latest code, it may be worthwhile posting further information about your requirements. There are a number of forum members who are also into model railways/railroads who may assist further.
still many more non-model railway folks can also help for many tasks even without an understanding of railways..

For instance, are the motors simple DC motors or are they stall motors (such as Tortoise or Cobalt) and what voltage do you operate the motors at.
If you are needing two relays to control operation and direction then IC alternatives such as the L293D, LV8548MC or if you use stall motors (which do not require turning off at end of travel) then the LV8549MC is also an option.
The L293D is a through hole part whereas the LV854xMC parts are surface mount.
If can come down to your electronics and soldering skills what is best for you so letting us know a bit about your capabilities and project requirements may get more than just a bit of programming help.

Note: I moved your thread into the main Active PICAXE forum area where it may be seen by more folks since it is not specifically about the operation of the Programming Editor
 

pfroment

New Member
what i have is a coal mine with 3 sidings. I have the program working where I can go from tr 1 to tr 2, tr 2 to tr 3 and tr 3 to tr 2. i haven't found a way (though I have tried many things) to reset the sidings when one is all done moving coal cars around, so that track 1 = track 1. In the program, this would be sub routine TR1A.

here is the code: any input would be much appreciated

BASIC converted from file:
'C:\Users\paul\Documents\PICAXE Editor\Documents\this turnout one.xml
'Converted 2017-02-10 at 10:44:36
Code:
main:
      if pinC.1 = 0 then
	 goto main
	 end if
     	goto start
start:   low B.7 
         high c.6
     toggle B.5       
	pause 2000
	toggle b.5
     	GOto tr2a 
	return
	
 tr2a:
       if pinb.2 = 0 then
       goto tr2a

       end if
       pinB.2 = 1 
     	low C.2       
    	high C.7       
    	toggle B.0    
	pause 2000
    	toggle B.0
    	high C.6        
 	goto tr3a
	return
	
 tr3a:
       if pinb.2 = 1 then
       goto tr3a 
	 end if
      pinB.2 = 0
    	high C.2
    	low C.7
    	toggle B.1       
	pause 2000
    	toggle B.1
    	high C.6
	pinB.2 = 1
	goto tr2a
		return
		
	
   	 
 tr1a:
  	if pinc.1 = 0 then
    	low C.6
    	high B.7
    	toggle B.3  
    	pause 2000
    	toggle B.3
     endif
     goto main
 
Last edited by a moderator:

edmunds

Senior Member
Dear @pfroment,

I run several large exhibition/museum railroads with a lot of picaxes doing things around them. Could you do two things to make helping you easier or possible at all, please? :)

1. Use comments and symbol definitions in the code, so people can understand what is it you are trying to do. To insert a comment add ";" or " ' " before the comment. Should look something like this:

Code:
...
  else                                                                 'If line in the centre (8 or 9) ...
  	  ELine = 0                                                     'Set error to zero
  	  agr_error = 0                                               'Set accumulator to zero
  	  steer_input = 0                                            'Do not steer
...
Instead of C.6 or pinC.1, define symbols and use those throughout the code. Should look something like this:

Code:
'Outputs
Symbol LED_A0 = A.0               'Line position LED display A0 pin
Symbol LED_A1 = A.1               'Line position LED display A1 pin
Symbol LED_A2 = A.2               'Line position LED display A2 pin

'Inputs
Symbol SensOut = pinB.1            'Analog out of the sensor

if SensOut = 1 then
  do something here
endif
2. Please indent your code properly and use [ CODE ] [ /CODE] tags in the forum.

If the list can go onto third, then if you could try and explain what is it you want to achieve again imagining we have no idea about operational details and setup of your layout, this would also help a great deal. A program, where you can go from tr1 to tr2 does not really tell a lot. Presumably, it is a train that has to move from track one to track two, but I doubt it can jump, so there needs to be some kind of backing out of the siding and driving into another one. And what is the input? You press a button, start a sequence on a computer in some MR control software or track switch - like reed switch or hall sensor?

Good luck,

Edmunds
 

pfroment

New Member
I can do that. not sure what you mean by:
Please indent your code properly and use [ CODE ] [ /CODE] tags in the forum.[/COLOR]
the rest i can and will do. looking foward to getting more ideas from you
 

stan74

Senior Member
In forum posts you type
Code:
then copy paste your code from program editor to here then put
at the end. that's [ /code ] without spaces.
I didn't know that when I 1st came here either. Labelling your code will help you as well as others because code looks like..er,code.
 

inglewoodpete

Senior Member
In forum posts you type
Code:
then copy paste your code from program editor to here then put
at the end. that's [ /code ] without spaces.
I didn't know that when I 1st came here either. Labelling your code will help you as well as others because code looks like..er,code.
Nearly correct. In the Programming Editor (Vers 6), select the code you want to post. Then, in the Home menu, Clipboard group, Click "Forum" button. Go to the forum and 'reply' and paste your clipboard to the text box. All of the formatting and colours are pasted into the reply text box.

It will look like:
Code:
      [color=Purple]bQuarter [/color][color=DarkCyan]= [/color][color=Black]Qtr
      [/color][color=Purple]bReadyToChime [/color][color=DarkCyan]= [/color][color=Blue]True
      [/color][color=Green]'Start the background timer (runs continuously)
      [/color][color=Purple]Timer [/color][color=DarkCyan]= [/color][color=Blue]tmrIntOn1stTick
      SetTimer t1s_8             [/color][color=Green]'Expires after 1 second @ 8 MHz[/color]
 

Buzby

Senior Member
Nearly correct. In the Programming Editor (Vers 6), select the code you want to post. Then, in the Home menu, Clipboard group, Click "Forum" button. Go to the forum and 'reply' and paste your clipboard to the text box.
I just select the text I want to show, right click, 'copy for forum', then paste into my forum post.

Code:
      [color=Purple]pinsC [/color][color=DarkCyan]= [/color][color=Purple]@ptrinc   [/color][color=Green]' Start X
      [/color][color=Purple]pinsB [/color][color=DarkCyan]= [/color][color=Purple]@ptrinc   [/color][color=Green]' Start Y
'pulsout Latch_1, 1 ' Latch start values

'pinsC = @ptrinc  ' End X
 'insB = @ptrinc  ' End Y
'pulsout Latch_2, 1  ' Output end values[/color]

Simples ! :)
 

lbenson

Senior Member
The code posted in #13 did not include the changes I suggested in post 5. That is at least part of the reason you are getting runtime errors.

In "main:" You did change "GOSUB tr2a" to "GOto tr2a", which further compounds the problem since there is a RETURN at the end of "tr2a:".

You cannot mix GOTO and RETURN. A good recommendation is to avoid using GOTO at all. (A common exception is "GOTO main" at the end of the "main:" code.)

Every GOSUB you use must follow a path which eventually ends in a RETURN which will transfer program execution back to the line following the GOSUB command. If you use GOTO, it can quickly complicate that path; in small programs this can be managed, but in larger programs it is likely to result in what has been termed "spaghetti code", where the actual paths of possible execution become very hard to follow.
 

BESQUEUT

Senior Member
A good recommendation is to avoid using GOTO at all. (A common exception is "GOTO main" at the end of the "main:" code.)
I agree for this recommendation, but not with this exception. instead of
Code:
main:
    if pinC.1 = 0 then
    else
    endif
goto main
Why not simply write :
Code:
do
   if pinC.1 = 0 then
   else
   endif
loop
With first code, you have to read entire program to know that this is a do loop.
With second one, you immediately know.
 

lbenson

Senior Member
I certainly agree with BESQUEUT. "GOTO main" is a common exception, but not one I would personally recommend.

His "do ... loop" method is preferred by those who wish to avoid "GOTO" entirely (not that I wish to re-open the GOTO wars (which you could find out more about by searching on the forum or elsewhere for "dijkstra goto")).
 

stan74

Senior Member
I just select the text I want to show, right click, 'copy for forum', then paste into my forum post.

Code:
      [color=Purple]pinsC [/color][color=DarkCyan]= [/color][color=Purple]@ptrinc   [/color][color=Green]' Start X
      [/color][color=Purple]pinsB [/color][color=DarkCyan]= [/color][color=Purple]@ptrinc   [/color][color=Green]' Start Y
'pulsout Latch_1, 1 ' Latch start values

'pinsC = @ptrinc  ' End X
 'insB = @ptrinc  ' End Y
'pulsout Latch_2, 1  ' Output end values[/color]

Simples ! :)
It doesn't allow big files though. I was "told" to do it the way I said, it doesn't include colours info, just indenting..I may be wrong. though.
 

pfroment

New Member
I feel like a 9th grader asking a Dr. of math how to slove 2x+1=5. I replaced the "goto" command with the "gosub". ran the simulation and got a stack overflow - more gosubs than returns
I did not get that with the goto commands. not sure why. i will post full code with no explanation and then break it down. If any one can show me a better and cheaper way to move turnouts, I will be greatfull.
Code:
[color=Green]'BASIC converted from file:
'C:\Users\paul\Documents\PICAXE Editor\Documents\this turnout one.xml
'Converted  2017-02-10 at 10:44:36[/color]

[color=Black]main:
      [/color][color=Blue]if [/color][color=Purple]pinC.1 [/color][color=DarkCyan]= [/color][color=Navy]0 [/color][color=Blue]then
       gosub [/color][color=Black]main
       [/color][color=Blue]end if
      gosub [/color][color=Black]start
start:   [/color][color=Blue]low B.7 
         high c.6
     toggle B.5       
      pause [/color][color=Navy]2000
      [/color][color=Blue]toggle b.5
      gosub [/color][color=Black]tr2a 
      [/color][color=Blue]return
      
 [/color][color=Black]tr2a:
       [/color][color=Blue]if [/color][color=Purple]pinb.2 [/color][color=DarkCyan]= [/color][color=Navy]0 [/color][color=Blue]then
       gosub [/color][color=Black]tr2a

       [/color][color=Blue]end if
       [/color][color=Purple]pinB.2 [/color][color=DarkCyan]= [/color][color=Navy]1 
      [/color][color=Blue]low C.2       
      high C.7       
      toggle B.0    
      pause [/color][color=Navy]2000
      [/color][color=Blue]toggle B.0
      high C.6        
      gosub [/color][color=Black]tr3a
      [/color][color=Blue]return
      
 [/color][color=Black]tr3a:
       [/color][color=Blue]if [/color][color=Purple]pinb.2 [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=Blue]then
       gosub [/color][color=Black]tr3a 
       [/color][color=Blue]end if
      [/color][color=Purple]pinB.2 [/color][color=DarkCyan]= [/color][color=Navy]0
      [/color][color=Blue]high C.2
      low C.7
      toggle B.1       
      pause [/color][color=Navy]2000
      [/color][color=Blue]toggle B.1
      high C.6
      [/color][color=Purple]pinB.2 [/color][color=DarkCyan]= [/color][color=Navy]1
      [/color][color=Blue]gosub [/color][color=Black]tr2a
            [/color][color=Blue]return
            
      
       
 [/color][color=Black]tr1a:
      [/color][color=Blue]if [/color][color=Purple]pinc.1 [/color][color=DarkCyan]= [/color][color=Navy]0 [/color][color=Blue]then
      low C.6
      high B.7
      toggle B.3  
      pause [/color][color=Navy]2000
      [/color][color=Blue]toggle B.3
     endif
     gosub [/color][color=Black]main 
     
  [/color]
step 1:
Code:
[color=Black]main:[/color]
[color=Green];       if pinC.1 = 0 then      this is m loop whch keeps track 1 lined to track
;                              if a spst is thrown, this makes c.1 = 1  Want
;       else                    c.1 to stay at 1
;       end if
;       gosub start[/color]
step 2
Code:
[color=Green];start: low B.7                   red led 
;       high c.6                  green led
;       toggle B.5                runs a relay to drive a motor to make track 1
;       pause 2000                ine to tk2
;       toggle b.5
;       GOsub tr2a 
;     return[/color]
step 3

Code:
[color=Black]tr2a:[/color]
[color=Green];      if pinb.2 = 0 then              this loop keeps tr1 to tr2 until a 
;      gosub tr2a                       second spst is thrown making b.2 =1[/color]
step 4

Code:
[color=Green];     end if                          this sequqnce reverses green/red leds
;     pinB.2 = 1                      and runs a second relay to drive motor 2
;     low C.2                      to make tr1 line to tr3
;     high C.7       
;     toggle B.0    
;     pause 2000
;     toggle B.0
;     high C.6        
;     gosub tr3a
;     return
      [/color]
step 5
Code:
[color=Black]tr3a:[/color]
[color=Green];     if pinb.2 = 1 then          this loops so that tr1 stays lined to tr2
;     gosub tr3a [/color]
step 6

Code:
[color=Green];     end if
;     pinB.2 = 0                    if spst 2 is thrown in opposite direction
;     high C.2                        then red / green leds change color
;     low C.7                        a third relay reverses motor 2 so tr 1 is 
;     toggle B.1                      lined with tr 2,  this process can go on
;     pause 2000                     until coal cars have been moved
;     toggle B.1
;     high C.6
;     pinB.2 = 1
;     gosub tr2a
;           return
            [/color]
finally my problem child

Code:
[color=Green]; tr1a:                                here is my problem child.  I want to make
;     if pinc.1 = 0 then               this subroutine to execute anytime that 
;     low C.6                          spst 1 is thron in the opposite direction
;     high B.7                         which runs a fourth relay to reverse  
;     toggle B.3                        motor  1 making tr1 line with tr1
;     pause 2000
;     toggle B.3                        we are now back to main
;     endif
;     gosub main 
     
  [/color]
there you have my brain storm, went from what a micro controller is to writing my first code in 5

this is a pic of the project

da0211171414 (1).jpg
 
Last edited:

hippy

Technical Support
Staff member
Think of ...

Code:
main:
  goto main
As being in your house, going out the back door and coming in through the front. You'll be going round in circles.

Now consider this ...

Code:
main:
  gosub main
Same as before, but every time you go out the back door put $10 on the table. You can pick that up when you come back in through the back door. But you never do, because you keep gosubbing round in a loop, out the back, placing $10, in through the front, never executing a RETURN command which sends you back to where you started from.

The "stack overflow" error is equivalent to you having run out of $10 bills.
 

lbenson

Senior Member
This is how I would lay out your code:
Code:
' 28train
#picaxe 28x2

main:
  do
    do : loop until pinC.1 = 1 ' loop until the pin goes high
    low B.7 
    high c.6
    toggle B.5       
    pause 2000
    toggle b.5
    gosub tr2a 
  loop
      
tr2a:
  do : loop until pinB.2 = 1 ' loop until the pin goes high
  pinB.2 = 1 
  low C.2       
  high C.7       
  toggle B.0    
  pause 2000
  toggle B.0
  high C.6        
  gosub tr3a
  return
      
tr3a:
  do : loop until pinB.2 = 0 ' loop until the pin goes low
  pinB.2 = 0
  high C.2
  low C.7
  toggle B.1       
  pause 2000
  toggle B.1
  high C.6
  pinB.2 = 1
  gosub tr1a
  return

tr1a:
  if pinc.1 = 0 then
    low C.6
    high B.7
    toggle B.3  
    pause 2000
    toggle B.3
  endif
  return
At the bottom of "tr3a:" you have "gosub tr2a". That would make this code "recursive", since tr2a called this routine. I suspect you didn't want that. You don't call tr1a anywhere, so I've substituted tr1a for tr2a.

You also didn't specify which chip; the picaxe 28x2 was the only one I could make compile with your pin selections, so I used that. This code compiles, and if in the simulator you toggle the right inputs, you can walk through every line of code. I don't know if it does what you want, because I don't know your logic.

You might try this in the simulator to see if you get what you intend.

Look carefully at the changes I have made and try to understand them.

Note also that there are many ways of doing things. This follows my general practice, but others may find different variations more understandable.
 

pfroment

New Member
I need tr1a to to executable at my whim. As part of a gosub, I lose the ability to switch between tr3a and tr2a as I need. Rolling over back to main won't work for this situation. It there a way to set pin c.1 to 0 at any time?
 

lbenson

Senior Member
The code you posted never went to tr1a at all. How do you see getting to that code (what input do you wish to respond to)?

Perhaps you could use an interrupt, but it's likely that if you describe the process more fully, people could show you how you could avoid that.
 

westaust55

Moderator
@ pfroment

I must admit that I am finding your code and information confusing. For example, as others have mentioned the IO used suggests a 28X2 or 40X2 PICAXE part yet your PE screenshot indicates an 18M2.

Adding SYMBOL statements to define in a form of "plain English" what the inputs, outputs and other variables are doing can make code far easier for you and all others to understand.

I note that at the top of your program listing there are statements suggesting it is converted. Converted from what?
There is also comment about one.xml. xml is a script language similar to javascript - is this where the concept originated?

are you in a position to re-assign the inputs and outputs to the PICAXE chip. That could make IO designations and coding even easier.
The code is not using a great deal of the PICAXE chip memory capacity. Do you have or are you aiming to include other code for additional features?

In an endeavour to try and help, have a try with the following code which has SYMBOL definitions and some comments and see if it does what you are seeking with respect to selection between the three railway tracks.

Code:
#PICAXE 28X2

;Define Inputs
SYMBOL Track1or2Seln	= pinC.1 	; spst1  low selects track 1, high selects track 2
SYMBOL Track2or3Seln	= pinB.2 	; spst2  low selects track 2, high selects track 3

; Define Outputs
SYMBOL Red_LED		= B.7 
SYMBOL Green_LED		= C.6

SYMBOL Motor1_2Reverse	= B.3		; relay 4 low to run to track 1, high to run to track 2
SYMBOL Motor2_2Reverse	= C.7 	; relay 3 low to run to track 2, high to run to track 3

SYMBOL Track1_2MotorRun	= B.5		; relay 1 high to energise Motor 1 
SYMBOL Track2_3MotorRun = B.0		; relay 2 high to energise Motor 2 
SYMBOL unknown 		= B.1 

;Define some constants
SYMBOL MotorRunTime = 2000
SYMBOL Track1Not2 = 0
SYMBOL Track2Not3 = 0



main:
    DO
       IF Track1or2Seln = Track1Not2 THEN    
         GOSUB SetTrack1
       ELSE
         IF Track2or3Seln = Track2Not3 THEN 
           GOSUB SetTrack2
         ELSE
           GOSUB SetTrack3
         ENDIF
       ENDIF  
    LOOP
    

SetTrack1:
	low Red_LED			; red led off
	high Green_LED		; green led on
	low Motor1_2Reverse	; set motor direction to Track 1
	high Track1_2MotorRun	' energise the motor 1
      pause MotorRunTime	; keep running desired time
     	low Track1_2MotorRun	; stop motor 1
	RETURN
	
SetTrack2:
	high Red_LED		; red led on
	low  Green_LED		; green led off
	high Motor1_2Reverse	; set motor direction to Track 2
	low  Motor2_2Reverse	; set motor direction to Track 2
	high Track1_2MotorRun	' energise the motor 1
	high Track2_3MotorRun	' energise the motor 2
      pause MotorRunTime	; keep running desired time
     	low  Track1_2MotorRun	; stop motor 1
	low  Track2_3MotorRun	' stop motor 2
	RETURN

SetTrack3:
	high Red_LED		; red led on
	low  Green_LED		; green led off
	high Motor1_2Reverse	; set motor direction to Track 2
	high Motor2_2Reverse	; set motor direction to Track 3
	high Track1_2MotorRun	' energise the motor 1
	high Track2_3MotorRun	' energise the motor 2
      pause MotorRunTime	; keep running desired time
     	low  Track1_2MotorRun	; stop motor 1
	low  Track2_3MotorRun	' stop motor 2
	RETURN
 

pfroment

New Member
I want to apologize to everyone for making all you fine people frustrated with me. I am a retired HVAC tech. My mind thinks in electromechanical terms and i have a hard time converting that into electronics. give me a room full of relays, contactors and controllers and i will build a circuit that will do what you want it to. If will fill a room and cost big bucks. give you the same project and you will come up with a 5 x 6 pc board that will to the same for pennies on the dollar. I envy you for that Give me a 57 chevy, open the hood and i am at home. give me a 2017 bmw, open the hood and i go DUH, what's all that stuff...

I know what i want the circuit to do and for the most part it is 95% good. What i need to know is how to store a subroutine in the chip's memory and call up that routine , when I want, while the program is running. Can i say OK bud, take subroutine tr1a and put it in our back pocket.. program is running and is at some obituary point during it's routine, i say Hey bud can you give me tr1a?
and bingo i reset back to main. is there a line of code i can stick in the program that will do this?

thamks for you patience

paul f
in snowy Connecticut USA (yes we are getting clobbered again)
 

premelec

Senior Member
You can put the subroutine in your code [not in special memory place] and then use a flag variable that is set and calls the GOSUB when the flag bit or variable is set by your code to call that subroutine... the flag variable stands for what might be a switch on in hardware situation... do something when switch is on... good luck with the snow - ;-0 BTW the called flagged subroutine should reset the flag - within the called subroutine - to 'show' the subroutine has been called... or not reset if you want to leave the switch on in my mechanical analogy...
 
Last edited:

hippy

Technical Support
Staff member
Can i say OK bud, take subroutine tr1a and put it in our back pocket.. program is running and is at some obituary point during it's routine, i say Hey bud can you give me tr1a? and bingo i reset back to main.
I think it's this "reset back to main" which is causing the problem. You either want to GOSUB to the routine then RETURN and continue with the code you were executing, or GOTO the routine and it will GOTO main. Though in the right circumstances you could GOSUB to the routine, RETURN and then GOTO main.

You could also RESET to get back to main, but that is usually the sign of a badly designed program, a square peg hammered into a round hole.

The overall problem is probably a lack of familiarity with programming, not having a clear understanding of loops, program flow and subroutines. It can be difficult to add something new to something which exists, because that has to work with what exists. The bale out and "reset back to main" approach usually causes problems, because it doesn't fit with what is there.
 

lbenson

Senior Member
Hey bud can you give me tr1a?
There's the rub. Unless you actually have a buddy there who responds to your request by doing something on your system (or unless you have a voice response system which implies more technical sophistication than it seems we are looking at), you now have to do something to accomplish on your model railroad whatever it is tr1a does. What is that? How do you see your picaxe-automated system doing that (in response to what)?

I suspect that part of the problem is that as you coded it, parts of the code are "blocking"--nothing can happen until a condition is satisfied. For instance

main:
if pinC.1 = 0 then : goto main : endif

Nothing can happen unless pinC.1 goes high. What does the value of pinC.1 signify? Likewise at the start of tr2a--what is pinB.2 supposed to mean in functional terms?

It would help if you could provide a drawing of your track layout (just pencil on paper would be fine), and then a description of how you want it to work. Then describe what each of the input and output pins means with respect to a train traversing your layout.

Note westaust55's code; try to provide that level of meaningful labeling and explanatory comments in the next code you post.

When you say it's 95% working, do you mean as installed, as simulated, in your head, or what? (In programming, there's many a slip twixt the cup and the lip.)

Believe me, you are the type of person whom experienced people on this forum like to help--someone who has obvious skills in one area, and wants to provide some automation to the task--an area where he lacks advanced skills.

But you need to provide us a little more to go on.
 

edmunds

Senior Member
What i need to know is how to store a subroutine in the chip's memory and call up that routine , when I want, while the program is running. Can i say OK bud, take subroutine tr1a and put it in our back pocket.. program is running and is at some obituary point during it's routine, i say Hey bud can you give me tr1a?
and bingo i reset back to main. is there a line of code i can stick in the program that will do this?
I'm afraid it is not as simple as that :). Basically, you have two concepts you can work with and both are not trivial at first, but make more sense more you apply them.

The first one is interrupt. You can have the chip check for certain condition to be true of false in between every operation it does, every unit of pause etc. Basically, very quick reaction to something happening. In case it detects the interrupt condition, it will jump to a special routine called interrupt in the end of the code, do what it says and go back to where it was in the main program, when done down there. There are various types of interrupts available depending on the picaxe you use, but it seems you need probably the most frequently used one - interrupt on momentary switch. Look up setint command.

The better option and one I use mostly on model railroads is a state machine approach. It took me, a totally non-programmer and not even a relays person about two years between I first heard of it and could apply it somewhat, but again, it is not difficult at all once you wrap your head around the basic idea. It basically presumes the system is in one of known states at all times and then you only need to tell the system what to do about it. A typical example would be a railroad crossing with lights and gates. The system would quickly loop around checking if some momentary contact showing a train has tripped. In case it does and the crossing is closed it would know it has to enter the loop crossing lights are toggled and gate should be closed. In case there is a momentary contact signal when the crossing is open it would know it has to open the gate and should not enter the crossing lights routing until the next command. You would basically set up several flags to describe the state the system is in and then do select case or if statements to check how many of them are true/false and act accordingly. Hope it makes sense :).


Good luck,

Edmunds
P.S. Feel good about yourself. You have gone a long way in 6 days and there is very little missing for your project to succeed.
 
Last edited:

premelec

Senior Member
@pfroment - note that if you are polling inputs and afraid of missing a momentary input on a pin because of the delay of the polling loop you can put a capacitor on the pin to stretch the input to be there longer than the instantaneous blip... the capacitor gets charged and if you put a bleeder resistor on it the input won't persist a long time - anyhow that's one way besides interrupts which demand 'instant' attention. In a fast loop only a few milliseconds stretch may do the job for you...
 

westaust55

Moderator
@pfroment,

Did you try the code provided at post 28 ?

It can be improved upon but did it work?
Improvement would be through not repeatedly pulsing the motors to the correct position.

Ultimately, whatever code you use will need to:
(A) In the first place (once off) check the position of the switches to set up the points/turnouts, and then
(B) For each and any change in the switches adjust the point/turnout positions between close/straight and throw/turn

Item B can be achieved by either
(i) Setting up interrupts and using an Interrupt subroutine to call the same subroutines whenever a change in switch state is detected. That will require changing the SETINT command parameters , or
(ii) Polling the switch positions in the main program loop and using flags with a couple of bit variables as mentioned by Edmunds in post 33. Each time there is a difference call the appropriate subroutine.

Unless the controlling switches are momentary pushbuttons or fleeting contact when switched, then typically the switch is moved to desired positions and left in the new position until a further/subsequent change in tract route is required, there should be no problems with polling.
 

pfroment

New Member
What I ended up doing is trashing that idea for something real simple. Wrote a program that operates one turnout. I will mass produce these boards and if I run into a situation, like the one I have posted about, then just use 2 boards. It will work perfectly.
That is for the input...learned a lot.
 
Top