Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Does anyone here know a little C#

Status
Not open for further replies.
HID requires buffer length to be exactly the "size of the input report + 1". The first byte in the buffer must be set to 0 prior to calling. Otherwise it won't work. The file read will copy the report into the buffer starting from the second byte.

I'm not sure C# call will convey all the parameters to the underlying "ReadFile" call exactly as you specify them. If not, you will need to call "ReadFile" directly.

This is whats doing my nut in... In another HID example they use ReadFile slightly differently.. I can set the Write function to data.length -1 but the flush fails... I will try your changes and get back to you
 
Okay.... Making the buffer 65 bytes then calling FileStream.Write() works.... Then Flush() fails... If I comment out Flush() the the next FileStream.Read() fails with a slightly different exception..

"The supplied user buffer is not valid for the requested operation."

I wish I had learned .Net a while since.... Ive been neglecting my brain updates...
 
When reading you need to do the same thing - 65 bytes and first byte of the buffer set to zero. Zero is needed because it is ReportId. If you had multiple reports, you could read them by putting their Ids as a first byte, but since you don't have report Ids you need to set the first byte to zero before reading.

I don't think you need Flush, because it's nothing to flush. These are blocking operations. They won't return until the device responds.
 
The plot thickens.... Or not!!

I have run the original project "As is" in Visual studio 2013 using .NET 4..

The project failed at exactly the same place.. If I change the filestream Buffer to 65 ( the report buffer is 64 )
AND!!!! change the report buffer to 65.... Viola!!! I know it works because a little LED on the pic board flashes..

This interface is too temperamental for my liking...

Cheers NorthGuy I was going to chuck the monitor through the window...

I was assuming that the filestream write was working.... But because it returned NULL there was no buffer to flush!!!

All done.... Now I have to get the feature transfer done!!
 
Okay! Re-typed into visual studio 2008... Success!!

Now I am faced with a C programmers nightmare!!.... In C a byte array is basically a string!! in C# they are worlds apart!!

In C

char str[] = {"Hello World!!");

printf("%s",str);

In C#

byte[] whatever = new byte[65];

/*fill array via report...*/

whatever.ToString(); <---- Apparently not!!!!
 
What are you trying to do? If you want to convert a byte array to an ASCII string, just use
Code:
byte[] bytes = new byte[100];  // get some dummy data of 100 zeros
string mystring = Encoding.ASCII.GetString(bytes);
 
Sorry ! I should have posted...

I used this...

Console.WriteLine(Encoding.Default.GetString(report));

Now its a string I can get on with parsing.... Basically I have a datalogger with a single text file!! I have it running on an SD on Fat32.... Now via HID I want to transfer the text file to the PC... each line of the text file will have the same sized format of 25 bytes... So I'm going to send two lines each transfer.... I believe Split() is the function to retrieve each line after its converted t a string...

I also want to have time / date change facility, but this is secondary as the datalogger has a graphical touch screen and you can modify any parameter in situ!!!

Things are going better now... I've converted to a Form application so I can make it user friendly..

I have found a website that will let you use a VID and a PID for free as long as you keep to 3~5 rules

https://github.com/obdev/v-usb/blob/master/usbdrv/USB-IDs-for-free.txt

It will make it more professional than the basic VID of 1234.... and PID of 0001
 
Right! This isn't really C# related but more on the USB side...

I have my C# application running... It recognizes and talks to my device... Now I instigate a read... This will be a multiple read as fast as I can muster.... Can I just send report after report or do I have to receive at the same time????

Basically I'm supposed to poll the USB periodically, but a multiple read would be faster without the polling, bu I may loose synchronization.... If the PC is reading and the pic is writing I'll need some sort of handshake... But sending a report just to say "Got it, send the next" will add to the transfer time...
 
Can you use a thread that keeps trying to read from the USB device, so that you are unlikely to miss anything?

If you can receive duplicate reports from your read() function, you could put a counter byte at the start of the report so that you can detect duplicates. If you still want a handshaking mechanism, then you could do acknowledgement of multiple reports in a single write (use the counter byte of the received reports as the ID). This way you could send an acknowledgement message every 60 reports or so...
 
Not clever enough for cross threading... I have achieved it but never really understood the invoke method.. I believe its similar to function pointers or friend functions in C++..

Until I'm up to speed I'll try and get this working within the scope of a single form...

I'll first try to multiple read with the first usable byte as a counter!!! If that is a problem I'll use a report echo.. It'll be slower but at least it will work..

In C we can manipulate a byte array using a pointer... ie

char report[65];
char * arrayptr = &report[1];

so I could loose the report ID byte...

How is this done in C# other than a loop ???
 
Not clever enough for cross threading... I have achieved it but never really understood the invoke method.. I believe its similar to function pointers or friend functions in C++..
It's probably easier than in C++. Here's an example; just paste into a new windows forms application
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Threading;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        bool abortThread = false;
        Thread myThread;
        int cnt = 0;
        void myThreadFunc()
        {
            while(!abortThread && !this.IsDisposed)
            {
                byte[] bytes = new byte[10];// File.ReadAllBytes("example.usb.txt");        // read in report (apparently this is a blocking call)
                Thread.Sleep(300);
                bytes[1] = (byte)cnt++;
                if(!this.IsDisposed)
                    this.BeginInvoke(new Action<byte[]>(reportReceived), bytes);
            }
        }

        void reportReceived(byte[] report)      // this is run in the form thread, so you can access the controls in here if you wanted
        {
            Text = report[1].ToString();
        }

        public Form1()
        {
            InitializeComponent();

            // start the thread
            myThread = new Thread(myThreadFunc);
            myThread.Start();
        }
    }
}
It will just display a number counting from 0 to 255 in the form title text. Obviously for your use, you would read in the data from the usb device, and wouldn't sleep for 300ms (that's just for a demo).

In C we can manipulate a byte array using a pointer... How is this done in C# other than a loop ???
Just use an index.
Code:
int reportCnt = report[1];
If you want to iterate through all bytes, you can use the normal indexed C++ version
Code:
for(int i = 0; i < report.Length; i++)
    doSomething(report[i]);
Or use an enumerable
Code:
foreach(byte b in report)
   doSomething(b);
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top