why / how can a switch statement execute halfway through?



  • Is C++ going crazy?
    I'm running a little project so i code this class:
    Header:

    #ifndef PUERTOSERIE2_H
    #define PUERTOSERIE2_H
    
    #include <QObject>
    #include <QWidget>
    #include <QSerialPort>
    #include <QByteArray>
    #include <QVector>
    #include <QPushButton>
    
    class PuertoSerie2 : public QWidget{
      Q_OBJECT
    
    public:
      explicit PuertoSerie2(QWidget *parent = nullptr);
    
    private Q_SLOTS:
      // Conecta con el dispositivo transmisor
      void conexion();
    
      // Lleva a cabo una lectura del vector de informacion entrante
      void leerPlaca();
    
    Q_SIGNALS:
      void SENSOR_A(int);
      void SENSOR_B(int);
      void SENSOR_C(int);
      void SENSOR_D(int);
      void SENSOR_E(int);
      void SENSOR_F(int);
      void SENSOR_G(int);
      void SENSOR_H(int);
      void SENSOR_I(int);
      void SENSOR_J(int);
      void SENSOR_K(int);
      void SENSOR_L(int);
      void SENSOR_M(int);
      void SENSOR_N(int);
      void SENSOR_O(int);
      void SENSOR_P(int);
    
    private:
      void emiteValor();
    
      char banderaEstado(QByteRef);
    
      void estado(char, char);
    
      void setValorSensores();
    
      int refactorizar(QByteArray);
    
      // Estado del boton
      int mPuertoEstado;
    
      QSerialPort *mPlaca;
    
      // Informacion de los sensores en arreglos para un  manejo mas compacto
      QVector<QByteArray> mSensorList;
    
      // Buffer de entrada
      QByteArray mBuffer;
    
      // Puerto de la PC
      QString mPuerto;
    
      // Boton que establece la conexion
      QPushButton *mBoton;  
    };
    
    #endif // PUERTOSERIE2_H
    

    And my cpp:

    PuertoSerie2::PuertoSerie2(QWidget *parent) : QWidget(parent){
      mPuertoEstado = 0;
      mPuerto = "COM3";
      mBuffer = "";
      mSensorList.push_back(QByteArray());
      qDebug() << "Vector de QByteArray" << mSensorList.at(0);
      mBoton = new QPushButton("Abrir Puerto", this);
    
      QHBoxLayout *layout = new QHBoxLayout(this);
      layout->addWidget(mBoton);
      layout->addStretch();
    
      connect(mBoton, SIGNAL(clicked()), this, SLOT(conexion()));
     }
    
    void PuertoSerie2::conexion(){
      if (mPuertoEstado == 0){
    
        mPlaca = new QSerialPort(this);
        mPlaca->setPortName(mPuerto);
        mPlaca->open(QIODevice::ReadWrite);
    
        if(mPlaca->isOpen() == false){
    
    	 QMessageBox::information(this, "Estado",
    	 "Error al Abrir el puerto: " + mPuerto);
    
        } else {
    
    	 mPlaca->setBaudRate(QSerialPort::Baud9600);
    	 mPlaca->setStopBits(QSerialPort::OneStop);
    	 mPlaca->setParity(QSerialPort::NoParity);
    	 mPlaca->setDataBits(QSerialPort::Data8);
    	 mPlaca->setFlowControl(QSerialPort::NoFlowControl);
    
    	 connect(mPlaca, SIGNAL(readyRead()), this, SLOT(leerPlaca()));
    
    	 mBoton->setText("Cerrar Puerto");
    	 QMessageBox::information(this, "Estado",
    	 "Puerto: " + mPuerto + " Abierto");
    	 mPuertoEstado = 1;
    
        }
      } else if (mPuertoEstado == 1){
    
        mPlaca->close();
        mPlaca->destroyed();
        mPuertoEstado = 0;
        mBoton->setText("Abrir Puerto");
        QMessageBox::information(this, "Estado",
        "Puerto: " + mPuerto + " Cerrado");
    
      }
    }
    
    void PuertoSerie2::estado(char bandera, char byte){
        switch (bandera) {
        // El estado a se supone que limpia los valores enteriores del vector
        // para introducir las nuevas lecturas
        case 'a':
            qDebug() << "\n----------Caso 'a' Disparado: " << byte;
            qDebug() << "\n          Tam de los vectores: " << mSensorList.size();
            qDebug() << "\n          Posicion: " << mSensorList.size();
            qDebug() << "\n          Contenido: ";
            for(int i = 0; i < mSensorList.size(); ++i){
                qDebug() << "\n          " << mSensorList.at(i);
            }
    
            while(mSensorList.size() > 1){
                mSensorList.pop_back();
            }
    
            for(int i = 0; i < mSensorList.size(); ++i){
                mSensorList[i].clear();
            }
    
            qDebug() << "\n~~~~~~~~~~Caso 'a' Saliendo: ";
            qDebug() << "\n          Tam de los vectores: " << mSensorList.size();
            qDebug() << "\n          Posicion: " << mSensorList.size();
        break;
    
        // El estado es un separador, aumenta el lugar del vector
        case 'b':
            qDebug() << "\n----------Caso 'b' Disparado: " << byte;
            qDebug() << "\n          Tam de los vectores: " << mSensorList.size();
            qDebug() << "\n          Posicion: " << mSensorList.size();
    
            emiteValor();
            mSensorList.push_back(QByteArray());
    
            qDebug() << "\n~~~~~~~~~~Caso 'b' Saliendo: ";
            qDebug() << "\n          Tam de los vectores: " << mSensorList.size();
            qDebug() << "\n          Posicion: " << mSensorList.size();
        break;
    
        // Tenemos informacion y la signamos al posicion actual de la coma
        case 'c':
            qDebug() << "\n----------Caso 'c' Disparado: " << byte;
            qDebug() << "\n          Posicion actual: " << mSensorList.size();
            qDebug() << "\n          Tam de los vectores: " << mSensorList.size();
            qDebug() << "\n          Contenido del vector actual: " <<
                        mSensorList.last();
    
            mSensorList.last() += byte;
    
            qDebug() << "\n~~~~~~~~~~Caso 'c' Saliendo: ";
            qDebug() << "\n          Posicion actual: " << mSensorList.size();
            qDebug() << "\n          Tam de los vectores: " << mSensorList.size();
            qDebug() << "\n          Contenido del vector actual: " <<
                        mSensorList.last();
        break;
    
        default:
        break;
        }
    }
    
    char PuertoSerie2::banderaEstado(QByteRef buffer){
      // 'a' = 42 (asterisco, inicio de cadena)
      // 'b' = 44 (coma, separador)
      // 'c' >= 48 (informacion, contenido)
    
      int var = (int)buffer;
    
      if(var == 42){
        return 'a';
      } else if(var == 44){
        return 'b';
      } else if(var >= 48){
        return 'c';
      }
    
      return 'd';
    }
    
    void PuertoSerie2::leerPlaca(){
    
      mBuffer = mPlaca->readAll();
    
      qDebug() << "\n>>>>>>>> Informacion de entrada: " << mBuffer;
    
      for(int i = 0; i < mBuffer.size(); ++i){
        estado(banderaEstado(mBuffer[i]), mBuffer.at(i));
      }
    
      mBuffer.clear();
    }
    
    void PuertoSerie2::emiteValor(){
        int valor = mSensorList.size() - 1;
        qDebug() <<"\n@@@@@@@@@@Valor emitido: " << mSensorList.at(valor).toInt();
        switch(valor){
    
        case 0:
            emit SENSOR_A(mSensorList.at(valor).toInt());
        break;
    
        case 1:
            emit SENSOR_B(mSensorList.at(valor).toInt());
        break;
    
        case 2:
            emit SENSOR_C(mSensorList.at(valor).toInt());
        break;
    
        case 3:
            emit SENSOR_D(mSensorList.at(valor).toInt());
        break;
    
        case 4:
            emit SENSOR_E(mSensorList.at(valor).toInt());
        break;
    
        case 5:
            emit SENSOR_F(mSensorList.at(valor).toInt());
        break;
    
        case 6:
            emit SENSOR_G(mSensorList.at(valor).toInt());
        break;
    
        case 7:
            emit SENSOR_H(mSensorList.at(valor).toInt());
        break;
    
        case 8:
            emit SENSOR_I(mSensorList.at(valor).toInt());
        break;
    
        case 9:
            emit SENSOR_J(mSensorList.at(valor).toInt());
        break;
    
        case 10:
            emit SENSOR_K(mSensorList.at(valor).toInt());
        break;
    
        case 11:
            emit SENSOR_L(mSensorList.at(valor).toInt());
        break;
    
        case 12:
            emit SENSOR_M(mSensorList.at(valor).toInt());
        break;
    
        case 13:
            emit SENSOR_N(mSensorList.at(valor).toInt());
        break;
    
        case 14:
            emit SENSOR_O(mSensorList.at(valor).toInt());
        break;
    
        case 15:
            emit SENSOR_P(mSensorList.at(valor).toInt());
        break;
    
        default:
        break;
        }
    }
    

    Now take a look at this: A new array of data was readed...

    >>>>>>>> Informacion de entrada:  "*2,70"
    
    ----------Caso 'a' Disparado:  *
    
              Tam de los vectores:  5
    
              Posicion:  5
    
              Contenido: 
    
               "2"
    
               "69"
    
               "0"
    
               "0"
    
               ""
    
    ~~~~~~~~~~Caso 'a' Saliendo: 
    
              Tam de los vectores:  1
    
              Posicion:  1
    
    ----------Caso 'c' Disparado:  2
    
              Posicion actual:  1
    
              Tam de los vectores:  1
    
              Contenido del vector actual:  ""
    
    ~~~~~~~~~~Caso 'c' Saliendo: 
    
              Posicion actual:  1
    
              Tam de los vectores:  1
    
              Contenido del vector actual:  "2"
    
    ----------Caso 'b' Disparado:  ,
    
              Tam de los vectores:  1
    
              Posicion:  1
    
    @@@@@@@@@@Valor emitido:  2
    
    ~~~~~~~~~~Caso 'b' Saliendo: 
    
              Tam de los vectores:  2
    
              Posicion:  2
    
    ----------Caso 'c' Disparado:  7
    
              Posicion actual:  2
    
              Tam de los vectores:  2
    
              Contenido del vector actual:  ""
    
    ~~~~~~~~~~Caso 'c' Saliendo: 
    
              Posicion actual:  2
    
              Tam de los vectores:  2
    
              Contenido del vector actual:  "7"
    
    ----------Caso 'c' Disparado:  0
    
              Posicion actual:  2
    
              Tam de los vectores:  2
    
              Contenido del vector actual:  "7"
    
    ~~~~~~~~~~Caso 'c' Saliendo: 
    
              Posicion actual:  2
    
              Tam de los vectores:  2
    
              Contenido del vector actual:  "70"
    
    ~~~~~~~~~~Caso 'b' Saliendo: 
    
              Tam de los vectores:  3
    
              Posicion:  3
    

    The last 2 cases ('c' and 'b') mark ''going out", specially the last one its a half case 'b'. Why is that? Specially when no data was recieved... this causes an Off-By-One Error in my widgets update.
    Any other comment about hidden erros will be welcome.


  • Qt Champions 2016

    @onimusha
    I don't know Spanish so it's pretty hard to make head or tails of what your code does and what the messages mean.

    One thing I saw is this:

    mPlaca->destroyed();
    

    this is a signal and you shouldn't be calling it explicitly from the outside. Aside from that I wasn't able to spot any obvious errors. What is this snippet supposed to do, it seems you're trying to parse some message, but it's somehow made very complicated by all the magic numbers ...? Do you get any crashes when debugging?



  • Hi @kshegunov the thing is simple, yes i'm parsing a message coming from an arduino, you know tha kind of projects. mPlaca->destroyed() is only called when i click for second time a button meaning i close the current COM port being used. the problem is when parsing one of my cases (the 'b' one) in the estado(char, char) function excecutes twice - the first time completly normal and the second time when the case 'c' is done but only the last part of it, the one that appends a new item to my QVector list therefore causing an off by one error in my widgets update. Why am i getting such a behavior? Is it due to the fact that i'm emitting my signals in that switch case? the last part of ny debug messages says "going out", thats 'c' case finishing and 'b' finsihng as well for no reason...


  • Qt Champions 2016

    @onimusha said:

    Is it due to the fact that i'm emitting my signals in that switch case?

    Probably, yes. Emitting a signal (when the sender and the receiver are in the same thread) is the same as calling the receiving signal/slot directly. So you might be having a somewhat "recursive" call through your functions. A quick thing to check would be to change all connections you have with your signals from the default (Qt:AutomaticConnection) to queued (Qt::QueuedConnection). If the problem disappears then this is indeed the problem.


Log in to reply
 

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