visca_parser_web_logo

ViscaParser C++ library

v3.0.4

Table of contents

Overview

The ViscaParser is a C++ library for encoding control commands and checking responses for VISCA protocol messages. The library is designed according to the VISCA protocol description for the camera Sony FCB-EV7520A. The library allows developer to control other cameras that support the VISCA protocol. Before encoding and decoding specific commands, please check the source code of the library for the corresponding command according to the technical description of your 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. Also, the library includes test application to test communication with cameras. Test application depends on SerialPort library (provides methods to work with serial ports, source code included, Apache 2.0 license).

Versions

Table 1 - Library versions.

Version Release date What’s new
1.0.0 20.01.2022 - First version.
2.0.0 02.06.2022 - New commands added.
- Bugs fixed.
3.0.0 03.04.2023 - Class name changed from ViscaProtocolParser to ViscaParser.
- ViscaProtocolParserDataStructures.h file excluded.
- Documentation updated.
3.0.1 11.02.2024 - Documentation updated.
3.0.2 24.04.2024 - Documentation updated.
- Code reviewed.
3.0.3 24.05.2024 - Documentation updated.

Library files

The library supplied by source code only. The user would be given a set of files in the form of a CMake project (repository). The repository structure is shown below:

CMakeLists.txt --------------- Main CMake file.
src -------------------------- Folder with library source code.
    CMakeLists.txt ----------- CMake file of the library.
    ViscaParser.h ------------ Main library header file.
    ViscaParser.cpp ---------- C++ implementation file.
    ViscaParserVersion.h ----- Header file with library version.
    ViscaParserVersion.h.in -- CMake file to generate version header.
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.
    CMakeLists.txt ----------- CMake file for test application.
    main.cpp ----------------- Source C++ file of test application.

ViscaParser class description

Class declaration

ViscaParser.h contains main class ViscaParser declaration and ViscaPackets enum that contains list commands and messages supported by VISCA protocol. Class declaration:

class ViscaParser
{
public:

    /// Get library version.
    static std::string getVersion();

    /// Encode COMMAND or ENQUIRY COMMAND.
    bool encodeCommand(
        visca::ViscaPackets commandId, uint8_t* packet,
        uint32_t& packetSize, uint32_t cameraAddress,
        uint32_t param1 = 0, uint32_t param2 = 0,
        uint32_t param3 = 0, uint32_t param4 = 0,
        uint32_t param5 = 0, uint32_t param6 = 0,
        uint32_t param7 = 0, uint32_t param8 = 0,
        uint32_t param9 = 0, uint32_t param10 = 0);

    /// Decode input data byte-by-byte.
    visca::ViscaPackets decodeData(
        uint8_t nextByte, uint32_t cameraAddress,
        uint32_t& param1, uint32_t& param2,
        uint32_t& param3, uint32_t& param4,
        uint32_t& param5, uint32_t& param6,
        uint32_t& param7, uint32_t& param8,
        uint32_t& param9, uint32_t& param10);

    };

getVersion method

The getVersion() method returns string of current version of ViscaParser class. Method declaration:

static std::string getVersion();

Method can be used without ViscaParser class instance:

std::cout << "ViscaParser class version: " << ViscaParser::getVersion();

Console output:

ViscaParser class version: 3.0.4

encodeCommand method

encodeCommand(…) method intended to encode VISCA command to send to camera. Method declaration:

bool encodeCommand(
        visca::ViscaPackets commandId, uint8_t* packet,
        uint32_t& packetSize, uint32_t cameraAddress,
        uint32_t param1 = 0, uint32_t param2 = 0,
        uint32_t param3 = 0, uint32_t param4 = 0,
        uint32_t param5 = 0, uint32_t param6 = 0,
        uint32_t param7 = 0, uint32_t param8 = 0,
        uint32_t param9 = 0, uint32_t param10 = 0);
Parameter Value
commandId ID of VISCA command according to ViscaPackets enum (declared in ViscaParser.h file). ViscaPackets enum defines names of commands from VISCA protocol specification.
packetSize Pointer to the packet buffer to be filled by the method. The size of the buffer must be at least 24 bytes.
cameraAddress Camera address. Usually equals 1 or can be reassigned with the command visca::ViscaPackets::COMMAND_AddressSet. The camera address can be in the range from 1 to 7.
param1 Parameter 1. The value of each parameter depends on the commandId (see ViscaPackets enum).
param2 Parameter 2. The value of each parameter depends on the commandId (see ViscaPackets enum).
param3 Parameter 3. The value of each parameter depends on the commandId (see ViscaPackets enum).
param4 Parameter 4. The value of each parameter depends on the commandId (see ViscaPackets enum).
param5 Parameter 5. The value of each parameter depends on the commandId (see ViscaPackets enum).
param6 Parameter 6. The value of each parameter depends on the commandId (see ViscaPackets enum).
param7 Parameter 7. The value of each parameter depends on the commandId (see ViscaPackets enum).
param8 Parameter 8. The value of each parameter depends on the commandId (see ViscaPackets enum).
param9 Parameter 9. The value of each parameter depends on the commandId (see ViscaPackets enum).
param10 Parameter 10. The value of each parameter depends on the commandId (see ViscaPackets enum).

Returns: TRUE if the command encoded or FALSE if not.

decodeData method

decodeData(…) method intended for decoding input data received from the camera, processing it byte by byte. This process is essential for identifying connected packets within the data stream obtained from the serial port. To be detected right user should send request first. In encodeCommand method the library remember last encoded messages and uses it for decoding. Method declaration:

visca::ViscaPackets decodeData(
            uint8_t nextByte, uint32_t cameraAddress,
            uint32_t& param1, uint32_t& param2,
            uint32_t& param3, uint32_t& param4,
            uint32_t& param5, uint32_t& param6,
            uint32_t& param7, uint32_t& param8,
            uint32_t& param9, uint32_t& param10);
Parameter Value
nextByte Next byte in data to decode.
cameraAddress Camera address. Usually equals 1 or can be reassigned with the command visca::ViscaPackets::COMMAND_AddressSet. The camera address can be in the range from 1 to 7.
param1 Output parameter 1. The value of each parameter depends on the commandId (see ViscaPackets enum).
param2 Output parameter 2. The value of each parameter depends on the commandId (see ViscaPackets enum).
param3 Output parameter 3. The value of each parameter depends on the commandId (see ViscaPackets enum).
param4 Output parameter 4. The value of each parameter depends on the commandId (see ViscaPackets enum).
param5 Output parameter 5. The value of each parameter depends on the commandId (see ViscaPackets enum).
param6 Output parameter 6. The value of each parameter depends on the commandId (see ViscaPackets enum).
param7 Output parameter 7. The value of each parameter depends on the commandId (see ViscaPackets enum).
param8 Output parameter 8. The value of each parameter depends on the commandId (see ViscaPackets enum).
param9 Output parameter 9. The value of each parameter depends on the commandId (see ViscaPackets enum).
param10 Output parameter 10. The value of each parameter depends on the commandId (see ViscaPackets enum).

Returns: ID of message according to enumeration ViscaPackets enum. If the method decoded a message, it returns the message identifier. If no message is decoded, the method returns the identifier visca::ViscaPackets::UNDEFINED_PACKET.

Data Structures

ViscaPackets enum

ViscaPackets enum declared in ViscaParser.h file. Enum represents all commands and replies described in VISCA protocol. The enum delaration:

enum class ViscaPackets
{
    /// Not VISCA packets.
    UNDEFINED_PACKET,

    /// ERROR MESSAGES.
    ERROR_Message_Length,
    ERROR_Syntax,
    ERROR_Command_Buffer_Full,
    ERROR_Command_Canceled,
    ERROR_No_Socket,
    ERROR_Command_Not_Executable,
        
    /// COMMAND MESSAGES.
        
    /// Set address value. Parameters:
    /// camera address.
    COMMAND_AddressSet,

    /// Clears the command buffers in the camera and cancels the command
    /// currently being executed. No parameters.
    COMMAND_IF_Clear_Broadcast,
    /// Clears the command buffers in the camera and cancels the command
    /// currently being executed. Parameters: camera address.
    COMMAND_IF_Clear,

    /// Cancels the command currently being executed. Parameters:
    /// camera address
    /// param_1 - socket number (1 or 2).
    COMMAND_CommandCancel,

    /// Camera power On. Parameters:
    /// camera address.
    COMMAND_CAM_Power_On,
    /// Camera power Off (Standby). Parameters:
    /// camera address.
    COMMAND_CAM_Power_Off,

    /// ...... other commands ...... ///
}

Examples

Command encoding example

Below is an example of encoding command.

// Encoding
uint8_t packetData[24];
uint32_t packetSize = 0;
visca_parser.encodeCommand(cr::visca::ViscaPackets::INQUIRY_CAM_ZoomPosInq, packetData, packetSize, 1, 1);

// Sending to serial port.
serialPort.sendData(packetData, packetSize);

Command decoding example

Below is an example of decoding cameras response.

// Read data from serial port.
int numberOfBytes = serial_port.readData(packetData, packetSize);

// Decode data.
if (numberOfBytes <= 0)
{
    std::cout << "No response" << std::endl;
}
else
{
    for (int i = 0; i < numberOfBytes; ++i)
    {
        uint32_t param1, param2, param3, param4, param5, param6, param7, param8, param9, param10 = 0;
        switch(visca_parser.decodeData(packetData[i], 1, param1, param2, param3, param4, param5,
                                       param6, param7, param8, param9, param10))
        {
        case cr::visca::ViscaPackets::ACKNOWLEDGE:
            std::cout << "ACKNOWLEDGE" << std::endl;
            break;
        case cr::visca::ViscaPackets::COMPLETION_COMMANDS:
            std::cout << "COMPLETION_COMMANDS" << std::endl;
            break;
        case cr::visca::ViscaPackets::COMPLETION_INQUIRY:
            std::cout << "COMPLETION_INQUIRY" << std::endl;
            break;
        case cr::visca::ViscaPackets::REPLY_CAM_ZoomPos:
            std::cout << "ZOOM POSITION" << std::endl;
            break;
        default:
            break;
        }
    }
}

Build and connect to your project

Typical commands to build ViscaParser library:

cd ViscaParser
mkdir build
cd build
cmake ..
make

If you want connect ViscaParser 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 ViscaParser repository there. New structure of your repository:

CMakeLists.txt
src
    CMakeList.txt
    yourLib.h
    yourLib.cpp
3rdparty
    ViscaParser

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_VISCA_PARSER                 ON  CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_VISCA_PARSER)
    SET(${PARENT}_VISCA_PARSER                       ON  CACHE BOOL "" FORCE)
    SET(${PARENT}_VISCA_PARSER_TEST                  OFF CACHE BOOL "" FORCE)
endif()

################################################################################
## INCLUDING SUBDIRECTORIES
## Adding subdirectories according to the 3rd-party configuration
################################################################################
if (${PARENT}_SUBMODULE_VISCA_PARSER)
    add_subdirectory(ViscaParser)
endif()

File 3rdparty/CMakeLists.txt adds folder ViscaParser to your project and excludes test application and example from compiling (by default test applications and example are excluded from compiling if ViscaParser is included as sub-repository). The new structure of your repository:

CMakeLists.txt
src
    CMakeList.txt
    yourLib.h
    yourLib.cpp
3rdparty
    CMakeLists.txt
    ViscaParser

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} ViscaParser)

Done!

Test application

Folder ViscaParser/test contains the test application files. The test application allows you to generate some commands, send it to the lens over the serial port, receive and decode the response. Once started, the user must enter the serial port name (full name for Linux or just the port number for Windows), baudrate and camera address.

================================================
VISCA protocol parser v3.0.4 test
================================================

Enter serial port name: 
Enter serial port baudrate (bps): 
Enter camera address [1:7], 1 - default: 
Serial port /dev/serial/by-id/usb-FTDI_TTL232R_Sony-if00-port0 open. Wait response timeout by default 500 msec

After user can choose command (enter command ID). Test application supports the following commands:

Type of command:
1 - Zoom tele.
2 - Zoom wide.
3 - Zoom stop.
4 - Focus far.
5 - Focus near.
6 - Focus stop.
7 - Inquiry zoom position.
8 - Inquiry focus position.
9 - Enable autofocus mode.
0 - Disable autofocus mode.
10 - Inquiry lens control system.
Command type: