Important update: Arm Announces End of Life Timeline for Mbed. This site will be archived in July 2026. Read the full announcement.
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!