Shop OBEX P1 Docs P2 Docs Learn Events
repeat until i==1023 works, but repeat until i==1024 or false does not in Serial Terminal — Parallax Forums

repeat until i==1023 works, but repeat until i==1024 or false does not in Serial Terminal

zepperikzepperik Posts: 16
edited 2015-09-17 19:20 in Propeller 1
I've got a cog listeningto the Parallax Serial Terminal object. I am sending 1024 bytes to it to construct a waveform. I've been struggling to get it to timeout if for whatever reason all 1024 bytes aren't sent. I've added " or (cnt-t>TIME_OUT) " to CharIn which seems to work fine. (Yes I know about RxTime in FullDuplexSerial). But now that I've got the repeat loop within CharIn timing out correctly, I need the loop within my function to timeout so that I can set i to 0 again.

I've replaced my timeout condition "or (cnt-t>TIME_OUT)" with "or false" and it still changes the behavior. This code works correctly if "or false" is not present. Any idea how that addition could possibly change the behavior?
PUB Listener | i
  repeat
    i:=0
    repeat until i==1023 or false
        byte[@Waveform+i]:=Pst.CharIn
        i++ 
    ConstructOutput(@Waveform)

I have increased MAXSTR_LENGTH in case you were wondering.

Comments

  • Sounds like a stack overflow. Did you try making that cog's stack bigger?
  • AleAle Posts: 2,363
    what about the precedence of == and or ?...
    just another question, what does "or false" do there ?
  • Sounds like a stack overflow. Did you try making that cog's stack bigger?

    I did. Its at 2000 longs.
    Ale wrote: »
    what about the precedence of == and or ?...
    just another question, what does "or false" do there ?

    I started with a code similar to RxTime which is looks like :
    t := cnt                                    
      repeat until (rxByte := RxCheck) => 0 or (cnt - t) / (clkfreq / 1000) > ms
    

    I added the second condition to the end of my repeat until i==1023 and it didn't work. It just stops in the middle of incrementing "i" like the buffer disappears. In trying to diagnose, I changed the second condition to just say false so that it really should have no effect, but it does.

    I must be overflowing the rx buffer whenever I slow down grabbing bytes. I just noticed that although I was able to set BUFFER_LENGTH to 2048 in FullDuplexSerial, I cannot do it in Parallax Serial Terminal. I'll try to rewrite it so that I grab 128 bytes at a time and see if that works.
  • zepperik wrote: »
    PUB Listener | i
      repeat
        i:=0
        repeat until i==1023 or false
            byte[@Waveform+i]:=Pst.CharIn
            i++ 
        ConstructOutput(@Waveform)
    

    Note that your loop is ending one iteration too soon. As for the "false" issue, no idea...





  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2015-09-17 20:50
    Unless your cog includes a method that uses deep recursion, 2000 is way to big for a stack. 30 is usually sufficient, and 100 should be more than adequate.

    To answer Ale's question, == has higher precedence than or.

    Also, Seairth is right: change 1023 to 1024.

    Finally, how exactly does or false "change the behavior" ?

    -Phil
  • Thank for your response! I have only been playing with this for a month so I'm fairly new to this. I thought iterating 0 to 1023 assigning byte[@x + i] would assign @x and then the 1023 registers after for a total of 1024, no?

    I've got it working pretty well now that I've slowed down the communication. I've got Matlab on the other end of the port. I've found that sending the bytes one at a time in a for loop takes about 1 second to execute and the Parallax sees all the data. If I send the entire 1024 bytes at once, Parallax seems to drop the data.

    I suppose this makes sense if the buffer in the Parallax Serial Terminal is overflowing. Should I set BUFFER_SIZE to 256 bytes and send chunks with a response in between? (I was going to delete the post in fear that I haven't been helpful in posting but I don't see a delete button. Maybe I should change the title to be more relevant?)
  • JasonDorieJasonDorie Posts: 1,930
    edited 2015-09-18 18:57
    The check happens at the beginning of the loop, not the end.

    For example, if you changed your initial assignment to i := 1022 the code inside the repeat would only execute once:

    (check i (1022) < 1023) succeeds.
    byte[@Waveform+1022]:=Pst.CharIn
    i++ (i is now 1023)

    (check i (1023) < 1023) fails, loop exits.
  • Finally, how exactly does or false "change the behavior" ?

    Well, it'll make it slower. :)
  • Cluso99Cluso99 Posts: 18,069
    t := cnt
    repeat until (rxByte := RxCheck) => 0 or (cnt - t) / (clkfreq / 1000) > ms
    Could this be a CNT overflow issue?
    Try it without the "or (cnt - t) / (clkfreq / 1000) > ms"
  • Cluso99 wrote:
    Could this be a CNT overflow issue?
    Not unless ms is larger than 26843.

    -Phil
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2015-09-19 23:34
    It seems to me that the timeout should apply to the whole 1024 byte waveform, not to individual bytes. For speed, it's best to precompute the timeout. Something like this with a timeout set at something like one second:
    ' precomputed:  timeout_ticks := clkfreq/1000 * milliseconds
    '  byte buffer[1024]
    
    PUB getwave | ticks, idx, char
      ticks := cnt
      repeat 
        if (char:=ser.rxCheck)>-1
          buffer[idx++]:=char
        elseif cnt-ticks>timeout_ticks
          return false
      until idx == [s]1023[/s]1024
      return true
    
    Note that the condition with 10231024 is at the end of the loop, so that index is now included in the transfer. And indeed, the serial queue has to be big enough to avoid overflow at the desired baud rate.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2015-09-19 21:45
    Note that the condition with 1023 is at the end of the loop, so that index is now included in the transfer.
    That still doesn't work, because the desired last value of idx++ is 1024.

    -Phil
  • Right you are, should be 1024. Now corrected.

    (Oh! the S for stikeout doesn't work in code blocks.)
Sign In or Register to comment.