PDA

View Full Version : Serial Problem



T Chap
12-19-2009, 12:20 PM
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[12]

PUB RS485test | i, val 'pingbuffer
dira[RSEna] := 1
outa[RSEna] := 0
repeat
ser.rxflush(1)
ser.txflush(1)
pingbuffer[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
If pingbuffer[0] == $1F 'string header
chksum := pingbuffer[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[RSena] := 1
ser.str(1, string($1F, $0A, $FF, $62, $65, $6C, $6C, $5F, $76, $30, $30, $31, $D2 ))
w(1_000_000)
outa[RSena] := 0
cls
go(1,0)
ser.hex(3, pingbuffer[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)

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

StefanL38
12-20-2009, 03:58 AM
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 Chap
12-20-2009, 04:16 AM
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[RSEna] := 1
outa[RSEna] := 0
repeat
ser.rxflush(1)
ser.txflush(1)
pingbuffer[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[0] == $1F 'string header
chksum := pingbuffer[0] + pingbuffer + pingbuffer
!chksum 'NOT
cls 'clear lcd