0
\$\begingroup\$

I am working on a project that requires data from 3 different sensors and syncing is necessary. The first sensor(HX711) is relatively slow proving 80 samples per second. The second sensor(MAX30101) works at around 200 samples per second. The third sensor(BMD101) works at around 500 samples per second. The third sensor is the one I'm currently having issues with.

I thought of timestamping the data and syncing them up using that. The problem that I'm facing is that when I add any small serial print along with just the third sensor data, I seem to miss a lot of data from the sensor and get checksum errors.

Here is the code I used to test this,

uint8_t inByte;

void setup() {
  //Set up Serial Ports
  Serial.begin(57600);
  Serial1.begin(57600);
}

void loop() {
  Serial1.readBytes(&inByte, 1);
  //Serial.write("E");
  Serial.write(inByte);
}

The BMD101 is connected to Serial1 of the Arduino Mega 2560 and the PC is at Serial. When I uncomment //Serial.write("E");. The data I receive is missing many bytes and I never receive the complete package, only checksum errors.

I don't just need it to be able to print a single character along with the data, I would like to have it print timestamps and data from two more sensors. How would I do that?

\$\endgroup\$
  • \$\begingroup\$ You are trying to insert "E" (0x45) in between every character from Serial1 and output that on Serial. Is that really what you are trying to do? \$\endgroup\$ – Jeroen3 Aug 20 at 8:24
  • \$\begingroup\$ For now yeah, But in the bigger picture, I'm trying to get data from three sensors, timestamp them and output that. But the third sensor is giving me issues with just inserting a single character (For eg. 'E'). let alone time stamp and attach data from two other sensors. \$\endgroup\$ – Prateek Dhanuka Aug 20 at 8:27
  • \$\begingroup\$ Is the data from the sensor only one byte each? \$\endgroup\$ – Jeroen3 Aug 20 at 8:29
  • \$\begingroup\$ Yes, the bytes accumulate to form a packet of variable length that I am parsing on the receiver side. \$\endgroup\$ – Prateek Dhanuka Aug 20 at 9:11
  • \$\begingroup\$ Do you NEED 500 Hz data, or can you send every other reading? \$\endgroup\$ – Scott Seidman Aug 20 at 11:14
3
\$\begingroup\$

While the Mega2560 is not the fastest process around it should be fast enough to handle the amount of data you are looking to process.

You do need to understand what the functions you are using are doing though, as well as how internal buffering works and the data rate limitations you are facing on your various serial interfaces.

Serial::readBytes will block (wait to return) until the specified number of bytes are retrieved or until a timeout occurs. You should check the return value for number of bytes received unless you are absolutely sure there will be a byte received within the specified time. The default timeout should be 1000 milliseconds. This function is used rarely, more common is to use available() and read() because they give you more control.

Serial.write will block if there is not enough room in the transmit buffers for the data you are trying to send.

Now, you say 500 samples per second - but you do not specify how many bytes of data is expected to be received for each sample. A quick check on the datasheet indicates it may be quite a few - at least 5, likely more. Even at just 5, with 500 samples/packets per second, that's a data rate of 2500 bytes per second.

Now, say that there is a little bit more than 5 bytes... like 6 bytes per packet/sample? Your data rate is now 3000 bytes per second.

For each incoming byte you are sending out two bytes, with write("E") uncommented. Your output data rate is 6000 bytes per second.

With standard 8,N,1 communication that's 60000 bits. It is not possible to send 60000 bits per second on a baudrate of 57600.

This means that your .write calls will block and during this time the input buffers of Serial1 will fill up faster than you can read them. They will overflow and this will look like missed characters.

\$\endgroup\$
  • \$\begingroup\$ Any way to overcome this? Is there any way to have non-blocking read write in Arduino? \$\endgroup\$ – Prateek Dhanuka Aug 20 at 9:49
  • \$\begingroup\$ Yes, using Serial.available() and Serial.read() is not blocking. Serial.write() is not blocking if you take care to never fill up the internal transmit buffer. In your specific example, simply increasing the baudrate of Serial may solve the issue for this particular test code. But you will need to think things through thoroughly for the final application. \$\endgroup\$ – Ronald McFüglethorn Aug 20 at 9:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.