Serial Connection Plugin
The Serial Connection plugin handles RS-232 serial ports, USB-to-Serial adapters, and virtual serial ports. This is one of the most commonly used connection methods in INDI drivers.
When to Use Serial
- RS-232 serial port devices
- USB-to-Serial adapters (FTDI, Prolific, CP2102, etc.)
- Virtual serial ports
- Most legacy astronomy equipment
- Arduino and microcontroller-based devices
Header File
#include <connectionplugins/connectionserial.h>
Basic Setup
class MyDriver : public INDI::DefaultDevice
{
public:
MyDriver()
{
// Set default connection mode to Serial
setConnectionMode(CONNECTION_SERIAL);
// Create the Serial Connection plugin
serialConnection = new Connection::Serial(this);
// Configure defaults (optional)
serialConnection->setDefaultBaudRate(Connection::Serial::B_9600);
serialConnection->setDefaultPort("/dev/ttyUSB0");
// Register handshake function (optional)
serialConnection->registerHandshake([&]() { return Handshake(); });
// Register with the driver
registerConnection(serialConnection);
}
private:
Connection::Serial *serialConnection = nullptr;
bool Handshake()
{
// Send test command to verify connection
char response[32];
if (sendCommand("*IDN?\n", response, sizeof(response)))
{
if (strstr(response, "MyDevice"))
{
LOG_INFO("Device handshake successful");
return true;
}
}
LOG_ERROR("Handshake failed");
return false;
}
};
Communication Example
bool MyDriver::sendCommand(const char *cmd, char *res, int reslen)
{
// Get the serial port file descriptor
int fd = serialConnection->getPortFD();
if (fd < 0)
{
LOG_ERROR("Serial port not open");
return false;
}
// Write command
int nbytes_written = write(fd, cmd, strlen(cmd));
if (nbytes_written < 0)
{
LOGF_ERROR("Write error: %s", strerror(errno));
return false;
}
// Read response if expected
if (res && reslen > 0)
{
int nbytes_read = read(fd, res, reslen - 1);
if (nbytes_read < 0)
{
LOGF_ERROR("Read error: %s", strerror(errno));
return false;
}
res[nbytes_read] = '\0';
}
return true;
}
Available Baud Rates
The Serial plugin supports standard baud rates:
Connection::Serial::B_9600 // 9600 bps
Connection::Serial::B_19200 // 19200 bps
Connection::Serial::B_38400 // 38400 bps
Connection::Serial::B_57600 // 57600 bps
Connection::Serial::B_115200 // 115200 bps
Connection::Serial::B_230400 // 230400 bps
Advanced: Reading with Timeout
#include <poll.h>
bool MyDriver::readWithTimeout(char *buffer, int len, int timeout_ms)
{
int fd = serialConnection->getPortFD();
struct pollfd pfd;
pfd.fd = fd;
pfd.events = POLLIN;
int rc = poll(&pfd, 1, timeout_ms);
if (rc < 0)
{
LOGF_ERROR("Poll error: %s", strerror(errno));
return false;
}
else if (rc == 0)
{
LOG_ERROR("Read timeout");
return false;
}
int nbytes = read(fd, buffer, len - 1);
if (nbytes < 0)
{
LOGF_ERROR("Read error: %s", strerror(errno));
return false;
}
buffer[nbytes] = '\0';
return true;
}
Binary Data Transfer
For binary data (images, firmware, etc.):
bool MyDriver::sendBinaryData(const uint8_t *data, size_t len)
{
int fd = serialConnection->getPortFD();
size_t totalWritten = 0;
while (totalWritten < len)
{
int nbytes = write(fd, data + totalWritten, len - totalWritten);
if (nbytes < 0)
{
LOGF_ERROR("Write error: %s", strerror(errno));
return false;
}
totalWritten += nbytes;
}
return true;
}
Best Practices
- Baud Rate: Use the device’s documented baud rate
- Timeouts: Always use timeouts for read operations
- Flow Control: Consider hardware flow control for high-speed transfers
- Error Recovery: Implement retry logic for transient errors
- Buffer Flushing: Flush buffers after errors or unexpected data
- Line Endings: Be consistent with line endings (\r\n, \n, etc.)
Common Issues
Permission Denied
# Add user to dialout group
sudo usermod -a -G dialout $USER
# Log out and log back in
Device Not Found
# List serial devices
ls -l /dev/ttyUSB* /dev/ttyACM*
# Check dmesg for connection messages
dmesg | tail -20
Wrong Baud Rate
Symptoms include:
- Garbled data
- No response from device
- Partial commands
Solution: Verify baud rate in device documentation
Example Drivers
- Most INDI drivers use serial communication
- Check
indi-eqmodfor telescope control - Check
indi-asifor camera control - Check any mount or focuser driver