How to permanently check If serial device connects/disconnects in UWP C#?

i have a UWP App running on Windows IoT on a Raspberry Pi. I have to connect several Barcode Scanners via USB-Com and receive Data via a serial port. What would be the best way to recognize if a device disconnects or connects? Right now each Barcode Scanner runs a loop. If it throws an Exception while waiting for Data i know it physically disconnected. Then i try to reconnect it by creating a new serial port using the devices HardwareString(which contains PID and VID). If that fails, it will will run in an endless loop trying to create a serial port throwing exceptions because the device ist physically disconnected. This Will go on until the device reconnects physically and is able to create the serial Port an receive Data on it.

Is there a more elegant way to permanently check for a specific device using the HardwareString?

Thank you very much.

1 answer

  • answered 2019-10-16 01:57 Michael Xu - MSFT

    You may try to use DeviceWatcher. DeviceWatcher is used to enumerate all the devices dynamically, your app can receive notifications if devices are added, removed, or changed after the initial enumeration is complete. If the USB-Com added it will raise DeviceWatcher.Added Event, while the device removed, it will raise DeviceWatcher.Removed Event. Please note that when the device disconnects, it will raise the device removed event, but all pending operations need to be canceled properly, and all of the resources need to clean up. Please refer to following code in EventHandlerForDevice. The callback in the code is used to close the device explicitly is to clean up resources, to properly handle errors,and stop talking to the disconnected device.

    private async void CloseCurrentlyConnectedDevice()
    {
        if (device != null)
        {
            // Notify callback that we're about to close the device
            if (deviceCloseCallback != null)
            {
                deviceCloseCallback(this, deviceInformation);
            }
    
            // This closes the handle to the device
            device.Dispose();
    
            device = null;
        }
    }
    

  • Problem accessing native executable resources in UWP package in user installation

    I have a windows native binary (actually, a small collection of them, but one is the 'controller' for everything else), which I want to be able to put in the Windows Store. The controller needs to run elevated. They're designed to be used with an installer and a workflow which is entirely unsuited to UWP, so Desktop Bridge isn't what I need. These are old, gnarly, and definitely not rewritable in short order, so I've concluded I need to create a UWP package and workflow which wraps the original binaries (albeit with some small adaptations). So, what I have now is a package containing:

    • the binaries, arranged in the package in the same relationship as in a native installation;
    • A .net intermediate process which starts the binaries elevated, intended to run full-trust;
    • A UWP UI program, which starts the intermediate full-trust;
    • A Service Provider, which mediates the communication between the UI and the intermediate.

    When I install the package onto a machine's admin account, and run it, everything works just fine. When I install it onto a user account, it works fine provided it is also installed into an admin account on the same machine. But if it's installed only onto the user account, and not the admin account, the intermediate fails to start the controller. The error it produces is "File not found" (which, I know, could mean anything). In fact, I can install on both, run it in the user account, then delete it from the admin account, and then it fails on the user account.

    The misbehaviour happens whether I side-load it onto development machines, or whether I download it from the store. It's a reliable failure, demonstrable on several different versions of W10.

    A bit of mousing around shows that the file is exactly where the intermediate thinks it should be (in the installation directory in Program Files\WindowsApps), and that doesn't change whether or not the admin installation is there. Also, the access control settings are identical whether or not the admin installation is there. In fact, I can't find any difference that would tell a user whether the admin has installed it. But something is causing an error, and I have no idea where to look for it.

    I want to stress: this is not a problem of the controller misbehaving in some way. The controller never even gets to run. I get to see the UAC prompt (which correctly identifies the file), and then the next thing I get is the File Not Found exception from inside Process.Start().

    Has anybody experienced anything like this, or have any deeper understanding of how the different users' installations are controlled? Thanks.

    EDIT: I think I've now satisfied myself that it's not a failure to find the file, it's a failure to run elevated. When the intermediate attempts to run the binary without elevation, the binary starts correctly (and then fails subsequently because of a lack of permissions for its own behaviour). Of course, there's no AUC prompt. So, what could cause a failure to elevate after the UAC prompt?

  • OpenCV locating centroid gives erros on PiCam

    I have a code which locates the centroid of an object placed in front of a camera. I ran the code on my Raspberry Pi where I am using a PiCam for the project, the cv2.moments() function's output object,has all values 0. The relevant part of the code is this:

    import cv2
    import numpy as np
    from picamera import PiCamera 
    from picamera.array import PiRGBArray
    
    camera = PiCamera()
    camera.resolution = (640,480)
    camera.framerate = 16
    camera.rotation=180
    rawCapture = PiRGBArray(camera, size=(640,480))
    
    for f in camera.capture_continuous(rawCapture,format='bgr',use_video_port=True):  
        # ret, orig_frame = video.read()
        orig_frame = f.array
        hsv = cv2.cvtColor(orig_frame, cv2.COLOR_BGR2HSV)
    
        low_red = np.array([100, 100, 100])
        up_red = np.array([255, 255, 255])
        mask = cv2.inRange(hsv, low_red, up_red)
        edges = cv2.Canny(mask, 100, 200)
        bit = cv2.bitwise_or(orig_frame, orig_frame, mask= mask)
    
        contours, _ ,heirarchy= cv2.findContours(frame1, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
        setpoint = 315
        stop1 = 250
        stop2 = 370
    
    
    
        for c in contours:
    
           M = cv2.moments(c)
           print(M) #OUTPUT HAS ALL VALUES 0
           # cX = int(M["m10"] / M["m00"]) 
           # cY = int(M["m01"] / M["m00"])
    

    The output of the print(M) statement is:

    {'m20': 0.0, 'mu20': 0.0, 'nu30': 0.0, 'm03': 0.0, 'm10': 0.0, 'mu03': 0.0, 'nu02': 0.0, 'm11': 0.0, 'm21': 0.0, 'mu21': 0.0, 'mu02': 0.0, 'mu30': 0.0, 'm12': 0.0, 'm01': 0.0, 'm00': 0.0, 'nu20': 0.0, 'nu03': 0.0, 'nu21': 0.0, 'nu11': 0.0, 'm02': 0.0, 'nu12': 0.0, 'mu11': 0.0, 'mu12': 0.0, 'm30': 0.0}
    

    As you can see, all values are 0

    However, if I run the same code on my laptop which uses its webcam, the code runs error free and the output of the print(M) statement is an object with non-zero values.

    This is the code on my local machine:

    import cv2
    import numpy as np
    video = cv2.VideoCapture(0)
    
    def make_custom(x, y):
        video.set(3, x)
        video.set(4, y)
    
    make_custom(800, 800) 
    while True:
        ret, orig_frame = video.read()
    
    
    
        #frame = cv2.GaussianBlur(orig_frame, (5, 5), 0)
        hsv = cv2.cvtColor(orig_frame, cv2.COLOR_BGR2HSV)   
        low_red = np.array([100, 100, 100])
        up_red = np.array([255, 255, 255])
        mask = cv2.inRange(hsv, low_red, up_red)
    
        frame1 = cv2.GaussianBlur(mask, (5, 5), 1)
        edges = cv2.Canny(mask, 100, 200)
        bit = cv2.bitwise_or(orig_frame, orig_frame, mask= mask)
    
        contours, _ = cv2.findContours(frame1, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)       
        for c in contours:
       # calculate moments for each contour
           M = cv2.moments(c)
           print(M)
    

    I am using Python 3.6 on both the machines

    What am I doing wrong, and how do I correct it?

  • Raspberry PI with 433Mhz receiver only receives on realy short range (5cm or less)

    As the title describes I set up a Raspberry with rasbian and a 433mhz receiver module (MX-RM-5V) using RFSniffer out of the 433Utils! I have a 433Mhz Remote for my car to sending codes to the receiver.

    The receiver is connected with data to a GPIO PIN, VCC to 3.3V out of the raspberry, GND to GND :-)

    If I now going with my remote close to the receiver: RFSniffer will print the code on screen. But if I am more away than 10cm from the receiver: RFSniffer don't get a code.

    Sure I have an 17.2cm Antenne connected right to the spool as described in other tutorials.

    Later I tried to drive the receiver by 5V VDC and creating a voltage divider for the data line to divide plus down to 3V to prevent the gpio pin. That also works but truely only on short distances!?

    Receiver Module: My Receiver Module

    Point of connection Antenna: enter image description here

    Is here anyone who also stucked in this problem earlier. Maybe my Antenna or the Antenna Port is wrong. May I need a physical conection to gronding point?

    As next also a short question: Must the Antenna conected by soldering to the spool or not? If Not what happens if it is connected to the spool (At me at is connected)?

    Before anyone ask for the remote: I am able to open my car in a distance over 50m... so the remote and their battery is fine!

  • MySQL db not working on Python 2.7 Raspberry Pi3

    I have found the code below as I want to print on an interval readings from BME280 to a MySQL database. Whenever I try to run below code it gives me

    Traceback (most recent call last):
      File "/home/pi/Adafruit_Python_BME280/sensor.py", line 7, in <module>
        import MySQLdb
      File "/usr/lib/python3/dist-packages/thonny/backend.py", line 305, in _custom_import
        module = self._original_import(*args, **kw)
    ModuleNotFoundError: No module named 'MySQLdb'
    

    I have installed the Mariadb and the python connectors etc. What might be the problem?

    #!/usr/bin/env python  
    
    import os  
    import time  
    import datetime  
    import glob  
    import MySQLdb  
    from time import strftime  
    from Adafruit_BME280 import *  
    
    sensor = BME280(t_mode=BME280_OSAMPLE_8, p_mode=BME280_OSAMPLE_8, h_mode=BME280_OSAMPLE_8)  
    
    #Variables for MySQL  
    db = MySQLdb.connect(host="localhost", user="root", passwd="karolk87", db="sensor") # replace password with your password  
    cur = db.cursor()  
    
    def dateTime(): #get UNIX time  
            secs = float(time.time())  
            secs = secs*1000  
            return secs  
    
    def tempRead(): #read temperature, return float with 3 decimal places  
            degrees = float('{0:.3f}'.format(sensor.read_temperature()))  
            return degrees  
    
    def pressRead():#read pressure, return float with 3 decimal places  
            pascals = float('{0:.3f}'.format(sensor.read_pressure()/100))  
            return pascals  
    
    def humidityRead(): #read humidity, return float with 3 decimal places  
            humidity = float('{0:.3f}'.format(sensor.read_humidity()))  
            return humidity  
    
    secs = dateTime()  
    temperature = tempRead()  
    pressure = pressRead()  
    humidity = humidityRead()  
    
    sql = ("""INSERT INTO bmesensor (datetime,temperature,pressure,humidity) VALUES (%s,%s,%s,%s)""", (secs, temperature, pressure, humidity))  
    
    try:  
        print ("Writing to the database...")  
        cur.execute(*sql)  
        db.commit()  
        print ("Write complete")  
    
    except:  
        db.rollback()  
        print ("We have a problem")  
    
    cur.close()  
    db.close()  
    
    print (secs)  
    print (temperature)  
    print (pressure)  
    print (humidity)
    
  • How to release serial COM port from dll

    I'm using .dll to in my code so i create object for that, in which .dll open the serial com port but after use it not release the comport. but in my application i want to open comport again but comport occupied by the .dll so it gives error.

    please give the solution.

  • Qt Serial Port with Arduino: write function works only first time its called


    I'm fairly new to Qt and Arduino and at the moment I'm kind of lost.
    My objective is to create an application in qt where you can set the various pins of the board to low or high. To do so I need to be able to frequently change the status of those pins.
    The first step I took is the creation of a simple interface where, given a string that contains the pin number and the pin status to set (0 or 1), those two are set properly. To test this function I used the led of the pin 13.
    It seems kinda basic to me, but something doesn't work and I can't figure out what it is.
    The program sets correctly the status of the led only the first time and afterwards stop working and starts doing nothing. The direction of the change of status of the pin (from 0->1 or from 1->0) is ininfluent in all of this.
    Here is part of the code:
    mainwindow.h:

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include "serialportcontroller.h"
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    private slots:
        void on_pbn_ok_clicked();
    
    
    private:
        Ui::MainWindow *ui;
        SerialPortController mw_serial;
    
    
    };
    #endif // MAINWINDOW_H
    

    mainwindow.cpp:

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QDebug>
    #include <QSerialPort>
    #include <QSerialPortInfo>
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::on_pbn_ok_clicked()
    {
    QString query = ui->lineEdit->text();
    ui->lineEdit->clear();
    mw_serial.write( query.toLatin1() );
    }
    

    serialportcontroller.h:

    #ifndef SERIALPORTCONTROLLER_H
    #define SERIALPORTCONTROLLER_H
    #include <QSerialPort>
    #include <QSerialPortInfo>
    
    class SerialPortController: public QObject
    {
    public:
        QSerialPort *serial;
        QString str_portName;
        QByteArray qba_data;
    public:
        SerialPortController();
        ~SerialPortController();
        void write( const QByteArray &writeData);
        void setPortName(QString str_port);
        void openSerialPort();   
    };
    
    #endif // SERIALPORTCONTROLLER_H
    

    serialportcontroller.cpp:

    #include "serialportcontroller.h"
    #include <QDebug>
    #include <QSerialPort>
    #include <QSerialPortInfo>
    
    SerialPortController::SerialPortController()
    {
        serial = new QSerialPort;
        setPortName("COM7");
        openSerialPort();
    }
    
    SerialPortController::~SerialPortController()
    {
        serial->close();
    }
    //------------------------------------------------------------------------------
    void SerialPortController::setPortName(QString str_port)
    {
        if (str_port != ""){
            str_portName = str_port;
        }else{
            qDebug()<<"[!]Port name is invalid";
        }
    }
    //------------------------------------------------------------------------------
    void SerialPortController::openSerialPort()
    {
        serial->setPortName(str_portName);
        serial->setBaudRate(QSerialPort::Baud9600);
        serial->setDataBits(QSerialPort::Data8);
        serial->setParity(QSerialPort::NoParity);
        serial->setStopBits(QSerialPort::OneStop);
        serial->setFlowControl(QSerialPort::NoFlowControl);
        if (serial->open(QIODevice::ReadWrite))
        {
            qDebug()<<"Device connected";
        }
        else
        {
            qDebug()<<"[!]Device not connected";
        }
    
    }
    //----------------------------------------------------------------------------
    void SerialPortController::write( const QByteArray &writeData)
    {
        qba_data = writeData;
        const qint64 bytesWritten = serial->write(writeData);
        qDebug()<<bytesWritten;
    }
    //----------------------------------------------------------------------------
    

    bytesWritten returns always 9, as it should given the format of the string I choose for the input.
    I tested the Arduino sketch and via Eclipse I'm able, via terminal with the same string used with qt, to change as many times as I want the status (0-1) of the pin and consequently of the led. I even downloaded terminal (terminal emulation program for RS-232) and tested the Arduino sketch with it so the problem has to be in my qt application.
    There are no problems with the text retrieved from the lineedit, otherwise it wouldn't work the first time and it would not work with eclipse or terminal. What am I missing here?

    Thank you so much in anticipation of your reply.

    Github repo: link

    Edit:
    After testing with a different laptop I came to the conclusion that the code has nothing wrong within itself, the problem I encounter is probably due to the USB-C to USB-A gen.3 adapter that I use to connect with Arduino.
    Using a normal USB A gen.2 port with the USB A to B adapter I was able to switch on and off the led without any issues.
    I've reported the bug to the Qt developers, link for the interested: link

  • WinForms Serial port eats data

    I have a serial port that recieves some color data from arduino board at 115200 baud rate. At small scale (1-byte request from arduino for pc to send next command, implemented for synchronization) it works fine, but when i request a lot of data (393 bytes) and it sends them, it looks as if serial port just eats data, and BytesToRead usually equals to 5 or 6

    Code:

    void GetCurrentState()
        {
            int i = 0;
            Color WrittenColor; //Color to write to an array
            byte red;
            byte green;
            byte blue;
            AddToQueue(new byte[] { 6 });  //adds command that requests data to a sender queue
            while (i <= StripLength) //read data until array is read completly
            {
                Console.WriteLine($"Bytes to read: {SerialPort1.BytesToRead}");//Debug
                if (SerialPort1.BytesToRead >= 3) //if we have a color ready to read and construct, do it, else wait for more data
                {
                    red = (byte)SerialPort1.ReadByte(); //Read red part
                    green = (byte)SerialPort1.ReadByte(); //Read green part
                    blue = (byte)SerialPort1.ReadByte(); //Read blue part
                    WrittenColor = Color.FromArgb(red, green, blue); //Make a color
                    SavedState[i] = WrittenColor; //Write it
                    i++; //increment counter
                }
            }
        }
    
  • Windows 10 IoT Dashboard - Unrecognized configuration section startup

    I'm trying to install Windows 10 IoT Core dashboard, however, the ClickOnce installer is failing.

    enter image description here

    The top of log file that I get is:

    PLATFORM VERSION INFO
        Windows             : 10.0.17763.0 (Win32NT)
        Common Language Runtime     : 4.0.30319.42000
        System.Deployment.dll       : 4.8.3761.0 built by: NET48REL1
        clr.dll             : 4.8.4042.0 built by: NET48REL1LAST_C
        dfdll.dll           : 4.8.3761.0 built by: NET48REL1
        dfshim.dll          : 10.0.17763.1 (WinBuild.160101.0800)
    
    SOURCES
        Deployment url          : https://iottools.blob.core.windows.net/iotdashboard/Windows10IoTCoreDashboard.application
    
    ERROR SUMMARY
        Below is a summary of the errors, details of these errors are listed later in the log.
        * Activation of https://iottools.blob.core.windows.net/iotdashboard/Windows10IoTCoreDashboard.application resulted in exception. Following failure messages were detected:
            + Configuration system failed to initialize
            + Unrecognized configuration section startup. (**C:\Windows\Microsoft.NET\Framework64\v4.0.30319\dfsvc.exe.Config** line 2)
    

    The dfsvc.exe.Config file is:

    <configuration>
        <appSettings>
          <add key="EnableWindowsFormsHighDpiAutoResizing" value="true"/>
        </appSettings>
        <runtime>
          <!-- AppContextSwitchOverrides values are in the form of 'key1=true|false;key2=true|false -->
          <!-- Enabling newer accessibility features (e.g. UseLegacyAccessibilityFeatures.2=false) requires all older accessibility features to be enabled (e.g. UseLegacyAccessibilityFeatures=false) -->
          <AppContextSwitchOverrides value="Switch.System.Net.DontEnableSchUseStrongCrypto=false;Switch.UseLegacyAccessibilityFeatures=false;Switch.UseLegacyAccessibilityFeatures.2=false;Switch.UseLegacyAccessibilityFeatures.3=false;Switch.System.Windows.Forms.UseLegacyImages=false" />
        </runtime>
    </configuration>
    

    So far, the only ideas I have found is to run the NetFxRepair tool and deleting the ClickOnce cache, but neither of them seem to have changed anything. I've got VS2019 Previe3w and VS2017 installed as whell

  • IOT developer jobs

    I am currently working as a java developer , parallely in I am interested in IOT . BUt not getting exact path how to start my career in IOT , Can anyone please help what are the skills and technologies needed for IOT Hardware and IOT software .

    I am familiar about the Raspberry pi , arduino and most of the sensors .

    Thanks Sree lakshmi

  • UWP application doesn't start without debugger

    I have a UWP app which works fine in Visual Studio 2017. Since I updated to Visual Studio 2019 the Application works fine while debugging with Visual Studio. The creation of the App Bundle finishes without problems, and the App works well on an X86 or X64 System. But if I install on a Raspberry Pi (ARM) the App won't start. It is showing the startup screen forever.

    Is there any way to narrow down the Problem?