Making a QT-creator Application communicate with a Microcontroller - c++

Currently I want to create a qt application on my Desktop that say, has 3 buttons. These 3 buttons can change certain variables for my device, which will be connected to the desktop with a microcontroller.
I want my desktop application to be able to communicate with the microcontroller. For example, clicking a button might flip a certain boolean variable and the microcontroller will adjust accordingly.
I have no idea how to start and what sort of questions I should be asking and how to tackle this at a high level.
Thank you.
My desktop is a macbook pro retina 15-inch 2014 and my microcontroller is either an Teensy, or an Intel Atom.

I don't know what type of microcontroller you are using, but if it has support for UART you can use the QSerialPort lib (http://doc.qt.io/qt-5/qserialport.html) to send data using a serial port.
In case of an arduino, you can send messages using this lib directly via the USB emulated COM port. If it don't have USB emulated COM port, you should use a serial adapter (an Arduino board can play this role).

The first thing to look at is what communication buses are common between your desktop computer and your microcontroller. Does your microcontroller have USB or ethernet capabilities? Does your microcontroller have expansion boards for WiFi or bluetooth support? Do you have access to an I2C bus in your desktop PC?
Depending on the answers above, if your microcontroller and your computer do not share common communication buses, you might have to use intermediary hardware, for instance, you might want to use something like the FTDI USB (on your desktop) to UART (for the microcontroller) cables, you can find those here: http://www.ftdichip.com/Products/Cables/USBTTLSerial.htm
In that case I'd recommend using a cable with VCD drivers, so the cable appears as a Serial port to your computer, which you can access in QT by using QSerialPort (http://doc.qt.io/qt-5/qserialport.html)
There would be other similar solutions, but I'd say that, if there are no shared buses between your microcontroller and host, this would be one of the most universal. Maybe if you specify your microcontroller or embedded board We could help a little more.

Related

Wemos D1 Mini (ESP8266) control with USB

I have a Wemos D1 Mini (ESP8266), flashed with WLED and I want to create an application like .exe and have control on turning it on/off and choose colors. Does anyone have any idea how I can do without to connect on wifi and just do everything via USB?
To control the WLED firmware over USB, you would use the firmware's ability to be controlled over a serial connection. It looks like you would open the virtual serial port that appears when you plug in the device, at a speed of 115200, and then you take the same JSON that you would POST to /json/state for controlling it over WiFi, and instead send it over the serial connection, and get your responses back over the serial connection.
You could also implement the TPM2 protocol, or the Adalight protocol (which doesn't really seem to be documented except in code), as those are also supposed to be supported.
If you want to do all this in C++ on Windows, you might start by reading the (very old) Windows tutorials for Win32 API serial port programming. If you only want to target Win10 or newer, you could learn C++/WinRT and then use the new WinRT serial APIs. Or you could consult the answers to this question about serial programming on Windows.

Creating a Fake Serial Port to Emulate Modem

I'm quite new to programming at linux and its file-based communication.
I need to create a virtual modem (or modem emulator) at linux machine. The idea is that the software module that sends commands to hardware modem on an FPGA,
At FPGA:
SoftwareModule <= ttyACM => HardwareModem
What I need to achieve at my computer:
SoftwareModule <=> MyModemEmulator acting like a fake UART
Purpose is that the software module can be tested on a linux machine where I have a fake software modem UART(?) port. So the software module sends the modem commands and my fake modem module catches and responds accordingly. So my module will be actually acting like a hardware modem.
What could be the steps I need to take for that? I'm quite new to working with serial ports and don't have deep knowledge of linux or hardware stuff.
I have come across 'socat' but I'm not sure if that can really serve the purpose.
So far I have only learned how to create a basic file system with FUSE (as it was suggested by someone), but I'm not sure how can I use it for my purpose. I'm not looking for a proprietary solution, and not looking for windows based solution either.
Please guide me to the right directions.
Thank you !
Creating a Fake Serial Port to Emulate Modem
What you refer to as a "serial port" in Linux is actually a serial terminal with many software layers.
Study Linux serial drivers, and the termios man page for salient functions that need to be emulated.
And you have not even considered how to factor in the USB component of the communication path.
At FPGA:
SoftwareModule <= ttyACM => HardwareModem
...
My computer with ubuntu does not have ttyACM
A /dev/ttyACMx device node is only created when a USB serial gadget is connected to the host.
So it's not surprising that you cannot find such a device node.
What I need to achieve at my computer:
SoftwareModule <=> MyModemEmulator acting like a fake UART
You have stated the issue poorly, since you (misguidedly) think that a "fake UART" (integrated with your "MyModemEmulator") is the appropriate solution.
Do not try to emulate both a serial terminal and an external modem on the Ubuntu host, since you are "quite new to programming at linux and serial ports" and the task of accurately emulating a serial terminal is risky and expensive.
What your goal should be is:
SoftwareModule <= ? => MyModemEmulator
and the question is "what is needed in the middle to interface these two units?".
IOW you have posted an XY problem.
There are a plethora of SBCs (single board computer) that have a USB gadget port and can be configured as a USB serial gadget that uses CDC ACM.
Since the actual "hardware modem on an FPGA" will use a USB CDC ACM connection, you should consider using an actual /dev/ttyACMx serial terminal, and emulating just the external device ("hardware modem") with a SBC.
In other words, instead of trying to achieve:
SoftwareModule <=> MyModemEmulator + fake USB serial terminal
it should be much easier to use existing interfaces and implement:
SoftwareModule <= USB => emulated HardwareModem
with a SBC running your Linux application for modem emulation using /dev/ttyGS0 (a USB serial terminal on the gadget end).
By using an actual USB CDC ACM connection and not implementing the "fake USB serial terminal", this approach eliminates an entire layer of SW+HW emulation and its possible false test results.
Addendum
If the use and/or cost of embedded Linux on a SBC concerns you, then there is an alternative scheme to emulate the "hardware modem" on your Ubuntu PC host instead of the SBC using a USB-to-RS232-to-USB connection.
Acquire a pair (i.e. quantity 2) of USB-to-RS232 adapters and a (very short) null-modem cable.
Connect the DB-9 ends of the adapters to the null-modem cable to make a single cable with both ends having a USB male type-A connector.
Plug one adapter into the PC to create the /dev/ttyUSB0 device node. Treat this as the equivalent to /dev/ttyACM0 for your SoftwareModule.
Plug the other adapter into the PC to create the /dev/ttyUSB1 device node. Treat this as the equivalent to /dev/ttyGS0 for your emulated "hardware modem".
Develop, execute, and debug your emulated "hardware modem" on the Ubuntu PC host (without the unnecessary task of "creating a fake serial port").

Send zeroes and ones to the USB data pins?

Am trying to figure how can I make some software and USB hardware.
Let's put the hardware thing aside for now. For software, how can I send data to a USB port?
C++ / Java or any other language (prefer to be working on Linux).
USB ports are not like "dumb" RS-232 serial ports. It's a bus, that requires quite complicated handling, all driven by the host (the computer, typically). Very low-level operations such as "sending ones and zeros" to the data pins are more or less impossible.
The easiest way to program USB from user-space in Linux is probably to use libusb.
On the client (your custom USB hardware) end, either look for a system featuring a built-in USB controller, or a software stack. I don't think writing your own software stack is feasible, since you (no offense) don't seem to be quite at that level regarding your knowledge of USB.
V-USB is a software USB stack for Atmel's AVR microcontrollers, for instance.
As others have pointed out you have to write a driver for the USB device.
Another option is to communicate with the device using a serial protocol over USB, then your hardware needs an USB to serial chip. The best answer regarding USB over serial is in the question How to get C++ to perform I/O from a USB Port like a Serial Port by Mike DeSimone
If you want to bitbang I/O using USB, then you can connect a FTDI chip like the FT232 (which is used in many USB to serial cables) to the USB port.
On the PC you can use libFTDI to bitbang the I/O pins of the FTDI chip.
I think this is the easiest way for controlling I/O pins using USB.
An alternative to serial port emulation is USB HID (Human Input Device), which is supported on Linux out of the box. You'd use the "HIDAPI" to communicate with your device.
A usb port is just a serial port. Therefore, the first place that you want to look is writing a sofware to handle serial port communication.
Be aware that the OS may assign a different port number to the device whenever it's connected.

How to get C++ to perform I/O from a USB Port like a Serial Port

Is it possible to read/write from/to a specific USB port, avoiding all that USB handshaking stuff?
What I want to do is communicate with a microcontroller, for example, that doesn't have a USB driver on board via USB. I want my C++ application to be able to send data via a specific USB port and then to receive data from that same USB port.
Basically what I want to be able to do is treat that USB port like a serial port. Is this possible? Is there a workaround I can use?
Thanks in advance.
PS: I know this isn't the best way to go about communication with a uC, but let's assume, for some reason, I have to do it this way.
Edit: BTW I'm using Windows 7
The usual solution is to use an FTDI USB-to-serial chip, such as the FT232R, on your microcontroller board. Then, as far as your MCU is concerned, it's talking to a serial port, and on the host machine you just have to have the right drivers.
On my Mac, the FTDI chip shows up as a serial port at /dev/tty.usbmodem____, where ____ is some persistent unique ID assigned by the Mac on first detection. Unplugging and replugging, even weeks later, gets the same number, but it's a different number on a different Mac.
On Windows, it shows up as a new COM port if you have the drivers installed, IIRC. On Linux, it shows up as /dev/ttyUSB_ where _ is a serial number starting at 0, if you have FTDI serial driver support enabled in the kernel. This can get tricky if you plug in more than one FTDI chip.
If your microcontroller has a built-in USB port, then you need to find the software for it to identify itself as a standard CDC (Communication Device Class) serial port device (standard documentation available). Most OSs have support for this standard USB device class.
Use one of the USB to serial port adapters. The USB port will look just like a serial port to your C++ program.
In general you can do a close approximation of this using the HID interface: drivers are built in, and you can send feature reports in both directions. It isn't quite serial port simplicity (since it is packets, as opposed to a continuous byte stream) but hidapi makes it really simple and cross-platform.

C++ USB Programming

I am new to hardware programming(especially USB) so please bear with me and my questions. I am using C++ and I need to send/receive some data (a byte array) to/from a USB port on a microprocessor board.
Now, I have done some serial port programming before and I know that for a serial port you have to open a port, setup, perform i/o and finally close the port. I am guessing to use a USB port, it is not as simple as what I mentioned above.
I do know that I want to use Microsoft standard drivers and implement standard Windows IO commands to accomplish this, since I believe there are no drivers for the microprocessor board for me to interact with.
If somebody can point me in the right direction as to the steps needed to "talk" to a USB port (open, setup, i/o) via standard Windows IO commands, I would truly and greatly appreciate it. Thanks you so much!!
USB in a nutshell is excellent background reading.
For a generic USB module try LibUSB which includes some examples of talking to standard devices. LibUSB-Win32 is the windows port of that library.
You're right though, it's nowhere near as simple as an RS232 port.
What microprocessor are you using? Does it come with any USB hardware or are you thinking of trying to implement it all in software (not something I'd recommend even contemplating!). A lot of microprocessors come with code samples which can emulate simple HID USB devices like keyboards / mice etc. which you can use as a starting point. Failing that, there's probably a few off-the-shelf options which will save you a lot of headaches :-)
Find out the USB chipset used on the microprocessor board, e.g. Ftdi, Cypress, etc. These manufacturers supply drivers, libraries and example programs for the comms, this is the easiest way.
There are no 'standard' drivers as such unless your board is set up as an HID device, however if you are using Windows, Microsoft supply a WinUSB.sys 'generic' driver which may or may not meet your needs (it doesn't support Isochronous transfers).
Should you write a driver for the USB device that will attach itself. If you know the type of chip that has the USB i/o on the board, the driver will be for that device.
There may already be driver's for that chip if it is an STM or there may be an API to help develop drivers for it. It would probably be a custom device but you should look through device types to see if there is an existing type that matches your device. If so there may also be a driver already for it which you can use. Information about the board is necessary.
WRITE YOUR OWN DRIVER
With out getting too far into it, you should learn Microsoft's driver model, the difference between user mode and kernal mode drivers, what driver node's represent, driver hierarchy and how they logically attach themselves, different types of drivers (filter, function, bus), how kernal driver's communicate with user interface, dynamic link libraries, frameworks and API's, WDM framework/API, KMDF and UMDF API's and this is just a short list.
OR you can use an existing driver.
USE USB MICROCONTROLLER SUPPLIED DRIVER
We do not know what firmware the USB microcontroller is using, if any. If there is no firmware (if say the chip came with out it or relies on eprom to store it and not flash) then if we knew if the chip supports usb bootloader, you can flash it or load it's firmware through the USB and there is no need for JTAG or other peripherials. Likely the usb alone is capable of getting you off the ground and anywhere from there. Typically these types of questions arise when considering board's with out a USB microcontroller.
Here is a link to a slighly related driver. Most USB microcontrollers serve the purpose of switching USB communication to UART as most microconrollers that actually do the thinking and control everything are not equiped with USB i/o but instead UART or some other i/o pins like I2C or SPI etc..
https://www.silabs.com/products/mcu/Pages/USBXpress.aspx
That driver may actually work, if not something similar but for the manufacturer of your USB microcontroller; will almost certainly do the job. Hope this helps.
By hardware programming, do you mean you will be programming the microcontroller? If so, there is no way you will use "standard windows drivers" or anything like that.
The USB standard is very thick. Check it out here
It is a very involved topic and I recommend finding USB implementations already created for your microcontroller. (which we may be able to find if you gave us more info)
What kind of microprocessor and what kind of board?
Many processors come with support for USB ports. Also, some hardware boards come with USB contollers too.
For example, the processor that my shop is using comes with two USB controllers that can act as a hub or as a device. We're even adding another processor to act as a USB controller.