QTimer problem?
-
Hi,
Your HID device is also capable of Bulk transfers. Only the 'normal' HID sequencial messages needs to be transmitted as described in your USD descriptor. In that descriptor you are also capable of adding a port that will be used for bulk transfer. Ok, you don't get error checking that much, so maybe if that's real important, try a data transfer port. You do not need the HID device sequential messages to do that.
Placing communication protocols in a different tread is always a good idea btw. So your GUI and communication timing do not interfere.
Greetz -
Thanks jeroentje... I will begin with a new thread (need to clean up code before I do that)... and then if it is not enough, I will add a bulk transfer endpoint.
-
OK.. I put the PollUSB function in a different thread.
I verify using : @qDebug()<<"Worker:: get called from?: "<<QThread::currentThreadId();@ that I am actually in another thread.
I get more consistent results, but it is always exactly 150ms in fact:
0.0150001049041748 seconds
Then I disconnected the device and got 1ms delay! So it is really the device that gets me 150ms delay.
-
What type of device is it? You made it?
If using Microchip controllers? USe interrupts ;-) -
I am using Microchip uC and I am also using interrupts. :)
I used a USB analyser this morning... and got interesting results.
I have about 1 to 2 ms between each successive read of the USB port.
So the real problem would be that the software skips frames??
If I recapitulate:
- Without usb connection, the software complete the loop in 1ms
- With usb connection the software takes 150ms to complete the loop
- With software and connection, the USB analyser tells me I have 1 frame each 1 to 2 ms.
-
Hmm, I think the bigger question is, what data do you need to transfer?
For a 'standard' HID device only a couple of bytes every 5 msec is more then enough. This is setup in your usb_descriptor.c file and is sequential.
Next to this, if you want large chunks of data transferred, you could setup a second endpoint that handles e.b. Bulk transfers or other MSD type of transfers. Then no timing will be used, only the time for ask/answer mechanism, but Windows will do that for you.
From Microchip download the application libs (which you did already?) and check out a couple of examples.
Maybe post the pollUSB function in the thread so I could take a look at it.
Your transfer rate should be much higher then 4 kb/s! I could flash a PIC24F256 in less then 3 seconds transferring the entire buffer and letting the chip program itself in bootloader mode ;-) So 256kB in 3 secs is about 800kB/s for estimated transfer rate ;-)
So, keep on trying, it could go much faster!
Post the code, we take a look at that. -
Yes... I know I could add another endpoint to transfert large chunk of data, but there is definitely an underlying problem that I don,t want to leave there.
Here is the pollUSB function;
@void HID_PnP::run()
{
timer = new QTimer();
connect(timer, SIGNAL(timeout()), this, SLOT(PollUSB()));
timer->start(1); //start in 1ms, will repeat ASAP (remainingTime=0;)
qDebug()<<"Worker:: get called from?: "<<QThread::currentThreadId();exec();
}void HID_PnP::PollUSB()
{if (isConnected == false) { device = hid_open(myVID, myPID, NULL); if (device) { isConnected = true; hid_set_nonblocking(device, true); timer->start(15); } } else { unsigned char *TxPtr; TxPtr = &TxBuff.Data[0]; //Calculate delay since last time we sent usb. We need at least 1ms for messages to process correctly double temps = QDateTime::currentDateTime().toMSecsSinceEpoch()/1000.0; static double lastTimeWeSentUSB=temps; double delay=temps-lastTimeWeSentUSB; lastTimeWeSentUSB=temps; // qDebug()<<"Worker:: get called from?: "<<QThread::currentThreadId(); if (TxBuff.Len>=MAX_STR&&delay>0.001) { // Send the packet with 65 bytes everytime (USB endpoint size is always 65 bytes to send) sendToUsb(TxPtr); if (TxBuff.Len >= MAX_STR) { // Send pending bytes in next loop. TxBuff.Len -=MAX_STR; // Point to next 64bytes. TxPtr += MAX_STR; } else { // No more bytes. TxBuff.Len=0; } } ////////////Read from device///////////////// if(isConnected){ if(hid_read(device, inBuf, sizeof(inBuf)) == -1) { closeDevice(); return; } receivedCommand(inBuf[0], inBuf, delay ); //qDebug()<<"Worker:: get called from?: "<<QThread::currentThreadId(); } inBuf[0]=0; } //Calculate delay since last time we sent usb. We need at least 1ms for messages to process correctly double temps2 = QDateTime::currentDateTime().toMSecsSinceEpoch()/1000.0; static double lastTimeWeReceiveUSB=temps2; static double lastTime=temps2; double delay=temps2-lastTimeWeReceiveUSB; static double numberOfbytes=0; if((temps2-lastTime)>10){ numberOfbytes+=64; double F_P_S=numberOfbytes/(temps2-lastTime); lastTime=temps2; numberOfbytes=0; //qDebug()<<"Worker:: get called from?: "<<QThread::currentThreadId(); }else{ numberOfbytes+=64; } lastTimeWeReceiveUSB=temps2;
}@
-
Ok... the problem is really is with my software.
Using USBlyser, I can reach up to 60KB/s, but the Qt software is missing frame. Using a break point at line 81 of the above code, I calculate delay=15ms every time even if USBlyser tells me 1.2ms.
I am using microchip hid.c file.
Thanks for your help.
-
I made some more tests. If I prevent the PollUSB function from sending or receiving commands and only measure how much time it takes between 2 successive PollUSB function it is 15ms if the device is connected and it is 1.6ms if the device is connected.
So I don't think this function is problematic.
-
OMG... found it!!
check out line 22.. it is a beautiful 15ms before start.. and it seems that was setting up a 15ms delay!
-
Now the hardest part comes in... plotting all that data in real time like an oscilloscope.