When I developed this asset, I really had in mind the optimization as well as giving the power to the user to optimize the code as he wishes. That's the main difference between Uduino and the other existing assets.


Communication with the Serial Port

Concretely, it means there are several of communicating with the Arduino Board:

  • Threads: Unity is not thread-safe, meaning it's not built by default to handle parallel calculations. By default in Uduino, the serial connection his done on a separated thread (let's call it "UduinoThread"), that runs in parallel with Unity main thread. Using a thread allows keeping constant FPS of the game when reading/writing information from the serial port (blocking operation).
  • Coroutines: If you toggle "Read On Threads" Boolean on the editor, the reading/writing will be done with Unity Coroutines, on the main thread. This option is present for developers who don't want to use threads.


Advanced Settings

Uduino features some advanced settings that you can manipulate to improve the performances of your game. These settings are available on the Editor under the Advanced dropdown.

Read and Write Buffers

Remember, if your game runs at 60 FPS, it means there is one Frame every 16 ms. By default the value of "Thread Frequency" is 16ms: Every 16 ms, the parallel thread will read and write some data to the Arduino board, then perform an action on the main Update loop of the game.

Buffer data storage

Every time you call a Uduino function (e.g. digitalWrite()), the command will be stored in a temporary buffer, waiting for the beginning of the new "UduinoThread" cycle to be sent over or to trigger an action on the Update()loop.
To skip the buffer and only send one information per cycle, you can toggle the Skip Queue boolean.
Every end of Update()loop, I could "empty" the send buffer (there is the option to clear everything but not to send everything at once). I chose not implement that, however, in a near future, I'm considering adding this as an additional option.

Buffer overload

If you send too many commands during the same Update() loop, the "write buffer" is going to be filled. And if you don't let enough time for the buffer to be sent to the Arduino board, for the user it will appear that some information is not sent properly to the board. For instance, the code here will most likely cause problems without optimization.

void Update() {
    UduinoManager.Instance.analogWrite(3, 155);
    UduinoManager.Instance.analogWrite(5, 30);
    UduinoManager.Instance.analogWrite(6, 215);
    UduinoManager.Instance.analogWrite(9, 0);
    UduinoManager.Instance.analogWrite(11, 100);
}

Hopefully, it's pretty easy to change Uduino settings to make it work!


Settings to avoid Buffer overflow and optimize reading/writing

  • Reducing Thread Frequency: By reducing the thread frequency, you can aim to communicate with the serial port more often than the FPS. Setting it to 3 ms
  • Limiting send rate: This option will automatically create Message Bundles. Once toggled on, ou will be able to select the Send rate speed (ms).
  • Reducing read/write timeouts: Everytime Uduino is performing a read or write operation on the serial port, a timeout ensure that the operation is non-blocking (it can otherwise significantly reduce the FPS). Reducing the read and write timeouts can improve performance but can also create problems when reading long streams of characters.
  • Disabling "Always read": If you don't need to read information from the Arduino board (e.g. a sensor value), toggling this option off will cut the read timeout.


Other methods to optimize Uduino

For an optimized code, using the default Uduino sketch is not the best solution. The best method is to develop your own commands sets using the advanced features of Uduino.
I recommend you to follow the tutorials on advanced data reading, advanced data writing, or other examples.