UART TOOL

Coding and general discussion relating to user created compiler modules

Moderators: David Barker, Jerry Messina

Widgetman
Posts: 136
Joined: Sun Dec 16, 2007 7:39 pm
Location: Florida

UART TOOL

Post by Widgetman » Fri Mar 11, 2011 12:58 am

Hi All,
Iam trying to get the PICKIT2 to show me what it sees on the RX pin at the TTL side. Below is the ISRRX routine I tried to implement as a standard RX routine. the issue I am having is the PICKIT2 UART tool does not show me anything even if I try to loop it out the TX pin. Is there a trick to getting this tool to show me what was received ?
Any insight would be greatly appreciated
Thanks


Sub ReadSerial()
Dim Index As Byte
SDataSize = 0
While ISRRX.DataAvailable
SData(SDataSize) = ISRRX.ReadByte()
Inc(SDataSize)
Inc (ByteCount)
Wend

If SDataSize > 0 Then
For Index = 0 To (SDataSize - 1)
RXData(Index) = SData(Index)
Next

End If
' Test Code To Verify 12 Bytes received In Packet
If ByteCount = 12 Then
Low(RED_LED)
DelayMS(500)
High(RED_LED)
For Index = 0 To (SDataSize - 1)
USART.write(RXData(I))
next

ByteCount = 0
End If


End Sub

Widgetman
Posts: 136
Joined: Sun Dec 16, 2007 7:39 pm
Location: Florida

UART TOOL

Post by Widgetman » Fri Mar 11, 2011 1:28 pm

Hi All,
It just dawned on me that the packet is stuffed into the buffer backwards since the (SdataSize - 1) decrements the byte counter. Am I right about the packets being stored backwards ? It still does not explain why I do not see anything on the RX pin using the PICKIT2 module. Any ideas ?
Thanks

Jerry Messina
Swordfish Developer
Posts: 1471
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Fri Mar 11, 2011 2:09 pm

No, it's not backwards. Index still increments from 0 to (SdataSize - 1).

To prove that to yourself, substitute a value for SdataSize and look at it again. For example, if SdataSize = 12, the loop effectively translates to
'For Index = 0 to 11'

The difference is that the expression '(SdataSize-1)' will be evaluated each time through the loop since it's not a constant.

Widgetman
Posts: 136
Joined: Sun Dec 16, 2007 7:39 pm
Location: Florida

Post by Widgetman » Fri Mar 11, 2011 5:35 pm

Hi,
Well I am stumped then. I can see the LED come on when a packet is received in the routine looking for 12 bytes in length, but when I try to compare the start of the packets with a constant it never matches. I thought I could use the PICKIT2 to view what it received, but that did not work out so hot either. Any idea how to tell what was received ??? I made a assumption that by defining the device it knew which pins TX and RX were on so I should be seeing some charcters I thought.
Thanks


Here is my compare code:
If RXData(0) = $FE And RXData(1) = $3F And RXData(2) = $16 Then

'Do Something here cause it matches

End If

Jerry Messina
Swordfish Developer
Posts: 1471
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Fri Mar 11, 2011 5:54 pm

Take a close look at

Code: Select all

For Index = 0 To (SDataSize - 1)
    USART.write(RXData(I))
next 
What's 'I' ?

That would explain one of the reasons you're not seeing the 12-byte packet on the UART tool.

Are you sure you're sending exactly 12 bytes? The first loop doesn't exit while there's data in the buffer.

Widgetman
Posts: 136
Joined: Sun Dec 16, 2007 7:39 pm
Location: Florida

Post by Widgetman » Fri Mar 11, 2011 7:10 pm

Hi Jerry
Below is the ISRRX routine. It gets called in the main code After it sets a packetflag I then use the If statement to verify the first few bytes are correct. The problem is I see the LED flashing indicating the ReadSerial() got called, but I never see any data in my PICKIT2 UART window, and I never get a macth on the bytes. That is what I am trying to determine is why I never see a match or see RX bytes in the UART tool window. It was my understanding that whatever appeared on the RX pin TTL wise would be displayed in the UART tool, but that is not my case here. Any thoughts would be greatly appreciated
Thanks


// Read serial port
Sub ReadSerial()
Dim Index As Byte
SDataSize = 0
While ISRRX.DataAvailable
SData(SDataSize) = ISRRX.ReadByte()
Inc(SDataSize)
Inc (ByteCount)
Wend

If SDataSize > 0 Then
For Index = 0 To (SDataSize - 1)
RXData(Index) = SData(Index)
Next
ISRRX.Reset ' Clear Buffer
End If
' Test Code To Verify 12 Bytes received In Packet
If ByteCount = 12 Then
Low(RED_LED)
DelayMS(500)
High(RED_LED)
ByteCount = 0
PacketFlag = true
End If
End Sub

' This part checks for a match of the data after it came in

While PacketFlag = True
If RXData(0) = $FE And RXData(1) = $1E And RXData(3) = $14 Then
' Do Something It Matches

End if
Wend

Jerry Messina
Swordfish Developer
Posts: 1471
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Fri Mar 11, 2011 7:58 pm

Widget-

Perhaps I misunderstood how you were using the uart tool. I thought you were connecting the PIC TX -> uart Tool RX and using the USART.write(RXData(I)) to display the packet on the uart tool.

If you're just connecting the uart tool RX to the PIC RX so you can see what the PIC ought to be seeing coming in, that should work too as long as you have the tool connected up properly, baudrate set, etc. Of course, that'll show you what it OUGHT to see, and not necessarily what your code's doing.

I'm not 100% sure I completely follow when you're calling ReadSerial(), but the first part of the routine

Code: Select all

	SDataSize = 0
	While ISRRX.DataAvailable
		SData(SDataSize) = ISRRX.ReadByte()
		Inc(SDataSize)
		Inc (ByteCount)
	Wend
can exit the while loop after any number of characters come in, depending on the speed at which your getting characters transmitted to you. If you're working at 9600 baud for example, that's about one character every msec, and that while loop will probably exit after getting just one character.

Later on you're checking to see how many chars you've gotten, etc, but each time you enter ReadSerial() you're resetting all of the array indexes, so when you copy data from Sdata(), the RXData() array gets set from index 0 all over again. Then, to boot, if SdataSize is > 0, you're emptying out the ISRRX input buffer by calling Reset.

The LED will flash when you get 12 characters, but the RXData() buffer probably isn't going to contain those 12 characters since most likely they've been overwritten.

I think you need to rearrange the code a bit. There's a bunch of different ways to do this, but it depends on if you want to wait in ReadSerial() for 12 bytes to come in, or just collect up bytes one at a time as they come in and do other stuff in between.

Widgetman
Posts: 136
Joined: Sun Dec 16, 2007 7:39 pm
Location: Florida

Thanks

Post by Widgetman » Sat Mar 12, 2011 1:15 pm

Hi Jerry,
Thanks for the input. I did not realize this was how the ISRRX routine worked. I will try to play with it and rearrange some stuff. The PICKIT2 connects to the 6 pin programming connector so I have to assume the software fetches the RX data on the RX pin and displays it in the UART tool. I tried to find a working example of how to receive bytes off the ISRRX interrupt automatically, but I could not really find any example that made sense so I decided to start with the example in the help. Basically all I am trying to do is sit in a main loop toggling LEDS till a packet of 12 bytes come in, then check that packet to a constant packet and verify I received a valid packet, then toggle my leds again. So far I have yet to get the packet verified. I will work on it some more
Thanks

Jon Chandler
Registered User
Registered User
Posts: 185
Joined: Mon Mar 10, 2008 8:20 am
Location: Seattle, WA USA
Contact:

Post by Jon Chandler » Sat Mar 12, 2011 2:59 pm

Ummm....looks like there may be some confusion here.

There's no magic in the UART tool. In order to communicate with the PIC's UART, the PICkit 2 must be connected to the PIC's transmit and receive pins, as well as power and ground. Connecting it to the ICSP connector won't do the job.

There are some examples of using the PICkit 2 UART Tool at Digital-DIY.
Jon

Check out the TAP-28 PIC Application board at http://www.clever4hire.com/throwawaypic/

Jerry Messina
Swordfish Developer
Posts: 1471
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Sat Mar 12, 2011 3:02 pm

If you have the UART tool connected up to the same ICSP connector that you use to program the chip, that won't work. You have to connect the UART tool RX and TX lines up to the PIC uart pins (see the pickit2 users guide).

The ISRRX routine will automatically read bytes that come in on the uart and put them into it's own buffer. You use the DataAvailable() and ReadByte() routines to get access to that buffer data. Here's a code snippet on how you might use the ISRRX module to read a 12 byte packet (completely untested)

Code: Select all

// setup serial port, ISRRX, etc

// clear buffer to start
ISRRX.Reset()

PacketFlag = false
ByteCount = 0

while (true)

	if (ISRRX.DataAvailable()) then
		RXData(ByteCount) = ISRRX.ReadByte()
		inc(ByteCount)
		if (ByteCount = 12) then
			PacketFlag = true
		endif
	endif
	
	if (PacketFlag) then
		if ((RXData(0) = $FE) and (RXData(1) = $1E) and (RXData(3) = $14)) then
			' Do Something It Matches
		endif
		// prepare for next packet
		'ISRRX.Reset() 	// only if you want to flush any new chars out of the isrrx buffer
		ByteCount = 0
		PacketFlag = false
	endif
	
end while
edit: As usual, I see Jon's beat me to it

Jon Chandler
Registered User
Registered User
Posts: 185
Joined: Mon Mar 10, 2008 8:20 am
Location: Seattle, WA USA
Contact:

Post by Jon Chandler » Sat Mar 12, 2011 3:33 pm

Jerry, at least we're usually in agreement :)
Jon

Check out the TAP-28 PIC Application board at http://www.clever4hire.com/throwawaypic/

Widgetman
Posts: 136
Joined: Sun Dec 16, 2007 7:39 pm
Location: Florida

Thanks a Bunch

Post by Widgetman » Sat Mar 12, 2011 5:24 pm

Hi Jerry and Jon,
Thanks a bunch for all the help. I just did not understand how the PICKIT2 unit worked. I guess I am also having a hard time understanding the UART interrupt stuff to. I will play with it this weekend and try not to bug you guys too much. Is is possible to also run a timer 0 interrupt in the background and still use the ISSRX to receive characters ? I would like to toggle my LED off the timer then RX packets in between the TOGGLE when they come in, but let the RX have a higher priority

Thanks

Jerry Messina
Swordfish Developer
Posts: 1471
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Sat Mar 12, 2011 7:53 pm

Is is possible to also run a timer 0 interrupt in the background and still use the ISSRX to receive characters ? I would like to toggle my LED off the timer then RX packets in between the TOGGLE when they come in, but let the RX have a higher priority
Sure. By default, the ISRRX module is setup to use the high-priority interrupt, so just assign the timer interrupt to the low priority one.

The nice thing about the ISRRX module is that it takes care of reading the incoming bytes from the usart for you and buffers them up. Otherwise, if you're just using the regular routines in USART.bas you have to make sure that you call Read() faster than they're sent or else you can lose bytes. Plus, Read() is a blocking call (meaning that it waits for a byte to come in), so you can't do anything else in the meantime.

Widgetman
Posts: 136
Joined: Sun Dec 16, 2007 7:39 pm
Location: Florida

Simple Timer

Post by Widgetman » Sun Mar 13, 2011 2:48 pm

Hi Jerry,
Well thanks to all you and Jon's help I was able to finally RX packets and decode them. I figured out that besides my coding errors the data coming in was inverted probably since I am using RS-485 hardware to interface too. Anyway I wanted to ask if there was a simple timer0 routine out there that I can basically start and have it increment a counter once a second in the back ground. I tried to use DelayMs as a time counter but it seemed to crawl off in a hole and never came back to service the RX packets after it dropped into the routine. I am new at this and still learning so please keep that in mind.
Thanks

Jerry Messina
Swordfish Developer
Posts: 1471
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Post by Jerry Messina » Mon Mar 14, 2011 10:39 am

I figured out that besides my coding errors the data coming in was inverted probably since I am using RS-485 hardware to interface to
If the data's inverted, it's probably because the RS485 data signals are swapped around. It's a common, easily-made mistake. With RS485, the standard says that 'A' is the inverting signal and 'B' is the non-inverting signal. This is the exact OPPOSITE of how many manufacturers (like TI) label their chips, so it's always a good idea to ignore the signal names and look to see which one's which.
I tried to use DelayMs as a time counter but it seemed to crawl off in a hole and never came back to service the RX packets after it dropped into the routine
DelayMs() doesn't return until the delay time has expired. That would keep you from servicing packets until after the delay, but it doesn't keep ISRRX from buffering up the incoming data packet while DelayMs() is running.

There are a number of examples/modules that use timers in the User sections. The SoftRTC sample http://www.sfcompiler.co.uk/wiki/pmwiki ... er.SoftRTC has a good discussion on timers, and there's an interrupt driven library module (ISRTimer.bas) that lets you create a number of "software timers" using a hardware timer as its base. There are some others as well.

Post Reply