Forward & Reverse switching?

JPB33

Senior Member
I'm working on a forward and reverse switch for a lathe using a 20M2. I've got this code working but I've hit a brick wall in my knowledge so I'm asking for advice.

input C.0 high is forward and C.1 high is reverse. The outputs are B.0, B.1 and B.3 which drive relays which is also works fine as does the closedown sequence when forward or reverse is switched off.

What I want to do is stop reverse being energised after being selected whilst forward is still closing down else both directions are working for a short time which isnt good!

I dont think I can use gosub as I'm not sure what direction will be selected first so its not a routine?

I would be grateful if someone can point me in the right direction or even understand my explanation! Thanks

Code:
   start:
	pause 1000
      do
	low B.0
	loop	until pinC.0 = 1 ; PinC.0 high to operate
	high B.0
	pause 1000
	if pinc.0 =0 then
	goto start
	endif
	high B.2
	do
	loop until pinC.0 = 0 
	low B.2
	pause 2000
	low B.0
	goto start
	

start1:
	pause 1000
      do
	low B.1
	loop	until pinC.1 = 1 ; PinC.1 high to operate
	high B.1
	pause 1000
	if pinC.1 = 0 then
	low B.1
	goto start1
	endif
	high B.2
	do
	loop until pinC.1 = 0 
	low B.2
	pause 2000
	low B.1
	goto start1
 

BESQUEUT

Senior Member
The outputs are B.0, B.1 and B.3 which drive relays which is also works fine as does the closedown sequence when forward or reverse is switched off
What are supoosed to do B.0, B.1 and B.2 ?
Note that there is no B.3 in your code...

Simply add
low B.1 before high B.0
and
low B.0 before high B.1

Your program is supposed to deal with short press/long press(more than 1s...) but you are not saying what you want your program to do...

My suggestion, without any GOTO command (maybe you know that I hate the GOTO command...) :
Code:
[color=Black]start:[/color]
[color=Blue]do
      pause [/color][color=Navy]1000
      [/color][color=Blue]low B.0
      do
      loop  until [/color][color=Purple]pinC.0 [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=Green]; PinC.0 high to operate


      [/color][color=Blue]low B.1 [/color][color=Black]: [/color][color=Blue]high B.0
      pause [/color][color=Navy]1000
      [/color][color=Blue]if [/color][color=Purple]pinc.0 [/color][color=DarkCyan]=[/color][color=Navy]1 [/color][color=Blue]then
            high B.2
            do
            loop until [/color][color=Purple]pinC.0 [/color][color=DarkCyan]= [/color][color=Navy]0

            [/color][color=Blue]low B.2
            pause [/color][color=Navy]2000
            [/color][color=Blue]low B.0
      endif
loop
      

start1:
do
      pause [/color][color=Navy]1000
      [/color][color=Blue]low B.1
      do
      loop  until [/color][color=Purple]pinC.1 [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=Green]; PinC.1 high to operate

      [/color][color=Blue]low B.0 [/color][color=Black]: [/color][color=Blue]high B.1
      pause [/color][color=Navy]1000
      [/color][color=Blue]if [/color][color=Purple]pinC.1 [/color][color=DarkCyan]= [/color][color=Navy]0 [/color][color=Blue]then
            low B.1
            
      else
            high B.2
            do
            loop until [/color][color=Purple]pinC.1 [/color][color=DarkCyan]= [/color][color=Navy]0
      
            [/color][color=Blue]low B.2
            pause [/color][color=Navy]2000
            [/color][color=Blue]low B.1
      endif
loop[/color]
 
Last edited:

techElder

Well-known member
What I think you need that you haven't written about is a device to detect when the lathe is no longer rotating.

Then it doesn't matter which direction is the "new" direction.
 

erco

Senior Member
Per Tex, the right way to do it is to have a rotary sensor to detect when the lathe has stopped. If no such sensor is available, you could just run some empirical tests to determine how long it takes your lathe to coast to a stop. Safest bet is to use the worst case scenario of max RPM turning a heavy load which acts like a flywheel and take longer to spool down. Whatever that interval is, program a PAUSE for that many seconds before restarting in the opposite direction. No pause is necessary if the restart is in the same direction of rotation previously used (you'll store/update the last direction as a variable for reference).

If this is a brushed DC motor you could get fancy with an extra relay and do some dynamic braking to slow the lathe down faster. Basically temporarily hooking a low-value, high-power resistor across the two motor terminals.
 

JPB33

Senior Member
Thanks everyone for the helpful comments, I should have explained it better but pleased I posted my problem as its lead to a solution! To explain further C.0 and C.1 are 5v inputs from the modified existing F&R switch. Outputs B.0 B.1 energise relays replacing the F&R switch, B.2 switches the inverter on. The relays are driven by darlington transistors.

The sequence of events is input C.0 high to select forward, B.0 goes high, contactors in, then a delay and goes B.1 high to start inverter. Lathe now running forward.

Switch off B.2 off first, inverter stops motor slows and stops, B.1 off after delay, contactors out. Then other the direction can be selected and the sequence repeated in opposite direction. What I wanted was to prevent the opposite direction being selected before the initial sequence finished and the motor stopped.

I want to use the existing control gear which works fine, but also wanted to allow time for the inverter to ramp up after the direction was selected. the motor is three phase 7.0 hp two speed (1440 & 2880 rpm) I had thought about using a rotation sensor on the motor but havent got that far yet, was going to determin the time delay (going to make it adjustable) after some test and may be enough bearing in mind the lathe dates from 1968 and its survived so far. Some lathes I've seen use dynamic braking with dc injection to the motor which gives good results.

My good friend The Bear has come up with a gosub routine that I couldnt get working so I think the problem is solved for now--many thanks

#Picaxe 20M2
#No_Data

output B.0,B.1,B.2,B.3,B.4,B.5,B.6,B.7
input C.0,C.1,C.2,C.3,C.4,C.5,C.6,C.7

Symbol SwitchFor = pinC.0
Symbol SwitchRev = pinC.1


Main:
low B.0, B.1,B.2
if SwitchFor = 1 then
Gosub FOR_WARD
endif
if SwitchRev = 1 then
Gosub REV_ERSE
endif
goto main

FOR_WARD:
pause 1000
high B.0
pause 1000
if SwitchFor =0 then
goto main
endif
high B.2
do
loop until SwitchFor = 0
low B.2
pause 3000
return


REV_ERSE:
pause 1000
high B.1
pause 1000
if SwitchRev = 0 then
low B.1
goto main
endif
high B.2
do
loop until SwitchRev = 0
low B.2
pause 3000
return
 

hippy

Technical Support
Staff member
I think what you need is a Finite State Machine (FSM). Multi-tasking can be used to set the desired state when a button is pushed and wit until button is released ...

Code:
Start0:
  Do
    if pinFWD = 1 Then
      desiredState = GO_FWD
      Do : Pause 100 : Loop While pinFWD = 1
    End If
  Loop
And similar for the reverse button.

Then a multi-tasking routine which knows whet state things are in and sequences then to what the desired state should be.
 

BESQUEUT

Senior Member
Thanks everyone for the helpful comments, I should have explained it better but pleased I posted my problem as its lead to a solution! To explain further C.0 and C.1 are 5v inputs from the modified existing F&R switch. Outputs B.0 B.1 energise relays replacing the F&R switch, B.2 switches the inverter on. The relays are driven by darlington transistors.

The sequence of events is input C.0 high to select forward, B.0 goes high, contactors in, then a delay and goes B.1 high to start inverter.
Do you mind B.2 high to start inverter ?

It is very dangerous to use a GOTO command within a subroutine. The RETURN command will never be reached, causing unpredictable behavour...

I want to use the existing control gear which works fine, but also wanted to allow time for the inverter to ramp up after the direction was selected.
Your code do exactly the opposite :
Il you want to allow time for the inverter to ramp up, you have to switch it first, and after sometime connect the requested motor...
 
Last edited:

hippy

Technical Support
Staff member
The FSM could look something like this -

Code:
Start7:
  Low FWD_MOTOR
  Low BWD_MOTOR
  state = STOPPED
  Do
    Select Case state
      Case STOPPED
        If desiredState = GO_FWD Then
          High FWD_MOTOR
          Pause 5000
          state = GO_FWD    
        ElIf desiredState = GO_BWD Then
          High BWD_MOTOR
          Pause 5000
          state = GO_BWD    
        End If
      
      Case GO_FWD
        If desiredState = STOPPED Then
          Low FWD_MOTOR
          Pause 5000
          state = STOPPED    
        ElIf desiredState = GO_BWD Then
          Low FWD_MOTOR
          Pause 5000
          High BWD_MOTOR
          Pause 5000
          state = GO_BWD   
        End If

      Case GO_BWD
        If desiredState = STOPPED Then
          Low BWD_MOTOR
          Pause 5000
          state = STOPPED    
        ElIf desiredState = GO_FWD Then
          Low BWD_MOTOR
          Pause 5000
          High FWD_MOTOR
          Pause 5000
          state = GO_FWD    
        End If

    End Select
    Pause 100
  Loop
That simply turns on and off the forward motors, waits 5 seconds for them to get up to speed or stop turning. The PAUSE can be replaced or added to with checks the turning has actually stopped.

In this example, if you are going forward ( state = GO_FWD ) and want to go reverse ( desiredState = GO_BWD ), the forward motor is turned off, it waits 5 seconds for it to stop, the backwards motor is turned on, waits 5 seconds for it to be up to speed, then moves into the GO_BWD state. That will then handle the next change of state.

The code could be improved so a change from stopped to forward can be aborted if a change to reverse is seen before the forward motor is up to speed.

Once you have the basics working all sorts of fanciness can be added to improve or optimise its behaviour but getting the basics working reliably and safely is key. Everything else simply builds on that.
 

JPB33

Senior Member
I've other machinery where the motor is connected to the inverter by a contactor then the inverter is activated (its already switched on) and ramps the motor up to speed, think I described it badly.

It is very dangerous to use a GOTO command within a subroutine. The RETURN command will never be reached, causing unpredictable behavour...
BESQUEUT Sorry i'm lost by that statement, be grateful if you can explain it?

HIPPY thanks for the code but it fails syntax with this message

Low FWD_MOTOR
^
Syntax error on line 2 at/before position 6

Error: This command requires the pin number in format PORT.PIN not PINx!


^
 

BESQUEUT

Senior Member
I've other machinery where the motor is connected to the inverter by a contactor then the inverter is activated (its already switched on) and ramps the motor up to speed, think I described it badly.
So B.2 starts the ramp process... am I right ?
Why is there a delay between Motor ON (B.0) and start ramp (B.2) ?

BESQUEUT Sorry i'm lost by that statement, be grateful if you can explain it?
Each time the Picaxe encounter a GOSUB, it push on the stack the address where it have to go when the RETURN is reached. At this time, this adress is popped and the stack unfilled.
If the RETURN is not reached, the address stay on the stack, till it become full...
At this point, olders return adress are losts...
As your program always return to Main, it's not a big problem, but it may be if you add others GOSUB in your program.
 
Last edited:

hippy

Technical Support
Staff member
You will have to define FWD_MOTOR as a symbol to a pin for controlling the motor along with BWD_MOTOR, and other constant names will need defining. You may need to modify for however you have things; it was was more an example of how rather than code to use.
 

lbenson

Senior Member
With regard to the code in post #5, I think the "goto main" doesn't fix the problem with mixing "gosub" and "goto". If you continue to do repeated "gosub" without doing a "return" for each, you will run out of stack space and your program will fail.

Something like this would do better:
Code:
FOR_WARD:
  pause 1000
  high B.0
  pause 1000
  if SwitchFor = 1 then
    high B.2
    do
    loop until SwitchFor = 0 
    low B.2
    pause 3000
  endif
  return
Every time you use a "gosub", you must exit the routine (sooner or later) with a "return" (unless you issue a "reset", which would reinitialize the stack counter--not recommended unless you have a specific need).
 

BESQUEUT

Senior Member
With regard to the code in post #5, I think the "goto main" doesn't fix the problem with mixing "gosub" and "goto". If you continue to do repeated "gosub" without doing a "return" for each, you will run out of stack space and your program will fail.
To be exact, the simulator will fail with a superb "Stack Overflow" message
Code:
[color=Navy]#Picaxe [/color][color=Black]O8M2
Main:
      [/color][color=Blue]inc [/color][color=Purple]b0
      [/color][color=Blue]sertxd([/color][color=Black]#[/color][color=Purple]b0[/color][color=Black], [/color][color=Red]" "[/color][color=Blue])
      gosub [/color][color=Black]SubRoutine[/color]
[color=Blue]goto [/color][color=Black]Main

SubRoutine:
      [/color][color=Blue]GOTO [/color][color=Black]Main
      [/color][color=Blue]RETURN[/color]
But a real Picaxe will survive ! (and a day or other do stranges things...)
as explained #11
 
Last edited:

JPB33

Senior Member
So B.2 starts the ramp process... am I right ?
Why is there a delay between Motor ON (B.0) and start ramp (B.2) ?
To allow the contactors time to come in also to allow for any operator error in case he changes his mind on direction the input state is checked again. and ramping the inverter can be aborted at that point and evrything returns to off.

I just ran #14 and I got it to 9 before it crashed? Just ran #5 and also got 9 before overflow if I aborted early so I see your point. Is there and easy way to monitor the stack overflow to see when it critical?

So return is safe and its only when the loop terminates early with a gosub?

Lots of learning for me---dont forget I'm only a novice with no programming background. I only know what I've learned with picaxe over the last few years so its been great! Thanks
 

BESQUEUT

Senior Member
So return is safe and its only when the loop terminates early with a gosub ?
If you are not using the GOTO command, you merely can not go out a subroutine without reaching the RETURN command...

So, my best advice (at least for a novice) is : DO NOT USE THE GOTO COMMAND
==> your code will be more readable,
==> the simulator will not crash with stack overflow,
==> real Picaxe will not have unpredictable behaviour...
 

lbenson

Senior Member
Is there and easy way to monitor the stack overflow to see when it critical?
The solution is not to "goto" out of a subroutine. You must write the code so that every "gosub" is matched with a "return" in the actual execution of the code. The easiest way to do this is to write your code so that you don't use "goto" at all. With the "block" commands like "do .. loop", "for ... next", and "gosub ... return" (and also "if"), this is not hard to do. It may take some consideration to get it right, but it will help you to avoid errors like the one you are encountering.
 

JPB33

Senior Member
Ok point taken. Replaced the goto in #5 with return and it runs fine and cannot make it crash with the stack overflow message.

In this instance its doing the same job?

Is that a safe fix?

Is there a way to monitor stack overflow with the program running or is it within the make up of the chip?

Thanks
 

BESQUEUT

Senior Member
Here is my contribution for a state machine:
Code:
[color=Navy]#Picaxe [/color][color=Black]20M2[/color]
[color=Navy]#No_Data    [/color]

[color=Blue]output B.0[/color][color=Black],[/color][color=Blue]B.1[/color][color=Black],[/color][color=Blue]B.2[/color][color=Black],[/color][color=Blue]B.3[/color][color=Black],[/color][color=Blue]B.4[/color][color=Black],[/color][color=Blue]B.5[/color][color=Black],[/color][color=Blue]B.6[/color][color=Black],[/color][color=Blue]B.7    
input C.0[/color][color=Black],[/color][color=Blue]C.1[/color][color=Black],[/color][color=Blue]C.2[/color][color=Black],[/color][color=Blue]C.3[/color][color=Black],[/color][color=Blue]C.4[/color][color=Black],[/color][color=Blue]C.5[/color][color=Black],[/color][color=Blue]C.6[/color][color=Black],[/color][color=Blue]C.7

Symbol [/color][color=Purple]SwitchFor [/color][color=DarkCyan]= [/color][color=Purple]pinC.0[/color]
[color=Blue]Symbol [/color][color=Purple]SwitchRev [/color][color=DarkCyan]= [/color][color=Purple]pinC.1[/color]

[color=Blue]Symbol Motor_Forward[/color][color=DarkCyan]=[/color][color=Blue]B.0
Symbol Motor_Backward[/color][color=DarkCyan]=[/color][color=Blue]B.1
Symbol Ramper[/color][color=DarkCyan]=[/color][color=Blue]B.2

Symbol Active[/color][color=DarkCyan]=[/color][color=Navy]1[/color]

[color=Blue]Symbol RelayDelay[/color][color=DarkCyan]=[/color][color=Navy]1 [/color][color=Green]'s[/color]
[color=Blue]Symbol RampDelay[/color][color=DarkCyan]=[/color][color=Navy]5 [/color][color=Green]'s[/color]
[color=Blue]Symbol RunningDelay[/color][color=DarkCyan]=[/color][color=Navy]20 [/color][color=Green]'s[/color]
[color=Blue]Symbol StoppingDelay[/color][color=DarkCyan]=[/color][color=Navy]6 [/color][color=Green]'s[/color]

[color=Blue]symbol [/color][color=Purple]Direction[/color][color=DarkCyan]=[/color][color=Purple]b1[/color]
[color=Blue]symbol UP[/color][color=DarkCyan]=[/color][color=Navy]1[/color]
[color=Blue]Symbol DOWN[/color][color=DarkCyan]=[/color][color=Navy]2[/color]

[color=Blue]Symbol [/color][color=Purple]State[/color][color=DarkCyan]=[/color][color=Purple]b2[/color]
[color=Blue]Symbol Stopped[/color][color=DarkCyan]=[/color][color=Navy]0[/color]
[color=Blue]Symbol BeforeRamp[/color][color=DarkCyan]=[/color][color=Navy]1[/color]
[color=Blue]Symbol Ramping[/color][color=DarkCyan]=[/color][color=Navy]2[/color]
[color=Blue]Symbol Running[/color][color=DarkCyan]=[/color][color=Navy]3[/color]
[color=Blue]symbol Stopping[/color][color=DarkCyan]=[/color][color=Navy]4[/color]
[color=Blue]symbol StopThenRamp[/color][color=DarkCyan]=[/color][color=Navy]5[/color]


[color=Black]Main:
      [/color][color=Blue]low B.0[/color][color=Black], [/color][color=Blue]B.1[/color][color=Black],[/color][color=Blue]B.2
      [/color][color=Purple]Direction[/color][color=DarkCyan]=[/color][color=Blue]Stopped
      [/color][color=Purple]State[/color][color=DarkCyan]=[/color][color=Blue]Stopped
      [/color][color=Purple]Time[/color][color=DarkCyan]=[/color][color=Navy]0
      [/color][color=Blue]do
            if [/color][color=Purple]SwitchFor[/color][color=DarkCyan]=[/color][color=Blue]Active then
                  if [/color][color=Purple]switchRev[/color][color=DarkCyan]=[/color][color=Blue]ON then [/color][color=Green]' Hey Dude ! What are you doing ?
                        [/color][color=Blue]GOSUB [/color][color=Black]GoStop
                  [/color][color=Blue]else
                        GOSUB [/color][color=Black]GoUP
                  [/color][color=Blue]endif
            else
                  if [/color][color=Purple]switchRev[/color][color=DarkCyan]=[/color][color=Blue]Active then
                        GOSUB [/color][color=Black]GoDOWN
                  [/color][color=Blue]else
                        GOSUB [/color][color=Black]GoStop
                  [/color][color=Blue]endif
            endif
            GOSUB [/color][color=Black]LookAtWatch
      [/color][color=Blue]loop
                  

                  [/color]

[color=Black]GoUP:
      [/color][color=Blue]select case [/color][color=Purple]Direction
      [/color][color=Blue]case Stopped
            high Motor_Forward
            [/color][color=Purple]state[/color][color=DarkCyan]=[/color][color=Blue]BeforeRamp [/color][color=Black]: [/color][color=Purple]Time[/color][color=DarkCyan]=[/color][color=Navy]0
      [/color][color=Blue]case DOWN
            low Motor_Backward
            [/color][color=Purple]state[/color][color=DarkCyan]=[/color][color=Blue]StopThenRamp [/color][color=Black]: [/color][color=Purple]Time[/color][color=DarkCyan]=[/color][color=Navy]0
      [/color][color=Blue]endselect
      [/color][color=Purple]Direction[/color][color=DarkCyan]=[/color][color=Blue]UP
      RETURN
      
      [/color]
[color=Black]GoDOWN:
      [/color][color=Blue]select case [/color][color=Purple]Direction
      [/color][color=Blue]case Stopped
            high Motor_Backward
            [/color][color=Purple]state[/color][color=DarkCyan]=[/color][color=Blue]BeforeRamp [/color][color=Black]: [/color][color=Purple]Time[/color][color=DarkCyan]=[/color][color=Navy]0
      [/color][color=Blue]case UP
            low Motor_Forward
            [/color][color=Purple]state[/color][color=DarkCyan]=[/color][color=Blue]StopThenRamp [/color][color=Black]: [/color][color=Purple]Time[/color][color=DarkCyan]=[/color][color=Navy]0
      [/color][color=Blue]endselect
      [/color][color=Purple]Direction[/color][color=DarkCyan]=[/color][color=Blue]DOWN
      RETURN
      [/color]
[color=Black]GoStop:
      [/color][color=Blue]low Motor_Forward[/color][color=Black],[/color][color=Blue]Motor_Backward[/color][color=Black],[/color][color=Blue]Ramper
      if [/color][color=Purple]Direction [/color][color=DarkCyan]<> [/color][color=Blue]Stopped then
            [/color][color=Purple]State[/color][color=DarkCyan]=[/color][color=Blue]Stopping [/color][color=Black]: [/color][color=Purple]Time[/color][color=DarkCyan]=[/color][color=Navy]0
      [/color][color=Blue]endif
      RETURN
      
      [/color]
[color=Black]LookAtWatch:
      [/color][color=Blue]select case [/color][color=Purple]State
      [/color][color=Blue]case BeforeRamp
            if [/color][color=Purple]Time[/color][color=DarkCyan]>[/color][color=Blue]RelayDelay then
                  high Ramper
                  [/color][color=Purple]State[/color][color=DarkCyan]=[/color][color=Blue]Ramping [/color][color=Black]: [/color][color=Purple]Time[/color][color=DarkCyan]=[/color][color=Navy]0
            [/color][color=Blue]endif 
      
      case Ramping
            if [/color][color=Purple]Time[/color][color=DarkCyan]>[/color][color=Blue]RampDelay then
                  [/color][color=Purple]State[/color][color=DarkCyan]=[/color][color=Blue]Running [/color][color=Black]: [/color][color=Purple]Time[/color][color=DarkCyan]=[/color][color=Navy]0
            [/color][color=Blue]endif
            
      case Running
            if [/color][color=Purple]Time[/color][color=DarkCyan]>[/color][color=Blue]RunningDelay then
                  low Motor_Forward[/color][color=Black],[/color][color=Blue]Motor_Backward[/color][color=Black],[/color][color=Blue]Ramper
                  [/color][color=Purple]State[/color][color=DarkCyan]=[/color][color=Blue]Stopping [/color][color=Black]: [/color][color=Purple]Time[/color][color=DarkCyan]=[/color][color=Navy]0
            [/color][color=Blue]endif
      
      case Stopping
            if [/color][color=Purple]Time[/color][color=DarkCyan]>[/color][color=Blue]StoppingDelay then
                  [/color][color=Purple]State[/color][color=DarkCyan]=[/color][color=Blue]Stopped
                  [/color][color=Purple]Direction[/color][color=DarkCyan]=[/color][color=Blue]Stopped
                  endif
      endselect[/color]
 

BESQUEUT

Senior Member
Ok point taken. Replaced the goto in #5 with return and it runs fine and cannot make it crash with the stack overflow message.

In this instance its doing the same job?

Is that a safe fix?
Probably, but please publish your code between
Code:
 ...[ /CODE] tags

[QUOTE="JPB33, post: 299163"]Is there a way to monitor stack overflow with the program running or is it within the make up of the chip?[/QUOTE]
No (and it depend from the Picaxe model...) The problem is inherent for all languages, and Picaxe BASIC of course.
With VB.NET 2010,  GOSUB is no longuer supported ...

VB6 will crash at first loop :
[CODE]
Private Sub Command1_Click()

Main:
    For i = 1 To 100
        Me.Caption = i
        DoEvents
        GoSub Toto
    Next i
    GoTo Fin
    
Toto:
    GoTo Main
    Return
    
Fin:
End Sub
 
Last edited:

JPB33

Senior Member
Thanks everyone for your comments. This is the latest version with all goto's eliminated--how safe is this one?

Code:
  #Picaxe 20M2
	#No_Data	
	
	output B.0,B.1,B.2,B.3,B.4,B.5,B.6,B.7	
	input  C.0,C.1,C.2,C.3,C.4,C.5,C.6,C.7
	
Symbol SwitchFor = pinC.0
Symbol SwitchRev = pinC.1


Main:
	do
	low B.0, B.1,B.2
	if SwitchFor = 1 then
Gosub FOR_WARD
	endif
	if SwitchRev = 1 then 
Gosub REV_ERSE	
	endif
	loop
	
FOR_WARD:
	pause 1000
	high B.0
	pause 1000
	if SwitchFor =0 then
	return
	endif
	high B.2
	do
	loop until SwitchFor = 0 
	low B.2
	pause 3000
	low B.0
	return
	
	
REV_ERSE:
	pause 1000
	high B.1
	pause 1000
	if SwitchRev = 0 then
	low B.1
	return
	endif
	high B.2
	do
	loop until SwitchRev = 0 
	low B.2
	pause 3000
	low B.1
	return
 

BESQUEUT

Senior Member
Thanks everyone for your comments. This is the latest version with all goto's eliminated--how safe is this one?

Code:
  #Picaxe 20M2
	#No_Data	
	
	output B.0,B.1,B.2,B.3,B.4,B.5,B.6,B.7	
	input  C.0,C.1,C.2,C.3,C.4,C.5,C.6,C.7
	
Symbol SwitchFor = pinC.0
Symbol SwitchRev = pinC.1


Main:
	do
	low B.0, B.1,B.2
	if SwitchFor = 1 then
Gosub FOR_WARD
	endif
	if SwitchRev = 1 then 
Gosub REV_ERSE	
	endif
	loop
	
FOR_WARD:
	pause 1000
	high B.0
	pause 1000
	if SwitchFor =0 then
	return
	endif
	high B.2
	do
	loop until SwitchFor = 0 
	low B.2
	pause 3000
	low B.0
	return
	
	
REV_ERSE:
	pause 1000
	high B.1
	pause 1000
	if SwitchRev = 0 then
	low B.1
	return
	endif
	high B.2
	do
	loop until SwitchRev = 0 
	low B.2
	pause 3000
	low B.1
	return
IMHO, this one is safe and do the job. BRAVO !
 

JPB33

Senior Member
Following on from the ealier postings now got the F&R switch working. Initially it was running on a 20m2 but realised I could use an 8m2 so converted the code and it works fine apart from earlier downloading issues which are now solved.

It runs fine in simulation also in the real world unless its in put into forward direction ie pin C.5 serial input high then powered up when it just flashes the o/p led. If C.5 is switched low and then high with the power on it works normally so it looks like I'm up setting something to do with C.5 serial input although I'm using disconnect?

Tried moving the disconnect command without success.

#Picaxe 08m2
#No_Data
Disconnect;
output C.0,C.1,C.2
input C.3,C.4,C.5

Symbol SwitchFor = pinC.5
Symbol SwitchRev = pinC.3
Symbol Inc_counter = b1
symbol Del_ay = b2



Main:

do
readadc C.4,Del_ay
low C.0, C.1,C.2
b1 = 0
if SwitchFor = 1 then
endif
pause 100
if switchfor=1 then
Gosub FOR_WARD
endif
if SwitchRev = 1 then
pause 100
endif
if switchRev=1 then
Gosub REV_ERSE
endif
loop

FOR_WARD:
pause 1000
high C.0
pause 1000
if SwitchFor =0 then
return
endif
high C.2
do
loop until SwitchFor = 0
low C.2
do
readadc C.4, Del_ay
Inc inc_counter
pause 20
loop until Inc_counter >= Del_ay
low C.0
b1 = 0
return


REV_ERSE:
pause 1000
high C.1
pause 1000
if SwitchRev = 0 then
low C.1
return
endif
high C.2
do
loop until SwitchRev = 0
low C.2
do
readadc C.4, Del_ay
Inc inc_counter
pause 20
loop until Inc_counter >= Del_ay
low C.1
b1 = 0
return
 

hippy

Technical Support
Staff member
C.5 ( Serial In ) must be kept low when the PICAXE is powered up or it will think there is a download being initiated and the program will not execute.
 
Top