Shop OBEX P1 Docs P2 Docs Learn Events
Serial Problem — Parallax Forums

Serial Problem

T ChapT Chap Posts: 4,223
edited 2009-12-19 20:16 in Propeller 1
I am using the 4port serial object for this, port 1. The method first waits for a byte indefinitely, if a byte is rec'd, it goes to ser.rxtime where it will wait just a short time, if a byte shows up it reads it, else move on. Using rxtime allows the loop to always park at the top.

I am sending a ping from a Mac, which is 4 bytes: 1F 01 01 DE and everything is fine. If I add 1 extra byte to the end of the string, the prop just doesn't respond, then I can remove the extra byte (5th byte) in the string and everything works again. But if I add 2 extra bytes at the end of the string, the cog crashes and never recovers, other cogs keep on running. I am sure this is something simple, but can't see it. The thing is that under controlled circumstances, the Prop would never see more than the controlled string I am sending it, but if like the example above where some error happened and the Mac or pc is sending out extra bytes, the Prop must handle the excess.



VAR   pingbuffer[noparse][[/noparse]12]

PUB RS485test    | i, val     'pingbuffer
    dira[noparse][[/noparse]RSEna] := 1
    outa[noparse][[/noparse]RSEna] := 0
    repeat
     ser.rxflush(1)
     ser.txflush(1)
     pingbuffer[noparse][[/noparse]0] := ser.rx(1)  'waits here for first byte
     i := 1
     Repeat 3                    'look for more, else return
       Val :=  ser.rxtime(1,2)   'read more, port 0, wait only 2 ms
       If val == -1
         Return
       pingbuffer[i] := Val
       i := i + 1
     If pingbuffer[noparse][[/noparse]0] == $1F     'string header
        chksum := pingbuffer[noparse][[/noparse]0] + pingbuffer + pingbuffer
        !chksum    'NOT   
        cls   'clear lcd
        go(0,0)
        ser.hex(3, chksum, 2)
        if chksum == pingbuffer      'c incoming chksum
           chksum :=  $1F + $01 + $FF  '1F + LEN + ACK   set ping response
           !chksum
           rem := 1
           outa[noparse][[/noparse]RSena] := 1
           ser.str(1, string($1F, $0A, $FF, $62, $65, $6C, $6C, $5F, $76, $30, $30, $31, $D2 ))
           w(1_000_000)
           outa[noparse][[/noparse]RSena] := 0
     cls
     go(1,0)
     ser.hex(3, pingbuffer[noparse][[/noparse]0], 2)
     ser.str(3, string(" "))
     ser.hex(3, pingbuffer, 2)
     ser.str(3, string(" "))
     ser.hex(3, pingbuffer, 2)
     ser.str(3, string(" "))
     ser.hex(3, pingbuffer, 2)[/i]

Post Edited (Todd Chapman) : 12/19/2009 4:25:56 AM GMT

Comments

  • StefanL38StefanL38 Posts: 2,292
    edited 2009-12-19 19:58
    is the code above the WHOLE program?

    then you need

    CON
      'serial communication requires a precise clockmode
      'internal oscillator-mode is much too much unprecise
      'so ALWAYS use a xtal1-mode  
      _clkmode = xtal1 + pll16x
      'when using another chrystal than 5 MHz adjust constant _xinfreq
      'to the right value
      _xinfreq = 5_000_000 
    
      'result of pll16x * _xinfreq should NOT exceed 80MHz  
      'example if _xinfreq = 10_000_000 than use pll8x instead of pll16x
      'as 10_000_000 * 16 = 160MHz   and 10_000_000 * 8 = 80MHz   
    
    



    best regards

    Stefan
  • T ChapT Chap Posts: 4,223
    edited 2009-12-19 20:16
    Stefan, the code posted was just a snippet. There is a 5m crystal and 16x, the set up is not an issue.

    The issue was resolved strangely by adding a delay as shown below, so all is well.


    PUB RS485test    | i, val     'pingbuffer
        dira[noparse][[/noparse]RSEna] := 1
        outa[noparse][[/noparse]RSEna] := 0
        repeat
         ser.rxflush(1)
         ser.txflush(1)
         pingbuffer[noparse][[/noparse]0] := ser.rx(1)  'waits here for first byte
         i := 1
         Repeat 3                    'look for more, else return
           Val :=  ser.rxtime(1,2)   'read more, port 0, wait only 2 ms
           If val == -1
             Return
           pingbuffer := Val
           i := i + 1
    
         waitcnt(2_000_000 + cnt)          '<<<<<<<<<<<<<<<<<<<<<< delay here stopped the cog lock up
         If pingbuffer[noparse][[/noparse]0] == $1F     'string header
            chksum := pingbuffer[noparse][[/noparse]0] + pingbuffer + pingbuffer
            !chksum    'NOT   
            cls   'clear lcd
    
Sign In or Register to comment.