2

I am performing a control analysis on an Arduino board.
As such, I want to minimize the board cycle duration.
(Faster board = faster controller).

Introduction:

I use Mathworks Matlab/Simulink to program the board.
I created a model in Simulink,
and embedded this model into my Arduino Mega 2650.

The model includes an Arduino Serial Transmit block.
I am therefore able to use Matlab software on my PC to request
serial transmission from the Arduino board to Matlab.

The Arduino Mega 2650 has the following serial constraints:

  • Maximum output buffer: 64 [byte]
  • Maximum baud frequency: ~115,000 [bit/s]

Problem:

To perform my control analysis,
I want to minimize the board cycle duration, and
I want to read several signals simultaneously.

The time it takes to read all signals sent
(as dictated by the baud rate)
is the primary obstacle in reducing my board cycle duration.

Requested Information:

Is it possible to reduce the board cycle duration
without reducing the duration in which
the serial transmission must be completed.

For example,
what if I run my board at 0.001 [s],
but I can only send all of my signals in 0.010 [s], what will happen during my reads?

If I read every 0.001 [s], obviously I will not receive all of the data,
as this is not feasible in the time that I am allotting.
My concern is regarding what will happen if I read every 0.010 [s]:

  1. Will the passing of several board cycles before the read completes affect the read?
  2. Is there a method to lock the serial output buffer while reading
    (such that the data does not change midread)?
  3. How long does it typically take to refill the serial output buffer with the next set of data?

Conclusion:

Ultimately, I would like to run the board as fast as possible,
since I believe that this could significantly improve my controller's performance,
despite not being able to read these additional cycles.

  • 1
    Decimation is not a problem, and is quite easy to do if you program the Arduino the “standard” way. The problem is you are programming with a tool that abstracts a lot of things away. You will then have to check whether this tool provides a “decimate” block. – Edgar Bonet May 30 '17 at 19:18
  • @EdgarBonet Decimation in the standard sense is easy. I could delay my read requests, such that they only occur every X board cycles. My concern is that if I start a read, and the read requires 10 board cycles to complete, then the variables which I am reading will change 10 times before I finish reading. If this occurs, will these variables be rewritten to the serial queue before I finish reading. If so, this could create racing conditions in which a read is occurring at the same time as a write. – kando May 30 '17 at 19:34
  • @EdgarBonet You are correct that using a 3rd party tool obfuscates even more of the things going on under the hood. – kando May 30 '17 at 19:35
  • @EdgarBonet - Adding a rate transition block before the serial transmit helped the decimation. As stated in Michel's answer, the data otherwise was sent to the serial buffer no matter how long I waited to read it. – kando May 30 '17 at 23:54
1

I don't think there will be a problem in this.

I do not understand exactly why you can only send signals every 0.010 s.

The board runs at 16 MHz, that's 16 million cycles per second, however, every 'instruction' normally takes many cycles (let along parsed C/Arduino language).

What you can do is to copy the read information into an array and use it later.

Keep in mind that the serial buffer is 64 bytes. If more is read, data will be overwritten. However, if you copy the buffer into your own (larger) buffer it might help. Also you can change the 64 bytes (it's somewhere in the Serial library).

The buffer works (afaik) with a sort of circular buffer, meaning it can store 64 bytes maximum 'unprocessed' bytes. So you don't have to wait until the buffer is full before processing (actually, this is not even the best method). You can process it as long as there are bytes available.

The pseudo code can be as follows:

lastSignalSent = millis(); // last time signals sent

void loop()
{
    while serial bytes available
    {
        process bytes
    }

    if (millis() - lastSignalSent > 10) // More than 10 ms ago
    {
        Send signals
         lastSignalSent = millis();
    }
}

This assumes the serial byte processing can be done faster than they arrive, but if not, you run into problems anyway, since the serial buffer (of only 64 bytes) will be full too fast.

  • Are these edits common? Mathworks provides no interface to make these edits by default with their standard library blocks, but I believe that it would be worth asking for if the changes were simple and unlocked faster and/or larger communication. – kando May 30 '17 at 19:04
  • This mentions increasing the serial rate to beyond 115,200 [Hz]. But it seems to require non-standard libraries, etcetera and references not a library specifically for faster transmission - rather, it mention a library intended for use with DMX (lighting) communication. – kando May 30 '17 at 19:08
  • I thought the max speed for serial is 115.2KHz, but DMX is 250KHz; maybe it uses a specific way of using the UART (or not an UART at all). There are many other ways to communicate (like SPI, I2C). – Michel Keijzers May 30 '17 at 20:16
  • About edits of common libraries, it's not common, but sometimes it is needed. It would be nicer if it was something that could be passed as argument. This edit is not inside Mathworks, it's in the Serial library (and unrelated to Mathworks). For Mathworks/matlab probably another forum is best to ask for details. – Michel Keijzers May 30 '17 at 20:17
  • I tested some things. I assumed that if I waited, that the old data was immediately overwritten by new data if I did not grab it. Instead, the data just builds up in the buffer until I read it. @EdgarBonet was correct in that I'll need to decimate it before it hits the Serial Transmit block. – kando May 30 '17 at 22:58

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.