Impact Acquire SDK C++
DigitalIOs.cpp

The DigitalIOs program shows the digital I/O information of the used Balluff device. The user can also interactively change the state of the digital output line and some other properties during the sample execution.

Purpose of the program
The DigitalIOs program shows the digital I/O information of the used Balluff device.
Program location
The source file DigitalIOs.cpp can be found under:
%INSTALLDIR%\apps\DigitalIOs\
Note
If you have installed the package without example applications, this file will not be available. On Windows® the sample application can be installed or removed from the target system at any time by simply restarting the installation package.
DigitalIOs example:
  1. Opens a Balluff device.
  2. You can change the state of the digital I/O's.
Console Output
[0]: BF000306 (mvBlueFOX-202C, Family: mvBlueFOX, interface layout: DeviceSpecific)

Please enter the number in front of the listed device followed by [ENTER] to open it: 0
Using device number 0.
This device has
  2 digital input(s)
   [0]: DigitialInput0(current state: 0)
   [1]: DigitialInput1(current state: 0)

All input registers can be queried with a single function call: Calling 'readInputRegister' returned 0x0
From the LSB to the MSB a '1' in this result indicates, that this input is currently connected to a signal
that is interpreted as a logical '1'. E.g. 0x13 indicates that inputs 0, 1 and 4 are currently in 'high' state.
  4 digital output(s)
   [0]: DigitalOutput0(current state: 0, manually switchable)
   [1]: DigitalOutput1(current state: 0, manually switchable)
   [2]: DigitalOutput2(current state: 0, manually switchable)
   [3]: DigitalOutput3(current state: 0, manually switchable)

Enter the number of a digital output followed by [ENTER] to modify its state or 'c' followed by [ENTER] to continue.

>>> 0
Please enter the number in front of the function that shall be called followed by [ENTER]:
  [0]: set
  [1]: reset
  [2]: flip

>>> 0
   [0]: DigitalOutput0(current state: 1, manually switchable)
   [1]: DigitalOutput1(current state: 0, manually switchable)
   [2]: DigitalOutput2(current state: 0, manually switchable)
   [3]: DigitalOutput3(current state: 0, manually switchable)

Enter the number of a digital output followed by [ENTER] to modify its state or 'c' followed by [ENTER] to continue.

>>>
How it works
In the main, a functions is called, where the user can select the device (getDeviceFromUserInput()). Afterwards the sample opens the device (pDev->open()) and will check, if the device is a member of the mvBlueFOX family, a member of the mvBlueCOGUAR family or a frame grabber.

According to the device, the digital I/O information will be displayed. In detail this will be:

Apart from this output of the current state and description of the different input and output signal lines and related properties the user can also interactively change the state of the digital output line and some other properties during the sample execution. How this can be achieved can be seen in the source code of the sample.

Source code
//
// @description: Example applications for Impact Acquire
// @copyright: Copyright (C) 2009 - 2023 Balluff GmbH
// @authors: APIs and drivers development team at Balluff GmbH
// @initial date: 2009-02-25
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,i
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <thread>
#include <vector>
#include <apps/Common/exampleHelper.h>
#include <common/minmax.h>
#include <mvIMPACT_CPP/mvIMPACT_acquire.h>
#include <mvIMPACT_CPP/mvIMPACT_acquire_GenICam.h>
using namespace std;
using namespace mvIMPACT::acquire;
//-----------------------------------------------------------------------------
string getStringFromCIN( void )
//-----------------------------------------------------------------------------
{
cout << endl << ">>> ";
string cmd;
cin >> cmd;
// remove the '\n' from the stream
cin.get();
return cmd;
}
//-----------------------------------------------------------------------------
int getIntFromCIN( void )
//-----------------------------------------------------------------------------
{
return atoi( getStringFromCIN().c_str() );
}
//-----------------------------------------------------------------------------
int getHEXFromCIN( void )
//-----------------------------------------------------------------------------
{
int result = 0;
#if (defined(_MSC_VER) && (_MSC_VER >= 1400)) || defined (__STDC_LIB_EXT1__) // is at least VC 2005 compiler OR implementation supports CRT extensions?
sscanf_s( getStringFromCIN().c_str(), "%i", &result );
#else
sscanf( getStringFromCIN().c_str(), "%i", &result );
#endif // #if (defined(_MSC_VER) && (_MSC_VER >= 1400)) || defined (__STDC_LIB_EXT1__) // is at least VC 2005 compiler OR implementation supports CRT extensions?
return result;
}
//-----------------------------------------------------------------------------
template<typename _Ty>
void hexToCOUT( const _Ty& param )
//-----------------------------------------------------------------------------
{
cout.setf( ios::hex, ios::basefield );
cout << "0x" << param;
cout.unsetf( ios::hex );
}
//-----------------------------------------------------------------------------
void modifySyncOutput( SyncOutput* p )
//-----------------------------------------------------------------------------
{
displayPropertyData( p->frequency_Hz );
modifyPropertyValue( p->frequency_Hz );
displayPropertyData( p->lowPart_pc );
modifyPropertyValue( p->lowPart_pc );
}
//-----------------------------------------------------------------------------
void displayCommonIOFeatures( IOSubSystem& ioss )
//-----------------------------------------------------------------------------
{
// display available features
cout << "This device has" << endl;
const unsigned int inputCount = ioss.getInputCount();
cout << " " << inputCount << " digital input(s)" << endl;
// display the state and name of each individual digital input
for( unsigned int i = 0; i < inputCount; i++ )
{
cout << " [" << i << "]: " << ioss.input( i )->getDescription() << "(current state: " << ioss.input( i )->get() << ")" << endl;
}
cout << endl;
if( inputCount > 0 )
{
// read the state of all digital inputs in a single function call
cout << "All input registers can be queried with a single function call: Calling 'readInputRegister' returned ";
hexToCOUT( ioss.readInputRegister() );
cout << endl;
cout << "From the LSB to the MSB a '1' in this result indicates, that this input is currently connected to a signal" << endl
<< "that is interpreted as a logical '1'. E.g. 0x13 indicates that inputs 0, 1 and 4 are currently in 'high' state." << endl;
}
const unsigned int outputCount = ioss.getOutputCount();
cout << " " << outputCount << " digital output(s)" << endl;
if( outputCount > 0 )
{
unsigned int readOnlyAccessMask = 0;
bool boRun = true;
while( boRun )
{
// display the state and name of each individual digital output
for( unsigned int j = 0; j < outputCount; j++ )
{
DigitalOutput* pOutput = ioss.output( j );
cout << " [" << j << "]: " << pOutput->getDescription() << "(current state: " << pOutput->get() << ", " << ( pOutput->isWriteable() ? "" : "NOT " ) << "manually switchable)" << endl;
if( !pOutput->isWriteable() )
{
readOnlyAccessMask |= 1 << j;
}
}
cout << endl;
cout << "Enter the number of a digital output followed by [ENTER] to modify its state or 'c' followed by [ENTER] to continue." << endl;
const string cmd( getStringFromCIN() );
if( cmd == "c" )
{
boRun = false;
continue;
}
const unsigned int index = static_cast<unsigned int>( atoi( cmd.c_str() ) );
if( ( index >= outputCount ) || !isdigit( cmd[0] ) )
{
cout << "Invalid selection" << endl;
continue;
}
DigitalOutput* pOutput = ioss.output( index );
if( !pOutput->isWriteable() )
{
cout << pOutput->getDescription() << " is not manually switchable." << endl;
continue;
}
cout << "Please enter the number in front of the function that shall be called followed by [ENTER]:" << endl;
cout << " [0]: set" << endl
<< " [1]: reset" << endl
<< " [2]: flip" << endl;
const int newMode = getIntFromCIN();
switch( newMode )
{
case 0:
pOutput->set();
break;
case 1:
pOutput->reset();
break;
case 2:
pOutput->flip();
break;
default:
cout << "Invalid selection." << endl;
break;
}
}
// read the state of all digital outputs in a single function call
cout << "All output registers can be queried with a single function call." << endl
<< endl
<< "From the LSB to the MSB a '1' in this result indicates, that this output is currently switched to 'high' or 'active' state" << endl
<< endl
<< "E.g. 0x22 indicates that outputs 1 and 5 (zero-based) are currently in 'high' state." << endl;
const unsigned int fullOutputMask = bitMask( outputCount );
boRun = true;
while( boRun )
{
cout << "Calling 'readOutputRegister' returned ";
hexToCOUT( ioss.readOutputRegister() );
cout << endl;
cout << "Please enter 'y' followed by [ENTER] to modify all digital outputs with a single function" << endl
<< "call or anything else followed by [ENTER] to continue." << endl;
if( getStringFromCIN() != "y" )
{
boRun = false;
continue;
}
cout << "Please enter the bitmask in hex that contains the new values for the digital outputs followed by [ENTER]: ";
unsigned int value = static_cast<unsigned int>( getHEXFromCIN() );
if( value & ~fullOutputMask )
{
value &= fullOutputMask;
cout << "WARNING: More bits than outputs specified. Bitmask truncated to ";
hexToCOUT( value );
cout << endl;
}
cout << "Please enter the bitmask in hex that contains '1's for outputs that shall be affected by this operation followed by [ENTER]: ";
const unsigned int mask = static_cast<unsigned int>( getHEXFromCIN() );
if( readOnlyAccessMask & mask )
{
cout << "WARNING: At least one selected output is not manually switchable: Mask: ";
hexToCOUT( mask );
cout << ", read-only access mask: ";
hexToCOUT( readOnlyAccessMask );
cout << endl;
cout << "No digital outputs have been modified." << endl
<< endl;
continue;
}
ioss.writeOutputRegister( value, mask );
}
}
cout << "This device also has" << endl;
cout << " " << ioss.RTCtrProgramCount() << " hardware real-time controller(s)." << endl
<< endl;
if( ioss.RTCtrProgramCount() > 0 )
{
cout << "How to program the HRTC (Hardware RealTime Controller) is not part of this sample, but the manual will contain a separate chapter on this topic.";
}
cout << " " << ioss.getPulseStartConfigurationCount() << " pulse start configuration(s)." << endl
<< endl;
}
//-----------------------------------------------------------------------------
void mvGenICamIOAccess( Device* pDev )
//-----------------------------------------------------------------------------
{
try
{
DigitalIOControl dioc( pDev );
//Count the number of Digital IOs
const unsigned int IOCount = dioc.lineSelector.dictSize();
bool boRun = true;
while( boRun )
{
cout << endl;
cout << " This device has " << IOCount << " DigitalIOs" << endl;
cout << " ------------------------------------------" << endl;
// display information about each individual DigitalIO
vector<int64_type> validLineSelectorValues;
dioc.lineSelector.getTranslationDictValues( validLineSelectorValues );
for( const auto& value : validLineSelectorValues )
{
dioc.lineSelector.write( value );
cout << " IO " << value << ": \t Type: " << dioc.lineMode.readS() << " \t Current state: " << ( dioc.lineStatus.read() ? "ON" : "OFF" ) << endl;
}
cout << " ------------------------------------------" << endl;
cout << endl;
cout << "Please enter a valid line number followed by [ENTER]:" << endl;
cout << "- if it is an output its value will be inverted" << endl;
cout << "- if it is an input its value will be polled continuously for 10 seconds" << endl;
cout << "- or enter 'c' followed by [ENTER] to continue:" << endl;
const string cmd( getStringFromCIN() );
if( cmd == "c" )
{
boRun = false;
continue;
}
const unsigned int index = static_cast<unsigned int>( atoi( cmd.c_str() ) );
if( ( index >= IOCount ) || !isdigit( cmd[0] ) )
{
cout << "Invalid selection" << endl;
continue;
}
//Define the IO we are interested in
dioc.lineSelector.write( index );
//check whether selected IO is an Output or an Input
if( dioc.lineMode.readS() == "Output" )
{
dioc.lineInverter.write( dioc.lineInverter.read() ? bFalse : bTrue );
}
else if( dioc.lineMode.readS() == "Input" )
{
cout << endl
<< endl;
cout << " ------------------------------------------" << endl;
cout << " Polling Input '" << dioc.lineSelector.readS() << "'" << endl;
cout << " ------------------------------------------" << endl;
cout << endl;
for( int i = 0; i < 100; i++ )
{
cout << "\r Value:" << ( dioc.lineStatus.read() ? "ON" : "OFF" );
this_thread::sleep_for( chrono::milliseconds( 100 ) );
cout << "\t Remaining Time:"
<< fixed << setprecision( 1 )
<< ( 10. - ( static_cast<double>( i + 1 ) / 10. ) );
cout.flush();
}
cout << endl
<< endl;
}
else
{
cout << "IO " << index << " is a '" << dioc.lineMode.readS() << "'!" << endl;
}
}
}
catch( const ImpactAcquireException& e )
{
cout << endl;
cout << " An " << PRODUCT_NAME << " exception occurred:" << e.getErrorCodeAsString() << endl;
cout << endl;
}
}
//-----------------------------------------------------------------------------
void mvBlueFOXIOAccess( Device* pDev )
//-----------------------------------------------------------------------------
{
IOSubSystemBlueFOX ioss( pDev );
displayCommonIOFeatures( ioss );
if( ioss.digitalInputThreshold.isValid() )
{
cout << "This device also supports the '" << ioss.digitalInputThreshold.name() << "' property." << endl;
displayPropertyData( ioss.digitalInputThreshold );
}
cout << "To use a digital output in 'expose active' mode, the property '" << cs.flashMode.name() << "' can be used." << endl
<< "If a delay between switching the output and starting the frame exposure is needed, this can be achieved by " << endl
<< "writing to the property '" << cs.flashToExposeDelay_us.name() << "'." << endl;
}
//-----------------------------------------------------------------------------
int main( void )
//-----------------------------------------------------------------------------
{
DeviceManager devMgr;
Device* pDev = getDeviceFromUserInput( devMgr );
if( pDev == nullptr )
{
cout << "Unable to continue! Press [ENTER] to end the application" << endl;
cin.get();
return 1;
}
if( pDev->interfaceLayout.isValid() && ( pDev->interfaceLayout.read() == dilGenICam ) )
{
mvGenICamIOAccess( pDev );
}
else if( pDev->family.read() == "mvBlueFOX" )
{
mvBlueFOXIOAccess( pDev );
}
else
{
cout << "Device " << pDev->serial.read() << "(" << pDev->product << ") is not supported by this sample" << endl;
cout << "Press [ENTER] to end the application" << endl;
cin.get();
return 1;
}
cout << "Press [ENTER] to end the application" << endl;
cin.get();
return 0;
}
mvBlueFOX related camera settings(Device specific interface layout only).
Definition mvIMPACT_acquire.h:20032
bool isValid(void) const
Checks if the internal component referenced by this object is still valid.
Definition mvIMPACT_acquire.h:1721
Grants access to devices that can be operated by this software interface.
Definition mvIMPACT_acquire.h:7171
This class and its functions represent an actual device detected by this interface in the current sys...
Definition mvIMPACT_acquire.h:6118
PropertyS product
A string property (read-only) containing the product name of this device.
Definition mvIMPACT_acquire.h:6537
PropertyS serial
A string property (read-only) containing the serial number of this device.
Definition mvIMPACT_acquire.h:6551
PropertyS family
A string property (read-only) containing the family name of this device.
Definition mvIMPACT_acquire.h:6526
PropertyIDeviceInterfaceLayout interfaceLayout
An enumerated integer property which can be used to define which interface layout shall be used when ...
Definition mvIMPACT_acquire.h:6644
bool get(void) const
Returns the current state of this input pin.
Definition mvIMPACT_acquire.h:15515
std::string getDescription(void) const
Returns a description for this digital input.
Definition mvIMPACT_acquire.h:15530
A class to represent a digital output pin(Device specific interface layout only).
Definition mvIMPACT_acquire.h:15546
bool get(void) const
Returns the current state of this output pin.
Definition mvIMPACT_acquire.h:15571
void set(void)
Sets the output pin to 'logic 1'.
Definition mvIMPACT_acquire.h:15594
void reset(void)
Sets the output pin to 'logic 0'.
Definition mvIMPACT_acquire.h:15599
bool isWriteable(void) const
Checks if the caller has write/modify access to this digital output.
Definition mvIMPACT_acquire.h:15589
std::string getDescription(void) const
Returns a description for this digital output.
Definition mvIMPACT_acquire.h:15609
bool flip(void)
Inverts the current state of the digital output and returns the previous state.
Definition mvIMPACT_acquire.h:15559
ZYX read(int index=0) const
Reads a value from a property.
Definition mvIMPACT_acquire.h:4300
Category that contains the digital input and output control features.
Definition mvIMPACT_acquire_GenICam.h:3917
A class to handle the digital inputs and outputs for mvBlueFOX USB cameras(Device specific interface ...
Definition mvIMPACT_acquire.h:16787
A base class to handle digital inputs and outputs(Device specific interface layout only).
Definition mvIMPACT_acquire.h:16385
unsigned int getInputCount(void) const
Returns the number of mvIMPACT::acquire::DigitalInput s available for the mvIMPACT::acquire::Device a...
Definition mvIMPACT_acquire.h:16569
unsigned int getPulseStartConfigurationCount(void) const
Returns the number of mvIMPACT::acquire::PulseStartConfiguration objects available for the mvIMPACT::...
Definition mvIMPACT_acquire.h:16546
virtual void writeOutputRegister(unsigned int value, unsigned int mask=UINT_MAX)=0
Alters the state of the digital output register.
DigitalOutput * output(unsigned int nr) const
Returns a pointer to a mvIMPACT::acquire::DigitalOutput object.
Definition mvIMPACT_acquire.h:16615
unsigned int RTCtrProgramCount(void) const
Returns the number of mvIMPACT::acquire::RTCtrProgram s available for the mvIMPACT::acquire::Device a...
Definition mvIMPACT_acquire.h:16564
const DigitalInput * input(unsigned int nr) const
Returns a const pointer to a mvIMPACT::acquire::DigitalInput object.
Definition mvIMPACT_acquire.h:16597
unsigned int getOutputCount(void) const
Returns the number of digital outputs available for the mvIMPACT::acquire::Device associated with thi...
Definition mvIMPACT_acquire.h:16622
virtual unsigned int readOutputRegister(void) const =0
Returns the current state of the digital output register.
virtual unsigned int readInputRegister(void) const =0
Returns the current state of the digital input register.
A base class for exceptions generated by Impact Acquire.
Definition mvIMPACT_acquire.h:256
std::string getErrorCodeAsString(void) const
Returns a string representation of the error associated with the exception.
Definition mvIMPACT_acquire.h:288
std::string read(int index=0) const
Reads a value from a property.
Definition mvIMPACT_acquire.h:5323
A class to represent a sync. output pin(Device specific interface layout only).
Definition mvIMPACT_acquire.h:15629
PropertyF lowPart_pc
A float property defining the width in percent the sync. signal stays low during one period....
Definition mvIMPACT_acquire.h:15644
PropertyF frequency_Hz
A float property defining the frequency(in Hertz) for the sync. signal generated by this pin.
Definition mvIMPACT_acquire.h:15642
@ bFalse
Off, false or logical low.
Definition mvDriverBaseEnums.h:589
@ bTrue
On, true or logical high.
Definition mvDriverBaseEnums.h:591
This namespace contains classes and functions belonging to the GenICam specific part of the image acq...
Definition mvIMPACT_acquire.h:23827
This namespace contains classes and functions belonging to the image acquisition module of this SDK.
Definition mvCommonDataTypes.h:34