Serial port break/freeze when sending data to arduino using QT



  • I have made a controller using Arduino that takes in the pin number and the state (0 or 1) to switch the lights connected to the digital output and analog pins on the Arduino. I have used all the pins on the Arduino except for pin 0 and 1 which is used for Serial port. I made a GUI in QT and added buttons for each of the lights. Whenever a button is pressed on the GUI, the relay connected to the GPIO pin makes a click sound indicating that the data has been transmitted serially.
    Everything was working fine for the first few days. But now the serial port seems to freeze. Doesn’t matter how much I press the button on the GUI but the lights don’t seem to come on and there is no click sound for the relay.
    I have been searching a lot about it, and found out about serial break (when the serial port is idle for some time, the connection breaks). Is it due to serial break? Or some other issue with my code?

    The usage of the controller depends on the user. On some days, its used very frequently and some days the idle time of the controller is long. The computer and Arduino have been ‘on’ for approximately 6 months now.

    The code that I uploaded to Arduino is:

    const byte numChars = 32;
    char receivedChars[numChars];
    char tempChars[numChars];   // temporary array for use when parsing
    
    //variables to hold parsed data
    char messageFromPC[numChars] = {0};
    int myPin = 0;
    int status_myPin = 0;
    int pinNumber;
    boolean newData = false;
    
    void setup()
    {
      for (pinNumber=2; pinNumber <70; pinNumber++)
      {
        pinMode(pinNumber,OUTPUT);
        digitalWrite(pinNumber,HIGH);
    
        // use serial port 0, this port is connected to the USB port on the arduino
        Serial.begin(9600);
      }
    }
    
    void loop()
    {
      recvWithStartEndMarkers();
    
      if (newData == true)
      {
        strcpy(tempChars, receivedChars); 
        /* this temporary copy is necessary to protect the original data because
         *  strtok() used in parseData() replaces the commas with \0 
         */
        parseData();
     
        newData = false;
      }
    }
    void recvWithStartEndMarkers()
    {
      static boolean recvInProgress = false;
      static byte ndx = 0;
      char startMarker = '<';
      char endMarker = '>';
      char rc;
    
      while (Serial.available() > 0 && newData == false)
      {
        rc = Serial.read();
    
        if (recvInProgress == true)
        {
          if (rc != endMarker)
          {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars)
            {
              ndx = numChars - 1;
            }
          }
          else
          {
            receivedChars[ndx] = '\0'; // terminate the string
            recvInProgress = false;
            ndx = 0;
            newData = true;
          }
        }
        else if (rc == startMarker)
        {
          recvInProgress = true;
        }
      }
    }
    
    // =================
    
    void parseData()    // Split the data into  its parts
    {
      char * strtokIndx; // this is used by strtok() as an index
    
      strtokIndx = strtok(tempChars,","); // get the first part - the string
     strcpy(messageFromPC, strtokIndx); // copy it to messageFromPc
    
      strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
      myPin = atoi(strtokIndx);  // converts this part to integer
    
      strtokIndx = strtok(NULL, ",");
      status_myPin = atoi(strtokIndx);  // converts this part to a float
    
      digitalWrite(myPin,status_myPin);
    }
    

    I am uploading the GUI code for 9 such buttons here:

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    QSerialPort serial;
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        ui->B1->setCheckable(true);
        ui->B2->setCheckable(true);
        ui->B3->setCheckable(true);
        ui->B4->setCheckable(true);
        ui->B5->setCheckable(true);
        ui->B6->setCheckable(true);
        ui->B7->setCheckable(true);
        ui->B8->setCheckable(true);
        ui->B9->setCheckable(true);
    
        serial.setPortName("COM5");
        serial.open(QSerialPort::ReadWrite);
        serial.setBaudRate(QSerialPort::Baud9600);
        serial.setDataBits(QSerialPort::Data8);
        serial.setParity(QSerialPort::NoParity);
        serial.setStopBits(QSerialPort::OneStop);
        serial.setFlowControl(QSerialPort::NoFlowControl);
        serial.write("ok");
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::on_B1_clicked(bool checked)
    {
        if(checked == true)
        {
            serial.write("<on,2, 0>");
        }
        if(checked == false)
        {
            serial.write("<off,2, 1>");
        }
    
    }
    
    void MainWindow::on_B2_clicked(bool checked)
    {
        if(checked == true)
        {
            serial.write("<on,3, 0>");
        }
        if(checked == false)
        {
            serial.write("<off,3, 1>");
        }
    
    }
    
    void MainWindow::on_B3_clicked(bool checked)
    {
        if(checked == true)
        {
            serial.write("<on,4, 0>");
        }
        if(checked == false)
        {
            serial.write("<off,4, 1>");
        }
    
    }
    
    void MainWindow::on_B4_clicked(bool checked)
    {
        if(checked == true)
        {
            serial.write("<on,5, 0>");
        }
        if(checked == false)
        {
            serial.write("<off,5, 1>");
        }
    
    }
    
    void MainWindow::on_B5_clicked(bool checked)
    {
        if(checked == true)
        {
            serial.write("<on,6, 0>");
        }
        if(checked == false)
        {
            serial.write("<off,6, 1>");
        }
    
    }
    
    void MainWindow::on_B6_clicked(bool checked)
    {
        if(checked == true)
        {
            serial.write("<on,7, 0>");
        }
        if(checked == false)
        {
            serial.write("<off,7, 1>");
        }
    
    }
    
    void MainWindow::on_B7_clicked(bool checked)
    {
        if(checked == true)
        {
            serial.write("<on,8, 0>");
        }
        if(checked == false)
        {
            serial.write("<off,8, 1>");
        }
    
    }
    
    void MainWindow::on_B8_clicked(bool checked)
    {
        if(checked == true)
        {
            serial.write("<on,9, 0>");
        }serial ardui
        if(checked == false)
        {
            serial.write("<off,9, 1>");
        }
    
    }
    
    void MainWindow::on_B9_clicked(bool checked)
    {
        if(checked == true)
        {
            serial.write("<on,10, 0>");
        }
        if(checked == false)
        {
            serial.write("<off,10, 1>");
        }
    
    }
    
    


  • Also after the serial port freezes (when pressing the button has no effect ), I close the window of my GUI, unplug the USB cables from the PC and then plug it back again, then it works. But I cant do this all the time, I want a permanent solution to this problem. Please guide me on this.
    Thank you


  • Qt Champions 2017

    Hi
    It sounds more like a serial over usb driver issue.
    Since it can run for days and start working as soon as the OS
    redetects the usb serial.
    what chip is it ? FTDI ?



  • Just connect the Rx/Tx pins of your serial port, open the qtserialport terminal example and try to enter any symbols and see what happens. In this case you will be know that a problem is in HW or in qtserialport.


  • Qt Champions 2017

    @jkprog that sounds indeed like a HW problem.

    I have these too sometimes, most often due to electrical ARCs in the slave device.

    but it can also happen if the electrical ground (GND) between PC and Arduiono is bad. in that case, electrical current flows trough the USB ground wire and disturbs communication.

    Regards



  • @aha_1980 but how do I solve the problem? How to make sure that the electrical ground is fine?



  • @kuzulis I bought another arduino, and uploaded the same program to it. Then I made a similar gui with 9 buttons. The arduino is connected since 3 days to my computer, and I try switching the buttons on the GUI and it has been working fine.
    But on the original controller with 2 arduinos connected to a different PC with windows 10 it doesnt seem to work as desired.
    I have also disabled the USB suspend settings on windows 10 to eliminate any chances of USB port getting disabled.



  • I have attached the circuit diagrams as to how I have connected my 2 arduino mega to power and relay module.
    The first circuit diagram shows how I powered my arduino and the relay modules.
    0_1530207034124_arduino_relay_power.jpeg

    The following diagram shows how the arduino GPIO pins are connected to the low voltage relays.0_1530207088771_arduino_relaymodule.jpeg

    Each arduino mega 2560 is connected to 4 relay modules. I have powered my relay modules with the same power source that is used to power each relay module. Both arduinos are being powered separately using a 7.5V 700mA regulated supply. The arduinos are powered from the same socket on 2nd floor and the computer is on 1st floor and is powered from a different socket.

    The GPIO pins of arduino are connected to the relays on the module. The output of the relays is connected to high voltage relays which are then connected to the lights to be switched on/off.

    Is there anything that I am doing wrong in the wiring?

    The 8-relay modules that I am using are :
    srd-05Vdc-SL-C


  • Qt Champions 2017

    @jkprog I'm no expert for the power supply part, just two questions:

    1. how long are the USB cables?
    2. can you try the arduionos without the power (relay) part?


  • @aha_1980 The arduino usb cable A/B is around 4ft. But then I have used USB extension cables which are of length 15-17ft.
    At times, just closing the GUI window and reopening it also makes it work.


  • Qt Champions 2017

    @jkprog everything over 3m works a bit, over 5m not at all. please check the max. length.



  • It is approx 8m.

    Is there some solution to this problem other than switching to WiFi? Will increasing the baud rate help to fix this problem?

    By the way, I have used the USB booster cable extension. Initially I used normal USB extension cables and the problem was even more frequent. With the usage of booster cables it got better but still this is not acceptable for my seniors.
    I cannot move the computer or the arduinos to the same floor.


  • Qt Champions 2017

    @jkprog

    Hi
    Why not use a serial over lan device ?
    Like
    https://www.startech.com/eu/Networking-IO/Serial-over-IP/1-port-RS232-serial-over-ip-adapter~NETRS2321P

    I had good result with those when i need serial from office to machine.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.