Cognex Mobile Barcode SDK (cmbSDK) is a tool for developing mobile barcode scanning applications. CmbSDK is based on Cognex's DataMan technology and the Manatee Works Barcode Scanning SDK allowing you to create applications for barcode scanning on mobile devices. Mobile devices used for barcode scanning are supported smartphones, tablets and the MX Series industrial barcode readers. CmbSDK abstracts the device through a CMBReaderDevice connection layer. Once the application establishes connection with the reader, a single and unified API serves as an interface to configure the device, without writing too much conditional code.
CmbSDK provides two basic CMBReaderDevice connection layers:
The cmbSDK supports Cognex’s MX Series Mobile Terminals with features using cmbSDK:
Submit a request on https://cmbdn.cognex.com/mfi/apply for each iOS app you want to submit to the App Store.
Once your MFI product plan request was processed, you are notified by e-mail about further steps, at which time you can submit your app to Apple directly.
Update your app’s notes before submitting to the App Store:
Connect your mobile device (phone or tablet) to your PC via the USB or lightning port to start debugging. If an MX Mobile Terminal is attached to your mobile device via the USB or lightning port while your application is running, you need to debug your application via Wi-Fi.
Prerequisites:
If you are running your application with XCode, make sure your device is plugged in via lightning cable and enable Connect via network on your mobile device:
Now you can close the Devices window and start debugging your application without using the lightning cable or USB.
Prerequisites.
After launching the application, you can safely unplug and continue your debugging session over Wi-Fi.
The differences in the barcode scanning capabilities of smartphones and purpose-built scanners result in different user experience, impacting the design of the mobile barcode scanning application. By following a few simple guidelines, you can develop applications with the cmbSDK that work the same way when using an MX Mobile Terminal or the built-in camera of a mobile device. Here are some links to start from:
Without a hardware trigger, mobile devices must use alternative methods to initiate barcode scanning. The cmbSDK supports three methods to trigger barcode scanning:
The built-in camera provides a live-stream preview on the display of the mobile device that can be in partial or full screen, in portrait or landscape orientation, for barcode aiming. Reposition the mobile device until the barcode appears in the field of view of the built-in camera and the application decodes it.
The cmbSDK supports passive aimers: devices attached to the mobile device or its case that use the LED flash of the device as a light source to project an aiming or targeting pattern. The mobile device can project an aimer pattern similar to a purpose-built scanner so live-preview is not needed.
In addition the CmbSDK supports an active aimer that has its own built-in LEDs for illumination and aiming: the MX-100 Barcode Reader. The MX-100 is a mobile device accessory for iOS smartphones attached to the mobile device with a mobile device case. The built-in LED of the MX-100 projects a green dot to help in reading the barcode.
The cmbSDK supports portrait orientation, landscape orientation and auto-rotation for both the presentation of the barcode preview and the scan direction. Mobile devices can scan most barcodes regardless of the orientation of the application and the mobile device.
For better read performance read QR, Data Matrix, and Maxicode in portrait orientation, and long codes like PDF417 in landscape orientation.
The cmbSDK is optimized for mobile environment, but image analysis and barcode decoding are still CPU intensive activities. Since these processes share the CPU of the mobile device with the mobile operating system (OS), services, and other applications, the following processes optimize your barcode scanning application and limit it to only using the features of the cmbSDK that they need.
To optimize your application:
Set up your application to use the iOS cmbSDK:
Open XCode and start a new project.
* SystemConfiguration.framework
* AVFoundation.framework
* CoreGraphics.framework
* CoreMedia.framework
* CoreVideo.framework
* MediaPlayer.framework
* Security.framework
* AudioToolbox.framework
* cmbSDK.framework
Go to your project's Info.plist file and add the Privacy - Camera Usage Description or NSCameraUsageDescription to display a message about how your application uses the camera of the user's mobile device.
The cmbSDK has been designed to provide a high-level, abstract interface for supported scanning devices. This includes not only the MX series of mobile terminals, but also for applications that intend to use the mobile device camera as the imaging device. The intricacies of communicating with and managing these devices is encapsulated within the SDK itself: leaving the application to just connect to the device of choice, then using it.
The primary interface between your application and a supported barcode scanning device is the CMBReaderDevice class. This class represents the abstraction layer to the device itself, handling all communication as well as any necessary hardware management (e.g., for smartphone scanning).
Perform the following steps to use the cmbSDK:
Initialize a Reader Device for the type of device you want to use: MX reader or camera reader.
Connect the Reader Device.
Configure the reader (if necessary).
Start scanning.
Initialization, connection, and configuration generally need to be performed only once in your application, except for the following cases:
Initializing the CMBReaderDevice for use with an MX mobile terminal like the MX-1000, MX-1100, or MX-1502 is easy: simply create the reader device using the MX device method (it requires no parameters), and set the appropriate delegate (normally self):
let readerDevice:CMBReaderDevice = CMBReaderDevice.readerOfMX()
readerDevice.delegate = self
CMBReaderDevice *readerDevice = [CMBReaderDevice readerOfMXDevice];
readerDevice.delegate = self;
The availability of the MX mobile terminal can change when the device turns ON or OFF, or if the lightning cable gets connected or disconnected. You can handle those changes using the following CMBReaderDeviceDelegate method.
func availabilityDidChange(ofReader reader: CMBReaderDevice)
- (void)availabilityDidChangeOfReader:(CMBReaderDevice *)reader
If you want to connect to a Cognex device on the network (e.g handheld or fixed mount) you have to use another framework named as NetworkDiscovery. This framework can be found in the cmbSDK bundle.
Barcode scanning with the built-in camera of the mobile device can be more complex than with an MX mobile terminal. Therefore the cmbSDK supports several configurations to provide the maximum flexibility, including support of optional external aimers and illumination, as well as the ability to customize the appearance of the live-stream preview. MX-100 is such an external device for your iPhone that we call active aimer.
To scan barcodes using MX-100 or the built-in camera of the mobile device, initialize the CMBReaderDevice object using the readerOfDeviceCameraWithCameraMode static method. The camera reader has several options when initialized. The following parameters are required:
* CDMCameraMode
* CDMPreviewOption
* UIView
The CameraMode parameter is of the type CDMCameraMode (defined in CDMDataManSystem.h), and it accepts one of the following values:
The above modes provide the following default settings for the mobile device as a code reader:
Based on the selected mode, the following additional options and behaviors are set:
The previewOptions parameter (of type CDMPreviewOption, defined in CDMDataManSystem.h) is used to change the reader’s default values or override defaults derived from the selected CameraMode. Multiple options can be specified by OR-ing them when passing the parameter. The available options are the following:
kCDMPreviewOptionHighResolution: Use the device camera in higher resolution to help with scanning small barcodes, but slow decode time. The option sets resolution to 1920x1080 on devices that support it, and the default one on devices that do not.The default resolution is 1280x720.
Examples:
Create a reader with no aimer and a full screen live-stream preview:
let readerDevice:CMBReaderDevice = CMBReaderDevice.readerOfDeviceCamera(with: CDMCameraMode.noAimer, previewOptions:CDMPreviewOption.init(rawValue: 0), previewView:nil)
readerDevice.delegate = self
CMBReaderDevice *readerDevice = [CMBReaderDevice readerOfDeviceCameraWithCameraMode:kCDMCameraModeNoAimer previewOptions:kCDMPreviewOptionDefaults previewView:nil];
readerDevice.delegate = self;
Create a reader with no aimer, no zoom button, and using a simulated trigger:
let readerDevice:CMBReaderDevice = CMBReaderDevice.readerOfDeviceCamera(with: CDMCameraMode.noAimer, previewOptions:[CDMPreviewOption.noZoomBtn, CDMPreviewOption.hwTrigger], previewView:nil)
readerDevice.delegate = self
CMBReaderDevice *readerDevice = [CMBReaderDevice readerOfDeviceCameraWithCameraMode:kCDMCameraModeNoAimer previewOptions:(kCDMPreviewOptionNoZoomBtn | kCDMPreviewOptionHwTrigger) previewView:nil];
readerDevice.delegate = self;
Initialize the CMBReaderDevice and set a delegate to handle responses from the reader.
Then connect using connectWithCompletion:
// Make sure the device is turned ON and ready
if self.readerDevice.availability == CMBReaderAvailibilityAvailable {
// create the connection between the readerDevice object and device
self.readerDevice.connect(completion: { (error:Error?) in
if error != nil {
// handle connection error
}
})
}
// Make sure the device is turned ON and ready
if (readerDevice.availability == CMBReaderAvailibilityAvailable) {
// create the connection between the readerDevice object and device
[readerDevice connectWithCompletion:^(NSError *error) {
if (error) {
// handle connection error
}
}];
}
When connected connectionStateDidChangeOfReader in the delegate is called, where you can check the connection status in your Reader Device's connectionState parameter. It should be CMBConnectionStateConnected, which means that you have successfully made the connection to the CMBReaderDevice, and can begin using the Cognex Mobile Barcode SDK.
To change some settings after connecting to the device the cmbSDK provides a set of high-level, device independent APIs for setting and retrieving the current configuration of the device.
The differences between using an MX reader and the camera reader for scanning are detailed in the following sections.
The MX family of mobile terminals provides sophisticated device configuration and management including saved configurations on the device. MX devices come Cognex preconfigured with most symbologies and features ready to use.
If you would like a custom configuration, reconfigure through DataMan Setup Tool, or the Cognex Quick Setup. Both tools distribute saved configurations easily to multiple devices for simple configuration management.
The mobile application is able to configure the MX device giving you the option to:
The cmbSDK employs a default set of options for barcode reading with the built-in camera of the mobile device. However, there are two important differences to keep in mind:
MX-100 is a device-case attachment for iPhones only that provides additional functionalities to the built-in camera such as aiming capabilities and better illumination control. Being a hybrid of an MX device and a built in scanner, the MX-100 has settings for aimer intensity, illumination intensity, and aimer modulation stored on the device, while the rest of the settings, like symbologies settings, are stored in the cmbSDK. See the MX-100 User Guide for more information.
Here are a few things to keep in mind when using an MX-100 device:
Individual symbologies can be enabled using the following method of the CMBReaderDevice object:
-(void) setSymbology:(CMBSymbology)symbology
enabled:(bool)enabled
completion:(void (^)(NSError *error))completionBlock;
All symbologies used for the symbology parameter in this method can be found in CMBReaderDevice.h.
Examples
self.readerDevice.setSymbology(CMBSymbologyQR, enabled: true, completion: {(_ error: Error?) -> Void in
if error != nil {
// Failed to enable that symbology, Possible causes are: reader disconnected, out of battery or cable unplugged, or symbology not supported by the current readerDevice
}
})
[readerDevice setSymbology:CMBSymbologyQR enabled:YES completion:^(NSError *error){
if (error) {
// Failed to enable that symbology, Possible causes are: reader disconnected, out of battery or cable unplugged, or symbology not supported by the current readerDevice
}
}];
The same method can also be used to turn symbologies off:
self.readerDevice.setSymbology(CMBSymbologyUpcEan, enabled: false, completion: {(_ error: Error?) -> Void in
if error != nil {
// Failed to enable that symbology, Possible causes are: reader disconnected, out of battery or cable unplugged, or symbology not supported by the current readerDevice
}
})
[readerDevice setSymbology:CMBSymbologyUpcEan enabled:NO completion:^(NSError *error){
if (error) {
// Failed to enable that symbology, Possible causes are: reader disconnected, out of battery or cable unplugged, or symbology not supported by the current readerDevice
}
}];
If your reader device is equipped with illumination (e.g. LEDs), you can control whether they are ON or OFF when scanning starts using the following method of your CMBReaderDevice object:
self.readerDevice.setLightsON(true) { (error:Error?) in
if error != nil {
// Failed to enable illumination, Possible causes are: reader disconnected, out of battery or cable unplugged, or device doesn't come with illumination lights
}
}
[readerDevice setLightsON:YES completion:^(NSError *error) {
if (error) {
// Failed to enable illumination, Possible causes are: reader disconnected, out of battery or cable unplugged, or device doesn't come with illumination lights
}
}];
Keep in mind that not all devices and device modes supported by the cmbSDK allow illumination control. For example, if using the built-in camera in passive aimer mode, illumination is not available since the LED is being used for aiming.
If built-in camera is used as reader device you have the possibility to configure zoom levels and define the way these zoom levels are used.
There are 3 zoom levels for the phone camera, which are:
You can define these zoom levels with "SET CAMERA.ZOOM-PERCENT [100-MAX] [100-MAX]" command. It configures how far the two levels will zoom in percentage. 100 is without zoom, and MAX (goes up to 1000) will zoom as far as the device is capable of. First argument is used for setting level 1 zoom, and the second for level 2 zoom.
When you want to check current setting, you can do this with the "GET CAMERA.ZOOM-PERCENT" that returns two values: level 1 and level 2 zoom.
Example
readerDevice.dataManSystem()?.sendCommand("SET CAMERA.ZOOM-PERCENT 250 500")
[readerDevice.dataManSystem sendCommand:@"SET CAMERA.ZOOM-PERCENT 250 500"];
here is another command that sets which zoom level you want to use or returns the actual setting: "GET/SET CAMERA.ZOOM 0-2".
Possible values for the SET command are:
You can call this command before scanning or even during scanning, the zoom goes up to the level that was configured.
When the scanning is finished, the values are reset to normal(0).
Example
readerDevice.dataManSystem()?.sendCommand("SET CAMERA.ZOOM 2")
[readerDevice.dataManSystem sendCommand:@"SET CAMERA.ZOOM 2"];
When using the built-in camrea of the mobile device, the cmbSDK allows you to see the Camera Preview inside a preview container or in full screen. This preview also contains an overlay, which can be customized. The cmbSDK camera overlay is built from buttons for zoom, flash, closing the scanner (in full screen), a progress bar indicating the scan timeout, and lines on the corners of the camera preview. There are two available overlays: legacy and CMB overlay.
To use the legacy camera overlay, which was used in the cmbSDK v2.0.x and the ManateeWorks SDK, use this property from MWOverlay before initializing the CMBReaderDevice:
MWOverlay.setOverlayMode(Int32(OM_LEGACY.rawValue))
[MWOverlay setOverlayMode:OM_LEGACY];
If using the CMB overlay, you can find the layout files in the Resources/layout directory:
CMBScannerPartialView.xib used when the scanner is started inside a container (partial view)
CMBScannerView.xib when the scanner is started in full screen
Copy the layout file that you need, or both layouts, then modify them as you like. Change the size, position or color of the views, remove views, and add your own views, like an overlay image. The views that are used by the cmbSDK (zoom, flash, close buttons, the view used for drawing lines on the corners, and the progress bar) are accessed by the sdk using the Tag attribute, make sure the Tag attribute remains unchanged, so that the cmbSDK is able to recognize the views and continue to function correctly.
Both the CMB and the legacy overlay allow you to change the images used on the zoom and flash buttons. To do that, first copy the assets folder MWBScannerImages.xcassets from the Resources dir into your project. In XCode you can look at the images contained in this assets folder, and replace them with your own while keeping the image names unchanged.
Both the CMB and the LEGACY overlay allow you to change the color and width of the rectangle that is displayed when a barcode is detected. Here's an example on how to do that:
MWOverlay.setLocationLineUIColor(UIColor.yellow)
MWOverlay.setLocationLineWidth(5)
[MWOverlay setLocationLineUIColor:UIColor.yellowColor];
[MWOverlay setLocationLineWidth:5];
Every Cognex scanning device implements DataMan Control Commands (DMCC), a method for configuring and controlling the device. Virtually every feature of the device can be controlled using this text based language. The API provides a method for sending DMCC commands to the device. Commands exist both for setting and querying configuration properties.
Appendix A includes the complete DMCC reference for use with the camera reader. DMCC commands for other supported devices (e.g. the MX-1000) are included with the documentation of that particular device.
Appendix B provides the default values for the camera reader’s configuration settings as related to the corresponding DMCC setting.
The following examples show different DMCC commands being sent to the device for more advanced configuration.
Example:
Change the scan direction to omnidirectional:
self.readerDevice.dataManSystem()?.sendCommand("SET DECODER.1D-SYMBOLORIENTATION 0", withCallback: { (response:CDMResponse?) in
if response?.status == DMCC_STATUS_NO_ERROR {
// Command was executed successfully
} else {
// Command failed, handle errors here
}
})
[readerDevice.dataManSystem sendCommand:@"SET DECODER.1D-SYMBOLORIENTATION 0" withCallback:^(CDMResponse *response){
if (response.status == DMCC_STATUS_NO_ERROR) {
// Command was executed successfully
} else {
// Command failed, handle errors here
}
}];
Change the scanning timeout of the live-stream preview to 10 seconds:
self.readerDevice.dataManSystem()?.sendCommand("SET DECODER.MAX-SCAN-TIMEOUT 10", withCallback: { (response:CDMResponse?) in
if response?.status == DMCC_STATUS_NO_ERROR {
// Command was executed successfully
} else {
// Command failed, handle errors here
}
})
[readerDevice.dataManSystem sendCommand:@"SET DECODER.MAX-SCAN-TIMEOUT 10" withCallback:^(CDMResponse *response){
if (response.status == DMCC_STATUS_NO_ERROR) {
// Command was executed successfully
} else {
// Command failed, handle errors here
}
}];
Get the type of the connected device:
self.readerDevice.dataManSystem()?.sendCommand("GET DEVICE.TYPE", withCallback: { (response:CDMResponse?) in
if response?.status == DMCC_STATUS_NO_ERROR {
// Command was executed successfully
let deviceType:String = response?.payload
} else {
// Command failed, handle errors here
}
})
[readerDevice.dataManSystem sendCommand:@"GET DEVICE.TYPE" withCallback:^(CDMResponse *response){
if (response.status == DMCC_STATUS_NO_ERROR) {
// Command was executed successfully
NSString *deviceType = response.payload;
} else {
// Command failed, handle errors here
}
}];
The cmbSDK includes a method for resetting the device to its default settings. In the case of an MX mobile terminal, this is the configuration saved by default, while in the case of the built-in camera, these are the defaults identified in Appendix B, where no symbologies will be enabled. This method is the following:
self.readerDevice.resetConfig { (error:Error?) in
if error != nil {
// Failed to reset configuration, Possible causes are: reader disconnected, out of battery or cable unplugged
}
}
[readerDevice resetConfigWithCompletion:^(NSError *error) {
if (error) {
// Failed to reset configuration, Possible causes are: reader disconnected, out of battery or cable unplugged
}
}];
With a properly configured reader, you are ready to scan barcodes. This is simply accomplished by calling the startScanning() method from your CMBReaderDevice object. What happens next is based on the type of CMBReaderDevice and how it has been configured. Generally:
Scanning stops under one of the following conditions:
When a barcode is decoded successfully, you will receive a CMBReadResults array in your CMBReaderDevice's delegate using the following CMBReaderDeviceDelegate method:
func didReceiveReadResult(fromReader reader: CMBReaderDevice, results readResults: CMBReadResults!)
- (void)didReceiveReadResultFromReader:(CMBReaderDevice *)reader results:(CMBReadResults *)readResults;
To simply display a ReadResult after scanning a barcode:
func didReceiveReadResult(fromReader reader: CMBReaderDevice, results readResults: CMBReadResults!) {
if readResults.readResults.count > 0 {
let readResult:CMBReadResult = readResults.readResults?.first as! CMBReadResult
if readResult.image != nil {
self.ivPreview.image = readResult.image
}
if readResult.readString != nil {
self.lblCode.text = readResult.readString
}
}
}
- (void)didReceiveReadResultFromReader:(CMBReaderDevice *)reader results:(CMBReadResults *)readResults {
if (readResults.readResults.count > 0) {
CMBReadResult *readResult = readResults.readResults.firstObject;
if (readResult.image) {
self.ivPreview.image = readResult.image;
}
if (readResult.readString) {
self.lblCode.text = readResult.readString;
}
}
}
In the example above, ivPreview is an UIImageView used to display an image of the barcode that was scanned, and lblCode is a UILabel used to show the result from the barcode. You can also use the BOOL from readResult.goodRead to check whether the scan was successful or not.
When a barcode is successfully read, a CMBReadResult object is created and returned by the didReceiveReadResultFromReader:results: method. In case of having multiple barcodes successfully read on a single image/frame, multiple CMBReadResult objects are returned. This is why the CMBReadResults class has an array of CMBReadResult objects containing all results.
The CMBReadResult class has properties describing the result of a barcode read:
When a scanning ends with no successful read, a CMBReadResult is returned with the goodRead property set to false. This usually happens when scanning is canceled or timed out.
To enable the image and imageGraphics properties being filled in the CMBReadResult object, you have to set the corresponding imageResultEnabled and/or SVGResultEnabled properties of the CMBReaderDevice object.
To see an example on how the image and SVG graphics are used and displayed in parallel, refer to the sample applications provided in the SDK package.
To access the raw bytes from the scanned barcode, you can use the XML property. The bytes are stored as a Base64 String under the "full_string" tag. Here's an example how you can use the iOS XML parser to extract the raw bytes from the XML property.
Example:
Parsing the XML and extracting the Base64 String is done using the XMLParser
// XMLParserDelegate
var currentElement = ""
var base64String = ""
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
currentElement = elementName
}
func parser(_ parser: XMLParser, foundCharacters string: String) {
if currentElement == "full_string" {
base64String = string
}
}
#pragma NSXMLParserDelegate
NSString *currentElement;
NSString *base64String;
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict {
currentElement = elementName;
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if ([currentElement isEqualToString:@"full_string"]) {
base64String = string;
}
}
After you have set the XMLParserDelegate to extract the base64 string from the XML result, you need to create a XMLParser object and parse the result.xml using this delegate. This can be done when receiving the scan result in the CMBReaderDeviceDelegate, or when accessing a CMBReadResult object. Here's how you can get the raw bytes using the delegate that you created earlier:
let xmlParser:XMLParser = XMLParser.init(data: result.xml)
xmlParser.delegate = self
if xmlParser.parse() {
// Access the raw bytes via this variable
let bytes:Data? = Data.init(base64Encoded: base64String)
}
NSXMLParser *xmlParser = [NSXMLParser.alloc initWithData:result.XML];
xmlParser.delegate = self;
if ([xmlParser parse]) {
// Access the raw bytes via this variable
NSData *bytes = [NSData.alloc initWithBase64EncodedString:base64String options:0];
}
By default, the image and SVG results are disabled, which means that when scanning, the CMBReadResults will not contain any data in the corresponding properties.
To enable image results, set the imageResultEnabled property from the CMBReaderDevice class by using the following method:
self.readerDevice.imageResultEnabled = true
[readerDevice setImageResultEnabled:YES];
To enable SVG results, set the imageResultEnabled property from the CMBReaderDevice class by using the following method:
self.readerDevice.svgResultEnabled = true
[readerDevice setSVGResultEnabled:YES];
There may be cases when a device disconnects due to low battery condition or manual cable disconnection. These cases can be detected by the connectionStateDidChangeOfReader callback of the CMBReaderDeviceDelegate.
After returning to your application from inactive state, the reader device remains initialized but not connected. There is no need for reinitializing the SDK but you need to re-connect.
Some iOS versions will send an "Availability" notification when resuming the application that the external accessory is available. You can use this in the CMBReaderDeviceDelegate method: (void)availabilityDidChangeOfReader:(CMBReaderDevice *)reader so when the reader becomes available, you can connect.
For example:
func availabilityDidChange(ofReader reader: CMBReaderDevice) {
if (reader.availability == CMBReaderAvailibilityAvailable) {
readerDevice.connect(completion: { error in
if error != nil {
// handle connection error
}
})
}
}
- (void)availabilityDidChangeOfReader:(CMBReaderDevice *)reader {
if (readerDevice.availability == CMBReaderAvailibilityAvailable) {
[readerDevice connectWithCompletion:^(NSError *error) {
if (error) {
// handle connection error
}
}];
}
}
Some iOS versions do not report availability change on resume, so you need to handle this manually. Add an observer for UIApplicationDidBecomeActiveNotification and connect.
Example:
override func viewDidLoad() {
super.viewDidLoad()
// Reconnect when app resumes
NotificationCenter.default.addObserver(self, selector: #selector(self.appBecameActive), name:NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
}
// handle app resume
func appBecameActive() {
if readerDevice != nil
&& readerDevice.availability == CMBReaderAvailibilityAvailable
&& readerDevice.connectionState != CMBConnectionStateConnecting && readerDevice.connectionState != CMBConnectionStateConnected {
readerDevice.connect(completion: { error in
if error != nil {
// handle connection error
}
})
}
}
- (void)viewDidLoad {
// Reconnect when app resumes
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appBecameActive)
name:UIApplicationDidBecomeActiveNotification object:nil];
}
// handle app resume
-(void) appBecameActive {
if (readerDevice != nil
&& readerDevice.availability == CMBReaderAvailibilityAvailable
&& readerDevice.connectionState != CMBConnectionStateConnecting && readerDevice.connectionState != CMBConnectionStateConnected) {
[readerDevice connectWithCompletion:^(NSError *error) {
if (error) {
// handle connection error
}
}];
}
}
The following table lists the various DMCC commands supported by the cmbSDK when using the built-in camera for barcode scanning.
GET/SET |
Command |
Parameter(s) |
Description |
Default Value | Device Reset Only? |
MX Terminal |
MX-100 |
---|---|---|---|---|---|---|---|
GET |
BATTERY.CHARGE |
[0-100] |
Displays current battery level in percentage. |
N/A |
x |
||
|
BEEP |
repetition [0-3] level [0-2] |
Plays the audible beep (tone). |
N/A |
x |
||
GET/SET |
BEEP.GOOD |
number of beeps [0-3] beep tone [0-2] |
Sets the number of beeps and the beep tone/pitch: low, medium, high. For the built-in camera, only a single beep with no pitch control is supported. 0 1 turns the beep off, 1 1 turns the beep on. |
1 1 Turn beep on |
x |
||
GET/SET | CAMERA.ZOOM | 0-2 |
Values for the SET command are: 0 - normal (no zoom) 1 - zoom at level 1, 2 - zoom at level 2. The zoom level is used during scanning. When scanning ends zoom level resets to 0. |
N/A | |||
GET/SET | CAMERA.ZOOM-PERCENT |
Level 1 [100-MAX] Level 2 [100-MAX] |
Gets or sets the percentage of camera zoom: level 1: default 200% level 2 :default 400% Note: Make sure to start the camera at least once from the SDK to have a proper value for max capable zoom (MAX).
|
N/A | |||
GET/SET |
CODABAR.CODESIZE |
any min max |
[ON | OFF] Accepts any length Codabar. [1-max] Sets min length of accepted Codabar |
N/A |
|
x | |
GET/SET |
C11.CHKCHAR |
[ON | OFF] |
Turns Code 11 check on/off. |
OFF |
|
||
GET/SET |
C11.CHKCHAR-OPTION |
[0-1] |
0: disable Requires single checksum. |
1 |
|
x | |
GET/SET |
C11.CODESIZE |
any min max |
[ON|OFF] Accepts any length Code 11. [1-max] Sets min length of accepted Code 11. |
N/A |
|
x | |
GET/SET |
C25.CODESIZE |
any min max
|
Code 25 Code Size. For the cmbSDK, all of the Code 25 variants use the same minimum length; thus it will accept either C25.CODESIZE or I205.CODESIZE. [ON|OFF] Accepts any length Code 25. [1-max] Sets min length of accepted Code 25. |
N/A |
|
x | |
GET/SET |
C39.ASCII |
[ON|OFF] |
Turns Code 39 extended ASCII on/off. |
OFF |
x |
||
GET/SET |
C39.CODESIZE |
any min max
|
[ON|OFF] Accepts any length Code 39. [2|4-max] Sets min length of accepted Code 39. (2 is the minimum for using camera API, 4 is used for MX mobile terminals) Setting codesize to 2-3 is risky as it may result misreadings. |
N/A |
x |
||
GET/SET |
C39.CHKCHAR |
[ON|OFF] |
Code 39 Check Character. |
OFF |
x |
||
GET/SET |
C93.ASCII |
[ON|OFF]
|
Turns Code 93 extended ASCII on/off |
OFF |
|
||
GET/SET |
C93.CODESIZE |
any min max |
[ON|OFF] Accepts any length Code 93. [1-max] Sets min length of accepted Code 93. |
N/A |
x |
||
|
CONFIG.DEFAULT |
|
Resets most of the camera API settings to default. Device identification and communications settings are not changed.To reset all settings, use DEVICE.DEFAULT.
|
N/A |
x |
||
CONFIG.SAVE | Saves the current configuration to non-volatile memory (MX-1xxx only). Note that when an MX powers off or enters sleep mode, the last saved configuration is restored when the device wakes up. | N/A | |||||
CONFIG.RESTORE | Restores the saved configuration from non-volatile memory (MX-1xxx only). | N/A | |||||
GET/SET |
DATA.RESULT-TYPE |
0 1 2 4 8 |
Specifies results to be returned (sum of multiple values): None Text string result (default) XML results XML stats Scan image (see IMAGE.* commands) |
1 |
x |
||
GET/SET |
DATABAR.EXPANDED |
[ON|OFF] |
Turns the DataBar Expanded symbology on/off. |
OFF |
x |
||
GET/SET |
DATABAR.LIMITED |
[ON|OFF] |
Turns the DataBar Limited symbology on/off. |
ON |
x |
||
GET/SET |
DATABAR.GROUP DATABAR.RSS14 |
[ON|OFF] |
Turns the DataBar GROUP (before cmbSDK 2.4.2 known as RSS14) symbology on/off. |
OFF |
x |
||
GET/SET |
DATABAR.RSS14STACK |
[ON|OFF] |
Turns the DataBar RSS14 Stacked symbology on/off. It is deprecated from cmbSDK 2.4.2, use DATABAR.GROUP instead. |
OFF |
|
||
GET/SET |
DECODER.1D- SYMBOLORIENTATION |
0 1 2 3 |
Use omnidirectional scan orientation. Use horizontal and vertical scan orientation. Use vertical scan orientation. Use horizontal scan orientation. |
1 |
x |
||
GET/SET | DECODER.CENTERING-WINDOW |
[0-100] [0-100] [0-100] [0-100] |
Location and size of centering window as a percentage of the sensor size. Center horizontally as percentage of centering window Center vertically as percentage of centering window Size horizontally as percentage of centering window Size vertically as percentage of centering window
|
x | x | ||
GET/SET | DECODER.DISPLAY-TARGET | [ON|OFF] | Displays centering window graphics. | OFF | x | x | |
GET/SET |
DECODER.EFFORT |
[0-5] |
Sets the effort level for image analysis/decoding. NOTE: Do not use 4-5 for online scanning.
|
2 |
|
||
GET/SET |
DECODER.MAX-SCAN- TIMEOUT |
[1-120] |
Sets the timeout for the live-stream preview. When the timeout is reached, decoding is paused, and the live-stream preview will remain on-screen. |
60 |
|
||
GET | DECODER.MAX-THREADS | Returns the max number of CPU threads supported by the device. | N/A | ||||
GET/SET | DECODER.REREAD-TIME | [0-10000] | Code re-reading delay in milliseconds. | 1000 | x | x | |
GET/SET | DECODER.ROI-PERCENT |
[0-100] [0-100] [0-100] [0-100] |
Location and size of region of interest as a percentage of the camera view size: Center horizontally as percentage of ROI Size horizontally as percentage of ROI Center vertically as percetage of ROI Size vertically as percentage of ROI |
N/A | x | ||
GET/SET | DECODER.TARGET-DECODING | [ON|OFF] | Enable target decoding, to read codes that has overlap with the target decoding window. | OFF | x | x | |
GET/SET | DECODER.THREADS-USED | [0-MAX] | Specify the max number of CPU threads that the scanner can use during the scanning process. | N/A | |||
GET/SET | DECODER.USE-CENTERING | [ON|OFF] | Only reads codes within the centering window. | OFF | x | x | |
|
DEVICE.DEFAULT |
|
Resets the camera API settings to default. |
x |
|||
GET |
DEVICE.FIRMWARE-VER |
|
Gets the device firmware version. |
N/A |
x |
||
GET |
DEVICE.ID |
string |
Returns device ID assigned by Cognex to the scanning device. For a built-in camera, SDK returns 53. For MX-100 Barcode Scanner, SDK returns 56. |
N/A |
x |
||
GET/SET |
DEVICE.NAME |
|
Returns the name assigned to the device. |
MX-the last 6 digits of DEVICE.SERIAL-NUMBER. |
x |
||
GET |
DEVICE.SERIAL- NUMBER |
|
Returns the serial number of the device. For a built-in camera, the SDK assigns a pseudo-random number. |
N/A |
x |
||
GET |
DEVICE.TYPE |
|
Returns the device name assigned by Cognex to the scanning device. For a built-in camera, SDK returns “MX-Mobile”. If MX-100 is available, SDK returns "MX-100". |
N/A |
x |
||
GET/SET |
FOCUS.FOCUSTIME |
[0-10] |
Sets the camera’s auto-focus period (how often the camera should attempt to refocus). For MX-100 the default is 1. |
3 |
x |
x | |
GET/SET |
I2O5.CHKCHAR |
[ON|OFF] |
Turns Interleaved 2 of 5 check digit on/off. |
OFF |
x |
||
GET/SET |
I2O5.CODESIZE |
any min max
|
For the cmbSDK, all of the Code 25 variants use the same minimum length; thus it will accept either C25.CODESIZE or I205.CODESIZE. [ON|OFF] Accepts any length Interleaved 2 of 5. [1-max] Sets min length of accepted Interleaved 2 of 5.
|
N/A |
|
x | |
GET/SET |
IMAGE.FORMAT |
0 1 2 |
Scanner returns image result in bitmap format. Scanner returns image result in JPEG format. Scanner returns image result in PNG format. |
1 |
x |
||
GET/SET |
IMAGE.QUALITY |
[10, 15, 20, ...90] |
Specifies JPEG image quality. |
50 |
x |
||
GET/SET |
IMAGE.SIZE |
0 1 2 3 |
Scanner returns full size image. Scanner returns 1⁄4 size image. Scanner returns 1/16 size image. Scanner returns 1/64 size image. |
1 |
x |
||
GET/SET |
LIGHT.AIMER |
[0-1] |
Disables/enables the aimer when the scanner starts. Default based on cameraMode: 0: NoAimer and FrontCamera 1: PassiveAimer and ActiveAimer |
ON |
x |
||
SET | LIGHT.AIMER-CONFIG |
[32-100] [0-15] [32-100] |
Sets MX-100's configuration aimer intensity, aimer modulation, illumination intensity |
N/A | x | ||
GET | LIGHT.AIMER-CONFIG | [0-1] |
Get's all of the MX-100 configuration parameters at one time. 0: reads the settings from the cache 1: always reads from the device. |
N/A | x | ||
GET/SET | LIGHT.AIMER-INTENSITY | [32-100] | Sets/gets the aimer LED's intensity as a percentage. | N/A | |||
GET/SET | LIGHT.AIMER-MODULATION | [0-15] | Sets/gets the aimer LED's modulation (blink rate) in milliseconds. | N/A | |||
GET/SET |
LIGHT.AIMER-TIMEOUT |
[0-600] |
Timeout in seconds for an aimer. This value is always overridden by DECODER.MAX-SCAN- TIMEOUT. |
60 |
x |
||
GET/SET |
LIGHT.INTERNAL- ENABLE |
[ON|OFF] |
Enables/disables illumination. |
OFF |
x |
||
GET/SET |
MSI.CHKCHAR |
[ON | OFF] |
Turns MSI Plessey check digit on/off. Default value is OFF. |
N/A |
x |
||
GET/SET |
MSI.CHKCHAR-OPTION |
0 1 2 3 4 5 |
Use mod 10 checksum Use mod 10 mod 10 checksum Use mod 11 checksum (IBM algorithm) Use mod 11 mod 10 checksum (IBM algorithm) Use mod 11 checksum (NCR algorithm) Use mod 11 mod 10 checksum (NCR algorithm) |
N/A |
|
x | |
GET/SET |
MSI.CODESIZE |
mode min max |
[ON|OFF] Accepts any length MSI Plessey. [1-max] Sets min/max length of accepted MSI Plessey. [min-80] Sets min/max length of accepted MSI Plessey.
|
N/A |
|
x | |
GET/SET |
SYMBOL.AZTECCODE |
[ON | OFF] |
Turns the Aztec Code symbology on/off. |
OFF |
x |
||
GET/SET |
SYMBOL.CODABAR |
[ON | OFF] |
Turns the Codabar symbology on/off. |
OFF |
x |
||
GET/SET |
SYMBOL.C11 |
[ON | OFF] |
Turns the Code 11 symbology on/off. |
OFF |
|
||
GET/SET |
SYMBOL.C128 |
[ON | OFF] |
Turns the Code 128 symbology on/off. |
OFF |
x |
||
GET/SET |
SYMBOL.C25 |
[ON | OFF] |
Turns the Code 25 symbology on/off (standard). |
OFF |
x |
||
GET/SET |
SYMBOL.C39 |
[ON | OFF] |
Turns the Code 39 symbology on/off. |
OFF |
x |
||
GET/SET | SYMBOL.C39-CONVERT-TO-C32 | [ON | OFF] | Enables/disables the conversion of Code39 to Code32. | OFF | x | x | |
GET/SET |
SYMBOL.C93 |
[ON | OFF] |
Turns the Code 93 symbology on/off. |
OFF |
x |
||
GET/SET |
SYMBOL.COOP |
[ON | OFF] |
Turns the COOP symbology (Code 25 variant) on/off. |
OFF |
|
||
GET/SET |
SYMBOL.DATAMATRIX |
[ON | OFF] |
Turns the Data Matrix symbology on/off. |
OFF |
x |
||
GET/SET |
SYMBOL.DATABAR |
[ON | OFF] |
Turns the DataBar symbologies on/off. Check also DATABAR.GROUP, DATABAR.LIMITED, DATABAR.EXPANDED to check which subtypes are read if Databar is turned on. |
OFF |
x |
||
GET/SET |
SYMBOL.DOTCODE |
[ON | OFF] |
Turns the DotCode symbology on/off. |
OFF |
x |
||
GET/SET |
SYMBOL.IATA |
[ON | OFF] |
Turns the IATA symbology (Code 25 variant) on/off. |
OFF |
|
||
GET/SET |
SYMBOL.INVERTED |
[ON | OFF] |
Turns the Inverted symbology (Code 25 variant) on/off. |
OFF |
|
||
GET/SET |
SYMBOL.ITF14 |
[ON | OFF] |
Turns the ITF-14 symbology (Code 25 variant) on/off. |
OFF |
|
||
GET/SET |
SYMBOL.UPC-EAN |
[ON | OFF] |
Turns the UPC-A, UPC-E, EAN-8, and EAN-13 symbologies on/off. |
OFF |
x |
||
GET/SET |
SYMBOL.MATRIX |
[ON | OFF] |
Turns the Matrix symbology (Code 25 variant) on/off. |
OFF |
|
||
GET/SET |
SYMBOL.MAXICODE |
[ON | OFF] |
Turns the MaxiCode symbology on/off. |
OFF |
|
||
GET/SET |
SYMBOL.MSI |
[ON | OFF] |
Turns the MSI Plessey symbology on/off. |
OFF |
x |
||
GET/SET |
SYMBOL.PDF417 |
[ON | OFF] |
Turns the PDF417 symbology on/off. |
OFF |
x |
||
GET/SET |
SYMBOL.PLANET |
[ON | OFF] |
Turns the PLANET symbology on/off. |
OFF |
x |
||
GET/SET |
SYMBOL.POSTNET |
[ON | OFF] |
Turns the POSTNET symbology on/off. |
OFF |
x |
||
GET/SET | SYMBOL.TELEPEN | [ON | OFF] | Turns the TELEPEN symbology on/off. | OFF | x | ||
GET/SET | SYMBOL.4STATE-AUS | [ON | OFF] | Turns the Australian Mail symbology on/off. | OFF | x | ||
GET/SET |
SYMBOL.4STATE-IMB |
[ON | OFF] |
Turns the Intelligent Mail Barcode symbology on/off. |
OFF |
x |
||
GET/SET |
SYMBOL.4STATE-RMC |
[ON | OFF] |
Turns the Royal Mail Code symbology on/off. |
OFF |
x |
||
GET/SET |
SYMBOL.QR |
[ON | OFF] |
Turns the QR and MicroQR symbologies on/off. |
OFF |
x |
||
GET/SET |
TRIGGER.TYPE |
0 1 2 3 4 5 |
Not supported Not supported Manual (default) Not supported Not supported Continuous |
N/A |
x |
||
GET/SET |
UPC-EAN.EAN13 |
[ON | OFF] |
Turns the EAN-13 symbology on/off. |
ON |
|
||
GET/SET |
UPC-EAN.EAN8 |
[ON | OFF] |
Turns the EAN-8 symbology on/off. |
ON |
|
||
GET/SET |
UPC-EAN.UPC-A |
[ON | OFF] |
Turns the UPC-A symbology on/off. |
ON |
|
||
GET/SET |
UPC-EAN.UPC-E |
[ON | OFF] |
Turns the UPC-E symbology on/off. |
ON |
|
||
GET/SET |
UPC-EAN.UPCE1 |
[ON | OFF] |
Turns the UPC-E1 symbology on/off. |
OFF |
x |
||
GET/SET |
UPC- EAN.SUPPLEMENT |
0 1-4 |
Turns off UPC supplemental codes. Turns on UPC supplemental codes. |
N/A |
x |
||
GET/SET | VIBRATION.GOOD | [ON | OFF] | Sets/gets whether to vibrate when a code is read (default is ON) | N/A | x |