Do I even need libusb? - c++

I have a feature request on a project I work on, it is to integrate with a Paylife CC handheld, which has a USB connector to connect with the computer. I have the docs, and am reading up on it.
When I searched on google how to read/write to a usb device on linux, it said, use libusb.
I was wondering, is there another possibility? Can't I just open it like a file and write a stream to it, and read a stream from it?
I don't actually need to do anything fancy. I just need to write a string of control codes to the device, and it would be mildly nice to read back the ACK and Error codes. But since those are already displayed on the device screen, I don't have to do much with it, just deliver the total required for payment.
So my question is, what are my options?
The connected computer is a regular ol ubuntu linux box.

It is definitely possible when the device complies with one of the USB device classes -- drivers for them are universal.
If that's not the case, then you may stick with a manufacturer-provided or a third-party driver, given there is one and you possess enough of it's documentation.
If that's also not the case, libusb-1.0 is your resort, unless you want to write a kernel driver youself :)

Related

Easiest way to control USB TMC device on Windows/C++

I am developing C++/Qt application which interacts with Tektronix TDS2002 oscilloscope via USB. The oscilloscope appears as "USB Test and Measurement device (IVI)".
Currently I use TekVISA library supplied by the oscilloscope's vendor. It works, but it is huge, old, buggy and poorly maintained. Therefore I would like to bypass the library and interface the device directly.
So far I have found this simple library: https://github.com/xyphro/WinUsbTmc It is exactly what I am looking for, but it uses libusb which requires to install some device filter and in addition it is advised to be more development tool than customer solution. Do you have any experience on this?
What is the easiest way to interact with USB Test and Measurement device in Windows/C++/Qt?
Thank you for your suggestions :)
You need a USB driver. My oscilloscope works with the driver included in this VISA package (the driver can be extracted very easily): http://www.keysight.com/main/software.jspx?cc=CZ&lc=eng&nid=-11143.0.00&id=2504667&pageMode=CV I assume all USB TMC devices can use the same driver, but I have no possibility to check this.
USB driver can be accessed via standard Windows functions. Guys on this forum were really close:
https://forum.tek.com/viewtopic.php?f=568&t=137573 and also this document was very useful: http://www.ivifoundation.org/downloads/Class%20Specifications/Ivi-6%202_USBTMC_2010-03-23.doc
You cannot write commands to OSC directly - data you send and receive have certain header which has to be in the correct format, otherwise the oscilloscope ignores the message. See reading and writting implementation in this simple library: https://github.com/xyphro/WinUsbTmc I didn't use this library because it uses libusb library which uses some kind of device filter and I personally do not like this concept (and in addition I have genuine working driver).
Data you read have also a simple header. To ensure you fit the header structure on input data well, you should first flush the input buffer. Then you issue reading request (using write command - see WinUsbTmc library above) and finally you receive the data and fit the header on its beginning.
I hope this will help to somebody :)
With regards
klasyc

Rtmidi opening ports?

I am working on a C++-based MIDI sending app and it's the first time I'm working with MIDI.
I chose the RtMidi library because it seems to be the most complete library around, but I'm open to suggestions.
The OS that I'm working on is Windows 7 and I have an USB-MID interface installed and it's working with other programs (i.e. Roland UM-One).
Now I may be way off-track, but I'd expect that when you do a search for ports, it should show this device.
When compiling the example code for RtMidi i get no ports; in or out.
What am I missing?
Do i need to open a virtual port?
This is also for others experiencing a similar issue as well:-
When I first started using RtMIDI, if you don't specify (on OSX at least) a macro define for the target system, the example code by default uses a dummy MIDI device, and this will have no MIDI ports.
Once I had specified MAC_OSX_CORE, then RtMIDI used the correct architecture and returned the MIDI devices on my system as expected. Perhaps you have to do something similar for your system - check the docs under "Compiling":
http://www.music.mcgill.ca/~gary/rtmidi/index.html#compiling
I've worked briefly with RtMidi and it is, as you stated, a rather complete library. However, when working with MIDI devices, you have to take the specific issues of this type of devices into account.
Another thing is that cheap USB-MIDI adapters often simply refuse to work with some applications "just because". They are very simple inside, yet apparently chinese manufacturers are still able to make malfunctioning devices.
If you're using unmodified, example code, and it's not showing your device, I'll first ensure all other apps that might be using it are closed, then try again. Creating a virtual interface is also a nice idea; I personally use freeware LoopBe1 for it. If it will show the virtual, but not the real interface, then the problem is with device itself. In that case you might want to experiment with different drivers or simply plugging it into a different port.
If it doesn't show any device, neither real nor virtual, then I strongly suspect there's something wrong in the way you build/run the application.

Detect an attempt to read from opposite end of pipe/fifo in Linux

I am thinking of implementing a sort of daemon/service in C/C++ for linux, that would communicate with a specific gpib device through shell (using linux-gpib library).
The idea is that the daemon would scan for all existing devices and would create a file/pipe /dev/gpib#-* (where * would be their address on specified gpib bus) for each device. The use would be such as of /dev/com#. I could then type into command-line:
echo "*IDN?" > /dev/gpib1-12
which would send the "*IDN?" string to device 12 on board 1. So far it is a peace of cake...
The problem starts, when I want to retrieve data from the device. I want it to work analogically, so that
cat /dev/gpib1-12
would write out what has the device to say... But I can not know which command, I have sent to the device, would make the device to return a string (value) and which wouldn't. So my options are:
Repeatedly check (while-loop) if the device has anything to reply and send it to the corresponding pipe afterwards.
-or-
Query the device only when the client program attempts to read from the /dev/gpib#-* pipe. This would have to be served through 'signals' and 'waits'.
For obvious reasons (performance and/or latency handicap) I do not want to implement solution 1. I do not know how to do the the other thing though... I feel, that it must be possible to implement on the ol'mighty linux, but how? I did read this and I think that some spin of the function select() is the right way forward, but I can not figure out how to use it for my problem. I also stumbled upon this, where the guy explains how to do something similar, yet sooo different (code mosfet.c).
The question is: how can I immediately detect and react upon an attempt to read from the other side of pipe/FIFO/file via signaling, waiting or interrupts?
Thanx for answers.
PS: It is half past seven in the morning here (yep another sleepless night), so please excuse my broken English...
PPS: Oh yes, and if anyone would already know of such gpib daemon for linux, or if the think I am asking (accessing individual devices through file I/O) would be possible via the linux-gpib library, please let me know. I did read the doc's and src's for linux-gpib, but found nothing helpful. All the linux-gpib library provides are bindings to C, Python, etc.
PPS: Are there maybe other alternatives to using pipes?
If you just need a nice terminal for your gpib device, you can use python (or even better ipython).
linux-gpib comes with python wrappers (for the code look here). so in your shell open python by typing python
In the python interpreter you can easily communicate with the device like this
>>>import Gpib
>>>device = Gpib.Gpib(pad=2)
This opens a connection to the gpib device with the primary address 2. To communicate with it simply do
>>>device.write('*IDN?')
>>>device.read()
'HEWLETT-PACKARD,33120A,0,8.0-5.0-1.0'
To simplify it even further, use ipython instead of plain python. This gives you tab-completion and much more.

How to most properly use libusb to talk to connected USB devices?

How do I most properly use libusb to talk to connected USB devices?
Specifically, how do I transfer data to the USB devices, receive information from the devices, find out the name of the connected device, if they have storage, etc.
More specifically, I will be running this on a Mac OS X machine, so I know I can't just use Windows header files.
If there is a good explanation on libusb and USB devices, that would be helpful too.
Here is a post on a similar question that might be useful to you. I include plenty of links.
But maybe you'd rather see it here. So in that case, here it goes!
Libusb allows you to enumerate devices and select the one you want based on a specific Vendor/Product id (V/P Id). If you don't know this and can't find it online with the product's description then you can easily find it.
If it is not online you will need to use an app similar to lsusb on Linux. (I don't believe it is on Mac.) When you run lsusb it lists connected devices and their V/P Ids. You can easily find your device by unplugging, running lsusb, and plugging the device back in and comparing. It's a piece of cake. Any usb list app on Mac will hopefully display the V/P ID like lsusb does.
Then once you have this V/P ID you will use libusb (if using 0.1) to enumerate all devices and find the device that matches that id. (I support using libusbx which happens to have a single find device function based on V/P id - in fact, libusbx is a whole lot more concise all around.)
After selecting your device you will send a packet using either Feature or Output Reports. This is the most complicated part because the packet you send is dependent on the individual device I believe. It is 8 bytes of data and only one of which is a single character you wish to send to the usb device. (If you wanted to send 8 characters, you would have to loop through an array of chars and send a feature or output report for each character.)
As an example feel free to reference a rather specific terminal example I wrote for controlling two LEDS. If it's helpful, great! It contains a libusbx and libusb-0.1 example.
I hope this helps!
The official site for libusb 1.0 (the newer and recommended version) is https://libusb.info/. The API documentation is at http://api.libusb.info. Click on the Modules section to walk through the different function areas. The source is at https://github.com/libusb/libusb and you can see some working examples at https://github.com/libusb/libusb/tree/master/examples. Hope that helps!
The article from #user2469202 is a good basic intro also.
The process that you can follow is:
Get the VID, PID for the device that you want to communicate using lsusb
Try to open the device and read the device descriptor
If you want name of the device use string descriptor to get that
Check if any kernel driver is attached. If it is, then detach it and do some raw data transfer
After getting the response again re-attach the driver.

Access USB hardware (pressure sensor matrix with native C++ API) using Python

I am working with a pressure-sensing mattress having a USB interface. The maker provides USB device drivers for Windows, and an API written in C++ which has functions to request data and set some parameters.
Currently, I cannot use this sensor for testing some Python data-visualization scripts directly, having had to ask my coworkers to write a text-logger for me, and then I read this information offline with Python.
Also, I cannot use Linux at all with the sensor, because there are not drivers for Linux, and I do not know where to start to "hack" the sensor, and that is why I am asking:
"If I were to try to read data from this sensor directly with Python and perhaps in Linux, what should I do first, or read first?"
EDIT: the device has an FTDI driver (FTD2XX.dll) if it helps.
Any help would be very welcome
Odds are fairly good it's a HID device, in which case you can probably start to write a userspace linux driver for it using libhid. First place to start with that would be enumerating the tree that gives you information about its capabilities. (lsusb -vvv or Example)
Failing that you can use libusb on linux (and other platforms too these days) to write a userspace driver still. You'll want to use something like usbsnoop or a real hardware equivalent to see what the official driver does when it's talking to the device and mimic it from there.
From the python side you can probably generate a decent wrapper to the existing C++ API using SWIG for relatively little effort, especially compared to developing an entirely custom driver.
Update:
If it's an FTDI device then it's might be a lot simpler to work with. Depending on what the vendor and product ID are showing it might automatically work with the FTDI driver in Linux, giving you as USB serial port. Failing that there are parameters to the module - vendor and product that I believe you can use to make it claim other devices besides the pid/vid combinations it knows about already. From there you can try opening the serial port device with different settings. With luck it might be sending state info regularly already.
If it's not you want to try and discover what the official software sends to make it start playing. You're back into the realm of sniffing again, but I think there might well be things that do it at the serial layer instead of the USB layer for windows (although I can't name any). You might also learn something by trying to make their library use a software emulated serial port instead of the FTDI device and seeing what it writes.
The FTDI chips have a linux driver. Just go to the FTDI website and download it. The driver creates a virtual serial port. You can use PySerial to interface with it.
Too bad I didn't see the post sooner!