Change scanner settings from the Serial Monitor
What this example shows
A menu in the Serial Monitor drives the scanner while it runs: start and stop a scan, switch the white illumination and the red aiming light on and off, pick how much of the camera frame is searched for a code, choose manual, continuous or motion-sense reading, and switch the 1D and 2D symbology groups on and off. Codes you scan while a menu waits still print.
The example uses pin 4 as the controller's RX (wire it to the scanner's TX)
and pin 5 as its TX (wire it to the scanner's RX); change the two numbers to
match your wiring. Use a 3.3 V controller, and switch the scanner to UART first
by scanning the POR232 configuration barcode.
This example also uses SoftwareSerial, which is not part of the Soldered DE2120 library. The example's comment says you can find it in the Arduino Library Manager.
The example code
/**
**************************************************
*
* @file SerialSettings.ino
* @brief Interactive configuration and scanning demo for the DE2120
* 1D/2D barcode scanner module over SoftwareSerial.
*
* Presents a Serial Monitor menu to control scanner settings
* at runtime: start/stop scanning, toggle the illumination
* flashlight and aiming reticle, adjust the reading area,
* switch reading modes (manual, continuous, motion), and
* enable or disable 1D/2D symbology groups.
*
* While the menu is displayed the sketch continuously polls
* for barcodes, printing any result to Serial Monitor before
* waiting for the next menu selection.
*
* The scanner must first be put into TTL/RS232 mode by
* scanning the POR232 barcode from the DYScan settings
* manual. Change the SoftwareSerial pin arguments to match
* your wiring before uploading.
*
* Make sure you have SoftwareSerial library installed. It
* can be found in Arduino library manager.
*
* @authors Fran Fodor @ soldered.com
***************************************************/
#include "SoftwareSerial.h"
SoftwareSerial softSerial(4, 5); // change according to your wiring
#include "DE2120-SOLDERED.h"
DE2120_Soldered scanner;
#define BUFFER_LEN 40
char scanBuffer[BUFFER_LEN];
void setup()
{
Serial.begin(115200);
Serial.println("DE2120 Scanner Example");
if (scanner.begin(softSerial) == false)
{
Serial.println("Scanner did not respond. Please check wiring. Did you scan the POR232 barcode? Freezing...");
while (1)
;
}
Serial.println("Scanner online!");
}
void loop()
{
flushRx(); // Clear the serial rx buffer to avoid line endings
Serial.println();
Serial.println("SparkFun DE2120 Barcode Scanner Library");
Serial.println("-------------------------------------");
Serial.println("1) Start Scan");
Serial.println("2) Stop Scan");
Serial.println("3) Enable/Disable Flashlight");
Serial.println("4) Enable/Disable Aiming Reticle");
Serial.println("5) Set Reading Area");
Serial.println("6) Set Reading Mode");
Serial.println("7) Enable Disable Symbologies");
Serial.println("-------------------------------------");
Serial.println("Select an option number: ");
// Wait for the user to reply but look for barcodes in the meantime
while (Serial.available() == false)
{
if (scanner.readBarcode(scanBuffer, BUFFER_LEN))
{
Serial.println("...");
Serial.print("Code found: ");
for (int i = 0; i < strlen(scanBuffer); i++)
Serial.print(scanBuffer[i]);
Serial.println();
}
delay(200);
}
switch (Serial.read())
{
case '1':
scanner.startScan();
break;
case '2':
scanner.stopScan();
break;
case '3':
flashlight();
break;
case '4':
reticle();
break;
case '5':
readingArea();
break;
case '6':
readingMode();
break;
case '7':
symbologies();
break;
default:
Serial.println("Command not recognized");
break;
}
}
void flashlight()
{
flushRx(); // Clear the serial rx buffer to avoid line endings
Serial.println();
Serial.println("-------------------------------------");
Serial.println("1) Enable Flashlight");
Serial.println("2) Disable Flashlight");
Serial.println("-------------------------------------");
Serial.println("Select an option number:");
while (Serial.available() == false)
{
//Wait for user to send char
}
switch (Serial.read())
{
case '1':
Serial.println("White scan light on");
scanner.lightOn();
break;
case '2':
Serial.println("White scan light off");
scanner.lightOff();
break;
default:
Serial.println("Command not recognized");
break;
}
}
void reticle()
{
flushRx(); // Clear the serial rx buffer to avoid line endings
Serial.println();
Serial.println("-------------------------------------");
Serial.println("1) Enable Reticle");
Serial.println("2) Disable Reticle");
Serial.println("-------------------------------------");
Serial.println("Select an option number:");
while (Serial.available() == false)
{
//Wait for user to send char
}
switch (Serial.read())
{
case '1':
Serial.println("Red scan reticle on");
scanner.reticleOn();
break;
case '2':
Serial.println("Red scan reticle off");
scanner.reticleOff();
break;
default:
Serial.println("Command not recognized");
break;
}
}
void readingArea()
{
flushRx(); // Clear the serial rx buffer to avoid line endings
Serial.println("...");
Serial.println("...");
Serial.println("...");
Serial.println("-------------------------------------");
Serial.println("1) Full Width (Default)");
Serial.println("2) Center 80%");
Serial.println("3) Center 60%");
Serial.println("4) Center 40%");
Serial.println("5) Center 20%");
Serial.println("-------------------------------------");
Serial.println("Select an option number:");
while (Serial.available() == false)
{
//Wait for user to send char
}
switch(Serial.read()){
case '1':
Serial.println("Scanning 100% of frame");
scanner.changeReadingArea(100);
return;
case '2':
Serial.println("Scanning center 80% of frame");
scanner.changeReadingArea(80);
return;
case '3':
Serial.println("Scanning center 60% of frame");
scanner.changeReadingArea(60);
return;
case '4':
Serial.println("Scanning center 40% of frame");
scanner.changeReadingArea(40);
return;
case '5':
Serial.println("Scanning center 20% of frame");
scanner.changeReadingArea(20);
return;
default:
Serial.println("Command not recognized");
return;
}
}
void readingMode()
{
flushRx(); // Clear the serial rx buffer to avoid line endings
Serial.println("...");
Serial.println("...");
Serial.println("...");
Serial.println("-------------------------------------");
Serial.println("1) Manual Read Mode (Default)");
Serial.println("2) Continuous Read Mode");
Serial.println("3) Motion Sensor Mode");
Serial.println("-------------------------------------");
Serial.println("Select an option number:");
while (Serial.available() == false)
{
//Wait for user to send char
}
switch(Serial.read()){
case '1':
Serial.println("Manual Trigger Mode enabled");
scanner.disableMotionSense();
return;
case '2':
Serial.println("Continuous Read Mode enabled");
scanner.enableContinuousRead();
return;
case '3':
Serial.println("Motion Trigger Mode enabled");
scanner.enableMotionSense();
return;
default:
Serial.println("Command not recognized");
return;
}
}
void symbologies()
{
flushRx(); // Clear the serial rx buffer to avoid line endings
Serial.println("...");
Serial.println("...");
Serial.println("...");
Serial.println("-------------------------------------");
Serial.println("1) Enable All 1D Symbologies");
Serial.println("2) Disable All 1D Symbologies");
Serial.println("3) Enable All 2D Symbologies");
Serial.println("4) Disable All 2D Symbologies");
Serial.println("-------------------------------------");
Serial.println("Select an option number:");
while (Serial.available() == false)
{
//Wait for user to send char
}
switch(Serial.read()){
case '1':
Serial.println("1D Symbologies enabled");
scanner.enableAll1D();
return;
case '2':
Serial.println("1D Symbologies disabled");
scanner.disableAll1D();
return;
case '3':
Serial.println("2D Symbologies enabled");
scanner.enableAll2D();
return;
case '4':
Serial.println("2D Symbologies disabled");
scanner.disableAll2D();
return;
default:
Serial.println("Command not recognized");
return;
}
}
void flushRx(){
while(Serial.available()){
Serial.read();
delay(1);
}
}
Expected result:
DE2120 Scanner Example
Scanner online!
SparkFun DE2120 Barcode Scanner Library
-------------------------------------
1) Start Scan
2) Stop Scan
3) Enable/Disable Flashlight
4) Enable/Disable Aiming Reticle
5) Set Reading Area
6) Set Reading Mode
7) Enable Disable Symbologies
-------------------------------------
Select an option number:
Send a number to pick an option. Options 3 to 7 open a second menu and print a
confirmation such as White scan light on, Scanning center 60% of frame or
Continuous Read Mode enabled once you choose; options 1 and 2 act at once
without a message. The main menu then appears again. A code scanned while the
main menu waits prints as ... followed by Code found: and the code's
contents.
Option 6, then 3 (Motion Sensor Mode) sends a POR command. It calls
enableMotionSense() with its default 50, which sends POR50, a command in
the scanner's communication-mode family. What POR50 does on the scanner is
not documented, and the library warns that a USB mode makes the scanner stop
answering on TTL. See the warning under enableMotionSense() below.
Functions used
SoftwareSerial(rxPin, txPin, inverse_logic)returns NoneConstructor from the SoftwareSerial library. Creates a serial port on two digital pins, run in software. Only one SoftwareSerial port can receive at a time.
ReturnsConstructor; no return value.
Parameters
| Type | Name | Description |
|---|---|---|
| pin number | rxPin | The pin that receives, wired to the scanner's TX. The example uses 4. |
| pin number | txPin | The pin that transmits, wired to the scanner's RX. The example uses 5. |
bool | inverse_logic | Inverts the signal sense. Optional, false by default; the example leaves it out. |
DE2120_Soldered()returns NoneCreates the scanner object. It holds no pins or port yet: begin() connects it to a serial port.
ReturnsConstructor; no return value.
scanner.begin(SoftwareSerial &serialPort)returns boolConnects the scanner object to a SoftwareSerial port and checks that the scanner answers. It starts the port at 9600 baud and asks for the firmware version. Without an answer it retries at 115200 baud, tells the scanner to switch to 9600 baud, and asks again. On success it empties the receive buffer so the first scan is read cleanly.
Returnstrue when the scanner answered, false when it did not.
Parameters
| Type | Name | Description |
|---|---|---|
SoftwareSerial & | serialPort | The port the scanner is wired to, here softSerial. |
scanner.readBarcode(char *resultBuffer, uint8_t size)returns boolReads the bytes waiting from the scanner into resultBuffer. A scan ends with a carriage return; once one arrives, the function returns true and the buffer holds the code, the carriage return and a terminating zero. A buffer that already holds a finished scan is cleared before the next one.
Returnstrue when a complete scan is in the buffer, false when no complete scan has arrived yet.
Parameters
| Type | Name | Description |
|---|---|---|
char * | resultBuffer | Buffer that collects the code. The example uses 40 bytes. |
uint8_t | size | Size of the buffer. At most this many bytes are read, so a longer code is cut short. |
scanner.startScan()returns boolSends the SCAN command, which starts a scan. Meant for manual (trigger) mode, the default.
Returnstrue when the scanner acknowledged the command.
scanner.stopScan()returns boolSends the SLEEP command, which stops a scan in progress.
Returnstrue when the scanner acknowledged the command.
scanner.lightOn()returns boolSwitches the white illumination LEDs on (LAMENA1). They are on by default.
Returnstrue when the scanner acknowledged the command.
scanner.lightOff()returns boolSwitches the white illumination LEDs off (LAMENA0).
Returnstrue when the scanner acknowledged the command.
scanner.reticleOn()returns boolSwitches the red aiming light on (AIMENA1). It is on by default.
Returnstrue when the scanner acknowledged the command.
scanner.reticleOff()returns boolSwitches the red aiming light off (AIMENA0).
Returnstrue when the scanner acknowledged the command.
scanner.changeReadingArea(uint8_t percent)returns boolSets how much of the camera frame, measured from its centre, the scanner searches for a code (IMGREG0 to IMGREG4). The full frame is the default.
Returnstrue when the scanner acknowledged the command; false for a value the function does not accept.
Parameters
| Type | Name | Description |
|---|---|---|
uint8_t | percent | 100 (full width), 80, 60, 40 or 20. |
scanner.disableMotionSense()returns boolPuts the scanner in manual (trigger) mode, the default (SCMMAN). The example uses it for its Manual Read Mode option.
Returnstrue when the scanner acknowledged the command.
scanner.enableContinuousRead(uint8_t repeatInterval = 2)returns boolPuts the scanner in continuous mode (SCMCNT), where it reads without a trigger, and sets how often the same code is sent again (CNTALW).
Returnstrue when the scanner acknowledged the interval setting; false for an interval of 4 or more.
Parameters
| Type | Name | Description |
|---|---|---|
uint8_t | repeatInterval | For the same code: 0 output once, 1 repeat with no interval, 2 every 0.5 s, 3 every 1 s. The example leaves it at 2. |
scanner.enableMotionSense(uint8_t sensitivity = 50)returns boolPuts the scanner in motion-sense mode (SCMMDH), then sends the sensitivity. In this library version the sensitivity goes out after the POR prefix instead of MDTTHR, the scanner's motion-sensitivity setting, so the return value reflects that second command rather than a sensitivity change.
ReturnsThe scanner's answer to the sensitivity command; false for a value the function does not accept.
Parameters
| Type | Name | Description |
|---|---|---|
uint8_t | sensitivity | 15 (highest), 20, 30, 50 or 100 (lowest). The example leaves it at 50. |
The sensitivity has no effect in this library version. The function sends
the value behind POR, the prefix of the scanner's communication-mode
commands (POR232 is TTL/RS232 mode, PORKBD, PORHID and PORVIC are USB
modes), not behind MDTTHR, so passing 15 or 100 does not change the
motion sensitivity. What the resulting POR15, POR20, POR30, POR50 or
POR100 command does on the scanner is not documented: none of them is among
the communication modes the library lists. The library itself warns that a
USB mode makes the scanner stop answering on TTL. To set the sensitivity, send it yourself with
scanner.sendCommand("MDTTHR", "15") (or 20, 30, 50, 100).
scanner.enableAll1D()returns boolSwitches on decoding of all 1D symbologies (ODCENA).
Returnstrue when the scanner acknowledged the command.
scanner.disableAll1D()returns boolSwitches off decoding of all 1D symbologies (ODCDIS).
Returnstrue when the scanner acknowledged the command.
scanner.enableAll2D()returns boolSwitches on decoding of all 2D symbologies (AQRENA).
Returnstrue when the scanner acknowledged the command.
scanner.disableAll2D()returns boolSwitches off decoding of all 2D symbologies (AQRDIS).
Returnstrue when the scanner acknowledged the command.
Putting it together
Each menu entry maps to one function, and each function sends one or two of the scanner's configuration commands and waits for its acknowledgement. The sketch ignores the return values; in your own code, check them to see whether the scanner accepted a setting.
In continuous mode the scanner reads without the trigger, and repeatInterval
sets how often it sends the same code again. To read on demand instead, stay in
manual mode and call startScan() from your code, or pull TRIG low.