OwlParser C++ library
v1.0.4
Table of contents
- Overview
- Versions
- Library files
- OwlParser class description
- Data structures
- Examples
- Test application
- Build and connect to your project
Overview
The OwlParser is a C++ library for encoding control commands and checking responses for Owl 640 camera. The library includes basic methods for preparing commands (encoding) and interpreting the camera responses (checking command arguments). It uses C++17 standard. The library provides simple interface and doesn’t have third party dependencies to be specially installed in OS. Also, the library provides test application to check communication with cameras via serial ports. Test application depends on SerialPort library (provides methods to work with serial ports, source code included, Apache 2.0 license) and ConfigReader library (provides methods to print logs, source code included, Apache 2.0 license).
Versions
Table 1 - Library versions.
Version | Release date | What’s new |
---|---|---|
1.0.0 | 04.05.2023 | - First version. |
1.0.1 | 27.03.2024 | - Documentation added. - Code optimized. |
1.0.2 | 23.05.2024 | - Documentation updated. |
1.0.3 | 31.07.2024 | - CMake structure updated. |
1.0.4 | 26.11.2024 | - Update included headers. |
Library files
The library is supplied only as source code. The user is given a set of files in the form of a CMake project (repository). The repository structure is shown below:
CMakeLists.txt ------------- Main CMake file of the library.
src ----------------------- Folder with library source code.
CMakeLists.txt --------- CMake file of the library.
OwlParser.h ------------ Main library header file.
OwlParserVersion.h ----- Header file with library version.
OwlParserVersion.h.in -- File for CMake to generate version header.
OwlParser.cpp ---------- C++ implementation file.
test ----------------------- Folder for test application files.
3rdparty --------------- Folder with third-party libraries.
CMakeLists.txt ----- CMake file to include third-party libraries.
SerialPort --------- Folder with SerialPort library source code.
ConfigReader ------- Folder with ConfigReader library source code.
CMakeLists.txt --------- CMake file for test application.
main.cpp --------------- Source C++ file of test application.
OwlParser class description
Class declaration
class OwlParser
{
public:
/// Get library version.
static std::string getVersion();
/// Encode owl command.
bool encodeCommand(uint8_t *data,
int &size,
Owl640Command id,
uint32_t arg1 = 0,
uint32_t arg2 = 0,
uint32_t arg3 = 0,
uint32_t arg4 = 0);
/// Process owl reply.
OwlReply processReply(Owl640Command commandId,
uint8_t commandCrc,
uint8_t nextByte,
std::vector<uint32_t> ¶ms);
};
getVersion method
The getVersion() method return string of current OwlParser class version. Method declaration:
static std::string getVersion();
Method can be used without OwlParser class instance:
std::cout << "OwlParser version: " << OwlParser::getVersion();
Console output:
OwlParser version: 1.0.4
encodeCommand method
The encodeCommand(…) method encodes (prepares data) control command for camera. See Command encoding example for usage of method. Method declaration:
bool encodeCommand(uint8_t *data,
int &size,
Owl640Command id,
uint32_t arg1 = 0,
uint32_t arg2 = 0,
uint32_t arg3 = 0,
uint32_t arg4 = 0);
Parameter | Value |
---|---|
data | Address of buffer for encoded data (command). Size of buffer also depends on command id but it is better to give at least 10 bytes. |
size | Size of encoded command. |
id | Command ID according to Owl640Command enum. |
arg1-arg4 | Arguments of command. The value of arguments depends on command ID. |
Returns: TRUE if commands encoded or FALSE if not (invalid ID or invalid parameters).
processReply method
The processReply(…) method processes the camera response. See the Response processing example. Once the data from the serial port has been read the user must pass it to the method byte-by-byte (each byte separately in sequence). The library has an internal ring buffer. When the user passes another byte to the method, the library shifts the ring buffer by one byte and copies the new byte to the end of the buffer. If the library detects a valid response in the ring buffer, it returns the response ID (see OwlReply enum) and returns the response arguments. Method declaration:
OwlReply processReply(Owl640Command commandId,
uint8_t commandCrc,
uint8_t nextByte,
std::vector<uint32_t> ¶ms);
Parameter | Value |
---|---|
commandId | Command ID according to Owl640Command enum. |
commandCrc | CRC of command. |
nextByte | Next byte of response. |
params | Vector of parameters. Number of parameters depends on command. |
Returns: OwlReply enum value.
Data structures
Owl640Command enum
The command IDs are described in the Owl640Command enum in the OwlParser.h file. The definition of the enum is as follows:
enum class Owl640Command
{
/**
* @brief Set systems state.
* @param arg1 0 - Checksum disabled, 1 - Checksum enabled.
* @param arg2 0 - Command ACK disabled, 1 - Command ACK enabled.
* @param arg3 0 - FPGA stop, 1 - FPGA run.
* @param arg4 0 - EEPROM serial disabled, 1 - EEPROM serial enabled.
*/
SET_SYSTEM_STATE,
/**
* @brief Will trap Micro causing watchdog and reset of Microcontroller firmware.
*/
RESET,
/**
* @brief Set 640 camera control register 0.
* @param arg1 0 - Horizontal Flip disable, 1 - Horizontal Flip enable.
* @param arg2 0 - Invert video disable, 1 - Invert video enable.
* @param arg3 0 - ALC disable, 1 - ALC enable.
* @param arg4 0 - TEC disable, 1 - TEC enable.
*/
SET_FLIP_ALC_TEC_MODE,
/**
* @brief Set 640 camera control register 1. AGMC and FAN (fo called only) mode.
* @param arg1 0 - AGMC disable, 1 - AGMC enable.
* @param arg2 0 - FAN disable, 1 - FAN enable.
*/
SET_AGMC_AND_FUN_MODE,
/**
* @brief Set 640 exposure. Note: ALC must be disabled.
* @param arg1 Exposure time 1 count = 1 * 40Mhz = 25 nsecs.
*/
SET_EXPOSURE_CMD1,
SET_EXPOSURE_CMD2,
SET_EXPOSURE_CMD3,
SET_EXPOSURE_CMD4,
/**
* @brief Set digital video gain.
* @param arg1 Gain.
* @param arg2 Level.
*/
SET_DIGITAL_VIDEO_GAIN_CMD1,
SET_DIGITAL_VIDEO_GAIN_CMD2,
/**
* @brief Set gain/trigger mode.
* @param arg1 0 - Internal trigger, 1 - External trigger.
* @param arg2 0 - -ve edge trigger, 1 - +ve edge trigger.
* @param arg3 0 - High Gain trigger mode 1, 1 - High Gain trigger mode 2.
* @param arg4 0 - Low gain, 1 - High gain.
*/
SET_GAIN_AND_TRIGGER_MODE,
/**
* @brief Set frame rate (internal trigger). 4 separate commands.
* @param arg1 Frame rate 1 count = 1 * 40MHz period = 25 nsecs.
*/
SET_FRAME_RATE_CMD1,
SET_FRAME_RATE_CMD2,
SET_FRAME_RATE_CMD3,
SET_FRAME_RATE_CMD4,
/**
* @brief Set TEC set point. 12 bit value to be converted to temperature
* from DAC calibration values.
* @param arg1 12bit DAC value.
*/
SET_TEC_SET_POINT_CMD1,
SET_TEC_SET_POINT_CMD2,
/**
* @brief Set NUC state.
* @param arg1 NUC mode: 0 - Offset corrected,
* 1 - Test pattern (ramp),
* 2 - Offset + Gain corrected.
* 3 - Uncorrected (NUC disabled).
* 4 - Offset + Gain + DARK (NUC enabled).
* @param arg2 0 - Bad pixels show disabled, 1 - Bad pixels show enabled.
*/
SET_NUC_STATE,
/**
* @brief Set auto level. 2 separate commands.
* @param arg1 14bit value (max 0x3FFF = White). Default 0x2000.
*/
SET_AUTO_LEVEL_CMD1,
SET_AUTO_LEVEL_CMD2,
/**
* @brief Set peak/average.
* @param arg1 8bit value: 0 - full peak, 255 - full average.
*/
SET_PEAK_AVERAGE,
/**
* @brief Set AGC speed.
* @param arg1 Gain from 0 to 15 (Default 7).
* @param arg2 Exposure speed from 0 to 15 (Default 7).
*/
SET_AGC_SPEED,
/**
* @brief Set ROI appearance.
* @param arg1 ROI mode: 0 - gain=1 outside ROI (Default).
* 1 - gain=0.75 outside ROI.
* 2 - gain=1 + ROI BOX.
*/
SET_ROI_APPEARANCE,
/**
* @brief Set ROI X offset.
* @param arg1 8bit value = 1/4 of X pixel offset.
*/
SET_ROI_X_OFFSET,
/**
* @brief Set ROI Y offset.
* @param arg2 8bit value = 1/4 of Y pixel offset.
*/
SET_ROI_Y_OFFSET,
/**
* @brief Set ROI X size.
* @param arg1 8bit value = 1/4 of X pixel offset.
*/
SET_ROI_X_SIZE,
/**
* @brief Set ROI Y size.
* @param arg1 8bit value = 1/4 of Y pixel offset.
*/
SET_ROI_Y_SIZE,
/**
* @brief Set trigger output.
* @param arg1 0 - Enable trigger output, 1 - disable trigger output.
*/
SET_TRIGGER_OUTPUT,
/**
* @brief Set gamma.
* @param arg1 0 - Disable gamma, 1 - Enable gamma.
*/
SET_GAMMA,
/**
* @brief Get system status.
*/
GET_SYSTEM_STATUS,
/**
* @brief Get Camera Control Register 0. 2 separate commands.
*/
GET_CAMERA_CONTROL_REGISTER_0_CMD1,
GET_CAMERA_CONTROL_REGISTER_0_CMD2,
/**
* @brief Get Camera Control Register 1. 2 separate commands.
*/
GET_CAMERA_CONTROL_REGISTER_1_CMD1,
GET_CAMERA_CONTROL_REGISTER_1_CMD2,
/**
* @brief Get exposure value (may also be read during Auto Exposure). 8 separate commands.
*/
GET_EXPOSURE_VALUE_CMD1,
GET_EXPOSURE_VALUE_CMD2,
GET_EXPOSURE_VALUE_CMD3,
GET_EXPOSURE_VALUE_CMD4,
GET_EXPOSURE_VALUE_CMD5,
GET_EXPOSURE_VALUE_CMD6,
GET_EXPOSURE_VALUE_CMD7,
GET_EXPOSURE_VALUE_CMD8,
/**
* @brief Get digital gain. 4 separate commands.
*/
GET_DIGITAL_GAIN_CMD1,
GET_DIGITAL_GAIN_CMD2,
GET_DIGITAL_GAIN_CMD3,
GET_DIGITAL_GAIN_CMD4,
/**
* @brief Get Gain/Trigger mode. 2 separate commands.
*/
GET_GAIN_TRIGGER_MODE_CMD1,
GET_GAIN_TRIGGER_MODE_CMD2,
/**
* @brief Get frame rate (Internal trig). 8 separate commands.
*/
GET_FRAME_RATE_CMD1,
GET_FRAME_RATE_CMD2,
GET_FRAME_RATE_CMD3,
GET_FRAME_RATE_CMD4,
GET_FRAME_RATE_CMD5,
GET_FRAME_RATE_CMD6,
GET_FRAME_RATE_CMD7,
GET_FRAME_RATE_CMD8,
/**
* @brief Get TEC Setpoint. 4 separate commands.
*/
GET_TEC_SET_POINT_CMD1,
GET_TEC_SET_POINT_CMD2,
GET_TEC_SET_POINT_CMD3,
GET_TEC_SET_POINT_CMD4,
/**
* @brief Get NUC state. 2 separate command.
*/
GET_NUC_STATE_CMD1,
GET_NUC_STATE_CMD2,
/**
* @brief Get auto level (Set point). 4 separate commands.
*/
GET_AUTO_LEVEL_CMD1,
GET_AUTO_LEVEL_CMD2,
GET_AUTO_LEVEL_CMD3,
GET_AUTO_LEVEL_CMD4,
/**
* @brief Get peak/average setting. 2 separate commands.
*/
GET_PEAK_AVERAGE_SETTING_CMD1,
GET_PEAK_AVERAGE_SETTING_CMD2,
/**
* @brief Get AGC speed. 2 separate commands.
*/
GET_AGC_SPEED_CMD1,
GET_AGC_SPEED_CMD2,
/**
* @brief Get ROI appearance. 2 separate commands.
*/
GET_ROI_APPEARANCE_CMD1,
GET_ROI_APPEARANCE_CMD2,
/**
* @brief Get ROI X offset. 2 separate commands.
*/
GET_ROI_X_OFFSET_CMD1,
GET_ROI_X_OFFSET_CMD2,
/**
* @brief Get ROI Y offset. 2 separate commands.
*/
GET_ROI_Y_OFFSET_CMD1,
GET_ROI_Y_OFFSET_CMD2,
/**
* @brief Get ROI X Size. 2 separate commands.
*/
GET_ROI_X_SIZE_CMD1,
GET_ROI_X_SIZE_CMD2,
/**
* @brief Get ROI Y Size. 2 separate commands.
*/
GET_ROI_Y_SIZE_CMD1,
GET_ROI_Y_SIZE_CMD2,
/**
* @brief Get Video Peak value. 4 separate commands.
*/
GET_VIDEO_PEAK_VALUE_CMD1,
GET_VIDEO_PEAK_VALUE_CMD2,
GET_VIDEO_PEAK_VALUE_CMD3,
GET_VIDEO_PEAK_VALUE_CMD4,
/**
* @brief Get Video Average value. 4 separate commands.
*/
GET_VIDEO_AVERAGE_VALUE_CMD1,
GET_VIDEO_AVERAGE_VALUE_CMD2,
GET_VIDEO_AVERAGE_VALUE_CMD3,
GET_VIDEO_AVERAGE_VALUE_CMD4,
/**
* @brief Get sensor PCB temperature. 4 separate commands.
*/
GET_SENSOR_PCB_TEMPERATURE_CMD1,
GET_SENSOR_PCB_TEMPERATURE_CMD2,
GET_SENSOR_PCB_TEMPERATURE_CMD3,
GET_SENSOR_PCB_TEMPERATURE_CMD4,
/**
* @brief Get Sensor Temp temperature. 4 separate commands.
*/
GET_SENSOR_TEMPERATURE_CMD1,
GET_SENSOR_TEMPERATURE_CMD2,
GET_SENSOR_TEMPERATURE_CMD3,
GET_SENSOR_TEMPERATURE_CMD4,
/**
* @brief Get Micro version.
*/
GET_MICRO_VERSION,
/**
* @brief Get Master FPGA version. 4 separate commands.
*/
GET_MASTER_FPGA_VERSION_CMD1,
GET_MASTER_FPGA_VERSION_CMD2,
GET_MASTER_FPGA_VERSION_CMD3,
GET_MASTER_FPGA_VERSION_CMD4,
/**
* @brief Get Slave FPGA version. 4 separate commands.
*/
GET_SLAVE_FPGA_VERSION_CMD1,
GET_SLAVE_FPGA_VERSION_CMD2,
GET_SLAVE_FPGA_VERSION_CMD3,
GET_SLAVE_FPGA_VERSION_CMD4,
/**
* @brief Get Unit Serial Number. 2 separate commands.
*/
GET_UNIT_SERIAL_NUMBER_CMD1,
GET_UNIT_SERIAL_NUMBER_CMD2,
/**
* @brief Get manufacturers Data. 2 separate commands.
*/
GET_MANUFACTURER_DATA_CMD1,
GET_MANUFACTURER_DATA_CMD2,
/**
* @brief Get Gamma. 2 separate commands.
*/
GET_GAMMA_CMD1,
GET_GAMMA_CMD2
};
The Owl640Command enum contains all possible commands for owl640 camera. Each command has its own set of arguments. The user must set arguments according to the command description.
OwlReply enum
The OwlReply enum contains all possible responses from the camera. The definition of the structure is as follows:
enum class OwlReply
{
/**
* @brief No message.
*/
NO_MESSAGE,
/**
* @brief Command acknowledge - command processed successfully.
*/
ETX,
/**
* @brief Partial command packet received, camera timed out waiting for end
* of packet. Command not processed.
*/
ETX_SER_TIMEOUT,
/**
* @brief Check sum transmitted by host did not match that calculated for the
* packet. Command not processed.
*/
ETX_CK_SUM_ERR,
/**
* @brief An I2C command has been received from the Host but failed
* internally in the camera.
*/
ETX_I2C_ERR,
/**
* @brief Data was detected on serial line, command not recognized.
*/
ETX_UNKNOWN_CMD,
/**
* @brief Host Command to access the camera EEPROM successfully
* received by camera but not processed as EEPROM is busy. I.e.
* FPGA trying to boot.
*/
ETX_DONE_LOW,
/**
* @brief Data.
*/
DATA,
/**
* @brief Format error.
*/
DATA_ERROR
};
Build and connect to your project
Typical commands to build OwlParser library:
cd OwlParser
mkdir build
cd build
cmake ..
make
If you want to connect OwlParser library to your CMake project as source code you can make follow. For example, if your repository has structure:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
Create folder 3rdparty and copy folder of OwlParser repository there. New structure of your repository:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
3rdparty
OwlParser
Create CMakeLists.txt file in 3rdparty folder. CMakeLists.txt should contain:
cmake_minimum_required(VERSION 3.13)
################################################################################
## 3RD-PARTY
## dependencies for the project
################################################################################
project(3rdparty LANGUAGES CXX)
################################################################################
## SETTINGS
## basic 3rd-party settings before use
################################################################################
# To inherit the top-level architecture when the project is used as a submodule.
SET(PARENT ${PARENT}_YOUR_PROJECT_3RDPARTY)
# Disable self-overwriting of parameters inside included subdirectories.
SET(${PARENT}_SUBMODULE_CACHE_OVERWRITE OFF CACHE BOOL "" FORCE)
################################################################################
## CONFIGURATION
## 3rd-party submodules configuration
################################################################################
SET(${PARENT}_SUBMODULE_OWL_PARSER ON CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_OWL_PARSER)
SET(${PARENT}_OWL_PARSER ON CACHE BOOL "" FORCE)
SET(${PARENT}_OWL_PARSER_TEST OFF CACHE BOOL "" FORCE)
endif()
################################################################################
## INCLUDING SUBDIRECTORIES
## Adding subdirectories according to the 3rd-party configuration
################################################################################
if (${PARENT}_SUBMODULE_OWL_PARSER)
add_subdirectory(OwlParser)
endif()
File 3rdparty/CMakeLists.txt adds folder OwlParser to your project and excludes test application and example from compiling (by default test applications and example are excluded from compiling if OwlParser is included as sub-repository). The new structure of your repository:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
3rdparty
CMakeLists.txt
OwlParser
Next you need include folder 3rdparty in main CMakeLists.txt file of your repository. Add string at the end of your main CMakeLists.txt:
add_subdirectory(3rdparty)
Next you have to include Lens library in your src/CMakeLists.txt file:
target_link_libraries(${PROJECT_NAME} OwlParser)
Done!
Examples
Command encoding example
Below is an example of encoding command.
// Init variables.
const int bufferSize = 1024; // Enough buffer size.
uint8_t buffer[bufferSize];
cr::owl::OwlParser parser;
int bytes = 0;
// Encode command.
if (!parser.encodeCommand(buffer, bytes, Owl640Command::SET_SYSTEM_STATE, 1, 1, 1, 0))
{
std::cout << "Command not encoded" << std::endl;
return;
}
// Clear serial port buffer.
g_serialPort.read(buffer, bufferSize);
// Send command.
if (g_serialPort.write(buffer, bytes) != bytes)
{
std::cout << "Data not sent" << std::endl;
return;
}
Response processing example
Below is an example of processing response.
// Init variables.
std::vector<uint32_t> params;
uint8_t commandCrc = 0;
Owl640Command commandId = Owl640Command::SET_SYSTEM_STATE;
// Buffer for received data.
uint8_t buffer[1024];
// Read data from serial port.
int bytesRead = g_serialPort.read(buffer, 1024);
// Process response.
for (int i = 0; i < bytesRead; i++)
{
OwlReply reply = parser.processReply(commandId, commandCrc, buffer[i], params);
// Use response ...
if (reply == OwlReply::ETX)
{
std::cout << "Command processed successfully" << std::endl;
for (int j = 0; j < params.size(); j++)
{
std::cout << "Param " << j << ": " << params[j] << std::endl;
}
}
else if (reply == OwlReply::ETX_SER_TIMEOUT)
{
std::cout << "Timeout" << std::endl;
}
else if (reply == OwlReply::ETX_CK_SUM_ERR)
{
std::cout << "Checksum error" << std::endl;
}
else if (reply == OwlReply::ETX_I2C_ERR)
{
std::cout << "I2C error" << std::endl;
}
else if (reply == OwlReply::ETX_UNKNOWN_CMD)
{
std::cout << "Unknown command" << std::endl;
}
else if (reply == OwlReply::ETX_DONE_LOW)
{
std::cout << "EEPROM busy" << std::endl;
}
}
Test application
Folder OwlParser/test contains the test application files. The test application automatically tests all commands one by one. Application sends commands to the camera over the serial port and then receive and prints the response as well as respond time. Application uses json configuration file OwlResponseTest.json to set serial port name, baudrate and timeout. If file does not exist, application will create the one with default values. The file has the following structure:
{
"Params":
{
"serialPortBaudrate": 115200,
"serialPortName": "\\\\.\\COM1",
"waitResponseTimeoutMsec":1000
}
}