Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to store a unsigned char array to float value?
Forum Update on Monday, May 27th 2025

How to store a unsigned char array to float value?

Scheduled Pinned Locked Moved Unsolved General and Desktop
13 Posts 6 Posters 3.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    Geeva
    wrote on last edited by
    #1

    I am trying to take the sensor data from Arduino & Raspberry Pi (Onboard QT installed) using RS232 serial communication. Because I have faced a problem with Qserial. I have searched for this small thing and found something related on this below link but was unable get the full idea.

    https://www.teuniz.net/RS-232/

    The values are properly coming from Arduino to Raspberry Pi (output attached below) and it is storing in a pointer to unsigned char[] which is defined as unsigned char *buf[4096]. Is it anything specific for qt?

    0_1557214148238_53e91d56-2cce-4e36-8d3d-56ae23bf542a-image.png

    int main()
    {
      int i, n,
          cport_nr=0,        /* /dev/ttyS0 (COM1 on windows) */
          bdrate=9600;       /* 9600 baud */
    
      unsigned char buf[4096];
    
      char mode[]={'8','N','1',0};
    
      while(1)
      {
        n = RS232_PollComport(cport_nr, buf, 4095);
    
        if(n > 0)
        {
          buf[n] = 0;
    
          for(i=0; i < n; i++)
          {
            if(buf[i] < 32)  /* replace unreadable control-codes by dots */
            {
              buf[i] = '.';
            }
          }
    
          printf("received %i bytes: %s\n", n, (char *)buf);
        }
    }
    

    Now I want to store these values in another float/double variable so that I can perform further operations on it. How to store a value suppose 0.01 to a float/double which is later used to create stuff.

    J.HilkJ KroMignonK 2 Replies Last reply
    0
    • G Geeva

      I am trying to take the sensor data from Arduino & Raspberry Pi (Onboard QT installed) using RS232 serial communication. Because I have faced a problem with Qserial. I have searched for this small thing and found something related on this below link but was unable get the full idea.

      https://www.teuniz.net/RS-232/

      The values are properly coming from Arduino to Raspberry Pi (output attached below) and it is storing in a pointer to unsigned char[] which is defined as unsigned char *buf[4096]. Is it anything specific for qt?

      0_1557214148238_53e91d56-2cce-4e36-8d3d-56ae23bf542a-image.png

      int main()
      {
        int i, n,
            cport_nr=0,        /* /dev/ttyS0 (COM1 on windows) */
            bdrate=9600;       /* 9600 baud */
      
        unsigned char buf[4096];
      
        char mode[]={'8','N','1',0};
      
        while(1)
        {
          n = RS232_PollComport(cport_nr, buf, 4095);
      
          if(n > 0)
          {
            buf[n] = 0;
      
            for(i=0; i < n; i++)
            {
              if(buf[i] < 32)  /* replace unreadable control-codes by dots */
              {
                buf[i] = '.';
              }
            }
      
            printf("received %i bytes: %s\n", n, (char *)buf);
          }
      }
      

      Now I want to store these values in another float/double variable so that I can perform further operations on it. How to store a value suppose 0.01 to a float/double which is later used to create stuff.

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by J.Hilk
      #2

      @Geeva
      as far as I know, there is no "Qt Way" to do this. You'll have to go the old-fashioned c++ way.

      Splice your array in 4 (float) 8(double) byte chunks and reinterpret cast it as a float/double if the byte order aligns, otherwise some shuffling beforehand is needed.

      an excerpt from one of my older projects:

      enum byteOrder{
              ABCD,
              BADC,
              CDAB,
              DCBA
          };
      
      float toFloat( quint16 ab, quint16 cd, byteOrder order)
      {
          short A(0),B(0),C(0),D(0);
          switch (order) {
          case ABCD:A = 0; B = 1; C = 2; D = 3;break;
          case BADC:A = 1; B = 0; C = 3; D = 2;break;
          case CDAB:A = 2; B = 3; C = 0; D = 1;break;
          case DCBA:A = 3; B = 2; C = 1; D = 0;break;
          }
      
          float f(0);
          auto *cArray = reinterpret_cast<unsigned char *>(&f);
          cArray[A] =  ab &0xFF;
          cArray[B] = (ab >> 8) & 0xFF;
          cArray[C] =  cd &0xFF;
          cArray[D] = (cd >> 8) & 0xFF;
      
          return f;
      }
      

      the above function is used by me in conjunction with QModbus module, that returns a QVector<quint16> -> therefore the arguments, you will have to adjust it for your case.


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      1 Reply Last reply
      2
      • VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on last edited by
        #3

        From the output in the screenshot it looks like you are sending the string representation of the numbers rather than the actual numbers. You just need to detect those "unreadable control-codes" that you are just replacing with a . as they will probably tell you when a number ends and another begins. you can then use QString::fromLatin1 to create a string from the input received and then you can use toDouble to convert it to a floating point type

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        1 Reply Last reply
        4
        • G Geeva

          I am trying to take the sensor data from Arduino & Raspberry Pi (Onboard QT installed) using RS232 serial communication. Because I have faced a problem with Qserial. I have searched for this small thing and found something related on this below link but was unable get the full idea.

          https://www.teuniz.net/RS-232/

          The values are properly coming from Arduino to Raspberry Pi (output attached below) and it is storing in a pointer to unsigned char[] which is defined as unsigned char *buf[4096]. Is it anything specific for qt?

          0_1557214148238_53e91d56-2cce-4e36-8d3d-56ae23bf542a-image.png

          int main()
          {
            int i, n,
                cport_nr=0,        /* /dev/ttyS0 (COM1 on windows) */
                bdrate=9600;       /* 9600 baud */
          
            unsigned char buf[4096];
          
            char mode[]={'8','N','1',0};
          
            while(1)
            {
              n = RS232_PollComport(cport_nr, buf, 4095);
          
              if(n > 0)
              {
                buf[n] = 0;
          
                for(i=0; i < n; i++)
                {
                  if(buf[i] < 32)  /* replace unreadable control-codes by dots */
                  {
                    buf[i] = '.';
                  }
                }
          
                printf("received %i bytes: %s\n", n, (char *)buf);
              }
          }
          

          Now I want to store these values in another float/double variable so that I can perform further operations on it. How to store a value suppose 0.01 to a float/double which is later used to create stuff.

          KroMignonK Offline
          KroMignonK Offline
          KroMignon
          wrote on last edited by KroMignon
          #4

          @Geeva I support the two dots after "13.60" are cariage return (ASCII 13) and line fied (ASCII 10)

          I would do this like this

          QSerialPort port;
          
          port.setBaudRate(9600);
          port.setParity(QSerialPort::NoParity);
          port.setDataBits(QSerialPort::Data8);
          port.setStopBits(QSerialPort::OneStop);
          
          QString buffer;
          
          port.open(QIODevice::ReadOnly);
          while(port.isOpen())
          {
              // to let QSerialPort handle events
              QThread::currentThread()->eventDispatcher()->processEvents(QEventLoop::AllEvents);
              QByteArray bArray= port.readAll();
              foreach(const auto& c, bArray)
              {
                  if(c < 32)  // unreadable is "end of string"
                  {
                       if(!buffer.isEmpty())
                       {
                            bool ok;
                            auto value = buffer.toDouble(&ok);
                            if(ok)
                            {
                                 qDebug() << "Received value": << value;
                            }
                            else
                            {
                                  qDebug() << "Failed to parse": << buffer;
                            }
                      }
                      buffer.clear();
                  }
                  else
                  {
                      buffer.append(c);
                  }
              }
          }
          
          

          Hope this will help you.

          It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

          aha_1980A 1 Reply Last reply
          0
          • KroMignonK KroMignon

            @Geeva I support the two dots after "13.60" are cariage return (ASCII 13) and line fied (ASCII 10)

            I would do this like this

            QSerialPort port;
            
            port.setBaudRate(9600);
            port.setParity(QSerialPort::NoParity);
            port.setDataBits(QSerialPort::Data8);
            port.setStopBits(QSerialPort::OneStop);
            
            QString buffer;
            
            port.open(QIODevice::ReadOnly);
            while(port.isOpen())
            {
                // to let QSerialPort handle events
                QThread::currentThread()->eventDispatcher()->processEvents(QEventLoop::AllEvents);
                QByteArray bArray= port.readAll();
                foreach(const auto& c, bArray)
                {
                    if(c < 32)  // unreadable is "end of string"
                    {
                         if(!buffer.isEmpty())
                         {
                              bool ok;
                              auto value = buffer.toDouble(&ok);
                              if(ok)
                              {
                                   qDebug() << "Received value": << value;
                              }
                              else
                              {
                                    qDebug() << "Failed to parse": << buffer;
                              }
                        }
                        buffer.clear();
                    }
                    else
                    {
                        buffer.append(c);
                    }
                }
            }
            
            

            Hope this will help you.

            aha_1980A Offline
            aha_1980A Offline
            aha_1980
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @KroMignon It would have been a better and more reuseable example with the readyRead()signal.

            Also, the data comes in in chucks and parsing it like this is likely to fail. Example:
            12345.6 can come in as 123 and 45.6, both valid floating point numbers.

            So you need to handle the special chars between them, like @VRonin said. Most likely these are line endings and perfectly suited to detect begin and end of a number.

            Regards

            Qt has to stay free or it will die.

            1 Reply Last reply
            2
            • G Offline
              G Offline
              Geeva
              wrote on last edited by Geeva
              #6

              @KroMignon @aha_1980 I have tried to use qserial for receiving data, but I didn't get the proper response. I don't know where is the problem exactly. I hope you can help me to get a solution.

              mainwindow.h

              #include <QMainWindow>
              
              namespace Ui {
              class MainWindow;
              }
              
              class MainWindow : public QMainWindow
              {
                  Q_OBJECT
              
              public:
                  explicit MainWindow(QWidget *parent = 0);
                  ~MainWindow();
              
              private slots:
              
                  void serialreceived();
              
              private:
                  Ui::MainWindow *ui;
              

              mainwindow.cpp

              #include "mainwindow.h"
              #include "ui_mainwindow.h"
              #include <QSerialPort>
              #include <QDebug>
              
              QSerialPort * serial;
              
              MainWindow::MainWindow(QWidget *parent) :
                  QMainWindow(parent),
                  ui(new Ui::MainWindow)
              {
                  ui->setupUi(this);
              
                  serial = new QSerialPort(this);
              
                  serial -> setPortName("/dev/ttyACM1");
                  serial -> setBaudRate(QSerialPort::Baud115200);
                  serial -> setDataBits(QSerialPort::Data8);
                  serial -> setParity(QSerialPort::NoParity);
                  serial -> setStopBits(QSerialPort::OneStop);
                  serial -> setFlowControl(QSerialPort::NoFlowControl);
                  serial -> open(QIODevice::ReadWrite);
              
                  connect(serial, SIGNAL(readyRead()),this,SLOT(serialreceived()));
              }
              
              MainWindow::~MainWindow()
              {
                  delete ui;
                  serial ->close();
              }
              
              void MainWindow::serialreceived()
              {
                  if(serial -> canReadLine())
                  {
                      QString str = serial -> readAll();
              
                      int num = str.toInt();
                      ui -> progressBar -> setValue(num);
                 }
              }
              

              I don't know, what's wrong with this code. Output getting only 0 If I get proper output with QSerial, it's not necessary to go with any other libraries like RS232 etc.

              aha_1980A J.HilkJ 2 Replies Last reply
              0
              • G Geeva

                @KroMignon @aha_1980 I have tried to use qserial for receiving data, but I didn't get the proper response. I don't know where is the problem exactly. I hope you can help me to get a solution.

                mainwindow.h

                #include <QMainWindow>
                
                namespace Ui {
                class MainWindow;
                }
                
                class MainWindow : public QMainWindow
                {
                    Q_OBJECT
                
                public:
                    explicit MainWindow(QWidget *parent = 0);
                    ~MainWindow();
                
                private slots:
                
                    void serialreceived();
                
                private:
                    Ui::MainWindow *ui;
                

                mainwindow.cpp

                #include "mainwindow.h"
                #include "ui_mainwindow.h"
                #include <QSerialPort>
                #include <QDebug>
                
                QSerialPort * serial;
                
                MainWindow::MainWindow(QWidget *parent) :
                    QMainWindow(parent),
                    ui(new Ui::MainWindow)
                {
                    ui->setupUi(this);
                
                    serial = new QSerialPort(this);
                
                    serial -> setPortName("/dev/ttyACM1");
                    serial -> setBaudRate(QSerialPort::Baud115200);
                    serial -> setDataBits(QSerialPort::Data8);
                    serial -> setParity(QSerialPort::NoParity);
                    serial -> setStopBits(QSerialPort::OneStop);
                    serial -> setFlowControl(QSerialPort::NoFlowControl);
                    serial -> open(QIODevice::ReadWrite);
                
                    connect(serial, SIGNAL(readyRead()),this,SLOT(serialreceived()));
                }
                
                MainWindow::~MainWindow()
                {
                    delete ui;
                    serial ->close();
                }
                
                void MainWindow::serialreceived()
                {
                    if(serial -> canReadLine())
                    {
                        QString str = serial -> readAll();
                
                        int num = str.toInt();
                        ui -> progressBar -> setValue(num);
                   }
                }
                

                I don't know, what's wrong with this code. Output getting only 0 If I get proper output with QSerial, it's not necessary to go with any other libraries like RS232 etc.

                aha_1980A Offline
                aha_1980A Offline
                aha_1980
                Lifetime Qt Champion
                wrote on last edited by aha_1980
                #7

                @Geeva

                Your code looks good so far, just make QSerialPort * serial; a proper class member.

                Also, check for errors on opening the port: serial->open(QIODevice::ReadWrite);

                Then, insert some qDebug() in serialreceived() to see if the slot is called at all and if the canReadLine() works.

                Hint: You should use readLine() instead readAll() like this:

                void MainWindow::serialreceived()
                {
                    while (serial->canReadLine()) {
                        QString str = serial -> readLine().trimmed();
                        qDebug() << str;
                
                        int num = str.toInt();
                        ui -> progressBar -> setValue(num);
                   }
                }
                

                Qt has to stay free or it will die.

                1 Reply Last reply
                4
                • G Geeva

                  @KroMignon @aha_1980 I have tried to use qserial for receiving data, but I didn't get the proper response. I don't know where is the problem exactly. I hope you can help me to get a solution.

                  mainwindow.h

                  #include <QMainWindow>
                  
                  namespace Ui {
                  class MainWindow;
                  }
                  
                  class MainWindow : public QMainWindow
                  {
                      Q_OBJECT
                  
                  public:
                      explicit MainWindow(QWidget *parent = 0);
                      ~MainWindow();
                  
                  private slots:
                  
                      void serialreceived();
                  
                  private:
                      Ui::MainWindow *ui;
                  

                  mainwindow.cpp

                  #include "mainwindow.h"
                  #include "ui_mainwindow.h"
                  #include <QSerialPort>
                  #include <QDebug>
                  
                  QSerialPort * serial;
                  
                  MainWindow::MainWindow(QWidget *parent) :
                      QMainWindow(parent),
                      ui(new Ui::MainWindow)
                  {
                      ui->setupUi(this);
                  
                      serial = new QSerialPort(this);
                  
                      serial -> setPortName("/dev/ttyACM1");
                      serial -> setBaudRate(QSerialPort::Baud115200);
                      serial -> setDataBits(QSerialPort::Data8);
                      serial -> setParity(QSerialPort::NoParity);
                      serial -> setStopBits(QSerialPort::OneStop);
                      serial -> setFlowControl(QSerialPort::NoFlowControl);
                      serial -> open(QIODevice::ReadWrite);
                  
                      connect(serial, SIGNAL(readyRead()),this,SLOT(serialreceived()));
                  }
                  
                  MainWindow::~MainWindow()
                  {
                      delete ui;
                      serial ->close();
                  }
                  
                  void MainWindow::serialreceived()
                  {
                      if(serial -> canReadLine())
                      {
                          QString str = serial -> readAll();
                  
                          int num = str.toInt();
                          ui -> progressBar -> setValue(num);
                     }
                  }
                  

                  I don't know, what's wrong with this code. Output getting only 0 If I get proper output with QSerial, it's not necessary to go with any other libraries like RS232 etc.

                  J.HilkJ Offline
                  J.HilkJ Offline
                  J.Hilk
                  Moderators
                  wrote on last edited by
                  #8

                  @Geeva to add to what @aha_1980 said,

                  you should use QByteArray to read your data. If there's any char in the response, that is not String conform, the resulting QString will be prematurely terminated.

                      QByteArray data = serial -> readLine();
                      qDebug() < data.toHex(' '); // prints the hex representation of your char array
                      QString str(data);
                      qDebug() << str;
                      ....
                  
                  

                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  aha_1980A 1 Reply Last reply
                  4
                  • J.HilkJ J.Hilk

                    @Geeva to add to what @aha_1980 said,

                    you should use QByteArray to read your data. If there's any char in the response, that is not String conform, the resulting QString will be prematurely terminated.

                        QByteArray data = serial -> readLine();
                        qDebug() < data.toHex(' '); // prints the hex representation of your char array
                        QString str(data);
                        qDebug() << str;
                        ....
                    
                    
                    aha_1980A Offline
                    aha_1980A Offline
                    aha_1980
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    @J.Hilk Good catch. I think to convert it to an int, not even a QString conversion is needed, as QByteArray has toInt() too.

                    Qt has to stay free or it will die.

                    1 Reply Last reply
                    4
                    • fcarneyF Offline
                      fcarneyF Offline
                      fcarney
                      wrote on last edited by fcarney
                      #10

                      If you are going to convert to values that may not have the same endianess you might be further ahead in using QDataStream to take as input a QByteArray. It allows you to easily select the endian format for the bytes and use stream semantics to read out your data as floats, ints, etc.

                      Edit: Unless your data is actually text...

                      C++ is a perfectly valid school of magic.

                      aha_1980A 1 Reply Last reply
                      1
                      • fcarneyF fcarney

                        If you are going to convert to values that may not have the same endianess you might be further ahead in using QDataStream to take as input a QByteArray. It allows you to easily select the endian format for the bytes and use stream semantics to read out your data as floats, ints, etc.

                        Edit: Unless your data is actually text...

                        aha_1980A Offline
                        aha_1980A Offline
                        aha_1980
                        Lifetime Qt Champion
                        wrote on last edited by aha_1980
                        #11

                        @fcarney

                        Edit: Unless your data is actually text...

                        Which seems the case here ;)

                        Qt has to stay free or it will die.

                        1 Reply Last reply
                        1
                        • G Offline
                          G Offline
                          Geeva
                          wrote on last edited by
                          #12

                          @aha_1980 I got the data, but I am facing a problem. The below code working fine, I got the data from the Arduino.

                          void MainWindow::serialreceived()
                          {
                              while (serial->canReadLine()) {
                                  QString str = serial -> readLine().trimmed();
                                  qDebug() << str;
                          
                                  double num = str.todouble();
                          
                          Output:
                          
                          0.00
                          0.01
                          0.02
                          0.03
                          etc..
                          

                          I have tried to store the data in variable Thread::store = num; When I was try to read the data from other thread I am getting improper data/slow data/inbetween 0. Can you help me to fix this issue?

                          aha_1980A 1 Reply Last reply
                          0
                          • G Geeva

                            @aha_1980 I got the data, but I am facing a problem. The below code working fine, I got the data from the Arduino.

                            void MainWindow::serialreceived()
                            {
                                while (serial->canReadLine()) {
                                    QString str = serial -> readLine().trimmed();
                                    qDebug() << str;
                            
                                    double num = str.todouble();
                            
                            Output:
                            
                            0.00
                            0.01
                            0.02
                            0.03
                            etc..
                            

                            I have tried to store the data in variable Thread::store = num; When I was try to read the data from other thread I am getting improper data/slow data/inbetween 0. Can you help me to fix this issue?

                            aha_1980A Offline
                            aha_1980A Offline
                            aha_1980
                            Lifetime Qt Champion
                            wrote on last edited by
                            #13

                            @Geeva

                            • Do you really need to have multiple threads? This is complicating things and needs a lot of experience to be handled correctly.
                            • No matter if you use threads or not, the easiest way is to define a signal void numberReceived(double number) and connect it to the receiver. Then emit this signal from your serialreceived function.

                            Regards

                            Qt has to stay free or it will die.

                            1 Reply Last reply
                            3

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved