C++17 header only, driver library providing low and high level access for TFmini ToF LIDAR sensors. The library is designed in such a way that it can work with single or multiple connected sensors. Supported firmware versions are 15x and 16x. The header only approach greatly simplifies the process of including it into other projects.
The minimum C++ standard is ISO/IEC 14882 (C++17).
The library is suitable from embedded devices to desktop computers and servers and anything in between as long as you have access to a C++17 compiler.
The project is hosted on GitHub https://github.com/ekondayan/libtfmini.
It is self contained and does not rely neither on the C++ Standard Library nor any other external dependencies. The code is just vanila C++17.
The library does not provide a low level communication layer, so it needs to be implemented by the user. This is easily done by implementing two global functions for sending and receiving data to/from the device.
void send(uint8_t device_id, const uint8_t *buffer, int16_t len);
void receive(uint8_t device_id, uint8_t *buffer, int16_t len);
Those two methods do one simple task - to send a buffer of specified length and to receive a buffer of specified length. This design decision was made for two reasons:
-
Communication layer is entirely project specific and it's implementation can differ from project to project. If you develop for a desktop you may want to use the native Linux serial port API or you may want to use the more user friendly and polished API of QT. If you develop for a MCU you may want to use the MCU's periphery directly or you may want to use the drivers provided by some RTOS. Those are just an examples of some use cases. The real world is much much more colorfull.
-
You may wish to have more control over the execution of
send
andreceive
. For example if you want to track the execution time or to count the bytes transfered by the two methods.
An example implementation of using the QT's SerialPort library
void send(uint8_t device_id, const uint8_t *buffer, int16_t len)
{
if(!port.isOpen()) return;
port.clearError();
port.write((const char*)buffer, len);
while(port.bytesToWrite() && port.waitForBytesWritten(100));
}
void receive(uint8_t device_id, uint8_t *buffer, int16_t len)
{
if(!port.isOpen()) return;
port.clearError();
int num_read = 0;
do num_read += port.read((char*)(buffer + num_read), len - num_read);
while(num_read != len && port.waitForReadyRead(100));
}
port
is an object of type QSerialPort
but you can use any other library.
device_id
is used to distinguish the connected devices. If you plan to use only one, you can safely discard it. If you plan to use multiple connected devices, you have to implement such a behaviour in send
and receive
. For example port
can be an array of QSerialPort
objects, each one connected to a different device.
void send(uint8_t device_id, const uint8_t *buffer, int16_t len)
{
if(!port[device_id].isOpen()) return;
port[device_id].clearError();
port[device_id].write((const char*)buffer, len);
while(port[device_id].bytesToWrite() && port[device_id].waitForBytesWritten(100));
}
void receive(uint8_t device_id, uint8_t *buffer, int16_t len)
{
if(!port[device_id].isOpen()) return;
port[device_id].clearError();
int num_read = 0;
do num_read += port[device_id].read((char*)(buffer + num_read), len - num_read);
while(num_read != len && port[device_id].waitForReadyRead(100));
}
The constructor of tfmini::TFmini
accepts three arguments:
-
device_id
- this parameter is passed tosend
andreceive
when an object wants to access a device. That waysend
andreceive
will know which device shall be accessed. It is used when you have more than one device connected. If you plan to work with just one device, you can safely discard it. -
send
pointer to function -
receive
pointer to function
tfmini::TFmini tfmini(device_id, &send, &receive);
A good practice is to subclass tfmini::TFmini
.
The API is organized in two layers: low level and high level.
Defined in tfmini_comm.h
. It's main purpose is to guarantee the correct transceiving of raw packets from/to the device.
Defined in tfmini.h
. It exposes high level functions for controlling the device. It's purpose is to correctly format the commands and pass them to the lower level API.
In the examples section you can find simple applications how to use the library.
You can download the project from GitHub using this command:
git clone https://github.com/ekondayan/libtfmini.git libtfmini
In order to use libtfmini, you just need to download and extract the header files into you project. In fact, the header files in the libtfmini subdirectory are the only files required to compile programs with the library. The header files are cross platform. It is not necessary to use CMake or install anything, just include the header files into your project.
Copyright (c) 2019-2020 Emil Kondayan
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
- if you are feeling nerdy, dig into the source code :)
Author: Emil Kondayan
Owner: Emil Kondayan
Maintainer: Emil Kondayan
Contributors: Emil Kondayan