Shop OBEX P1 Docs P2 Docs Learn Events
Three questions about CASE logic — Parallax Forums

Three questions about CASE logic

SteveWoodroughSteveWoodrough Posts: 190
edited 2012-12-18 16:28 in Propeller 1
The last few days I’ve been experimenting with CASE logic, and learned a few lessons.

Three questions:
1) How do I describe a CASE where both Ina[pinA] and Ina[pinB] are high? AND / OR do not seem to work. As I RTFM it looks like I need to add conditions together as variable names to determine the logic table. Is there a way to simply compare or add the input addresses?
2) Completely by accident I got the code below to work. I was playing with the CASE logic and decided to start a cog based on certain input pin being pressed. Using the traditional method to stop a cog would give really bizarre results. Rarely the code would work, mostly it would fail, and sometimes the program running in Cog 0 would be shut down if I stopped a cog with:
PUB StopBlink   '                                 
    if BlinkCog
       cogstop(BlinkCog~ -1)                          'Stop previously launched cog


I had to use:
PUB StopBlink   '                                 
    if BlinkCog
       cogstop(BlinkCog)                               'Stop previously launched cog


Any ideas on why that is the case? (pardon the pun)


What exactly (in English) is this code below saying? I’ve read why it should be done, but I have never really understood exactly what is being said.

3)
    if BlinkCog
       cogstop(BlinkCog~ -1)         


Here is the meat of the experiment in its successful form:
CON
        _clkmode = xtal1 + pll16x                                               'Standard clock mode * crystal frequency = 80 MHz
        _xinfreq = 5_000_000

VAR
  long BlinkStack[100]
  byte BlinkCog

  long X
OBJ
  
  
PUB Main

   LEDCase(10,24)


Pub LEDCase(pinA,pinB)  
 dira[16..23]~~

repeat


  waitcnt(clkfreq/5+cnt)                                'I set the scan rate so that it's fast, but not
                                                        'faster than the blink rate of the LED
                                                                                                                

        Case Ina[pinA] 
              1  : Outa[23]~~                           'If the input is HIGH, then the LED is HIGH
              0  : Outa[23]~                            'If the input is LOW, then the LED is LOW
        Case Ina[pinB]
              1  :                                      'If INA Pin B is HIGH
                    X:= 0                               'Reset X to zero, X is used to determine a single instance of the
                                                        'CASE given below.
                   Outa[16]~~                           'If the input is HIGH, then the LED is HIGH  
                   StopBlink
                                                    
              0  :                                      'If INA Pin B is LOW

                   X:=X++                               'Post increment X
                   if X:=1                              'On the first cycle, start a cog
                    StartBlink(20)                      'Blink LED
        
               Outa[16]~                                                   'Set the output to the LED low.  

    
Pub Blink(pin)
   dira[pin]~~  

repeat 
    waitcnt (clkfreq/17 + cnt)                          
    ! outa[pin]
  
PUB StartBlink(pin)                                       'Starts Cruise Control
 StopBlink                                          'Prevent multiple starts
 BlinkCog := cognew(Blink(pin), @BlinkStack)   'Launch method in separate COG

PUB StopBlink   '                                 
    if BlinkCog
       cogstop(BlinkCog)'~ -1)                          'Stop previously launched cog



Thank You! Steve

Comments

  • T ChapT Chap Posts: 4,223
    edited 2012-12-17 18:52
    Are pina and pinb next to each other?
    Case ina[ pina..Pinb ] 
           %11 :  dosomething
    

    I haven't tested this.

    If the pins are not consecutive, you could construct a variable first

    Pinvar := ina[ pina ] << 1
    pinvar := ina[ pina ] + ina[ pinb ]

    Case pinvar

    I am sure there is a better way though with less code, this shows a concept in long form.
  • SteveWoodroughSteveWoodrough Posts: 190
    edited 2012-12-17 19:04
    I thought about the bitwise form as I was drafting the question. I suppose it would work, and I need to evaluate. I do not have a specific application, I was just trying to sharpen my understanding of the CASE logic syntax.

    Regards,
    Steve
  • JonnyMacJonnyMac Posts: 9,108
    edited 2012-12-17 19:29
    This code is a little over-wrought:
    Case Ina[pinA] 
                  1  : Outa[23]~~                           'If the input is HIGH, then the LED is HIGH
                  0  : Outa[23]~                            'If the input is LOW, then the LED is LOW
    


    I believe a more elegant approach is just one line:
    outa[23] := ina[pina]
    


    BTW... I'd also suggest using a named constant in place of '23' -- magic numbers in code like this are not terribly meaningful when it comes to function. Better you do something like this:
    outa[LED] := ina[LED_CTRL]
    
  • SteveWoodroughSteveWoodrough Posts: 190
    edited 2012-12-18 14:19
    Jon,
    Points taken, thank you. My main reason for doing this exercise is to develop a better understanding of the CASE logic structure.

    What really puzzles me is the way I had to stop the cogs. I could not use the typical:
    PUB StopBlink   '                                 
        if BlinkCog
           cogstop(BlinkCog~ -1)                          'Stop previously launched cog
    
    

    The only way the program would work was using the cog stop method below.
    PUB StopBlink   '                                 
        if BlinkCog
           cogstop(BlinkCog)                               'Stop previously launched cog
    	
    

    Why would the traditional cog stopping method not work?

    Regards,
    Steve
  • kuronekokuroneko Posts: 3,623
    edited 2012-12-18 15:43
    That's because your stop sequence doesn't match the start sequence. The latter returns/stores the result of cognew (-1..7) while the former (typical) expects (0..8). This is achieved by adding 1 to the cognew result which gives 0 for failure (FALSE) and non-zero (cogid+1) for success (equivalent to TRUE). Global variables are initialised to 0, IOW if you call StopBlink it does nothing. Then StartBlink will (usually) set BlinkCog to 1..8 (unless it fails) which requires an additional +1 in said method.
  • SteveWoodroughSteveWoodrough Posts: 190
    edited 2012-12-18 16:28
    THANK YOU! I see the error of my ways. I never added 1 to the cognew value. That's what I get for coping the wrong sample from the book.

    Regards,
    Steve
Sign In or Register to comment.