PDA

View Full Version : Instruction cycle measurement



Christopher4187
- 4th August 2012, 23:03
I have a program on an 18F4550 with a 20 mhz oscillator that interfaces with a VB program via USB. I need to be able to monitor data at about 500Kbps. I'm using the computer to store the information as it comes in. When I use the computer in real time (not storing data but just viewing) it seems pretty quick. When I press the button to store the data, it seems to slow just a little bit. When I look at the data using Excel, I have roughly 45 measurements per second, which is about 455 short of what I need. I think the 18F4550 can achieve a 2mS measurement but I'm not 100% sure since I've never needed anything with this short of a timing cycle.

So my questions are:

1. Can the 18F4550 do this quick of a measurement?

2. Is there a list of instructions where it lists the amount of time (i.e. If then = 400nS)

3. Is there an easy way to find out where my issue is? (VB or PBP code)

4. Is there a relatively easy way to do data logging on a PIC? Would I need an external memory chip?

enauman
- 5th August 2012, 02:15
Look at the data sheet for the A/D converter. I assume you are making analog measurements. Most PICs A/D can sample around 50uS.

HenrikOlsson
- 5th August 2012, 07:25
Hi,
How do you transfer the data from the PIC to the PC?

I'm a bit confused about your math... You say you need 500Kbs (which is quite a bit), but then you say you want 500 measurements per second. With an ADC resolution of 10 bits (each measurement taking two bytes) that's 1000 bytes per second which would be around 100Kbs. Never the less, the bottleneck is probably in the datatransfer itself.

Is it a continous stream of samples or is it a defined amount of samples at a certain sample rate or what exactly are you trying to do. The 4550 has 2k of ram so depending on what else your program is doing you might be able to store the samples in RAM and then transfer them to the PC - but again, it all depends on what you're doing.

/Henrik.

Christopher4187
- 5th August 2012, 15:01
I assume you are making analog measurements.Your assumption is wrong.

How do you transfer the data from the PIC to the PC?

I'm a bit confused about your math... You say you need 500Kbs (which is quite a bit), but then you say you want 500 measurements per second. With an ADC resolution of 10 bits (each measurement taking two bytes) that's 1000 bytes per second which would be around 100Kbs. Never the less, the bottleneck is probably in the datatransfer itself.

Is it a continous stream of samples or is it a defined amount of samples at a certain sample rate or what exactly are you trying to do. The 4550 has 2k of ram so depending on what else your program is doing you might be able to store the samples in RAM and then transfer them to the PC - but again, it all depends on what you're doing.Hi Henrik,

I need to clarify my original post. The 500Kbps is the speed of the CAN network and there are about 500 messages a second. I know the 4550 can do this because the demo boards do it with no problems so it's an issue within my code. Actually, I've seen the demo boards handle 1100 messages a second. Again, I'm not sure if it's the VB code or it's the PIC code. Here is what I have for the PIC code:





START:

RxBuffer = 0 'clear flag

Low CS
SSPBUF = %00000011 'read command
GoSub letclear
SSPBUF = CANINTF 'buffer flags are contained in this mcp2515 can controller register
GoSub letclear
SSPBUF = 0 'clock it out
GoSub letclear
RXDATA = SSPBUF 'receive buffer status
High CS
RxBuffer = RXDATA & %00000011 'isolate last two bits
If RxBuffer > 0 Then
'a buffer is full, or 3, then both are full
If (RxBuffer = 1) Or (RxBuffer = 3) Then
RxBufferSub = 1
DATA35=1 'VB LED
GoSub ReceiveCanSub0
EndIf
If (RxBuffer = 2) Or (RxBuffer = 3) Then
RxBufferSub = 2
DATA35=1 'VB LED
GoSub ReceiveCanSub1
EndIf

GOTO START

ReceiveCanSub0:

LED_RX=0

Low CS
SSPBUF = 3 'read
GoSub letclear
SSPBUF = RXB0DLC + (RxBufferSub - 1) * 16 'receive buffer of data bytes offset 16
GoSub letclear
SSPBUF = 0 'dummy clock it
GoSub letclear
RXDATA = SSPBUF 'should contain the number of data bytes
High CS

DataBytesRx0 = RXDATA & %00001111 'bits 0-3 contain the number of data bytes
DATA1=DATABYTESRX0
If DataBytesRx0 > 0 Then
For i = 0 To DataBytesRx0 - 1 '(say data is 2, then 0 and 1)

Low CS
SSPBUF = 3
GoSub letclear
SSPBUF = (RXB0D0 + (RxBufferSub - 1) * 16) + i
GoSub letclear
SSPBUF = 0 'dummy clock
GoSub letclear
RXDATA = SSPBUF 'mcp2515 can controller data
High CS

CanDataRx0 [i] = RXDATA
DATA2 = CanDataRx0[0]
DATA3 = CANDATARX0[1]
DATA4 = CANDATARX0[2]
DATA5 = CANDATARX0[3]
DATA6 = CANDATARX0[4]
DATA7 = CANDATARX0[5]
DATA8 = CANDATARX0[6]
DATA9 = CANDATARX0[7]
Next
EndIf
Low CS
SSPBUF = 3 'read
GoSub letclear
SSPBUF = RXB0SIDH + (RxBufferSub - 1) * 16 'high identifier
GoSub letclear
SSPBUF = 0 'clock spi
GoSub letclear
RXDATA = SSPBUF 'identifier
High CS

CanRxIDHigh0 = SSPBUF

Low CS
SSPBUF = 3 'read
GoSub letclear
SSPBUF = RXB0SIDL + (RxBufferSub - 1) * 16 'low identifier
GoSub letclear
SSPBUF = 0 'clock spi
GoSub letclear
RXDATA = SSPBUF 'identifier
High CS

CanRxIDLow0 = SSPBUF


'now, clear the buffer!
'use bit modify...
Low CS
SSPBUF = %00000101 'bit modify command
GoSub letclear
SSPBUF = CANINTF 'mcp2515 can controller interrupt flags
GoSub letclear
SSPBUF = RxBufferSub 'mask for buffer number n
GoSub letclear
SSPBUF = %00000000 'clock in a clear bit
GoSub letclear
High CS
LED_RX=1
DATA35=0 'VB LED
Return

HenrikOlsson
- 5th August 2012, 16:23
Hi,

Oh, I also thought you did ADC sampling since you asked about measurment speed but OK.

I must be blind but I can't for the life of me see where in the code you're actually sending anything from the PIC to the PC.
Are you using the USART or are you using USB or am I completely missunderstanding this.

Anyway, if the PIC is executing the exact same code when you view the data "real time" as it does when you "record" it then there can't really be any problem with the PIC code or the link to the PC. The problem in that case must be with the VB code.

Why not flip an output each time the PIC processes a message and measure the frequency of that of that output. Then you'll see how many messages per second the PIC is actually processing.

/Henrik.

Christopher4187
- 5th August 2012, 17:45
Why not flip an output each time the PIC processes a message and measure the frequency of that of that output. Then you'll see how many messages per second the PIC is actually processing.It's the VB code. I put a counter and a timestamp for each cycle through the mainloop. The results vary but the VB code is only able to poll the PIC every 10-30mS or so, and the counter jumps ~20 cycles. So in one second I can be missing a ton of packets. The VB poll looks like this:
Time (HH:MM:SS:MS) Counter(X)
11:07:25.92 / 58
11:07:25.94 / 70
11:07:25.95 / 88
11:07:25.97 / 100
11:07:25.98 / 115
11:07:26.00 / 130
11:07:26.02 / 146
11:07:26.03 / 160

When I datalog it's worse

12:48:54.84 / 252
12:48:54.88 / 30
12:48:54.91 / 64
12:48:54.94 / 90
12:48:54.97 / 126
12:48:55.00 / 156
12:48:55.03 / 186
12:48:55.06 / 216

Now I have to look at the VB code and figure that out.........

HenrikOlsson
- 5th August 2012, 17:53
Hi,
Windows isn't known for being good at high resolution timing, atleast not with the "standard" tools. Why not do one of two things:
1) Just stream the data from the PIC to the PC. The serial port control in VB buffers the data behind the scenes.
2) If you do need to have the PC poll the PIC then buffer the data in a circular buffer with enough size and send it off in bursts.

/Henrik.

Christopher4187
- 5th August 2012, 17:56
Hi,
Windows isn't known for being good at high resolution timing, atleast not with the "standard" tools. Why not do one of two things:
1) Just stream the data from the PIC to the PC. The serial port control in VB buffers the data behind the scenes.
2) If you do need to have the PC poll the PIC then buffer the data in a circular buffer with enough size and send it off in bursts.

/Henrik.It's above my level of knowledge. But, I'm willing to learn. It's actually a USB VB program but I'm guessing the same ideas apply. I'll play around with it and see what I can do. Thanks for the help.

Christopher4187
- 5th August 2012, 19:09
After some searching, it appears as though there's no way to get below a 1mS timer with VB6. The problem, as you mentioned, is windows.

Now how to solve it?

I can miss up to 30 packets per revolution of code (mainloop -> Goto mainloop) so what is the easiest way to get every single piece of data? My preference would be for the PIC to store the data and then when the PC gets around to it, that packet will be sent.

HenrikOlsson
- 6th August 2012, 07:50
Hi,
USB, OK, never played with that myself. But anyway, are you sending one single measurment from the PIC to the PC each time the PIC is polled? If you reliably can get a poll rate of say 20Hz and you need 500 measurments per second you need a buffer in the PIC of atleast 500/20=25 measurements (bytes or words?) but I'd probably add some margin to that.

Now, depending on how the rest of the code is set up, ie. if interrupts are used etc using the local buffer can be more or less complicated. Assuming that no interrupts are used to put data INTO the buffer all your main program has to do keep track of where in the buffer to put the next byte using a pointer variable

BufferSize CON 25
LocalBuffer VAR BYTE[BufferSize]
Ptr VAR BYTE
Ptr = 0

Each time you get a new measurment to put in the buffer you do something like

LocalBuffer[Ptr] = NewMeasurment
Ptr = Ptr + 1
If Ptr = BufferSize THEN GOTO BufferOverFlow ' Buffer not emptied in time.....
The routine that sends the data to the PC when polled then just have to send any data that's in the buffer. I'm using HSEROUT here since I don't know how you're doing it with USB

If Ptr > 0 'Only do this of there's any new data in the buffer
For i = 0 to (Ptr - 1)
HSEROUT [LocalBuffer[i], 10,13]
NEXT
Ptr = 0 ' Reset pointer
ENDIF

Something like that, perhaps.

If you're not using interrupts then obviosuly the PIC can't read data and put into the buffer at the same time that it's sending data but I don't know exactly how that works when using USB. If you're using interrupts to fill the buffer, ie. the routine that sends data to the PC can be interrupted by the routine putting data into the buffer you'll need to resort to a circular buffer.

/Henrik.