Introduction
blendixserial is an Arduino library that enables real-time, two-way communication between Arduino microcontroller boards and Blender 3D software. It allows you to synchronize 3D object properties (position, rotation, and size) between your physical Arduino hardware and virtual 3D scenes in Blender, making it possible to visualize sensor data, control animations with physical devices, and create interactive installations that blend the physical and digital worlds.
blendixserial is a lightweight, efficient C++ library designed for Arduino and Arduino-compatible microcontrollers. It provides a complete solution for bidirectional serial communication of 3D object transformation data. The library implements a custom binary protocol that minimizes bandwidth usage while maintaining robust error detection through XOR checksums.

Installation
- Download the library files from the given link.
- Extract the downloaded files.
- Copy the entire extracted folder into the Arduino libraries folder. The default location for this folder is:
- Windows: Documents\Arduino\libraries
- macOS: Documents/Arduino/libraries
- Linux: Documents/Arduino/libraries
- Restart the Arduino IDE if it was already open
Public API Reference
The blendixserial API is simple and intuitive. You work with three main concepts: objects, properties, and axes. Objects are the 3D entities in your Blender scene (0, 1, 2, etc.). Properties are the three types of transforms: Location (position), Rotation (orientation), and Scale (size). Axes are the three dimensions: X, Y, and Z.
Initialization
Create a global instance of the library:
blendixserial blendix;Sending Data to Blender
setLocation()
Set the position of a 3D object
Syntax: blendix.setLocation(objectIndex, x, y, z);Parameters:
- object Index: Which object to move (0, 1, 2, …)
- x: Position along X axis
- y: Position along Y axis
- z: Position along Z axis
Examples:
blendix.setLocation(0, 10.0, 5.0, -2.5); // Move object 0
blendix.setLocation(1, 0.0, 0.0, 0.0); // Move to origin
blendix.setLocation(2, sensor * 0.1, 0.0, 0.0); // Move based on sensorsetRotation()
Set the rotation (orientation) of a 3D object
Syntax: blendix.setRotation(objectIndex, x, y, z);Parameters:
- object Index: Which object to rotate (0, 1, 2, …)
- x: Rotation around X axis
- y: Rotation around Y axis
- z: Rotation around Z axis
Examples:
blendix.setRotation(0, 0.0, 0.0, 45.0); // Rotate 45 degrees around Z
blendix.setRotation(1, angle, 0.0, 0.0); // Rotate continuously
blendix.setRotation(2, 90.0, 90.0, 0.0); // Tilt and roll
setScale()
Set the size of a 3D object
Syntax: blendix.setScale(objectIndex, x, y, z);Parameters:
- object Index: Which object to scale (0, 1, 2, …)
- x: Scale factor for X dimension (1.0 = normal size)
- y: Scale factor for Y dimension
- z: Scale factor for Z dimension
Examples:
blendix.setScale(0, 2.0, 2.0, 2.0); // Make object 2x larger
blendix.setScale(1, scale, scale, scale); // Scale based on variable
blendix.setScale(2, 1.0, 1.0, 0.1); // Make flat disc
setValue()
Set a single transform component (when you need more control)
Syntax: blendix.setValue(objectIndex, Property, Axis, value);Parameters:
- object Index: Which object (0, 1, 2, …)
- Property: Location, Rotation, or Scale
- Axis: X, Y, or Z
- value: The numerical value to set
Examples:
blendix.setValue(0, Location, X, 5.0); // Set only X location
blendix.setValue(1, Rotaion, Y, 45.0); // Set only Y rotation
blendix.setValue(2, Scale, Z, 2.0); // Set only Z scale
setText()
Send a text message to Blender
Syntax: blendix.setText("message");Parameters: message: A text string (max 24 characters by default)
Examples:
blendix.setText("Running");
blendix.setText("Status: OK");
sprintf(buffer, "Temp: %d C", temperature);
blendix.setText(buffer);
Receiving Data from Blender
axisAvailable()
Check if a specific transform value has been received
Syntax: if(blendix.axisAvailable(objectIndex, Property, Axis)) { ... }Returns: true if the value is available
Example:
if (blendix.axisAvailable(0, Location, X)) {
float x = blendix.getValue(0, Location, X);
}
getValue()
Retrieve a single transform component
Syntax: float value = blendix.getValue(objectIndex, Property, Axis);Returns: The float value
Example:
float rotation = blendix.getValue(0, Rotation, Y);
Serial.println(rotation);
getLocation()
Retrieve all three position coordinates
Syntax: blendix.getLocation(objectIndex, x, y, z);Returns: Values returned in x, y, z variables
Example:
float x, y, z;
blendix.getLocation(0, x, y, z);
Serial.print("Position: "); Serial.print(x);
getRotation()
Retrieve all three rotation components
Syntax: blendix.getRotation(objectIndex, x, y, z);Returns: Values returned in x, y, z variables
Example:
float rx, ry, rz;
blendix.getRotation(0, rx, ry, rz);
getScale()
Retrieve all three scale factors
Syntax: blendix.getScale(objectIndex, x, y, z);Returns: Values returned in x, y, z variables
Example:
float sx, sy, sz;
blendix.getScale(0, sx, sy, sz);
Text API (Future Use)
These methods are reserved for future updates when Blender gain text sending capabilities.
bool textAvailable()Checks if new text has been received. Currently not used in Blender integration.
const char* getText()
Retrieves the received text and clears the flag. Always returns a null-terminated string. Currently not used in Blender integration.
Core Communication Functions
These two functions handle the actual serial communication. bodBuild() prepares data for transmission, and bodParse() processes incoming data.
bodBuild()
Create a packet containing all pending changes and transmit it
Syntax: uint16_t len = blendix.bodBuild(buffer);Parameters: buffer: An array of bytes (at least 256 bytes)
Returns: The number of bytes in the packet (0 if nothing to send)
Usage:
uint16_t len = blendix.bodBuild(buf);
if (len > 0) {
Serial.write(buf, len);
}Call this function after you have set all the transforms and text you want to send. It automatically packages everything efficiently into a binary format. If nothing has changed, it returns 0 and no packet is sent (saving bandwidth).
bodParse()
Process one byte of incoming serial data from Blender
Syntax: bool ready = blendix.bodParse(byte);Parameters: byte: A single byte from Serial.read()
Returns: true when a complete packet is received, false otherwise
Usage:
if (Serial.available()) {
uint8_t byte = Serial.read();
if (blendix.bodParse(byte)) {
// Complete packet received!
// Now you can call getValue(), getText(), etc.
}
}
Call this function for each byte received. It automatically handles packet assembly, validation, and error checking. When a complete packet arrives, bodParse() returns true, and you can then read the data using getValue(), getLocation(), getText(), etc.
Communication Patterns
Basic Send-Only Pattern
The simplest pattern: Arduino continuously sends data to Blender, Blender receives and displays it. No data flows back to Arduino.
void loop()
{
// Step 1: Set position and rotation
blendix.setLocation(0, 10.0, 20.0, 30.0); // X, Y, Z
blendix.setRotation(0, 0.0, 45.0, 0.0); // Rotate 45° on Y axis
// Step 2: Build packet
uint16_t len = blendix.bodBuild(buffer);
// Step 3: Send to Blender
if (len > 0) {
Serial.write(buffer, len);
}
// Step 4: Wait before sending next update
delay(50);
}Receive-Only Pattern
Opposite scenario: Blender sends transform data to Arduino, Arduino reads and responds.
void loop() {
if (Serial.available()) {
uint8_t byte = Serial.read();
if (blendix.bodParse(byte)) {
float x = blendix.getValue(0, LOCATION, X);
// Use the received value to control hardware
analogWrite(LedPin, x);
}
}
}Call this function for each byte received. It automatically handles packet assembly, validation, and error checking. When a complete packet arrives, bodParse() returns true, and you can then read the data using getValue(), getLocation(), getText(), etc.
Practical Examples
Arduino-to-Blender Data Example
#include "blendixserial.h"
blendixserial blendix;
uint8_t txBuffer[BLENDIXSERIAL_MAX_PACKET_SIZE];
unsigned long frame = 0;
void setup() {
Serial.begin(9600);
delay(500);
}
void loop() {
float posX, posY, posZ;
// Bobbing and Swaying
posX = sin(frame * 0.05) * 5.0;
posY = cos(frame * 0.03) * 3.0;
posZ = cos(frame * 0.04) * 5.0;
// Rotation: Smooth continuous rotation
float rotX = 0.0;
float rotY = frame * 2.0;
float rotZ = 0.0;
// Set and send
blendix.setLocation(0, posX, posY, posZ);
blendix.setRotation(0, rotX, rotY, rotZ);
uint16_t len = blendix.bodBuild(txBuffer);
if (len > 0) {
for (uint16_t i = 0; i < len; i++) {
Serial.write(txBuffer[i]);
}
}
frame++;
delay(50);
}Blender-to-Arduino Data Example
#include <SoftwareSerial.h>
#include "blendixserial.h"
#define BLENDER_RX 10
#define BLENDER_TX 11
SoftwareSerial blenderSerial(BLENDER_RX, BLENDER_TX);
blendixserial blendix;
void setup()
{
Serial.begin(9600);
blenderSerial.begin(9600);
Serial.println("Arduino Ready");
}
void loop()
{
while (blenderSerial.available())
{
uint8_t byteIn = blenderSerial.read();
if (blendix.bodParse(byteIn))
{
readObject0();
}
}
}
void readObject0()
{
float x, y, z;
// Get location only
blendix.getLocation(0, x, y, z);
Serial.print("Object0 Location: ");
Serial.print(x);
Serial.print(" , ");
Serial.print(y);
Serial.print(" , ");
Serial.println(z);
}Dual Serial Communication
As you can see in the receiving code example where we get data from Blender (Blender-to-Arduino Data Example), I used SoftwareSerial with the Arduino Uno. If you already know why it is used, that’s great. But if not, let me explain briefly.
Scenario
When sending data from Blender to an Arduino Uno, the data is transmitted through a serial connection. Normally, the Arduino communicates with the computer through its USB port, which uses the board’s hardware serial interface called Serial.
During development, programmers usually want to see debugging information such as received values or connection status. This is done by opening the Serial Monitor in the Arduino IDE and printing messages using Serial.print().
At the same time, Blender also needs to send data to the Arduino through a serial port. If both debugging and Blender communication use the same serial port, a conflict occurs. A common error that appears in this situation is:
Port monitor error: command 'open' failed: Serial port busy.
Could not connect to COMxx serial port.This happens because the serial port is already being used by another program.
The Problem
The Arduino Uno has only one hardware serial port (Serial). This port is internally connected to the USB interface of the board. Because of this, only one program can use the port at a time. For example:
- If Blender is connected to the Arduino through the USB serial port, the Serial Monitor cannot open it.
- If the Serial Monitor is already open, Blender cannot connect to the port.
Therefore, debugging messages and Blender communication cannot run simultaneously on the same serial port.
The Fix
To solve this limitation, an additional serial interface can be created using the SoftwareSerial. This library allows the Arduino to simulate another serial port using two digital pins. A USB to TTL converter is then connected to those pins to communicate with Blender. The final setup becomes:
- Hardware Serial (
Serial) → used for debugging with the Serial Monitor. - SoftwareSerial → used to receive data from Blender through the USB-to-TTL converter.
With this arrangement, Blender and the Serial Monitor use different serial channels, preventing port conflicts and allowing debugging while data is being received.
Arduino Mega Alternative
If you use an Arduino Mega 2560 or any board that has multiple hardware serial ports, you do not need SoftwareSerial. However, you still need a USB to TTL converter.
This is because the main port Serial0 is already connected to the onboard USB interface for communication with the PC. The additional ports (Serial1, Serial2, Serial3) are raw TTL serial pins, so a separate USB-to-TTL adapter is required to connect them directly to the computer.
Configuration
The behavior of the blendixserial library can be customized by editing the blendixserial_config.h file before compiling your sketch.
This configuration file defines a few important limits that control how much memory the library uses and how much data it can handle. By adjusting these values, you can adapt the library to suit different projects, from small Arduino setups with limited RAM to more complex scenes with multiple objects. Each parameter sets a maximum limit for a specific feature of the protocol.
Parameter: BLENDIXSERIAL_MAX_OBJECTS
Default: 3
Meaning: Maximum number of simultaneous objects.
This parameter defines how many objects the library can manage at the same time. Each object represents an element whose transformation data (location, rotation, and scale) can be transmitted through the protocol. You should set this value to match the number of objects in your Blender scene that you want to control or monitor. For example, if your project only interacts with a single object, you can reduce this value to save memory:
#define BLENDIXSERIAL_MAX_OBJECTS 1If your scene contains multiple objects, increase the value accordingly. For example, a scene with five controllable objects would require:
#define BLENDIXSERIAL_MAX_OBJECTS 5Keep in mind that each additional object requires extra memory because the library stores several floating-point values for each object’s transformation data.
Parameter: BLENDIXSERIAL_MAX_PAYLOAD
Default: 128
Meaning: Maximum payload size in bytes.
This parameter determines the maximum size of the data payload that can be transmitted in a single packet. The payload contains the actual information being exchanged, such as:
- Object transformation data
- Numeric values
- Optional text messages
In most cases the default value of 128 bytes is sufficient. However, if your application sends updates for many objects or includes larger messages, you may need to increase the payload size. Example:
#define BLENDIXSERIAL_MAX_PAYLOAD 200Increasing this value allows larger packets to be sent, but it also increases RAM usage because the library allocates a buffer of this size internally. For small projects, reducing the payload size can help conserve memory.
Parameter: BLENDIXSERIAL_MAX_TEXT
Default: 24
Meaning: Maximum length of text messages.
blendixserial supports sending short text messages along with object data. This parameter specifies the maximum number of characters that a text message can contain. For example, if you want to allow longer messages, you can increase the value:
#define BLENDIXSERIAL_MAX_TEXT 40If a message exceeds the configured length, it will be automatically truncated to fit within the buffer. Reducing this value lowers memory usage, which can be beneficial on microcontrollers with limited RAM.
Choosing Appropriate Values
When selecting configuration values, it is important to balance functionality and memory usage. For small projects or memory-constrained boards such as the Arduino Uno, it is recommended to keep these limits relatively low and only increase them when necessary.
The BlendixSerial Configurator available on the website can help you determine the correct values for all three configuration parameters. By entering details about your setup—such as the number of objects in your scene and the type of data you plan to send—the configurator calculates recommended values for:
BLENDIXSERIAL_MAX_OBJECTS
BLENDIXSERIAL_MAX_PAYLOAD
BLENDIXSERIAL_MAX_TEXTUsing the configurator ensures that the configuration matches your project requirements while keeping memory usage as efficient as possible. This is especially helpful when working with microcontrollers that have limited RAM.
License
This library is released under the terms of the GNU General Public License version 3 (GPLv3). Refer to the accompanying LICENSE file for details.
Video Gide
This video guide is for the old blendixserial (Blender addon + Arduino library). A new video guide will be coming soon.