Click here to Skip to main content
15,884,936 members
Please Sign up or sign in to vote.
4.00/5 (2 votes)
Hi every1....

Im trying to communicate my PIC (18f4550) micro controller with PC using USB HID, and a DLL driver. The host application is developed in C#. The data send to the pc is collected using Event catcher function. Communication, data receiving all the stuffs going well.
Though I speedup the data rate inside the micro controller program, the C# app does not display a significant data receiving rate, I think the problem might occur inside the event catcher function. I'll put both codes here...

Eg:- I send my data buffer at 500uS or 1mS speed to the pc, but the text box is not updated to given speed.


C#
using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Collections.Generic;
using USBHIDDRIVER;


namespace My_NEWWW_HID_CS{
   
    public partial class Form1 : Form{
        
        USBHIDDRIVER.USBInterface usb = new USBInterface("vid_1234", "pid_1234");
               
        public Form1(){
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e){

        }

        private void button1_Click(object sender, EventArgs e){
            try {
                usb.Connect();
                if (usb.Connect() == true)
                    MessageBox.Show("Connected !!!");
                else
                    MessageBox.Show("Not Connected !!!");
            }catch(Exception er){
                MessageBox.Show("BAAA");
            }
         }

        private delegate void setTextDelegate(byte []array);
        
        // set and update a text box using received data from microcontroller

        private void setText(byte []array){
            if (this.Outbox.InvokeRequired){
                this.Outbox.Invoke(new setTextDelegate(this.setText), array);
            }else{
                this.Outbox.Text = this.Outbox.Text + "\r\n" + array[1].ToString();
                this.Outbox.SelectionStart = Outbox.Text.Length;
                this.Outbox.ScrollToCaret();
                this.Outbox.Refresh();
            }
        }

        private void button3_Click(object sender, EventArgs e){
            byte[] DataWrite = new byte[64];
            if (usb.Connect() == true){
                DataWrite[0] = byte.Parse(textBox1.Text);
                usb.write(DataWrite);
                usb.enableUsbBufferEvent(new System.EventHandler(myEventCatcher));
                Thread.Sleep(5);
                usb.startRead();
                MessageBox.Show("Data Reading!");
                //Thread.Sleep(2000);
                usb.stopRead();
                DataWrite[0] = 20;
                usb.write(DataWrite);
            }
        }
        //this is the event catcher !!!
        public void myEventCatcher(object sender,System.EventArgs e){
            //MessageBox.Show("Event Caught");
            if (USBHIDDRIVER.USBInterface.usbBuffer.Count > 0){
                byte[] currentRecord = new byte[64]; 
                int counter = 0;
               
              while ((byte[])USBHIDDRIVER.USBInterface.usbBuffer[counter] == null){
                    lock (USBHIDDRIVER.USBInterface.usbBuffer.SyncRoot){
                        USBHIDDRIVER.USBInterface.usbBuffer.RemoveAt(0);
                    }
              }
                
                currentRecord = (byte[])USBHIDDRIVER.USBInterface.usbBuffer[0];
               
                lock (USBHIDDRIVER.USBInterface.usbBuffer.SyncRoot){
                    USBHIDDRIVER.USBInterface.usbBuffer.RemoveAt(0);
                }
                setText(currentRecord); //update text box with received data
                
            }
         }

           }//end class

}//end namespace



Micro controller code - (just to give an idea, i know this is not the place)

C#
HID_Enable(&readbuff,&writebuff);

  while(1){
     if(HID_Read()){
         Lcd_Cmd(_LCD_CLEAR);
         ByteToStr(readbuff[0],txt);

         if(readbuff[0]==10){
            writebuff[0]=2;
            while(!HID_Read()){
              HID_Write(&writebuff,64);
              Delay_us(500);
            }

         }else{
            while(!HID_Read()){
               Lcd_Out(1,10,txt);
            }
         }
     }


Can some1 please explain me how can I speed up data receiving rate in C# code ? Can I modify my event catcher code for it ???

Thanx
Regards
Anuradha
Posted
Updated 13-May-12 8:08am
v2

Hi,

important question for me is: do you run your microcontroller at usb 1.1 port?
If yes, data sending/receiving with USB is controlled by using time. The unit of time is the frame and length of each of frame is regulated by the bus clock (1KHz -> 1000 frames/s -> so one per millisecond)

See at Section "Frames and Microframes":
http://www.usbmadesimple.co.uk/ums_6.htm[^]

Do you've tried to flush frames after receiving?

Regards
 
Share this answer
 
On top of what has already been said, there is no way you're going to get 1,000 frames a second updating a textbox.

Your textbox should be painted on a "snapshot" schedule. Nobody can read 1,000 frames a second, so why are you trying to update at that rate? Update the textbox with the lastest value every half second or so.
 
Share this answer
 
Comments
sjelen 14-May-12 13:16pm    
That's a good point.
Ranabasu 15-May-12 12:56pm    
Yehh.. thnx for the point, so is there any object (here the textbox) to check or display such a data rate in C#? (can i plot a graph/ wave format sampled at this rate ?)
Dave Kreskowiak 15-May-12 17:18pm    
You're not going to get 1000 frames a second out of ANYTHING in Windows. You'll have a hard time coaxing that kind of data rate out of the video card itself even using DirectX.

You can sample at that rat, provided your hardware supports it. You'll NEVER display at that rate.

Hell, you don't even find 1000fr/sec displayed on a dedicated digital scope!
At first look I think setText() method is your bottleneck.
Try using BeginInvoke instead of Invoke.

this.OutBox is a TextBox?
Try:
C#
this.OutBox.AppendText("\r\n" + array[1].ToString());

instead of:
C#
this.Outbox.Text = this.Outbox.Text + "\r\n" + array[1].ToString();


I'm not familiar with USBHIDDRIVER library, but I would change myEventCatcher to do all it's work under a single lock:
C#
public void myEventCatcher(object sender,System.EventArgs e){
            //MessageBox.Show("Event Caught");
            if (USBHIDDRIVER.USBInterface.usbBuffer.Count > 0){
                byte[] currentRecord = new byte[64]; 
                int counter = 0;
              lock (USBHIDDRIVER.USBInterface.usbBuffer.SyncRoot){ 
                  while ((byte[])USBHIDDRIVER.USBInterface.usbBuffer[counter] == null){
                    
                        USBHIDDRIVER.USBInterface.usbBuffer.RemoveAt(0);
                  }
                  currentRecord = (byte[])USBHIDDRIVER.USBInterface.usbBuffer[0];
                  USBHIDDRIVER.USBInterface.usbBuffer.RemoveAt(0);
              }
                
                
              setText(currentRecord); //update text box with received data
                
            }
         }
 
Share this answer
 
Comments
Ranabasu 15-May-12 12:34pm    
Hi all... thnkx for the quick replies. Actually Im gonna develop this code for a pc based oscilloscope application. So the higher throughput makes better the app. I use the Outbox textbox to check the incoming data from the device to check the throughput of the usb device bus. May be I'm doing a mistake to check it just using a textbox. As Dave says it might be hard to read such a data rate,and I use usb2 port. I'm not much familiar with C# so I've a doubt about event handler, and I was looking for a way to improve the speed by modifying it. Thanx sjelen for the sugestion and I'll modify as u said, Thanx all :)
sjelen 17-May-12 7:30am    
In that case TextBox is definitely bad choice. As Dave said, none of the form controls can achieve that refresh rate. If you just want to measure throughput why don't you (instead of displaying all data) just read the data from USB, get the number of bytes/frames read, use that to calculate current speed periodically and display speed in TextBox.
Anyway, even for drawing a waveform you'll need a buffer. Then myEventCatcher could read the data as it arrives from USB (as fast as it can) and store it in the buffer. On the other end you can have display control process/draw that data at it's own (slower) speed.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900