How do I use C++ to communicate with my Remote IO Module?

FAQs

C++ is a popular multi platform programming language. Brainboxes have created a API (Application Programming Interface) which allows easy integration of Brainboxes Ethernet IO Modules (ED-xxx) into your C++ code.

There are 2 versions of the C++ API to target different platforms (both use the same source, but are packaged differently):

Each archive uses the same source C++ code but is packaged to be compiled by different toolchains and run on different OSes. The C++ API provides low level access to the ASCII protocol used by the Brainboxes Ethernet IO Modules, often C++ applications have strict timing requirements and for this reason a higher level API is not currently available. If you are looking for a higher level API it is recommended to use the Brainboxes.IO .NET API.

The Brainboxes.IO C++ API uses TCP connections to communicate with the Ethernet IO Module therefore no virtual com ports are required.

Requirements

  • Windows or Linux Computer (including but not limited to Raspbian Linux, Debian, Red Hat Linux, Ubuntu, Cygwin)
  • C++ Compiler, (e.g. GCC on Linux or Microsoft C++ Compiler on Windows)
  • Code Editor (for example Eclipse, TextMate, Visual Studio or a simple text editor)

Example Code

The following example code compiles to produce a command line Ethernet IO Module Console application.

C++ Brainboxes.IO API example application

/*
This file is part of the C++ example/library code for communication with with
Brainboxes Ethernet-attached data acquisition and control products, and is
provided by Brainboxes Limited.  Examples in other programming languages are
also available.
Visit http://www.brainboxes.com to see our range of Brainboxes Ethernet-
attached data acquisition and control products, and to check for updates to
this code package.

This is free and unencumbered software released into the public domain.
*/

#include "porting.h"
#include "exceptions.h"
#include "EDDeviceTCP.h"

#include <stdlib.h>
#include <iostream>
#include <string>

#ifdef USE_WINSOCK
#include <winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
#define PROCESS_CLEANUP { WSACleanup(); }
#else
#define PROCESS_CLEANUP { }
#endif

int main(int argc, char **argv)
{
	std::string ed_ipaddr;
	std::string ed_port = "9500";
	double timeout = 1.0;

	if (argc < 2) {
		std::cout << "usage: " <<] argv[0] << " <IP address> [<port number>] [<timeout>]n";
		return 1;
	}

#ifdef USE_WINSOCK
	// If we're using WinSock, it needs to be initialised once per application/process
	{
		WSADATA wsaData;
		WORD wVersionRequested = MAKEWORD(2, 2);

		if (WSAStartup(wVersionRequested, &wsaData) != 0) {
			// throw new Brainboxes_IO::Exception("Failed to initialise WinSock");
			std::cerr << "Failed to initialise WinSock.n" << std::flush;
			return 1;
		}
	}
#endif

	// get the arguments from the command line
	ed_ipaddr = argv[1];

	if (argc >= 3)
		ed_port = argv[2];

	if (argc >= 4)
		timeout = atof(argv[3]);

	std::cout << "Will attempt to connect to IP address '" << ed_ipaddr << "', port number " << ed_port << "...n" << std::flush;

	try {
		// create the Brainboxes_IO::EDDeviceTCP object which encapsulates the connection to the ED device
		Brainboxes_IO::EDDeviceTCP iodev(ed_ipaddr, ed_port);
		iodev.SetTimeout(timeout);

		// open the connection
		iodev.Connect();
		std::cout << "connected.n" << std::flush;

		// an example non-interactive communication
		std::string devname = iodev.SendCommand("$01M");
		std::cout << "Response to '$01M' is '" << devname << "'n";

		// a simple interactive terminal
		std::cout << "nEnter ASCII commands at the prompt below: enter a blank command to exit.n";
		while (!std::cin.eof()) {
			// get an ASCII command from the user
			std::string command;
			std::cout << ">" << std::flush;
			std::getline (std::cin, command);
			if (command.length()==0)
				break;
			// send the command to the ED device and display the response
			std::string response = iodev.SendCommand(command);
			std::cout << response << "n" << std::flush;
		}

		// close the connection
		iodev.Disconnect();
	}
	catch (Brainboxes_IO::Exception *e) {
		// error handling: exceptions thrown by the Brainboxes_IO library
		std::cout << std::flush;
		std::cerr << "An error occurred: " << e->message() << "n" << std::flush;
		PROCESS_CLEANUP
		return 1;
	}
	catch (...) {
		// error handling: exceptions thrown by something other than the Brainboxes_IO library
		std::cout << std::flush;
		std::cerr << "An unexpected exception occurred.n" << std::flush;
		PROCESS_CLEANUP
		return 1;
	};

	// std::cout << "nClean exitn";
	PROCESS_CLEANUP

	return 0;
}

Reference

For a full list of ASCII protocol commands which can be sent to the device see:
Brainboxes Remote IO ASCII protocol reference

FAQs