I'm trying to read a code from a QR reader with python. Have used pigpio example from here http://abyz.me.uk/rpi/pigpio/examples.html#Python_wiegand_py
When I scan a QR it returns bits=34 value=12835750879
which is too long, the code should be 10 digit only.
The QR sends 34 bits, and the guy that installed it said I need to ignore the last 2 bits, to take only 0-31, thing is I don't really understand the code, I come from PHP, which has nothing to do with bits and memory.
This is the part of the code that deals with the reading, I think somewhere in the _cb
function.
Can somebody help me understand the code better so I can go into the right direction?
def __init__(self, pi, gpio_0, gpio_1, callback, bit_timeout=5):
"""
Instantiate with the pi, gpio for 0 (green wire), the gpio for 1
(white wire), the callback function, and the bit timeout in
milliseconds which indicates the end of a code.
The callback is passed the code length in bits and the value.
"""
self.pi = pi
self.gpio_0 = gpio_0
self.gpio_1 = gpio_1
self.callback = callback
self.bit_timeout = bit_timeout
self.in_code = False
self.pi.set_mode(gpio_0, pigpio.INPUT)
self.pi.set_mode(gpio_1, pigpio.INPUT)
self.pi.set_pull_up_down(gpio_0, pigpio.PUD_UP)
self.pi.set_pull_up_down(gpio_1, pigpio.PUD_UP)
self.cb_0 = self.pi.callback(gpio_0, pigpio.FALLING_EDGE, self._cb)
self.cb_1 = self.pi.callback(gpio_1, pigpio.FALLING_EDGE, self._cb)
def _cb(self, gpio, level, tick):
"""
Accumulate bits until both gpios 0 and 1 timeout.
"""
if level < pigpio.TIMEOUT:
if self.in_code == False:
self.bits = 1
self.num = 0
self.in_code = True
self.code_timeout = 0
self.pi.set_watchdog(self.gpio_0, self.bit_timeout)
self.pi.set_watchdog(self.gpio_1, self.bit_timeout)
else:
self.bits += 1
self.num = self.num << 1
if gpio == self.gpio_0:
self.code_timeout = self.code_timeout & 2 # clear gpio 0 timeout
else:
self.code_timeout = self.code_timeout & 1 # clear gpio 1 timeout
self.num = self.num | 1
else:
if self.in_code:
if gpio == self.gpio_0:
self.code_timeout = self.code_timeout | 1 # timeout gpio 0
else:
self.code_timeout = self.code_timeout | 2 # timeout gpio 1
if self.code_timeout == 3: # both gpios timed out
self.pi.set_watchdog(self.gpio_0, 0)
self.pi.set_watchdog(self.gpio_1, 0)
self.in_code = False
self.callback(self.bits, self.num)
To remove the two last bits, you can convert the integer self.num
to a binary string with bin()
, trim off two characters, then convert back to integer.
Here is an example:
num = 2**34 - 1 # 17179869183
num_b = bin(num) # '0b1111111111111111111111111111111111'
num = int(num_b[:-2], base=2) # 4294967295
So you want to use int(bin(self.num)[:-2], 2)
somewhere in your code where you retrieve the complete QR code.