Speed of USB EasyHID and Time problem


Closed Thread
Results 1 to 11 of 11
  1. #1
    Join Date
    Mar 2006
    Location
    Gothenburgh, Sweden
    Posts
    18

    Default Speed of USB EasyHID and Time problem

    I'm working on a project measuring high pulse and then during the low pulse, send the value by USB to a VB app.
    The problem is that when the period (High and Low pulse) is shorter than aprox 7ms I get strange data from the pic.

    I decided to measure how long time a USBOut and USBSERVICE takes and here is what I got:

    USBSERVICE = 4.08us
    USBOut 8 Byte = 12.4us
    USBOut 16 Byte = 15.7us
    USBOut 32 Byte = 22.4us
    USBOut 64 Byte = 35.7us

    So the USB transfer should not affect my measurements of the pulse width.
    I use Timer3 to measure parts of my program.
    The part of code I measure in the pic code below takes 15.5us.

    I use a Basic Stamp to create a squarewave to my pic CCP1 input.
    The program looks like this:
    Code:
    Main:
      IF IN15 THEN
      HIGH 6
      PAUSE 3
      LOW 6
      PAUSE 4
      ENDIF
      GOTO Main
      END
    In this case I get correct readings sent to the pc.
    But if I change Pause 4 to Pause 3 the data variates a lot.
    Also the Timer3 values in the pic code below variates a lot.
    Wich means that that part of code takes different times to execute from time to time.

    If I change the Basic Stamp program to this; the data is correct:
    Code:
    Main:
      IF IN15 THEN
      HIGH 6
      PAUSE 0
      LOW 6
      PAUSE 7
      ENDIF
      GOTO Main
      END
    And also this works:
    Code:
    Main:
      IF IN15 THEN
      HIGH 6
      PAUSE 7
      LOW 6
      PAUSE 0
      ENDIF
      GOTO Main
      END
    But as soon the period is under 7ms I get strange values to my vb app.

    Please help me find what is wrong with my code.
    I use a Pic18F4550 20Mhz, MicroCode Studio Plus and Pbp 2.46.

    Thanks in advance,
    Stefan

    Code:
       
    '********************************************
    'Pulse width measuring
    '********************************************
    DEFINE OSC 48          
    DEFINE LOADER_USED 1
    DEFINE RESET_ORG 800h         ' For Microchip USB Bootloader
    DEFINE INTERRUPT_ORG 808h   ' For Microchip USB Bootloader
    
    USBBufferSizeMax   con 8        ' maximum buffer size
    USBBufferSizeTX    con 8         ' input 
    USBBufferSizeRX    con 8         ' output
    USBBuffer       Var Byte[USBBufferSizeMax] 
    USBBufferCount  Var Byte 
    
    Counts1          Var Word       ' Holds Timer1 counts
    Counts1Of       Var Byte       ' Holds the Overflow counts
    Overflow         var byte
    RisingEdge       Var Bit
    Preset            Var Bit              
    SendBytes       Var Bit
    SampleNo        var byte
    NewSample      var byte
    CCP1IE            var PIE1.2 
    CCP1IF           VAR PIR1.2
    TMR1ON         VAR T1CON.0
    TRM1IF           var PIR1.0
    TMR1IE           VAR PIE1.0
    IrOnRising        var BYTE
    IrOnFalling       var BYTE
    x                    var byte
    y                    var byte
    Led                VAR PortB.5
    
    'Timer3 declarations
    TMR3ON          var T3CON.0
    TMR3IF            var PIR2.1
    TMR3IE            var PIE2.1
    TMR3VALUE      var WORD
    TMR3OverF       var byte
    
    
    USBINIT
        ADCON1 = 15     ' Set PORTA, PORTE and PORTB to digital.
        TRISD.1 = 0       'Port D Bit 1 as Output
        TRISB.5 = 0       'Port B Bit6 as Output for LED
        TRISC.2 = 1       'Port C Bit2 CCP1 as Input
        IrOnFalling = 4    '0100 = Capture mode: every falling edge
        IrOnRising = 5     '0101 = Capture mode: every rising edge
        T1CON.4 = 1      'Timer1 Prescaler Bit4
        T1CON.5 = 1      'Timer1 Prescaler Bit5
        Counts1 = 0
        TMR1H = 0
        TMR1L = 0
        CCP1CON = IrOnRising     '0101 = Capture mode: every rising edge
        CCP1IE = 1                   'CCP1IE Interrupt Disabled
        SampleNo = 1
        Counts1Of = 0
        Overflow = 0
        Low Led
    
    'Timer3 inits
        TMR3OverF = 0
        TMR3IE = 1
        TMR3IF = 0    
        T3CON.4 = 0
        T3CON.5 = 0
    
        
    ProgramStart:
       USBSERVICE                               ' keep connection alive
    
            if TRM1IF THEN                      'If Timer1 Overflows
                Overflow = Overflow + 1      'Incr Overflow counter
                TRM1IF = 0                       'Reset Flag
            ENDIF 
    
        IF CCP1IF = 0 THEN ProgramStart     'Return if no Interrupt
    
            IF CCP1CON = IrOnRising THEN
                CCP1IF = 0                       'Reset Flag
                CCP1IE = 0                       'CCP1IE Interrupt Disabled
                CCP1CON = IrOnFalling        'Capture mode: every falling edge
                CCP1IE = 1                       'CCP1IE Interrupt Enabled
                TMR1H = 0                   
                TMR1L = 0
                TMR1IE = 1                       'Enable overflow flag
                TMR1ON = 1                      'Start Timer 1
    '            high Led
                goto ProgramStart
            ENDIF
    
            IF CCP1CON = IrOnFalling THEN
                TMR3ON = 1                        'Using Timer3 for measuring
                CCP1IF = 0                          'Reset Flag
                Counts1.HighByte = CCPR1H   'Save Values
                Counts1.LowByte = CCPR1L
                Counts1Of = Overflow        
                Overflow = 0                       'Reset Overflow counter
                CCP1IE = 0                         'CCP1IE Interrupt Disabled
                CCP1CON = IrOnRising           'Capture mode: every rising edge
                CCP1IE = 1                         'CCP1IE Interrupt Disabled
                'TMR1ON = 0                       'Stop Timer 1
                TMR1H = 0
                TMR1L = 0
                if SampleNo = 1 then            'SampleNo used by VB app.
                   SampleNo = 2
                else
                   SampleNo = 1
                endif
                USBBuffer(0) = Counts1.LowByte
                Counts1.LowByte = 0
                USBBuffer(1) = Counts1.HighByte
                Counts1.HighByte = 0
                USBBuffer(2) = Counts1Of
                USBBuffer(3) = SampleNo
                USBBuffer(4) = TMR3VALUE.highbyte
                USBBuffer(5) = TMR3VALUE.lowbyte
                'low Led
                Gosub DoUSBOut
                TMR3ON = 0                      'Using Timer3 for measuring                
                TMR3VALUE.highbyte = TMR3H
                TMR3VALUE.lowbyte = TMR3L
                TMR3H = 0 
                TMR3L = 0
                goto ProgramStart
            ENDIF
            
            
    GOTO ProgramStart
    
    ' ************************************************************
    ' * receive data from the USB bus                            *
    ' ************************************************************
    DoUSBIn:
       USBBufferCount = USBBufferSizeRX              ' RX buffer size
        x=x+1
        if x > y THEN Skipping
       USBService                                    ' keep connection alive
       USBIn 1, USBBuffer, USBBufferCount, DoUSBIn   ' read data, if available
        Skipping:
        x=0
       return
      
    ' ************************************************************
    ' * wait for USB interface to attach                         *
    ' ************************************************************
    DoUSBOut:
       USBBufferCount = USBBufferSizeTX              ' TX buffer size
       USBService                                    ' keep connection alive
       USBOut 1, USBBuffer, USBBufferCount, DoUSBOut ' if bus available, transmit data
       return
         
     End

  2. #2
    Join Date
    Mar 2006
    Location
    Gothenburgh, Sweden
    Posts
    18

    Question Speed of USB EasyHID and Time problem

    Can someone please help me to find out why I'm not able to measure higher freq than 67Hz. Is it the speed of the USB transfer that takes too long time?

    I would really apreciate if you can help me.

    Thanks

    Stefan.

  3. #3
    skimask's Avatar
    skimask Guest

    Default

    Quote Originally Posted by sjohansson View Post
    Can someone please help me to find out why I'm not able to measure higher freq than 67Hz. Is it the speed of the USB transfer that takes too long time?

    I would really apreciate if you can help me.

    Thanks

    Stefan.
    Are you saying that you can only get samples from USB at 67hz or that the PIC can only count up to 67hz?

  4. #4
    Join Date
    Mar 2006
    Location
    Gothenburgh, Sweden
    Posts
    18

    Question

    No not really. It should be 130Hz something. When the dutycycle is shorter than 7,5ms (130Hz) the pic send strange values to my vb application.
    I'm sure the pic can count much higher frequences, especially as I use the CCP1 input. But my question is if there is some bugs in my pic program or if the USB is taking too long so the timer1 measure something else than only the high pulse.

    Sorry for the bad English.

    Regards
    Stefan.

  5. #5
    skimask's Avatar
    skimask Guest

    Default

    Quote Originally Posted by sjohansson View Post
    No not really. It should be 130Hz something. When the dutycycle is shorter than 7,5ms (130Hz) the pic send strange values to my vb application.
    I'm sure the pic can count much higher frequences, especially as I use the CCP1 input. But my question is if there is some bugs in my pic program or if the USB is taking too long so the timer1 measure something else than only the high pulse.

    Sorry for the bad English.

    Regards
    Stefan.
    So, simulate some numbers. Plug in fake values into your registers (turn off the timers so they don't count up themselves), and see what the VB program displays. If it's good, you've probably got your CCP registers set up incorrectly. Also, make sure you're not trying to start counting in the middle of a pulse or something when the USB service RETURNs, wait for a solid high or low, then start counting.

  6. #6
    Join Date
    Mar 2006
    Location
    Gothenburgh, Sweden
    Posts
    18

    Question

    So, simulate some numbers. Plug in fake values into your registers (turn off the timers so they don't count up themselves), and see what the VB program displays.
    Good idea, I will try that.

    Also, make sure you're not trying to start counting in the middle of a pulse or something when the USB service RETURNs, wait for a solid high or low, then start counting.
    How can I do that? I thought that's what CCP1IF does. Just triggering if ccp pin rising or falling. Right?

    Also another question; Is it best to turn On and Off the timer for each cycle or should it be On all the time and just reset the timer registers?

  7. #7
    skimask's Avatar
    skimask Guest

    Default

    Quote Originally Posted by sjohansson View Post
    Good idea, I will try that.


    How can I do that? I thought that's what CCP1IF does. Just triggering if ccp pin rising or falling. Right?

    Also another question; Is it best to turn On and Off the timer for each cycle or should it be On all the time and just reset the timer registers?
    Just a thought, and I know it's not the best thought...

    Since the hardware is giving you a bit of a problem, have you thought about using PBP's built-in Count and/or Pulsin commands? At 48mhz, you should have plenty of resolution to work with.

    Also, you might want to put an LCD of some sort on your PIC, so you can read the values before they get send over the USB to the PC. You might be sending bad numbers in the first place.

    For the problem-How about a variable that's declared as a byte variable that you might actually want as a word variable? (overflowing where you don't want it to, something like that)

  8. #8
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    Hi Stefan,

    I've been looking at your program, and frankly I've got more questions than answers. But, I have found a few interesting things.

    First off, I can verify that the program completely "Wigs Out" when the pulses are faster than 125pps. This also seems to be the Limit for the number of HID reports per second. I've been working on a couple other USB programs and have seen the same number.

    An easy way to verify what's happening is to modify the DoUSBout like this...
    Code:
    ' ************************************************************
    ' * wait for USB interface to attach                         *
    ' ************************************************************
    DoUSBOut:
       USBBufferCount = USBBufferSizeTX              ' TX buffer size
       USBService                                    ' keep connection alive
       USBOut 1, USBBuffer, USBBufferCount, OutBusy  ' if bus available, transmit data
       return
         
    OutBusy:
      toggle PORTB.0         ' toggle led to show when USB is busy
    GOTO DoUSBOut
    Change the PORTB.0 to an LED on your board.

    Then you'll see that the "BAD" numbers received by the VB program, happen at the same time the LED starts blinking, due to a busy USB condition. (anything above 125hz)

    At this point I still don't understand what's going wrong, but I have found a possible way around it. By changing the DoUSBOut to this...
    Code:
    ' ************************************************************
    ' * don't wait for USB interface to attach, abort if busy    *
    ' ************************************************************
    DoUSBOut:
       USBBufferCount = USBBufferSizeTX              ' TX buffer size
       USBService                                    ' keep connection alive
       USBOut 1, USBBuffer, USBBufferCount, OutBusy  ' if bus available, transmit data
       RETURN
         
    OutBusy:
      toggle PORTB.0         ' toggle led to show when USB is busy
    RETURN
    This will discard the current reading if the USB is busy, and go back and measure another pulse, (rinse and repeat).

    I've run it up to 500hz and it never "messes up".

    Of course, this won't be able to report every pulse to the VB program, Hopefully you don't need them all.

    HTH,
    DT

  9. #9
    Join Date
    Mar 2006
    Location
    Gothenburgh, Sweden
    Posts
    18

    Default

    Hi Darrel.

    Thanks for verifying the problem. Now I know that it is not just my program messing with me..

    But it's still confusing because when I use my Basic Stamp to simulate a signal, it works fine with 7ms High and 0ms low pulse. (BS code #3 in my first post.) This means that USBOut has enough time to execute even if the low pulse is only a few us. Can it be the vb app that is the bottleneck here?
    Pic send it quick but next time it try to send the pc is still busy with the last one. What do you think about that?
    If the pic is the bottleneck then I wonder how it can catch the next pulse without any problem? In that case it should be stuck in the DoUSBOut routine.

    I will make a test to measure 16 pulses, save all values in buffer(0) to buffer(31) and then send all 32byte to the pc. Sending 32 bytes takes 22.4us according to my tests so that should be just fine from the pic point of view. It will be interesting to se how the pc handle it.

    Unfortunatley I need to measure all pulses. I use the values in the vb app to calculate acceleration, rpm and total revs.

    My next task is to simultaneously check the USBIn for new data.
    This without halting the program. I have made some test with the code example from bruce at post:
    http://www.picbasic.co.uk/forum/show...05&postcount=3
    This seems to work but I have not test it at higher speed yet.
    Do you have any other good solutions to do this? Maybe using USB interrupt USBIF or something else?

    I'll let you know about my further test.

    Thanks again.

    Stefan.

  10. #10
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959

    Default

    > Can it be the vb app that is the bottleneck here?

    I was using a Delphi App, also created by EasyHID, and saw the same thing. So I doubt it's anything to do on the PC side.

    > If the pic is the bottleneck then I wonder how it can catch the next pulse without any problem? In that case it should be stuck in the DoUSBOut routine.

    As long as the frequency is less than 125hz, it never get's a BUSY response. But, once it goes above that, it does get "stuck in the DoUSBOut routine".
    This becomes evident if you try the first example in Post#8.

    > I will make a test to measure 16 pulses, save all values in buffer(0) to buffer(31) and then send all 32byte to the pc.

    I guess it depends on the highest frequency you'll need to measure, but you may not need to go that high. For say 10,000 RPM, you'll only need about 166 samples per second (Unless there are multiple pulses per rev). So if you capture 2 samples per report, you'll only need 83 reports per second, which should be well within the limits, and give a faster "Update Rate".

    > Do you have any other good solutions to do this? Maybe using USB interrupt USBIF or something else?

    Well, there's this ...
    Instant Interrupts - Revisited, post 148
    http://www.picbasic.co.uk/forum/show...0682#post30682

    Which works with this ...
    USBDemo, something to learn USB a little bit
    http://www.picbasic.co.uk/forum/showthread.php?t=5418

    DT

  11. #11
    Join Date
    Mar 2006
    Location
    Gothenburgh, Sweden
    Posts
    18

    Default

    Thanks Darrel.

    Fels like I'm on the right track again.
    I made some tests with USBIn today and it seems to work.
    I call DoUSBIn directly after the DoUSBOut so it has time enough to transmit before the next high pulse trig the ccp input.
    And if the drum is not rotating DoUSBIn is called by interval using Timer3.

    Regards

    Stefan.

Similar Threads

  1. Instant Interrupts - Revisited
    By Darrel Taylor in forum Code Examples
    Replies: 772
    Last Post: - 17th February 2016, 22:14
  2. Replies: 14
    Last Post: - 31st March 2009, 12:04
  3. USB 18F4550 in High or full speed???
    By Jonathan Orrego in forum USB
    Replies: 8
    Last Post: - 16th July 2008, 16:13
  4. Need Help with USB using PIC18F2455
    By iugmoh in forum USB
    Replies: 17
    Last Post: - 15th April 2008, 17:07
  5. Time to transfer data in EasyHID
    By Demon in forum USB
    Replies: 20
    Last Post: - 22nd August 2006, 16:06

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