The use of millis() in serial communication, Arduino 101

Hello all,

I have a gas sensor that measures the carbon dioxide concentration in the atmosphere. The sensor outputs the reading to the serial monitor by means of serial communication. By default, it collects 20 data per second, but I only want it to show 1 data per second. I’ve incorporated the code from the example ‘Blink Without Delay’, but encountered a problem. On my serial monitor, sometimes two consecutive data strings are concatenated together (refer to attached photo and Arduino code). How do I fix this?

serial monitor.JPG

sketch_feb02a.ino (2.32 KB)

      buffer[ind] = mySerial.read();
      ind++;

You assume that there will be room in the buffer for the character. That is NOT a good idea.

      val += buffer[i]-48; //because we break at 'z' the only bytes getting added are the numbers

There is no reason to piss away resources using a String. You could replace the 'z' in the buffer with a NULL, making buffer a string. Then, you could call atoi() with the string.

What is the point of multiplying an int by 10, and then pretending you got two decimal places of accuracy?

I would be interested in knowing what is actually in buffer. If you have garbage in buffer, then that would explain the garbage out periodically.

Reading the sensor once a second, and sending data to the PC once a second are two distinct things. Only one of them makes sense, since you have no control over when the sensor sends data. It may be sending it faster than you are reading it, causing data to be discarded on occasion, resulting in crap in the serial buffer.

Finally, it is not necessary to talk slowly to the PC. It can understand MUCH higher baud rates.

I would be interested in knowing what is actually in buffer. If you have garbage in buffer, then that would explain the garbage out periodically.

The buffer for each data goes like "Z 00400 z 00360". We are only interested in the filtered value, which in this case is 00400. This is why I'm ignoring 'Z', the blank space, and whatever is after 'z' in report().

The main reason I want to send data to PC at a slower rate than the sensor's rate of collection is that I'm trying to use Arduino 101's Bluetooth function to send off the data to a mobile app, which cannot handle 20 incoming data per second.

The main reason I want to send data to PC at a slower rate than the sensor’s rate of collection is that I’m trying to use Arduino 101’s Bluetooth function to send off the data to a mobile app, which cannot handle 20 incoming data per second.

How long it takes the mobile app to deal with the data that it has received has NOTHING to do with the baud rate you use to talk to it. And, the baud rate used to talk to the bluetooth device has nothing to do with the baud rate you use to talk to the PC, unless your bluetooth device is connected to the hardware serial pins and can’t be configured to get out of the stone age.

What the buffer is supposed to hold bears only a passing relationship to what it DOES hold.

Put the bluetooth device in a padded envelope and mail it to a friend on the other side of the world. Ask him/her to return it when you have the other issues in your code worked out.

If the device sending data is sending it faster than you are reading it, resulting in lost data, then you have choices:

  1. Read the data faster
  2. Have the device send data slower
  3. Have the device send less data
  4. Live with the losses

Which did you pick?

The way you are reading your sensor data is not robust. Have a look at the second example in Serial Input Basics

I think you should receive EVERY message from the sensor and save the value in a variable. If you don't need the older values just overwrite the previous value. If you don't process every message the Serial Input Buffer will fill up and you will not know what you are dealing with.

Then, once per second you can send whatever is the latest value in that variable to the PC.

Your code in loop() could be like this pseudo code

void loop() {
   recvWithEndMarker();
   if (newData == true) {
      save the value
      newData = false;
   if (one second has passed)
      send the value
}

Note how this completely disentangles the receiving and the sending.

...R