Results 1 to 7 of 7

Thread: How to use QSerialPort for double thread

  1. #1
    Join Date
    Nov 2015
    Posts
    3
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default How to use QSerialPort for double thread

    I need a serial port for read camera, and other serial port for write control command.
    Now I can read frame, but can't write command to serial port.
    And the error: QSocketNotifier: Can only be used with threads started with QThread.


    ViSP and UEyeOpenCV(camera) are Third-party libraries.
    Qt Code:
    1. /*****main.cpp*****/
    2. #include <iostream>
    3. #include "UEyeOpenCV.hpp"
    4. #include "opencv2/opencv.hpp"
    5. #include <servocontroller.h>
    6.  
    7. #include <visp/vpFeatureBuilder.h>
    8. #include <visp/vpFeatureDepth.h>
    9. #include <visp/vpFeaturePoint.h>
    10. #include <visp/vpHomogeneousMatrix.h>
    11. #include <visp/vpPlot.h>
    12. #include <visp/vpServo.h>
    13. #include <visp/vpVelocityTwistMatrix.h>
    14. #include <visp/vpDot2.h>
    15. #include <visp/vpDisplay.h>
    16. #include <visp/vpImageIo.h>
    17. #include <visp/vpImageTools.h>
    18. #include <visp/vpDisplayOpenCV.h>
    19. #include <visp/vpConfig.h>
    20. #include <visp/vpRobotCamera.h>
    21.  
    22. int main(){
    23. /* set undistort */
    24. cv::FileStorage fs("out_camera_data.xml", cv::FileStorage::READ);
    25. cv::Mat cameraMatrix, distCoeffs;
    26. fs["Camera_Matrix"] >> cameraMatrix;
    27. fs["Distortion_Coefficients"] >> distCoeffs;
    28. std::cout << "camera matrix: " << cameraMatrix << std::endl
    29. << "distortion coeffs: " << distCoeffs << std::endl;
    30. cv::Mat image;
    31.  
    32. /* open camera */
    33. UeyeOpencvCam cam = UeyeOpencvCam(752,480);
    34.  
    35. /* define a wondow of image*/
    36. vpImage<unsigned char> I(480, 752); // Create a gray level image
    37. cv::Mat grayFrame;
    38. vpDisplayOpenCV d;
    39. d.init(I, 0, 0, "Visual servoing on dot");
    40.  
    41. /* set dot*/
    42. vpDot2 blob;
    43. blob.setGraphics(true);
    44. blob.setGraphicsThickness(2);
    45. vpImagePoint germ;
    46. bool init_done = false;
    47.  
    48. /* set com*/
    49. unsigned short zoom=1500;
    50. ServoController com;
    51. com.ServoController::createSerialPort();
    52. com.setTarget(zoom*4);
    53.  
    54. while(true) {
    55. cv::Mat frame= cam.getFrame();
    56. cv::cvtColor(frame,grayFrame, CV_BGR2GRAY);
    57. cv::undistort(grayFrame,image,cameraMatrix,distCoeffs);
    58. cv::Mat image2;
    59. cv::flip(image,image2,-1);
    60. vpImageConvert::convert(image2, I);
    61. vpDisplay::display(I);
    62.  
    63. if (! init_done) {
    64. vpDisplay::displayText(I, vpImagePoint(10,10), "Click in the blob to initialize the tracker", vpColor::red);
    65. if (vpDisplay::getClick(I, germ, false)) {
    66. blob.initTracking(I, germ);
    67. init_done = true;
    68. }
    69. }
    70. else {
    71. blob.track(I);
    72. vpImagePoint mcog;
    73. mcog=blob.getCog();
    74. int x=mcog.get_i();
    75. if (x<240){
    76. zoom=zoom+10;
    77. com.setTarget(zoom*4);
    78. cv::waitKey(33);
    79. }
    80. else{
    81. zoom=zoom-10;
    82. com.setTarget(zoom*4);
    83. cv::waitKey(33);
    84. }
    85. }
    86. vpDisplay::flush(I);
    87. }
    88. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. //servocontroller.h
    2. /*****servocontroller.h*****/
    3. #ifndef SERVOCONTROLLER_H
    4. #define SERVOCONTROLLER_H
    5.  
    6. #include <string>
    7. #include <QtSerialPort/QSerialPort>
    8. #include <QtSerialPort/QSerialPortInfo>
    9. #include <termios.h>
    10. #include <QDebug>
    11. #include <QString>
    12.  
    13. class ServoController
    14. {
    15. public:
    16. virtual ~ServoController();
    17. void createSerialPort();
    18. void setTarget( unsigned short target );
    19.  
    20. private:
    21. static const unsigned short mMinChannelValue = 4000;
    22. static const unsigned short mMaxChannelValue = 8000;
    23. unsigned short target;
    24. unsigned char channelNumber;
    25. QSerialPort* myCom;
    26. QByteArray command;
    27. };
    28.  
    29. #endif // SERVOCONTROLLER_H
    30.  
    31.  
    32.  
    33. /*****servocontroller.cpp*****/
    34. #include "servocontroller.h"
    35. #include <QtSerialPort/QSerialPort>
    36. #include <QtSerialPort/QSerialPortInfo>
    37. #include <iostream>
    38.  
    39. void ServoController::createSerialPort()
    40. {
    41. myCom= new QSerialPort();
    42. myCom->setPortName("/dev/ttyACM0");
    43. myCom->open(QIODevice::WriteOnly);
    44. myCom->setBaudRate(9600);
    45. myCom->setDataBits(QSerialPort::Data8);
    46. myCom->setParity(QSerialPort::NoParity);
    47. myCom->setStopBits(QSerialPort::OneStop);
    48. myCom->setFlowControl(QSerialPort::NoFlowControl);
    49. }
    50.  
    51. ServoController::~ServoController()
    52. {
    53. myCom->close();
    54. }
    55.  
    56. void ServoController::setTarget(unsigned short target )
    57. {
    58. if (target<mMinChannelValue ){
    59. target=mMinChannelValue;
    60. }
    61. if(target>mMaxChannelValue){
    62. target=mMaxChannelValue;
    63. }
    64.  
    65. command.resize(4);
    66. command[0]=0x84;
    67. command[1]=0x01;
    68. command[2]=(char)(target & 0x7F);
    69. command[3]=(char)((target >> 7) & 0x7F);
    70. myCom-> QSerialPort::write(command);
    71. }
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. HEADERS += \
    2. UEyeOpenCV.hpp \
    3. servocontroller.h
    4.  
    5. SOURCES += \
    6. main.cpp \
    7. ueyeopencv.cpp \
    8. servocontroller.cpp
    9.  
    10. # important
    11. # library of QSerialport
    12. QT += serialport
    13.  
    14. # library of OpenCV
    15. INCLUDEPATH += /usr/local/include \
    16. /usr/local/include/opencv \
    17. /usr/local/include/opencv2
    18. LIBS += /usr/local/lib/libopencv_core.so \
    19. /usr/local/lib/libopencv_highgui.so \
    20. /usr/local/lib/libopencv_imgproc.so
    21.  
    22. # library of UEye
    23. win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../../../usr/lib/release/ -lueye_api
    24. else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../../../usr/lib/debug/ -lueye_api
    25. else:unix: LIBS += -L$$PWD/../../../../usr/lib/ -lueye_api
    26. INCLUDEPATH += $$PWD/../../../../usr/include
    27. DEPENDPATH += $$PWD/../../../../usr/include
    28.  
    29. # libreria de ViSP
    30. win32:CONFIG(release, debug|release): LIBS += -L$$PWD/../../ViSP-build-release/lib/x86_64-linux-gnu/release/ -lvisp
    31. else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/../../ViSP-build-release/lib/x86_64-linux-gnu/debug/ -lvisp
    32. else:unix: LIBS += -L$$PWD/../../ViSP-build-release/lib/x86_64-linux-gnu/ -lvisp
    33. INCLUDEPATH += $$PWD/../../ViSP-build-release/lib/x86_64-linux-gnu
    34. DEPENDPATH += $$PWD/../../ViSP-build-release/lib/x86_64-linux-gnu
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    May 2015
    Posts
    66
    Thanks
    10
    Thanked 17 Times in 17 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to use QSerialPort for double thread

    The Qt documentation says:
    Note: The serial port is always opened with exclusive access (that is, no other process or thread can access an already opened serial port).
    The serial port read in your case probably happens in a separate thread.. You need to make sure read and write happens in the same thread in which you open the port. Hope that helps..

    Regards
    Vikram

  3. #3
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How to use QSerialPort for double thread

    My guess is that the problem is your missing Q(Core/Ui)Application instance.
    So the main thread is not "adopted" as a QThread and thus lacks the necessary event dispatcher for socketnotifier's event handling.

    Cheers,
    _

  4. #4
    Join Date
    Nov 2015
    Posts
    3
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: How to use QSerialPort for double thread

    Quote Originally Posted by Vikram.Saralaya View Post
    The Qt documentation says:


    The serial port read in your case probably happens in a separate thread.. You need to make sure read and write happens in the same thread in which you open the port. Hope that helps..

    Regards
    Vikram
    But how to do it?
    I think that my program use only one thread.


    Added after 15 minutes:


    Quote Originally Posted by anda_skoa View Post
    My guess is that the problem is your missing Q(Core/Ui)Application instance.
    So the main thread is not "adopted" as a QThread and thus lacks the necessary event dispatcher for socketnotifier's event handling.

    Cheers,
    _
    Make a widgets project?
    Last edited by nistar; 18th November 2015 at 14:54.

  5. #5
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: How to use QSerialPort for double thread

    Quote Originally Posted by nistar View Post
    Make a widgets project?
    If you don't have any Qt UI then you don't need a widgets project.
    But you need an instance of QCoreApplication (or on of its subclasses) and run its event loop (by calling its exec() function).

    Just try to start with an empty main() function.
    Then creating and configuring the QSerialPort instance.
    Then maybe trying to write a fixed command.

    When that works, add the original code instead of the test QSerialDevice code.

    Cheers,
    _

  6. #6
    Join Date
    May 2015
    Posts
    66
    Thanks
    10
    Thanked 17 Times in 17 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to use QSerialPort for double thread

    Try replacing QT += serialport with QT += core serialport in the pro file

  7. #7
    Join Date
    Nov 2015
    Posts
    3
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Re: How to use QSerialPort for double thread

    Quote Originally Posted by anda_skoa View Post
    My guess is that the problem is your missing Q(Core/Ui)Application instance.
    So the main thread is not "adopted" as a QThread and thus lacks the necessary event dispatcher for socketnotifier's event handling.

    Cheers,
    _
    O, I do it.
    Only make a application project, and copy the code.

    Thanks

Similar Threads

  1. QserialPort
    By arturs in forum Newbie
    Replies: 0
    Last Post: 13th May 2015, 20:37
  2. Qt5 cmake and QSerialPort
    By Chris.Burner in forum Newbie
    Replies: 1
    Last Post: 21st April 2013, 16:13
  3. Program not finding an existing double in a QList<double>
    By aarelovich in forum Qt Programming
    Replies: 2
    Last Post: 9th May 2011, 20:59
  4. Replies: 2
    Last Post: 24th June 2009, 15:38

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.