Shop OBEX P1 Docs P2 Docs Learn Events
My Spin Logic is not Logical? — Parallax Forums

My Spin Logic is not Logical?

garyggaryg Posts: 420
edited 2013-12-27 20:22 in Propeller 1
Hi
I'm attempting to program my Prop-Mini.
pub RCinput should be able to make a decision as to what subroutine I want to go to.
What appears to be happening, is that Qaitpeq seems to be working.
The current drawn by the prop and key fob remote is about 21ma before any button press on the key fob remote.
When I press any button on the keyfob remote, it seems that the program drops through and goes to TurnLeft.
Program appears to be ignoring my IF INA statements and going directly to the TurnLeft subroutine.
I've been looking at programs in the OBEX and any message threads I could find for a number of hours now
in an attempt at finding an example that was similar in some manner to my program, but could not find anything
enlightening.
I've gone over the IF, ELSIF section of the Propeller Manual v1.2 and feel like there is something very basic that
I'm not understanding.

When I copied and Pasted my code using the
thing, I don't appear to get that grey box that I usually see.
My program is pretty wordy, I'm hoping that someone can give suggestions on where I'm going wrong.


Thanks in advance for any comments, help etc.
Garyg

[code] pub RCinput
' WAITPEQ, "Wait for Pin(s) to Equal" Reduce power consumption by 7/8 while waiting
' "|< Pin" is called Bitwise Decode Operator.
' Waitpeq (|<15, |<15, 0) The 0 is the port which on Propeller1 is always 0
' Pin 15 is the Key Fob Remote VT input, It goes high when any remote button is pressed.
Waitpeq (|<15, |<15, 0) 'I should be able to pause program execution
'until A,B,C or D is selected on the
'Keychain fob. 
'Program always goes to left turn signal.
'I put this waitcnt delay in there in case there are
'unstable outputs from the Key Fob Remote receiver.
'Maybe the output is unstable for the 1st second or two, while the
'Prop-mini is waking up.
waitcnt (60_000_000 + cnt) 
'Now I need to check which input is actually active and send the result to
'the proper turn signal direction.
If INA[11]:=1 
TurnLeft
If INA[12]:=1 
TurnRight
If INA[13]:=1
AutoArmSignal
else
RCinput
'If none of the buttons on the Keychain Fob have been pressed the program
'should return back to the RCinput beginning and put the PropMini back
'into power conserve mode. 
RCinput

pub TurnLeft
'What needs to be resolved here in the TurnLeft subroutine is that
'I need to check for a different button press on the Key Fob Remote and
'Either GOTO TurnRight or turn all LEDs off and return back to RCinput
counter :=0
repeat counter from 0 to 31
!outa[0] 'Left LED
!outa[1] 'Center LED

'The drop out of the repeat counter is only checked
'after the outputs toggle. This may work out ok, maybe.
' if INA[12]:=1
' TurnRight
' if INA[14]:=1
' Cancel
waitcnt (30_000_000 + cnt)
outa[0] :=0
outa[1] :=0
RCinput

Pub TurnRight
'What needs to be resolved here in the TurnRight subroutine is that
'I need to check for a different button press on the Key Fob Remote and
'Either GOTO TurnLeft or turn all LEDs off and return back to RCinput
counter :=0
repeat counter from 0 to 31
!outa[2] 'Right LED
!outa[1] 'Center LED
' if INA[11]:=1
' TurnLeft
' if INA[14]:=1
' Cancel 
waitcnt (30_000_000 + cnt)
outa[2]:=0
outa[1]:=0
RCinput
PUB AutoArmSignal
'This subroutine is reserved for when I attempt to use Tilt Switches
'Mounted in the jacket sleeve to operate the directionals.
'The repeat looks for Low on Key Fob Remote VT. then returns to RCinput.
repeat
repeat until INA[15]:=0
RCinput 
Pub Cancel
'Turn off all LEDs, pause a bit to allow time for Key Fob Remote button
'to be released, then return to RCinput.
Outa[0] :=0
Outa[1] :=0
Outa[2] :=0
repeat
repeat until INA[15]:=0
Waitcnt (30_000_000 + cnt)
RCinput 

Comments

  • T ChapT Chap Posts: 4,223
    edited 2013-12-23 21:32
    Instead of using \code use /code at the bottom of the code.

    If you want to check to see what a pin state is, use ==, not :=

    := is to SET a pin to a state. == is to read the state.


    if INA[11] == 1 NOT if INA[11]:=1

    repeat until INA[15] == 0 NOT repeat until INA[15 ]:= 0


    outa[0] :=0
    outa[1] :=0

    To use this code setting the outputs 0 and 1 to 0, make sure that somewhere else in the same COG you have established the pins as outputs using the format DIRA[0] := 1

    You can also set a group of pins like this DIRA[0..1]~~
  • kuronekokuroneko Posts: 3,623
    edited 2013-12-23 21:39
    Apart from the comparison/assignment issue, SPIN function calls are of the GOSUB nature (not GOTO), which means that if you (blindly) call a function from within itself you will run out of stack at some point. If you need an endless loop simply wrap everything under a repeat statement.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-12-23 22:01
    The suggestions given so far should go a long way in helping getting your program working.

    Make sure not to wait too long before asking for help again.
  • garyggaryg Posts: 420
    edited 2013-12-23 23:17
    Thanks.
    T CHAP - I followed all of your suggestions.
    My system is now working correctly and
    In case you didn't notice, I now have the grey code box with properly displayed code.

    kuroneko - While I really don't understand about running out of stack space, I will attempt to wrap
    my RCinput subroutine in a repeat statement.
    I'm thinking that what you are telling me is that I should not tell the RCinput program to return to it's beginning by
    just typing RCinput at the bottom of that subroutine.

    Duane - I always like attempting to find the answers myself if I can.
    If I'm not able to succeed in that endevor, I ask in the forum.
    After asking in the forum, within a few hours or minutes, I always have the answer or am pointed in the correct direction.


    I've attached my latest revisions below.
    While my notes need lots of cleaning up and the program needs to be developed further
    it may help someone in some manner.
    BLINKER - 7th TRY.spin
    Thanks again
  • T ChapT Chap Posts: 4,223
    edited 2013-12-24 04:55
    Glad you are making progress. It is a good practice to use indention to space all code under CON, OBJ, VAR, etc over to the right so that you can better see the flow of things. SPIN uses indention as part of the programming method. For example, the first repeat below will lock the code up at that point and never proceed.

          Repeat
          Repeat while ina[0] == 1    '  this line will never even be ran
    


    In this code, both repeats will function
        Repeat
          Repeat while ina[1] == 1
          'do other stuff
    
    


    In your code above,
    If INA[11]:=1 
    TurnLeft
    
    

    The TurnLeft method will ALWAYS run, since it is not indented at least one space to the right under If Ina[11]:=1



    EDIT: I looked at the file you uploaded and at a glance it appears you have corrected the indention.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-12-24 11:49
    Garyg,

    You've still got a serious problem with your code.

    You're still treating method calls like "GOTO" statements rather than "GOSUB" statements.

    For example when call "TurnLeft" the code will eventually return to the line after the call (if the "TurnLeft" method were ever allowed to finish (as it is now, "TurnLeft" never returns flow back to the original location in code)).

    You need to remove all the "RCinput" calls at the end of you methods (with the exception of Main). Your program won't work for very long the way it's currently written.

    Instead of the "RCinput" call at the end of your methods, you need to make RCinput into a continuous loop with a repeat statement (as kuroneko mentioned earlier).

    I'm very willing to fix these errors if you'd like me to but I'm sure you'd rather give a go yourself first.

    I'll start you out with a hint.

    Remove the "RCinput" calls from the end of all your methods except "main" and modify "RCinput" like this:
    pub RCinput
    
    ' WAITPEQ, "Wait for Pin(s) to Equal" Reduce power consumption by 7/8 while waiting
    ' "|< Pin" is called Bitwise Decode Operator.
    ' Waitpeq (|<15, |<15, 0) The 0 is the port which on Propeller1 is always 0
    ' Pin 15 is the Key Fob Remote VT input, It goes high when any remote button is pressed.
      repeat
        Waitpeq (|<15, |<15, 0)          'I should be able to pause program execution
                                         'until A,B,C or D is selected on the
                                          'Keychain fob.    
    
    
    'Program always goes to left turn signal.
    'I put this waitcnt delay in there in case there are
    'unstable outputs from the Key Fob Remote receiver.
    'Maybe the output is unstable for the 1st second or two, while the
    'Prop-mini is waking up.
    'waitcnt (60_000_000 + cnt)         
    'Now I need to check which input is actually active and send the result to
    'the proper turn signal direction.
        If INA[11]==1 
          TurnLeft
        If INA[12]==1 
          TurnRight
        If INA[13]==1
          AutoArmSignal
        'else
          'RCinput
    
    
    'If none of the buttons on the Keychain Fob have been pressed the program
    'should return back to the RCinput beginning and put the PropMini back
    'into power conserve mode.            
    
    
      'RCinput
    
  • garyggaryg Posts: 420
    edited 2013-12-24 12:56
    T Chap
    I was able to correct the indention.
    Thanks for your explinations.
    Program is running pretty good, except for one glitch.
  • garyggaryg Posts: 420
    edited 2013-12-24 13:04
    Duane Degn wrote: »
    Garyg,

    You've still got a serious problem with your code.

    You're still treating method calls like "GOTO" statements rather than "GOSUB" statements.

    Thanks Duane
    I'm thinking that you are saying the same thing that was mentioned earlier about possibly running out of Stack Space.
    I noticed that after about 15 or 20 button presses while testing, the program would just quit working.
    I would power down, then power up to reset and it would work again.
    I'll definitely look into what you are talking about in that I'm using method calls like "GOTO" statements rather than "GOSUB" statements.
    Over the next few days, I should be able to get some time to try fixing that.
  • garyggaryg Posts: 420
    edited 2013-12-26 18:14
    Hi
    I found a few hours to research more on all of the suggestions offered on this message thread.
    I updated my program to reflect all of your suggestions.

    I've loaded and tested the program on my Prop-Mini and it works pretty good.
    The only thing that is not quite as smooth as I would like it, has to do with getting very
    button happy on my remote, changing from left to right and back again with very quick button jabs on the remote
    will occasionally cause ambiguous display LEDs to stay on.
    Pressing any button again, for just a bit longer corrects this problem and everyting goes back to normal.

    I would really appreciate someone looking over my revised program to see if I'm correctly following the
    spin programming.

    I'll attempt to attach my code here BLINKER - 8th TRY.spin

    and I'll attempt to use the code brackets thing below
    '' =================================================================================================
    ''
    ''   File....... BLINKER - 8th TRY
    ''   Purpose.... Simple program using minimum current to drive bicycle directionals.
    ''   Author..... Gary Garski                   Jon "JonnyMac" McPhalen
    ''               I'm using JonnyMac            Copyright (c) 2013 Jon McPhalen
    ''               Simple Spin                   -- see below for terms of use
    ''               Edited by me to work for me.  E-mail..... [EMAIL="jon@jonmcphalen.com"]jon@jonmcphalen.com[/EMAIL]
    ''   Started.... 10-25-13
    ''   Updated.... 12-26-13
    ''
    '' I'm trying WaitPEQ statement from Spin Language Quick Reference.
    '' On 12-26-13, I'm making corrections to the Methods "subdirectories" and
    '' make my notes match this 8th Try.
    '' 
    
    '' =========12-22-13===============================================================================
    '' I have 7th TRY loaded on the Propeller Mini. 
    '' This is the physical layout for the Blinker circuitry.
    '' Layout of Propeller Mini
    '' P11  Input to prop from Key Fob Remote D1 button A , Left blink
    '' P12  Input to prop from Key Fob Remote D2 button B , right blink
    '' P13  Input to prop from Key Fob Remote D3 button C , AutoArm
    '' P14  Input to prop from Key Fob Remote D4 button D , Cancel
    '' P15  Input to prop from Key Fob Remote VT goes high when pressing any button
    '' P17  Input to Prop from upper arm tilt switch
    '' P18  Input to Prop from For arm tilt switch
    ''
    '' PO   Output from prop to mosfet gate -Left arrow LEDs
    '' P1   Output from prop to mosfet gate -Arrow Shaft LEDs
    '' P2   Output from prop to mosfet gate -Right Arrow LEDs
    '' P16  Output from prop to mosfet gate -Power the hand signal switches.
    '' =================================================================================================               
    '' On 12-26-13, I checked the syntax using the RUN, COMPILE CURRENT, VIEW INFO
    '' After correcting a few syntax problems, it appears that there are no errors.
    '' Loaded it on Prop-Mini
    '' I posted a thread concerning my problems on the Parallax forum
    '' #1
    '' I did not understand the meaning of := and ==
    '' := is used to set a pin to a state.
    '' == is used to read the state of a pin.
    '' #2
    '' I need to be very careful of intentations when writing the program.
    ''
    '' #3
    '' It's not a good idea to call a function from within itself,
    '' An example would be to place RCinput as the last statement in
    '' the RCinput method.
     
    con
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000                                          ' use 5MHz crystal
      CLK_FREQ = ((_clkmode - xtal1) >> 6) * _xinfreq               ' system freq as a constant
      MS_001   = CLK_FREQ / 1_000                                   ' ticks in 1ms
      US_001   = CLK_FREQ / 1_000_000                               ' ticks in 1us
    con
     
    var
     word counter
    pub main 
        
      waitcnt (3_000_000 + cnt)            'pause(10)   pause (10) was the original jonnymac statement.
     
     
    ' Make pins 11,12,13  and 14 input
    ' Pin 11,D1 will be left turn, pin 12,D2 will be right turn.
    dira[11] := 0
    dira[12] := 0
    dira[13] := 0
    dira[14] := 0
    ' Make pins 0,1 and 2 output and set them low P0 isleft, P1 iscenter, P2 isright
    outa[0] := 0
    outa[1] := 0
    outa[2] := 0
    dira[0] := 1
    dira[1] := 1
    dira[2] := 1 
    RCinput
    pub RCinput
    ' WAITPEQ, "Wait for Pin(s) to Equal" Reduce power consumption by 7/8 while waiting
    ' "|< Pin" is called Bitwise Decode Operator.
    ' Waitpeq (|<15, |<15, 0) The 0 is the port which on Propeller1 is always 0
    ' Pin 15 is the Key Fob Remote VT input, It goes high when any remote button is pressed.
     Repeat
       Waitpeq (|<15, |<15, 0)          'I should be able to pause program execution
                                         'until A,B,C or D is selected on the
                                          'Keychain fob.    
    '  Now I need to check which input is actually active and send the result to
    '  the proper turn signal direction.
       If INA[11]==1 
         TurnLeft
       If INA[12]==1 
         TurnRight
       If INA[13]==1
         AutoArmSignal
       If INA[14]==1
         Cancel 
     
    'If none of the buttons on the Keychain Fob are currently pressed,
    'The program should return back to the RCinput "Repeat" instruction
    'and put the PropMini back into power conserve mode.            
    'It's not a good idea to call a Method "subroutine" from within the Method "subroutine"
    'Using Repeat as in this RCinput method                                                   
    pub TurnLeft
    'This Method "subroutine" Flashes the Left arrow and arrow shaft for
    'about 25 Seconds.
    'While the Left signal flashes, If I switch to Right turn or Cancel
    'the program will go to those subroutines.
    
    counter :=0
    outa[0..2]:=0
     repeat counter from 0 to 61
       !outa[0]              'Left LED
       !outa[1]              'Center LED
    
        'The drop out of the repeat counter is only checked
        'after the outputs toggle.  This appears to work out OK.
       if INA[12]==1
         return       'TurnRight
       if INA[14]==1
         return        'Cancel
       waitcnt (30_000_000 + cnt)
     outa[0] :=0
     outa[1] :=0
    'If the program runs to the end of this method, it should return to the
    'RCinput method because the RCinput method is running in a continuous loop.
    'When a method is done running, the program goes back to the method that called it.
      
    Pub TurnRight
    'This Method "subroutine" Flashes the Right Arrow and Arrow Shaft for
    'about 25 Seconds.
    'While the Left signal flashes, If I switch to Right turn or Cancel
    'the program will go to those subroutines.
    counter :=0
    outa[0..2]:=0      
     repeat counter from 0 to 61
       !outa[2]              'Right LED
       !outa[1]              'Center LED
       if INA[11]==1
        return               'TurnLeft
       if INA[14]==1
        return                'Cancel  
       waitcnt (30_000_000 + cnt)
    outa[2]:=0
    outa[1]:=0
    PUB AutoArmSignal
    'This subroutine is reserved for when I attempt to use Tilt Switches
    'Mounted in the jacket sleeve to operate the directionals.
    'The repeat looks for Low on Key Fob Remote VT. then returns to RCinput.
    repeat until INA[15]==0
      
    Pub Cancel
    'Turn off all LEDs, pause a bit to allow time for Key Fob Remote button
    'to be released, then return to RCinput.
    Outa[0..2] :=0
    repeat until INA[15]==0
    Waitcnt (30_000_000 + cnt)
       
    

    Thanks for all your help
    I feel like I'm learning something.
    Gary
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-12-27 20:22
    garyg wrote: »
    I would really appreciate someone looking over my revised program to see if I'm correctly following the
    spin programming.

    It looks good to me.

    There are several formatting issues but these don't effect the function of the program, just it's readability.

    As T Chap mentioned previously:
    T Chap wrote: »
    Glad you are making progress. It is a good practice to use indention to space all code under CON, OBJ, VAR, etc over to the right so that you can better see the flow of things.

    Adding indentations when they're not required can make code more confusing.

    Here's the way I'd indent the "LeftTurn" method (I removed most of the comments to make the indentation easier to see).
    pub TurnLeft
    
      counter :=0
      outa[0..2]:=0
      repeat counter from 0 to 61
        !outa[0]              'Left LED
        !outa[1]              'Center LED
    
    
        if INA[12]==1
          return    
        if INA[14]==1
          return      
        waitcnt (30_000_000 + cnt)
      outa[0] :=0
      outa[1] :=0
    
    
    

    There are a few things I'm not clear about.

    I just looked at the code again. I don't think you're exiting the method the way you intend to. For example in the "LeftTurn" method your "return" statements don't turn off any LEDs which may be on. If you change your "return" statements to "quit" then the loop will end and take care of the end of method housekeeping before returning to the "RCinput" main loop. I think your program would behave more like you expect it to if you replace all the "return" statements with "quit". I think this should clear up the trouble you're having when multiple buttons are pressed one after another.
Sign In or Register to comment.