Instruction cycle measurement


Closed Thread
Results 1 to 10 of 10
  1. #1
    Join Date
    Oct 2005
    Location
    New Jersey
    Posts
    425

    Default Instruction cycle measurement

    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?

  2. #2
    Join Date
    Jul 2005
    Location
    Palmdale, CA
    Posts
    37


    Did you find this post helpful? Yes | No

    Default Re: Instruction cycle measurement

    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.

  3. #3
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: Instruction cycle measurement

    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.

  4. #4
    Join Date
    Oct 2005
    Location
    New Jersey
    Posts
    425


    Did you find this post helpful? Yes | No

    Default Re: Instruction cycle measurement

    Quote Originally Posted by enauman
    I assume you are making analog measurements.
    Your assumption is wrong.
    Quote Originally Posted by 25HenrikOlsson
    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:



    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

  5. #5
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: Instruction cycle measurement

    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.

  6. #6
    Join Date
    Oct 2005
    Location
    New Jersey
    Posts
    425


    Did you find this post helpful? Yes | No

    Default Re: Instruction cycle measurement

    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.........
    Last edited by Christopher4187; - 5th August 2012 at 17:49.

  7. #7
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: Instruction cycle measurement

    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.

  8. #8
    Join Date
    Oct 2005
    Location
    New Jersey
    Posts
    425


    Did you find this post helpful? Yes | No

    Default Re: Instruction cycle measurement

    Quote Originally Posted by HenrikOlsson View Post
    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.

  9. #9
    Join Date
    Oct 2005
    Location
    New Jersey
    Posts
    425


    Did you find this post helpful? Yes | No

    Default Re: Instruction cycle measurement

    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.

  10. #10
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,521


    Did you find this post helpful? Yes | No

    Default Re: Instruction cycle measurement

    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
    Code:
    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
    Code:
    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
    Code:
    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.

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts