I’m doing something rather similar, but without the keyboard wedge output (my first version used a network socket to talk to an application on a PC, my current version does all of the processing locally on the Linux side and displays results on a character LCD driven by the sketch.)
It sounds like your first stumbling block is the barcode reader. I use a Symbol LS2104 scanner that has a USB interface and acts as a keyboard wedge. This is plugged into the Host USB port (the large Type A connector) for the Linux side. I found this thread to be very helpful in getting the reader recognized by Linux: Interface barcode scanner with arduino yun
Then, it was a matter of actually reading the barcodes. Using a few different resources, I was able to come up with the this Python script that processes individual low-level HID keyboard reports.
# Note -u parameter above, which makes this script run in ubuffered mode.
# Without it, the serial output to the Process object that called it is
# buffered until a lot of data is queued up, and that is not tolerable here.
# This script expects one argument, the event id number.
# default values
infile_path = "/dev/input/event0"
key = "0"
# Update the values if there is an argument
if len(sys.argv) > 1:
key = sys.argv
infile_path = "/dev/input/event" + key
# Define the structure of the event record:
# l = long int Time value, seconds
# l = long int Time value, microseconds
# H = unsigned short Event type
# H = unsigned short Event code
# I = unsigned int Event value
FORMAT = 'llHHI'
EVENT_SIZE = struct.calcsize(FORMAT)
# a lookup table to translate a key code to an ASCII character.
# Values that are a blank string are essentially ignored.
KeyLookup = [
'', # 0 KEY_RESERVED
'', # 1 KEY_ESC
'1', # 2 KEY_1
'2', # 3 KEY_2
'3', # 4 KEY_3
'4', # 5 KEY_4
'5', # 6 KEY_5
'6', # 7 KEY_6
'7', # 8 KEY_7
'8', # 9 KEY_8
'9', # 10 KEY_9
'0', # 11 KEY_0
'', # 12 KEY_MINUS
'', # 13 KEY_EQUAL
'', # 14 KEY_BACKSPACE
'', # 15 KEY_TAB
'Q', # 16 KEY_Q
'W', # 17 KEY_W
'E', # 18 KEY_E
'R', # 19 KEY_R
'T', # 20 KEY_T
'Y', # 21 KEY_Y
'U', # 22 KEY_U
'I', # 23 KEY_I
'O', # 24 KEY_O
'P', # 25 KEY_P
'[', # 26 KEY_LEFTBRACE
']', # 27 KEY_RIGHTBRACE
'', # 28 KEY_ENTER
'', # 29 KEY_LEFTCTRL
'A', # 30 KEY_A
'S', # 31 KEY_S
'D', # 32 KEY_D
'F', # 33 KEY_F
'G', # 34 KEY_G
'H', # 35 KEY_H
'J', # 36 KEY_J
'K', # 37 KEY_K
'L', # 38 KEY_L
'', # 39 KEY_SEMICOLON
'', # 40 KEY_APOSTROPHE
'', # 41 KEY_GRAVE
'', # 42 KEY_LEFTSHIFT
'\\', # 43 KEY_BACKSLASH
'Z', # 44 KEY_Z
'X', # 45 KEY_X
'C', # 46 KEY_C
'V', # 47 KEY_V
'B', # 48 KEY_B
'N', # 49 KEY_N
'M', # 50 KEY_M
'', # 51 KEY_COMMA
'.', # 52 KEY_DOT
'/' ] # 53 KEY_SLASH
TERMINATOR = 51 # key code for end of barcode (KEY_COMMA)
barcode = ""
#open event input device file in binary mode
in_file = open(infile_path, "rb")
# read the first event
event = in_file.read(EVENT_SIZE)
# keep looping as long as there are events read
# decode the event using the defined structure format
(tv_sec, tv_usec, type, code, value) = struct.unpack(FORMAT, event)
if type == 1 and value == 1: # Check whether this is a simulated key press.
if code == TERMINATOR: # Is this the barcode terminator character?
print barcode # Got the end of the barcode. Print it so it's received by the sketch.
barcode = "" # Clear out the buffer, ready for the next code.
if code < len(KeyLookup): # Not the end. If the code is in range of the lookup tabke, add the chracter to the buffer.
barcode = barcode + KeyLookup[code]
event = in_file.read(EVENT_SIZE) # Wait for another event
in_file.close() # No event read, close file and exit.
I’m using very simple Code39 barcodes, that just use digits, upper case letters, and a few special symbols, so the Python script is only set up for those few characters. Of course, it could be expanded to handle more. To make parsing easier, I set up the scanner to add a prefix and suffix to every code that it reports, using characters that are not part of the regular barcode alphabet - in my case, I chose ‘[’ as the prefix, and ‘]’ as the suffix.
If you just run the Python code from the command line, it will echo any barcodes scanned to the terminal. The way I use it in my system is that my sketch uses a Process object to run the Python script asynchronously. Then in loop(), it calls Process.available() to see if the script has returned any data, and if so, it reads the data from the process into a character array. If it sees a ‘[’ character, it resets the character array index to zero, so that it starts looking for a new code. When it sees a ‘]’ character, it knows it has a complete code and processes it as needed.
An instance of a Process object named EventProcess is declared globally, and this code in setup() starts the process:
This is called from within loop(), where Barcode is a globally defined character array, and Index is a globally defined byte variable:
// Read the character
char ch = EventProcess.read();
// Is this the beginning of a barcode?
if (ch == '[')
Index = 0; // Reset the buffer
// Store the character in the buffer
Barcode[Index] = ch;
// Bump the index
// Don't overflow the buffer, and make sure there is room for the NULL terminator.
if (Index >= sizeof(Barcode))
Index = sizeof(Barcode) - 1;
// Is this the end of a barcode?
if (ch == ']')
// Null terminate the barcode string
Barcode[Index+1] = '\0';
// Process the barcode string as needed here.
// Reset the buffer
Index = 0;
Is this anything like what you are looking to do?