Shop OBEX P1 Docs P2 Docs Learn Events
Help with outa[ ] — Parallax Forums

Help with outa[ ]

mynet43mynet43 Posts: 644
edited 2013-11-04 06:26 in Propeller 1
I solved a problem with outa[ ]. But I don't know why my original solution didn't work.

Here's the sample code:
CON
  LIGHT_RELAY1 = 24

VAR
  long  light_type                 ' type of bulb being used

DAT
  light_case  long  0, %0100, %0011, %0100, %0111  ' truth table logic for each light case

PUB outa_test
  light_type := 4
  light_on_1        ' this program does NOT work, it sets the outa to zero
  light_on_2        ' this program works, it sets the outa to one
      
PRI light_on_1
  outa[LIGHT_RELAY1] := (light_case[light_type] & 4) >> 2                               

PRI light_on_2 | ix1
  ix1 := (light_case[light_type] & 4) >> 2
  outa[LIGHT_RELAY1] := ix1                              


Can someone help me understand why the first program doesn't work and the second one does work?

It looks to me like they should both be doing the same thing.

Thank you for your help.

Jim

Comments

  • Mike GMike G Posts: 2,702
    edited 2013-11-03 06:58
    First, the DIRA register must be set to an output.
    DIRA[LIGHT_RELAY1] := 1
    

    Second, when the program ends the main cog stops.
    CON
      _clkmode = xtal1 + pll16x     
      _xinfreq = 5_000_000
      LIGHT_RELAY1 = 24
    
    VAR
      long  light_type                 ' type of bulb being used
    
    DAT
      light_case  long  0, %0100, %0011, %0100, %0111  ' truth table logic for each light case
    
    PUB Main
      DIRA[LIGHT_RELAY1] := 1
      light_type := 4
      outa[LIGHT_RELAY1] := (light_case[light_type] & 4) >> 2 
      repeat
    
  • mynet43mynet43 Posts: 644
    edited 2013-11-03 09:40
    Hi Mike,

    My apologies for making greatly oversimplified sample code.

    In fact, I did initialize the dira[ ] for this pin. And the code is part of a large program that does not exit after this call.

    My whole point was to ask why one line of code didn't work:
    outa[LIGHT_RELAY1] := (light_case[light_type] & 4) >> 2

    Here's is a better example of code that should work.

    If you call routine outa_test_1, it does not set the pin.

    If you call routine outa_test_2, it DOES set the pin.

    I think they should be equivalent, but one works, the other doesn't.

    Thanks again for your help.

    Jim
    CON
      _clkmode = xtal1 + pll16x     
      _xinfreq = 5_000_000
      LIGHT_RELAY1 = 24
    
    VAR
      long  light_type                 ' type of bulb being used
    
    DAT
      light_case  long  0, %0100, %0011, %0100, %0111  ' truth table logic for each light case
      relay_pin   long  24, 5, 4    ' relay control pins for relays 1, 2, 3
    
    PUB outa_test_1 | i
    
      repeat i from 0 to 2
        outa[relay_pin[i]]~        ' set relay line to OFF
        dira[relay_pin[i]]~~       ' then set pin to output
        
      light_type := 4
      light_on_1        ' this program does NOT work, it sets the outa to zero
      repeat
    
    PUB outa_test_2 | i
    
      repeat i from 0 to 2
        outa[relay_pin[i]]~        ' set relay line to OFF
        dira[relay_pin[i]]~~       ' then set pin to output
        
      light_type := 4
      light_on_2        ' this program works, it sets the outa to one
      repeat
          
    PRI light_on_1
      outa[LIGHT_RELAY1] := (light_case[light_type] & 4) >> 2                               
    
    PRI light_on_2 | ix1
      ix1 := (light_case[light_type] & 4) >> 2
      outa[LIGHT_RELAY1] := ix1
    
    
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-11-03 12:23
    Can I ask a question? What were you trying to accomplish with the construction of the code? It seems to be working WAY too hard for such a simple task. That leads me to believe that there is more to this that is not revealed.

    Sometimes obvious is best:
    pub light_on(check)
    
      if (check & 4)  ' use binary value here for ease of reading -- forum code block won't display
        outa[LIGHT_RELAY1] := 1
      else
        outa[LIGHT_RELAY1] := 0
    
      dira[LIGHT_RELAY1] := 1
    


    Once you get things working, then start on code optimization. My friend, Peter, constantly reminds me: don't optimize early. Get it working, first.
  • mynet43mynet43 Posts: 644
    edited 2013-11-03 14:32
    Hi Jonny,

    Thanks for asking. The real code is controlling three solid state relays to turn on different combinations of high powered spotlights, up to 28V @ 16A.

    The earlier example was just trying to simplify the question.

    Here's the actual routine in question, before and after the code fix:

    Before code. This one did NOT work for LIGHT_RELAY_1:
    PRI light_on
        outa[LIGHT_RELAY1] := (light_case[light_type] & 4) >> 2                               
        outa[LIGHT_RELAY2] := (light_case[light_type] & 2) >> 1
        outa[LIGHT_RELAY3] :=  light_case[light_type] & 1   
    

    After. This one works fine for all of them:
    PRI light_on | ix1, ix2, ix3
      ix1 := (light_case[light_type] & 4) >> 2
      ix2 := (light_case[light_type] & 2) >> 1
      ix3 :=  light_case[light_type] & 1
    
      ' set each relay to the correct logic for the bulb 
      outa[LIGHT_RELAY1] := ix1                              
      outa[LIGHT_RELAY2] := ix2
      outa[LIGHT_RELAY3] := ix3
    

    Still looking for the answer...

    Thanks,

    Jim
  • Mike GMike G Posts: 2,702
    edited 2013-11-03 14:49
    mynet43 wrote:
    My whole point was to ask why one line of code didn't work:
    outa[LIGHT_RELAY1] := (light_case[light_type] & 4) >> 2
    Post #3 explicitly tests this situation.

    The logic error is probably elsewhere in the code base...

    Maybe post all your code?
  • kuronekokuroneko Posts: 3,623
    edited 2013-11-03 14:53
    mynet43 wrote: »
    My whole point was to ask why one line of code didn't work:
    outa[LIGHT_RELAY1] := (light_case[light_type] & 4) >> 2
    FWIW, this works perfectly over here although I use different pins (16..18). Which suggests that something else is going wrong in other parts of your program.
  • mynet43mynet43 Posts: 644
    edited 2013-11-03 15:20
    OK, thank you all.

    I guess I answered my own question. :)

    I'll go back and look again and post if I can't find the problem.

    Now I'm really curious.

    Thanks!

    Jim
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-11-03 15:29
    You can simplify your expressions:
    pri light_on
      outa[LIGHT_RELAY1] := light_case[light_type] >> 2
      outa[LIGHT_RELAY2] := light_case[light_type] >> 1
      outa[LIGHT_RELAY3] := light_case[light_type]
    


    This works because your output is a single bit, hence only the LSB of the expression is used.
  • mynet43mynet43 Posts: 644
    edited 2013-11-03 17:21
    Jonny,

    Are you saying the outa[ ] := var depends only on the state of bit 0 of var?

    I didn't know that and it doesn't appear to be in the manual.

    So if I set outa[24] := 6, it will set P24 to zero. Is that correct?

    If so, it seems like the manual should state that.

    Please let me know.

    Thanks!

    Jim
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-11-03 18:02
    Are you saying the outa[ ] := var depends only on the state of bit 0 of var?

    Only if there is ONE bit specified in the outa parameter field -- as is the case in your program.
    So if I set outa[24] := 6, it will set P24 to zero. Is that correct?

    Yes.
    If so, it seems like the manual should state that.

    Page 177, just below the middle of the page (manual 1.2):

    Here, DIRA bits 8 through 12 are set to high (like before) but OUTA bits 8, 9, 10, 11 and 12 are set equal to 1, 1, 0, 0, and 1, respectively, making P8, P9 and P12 output high and P10 and P11 output low.
  • mynet43mynet43 Posts: 644
    edited 2013-11-03 19:30
    Jonny,

    I was referring only to the single pin, outa[24] case.

    The reference you gave in the manual is for the multiple pin case.

    Is there something in the manual that refers to what you said about the single pin case? Or do you just know it from experience, which is fine?

    I just want to be sure this is a general case.

    Thank you for your help.

    Jim
  • JonnyMacJonnyMac Posts: 9,107
    edited 2013-11-03 21:51
    Is there something in the manual that refers to what you said about the single pin case?

    That statement in the manual explains how the bits work -- from the LSB end -- and applies to any number of bits which can in fact be from 1 to 32. You're going to be very unhappy if you expect every possible combination to be spelled out for you.
  • mynet43mynet43 Posts: 644
    edited 2013-11-04 06:26
    Hi Jonny,

    Sorry, I wasn't trying to pin you down. I appreciate your help and support.

    I'm very happy to be doing what I love to do.

    Thanks again,

    Jim
Sign In or Register to comment.