In this tutorial we will create the most basic INDI driver: a simple device! The simple device performs no functions, it just connects and disconnects.

All INDI devices inherit from INDI::DefaultDevice. Some specialized classes like INDI::Telescope also inherits from INDI::DefaultDevice and specific telescope drivers then inherit from INDI::Telescope.

Let's checkout the header file for Simple Device, which is included in the INDI Library package

#include "indibase/defaultdevice.h"

class SimpleDevice : public INDI::DefaultDevice
{
public:
    SimpleDevice();

protected:
    bool Connect();
    bool Disconnect();
    const char *getDefaultName();

};

Above, we declared a SimpleDevice class and inherited from INDI::DefaultDevice. We declared two functions that are called by the INDI framework when a client wants to Connect to or Disconnect from the device. The last function is called by INDI framework to find out the default name of the device, which may change at run time if necessary.

Let's look now at the implementation of the driver.

std::auto_ptr simpleDevice(0);

First, we declare an auto pointer to our class, we will use the pointer below to instantiate the object.

void ISInit()
{
 static int isInit=0;
 if (isInit)
  return;
 if (simpleDevice.get() == 0)
 {
     isInit = 1;
     simpleDevice.reset(new SimpleDevice());
 }
}

There are six mandatory INDI functions called by the INDI framework that must be declared in ALL INDI drivers:

  • ISGetProperties(): Is called when a client wants to retrieve a list of properties from the device.
  • ISNewSwitch: Is called when a client wants to set a new switch value.
  • ISNewText: Is called when a client wants to set a new text value.
  • ISNewNumber: Is called when a client wants to set a new number value.
  • ISNewBLOB: Is called when a client wants to set a new blob (Binary Large Object) value.
  • ISSnoopDevice: Is called when we receive property updates from other drivers we are monitoring for changes.

We call ISInit() from these functions to ensure proper initialization of the SimpleDevice pointer. We then simply pass the calls of the functions above to the SimpleDevice object which will handle them properly.

/**************************************************************************************
** Return properties of device.
***************************************************************************************/
void ISGetProperties (const char *dev)
{
 ISInit();
 simpleDevice->ISGetProperties(dev);
}

/**************************************************************************************
** Process new switch from client
***************************************************************************************/
void ISNewSwitch (const char *dev, const char *name, ISState *states, char *names[], int n)
{
 ISInit();
 simpleDevice->ISNewSwitch(dev, name, states, names, n);
}

/**************************************************************************************
** Process new text from client
***************************************************************************************/
void ISNewText (const char *dev, const char *name, char *texts[], char *names[], int n)
{
 ISInit();
 simpleDevice->ISNewText(dev, name, texts, names, n);
}

/**************************************************************************************
** Process new number from client
***************************************************************************************/
void ISNewNumber (const char *dev, const char *name, double values[], char *names[], int n)
{
 ISInit();
 simpleDevice->ISNewNumber(dev, name, values, names, n);
}

/**************************************************************************************
** Process new blob from client
***************************************************************************************/
void ISNewBLOB (const char *dev, const char *name, int sizes[], int blobsizes[], char *blobs[], char *formats[], char *names[], int n)
{
    ISInit();
    simpleDevice->ISNewBLOB(dev, name, sizes, blobsizes, blobs, formats, names, n);
}

/**************************************************************************************
** Process snooped property from another driver
***************************************************************************************/
void ISSnoopDevice (XMLEle *root)
{
  INDI_UNUSED(root);
}

Next we implement the Connect() and Disconnect() functions. We simply inform the client that the device was connected/disconnected successfully and return true.

SimpleDevice::SimpleDevice()
{
}

/**************************************************************************************
** Client is asking us to establish connection to the device
***************************************************************************************/
bool SimpleDevice::Connect()
{
    IDMessage(getDeviceName(), "Simple device connected successfully!");
    return true;
}

/**************************************************************************************
** Client is asking us to terminate connection to the device
***************************************************************************************/
bool SimpleDevice::Disconnect()
{
    IDMessage(getDeviceName(), "Simple device disconnected successfully!");
    return true;
}

Finally, we implement the getDefaultName() function.

/**************************************************************************************
** INDI is asking us for our default device name
***************************************************************************************/
const char * SimpleDevice::getDefaultName()
{
    return "Simple Device";
}

That's all for the most simple INDI device driver! You will also note that SimpleDevice create another tab Options, this is created by default for all devices and includes options to load/save configuration in addition to advanced options such as simulation or debugging.

Login

3rd Party

Choose from the numerous 3rd party INDI drivers to suit your needs!

Got Problem?

Check out the FAQ, the forum, and the bug tracking system to resolve any issues you might have!
You can also subscribe to INDI newsletter and development mailing lists to get the latest updates on INDI!