NEW Barcode Input Capture (USB and RS232 compatible)

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
labrint
Posts: 383
Joined: 14 Jun 2017, 05:06
Location: Malta

NEW Barcode Input Capture (USB and RS232 compatible)

24 Aug 2017, 03:37

Hi guys, I need to develop a system which can identify and capture barcode from whichever source they come based on the speed of input. I have two working prototypes but they are both inefficient and so I left that code at the end if you want to have a look at it.

The code is certainly doable, but I don't think it's ever been done before. It must work on the following principle;

a) activates at the moment the first key is pressed or input received
b) starts a timer at the moment of activation
c) check the speed at which inputs are received (inputs/time)
d) it recognizes the barcode by determining the speed of the input
e) it stores the barcode in a variable/text file
f) the system must run in the background and allow normal barcode input into applications
g) the system must have an option, not store strings which contain certain chars

Below is the code I was dabbling with, which does not measure time and speed of input but only the length of the string obtained before a timeout. It is inefficient.

The first code uses a timer;

Code: Select all

#SingleInstance force
#Persistent
SetTimer, BarcodeCaptureTimer, 250
return

BarcodeCaptureTimer:
BarcodeCapture :=
Input, BarcodeCapture, I V T0.5
StringLen, BarcodeLength, BarcodeCapture
If BarcodeLength > 5
{
FileAppend, %BarcodeCapture%, %A_Desktop%\BarcodeCapture.txt
}
If BarcodeLength < 5
{}
Return
The second code uses a Loop;

Code: Select all

#SingleInstance force
Loop
{
GoSub, BarcodeCaptureTimer
}


BarcodeCaptureTimer:
BarcodeCapture :=
Input, BarcodeCapture, I V T2
StringLen, BarcodeLength, BarcodeCapture
If BarcodeLength > 5
{
FileAppend, %BarcodeCapture%, %A_Desktop%\BarcodeCapture.txt
}
If BarcodeLength < 5
{}
Return
User avatar
labrint
Posts: 383
Joined: 14 Jun 2017, 05:06
Location: Malta

Re: NEW Barcode Input Capture (USB and RS232 compatible)

24 Aug 2017, 04:00

Possible tips on ways to achieve this;

1: Calculate the time it takes for a Key Down (Char) to become a Key Up (Char)
2: Calculate the time between successive Key Downs OR Key Ups
3: Halt capture if a timeout between successive Key Downs OR Key Ups is reached
User avatar
labrint
Posts: 383
Joined: 14 Jun 2017, 05:06
Location: Malta

Re: NEW Barcode Input Capture (USB and RS232 compatible)

24 Aug 2017, 11:26

Still in progress. The following code builds on my previous ideas.

Code: Select all

#SingleInstance force

a := 1 ; a is the number attributed to x (the input variable)
b := 1 ; b is the number attributed to y (the time variable)

Loop,

{
Input, x%a%, L1 V, {ENTER}
y%b% := A_TickCount ; stores the time of input

a += 1 ; moves to create the next dynamic var to store the next char input
c := b ; creates a duplicate dynamic variable to store the 'current' time/input
b += 1 ; moves to create the next dynamic var to store the next time

Input, x%a%, L1 V, {ENTER}
y%b% := A_TickCount ; stores the time of input

if (y%b% - y%c% < 90) {
	Word .= x%c% . x%a%
 }
}

Until (y%b% - y%c% > 1000) 
FileAppend, %Word%, %A_Desktop%\BarcodeCapture.txt
Return
User avatar
labrint
Posts: 383
Joined: 14 Jun 2017, 05:06
Location: Malta

Re: NEW Barcode Input Capture (USB and RS232 compatible)

25 Aug 2017, 06:37

I found this code which is amazing, but it does not capture text. Can anyone explain it to me? It is very similar to my method using the millisecond timer.

Code: Select all

Loop 10
   Hotkey, % "$~" A_Index-1, BarCodeHandler, on
   
BarCodeHandler:
Accu .= SubStr(A_ThisHotkey, 0)
If Strlen(Accu) > 4 && A_TimeSincePriorHotkey < 60
   SetTimer, TheBigShebang, -60
If (A_TimeSincePriorHotkey > 100)
   Accu := SubStr(A_ThisHotkey, 0)
return
TheBigShebang:
If Accu
   msgbox You scanned barcode %Accu%
return
User avatar
evilC
Posts: 4824
Joined: 27 Feb 2014, 12:30

Re: NEW Barcode Input Capture (USB and RS232 compatible)

25 Aug 2017, 07:58

Code: Select all

Loop 10
   Hotkey, % "$~" A_Index-1, BarCodeHandler, on
This code declares hotkeys to number 0-9
That is why it does not capture letters.

Add this code to also bind hotkeys to letters

Code: Select all

start := Ord("a") - 1
Loop 26
    Hotkey, % "$~" Chr(A_Index + start), BarCodeHandler, on
User avatar
labrint
Posts: 383
Joined: 14 Jun 2017, 05:06
Location: Malta

Re: NEW Barcode Input Capture (USB and RS232 compatible)

25 Aug 2017, 09:13

I replaced the above with your code but it did not work at all evilC, no MsgBox came up with the barcode. I suspect you are on the right track because that is what I also think should be modified but had no clue how to. Thanks for your contribution. I hope someone solves it.
User avatar
labrint
Posts: 383
Joined: 14 Jun 2017, 05:06
Location: Malta

Re: NEW Barcode Input Capture (USB and RS232 compatible)

25 Aug 2017, 10:05

I removed the first snippet in your reply and replaced it with the second snippet.

Code: Select all

start := Ord("a") - 1
Loop 26
    Hotkey, % "$~" Chr(A_Index + start), BarCodeHandler, on
	
BarCodeHandler:
Accu .= SubStr(A_ThisHotkey, 0)
If Strlen(Accu) > 4 && A_TimeSincePriorHotkey < 60
   SetTimer, TheBigShebang, -60
If (A_TimeSincePriorHotkey > 100)
   Accu := SubStr(A_ThisHotkey, 0)
return
TheBigShebang:
If Accu
   msgbox You scanned barcode %Accu%
return
User avatar
evilC
Posts: 4824
Joined: 27 Feb 2014, 12:30

Re: NEW Barcode Input Capture (USB and RS232 compatible)

25 Aug 2017, 10:20

That would stop numbers from working.

Try this:

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance force

Loop 10 {
    char := A_Index - 1
    fn := Func("BarCodeHandler").Bind(char)
    Hotkey, % "$~" char, % fn, on
}
start := Ord("a") - 1
Loop 26 {
    char := Chr(A_Index + start)
    fn := Func("BarCodeHandler").Bind(char)
    Hotkey, % "$~" char, % fn, on
}
return

BarCodeHandler(key){
    global Accu
    Accu .= key
    if (StrLen(Accu) > 4 && A_TimeSincePriorHotkey < 60){
        SetTimer, TheBigShebang, -60
    } else if (A_TimeSincePriorHotkey >= 60){
        Accu := key
    }
}

TheBigShebang:
If Accu
   msgbox You scanned barcode %Accu%
return
User avatar
labrint
Posts: 383
Joined: 14 Jun 2017, 05:06
Location: Malta

Re: NEW Barcode Input Capture (USB and RS232 compatible)

25 Aug 2017, 10:38

Still not getting the text in the QR code, only numbers.
User avatar
evilC
Posts: 4824
Joined: 27 Feb 2014, 12:30

Re: NEW Barcode Input Capture (USB and RS232 compatible)

25 Aug 2017, 10:41

Hmm, are the letters it is scanning upper case? My code only dealt with lower case

Try this

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance force

Loop 10 {
    char := A_Index - 1
    fn := Func("BarCodeHandler").Bind(char)
    Hotkey, % "$~" char, % fn, on
}
start := Ord("a") - 1
Loop 26 {
    char := Chr(A_Index + start)
    fn := Func("BarCodeHandler").Bind(char)
    Hotkey, % "*$~" char, % fn, on
}
return

BarCodeHandler(key){
    global Accu
    Accu .= key
    if (StrLen(Accu) > 4 && A_TimeSincePriorHotkey < 6000){
        SetTimer, TheBigShebang, -60
    } else if (A_TimeSincePriorHotkey >= 6000){
        Accu := key
    }
}

TheBigShebang:
If Accu
   msgbox You scanned barcode %Accu%E
return
User avatar
labrint
Posts: 383
Joined: 14 Jun 2017, 05:06
Location: Malta

Re: NEW Barcode Input Capture (USB and RS232 compatible)

25 Aug 2017, 10:54

Still does not capture barcode, even more so it is capturing keyboard text now. My barcode looks something like this "JOHN FRENDO 111222M" without the inverted commas.
User avatar
labrint
Posts: 383
Joined: 14 Jun 2017, 05:06
Location: Malta

Re: NEW Barcode Input Capture (USB and RS232 compatible)

28 Aug 2017, 09:13

Can anyone help me bind text (upper and lower case) as well as numbers for this barcode capture?
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: NEW Barcode Input Capture (USB and RS232 compatible)

12 Sep 2017, 11:55

I have two variations of the approaches above, the Input approach, and the hotkey approach:

Code: Select all

q::
vOutput := ""
VarSetCapacity(vOutput, 1000000*2)
Loop
{
	Input, vInput, V I L1
	if (A_TickCount-vTickCount > 500)
		vOutput .= "[GAP]`r`n"
	vOutput .= vInput
	vTickCount := A_TickCount
	ToolTip, % vOutput
}
return

Code: Select all

vOutput := ""
VarSetCapacity(vOutput, 1000000*2)
;#If 0 ;to temporarily comment out hotkeys
q::
w::
e::
r::
t::
y::
#If
if (A_TickCount-vTickCount > 500)
	vOutput .= "[GAP]`r`n"
vOutput .= SubStr(A_ThisHotkey, StrLen(A_ThisHotkey))
vTickCount := A_TickCount
ToolTip, % vOutput
return
This may or may not work to solve your uppercase/lowercase problem:

Code: Select all

1::
a::
+a::
MsgBox, % A_ThisHotkey
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
labrint
Posts: 383
Joined: 14 Jun 2017, 05:06
Location: Malta

Re: NEW Barcode Input Capture (USB and RS232 compatible)

13 Sep 2017, 02:37

jeeswg wrote:I have two variations of the approaches above, the Input approach, and the hotkey approach:

Code: Select all

q::
vOutput := ""
VarSetCapacity(vOutput, 1000000*2)
Loop
{
	Input, vInput, V I L1
	if (A_TickCount-vTickCount > 500)
		vOutput .= "[GAP]`r`n"
	vOutput .= vInput
	vTickCount := A_TickCount
	ToolTip, % vOutput
}
return
This method does not distinguish between USB barcode and keyboard and moreover, skips a lot of characters.
jeeswg wrote:

Code: Select all

vOutput := ""
VarSetCapacity(vOutput, 1000000*2)
;#If 0 ;to temporarily comment out hotkeys
q::
w::
e::
r::
t::
y::
#If
if (A_TickCount-vTickCount > 500)
	vOutput .= "[GAP]`r`n"
vOutput .= SubStr(A_ThisHotkey, StrLen(A_ThisHotkey))
vTickCount := A_TickCount
ToolTip, % vOutput
return
This method also skips a lot of characters.
jeeswg wrote:This may or may not work to solve your uppercase/lowercase problem:

Code: Select all

1::
a::
+a::
MsgBox, % A_ThisHotkey
return
I'm not sure how to use this code.

So far the best solution is that of evilC. I have done some preliminary tests on that code to find out where it fails and where it succeeds. First of all this is the code;
evilC wrote:

Code: Select all

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
#SingleInstance force

Loop 10 {
    char := A_Index - 1
    fn := Func("BarCodeHandler").Bind(char)
    Hotkey, % "$~" char, % fn, on
}
start := Ord("a") - 1
Loop 26 {
    char := Chr(A_Index + start)
    fn := Func("BarCodeHandler").Bind(char)
    Hotkey, % "$~" char, % fn, on
}
return

BarCodeHandler(key){
    global Accu
    Accu .= key
    if (StrLen(Accu) > 4 && A_TimeSincePriorHotkey < 60){
        SetTimer, TheBigShebang, -60
    } else if (A_TimeSincePriorHotkey >= 60){
        Accu := key
    }
}

TheBigShebang:
If Accu
   msgbox You scanned barcode %Accu%
return
I have tested it against these QR Codes;

testing 1234 Result: testing1234
1234 testing Result: 1234testing
TESTING 1234 Failed
1234 TESTING Failed
TESTING Failed
1234 Failed
testing Result: testing
testing testing 1234testing Result: testingtesting1234testing

Spaces were also ignored which is a problem. It is also important to capture these types of characters; ¬!"£$%^&*()_+@~{}<>?[];',./#\|
evilC managed to add something valuable to the previous shebang code, but his subsequent additions to bind upper case failed. This is the closest we are to solving this problem. This type of capture is not missing characters which is fantastic. I did have one random error though. One time it simply recorded "tetsing" instead of "testing".
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: NEW Barcode Input Capture (USB and RS232 compatible)

13 Sep 2017, 03:06

Do you have a method that distinguishes between USB barcode and keyboard? Which bit of code does that?
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
labrint
Posts: 383
Joined: 14 Jun 2017, 05:06
Location: Malta

Re: NEW Barcode Input Capture (USB and RS232 compatible)

13 Sep 2017, 03:30

Jeeswg please refer to the evilC code in the last message more specifically to;

Code: Select all

     global Accu
    Accu .= key
    if (StrLen(Accu) > 4 && A_TimeSincePriorHotkey < 60){
        SetTimer, TheBigShebang, -60
    } else if (A_TimeSincePriorHotkey >= 60){
        Accu := key
    }
The code is distinguishing the barcode from the keyboard using the difference in time (milliseconds) from one hotkey to another (more specifically less than 60 milliseconds). The keyboard cannot achieve this rate of data input and would require roughly more than 100 milliseconds between hotkeys.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: NEW Barcode Input Capture (USB and RS232 compatible)

13 Sep 2017, 03:38

This is the code I have so far. It doesn't account for the difference in delay.

Code: Select all

oArray := {",":"<"}
;` 1234567890 -= [] ;'# \ ,./
;¬ !"£$%^&*() _+ {} :@~ | <>?
vList := "``¬,1!,2"",3£,4$,5%,6^,7&,8*,9(,0),-_,=+,{[,}],;:,'@,#~,\|,.>,/?"
Loop, Parse, vList, % ","
	oArray["" SubStr(A_LoopField,1,1)] := SubStr(A_LoopField,2)
vOutput := ""
VarSetCapacity(vOutput, 1000000*2)

vList2 := "``1234567890-=[];'#\,./"
Loop, Parse, vList2
	Hotkey, % "*$~" A_LoopField, GetKeys, On
Loop, 26
	Hotkey, % "*$~" Chr(96+A_Index), GetKeys, On
return

GetKeys:
*$~Space::
vKey := SubStr(A_ThisHotkey, StrLen(A_ThisHotkey))
if GetKeyState("Shift", "P")
	if vKey is alpha
		vKey := Format("{:U}", vKey)
	else
		vKey := oArray["" vKey]
if (A_ThisHotkey ~= "Space$")
	vKey := " "
if (A_TickCount-vTickCount > 500)
	vOutput .= "[GAP]`r`n"
vOutput .= vKey
vTickCount := A_TickCount
ToolTip, % vOutput
return
If you haven't done so yet, I would imagine looking into AHKHID or Lua or whatever methods there are of distinguishing between keyboards would be a good idea.

I'd say more, but I haven't ever tried to do anything like that.

==================================================

Here is a slight variant that logs the times between each press.

Code: Select all

oArray := {",":"<"}
;` 1234567890 -= [] ;'# \ ,./
;¬ !"£$%^&*() _+ {} :@~ | <>?
vList := "``¬,1!,2"",3£,4$,5%,6^,7&,8*,9(,0),-_,=+,{[,}],;:,'@,#~,\|,.>,/?"
Loop, Parse, vList, % ","
	oArray["" SubStr(A_LoopField,1,1)] := SubStr(A_LoopField,2)
vOutput := ""
VarSetCapacity(vOutput, 1000000*2)

vList2 := "``1234567890-=[];'#\,./"
Loop, Parse, vList2
	Hotkey, % "*$~" A_LoopField, GetKeys, On
Loop, 26
	Hotkey, % "*$~" Chr(96+A_Index), GetKeys, On
return

GetKeys:
*$~Space::
vTime := (A_TickCount-vTickCount)
vTickCount := A_TickCount
vKey := SubStr(A_ThisHotkey, StrLen(A_ThisHotkey))
if (SubStr(A_ThisHotkey, StrLen(A_ThisHotkey)-4) = "Space")
	vKey := " "
else if GetKeyState("Shift", "P")
	if vKey is alpha
		vKey := Format("{:U}", vKey)
	else
		vKey := oArray["" vKey]
if (vTime > 500)
	vOutput .= "[GAP]`r`n"
;vOutput .= vKey
vOutput .= "[" vTime "]" vKey
ToolTip, % vOutput
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
labrint
Posts: 383
Joined: 14 Jun 2017, 05:06
Location: Malta

Re: NEW Barcode Input Capture (USB and RS232 compatible)

13 Sep 2017, 04:34

The first code skips a lot of characters and does not distinguish between barcode and keyboard. The second is quite cool and I can give you a feedback on the times. Between barcoded characters, there was an interval of not more than 16 milliseconds and between keyboard more than 31. I don't think this is accurate though being that the other code set at 60 milliseconds did not capture keyboard text.

I will explore Lua and AHKHID but I doubt there is another method unless there is some method which captures any input from a particular USB port.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: NEW Barcode Input Capture (USB and RS232 compatible)

13 Sep 2017, 04:53

I wrote the code in such a way that no/almost no characters should be skipped. So I'm surprised that there are problems. And would be interested to hear any specifics. Does it work correctly with keyboard input? Otherwise you could check KeyHistory, and see what VK/SC values the script is receiving, and create hotkey labels based on those.

A_TickCount is not very precise, it tends to gives numbers that are roughly multiples of 16.

Is it not possible with one of the input devices to start and end each input of text with a special character or sequence?
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: apeironn, madensuyu1, peter_ahk and 349 guests