Notices


Reply
Thread Tools
Posts: 674 | Thanked: 191 times | Joined on Mar 2008 @ Buenos Aires, Argentina
#11
That would be nice.
 
Posts: 8 | Thanked: 0 times | Joined on Feb 2008 @ Colorado, USA
#12
I whipped this up just last night ( probably in the wrong thread but posting anyway)

Code:
#!/usr/bin/env python

# This program connects to a Baracoda Pencil2 Bluetooth UPC scanner,
# polls for barcodes, xml-rpc queries upcdatabase.com, then prints UPC metadata.
# I've tested this on my lenny debian desktop and Nokia N810 
# (RX-44_DIABLO_4.2008.23-14_PR_COMBINED_MR0_ARM.bin)
#
# I didn't use any Baracoda libs, just read the Pencil2 protocol doc and figured
# out how to talk to the scanner. Open box to barcode metadata printouts = 3 hou


import bluetooth, time, traceback, sys
from xmlrpclib import ServerProxy, ProtocolError

# I'm connecting to a Baracoda Pencil 2, got the bt id from the unit, confirmed 
# with desktop hcitool.
host = '00:A0:96:18:A7:64' # can scan for this, but hardcoding for faster connec
name = 'Spp'
port = 1
print "connecting to \"%s\" on %s" % (name, host)
sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
sock.connect((host, port))
sock.settimeout(2.0) # keep us from hanging around too long

# I'm setting frame prefix and suffix to find my barcode data in the char stream
# see Pencil2 communications protocol document
#prefix set
sock.send(chr(0xEC)+chr(0x00)+chr(0x02)+chr(0x01)+chr(0x01))
#suffix set
sock.send(chr(0xF0)+chr(0x00)+chr(0x02)+chr(0x01)+chr(0x04))
#data format set
sock.send(chr(0xE8)+chr(0x00)+chr(0x01)+chr(0x07))
data = sock.recv(1024) # throw away all the results

upc = ""
while True:
    try:
        data = sock.recv(100) # this here is binary data, you may not get it all
        for c in data:
            o = ord(c)
            if o > 33 and o < 126:
                print "0x%02X %3d %s"%(o,o,c)
            else:
                print "0x%02X %3d"%(o,o)
            if o == 0x01: # prefix is 0x01
                upc = ""
                continue
            if o == 0x04: # suffix is 0x04, upc now has a valid number
                l = len(upc)
                print ">%s<"%upc, l
                while True:
                    try:
                        server = ServerProxy("http://dev.upcdatabase.com/rpc")
                        if l == 8:
                            reply = server.lookupEAN(server.convertUPCE(upc))
                        elif l == 12:
                            ean = server.calculateCheckDigit(upc[:-1]+"C")
                            reply = server.lookupEAN(ean)
                        elif l == 13:
                            reply = server.lookupEAN(upc)
                        else:
                            print 'not a valid UPC code'
                            break;
                            #oldschool, reply = server.lookupUPC(upc)
                        #print server.help()
                        #print reply
                        if reply['found'] == True:
                            keys = reply.keys() # sort the keys and print alphab
                            keys.sort()
                            for key in keys:
                                print "%-20s %s"%(key,reply[key])
                        if reply['found'] == False:
                            print 'not found'
                        break
                    except ProtocolError,e: 
                        print 'server return error',e,' retrying in 5 seconds'
                        time.sleep(5)
                    except:
                        traceback.print_exc(file=sys.stdout)
                        break

            upc += c
    except bluetooth.BluetoothError:
        pass # this is normal
    except KeyboardInterrupt:
        break
    except:
        traceback.print_exc(file=sys.stdout)
    

# xml-rpc help 
#  help - returns string
#          Show available functions and their parameters.
#  
#  lookupEAN(ean string) - returns struct
#          Lookup upc database entry.
#  
#  lookupUPC(upc string) - returns struct
#          Lookup upc database entry.
#          DEPRECATED!  Use 'lookupEAN' instead.
#  
#  writeEntry(username string, password string, ean string, description string, 
#          Add or modify an entry in the database.
#          This function is unimplemented at this time,
#          but is here for API review.
#  
#  calculateCheckDigit(partialean string) - returns string
#          Parameter 'ean' should have 'C' or 'X' in
#          place of the check digit (last character).
#          Length of 'partialean' parameter should be
#          11 or 12 digits, plus 'X' or 'C' character.
#  
#  convertUPCE(upce string) - returns string
#          Parameter 'upce' should be exactly 8 digits.
#          Returns full EAN-13.
#  
#  decodeCueCat(cuecatscan string) - returns struct
#          Returns serial number, type, and code given
#          CueCat scanner output.
#  
#  latestDownloadURL - returns string
#          Return URL of latest full database download.
#  
#  All 'upc' parameters should be 12 digits long.
#  All 'ean' parameters should be 13 digits long.


'''
/* Copyright (C) 2008 by Craig Hollabaugh
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Library General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
'''



Code:
Nokia-N810-23-14:~# ./upcdemo.py 
connecting to "Spp" on 00:A0:96:18:A7:64
0xF0 240
0x00   0
0x01   1
0x01   1
0xE8 232
0x00   0
0x01   1
0x01   1
0x32  50 2
0x00   0
0x16  22
0x30  48 0
0x30  48 0
0x30  48 0
0x38  56 8
0x30  48 0
0x31  49 1
0x31  49 1
0x30  48 0
0x32  50 2
0x36  54 6
0x32  50 2
0x33  51 3
0x01   1
0x30  48 0
0x31  49 1
0x32  50 2
0x32  50 2
0x33  51 3
0x31  49 1
0x30  48 0
0x31  49 1
0x04   4
>01223101< 8
/usr/lib/python25.zip/xmllib.py:9: DeprecationWarning: The xmllib module is obso
description          Diet Pepsi
ean                  0012000002311
found                True
isCoupon             False
issuerCountry        United States
issuerCountryCode    us
lastModified         2005-07-19 15:21:08
message              Database entry found
mfrGLN               0120000000036
pendingUpdates       0
size                 2 liter
upc                  012000002311
upce                 01223101
 
Posts: 2,102 | Thanked: 1,309 times | Joined on Sep 2006
#13
I don't suppose there's any reason to require that the camera does the capture & decoding, a hardware scanner should also be allowed to do that (as you show above). They are just very expensive (for BT ones) or require USB (i.e. powered hub, etc.).

Good to see how to obtain the UPC metadata
 
Posts: 8 | Thanked: 0 times | Joined on Feb 2008 @ Colorado, USA
#14
You may also want to look BaToo, http://people.inf.ethz.ch/adelmanr/b.../Main/HomePage. The product information video, http://people.inf.ethz.ch/adelmanr/r...nformation.wmv, is very nice.
 
Posts: 2,102 | Thanked: 1,309 times | Joined on Sep 2006
#15
Interesting, it does work very smoothly (the book demo is exactly what I was talking about for books). It doesn't do very many types of barcode though (some of the 2D and stacked 1D barcodes can encode urls and the like, which would be interesting), and it's written in Java (uurgh )

I'm still going to have a go at writing one (or at least using libraries other people have written in the first instance).

This paper on their site (http://www.vs.inf.ethz.ch/publ/paper/barcodes2006.pdf) gives some references to more advanced techniques (2D Fourier transform anyone, DSP.... ) but I see their software uses the same simple approach (i.e. low power) as I was doing in my MATLAB code (scanlines). Glad to see I wasn't too far off the ball

Time to see if there are any papers about decoding 2D barcodes anywhere...
 
Posts: 118 | Thanked: 297 times | Joined on Nov 2007
#16
If the built in camera had an gstreamer API for adjusting gain, hue and contrast it would probably be sufficient for scanning barcodes. As for now pictures taken indoors are always to grainy...
 
Posts: 2,102 | Thanked: 1,309 times | Joined on Sep 2006
#17
The recommended method for accessing the camera is though gstreamer, is it possible to access it directly though v4l2?
 
Posts: 2,102 | Thanked: 1,309 times | Joined on Sep 2006
#18
Scratch that, I just took a picture of a barcode with the internal camera (maemo-camera app) and it doesn't look too awful.
 
Posts: 8 | Thanked: 0 times | Joined on Feb 2008 @ Colorado, USA
#19
Lardman,

This might provide you with 2D insight.

http://blogs.s60.com/tommi/2006/12/2...manifesto.html

Craig
 
Bundyo's Avatar
Posts: 4,708 | Thanked: 4,649 times | Joined on Oct 2007 @ Bulgaria
#20
http://scan.jsharkey.org/

Android is ahead...
__________________
Technically, there are three determinate states the cat could be in: Alive, Dead, and Bloody Furious.
 
Reply


 
Forum Jump


All times are GMT. The time now is 15:49.