0

I'm trying to send an integer between 0 and 400 each second via serial port, and display it in Qt. The problem is that I'm reading inconsistent numbers like so:

174, 229, 397, 51, 220, 18, 1, 42

Here is my Arduino Code:

int data = 0; // variable to send via serial
unsigned long deltaTime;
unsigned long oldTime = 0;

void setup() {
  // initialize the serial communication:
  Serial.begin(9600);
}

void loop() {
   // decompose the integer into low and high bytes 
   byte b0 = lowByte(data);
   byte b1 = highByte(data);
   // Create a buffer and store the two bytes in it
   byte buff[2];
   buff [0] = b0;
   buff [1] = b1;
   deltaTime = millis() - oldTime;
   // When one second is passed send Data
   if (deltaTime > 1000) {
       // Send the packet
       Serial.write(buff,2) ;
       oldTime = millis();
   }
   // incremment the integer:
   data++; 
   if(data >= 400 ) data = 0;
}

And here is the Slot code in Qt:

void MainWindow::readData(){
    // read two bytes at once
    QByteArray data  = serial->read(2);
    // convert them back to int and display
    unsigned char b0 = (unsigned char)data[0];
    unsigned char b1 = (unsigned char)data[1];
    int val = (int)b1 * 256 + (int)b0 ;
    qDebug()<< val << endl;
}
3
  • Check the return value of Serial.write(). Are you sure the QSerialPort object is configured correctly? Commented Dec 23, 2015 at 8:38
  • @FrankOsterfeld The serial.write() simply send the buff array, and the port in Qt is configured corretly because i can send integers from Qt to arduino with no problems, the inverse is the one troubling me. Commented Dec 23, 2015 at 8:57
  • @Apastrix usually when you have an answer you should write if the answer itself solved your problem (and so accept it) or if it didn't (and tell why)... Commented Jan 5, 2016 at 10:26

1 Answer 1

2

Did you try to just print the data? I think no, because otherwise you would have noticed that.. You are not sending the integers one after the other.

The reason? You are adding one to data every iteration, but you are sending it away every second.

The way to fix it is really simple: this

if (deltaTime > 1000)
{  
    // Send the packet
    Serial.write(buff,2) ;
    oldTime = millis();
}

// increment the integer:
data++; 

if(data >= 400 ) data = 0;

should become this

if (deltaTime > 1000)
{  
    // Send the packet
    Serial.write(buff,2) ;
    oldTime = millis();

    // increment the integer:
    data++; 

    if(data >= 400 ) data = 0;
}

However I think you will experience some problems in the long run, especially if you are calling the slot with a 1s period.

I suggest you to use the unused bits (you send integers from 0 to 400, so 9 bits, but you are sending 16 of them) to provide a way to understand if the byte is the high one or the low one.

The easiest way would be to send the upper 7 bits in the first byte and set the highest bit to one, then send the lowest 7 bits and set the highest bit to zero. In the qt, then, read continuously. If the first bit is one then save the other part as the uppermost, if it is zero join the other part to the saved one and output it to the console.

Sign up to request clarification or add additional context in comments.

1 Comment

DId not review the code samples, but the idea of tagging the bytes is simple and clever.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.