I have a QR-Code Scanner Device which is connected via USB with my Computer. The device itself is set to the HID Keyboard Interface. I tried to detect a new QR-Code with the hidlibrary, but unfortunately I can't get it to work. I am using WPF, C# and .NET Core. I tried something like this:
devices = HidDevices.Enumerate(0x05E0, 0x1200).ToList();
SelectedDevice = devices.FirstOrDefault();
SelectedDevice.OpenDevice();
SelectedDevice.Inserted += SelectedDevice_Inserted;
SelectedDevice.Removed += SelectedDevice_Removed;
SelectedDevice.ReadReport(OnReport);
private void OnReport(HidReport report)
{
if (!SelectedDevice.IsConnected) return;
var byteFromDevice = report.Data;
SelectedDevice.ReadReport(OnReport);
}
private void SelectedDevice_Removed()
{
logger.Info("Scanner device removed!");
}
private void SelectedDevice_Inserted()
{
logger.Info("Scanner device attached");
SelectedDevice.ReadReport(OnReport);
}
I am pretty sure that the VendorID(0x05E0) and the ProductID(0x1200) are correct. For safety I'll attach a screenshot of the device settings from windows. When I try to run this code I get this error message: Operation is not supported on this platform.
I searched a lot on google on how to get the scanned data from a QR-Code Scanner but can't find anything working. This hidlibrary was my last chance but somehow it does not work.
I saw things like getting the KeyDownEvent from the QR-Code Scanner, but the problem is, that the code where I receive the events is not in a Form or Window. Therefore I can't receive these events.
Change your device to "USB Serial" and then use SerialPort Class
See this post for how to read the data.
Related
I'm facing a very strange three-way headache. I'm using Unity Engine and a BrainLink Bluetooth device as a source of input. I connect to the BrainLink device automatically via code using a library called Neurosky.ThinkGear and so far these two work fine together, but that's assuming the device has been paired manually via Bluetooth & Other Devices window.
Now I've been asked to also PAIR the device automatically, and this is where I hit a snag. Because using Unity Engine I can't use the windows runtime stuff (like Windows.Enumeration.Devices), I've decided to use the InTheHand 32Feet solution for Bluetooth devices and it seems to kind of work. The device appears as listed in Bluetooth & Other Devices if it wasn't already and it's listed as Paired as well. The problem is that when paired via code and not manually, the library that handles connecting to the device (aforementioned Neurosky.ThinkGear) can't connect to the device. It only connects if the device is removed and paired again via Bluetooth & Oher Devices window.
The Code I'm currently testing is as follows:
private void Start()
{
Debug.Log("Operation Start");
//btClient is a class field
btClient = new BluetoothClient();
//Search for existing paired devices that contain "brainlink" in their name
BluetoothDeviceInfo btDevice = CheckExistingPairedDevices();
if (btDevice == null)
{
Debug.Log("No paired device found, trying to discover");
//Try to discover devices in range with "brainlink" in their name
btDevice = TryDiscoverDevice();
}
if(btDevice!= null)
{
Debug.Log("Found Device " + btDevice.DeviceName+", checking for pairing");
bool paired = AttemptPair(btDevice);
Debug.Log("Pair Status: " + paired);
}
else
{
Debug.Log("Could not discover device");
}
CloseClient();
}
This is the method that handles pairing. At the moment, I never pass a value to pin but it's there just in case I need to support other devices in the future.
private bool AttemptPair(BluetoothDeviceInfo btDevice, string pin = null)
{
//Check if this device has been paired before
if (btDevice.Authenticated)
return true;
bool result = BluetoothSecurity.PairRequest(btDevice.DeviceAddress, pin);
btDevice.Refresh();
return result;
}
I have zero knowledge about your devices/tools, but what I know is that to establish a Bluetooth connection, we need to discover devices first.
The reason is that such a discovery creates an object that is later used on Bluetooth actions (e.g., pairing, connecting).
The device appears as listed in Bluetooth & Other Devices if it wasn't
already and it's listed as Paired as well.
I think by this, what you mean is previously paired devices. The device appearing on the list might not mean that the device is currently discovered. I suggest change your code accordingly where you perform discovery first.
I am using Lecia Disto e7100i which basically measures distance and area using laser. This device has bluetooth and can be paired with windows.
I am trying to develop an wpf app that reads the mesaured data using c#
There is no sdk that comes along with the device.
I have tried to use 32feet.Net but since there is no proper documentation I don't know where to start.
Is there any way that I can do to solve my problem?
This is not a full response, instead its more of a guideline on how to resolve your issue:
Pair the device with your Computer
Run the included software that displays the data somehow
Use WireShark to analyze the traffic
see if it is a standard protocol type or something custom
understand the protocol and reimplement it using c# and BluetoothSockets
To get started, you can try:
var client = new BluetoothClient();
// Select the bluetooth device
var dlg = new SelectBluetoothDeviceDialog();
DialogResult result = dlg.ShowDialog(this);
if (result != DialogResult.OK)
{
return;
}
BluetoothDeviceInfo device = dlg.SelectedDevice;
BluetoothAddress addr = device.DeviceAddress;
Console.WriteLine(device.DeviceName);
BluetoothSecurity.PairRequest(addr, "PIN"); // set the pin here or take user input
device.SetServiceState(BluetoothService.HumanInterfaceDevice, true);
Thread.Sleep(100); // Precautionary
if (device.InstalledServices.Length == 0)
{
// handle appropriately
}
client.Connect(addr, BluetoothService.HumanInterfaceDevice);
Also make sure that
Device appears in "Bluetooth devices" in the "Control panel".
Device is HID or change code accordingly.
Hope it helps. Cheers!
Try this demo project, and the following articles after that one.
Try to follow this tutorial
Here you can see a direct answer by the mantainer of 32feet, with which you can get in touch
Check also this answer
I've made a Bootloader implementation in a SAMD21J18A mcu, based on a
Atmel example. I can connect to the bootloader via USB CDC and it is recognized in windows as a COM port with the name: AT91 USB to Serial Converter, not showing any problems.
The COM-port works fine, I've made a working Windows Form C# program to download code to the bootloader. In the working program I've just manually set the PortName.
Now, I want to make the program more user friendly and want to make a ComboBoxto enable the user to pick the COM-port to use. Therefore I'm calling the GetPortNames function:
string[] Ports = null;
Ports = SerialPort.GetPortNames();
This works fine, as long as I don't plugin my bootloader.
If I attach eg. a FTDI device, it detects the device and adds it to the list, but if I attach the Bootloader("AT91 USB to Serial Converter"), then I get a System.StackOverflowException on the SerialPort.GetPortNames() function.
Does anyone know what is wrong with GetPortNames or the USB CDC driver?
Thanks for your help mjwills :-)
The complete program were too large to show here, so I decided to make a short program showing the problem. However, the new short program didn't have this problem. So, found out the problem didn't directly originate from the line refered to by visual studio.
Anyway, here's the function which created the problem:
// Update comport pull-down list:
private void UpdateComPortList()
{
string[] Ports = null;
Ports = SerialPort.GetPortNames();
int index = -1;
string ComPortName = null;
comboBoxComPort.Items.Clear();
do
{
index += 1;
comboBoxComPort.Items.Add(Ports[index]);
//if(Properties.Settings.Default.comPort == Ports[index]) comboBoxComPort.SelectedIndex = index;
}
while (!((Ports[index] == ComPortName) || (index == Ports.GetUpperBound(0))));
comboBoxComPort.Items.Add("update list...");
}
If I remove the line which I've now commented, the program works.
I think the problem is that, I try to select an item while at the same time adding items...
I have gone through Microsoft Developer website. There is development using pointOfService. but I am getting error in:
scanner = await BarcodeScanner.GetDefaultAsync();
SAYING: IAsyncOperation does not contain definition for GetAwaiter
May be I am missing any Reference but not sure which one.
If there is any other way to do please share it. And one Important thing I am developing Windows Desktop Application.
Complete Code is:
private async Task<bool> CreateDefaultScannerObject()
{
if (scanner == null)
{
UpdateOutput("Creating Barcode Scanner object.");
scanner = await BarcodeScanner.GetDefaultAsync();
if (scanner != null)
{
UpdateOutput("Default Barcode Scanner created.");
UpdateOutput("Device Id is:" + scanner.DeviceId);
}
else
{
UpdateOutput("Barcode Scanner not found. Please connect a Barcode Scanner.");
return false;
}
}
return true;
}
You cannot use the BarcodeScanner class in a Desktop application. This class is part of the new "Universal Windows Platform" that only works in Universal Apps for Windows 8 and Windows 10.
The easiest way to use barcode scanners is by having them emulate the keyboard. You can configure the scanners to send prefix and suffix characters before and after the actual code.
Usually, you will configure "Return" as the suffix and some special code that the user usually never enters as the prefix.
If you process all keypress events in your application you can react to receiving the configured prefix by clearing and setting focus to a textbox that is meant to receive the barcode. The barcode is then (via the keyboard emulation) inserted into the textbox and return is pressed.
The textbox can then process this the same way as if a user had entered the code into the textbox and pressed Return.
For some more details and code samples see http://www.codeproject.com/Articles/296533/Using-a-bar-code-scanner-in-NET
I was looking for a cross platform way of getting usb arrival and removal events in C# and i found "LibUsbDotNet C# USB Library" (http://sourceforge.net/projects/libusbdotnet/?source=navbar).
It works as it should but in Linux it seems that i can't get device mount point (path). In Linux it uses "libusb" library which does not have a method for getting the device path.
Here is a simple code sample that detects the device events:
internal class DeviceNotification
{
public static IDeviceNotifier UsbDeviceNotifier = DeviceNotifier.OpenDeviceNotifier();
private static void Main(string[] args)
{
// Hook the device notifier event
UsbDeviceNotifier.OnDeviceNotify += OnDeviceNotifyEvent;
// Exit on and key pressed.
Console.Clear();
Console.WriteLine();
Console.WriteLine("Waiting for system level device events..");
Console.Write("[Press any key to exit]");
while (!Console.KeyAvailable)
Application.DoEvents();
UsbDeviceNotifier.Enabled = false; // Disable the device notifier
// Unhook the device notifier event
UsbDeviceNotifier.OnDeviceNotify -= OnDeviceNotifyEvent;
}
private static void OnDeviceNotifyEvent(object sender, DeviceNotifyEventArgs e)
{
// A Device system-level event has occured
Console.SetCursorPosition(0,Console.CursorTop);
Console.WriteLine(e.ToString()); // Dump the event info to output.
Console.WriteLine();
Console.Write("[Press any key to exit]");
}
}
and here is a sample of the output:
[DeviceType:DeviceInterface] [EventType:DeviceArrival] Name:usbdev1.17
BusNumber:1 DeviceAddress:17 Length:18 DescriptorType:Device
BcdUsb:0x0200 Class:PerInterface SubClass:0x00 Protocol:0x00
MaxPacketSize0:64 VendorID:0x059F ProductID:0x1014 BcdDevice:0x0000
ManufacturerStringIndex:1 ProductStringIndex:2 SerialStringIndex:3
ConfigurationCount:1
[Press any key to exit][DeviceType:DeviceInterface]
[EventType:DeviceRemoveComplete] Name:usbdev1.17 BusNumber:1
DeviceAddress:17 Length:18 DescriptorType:Device BcdUsb:0x0200
Class:PerInterface SubClass:0x00 Protocol:0x00 MaxPacketSize0:64
VendorID:0x059F ProductID:0x1014 BcdDevice:0x0000
ManufacturerStringIndex:1 ProductStringIndex:2 SerialStringIndex:3
ConfigurationCount:1
My question is how can I get the path of the device attached or removed, or how can I bind the info returned by libusb with an actual device path?
You need to use UDev instead of libusb. Libusb merely tells you about what USB devices are on the system, but won't tell you anything about where they're mounted. UDev handles mounting them.
There is libudev and the documentation should be here: http://www.freedesktop.org/software/systemd/libudev/ but it appears to be down at the moment. Here's a tutorial on libudev: Tutorial: How to use libudev and SysFS in Linux
There is also a GLib based wrapper for libudev, docs here: http://ftp.osuosl.org/pub/linux/utils/kernel/hotplug/gudev/ and there appears to be a c# wrapper for libgudev.
But finally you may find using GLib's GIO easier than getting down to the udev level: Volumes and Drives API reference.
USB device files are usually stored in the path:
/dev/bus/usb
In that folder will be sub-directories that should match with your bus numbers above. Things will get complicated if the USB device isn't directly attached to the computer, for instance through a hub or other external device. Don't forget to convert from hex.