QGamepadManager does not detect controller disconnection on ubuntu - qt

I am working on a Qt project with a drone. Me and my friends are controlling a drone with a Xbox 360 Controller.
So to detect buttons and axes we have used the QGamepadManager class which is in the gamepadmanager module. It works well ! But we have a problem with this simplified code :
while (true)
{
if (this->gamepad->isConnected()) {
cout << "gamepad connected" << endl;
} else {
cout << "gamepad disocnnected" << endl;
}
}
bool GamepadMonitor::isConnected()
{
return QGamepadManager::instance()->connectedGamepads().size() == 1;
}
On windows, the method isConnected() works well but not on Ubuntu. When we launch the application with the gamepad connected the buttons are recognized and axis too. But the disconnection is not detected. When we launch the application without the gamepad, the connection is not recognized.
I have installed the joystick package. I am on Ubuntu 16.04. I am developping with Qt 5.8.
Do you have an idea ?
EDIT : I add the dmesg output
When I connect the gamepad :
[ 330.430405] usb 3-1: new full-speed USB device number 4 using xhci_hcd
[ 330.575708] usb 3-1: New USB device found, idVendor=045e, idProduct=028e
[ 330.575714] usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 330.575718] usb 3-1: Product: Controller
[ 330.575721] usb 3-1: Manufacturer: ©Microsoft Corporation
[ 330.575723] usb 3-1: SerialNumber: 1E69441
[ 331.614141] input: Microsoft X-Box 360 pad as /devices/pci0000:00/0000:00:14.0/usb3/3-1/3-1:1.0/input/input23
[ 331.622581] usbcore: registered new interface driver xpad
When I disconnect it :
[ 392.733786] usb 3-1: USB disconnect, device number 4
[ 392.733995] xpad 3-1:1.0: xpad_try_sending_next_out_packet - usb_submit_urb failed with result -19

I would recommand checking if Ubuntu itself detects the disconnection, by looking at the game state, or directly at dmesg output.
As it probably is detecting it, I encourage you to then fill a bug report on Qt tracker :)

Related

finding connected Wifi network

I'm using Ubuntu 18.04.
How do I retrieve the name of the WiFi that the system is connected to. So far I'm querying with the following but it is returning interface names instead of Wifi names:
QNetworkConfigurationManager nwkMgr;
QList<QNetworkConfiguration> nwkCnfList = nwkMgr.allConfigurations();
for(const QNetworkConfiguration &ncnf : nwkCnfList)
{
qDebug() << ncnf.name() << ncnf.bearerType();
if (ncnf.bearerType() == QNetworkConfiguration::BearerWLAN)
{
// would like to detect WiFi here
qDebug() << "WiFi:" << ncnf.name();
}
}
This lists the interfaces:
"Wired connection 1" 1
"ens33" 1
How can I get the NAME of the Wifi?
Can you use system variables ? If so do this:
export WNAME=$(iw dev | grep ssid | awk '{print $2}')
It will export it to a variable WNAME and you can use it inside scripts untill you logout or shutdown the system.

Can't override board_vendor (USB manufacturer) via platformio.ini

I want to override the USB_PRODUCT and USB_MANUFACTURER strings on my Sparkfun Pro Micro.
According to the docs (http://docs.platformio.org/en/latest/boards/atmelavr/sparkfun_promicro16.html#configuration), I can
override default SparkFun Pro Micro 5V/16MHz settings per build environment using board_*** option
The Pro Micro's board settings json have the build.usb_product and vendor fields (defaults are SparkFun Pro Micro and SparkFun).
I can override the USB_PRODUCT with this platformio.ini:
[env:sparkfun_promicro16]
platform = atmelavr
board = sparkfun_promicro16
framework = arduino
board_build.usb_product = "MyProduct"
board_vendor = "MyCompany"
The correct defines will show up in .vscode/c_cpp_properties.json:
...
"defines": [
"PLATFORMIO=30602",
"ARDUINO_AVR_PROMICRO16",
"F_CPU=16000000L",
"ARDUINO_ARCH_AVR",
"ARDUINO=10805",
"USB_VID=0x1B4F",
"USB_PID=0x9203",
"USB_PRODUCT=\"MyProduct\"",
"USB_MANUFACTURER=\"MyCompany\"",
"__AVR_ATmega32U4__",
""
],
...
But as dmesg shows, only USB_PRODUCT is applied, not USB_MANUFACTURER:
[119019.190230] usb 1-1: new full-speed USB device number 115 using xhci_hcd
[119019.344882] usb 1-1: New USB device found, idVendor=1b4f, idProduct=9203, bcdDevice= 1.00
[119019.344888] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[119019.344892] usb 1-1: Product: MyProduct
[119019.344896] usb 1-1: Manufacturer: SparkFun
[119019.346978] cdc_acm 1-1:1.0: ttyACM0: USB ACM device
The relevant code is at https://github.com/platformio/platform-atmelavr/blob/master/builder/frameworks/arduino.py#L40.
It looks like the build_vendor setting should work?
What am I missing?

Error on sending AT+CWJAP_DEF commands to ESP8266

I am trying to send AT commands to ESP8266 to get connected with internet with the Wifi.
When I am sending AT and AT+RST command on serial monitor then I am getting OK and ready response which seems perfect.
Then I am sending AT+CWLAP to get list of available wifi networks which is also executing correctly.
AT+CWLAP
+CWLAP:(3,"Moto",-42,"a4:70:d6:7a:fa:6c",1,25,0)
+CWLAP:(4,"PRANJAL",-95,"1c:a5:32:3d:f5:c4",1,-16,0)
+CWLAP:(2,"VIHAN",-94,"c8:3a:35:2f:1d:81",1,-21,0)
+CWLAP:(3,"Tenda",-93,"c8:3a:35:20:a9:b1",9,-4,0)
OK
Then I sent AT+CWMODE? which is also perfect.
AT+CWMODE?
+CWMODE:1
OK
Now I am trying to connect ESP8266 with above listed Wifi with this command, it is sending an ERROR on serial monitor.
AT+CWJAP_DEF="Moto","reset1234"
Error
⸮=IRe"Moto","reset1234"
ERROR
Can anyone suggest me what could be the reason of this issue ?
#include "SoftwareSerial.h"
SoftwareSerial esp8266(2, 3); // RX, TX
void setup()
{
Serial.begin(9600); // serial port used for debugging
esp8266.begin(9600); // your ESP's baud rate might be different
}
void loop()
{
if(esp8266.available()) // check if the ESP is sending a message
{
while(esp8266.available())
{
char c = esp8266.read(); // read the next character.
Serial.write(c); // writes data to the serial monitor
}
}
if(Serial.available())
{
delay(10); // wait to let all the input command in the serial buffer
// read the input command in a string
String cmd = "";
while(Serial.available())
{
cmd += (char)Serial.read();
}
// send to the esp8266
esp8266.println(cmd);
}
}
The current official AT command set seems to be documented on https://github.com/espressif/ESP8266_AT/wiki/AT_Description
http://espressif.com/sites/default/files/documentation/4a-esp8266_at_instruction_set_en.pdf
https://www.itead.cc/wiki/ESP8266_Serial_WIFI_Module#AT_Commands
If the module is to be configured as a client, i.e. to connect to an access point, the following AT commands have to be sent (11500 baud 8N1, CR-LF line termination):
AT+RST
AT+CWMODE=3 (1 is "Station" only (wifi client), 3 is mixed mode "Station and Access-Point", both should work)
AT+CWJAP="Moto","reset1234"
AT+CWJAP_CUR="Moto","reset1234" (temporary) or
AT+CWJAP_DEF="Moto","reset1234" (stored)
For reference, a "success story" (ESP8266 module with USB-UART, Software: HTerm, Access Point with WPA2 (both TKIP / CCMP tested)):
AT<\r><\r><\n><\r><\n>
OK<\r><\n>
AT+RST<\r><\r><\n><\r><\n>
OK<\r><\n>
<\r><\n>
ets Jan 8 2013,rst cause:2, boot mode:(3,6)<\r><\n>
<\r><\n>
load 0x40100000, len 1856, room 16 <\r><\n>
tail 0<\r><\n>
chksum 0x63<\r><\n>
load 0x3ffe8000, len 776, room 8 <\r><\n>
tail 0<\r><\n>
chksum 0x02<\r><\n>
load 0x3ffe8310, len 552, room 8 <\r><\n>
tail 0<\r><\n>
chksum 0x79<\r><\n>
csum 0x79<\r><\n>
<\r><\n>
2nd boot version : 1.5<\r><\n>
SPI Speed : 40MHz<\r><\n>
SPI Mode : DIO<\r><\n>
SPI Flash Size & Map: 32Mbit(512KB+512KB)<\r><\n>
jump to run user1 # 1000<\r><\n>
<\r><\n>
??r?d?l<18>?<31><\0><\f>?l`<3>??s?l?<28>?<19>?<4><4><4>$ <2>??r?$<4>??<27>?<4><4>ll`<3>r$?<18>?"<\0>????"<4>l?cs|<\f>?`?22???<27>BB<18>c??o??<18>NN?<16><2><\0><2>d$??<2>d??<\0>?<4>d??<\0>ll????d??l`<2>?<2>N?<\0>????"<4>d??<28>p<4><4><2><2>???"b<4>$<4>?"prlrl<\r><\n>
Ai-Thinker Technology Co. Ltd.<\r><\n>
<\r><\n>
ready<\r><\n>
WIFI DISCONNECT<\r><\n>
AT+CWMODE?<\r><\r><\n>+CWMODE:3<\r><\n>
<\r><\n>
OK<\r><\n>
AT+CWJAP_CUR="Moto","reset1234"<\r><\r><\n>
WIFI CONNECTED<\r><\n>
WIFI GOT IP<\r><\n>
<\r><\n>
OK<\r><\n>
AT+CIFSR<\r><\r><\n>+CIFSR:APIP,"0.0.0.0"<\r><\n>
+CIFSR:APMAC,"00:00:00:00:00:00"<\r><\n>
+CIFSR:STAIP,"0.0.0.0"<\r><\n>
+CIFSR:STAMAC,"00:00:00:00:00:00"<\r><\n>
<\r><\n>
OK<\r><\n>
AT+GMR<\r><\r><\n>AT version:1.1.0.0(May 11 2016 18:09:56)<\r><\n>
SDK version:1.5.4(baaeaebb)<\r><\n>
Ai-Thinker Technology Co. Ltd.<\r><\n>
Jun 13 2016 11:29:20<\r><\n>
OK<\r><\n>
This also works with mode=1.
Major rewrite.
Questions and ideas to test:
what is your module firmware version?
access point issues (e.g. MAC address restrictions)?
power supply good?
might there be any old configuration or other code running on the module?
what is the byte code of ⸮ in the error message - Is it two bytes 0x2E2E?
are you using the Arduino serial monitor for communication?
in contrast to my comment, maybe the arduino does have an influence (timing?). Try to rule this out by
doing the pass-through character-based instead of line-based, e.g.:
(end of list, no code possible otherwise:)
loop(){
if( esp8266.available() )
Serial.write(esp8266.read());
if( Serial.available() )
esp8266.write(Serial.read());
}
keeping the AVR in reset and connecting the ESP8266 serial lines directly to the USB-UART converter
Alright! I just tried to connect with different wifi and it got connected with it. It was some kinda issue with mobile hotspot.

qt read data from serial port just after open by another program

I'm using Qt version 5.5.1 from windows 8.1.
When I run qtserialport terminal example,
program connects to port successfully, but does not receive any data.
But when I close this program and open Hercules_3-2-6 Application (rs232 terminal software), that application read data,
and after close Hercules_3-2-6 application and open terminal example again, this program works and reads data until restarting computer.
I repeat this process many times.
But terminal project does not receive any data after restarting system until port opens one time by Hercules_3-2-6 Application.
Specification of port:
Name: COM3,
Baud Rate: 9600,
Data bits: 8,
Parity: None,
Stop bits: 1,
Flow control: None
void MainWindow::openSerialPort()
{
SettingsDialog::Settings p = settings->settings();
serial->setPortName(p.name);
serial->setBaudRate(p.baudRate);
serial->setDataBits(p.dataBits);
serial->setParity(p.parity);
serial->setStopBits(p.stopBits);
serial->setFlowControl(p.flowControl);
if (serial->open(QIODevice::ReadWrite)) {
console->setEnabled(true);
console->setLocalEchoEnabled(p.localEchoEnabled);
ui->actionConnect->setEnabled(false);
ui->actionDisconnect->setEnabled(true);
ui->actionConfigure->setEnabled(false);
showStatusMessage(tr("Connected to %1 : %2, %3, %4, %5, %6")
.arg(p.name).arg(p.stringBaudRate).arg(p.stringDataBits)
.arg(p.stringParity).arg(p.stringStopBits).arg(p.stringFlowControl));
} else {
QMessageBox::critical(this, tr("Error"), serial->errorString());
showStatusMessage(tr("Open error"));
}
}
void MainWindow::readData()
{
QByteArray data = serial->readAll();
console->putData(data);
}
Simply you must configure serial port after that you have open it. If you open the port after these instruction:
serial->setBaudRate(p.baudRate);
serial->setDataBits(p.dataBits);
serial->setParity(p.parity);
serial->setStopBits(p.stopBits);
serial->setFlowControl(p.flowControl);
they was ignored. Your second program configure right the serial port for you and the configuration remain when you start your program.
Try this:
void MainWindow::openSerialPort()
{
SettingsDialog::Settings p = settings->settings();
serial->setPortName(p.name);
if (serial->open(QIODevice::ReadWrite)) {
serial->setBaudRate(p.baudRate);
serial->setDataBits(p.dataBits);
serial->setParity(p.parity);
serial->setStopBits(p.stopBits);
serial->setFlowControl(p.flowControl);
console->setEnabled(true);
console->setLocalEchoEnabled(p.localEchoEnabled);
ui->actionConnect->setEnabled(false);
ui->actionDisconnect->setEnabled(true);
ui->actionConfigure->setEnabled(false);
showStatusMessage(tr("Connected to %1 : %2, %3, %4, %5, %6")
.arg(p.name).arg(p.stringBaudRate).arg(p.stringDataBits)
.arg(p.stringParity).arg(p.stringStopBits).arg(p.stringFlowControl));
} else {
QMessageBox::critical(this, tr("Error"), serial->errorString());
showStatusMessage(tr("Open error"));
}
}
void MainWindow::readData()
{
QByteArray data = serial->readAll();
console->putData(data);
}
You must pay attention when configuring a serial port, any option can return true or false; best practice want to check and manage every error that can be returned.

Qt5.4 QAudioOutput on Raspberry Pi With PulseAudio on the 3.5mm Audio Jack Doesn't work but Qt 5.3 Does

Qt5.3 sees the default Raspberry Pi also_output.0.analog-mono device ( 3.5 mm headphone jack ) and QAudioOutput from 5.3 successfully writes audio to that device and I can hear the audio with my headphones. This all works with default Raspbian, with PulseAudio 2.0 from apt-get, and no extra configuration. PulseAudio is run as session process and not in the System Daemon mode. Qt 5.4 does not see the device with the exact same source code and Raspbian ( except cross-compiled with Qt 5.4.0 and not Qt 5.3.2 ) and also cannot write data to it.
It gives me this error ( Please note that I've manually assigned both sys default:CARD=ALSA and 'default' but they both return the same 'snd_pcm_hw_params' error ):
Output Device name: "sysdefault:CARD=ALSA"
Output Device name: "default"
Default device is "default"
Output device is: "default"
"QAudioOutput: snd_pcm_hw_params: err = -12"
Pactl sees it:
pactl list sinks
Sink #0
State: SUSPENDED
Name: alsa_output.0.analog-mono
Description: bcm2835 ALSA Analog Mono
Driver: module-alsa-card.c
Sample Specification: u8 1ch 8000Hz
I've tried to modify /etc/pulse/default.pa with this at the bottom to force the output device:
load-module module-alsa-sink sink_name=alsa_output.0.analog-mono device=hw:0
set-default-sink alsa_output.0.analog-mono
Here is my setup code that gives the error:
// Coordinator receives Audio data
m_Format.setSampleRate(8000);
m_Format.setChannelCount(1);
m_Format.setSampleSize(8);
m_Format.setCodec("audio/pcm");
m_Format.setByteOrder(QAudioFormat::BigEndian);
m_Format.setSampleType(QAudioFormat::UnSignedInt);
QAudioDeviceInfo infoOut(QAudioDeviceInfo::defaultOutputDevice());
foreach (const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)) {
qDebug() << "Output Device name: " << deviceInfo.deviceName();
}
qDebug() << "Default device is" << infoOut.deviceName();
if (!infoOut.isFormatSupported(m_Format))
{
qDebug()<< "Default format not supported - trying to use nearest";
m_Format = infoOut.nearestFormat(m_Format);
}
qDebug() << "Output device is: " << infoOut.deviceName();
m_AudioOutput = new QAudioOutput(infoOut, m_Format, this);
// This data accumulates and dumps data to output
m_DataForOutput.clear();
// Now Start playing
// m_Output gets written to to send data to speakers
m_Output = m_AudioOutput->start();
What in the world is going on? How come the same configuration works with 5.3.2 and not 5.4.1. Assigning the default audio device doesn't work... What can I do here and how can I make it work? Thanks!
The answer was to run in session mode ( not a system-wide PulseAudio daemon ) and edit default.pa to look like this:
## Create the default output device
#load-module module-udev-detect tsched=0
load-module module-alsa-card device_id=0
#load-module module-alsa-card device_id=0 tsched=0 fragments=10 fragment_size=640 tsched_buffer_size=4194384 tsched_buffer_watermark=262144
#load-module module-alsa-card device_id=0 tsched=0 fragments=6 fragment_size=16 tsched_buffer_size=4194384 tsched_buffer_watermark=262144
load-module module-suspend-on-idle timeout=86400
### Load several protocols
load-module module-native-protocol-unix
### Make sure we always have a sink around, even if it is a null sink.
#load-module module-always-sink

Resources