Shop OBEX P1 Docs P2 Docs Learn Events
code issue — Parallax Forums

code issue

mikeamikea Posts: 283
edited 2012-06-02 07:17 in Propeller 1
I'm having a code problem. Everything works fine until it gets to the case section. It has executed the first case line to play wave file 0(it did so when i waived my hand in front of the ping ..not when it was at its limit of sight ), also it correctly executed the second line to play file 1 when my hand was within a foot, but it wont do either of these things consistently or any of the ones below them at all. The case is supposed to check the value of" range" from ping and play a file if it is in the correct inches range for each file. Does anything look wrong in the case statement? Thanks-mike
CON
  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000
  PING_Pin      = 16                                          ' I/O Pin For PING)))
                                       
  Distlimit     = 120                                          ' In inches
  
  do  = 0
  clk = 1
  di  = 2
  cs  = 3
  laudio = 11 ' -1 if unused.
  raudio = 10 ' -1 if unused.
  volume = 20 ' Default volume.
VAR
    long stack[100] 
  long  range
   long spinPlayerStack[100] 
OBJ
  Debug  : "FullDuplexSerial"
  ping   : "ping"
  wav    : "WAV-Player_DACEngine.spin"
PUB Start

  cognew(talker,@stack) 
  Debug.start(31,30,0,9600)
  waitcnt(clkfreq + cnt)
    
  repeat                                                ' Repeat Forever
    debug.str(string(1,"PING))) Demo ", 13, 13, "Inches = ", 13, "Centimeters = ", 13))
    debug.str(string(2,9,2))
    range := ping.Inches(PING_Pin)                      ' Get Range In Inches           
    debug.dec(range)
    debug.tx(11)
  {  debug.str(string(2,14,3))
    range := ping.Millimeters(PING_Pin)                 ' Get Range In Millimeters
    debug.dec(range / 10)                               ' Print Whole Part
    debug.tx(".")                                       ' Print Decimal Point
    debug.dec(range // 10)                              ' Print Fractional Part
    debug.tx(11)                                                                   }
    range := ping.Inches(PING_Pin)                      ' Get Range In Inches
  
 
  
pub talker
dira[6]~
  wav.FATEngineStart(do, clk, di, cs, -1, -1, -1, -1, -1)
  wav.DACEngineStart(laudio, raudio, volume)
  waitcnt(clkfreq*4+cnt)  
  if ina[6]==1
         wav.playWAVFile(@file12)              '"wanna play a game?"   ''change back to 12
         waitcnt(clkfreq*4+cnt)
  
    wav.playWAVFile(@file11)           ''''''''''''want me to guess how far away you are?    file 11
    waitcnt(clkfreq*4+cnt) 
    feet_guesser
pub feet_guesser              
  repeat
    case range
      range  >distlimit: wav.playWAVFile(@file0)           ''''''''''' come closer, i cant see you     file 0
                  waitcnt(clkfreq*4+cnt) 
      range >0 and range <24 : wav.playWAVFile(@file1)             '''''you are 1 foot away
                  waitcnt(clkfreq*4+cnt)
      range >12 and range <36 : wav.playWAVFile(@file2)             '''you are 2 feet away
                  waitcnt(clkfreq*4+cnt)
      range >24 and range <48 : wav.playWAVFile(@file3)             '''you are 3 feet away
                  waitcnt(clkfreq*4+cnt)
      range >36 and range <60 : wav.playWAVFile(@file4)             '''you are 4 feet away
                  waitcnt(clkfreq*4+cnt)
      range >48 and range <72 : wav.playWAVFile(@file5)             '''you are 5 feet away
                  waitcnt(clkfreq*4+cnt)
      range >60 and range <84 : wav.playWAVFile(@file6)             '''you are 6 feet away
                  waitcnt(clkfreq*4+cnt)
      range >72 and range <96 : wav.playWAVFile(@file7)             '''you are 7 feet away
                  waitcnt(clkfreq*4+cnt)
      range >84 and range <108 : wav.playWAVFile(@file8)             '''you are 8 feet away

Comments

  • BitsBits Posts: 414
    edited 2012-06-01 11:07
    Hum for some reason I cant read the code. Is it me (my browser) or you?
  • turbosupraturbosupra Posts: 1,088
    edited 2012-06-01 11:29
    Since you are waiting 4 seconds, use the PST

    Have it print which section of the code you are in at that time and have it print when it is outside of any cases and just in the general loop

    I'm not 100% on this, but I believe I also vaguely remember having issues with waitcnt when I coded like this
    waitcnt(clkfreq*4+cnt)

    instead I always write it this way now
    waitcnt((clkfreq*4)+cnt)

    I also write it as follows
    (range >0) and (range <24) : wav.playWAVFile(@file1) '''''you are 1 foot away
  • Cluso99Cluso99 Posts: 18,069
    edited 2012-06-01 12:45
    You have overlapping case ranges.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-06-01 12:57
    I'm pretty sure the case statments work like a long list of "elseif" statements. You only need to check for the less than condition and not the greater than condition since only the values greater than the previous tests will make that far in the list.

    I'lll give you an example from your first few conditions.


    Edit: This is junk code. See kuroneko's explanation below.

    pub feet_guesser              
      repeat
        case range
          range  >distlimit: wav.playWAVFile(@file0)           ''''''''''' come closer, i cant see you     file 0
                      waitcnt(clkfreq*4+cnt) 
          range <24 : wav.playWAVFile(@file1)             '''''you are 1 foot away
                      waitcnt(clkfreq*4+cnt)
          range <36 : wav.playWAVFile(@file2)             '''you are 2 feet away
                      waitcnt(clkfreq*4+cnt)
          range <48 : wav.playWAVFile(@file3)             '''you are 3 feet away
                      waitcnt(clkfreq*4+cnt)
          range <60 : wav.playWAVFile(@file4)             '''you are 4 feet away
    

    As Cluso99 mentioned, you have overlapping ranges. This really doesn't matter much (it just looks bad) since your code and the code I just posted should behave the same.

    You could move the first condition to the end and use "other". I think the code would have a more logical flow (to humans reading it) if you started testing for near items and moved the test distance away with each comparison. If you do start with the out of range test, then I'd keep move inward by tesing to see it the range is greater than a certain value.

    I agree with turbo's suggestion of adding debug statements. I fill my code with debug statements whenever I'm trying to figure out what it's doing.
  • kuronekokuroneko Posts: 3,623
    edited 2012-06-01 14:34
    Think about this for a moment:
    PUB null | range
    
      dira[16..23]~~
    
      range := 0
      case range
        range < 4: outa[16]~~
        other:     outa[23]~~
    
      waitpne(0, 0, 0)
    
    DAT
    
    The case expression is compared against each of the targets (top to bottom). So we have 0 as a case expression, the target is (range < 4) which is -1 (TRUE). This means the first case doesn't match (0 <> -1) and it falls through to other. If you use -1 you'll get a match ...

    In other words all you have are -1/0 (TRUE/FALSE) target expressions which - I assume - is not what you want.
  • mikeamikea Posts: 283
    edited 2012-06-01 21:17
    Not sure why its doing what it is. I've never used the serial terminal for problem solving, its a huge help. Also is there a way to attach code files mid-thread , so i can post them how they are displayed with the prop tool rather than copy/paste? I only see an option for that when starting a new thread. Thanks for the help-mike
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-06-01 21:28
    mikea wrote: »
    Also is there a way to attach code files mid-thread , so i can post them how they are displayed with the prop tool rather than copy/paste? I only see an option for that when starting a new thread.

    Use the "Go Advanced" button and then "Manage Attachements". You should then be able to upload files.
  • turbosupraturbosupra Posts: 1,088
    edited 2012-06-01 21:37
    Another thing you can do is attach the entire project as a zip file. In the prop tool (with the parent object open) go to file --> archive --> [parentobjectname] --> project and attach that as a zip file the way that Duane suggested.

    If you've never used the serial terminal for problem solving, you are in for a treat as it should really make your life easier if you start to.

    Kuroneko is like Hawkeye, he can spot a comparison error from a mile away, I can almost guarantee that it is doing whatever it shouldn't be doing because of what he commented about


    mikea wrote: »
    Not sure why its doing what it is. I've never used the serial terminal for problem solving, its a huge help. Also is there a way to attach code files mid-thread , so i can post them how they are displayed with the prop tool rather than copy/paste? I only see an option for that when starting a new thread. Thanks for the help-mike
  • Cluso99Cluso99 Posts: 18,069
    edited 2012-06-01 23:05
    There is another way to debug your code too. Use my 1pin TV (requires a composite monitor/TV and 1 prop pin and a series resistor 150R-1K) and the same style of debug statements except output to the TV.

    There are also debuggers such as
    PASD by Ariba
    Zero-Footprint debugger by Cluso99 (me) - its a bit complex to setup but can trace spin and pasm code.
    jazzed has done a debugger too (sorry, forget the name of it atm)
    Hanno has a commercial product (sorry, a real senior moment here - forget what he calls it to)
    And there are a couple of emulators as well.
  • kuronekokuroneko Posts: 3,623
    edited 2012-06-02 02:14
    Let's try this again:
    PUB null | range
    
      dira[16..23]~~
    
      range := 1
      case [COLOR="orange"]range[/COLOR]
        [COLOR="blue"]range > 0 and range < 24[/COLOR]: outa[16]~~
        other:                    outa[23]~~
    
      waitpne(0, 0, 0)
    
    DAT
    
    range (CaseExpression) is compared against range > 0 and range < 24 (MatchExpression). So on the left side we have 1, on the right side we have a boolean expression which evaluates to TRUE (1 > 0 and 1 < 24) which is the same as -1. However 1 is not equal -1 which is why the first case isn't selected. IOW for this specific case (range == 1) your case statement looks effectively like this:
    PUB null | range
    
      dira[16..23]~~
    
      range := 1
      case [COLOR="orange"]range[/COLOR]
        [COLOR="blue"]-1[/COLOR]:    outa[16]~~
        other: outa[23]~~
    
      waitpne(0, 0, 0)
    
    DAT
    
    If you want a case statement to be executed for the range between 0 and 24 (exclusive) then you should use something like this:
    PUB null | range
    
      dira[16..23]~~
    
      range := 1
      case [COLOR="orange"]range[/COLOR]
        [COLOR="blue"]1..23[/COLOR]: outa[16]~~       ' selected for range within 1 to 23 (inclusive, 0 < range < 24)
        other: outa[23]~~
    
      waitpne(0, 0, 0)
    
    DAT
    
  • mikeamikea Posts: 283
    edited 2012-06-02 04:56
    Kuroneko,I've changed the case match to the 1..23 and so forth as in your reply and it works now. It didn't sink in before i'm glad you "tried again" i think i get it now, thank you!!! Thanks you guys for the help i appreciate it.-mike
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-06-02 07:17
    kuroneko wrote: »
    Let's try this again:

    Thanks for the second attempt. Now it stuck in my brain too.

    I always use case the way you just describe but I didn't catch the problem in the original code or my changed version.

    Thanks again for helping me us see the light.
Sign In or Register to comment.