Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
HID USB data rate
Vincent Donnefort wrote:
Hello,
I need to send to the Mbed 528bytes 25 times per second.
So I used HID USB on mbed and HIDAPI on my computer (with Qt). I make messages from 63bytes (and I add a "0x00" Report ID) to send a complete transfert to the mbed.
It works great but the data rate transfert is really bad (8kB/s to send the 528bytes...) I don't see how I can improve this rate. Can you help me?
Thanks a lot!
Dear Vincent,
could you find any solution for improve the data rate?
Selim.
Hi,
Concerning the HID usb interface, you can send up to 64bytes each millisecond (64 kBytes/s). For that you have to use:
USBHID hid(64, 64); send_report.length = 64; for (int i = 0; i < send_report.length; i++) { send_report.data[i] = rand() & 0xff; } //Send the report hid.send(&send_report);
Hope that helps
Sam
Hi Samuel,
Thanks for reply.
I tried as you wrote. It worked fine at 64kb/s. I tried my code after that . It also worked same data rate (I didn't do any changes on my code). But my code is works 8kb/s when I power off and power on the mbed. Why does it happen You think?
Thanks
Selim.
Hi Selim,
Quote:
I tried as you wrote. It worked fine at 64kb/s. I tried my code after that . It also worked same data rate (I didn't do any changes on my code). But my code is works 8kb/s when I power off and power on the mbed. Why does it happen You think?
I didn't understand very well. When you try my code, the rate is 64kBytes/s and when you use your code, the rate is 8kBytes/s ?
Sam
Samuel Mokrani wrote:
Hi Selim,
Quote:
I tried as you wrote. It worked fine at 64kb/s. I tried my code after that . It also worked same data rate (I didn't do any changes on my code). But my code is works 8kb/s when I power off and power on the mbed. Why does it happen You think?
I didn't understand very well. When you try my code, the rate is 64kBytes/s and when you use your code, the rate is 8kBytes/s ?
Sam
Samuel,
Your code works very well at 64 KB/s while mine works at 8 KB/s. But if i test my code after testing yours keeping the usb cable plugged in, my code also works at 64 KB/s. However, if i unplug the usb cable after testing your code and re-plug it (i.e. restart the mbed) my code goes back to work at 8 KB/s.
Selim.
Selim Olcer wrote:
Samuel Mokrani wrote:
Hi Selim,
Quote:
I tried as you wrote. It worked fine at 64kb/s. I tried my code after that . It also worked same data rate (I didn't do any changes on my code). But my code is works 8kb/s when I power off and power on the mbed. Why does it happen You think?
I didn't understand very well. When you try my code, the rate is 64kBytes/s and when you use your code, the rate is 8kBytes/s ?
Sam
Samuel,
Your code works very well at 64 KB/s while mine works at 8 KB/s. But if i test my code after testing yours keeping the usb cable plugged in, my code also works at 64 KB/s. However, if i unplug the usb cable after testing your code and re-plug it (i.e. restart the mbed) my code goes back to work at 8 KB/s.
Selim.
Meanwhile, my usb definitions in my code is same in yours
Hello Selim, are You using ticker in Your code? Can You please post Your code? I am also interested in "what is going on"?
little llumpu wrote:
Hello Selim, are You using ticker in Your code? Can You please post Your code? I am also interested in "what is going on"?
Hello,
No, I don't use ticker but I use adc interrupt. my code is:
#include "mbed.h" #include "USBHID.h" #include "stdio.h" #include "tanimlamalar.h" void adcInit(uint32_t ADC_Clk ); extern "C" void ADC_IRQHandler (void) __irq ; uint32_t ADCRead( uint8_t ); void sinyalVer(void); volatile uint32_t OverRunCounter = 0; volatile uint32_t ADCIntDone = 0, tumPiksellerOkundu = 0; void changeRowCol(unsigned char row, unsigned char column); void changeRowColOwnCode(unsigned char row, unsigned char column); unsigned int rowBusData[64] = {0,512,64,576,2,514,66,578,256,768,320,832,258,770,322,834,1,513,65,577,3,515,67,579,257,769,321,833,259,771,323,835,128,640,192,704,130,642,194,706,384,896,448,960,386,898,450,962,129,641,193,705,131,643,195,707,385,897,449,961,387,899,451,963}; //We declare a USBHID device. By default input and output reports are 64 bytes long. //USBHID hid(64,8 ,0x1234,0x0006); USBHID hid(64, 64); //This report will contain data to be sent HID_REPORT send_report; HID_REPORT recv_report; //AnalogIn adcCInput(p16); //Cartesian array i�in analog giri� PwmOut pwm(p21); DigitalOut adcToggle(p20); //adc okurken toggle yap�p kontrol ediyorum sadece DigitalOut transmitLed(LED1); DigitalOut receiveLed(LED2); DigitalOut debugLed(LED3); DigitalOut donguLed(LED4); BusInOut cRowBus(p5, p8, p10, p6, p9, p7); //Cartesian array sat�r pinleri. s�ras� �nemli BusInOut cColBus(p25, p26, p29, p27, p28, p30); //Cartesian array s�tun pinleri volatile unsigned char mainStateMachine =0, colIndex=0,rowIndex=0,sayac=0,colIndexTemp=0,rowIndexTemp=0 ; volatile unsigned int pixels[64][64],adcValue,averageCount,tempInteger,tempInteger1; volatile unsigned long averageValue; float pwmDutyCycleValue=0.50; unsigned int pwmPeriodUs=654; char c=0; int main() { send_report.length = 64; cColBus.mode(OpenDrain); cColBus.output(); cRowBus.mode(OpenDrain); cRowBus.output(); pwm.period_us(pwmPeriodUs); pwm = pwmDutyCycleValue; if (averageCount==0) averageCount=1; mainStateMachine=bekle; adcInit(13000000); ADCRead(1); while (1) { if (OverRunCounter>0) { while (1) { donguLed=~donguLed; wait_ms(500); } } //try to read a msg if (hid.readNB(&recv_report)) { receiveLed = !receiveLed; switch (recv_report.data[komut]) { case sadeceBirPikselOku: rowIndexTemp=recv_report.data[2]; // istenen piksel numaras�n� sakl�yorum. colIndexTemp=recv_report.data[3]; //changeRowCol(rowIndex,colIndex); //uygun kanala gec averageCount=recv_report.data[4]*256; //Average de�erini al averageCount+=recv_report.data[5]; send_report.data[0]=sadeceBirPikselOku; //Komut send_report.data[1]=rowIndexTemp; //Parametre 1 send_report.data[2]=colIndexTemp; //Parametre 2 send_report.data[3]=(char)((pixels[rowIndexTemp][colIndexTemp])>>8&0x00FF); send_report.data[4]=(char)((pixels[rowIndexTemp][colIndexTemp])&0x00FF); send_report.data[5]=(char)((int)(pwmDutyCycleValue*1000)>>8&0x00ff); send_report.data[6]=(char)((int)(pwmDutyCycleValue*1000)&0x00ff); send_report.data[7]=(char)((averageCount>>8)&0x00ff); send_report.data[8]=(char)(averageCount&0x00ff); hid.send(&send_report); transmitLed=!transmitLed; break; case averageSayisiYaz: averageCount=recv_report.data[2]*256; averageCount+=recv_report.data[3]; break; case tumunuToptanGonder: for (rowIndexTemp=0; rowIndexTemp<64; rowIndexTemp++) { for (colIndexTemp=0; colIndexTemp<32; colIndexTemp++) { send_report.data[(colIndexTemp*2)]=(char)(pixels[rowIndexTemp][colIndexTemp] >> 8) & 0x00FF; send_report.data[(colIndexTemp*2)+1]=(char)(pixels[rowIndexTemp][colIndexTemp] & 0x00FF); } hid.send(&send_report); for (colIndexTemp=32; colIndexTemp<64; colIndexTemp++) { send_report.data[(colIndexTemp-32)*2]=(char)(pixels[rowIndexTemp][colIndexTemp] >> 8) & 0x00FF; send_report.data[(colIndexTemp-32)*2+1]=(char)(pixels[rowIndexTemp][colIndexTemp] & 0x00FF); } hid.send(&send_report); } break; case pwmPeriyodYaz: tempInteger=recv_report.data[2]*256; // pwmFrekans i�in gelen us cinsinden periyot s�resi tempInteger+=recv_report.data[3]; if (tempInteger>0) { pwm.period_us(tempInteger); } tempInteger=recv_report.data[4]*256; // pwmDutyCycle degeri tempInteger+=recv_report.data[5]; pwm = (float)tempInteger/1000; pwmDutyCycleValue=pwm.read(); break; } // switch recv_report.data } //if (hid.readNB(&recv_report)) } //while(1) } //main void changeRowCol(unsigned char row, unsigned char column) { cRowBus.write(row); cColBus.write(column); } void adcInit(uint32_t ADC_Clk) { uint32_t pclkdiv, pclk; /* Enable CLOCK into ADC controller */ LPC_SC->PCONP |= (1 << 12); /* all the related pins are set to ADC inputs, AD0.0~7 */ LPC_PINCON->PINSEL1 &= ~0x00030000; //p0.24 fonksiyonunu s�f�rlar LPC_PINCON->PINSEL1 |= 0x00010000; //p0.24'�n� ad0.1 fonksiyonuna atar /* No pull-up no pull-down (function 10) on these ADC pins. */ LPC_PINCON->PINMODE1 &= ~0x00030000; //p0.24 pinmode s�f�rlar LPC_PINCON->PINMODE1 |= 0x00020000; //p0.24 pull-up or pull-down yok /* By default, the PCLKSELx value is zero, thus, the PCLK for all the peripherals is 1/4 of the SystemCoreClock. */ /* Bit 24~25 is for ADC */ pclkdiv = (LPC_SC->PCLKSEL0 >> 24) & 0x03; switch ( pclkdiv ) { case 0x00: default: pclk = SystemCoreClock/4; break; case 0x01: pclk = SystemCoreClock; break; case 0x02: pclk = SystemCoreClock/2; break; case 0x03: pclk = SystemCoreClock/8; break; } LPC_ADC->ADCR = ( 0x01 << 1 ) | /* SEL=1,select channel 0~7 on ADC0 */ ( ( pclk / ADC_Clk - 1 ) << 8 ) | /* CLKDIV = Fpclk / ADC_Clk - 1 */ ( 0 << 16 ) | /* BURST = 0, no BURST, software controlled */ ( 0 << 17 ) | /* CLKS = 0, 11 clocks/10 bits */ ( 1 << 21 ) | /* PDN = 1, normal operation */ ( 0 << 24 ) | /* START = 0 A/D conversion stops */ ( 0 << 27 ); /* EDGE = 0 (CAP/MAT singal falling,trigger A/D conversion) */ /* If POLLING, no need to do the following */ NVIC_EnableIRQ(ADC_IRQn); //LPC_ADC->ADINTEN = 0x1FF; /* Enable all interrupts */ LPC_ADC->ADINTEN = 0x102; return; } extern "C" void ADC_IRQHandler (void) __irq { uint32_t regVal; volatile uint32_t dummy; regVal = LPC_ADC->ADSTAT; /* Read ADC will clear the interrupt */ if ( regVal & 0x0000FF00 ) { /* check OVERRUN error first */ OverRunCounter++; regVal = (regVal & 0x0000FF00) >> 0x08; /* if overrun, just read ADDR to clear */ /* regVal variable has been reused. */ dummy = LPC_ADC->ADDR0; dummy = LPC_ADC->ADDR1; dummy = LPC_ADC->ADDR2; LPC_ADC->ADCR &= ~((0x7<<24)|(0x1<<16)); /* stop ADC now, turn off BURST bit. */ ADCIntDone = 1; return; } adcValue = ( LPC_ADC->ADDR1 >> 4 ) & 0xFFF; pixels[rowIndex][colIndex]=adcValue; if (colIndex<63) { colIndex++; } else { colIndex=0; rowIndex++; if (rowIndex==64) { rowIndex=0; } } changeRowCol(rowIndex,colIndex); // LPC_ADC->ADCR &= ~(0x7<<24); /* stop ADC now */ LPC_ADC->ADCR |= (1 << 24) ; //ADC durmadan devam ediyor. ADCIntDone = 1; return; } /***************************************************************************** ** Function name: ADCRead ** ** Descriptions: Read ADC channel ** ** parameters: Channel number ** Returned value: Value read, if interrupt driven, return channel # ** *****************************************************************************/ uint32_t ADCRead( uint8_t channelNum ) { //LPC_ADC->ADCR &= 0xFFFFFF00; LPC_ADC->ADCR |= (1 << 24) ;//| (1 << channelNum); /* switch channel,start A/D convert */ return ( channelNum ); /* if it's interrupt driven, the ADC reading is done inside the handler. so, return channel number */ } void sinyalVer(void) { debugLed=1; wait_ms(100); debugLed=0; wait_ms(100); debugLed=1; wait_ms(100); debugLed=0; }
Hello,
I need to send to the Mbed 528bytes 25 times per second.
So I used HID USB on mbed and HIDAPI on my computer (with Qt). I make messages from 63bytes (and I add a "0x00" Report ID) to send a complete transfert to the mbed.
It works great but the data rate transfert is really bad (8kB/s to send the 528bytes...) I don't see how I can improve this rate. Can you help me?
Thanks a lot!