Teensy HID C# project

Status
Not open for further replies.

nlambuca

Member
Hi,
we are trying to get Teensy to send usb data to PC. Using Visual Studio and C# it seems we are having issues with some exceptions happening and not being able to connect.
Is there an example we can use? Has someone done it?

Thanks
 
Never had any latency problems with Serial and c# but that of course depends on the requirements. However, I'm not sure if HID will be better (latency is probably more a USB problem).
Anyway, never did communication over HID it but I can give it a try later today
 
Thanks. I need to send something like 5x 32bit words at 10Khz. Concept is kind of digital scope, no buffering. Real Time.
 
I could be wrong but I think usb 2 has like a millisecond frame, so my guess is you might not be able to send more than 1000 packets per second.

So question is can you package up more than Set of data per packet.
 
You might also consider the fact that "real time" display of data does not mean 0ms latency, because a typical display only shows a new frame every 16.667ms (at 60 Hz frame rate).
Even audio has a latency, although it varies based on the buffer size (and OS too, I guess).

Even if you use custom hardware, us humans tend not to notice a latency or timing discrepancy of a few milliseconds at all. So, strive for good and practical, not for perfect.
 
As promised, a minimal example which compiles and works. The Teensy firmware repeatedly sends a raw hid frame where the first byte contains a counter to the PC. The PC software waits until it receives a frame and writes the first byte of the frame to the console. Hope that helps.

Here the c# part (Windows Console App, I use the HID library from Mike O'Brian which you can install from nuget)

Code:
using HidLibrary;
using System;
using System.Linq;

namespace hid2
{
    class Program
    {
        static void Main(string[] args)
        {
            var teensy = HidDevices.Enumerate(0x16C0, 0x0486).Where(d => d.Capabilities.Usage == 512).FirstOrDefault();

            while (teensy != null)
            {
                var report = teensy.ReadReport();
                Console.WriteLine(report.Data[0]);
            }
        }
    }
}

and here the Teensy part

Code:
#include "Arduino.h"

uint8_t buf[64];

void setup()
{
   pinMode(LED_BUILTIN, OUTPUT);
}

byte cnt = 0;

void loop()
{
   buf[0] = cnt++;
   usb_rawhid_send(buf, 1000);

   digitalWriteFast(LED_BUILTIN, !digitalReadFast(LED_BUILTIN));
   delay(500);
}

Output:

hid.PNG
 
You might also consider the fact that "real time" display of data does not mean 0ms latency, because a typical display only shows a new frame every 16.667ms (at 60 Hz frame rate).
Even audio has a latency, although it varies based on the buffer size (and OS too, I guess).

Even if you use custom hardware, us humans tend not to notice a latency or timing discrepancy of a few milliseconds at all. So, strive for good and practical, not for perfect.

Nobody can read a 10khz updates...
Apart from that, you have to add the time the usb-transfer need. there is some latency, too, which depends on how many other devices are connected, the OS you use, maybe the chipset or the speed of your PC.
Depends how you defines "realtime". For human eyes, 10HZ (- notice: not kHz) is more than enough - even that is too fast to read, not to speak of any human reaction/interaction.
 
If one wants to get into the details of human perception, look at psychovisual and psychoacoustic modeling. Don't let the psycho scare you, is actually just modeling how humans perceive things, and is actively used when designing e.g. video and sound compression. Even "old" MP3 could use (depending on the compression software used!) psychoacoustic modeling to "hide" the quantization noise, by shaping it so that its spectrum follows the sensitivity of human hearing, yielding better sounding recordings using fewer bits.

Frank B is absolutely right that it all depends on the definition of "realtime". There is even a measurable latency from the point where photons hit your rod or cone cells in your retina, and the corresponding perception in the brain. Simply put, if you keep your total latency under 20ms or so (a common round figure, not a fixed precise value by any means), you have scientific literature to back the claim it is still "realtime". Anything less does not matter to us humans, and is just marketing speak. Anything longer (say, 100ms or more), and it becomes a bit more complicated; depends a lot on the user interface.
 
I didn't know that limitation.. so UART at 1M baud would be better?

Yes. BTW there is no such thing as a 1M baudrate for the USB Serial. It will always transmit with the full USB speed.

Here a (very) basic example how to read serial data from the Teensy in c#

Code:
using System;
using System.IO.Ports;

namespace test
{
    class Program
    {
        static void Main(string[] args)
        {
            SerialPort port = new SerialPort("COM27");  // See https://github.com/luni64/TeensySharp if you need to autodetect the teensy port

            port.Open();          
            while (!Console.KeyAvailable)
            {
                Console.WriteLine(port.ReadLine());
            }            
            port.Close();

            port.Dispose();            
        }    
    }
}

Teensy test code
Code:
#include "Arduino.h"

void setup()
{  
}

void loop()
{ 
   Serial.printf("Test: %d\n", millis());
}
 
I didn't know that limitation.. so UART at 1M baud would be better?

A UART at 1M baud - like Serial1 - would end up near 100,000 bytes/sec.

Would take non-HID USB, or faster UART rate, which Teensy can do - though not sure which one in use - Serial1 and Serial2 typically have best hardware FIFO support and 2+M Baud could work if the other end can keep up.
 
Status
Not open for further replies.
Back
Top