I have usbasp programmer for AVR microcontrollers. This programmer uses libusb library. I've managed to connect it to pc, system detected new device and I managed to install driver for this device. It works well since I'm able to program AVR chips with it. So hardware part is 100% OK.
Now software part:
Using simple iterating over my libusb-win32 devices using LibUsbDotNet I find 2 devices. Both of them are named the same (and have same VID and PID) so I think this is composite device. Second one has some data in it. This is well shown on screenshots bellow.
And the code (it is just copy pasted from the examples)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LibUsbDotNet;
using LibUsbDotNet.Info;
using LibUsbDotNet.Main;
namespace USB_Test_CLI_CS {
class Program {
public static readonly int VendorID = 0x16C0;
public static readonly int ProductID = 0x05DC;
public static void Main(string[] args) {
UsbDevice usbDevice = null;
UsbRegDeviceList allDevices = UsbDevice.AllDevices;
Console.WriteLine("Found {0} devices", allDevices.Count);
foreach (UsbRegistry usbRegistry in allDevices) {
Console.WriteLine("Got device: {0}\r\n", usbRegistry.FullName);
if (usbRegistry.Open(out usbDevice)) {
Console.WriteLine("Device Information\r\n------------------");
Console.WriteLine("{0}", usbDevice.Info.ToString());
Console.WriteLine("VID & PID: {0} {1}", usbDevice.Info.Descriptor.VendorID, usbDevice.Info.Descriptor.ProductID);
Console.WriteLine("\r\nDevice configuration\r\n--------------------");
foreach (UsbConfigInfo usbConfigInfo in usbDevice.Configs) {
Console.WriteLine("{0}", usbConfigInfo.ToString());
Console.WriteLine("\r\nDevice interface list\r\n---------------------");
IReadOnlyCollection<UsbInterfaceInfo> interfaceList = usbConfigInfo.InterfaceInfoList;
foreach (UsbInterfaceInfo usbInterfaceInfo in interfaceList) {
Console.WriteLine("{0}", usbInterfaceInfo.ToString());
Console.WriteLine("\r\nDevice endpoint list\r\n--------------------");
IReadOnlyCollection<UsbEndpointInfo> endpointList = usbInterfaceInfo.EndpointInfoList;
foreach (UsbEndpointInfo usbEndpointInfo in endpointList) {
Console.WriteLine("{0}", usbEndpointInfo.ToString());
}
}
}
usbDevice.Close();
}
Console.WriteLine("\r\n----- Device information finished -----\r\n");
}
Console.WriteLine("Trying to find our device: {0} {1}", VendorID, ProductID);
UsbDeviceFinder usbDeviceFinder = new UsbDeviceFinder(VendorID, ProductID);
// This does not work !!! WHY ?
usbDevice = UsbDevice.OpenUsbDevice(usbDeviceFinder);
if (usbDevice != null) {
Console.WriteLine("OK");
} else {
Console.WriteLine("FAIL");
}
UsbDevice.Exit();
Console.Write("Press anything to close");
Console.ReadKey();
}
}
}
Here's output of this program
Found 2 devices
Got device: Van Ooijen Technische Informatica - USBasp
----- Device information finished -----
Got device: Van Ooijen Technische Informatica - USBasp
Device Information
------------------
Length:18
DescriptorType:Device
BcdUsb:0x0110
Class:VendorSpec
SubClass:0x00
Protocol:0x00
MaxPacketSize0:8
VendorID:0x16C0
ProductID:0x05DC
BcdDevice:0x0103
ManufacturerStringIndex:1
ProductStringIndex:2
SerialStringIndex:0
ConfigurationCount:1
ManufacturerString:www.fischl.de
ProductString:USBasp
SerialString:
VID & PID: 5824 1500
Device configuration
--------------------
Length:9
DescriptorType:Configuration
TotalLength:18
InterfaceCount:1
ConfigID:1
StringIndex:0
Attributes:0x80
MaxPower:25
ConfigString:
Device interface list
---------------------
Length:9
DescriptorType:Interface
InterfaceID:0
AlternateID:0
EndpointCount:0
Class:PerInterface
SubClass:0x00
Protocol:0x00
StringIndex:0
InterfaceString:
Device endpoint list
--------------------
----- Device information finished -----
Trying to find our device: 5824 1500
FAIL
Press anything to close
What I'd like to get is this simple code to detect this device which IS present (since simple iteration over all devices finds it and other tool "USB Cfg Interrogator" find it too).
This has been asked before but there were no constructive answer.
I also could use libusb-win32 c++ library and create some C# wrappers for it but if it is not needed and I can use LibUsbDotNet library I'd like to use it instead of creating wrappers myself.
What I'd like to get is this simple code to detect this device which IS present
You almost have that already. There is only one for which usbRegistry.Open() actually works.
There should be no other device - check that your use latest libusb-win32 version (1.2.6.0 at this time).
UsbDeviceFinder seems to have a problem with this phantom device.
You may try filter wizard to install device filter.
Related
I am using 32Feet.Net's sample (list below) with using statements removed for brevity.
static void Main(string[] args)
{
BluetoothClient client = new BluetoothClient();
BluetoothDeviceInfo device = null;
foreach (var dev in client.DiscoverDevices())
{
if (dev.DeviceName.Contains("moto g(6)"))
{
device = dev;
break;
}
}
client.Connect(device.DeviceAddress, BluetoothService.SerialPort);
client.Close();
}
The line client.Connect(device.DeviceAddress, BluetoothService.SerialPort); blows up with this error {"The requested address is not valid in its context 601D914C50BF:0000110100001000800000805f9b34fb"}.
The only thing I altered in the sample was to find my smart phone, the moto g6. What am I missing?
Before putting a bounty on this question, I need to clarify that I am also looking for documentation or examples of having a desktop computer running Windows 10 be able to receive a file from iOS or Android and without having to use the built-in Bluetooth step by step in Windows 10. I would like to know what to do to correct the error.
I realize there is Command Line Bluetooth, but it would be nice to click a button in a gui and transfer a file using 32Feet.net.
Looks like the issue is because of services that are running on the device https://archive.codeplex.com/?p=32feet
Are you sure that device you are using has SerialPort profile running?
Also, Can you try the following code by using
private void BluetoothClientConnectCallback(IAsyncResult ar)
{
// Write your Call Back Code here
}
static void Main(string[] args)
{
BluetoothClient client = new BluetoothClient();
AllDevices = client.DiscoverDevicesInRange();
foreach (BluetoothDeviceInfo Device in AllDevices)
{
if (Device.DeviceName.Equals("moto g(6)"))
{
if (!client.Connected)
client = new BluetoothClient();
client.BeginConnect(Device.DeviceAddress, Device.InstalledServices[0], this.BluetoothClientConnectCallback, client);
break;
}
}
client.Close();
}
Also, you have to pair your device before connecting. Check here
BluetoothSecurity.PairRequest(Device.DeviceAddress,"123456");
I am new in c#
I am trying to send command to USB port(usbport=========fx3(Cypress chip), to light on LED than with in the custom board))
I tried to scanport but it was failed because my computer(win10) recognized the usb as camera(fx3 is chip that image processing)
so i found this code in sysnet.pe.kr
using System;
using System.Threading.Tasks;
using Windows.Devices.Enumeration;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
ListDevices().GetAwaiter().GetResult();
}
private static async Task ListDevices()
{
var devices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
foreach (var item in devices)
{
Console.WriteLine($"{item.Id}: {item.Name}");
devices.
}
}
}
}
it works!!! so I found port
but i don't have idea how to send command to the port!!!
please help me ㅠㅠ
First you must read your camera documentation (from producer website or .. , it may have programing sdk)
Otherwise you can use LibUsbDotNet
Here is what I have,
A bluetooth wearable (MyoArm band).
Windows Mobile 10 with anniversary update.
Both of them are paired properly.
Now, here is what I am trying to do,
I am trying to enumerate the list of all services exposed by the bluetooth device connected to my windows mobile.
I would then like to read input streams, if the service provides one.
I went though MSDN documentation and here is what I have done so far.
P.S. I have added Bluetooth access to the capabilities in the application manifest.
private async void OnReceiveClick(object sender, RoutedEventArgs e)
{
var devices = await DeviceInformation.FindAllAsync();
IList<DeviceInformation> myBluetoothDevices = new List<DeviceInformation>();
foreach (var device in devices)
{
if (device.Name.Contains("myo"))
{
var trace = string.Format("Name: {2} \t Paired: {3} \t Kind: {1} \t Id: {0}", device.Id, device.Kind, device.Name, device.Pairing?.IsPaired);
builder.AppendLine(trace);
myBluetoothDevices.Add(device);
}
}
foreach (var myBluetoothDevice in myBluetoothDevices)
{
try
{
if (myBluetoothDevice != null)
{
var service = await RfcommDeviceService.FromIdAsync(myBluetoothDevice.Id);
// TODO: Read input stream somehow here!!!
log.Text = builder.AppendLine(string.Format("Name: {0} \t Id: {1} \t Device Info Name: {2} \t Connection Host Name: {3} \t Service Id: {4}", service.Device.Name, service.Device.DeviceId, service.Device.DeviceInformation.Name, service.ConnectionHostName, service.ServiceId.Uuid)).ToString();
}
}
catch (Exception ex)
{
builder.AppendLine(ex.Message);
}
finally
{
log.Text = builder.ToString();
}
}
}
When I run the code and click the "Receive" button, I get an exception while calling the RfcommDeviceService.FromIdAsync method.
Exception: Element not found. (Exception from HRESULT: 0x80070490)
Am I missing something here? I am new to programming with bluetooth devices, so am I approaching the problem correctly?
Firstly, please ensure the devices queried out by device name are Bluetooth devices since you find all devices not only Bluetooth devices for query. For find Bluetooth devices, DeviceWatcher is recommended and sample code please reference StartUnpairedDeviceWatcher() method in this file.
Secondly, I'm not sure why RfcommDeviceService.FromIdAsync(myBluetoothDevice.Id); cannot get a RfcommDeviceService instance but the official sample is not using this method for getting the service. It got the BluetoothDeivce firstly and then GetRfcommServices from the device.
var bluetoothDevice = await BluetoothDevice.FromIdAsync(myBluetoothDevice.Id);
var rfcommServices = await bluetoothDevice.GetRfcommServicesForIdAsync(RfcommServiceId.FromUuid(Constants.RfcommChatServiceUuid));
if (rfcommServices.Services.Count > 0)
{
service = rfcommServices.Services[0];
}
The RfcommServiceId is same as RfcommServiceProvider created. Details please reference the official sample which I have tested can run and find RfcommDeviceService instance successfully.
I'm trying to communicate with UHF RFID reader based on AS3992 chip.
This device is detected by Windows as standard HID and it works with 3rd party app (I found some UHF RFID Reader GUI by LinkSprite which works, but it seems like some older C++ application).
So I'm trying to integrate this device support into my .NET application. After some research I tried HidLibrary, but when I'm trying to write something to this device (initial sequence in this sample), it hangs on "write".
Does anybody know what I'm doing wrong?
Thank you!
My OS is Win 8.1 x64.
Here's the sample application:
using HidLibrary;
namespace HidTest2
{
class Program
{
static void Main(string[] args)
{
var devices = HidDevices.Enumerate(0x1325);
var rfid = devices.First();
rfid.OpenDevice();
rfid.Write(new byte[] { 0x31, 0x03, 0x01 }); // Application hangs here
while (true) // I can't get here
{
Thread.Sleep(50);
var result = rfid.Read();
Console.Write(result.Data);
}
}
}
}
PS: I also tried HidSharp, but I got same result. HID device detected, but I can't write into it.
PSS: This is the device: Link to ebay
I can't find a datasheet for the AS3229 chip that you mentioned, so I'm guessing here...
The device is probably presenting as a USB keyboard, so you would typically only be able to write LED status bits to it (Caps lock, Num lock, Shift). Is that what you are trying to write to it?
Try removing the write and just wait for the scanned RFID string to come in.
Edit: It looks like this device is presenting as a serial device over USB...I found a description closely matching it here:
https://s3.amazonaws.com/linksprite/cuttonwood/datasheet.pdf
If it's the same device you are testing then I would try communicating to it over a COM port API rather than using the relatively lower level HID APIs you have been using.
Because time by time I get an email how and if I solved this issue, here's an answer:
I had to replace original firmware for HID communication by firmware for serial communication (search for "as399x uart 115200 hex" or "as399x uart 9600 hex" on the internet) and then it worked like a sharm. Of course you need proper programmer for C8051Fxxx (about 20$ from China), USB-Serial converter and be familiar with some soldering (You'll have to solder pins on board for JTAG and Serial port).
As mentioned above, the device may not actually be a Hid device. Have you tried enumerating through USB devices instead of Hid devices? Here is some code to enumerate USB or Hid devices. The code is here.
For Hid devices use a ClassGuid of : 4D1E55B2-F16F-11CF-88CB-001111000030
and for Win USB devices use: dee824ef-729b-4a0e-9c14-b7117d33a817
https://github.com/MelbourneDeveloper/Device.Net/blob/master/src/Device.Net/Windows/WindowsDeviceConstants.cs
public async Task<IEnumerable<DeviceDefinition>> GetConnectedDeviceDefinitions(uint? vendorId, uint? productId)
{
return await Task.Run<IEnumerable<DeviceDefinition>>(() =>
{
var deviceDefinitions = new Collection<DeviceDefinition>();
var spDeviceInterfaceData = new SpDeviceInterfaceData();
var spDeviceInfoData = new SpDeviceInfoData();
var spDeviceInterfaceDetailData = new SpDeviceInterfaceDetailData();
spDeviceInterfaceData.CbSize = (uint)Marshal.SizeOf(spDeviceInterfaceData);
spDeviceInfoData.CbSize = (uint)Marshal.SizeOf(spDeviceInfoData);
var guidString = ClassGuid.ToString();
var copyOfClassGuid = new Guid(guidString);
var i = APICalls.SetupDiGetClassDevs(ref copyOfClassGuid, IntPtr.Zero, IntPtr.Zero, APICalls.DigcfDeviceinterface | APICalls.DigcfPresent);
if (IntPtr.Size == 8)
{
spDeviceInterfaceDetailData.CbSize = 8;
}
else
{
spDeviceInterfaceDetailData.CbSize = 4 + Marshal.SystemDefaultCharSize;
}
var x = -1;
var productIdHex = GetHex(productId);
var vendorHex = GetHex(vendorId);
while (true)
{
x++;
var isSuccess = APICalls.SetupDiEnumDeviceInterfaces(i, IntPtr.Zero, ref copyOfClassGuid, (uint)x, ref spDeviceInterfaceData);
if (!isSuccess)
{
var errorCode = Marshal.GetLastWin32Error();
if (errorCode == APICalls.ERROR_NO_MORE_ITEMS)
{
break;
}
throw new Exception($"Could not enumerate devices. Error code: {errorCode}");
}
isSuccess = APICalls.SetupDiGetDeviceInterfaceDetail(i, ref spDeviceInterfaceData, ref spDeviceInterfaceDetailData, 256, out _, ref spDeviceInfoData);
WindowsDeviceBase.HandleError(isSuccess, "Could not get device interface detail");
//Note this is a bit nasty but we can filter Vid and Pid this way I think...
if (vendorId.HasValue && !spDeviceInterfaceDetailData.DevicePath.ToLower().Contains(vendorHex)) continue;
if (productId.HasValue && !spDeviceInterfaceDetailData.DevicePath.ToLower().Contains(productIdHex)) continue;
deviceDefinitions.Add(GetDeviceDefinition(spDeviceInterfaceDetailData.DevicePath));
}
APICalls.SetupDiDestroyDeviceInfoList(i);
return deviceDefinitions;
});
}
I need to gather some system information for the application I'm developing. The memory available and the CPU load are easy to get using C#. Unfortunately, the CPU temperature it's not that easy. I have tried using WMI, but I couldn't get anything using
Win32_TemperatureProbe
or
MSAcpi_ThermalZoneTemperature
How can I do this? I'm wondering how monitoring programs, as SiSoftware Sandra, can get that information...
Here is the code of the class:
public class SystemInformation
{
private System.Diagnostics.PerformanceCounter m_memoryCounter;
private System.Diagnostics.PerformanceCounter m_CPUCounter;
public SystemInformation()
{
m_memoryCounter = new System.Diagnostics.PerformanceCounter();
m_memoryCounter.CategoryName = "Memory";
m_memoryCounter.CounterName = "Available MBytes";
m_CPUCounter = new System.Diagnostics.PerformanceCounter();
m_CPUCounter.CategoryName = "Processor";
m_CPUCounter.CounterName = "% Processor Time";
m_CPUCounter.InstanceName = "_Total";
}
public float GetAvailableMemory()
{
return m_memoryCounter.NextValue();
}
public float GetCPULoad()
{
return m_CPUCounter.NextValue();
}
public float GetCPUTemperature()
{
//...
return 0;
}
}
For others who may come by here, maybe take a look at : http://openhardwaremonitor.org/
Follow that link and at first you might think, "Hey, that's an application, and that is why it was removed. The question was how to do this from C# code, not to find an application that can tell me the temperature..." This is where it shows you are not willing to invest enough time in reading what "Open Hardware Monitor" also is.
They also include a data interface. Here is the description:
Data Interface
The Open Hardware Monitor publishes all sensor data to
WMI (Windows Management Instrumentation). This allows other
applications to read and use the sensor information as well. A
preliminary documentation of the interface can be found here (click).
When you download it, it contains the OpenHardwareMonitor.exe application, and you're not looking for that one. It also contains the OpenHardwareMonitorLib.dll, and you're looking for that one.
It is mostly, if not 100%, just a wrapper around the WinRing0 API, which you could choose to wrap yourself if you feel like it.
I have tried this out from a C# application myself, and it works. Although it was still in beta, it seemed rather stable. It is also open source, so it could be a good starting point instead.
You can indeed read the CPU temperature very easily in C# by using a WMI approach.
To get the temperature in Celsius, I have created a wrapper that converts the value returned by WMI and wraps it into an easy-to-use object.
Please remember to add a reference to the System.Management.dll in Visual Studio.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
namespace RCoding.Common.Diagnostics.SystemInfo
{
public class Temperature
{
public double CurrentValue { get; set; }
public string InstanceName { get; set; }
public static List<Temperature> Temperatures
{
get
{
List<Temperature> result = new List<Temperature>();
ManagementObjectSearcher searcher = new ManagementObjectSearcher(#"root\WMI", "SELECT * FROM MSAcpi_ThermalZoneTemperature");
foreach (ManagementObject obj in searcher.Get())
{
Double temperature = Convert.ToDouble(obj["CurrentTemperature"].ToString());
temperature = (temperature - 2732) / 10.0;
result.Add(new Temperature { CurrentValue = temperature, InstanceName = obj["InstanceName"].ToString() });
}
return result;
}
}
}
}
I'm pretty sure it's manufacturer dependent, since they will be accessed through an I/O port. If you have a specific board you're trying to work with, try looking through the manuals and/or contacting the manufacturer.
If you want to do this for a lot of different boards, I'd recommend contacting someone at something like SiSoftware or be prepared to read a lot of motherboard manuals.
As another note, not all boards have temperature monitors.
You also might run into problems getting privileged access from the kernel.
You can give the Open Hardware Monitor a go, although it lacks support for the latest processors.
internal sealed class CpuTemperatureReader : IDisposable
{
private readonly Computer _computer;
public CpuTemperatureReader()
{
_computer = new Computer { CPUEnabled = true };
_computer.Open();
}
public IReadOnlyDictionary<string, float> GetTemperaturesInCelsius()
{
var coreAndTemperature = new Dictionary<string, float>();
foreach (var hardware in _computer.Hardware)
{
hardware.Update(); //use hardware.Name to get CPU model
foreach (var sensor in hardware.Sensors)
{
if (sensor.SensorType == SensorType.Temperature && sensor.Value.HasValue)
coreAndTemperature.Add(sensor.Name, sensor.Value.Value);
}
}
return coreAndTemperature;
}
public void Dispose()
{
try
{
_computer.Close();
}
catch (Exception)
{
//ignore closing errors
}
}
}
Download the ZIP file from the official source, extract and add a reference to file OpenHardwareMonitorLib.dll in your project.
I extracted the CPU part from Open Hardware Monitor into a separate library, exposing sensors and members normally hidden into OHM.
It also includes many updates (like the support for Ryzen and Xeon) because on Open Hardware Monitor (OHM) they haven't accepted pull requests since 2015.
https://www.nuget.org/packages/HardwareProviders.CPU.Standard/
It's depends on if your computer supports WMI. My computer can't run this WMI demo either.
But I successfully get the CPU temperature via Open Hardware Monitor. Add the Openhardwaremonitor reference in Visual Studio. It's easier. Try this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenHardwareMonitor.Hardware;
namespace Get_CPU_Temp5
{
class Program
{
public class UpdateVisitor : IVisitor
{
public void VisitComputer(IComputer computer)
{
computer.Traverse(this);
}
public void VisitHardware(IHardware hardware)
{
hardware.Update();
foreach (IHardware subHardware in hardware.SubHardware) subHardware.Accept(this);
}
public void VisitSensor(ISensor sensor) { }
public void VisitParameter(IParameter parameter) { }
}
static void GetSystemInfo()
{
UpdateVisitor updateVisitor = new UpdateVisitor();
Computer computer = new Computer();
computer.Open();
computer.CPUEnabled = true;
computer.Accept(updateVisitor);
for (int i = 0; i < computer.Hardware.Length; i++)
{
if (computer.Hardware[i].HardwareType == HardwareType.CPU)
{
for (int j = 0; j < computer.Hardware[i].Sensors.Length; j++)
{
if (computer.Hardware[i].Sensors[j].SensorType == SensorType.Temperature)
Console.WriteLine(computer.Hardware[i].Sensors[j].Name + ":" + computer.Hardware[i].Sensors[j].Value.ToString() + "\r");
}
}
}
computer.Close();
}
static void Main(string[] args)
{
while (true)
{
GetSystemInfo();
}
}
}
}
You need to run this demo as an administrator.
You can see the tutorial in Using Open Hardware Monitor to get CPU temperature in C# and make a fan cooling system.
The mentioned WMI classes were not working for me in the latest version of Windows 10.
On my Dell laptop I could get the CPU temperature in Celsius like this via PowerShell:
$data = Get-WMIObject -Query "SELECT * FROM Win32_PerfFormattedData_Counters_ThermalZoneInformation" -Namespace "root/CIMV2"
#($data)[0].HighPrecisionTemperature
It can be done in your code via WMI. I've found a tool (WMI Code Creator v1.0) from Microsoft that creates code for it.
The WMI Code Creator tool allows you to generate VBScript, C#, and VB
.NET code that uses WMI to complete a management task such as querying
for management data, executing a method from a WMI class, or receiving
event notifications using WMI.