Barcode scanner: Add buzzer, adjust USB timings, add scan engine configuration, fix UART code
This commit is contained in:
parent
ec85621f9e
commit
681b17741f
@ -37,11 +37,12 @@
|
||||
UART_ID = 0 # TX/RX: UART 0: 0/1, 12/13, or 16/17; UART 1: 4/5 or 8/9
|
||||
UART_TX_PIN=0
|
||||
UART_RX_PIN=1
|
||||
BUZZER_PWM_PIN = 11 # Pin for passive buzzer PWM
|
||||
TRIGGER_BUTTON_PIN = 12 # Pin to read for scan trigger button, connect trigger button between this and ground
|
||||
TRIGGER_PIN = 13 # Pin that connects to the scan module's trigger line, pulls the line low while the user is pressing the trigger button
|
||||
UP_BUTTON_PIN = 14 # Pin to read for navigation up button
|
||||
DOWN_BUTTON_PIN = 15 # Pin to read for navigation down button
|
||||
LED_PIN = "LED" # 3 in prod
|
||||
LED_PIN = 3 # "LED" for testing, 3 for prod
|
||||
FIRMWARE_VERSION = "0.0.1"
|
||||
|
||||
#
|
||||
@ -49,7 +50,7 @@ FIRMWARE_VERSION = "0.0.1"
|
||||
#
|
||||
SCAN_GAP_MS = 50 # Amount of time to wait for more characters from the scan engine before sending a barcode
|
||||
MAX_BARCODE_LENGTH = 8192 # Barcodes longer than this from the scan engine are assumed to be a glitch
|
||||
TESTMODE = True # Sends a simulated barcode scan every 5 seconds
|
||||
TESTMODE = False # Sends a simulated barcode scan every 5 seconds
|
||||
|
||||
#
|
||||
# USB configuration
|
||||
|
||||
@ -30,12 +30,77 @@
|
||||
# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
# THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from machine import Pin
|
||||
from time import sleep_us
|
||||
from machine import Pin, PWM
|
||||
import machine
|
||||
from time import sleep_us, sleep_ms
|
||||
import config
|
||||
from oledscreen import iconDisplay, centerText
|
||||
import _thread
|
||||
|
||||
onboardLED = Pin(config.LED_PIN, Pin.OUT)
|
||||
buzzerPin = PWM(Pin(config.BUZZER_PWM_PIN))
|
||||
ledSequence = []
|
||||
ledLock = _thread.allocate_lock()
|
||||
|
||||
# Run LED on the second core so it doesn't slow down the main process
|
||||
|
||||
def ledThreadFn():
|
||||
global feedbackType, ledSequence
|
||||
while True:
|
||||
ledLock.acquire()
|
||||
if not ledSequence:
|
||||
ledLock.release()
|
||||
sleep_ms(1)
|
||||
continue
|
||||
seq = ledSequence
|
||||
ledSequence = []
|
||||
ledLock.release()
|
||||
for speed in seq:
|
||||
pulseLED(speed)
|
||||
|
||||
|
||||
ledThread = None
|
||||
|
||||
# Run in main.py during boot
|
||||
def createLEDThread():
|
||||
global ledThread
|
||||
ledThread = _thread.start_new_thread(ledThreadFn, ())
|
||||
|
||||
def doFeedback(mode):
|
||||
global ledSequence
|
||||
if mode == "SCAN":
|
||||
ledLock.acquire()
|
||||
ledSequence = ["fast"]
|
||||
ledLock.release()
|
||||
passiveBuzzer(1047, 100)
|
||||
elif mode == "OK":
|
||||
ledLock.acquire()
|
||||
ledSequence = ["fast"]
|
||||
ledLock.release()
|
||||
passiveBuzzer(1175, 100)
|
||||
elif mode == "ERR":
|
||||
ledLock.acquire()
|
||||
ledSequence = ["fast", "fast", "fast"]
|
||||
ledLock.release()
|
||||
passiveBuzzer(440, 100)
|
||||
sleep_ms(50)
|
||||
passiveBuzzer(440, 100)
|
||||
sleep_ms(50)
|
||||
passiveBuzzer(440, 100)
|
||||
elif mode == "POW":
|
||||
ledLock.acquire()
|
||||
ledSequence = ["normal"]
|
||||
ledLock.release()
|
||||
passiveBuzzer(880, 100)
|
||||
passiveBuzzer(988, 100)
|
||||
passiveBuzzer(1047, 100)
|
||||
elif mode == "NAF":
|
||||
ledLock.acquire()
|
||||
ledSequence = ["normal", "fast", "fast", "normal"]
|
||||
ledLock.release()
|
||||
passiveBuzzer(440, 100)
|
||||
passiveBuzzer(494, 100)
|
||||
passiveBuzzer(440, 200)
|
||||
|
||||
# Pulse the LED on and off with brightness fade
|
||||
def pulseLED(speed):
|
||||
@ -58,24 +123,17 @@ def pulseLED(speed):
|
||||
onboardLED.off()
|
||||
sleep_us(i)
|
||||
|
||||
def passiveBuzzer(frequency, duration):
|
||||
global buzzerPin
|
||||
buzzerPin.duty_u16(int(65536*0.2))
|
||||
buzzerPin.freq(frequency)
|
||||
sleep_ms(duration)
|
||||
buzzerPin.duty_u16(int(0))
|
||||
|
||||
def firmwareUpdateMessage():
|
||||
centerText("Firmware Update", False, True)
|
||||
|
||||
def feedbackBuzzer(feedback):
|
||||
if feedback == "OK":
|
||||
iconDisplay("OK")
|
||||
pulseLED("fast")
|
||||
elif feedback == "ERR":
|
||||
iconDisplay("ERR")
|
||||
pulseLED("fast")
|
||||
pulseLED("fast")
|
||||
pulseLED("fast")
|
||||
elif feedback == "POW":
|
||||
def feedbackBuzzer(feedback, onMain = False):
|
||||
if feedback == "POW":
|
||||
iconDisplay("POW")
|
||||
#pulseLED("normal")
|
||||
elif feedback == "NAF":
|
||||
iconDisplay("NAF")
|
||||
pulseLED("normal")
|
||||
pulseLED("fast")
|
||||
pulseLED("fast")
|
||||
pulseLED("normal")
|
||||
doFeedback(feedback)
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
# THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
from sys import stdin, exit
|
||||
from sys import stdin, exit, print_exception
|
||||
import machine
|
||||
from machine import Pin, USBDevice, UART
|
||||
from utime import sleep, sleep_ms, sleep_us
|
||||
@ -41,7 +41,7 @@ import time
|
||||
from config import *
|
||||
from oledscreen import bootDisplay, clearDisplay, brightDisplay, mainDisplay, centerText
|
||||
from scannerusb import initUSBHID, createAndSendBarcodeReports
|
||||
from feedback import feedbackBuzzer
|
||||
from feedback import feedbackBuzzer, createLEDThread
|
||||
from scanmode import isScanInhibited, setModeID, getCurrentModeID, processNewListUSBReport
|
||||
from watchdog import startwatchdog, feedwatchdog
|
||||
|
||||
@ -92,13 +92,26 @@ menuUpButton.irq(handler=menuUpButtonHandler, trigger=Pin.IRQ_FALLING)
|
||||
menuDownButton.irq(handler=menuDownButtonHandler, trigger=Pin.IRQ_FALLING)
|
||||
|
||||
#
|
||||
# Send scan engine configuration commands over UART
|
||||
#
|
||||
#
|
||||
# TODO: Send scan engine configuration commands over UART
|
||||
#
|
||||
#
|
||||
#
|
||||
uart.write(b'\x7E\x00\x08\x01\x00\xD9\x50\xAB\xCD') # Restore factory defaults
|
||||
uart.write(b'\x7E\x00\x08\x01\x00\x00\xC4\xAB\xCD') # 11000100 (LED settings)
|
||||
uart.write(b'\x7E\x00\x08\x01\x00\x01\x90\xAB\xCD') # 10010000 (trigger settings)
|
||||
uart.write(b'\x7E\x00\x08\x01\x00\x03\x03\xAB\xCD') # 00000011 (setup barcode settings)
|
||||
uart.write(b'\x7E\x00\x08\x01\x00\x05\x05\xAB\xCD') # 500ms timeout between decodes of same barcode
|
||||
uart.write(b'\x7E\x00\x08\x01\x00\x07\x00\xAB\xCD') # Disable deep sleep mode
|
||||
uart.write(b'\x7E\x00\x08\x01\x00\x0D\x00\xAB\xCD') # Disable invoicing and virtual keyboard, set TTL232 output
|
||||
uart.write(b'\x7E\x00\x08\x01\x00\x16\x01\xAB\xCD') # Try harder to decode bad barcodes
|
||||
uart.write(b'\x7E\x00\x08\x01\x00\x17\x00\xAB\xCD') # Disable code128 prefix and GS replacement
|
||||
uart.write(b'\x7E\x00\x08\x01\x00\x18\x1D\xAB\xCD') # Set GS replacement char to GS char just in case
|
||||
uart.write(b'\x7E\x00\x08\x01\x00\x2C\x02\xAB\xCD') # Enable all symbologies
|
||||
uart.write(b'\x7E\x00\x08\x01\x00\x33\x41\xAB\xCD') # Disable parentheses on Code128 AI, enable Code128
|
||||
uart.write(b'\x7E\x00\x08\x01\x00\x3F\x61\xAB\xCD') # Disable parentheses on QR/DataMatrix AI, enable QR
|
||||
uart.write(b'\x7E\x00\x08\x01\x00\xD9\x56\xAB\xCD') # Save as custom defaults
|
||||
|
||||
|
||||
feedwatchdog()
|
||||
createLEDThread()
|
||||
feedwatchdog()
|
||||
feedbackBuzzer("POW")
|
||||
feedwatchdog()
|
||||
@ -155,7 +168,7 @@ while True:
|
||||
uartBuffer.extend(data)
|
||||
lastBufferActivity = time.ticks_ms()
|
||||
if len(uartBuffer) > MAX_BARCODE_LENGTH:
|
||||
uartBuffer.clear()
|
||||
uartBuffer[:] = b'' # clear buffer
|
||||
bufferOverflow = True
|
||||
lastBufferActivity = None
|
||||
|
||||
@ -163,8 +176,8 @@ while True:
|
||||
if lastBufferActivity is not None and time.ticks_diff(time.ticks_ms(), lastBufferActivity) > SCAN_GAP_MS:
|
||||
if not isScanInhibited() and uartBuffer and not bufferOverflow:
|
||||
createAndSendBarcodeReports(bytes(uartBuffer))
|
||||
feedbackBuzzer("OK")
|
||||
uartBuffer.clear()
|
||||
feedbackBuzzer("SCAN", True)
|
||||
uartBuffer[:] = b'' # clear buffer
|
||||
lastBufferActivity = None
|
||||
bufferOverflow = False
|
||||
|
||||
@ -172,7 +185,7 @@ while True:
|
||||
|
||||
if TESTMODE and time.ticks_diff(time.ticks_ms(), lastTestSend) > 5000:
|
||||
createAndSendBarcodeReports(b'test barcode 12345')
|
||||
feedbackBuzzer("OK")
|
||||
feedbackBuzzer("SCAN")
|
||||
lastTestSend = time.ticks_ms()
|
||||
|
||||
feedwatchdog()
|
||||
@ -185,5 +198,5 @@ while True:
|
||||
machine.idle()
|
||||
except Exception as e:
|
||||
# Dump exceptions over serial for debugging
|
||||
print(e)
|
||||
print_exception(e)
|
||||
machine.reset()
|
||||
|
||||
@ -39,6 +39,7 @@ from feedback import feedbackBuzzer, firmwareUpdateMessage
|
||||
from watchdog import feedwatchdog
|
||||
import time
|
||||
from sys import stdout
|
||||
from utime import sleep_ms
|
||||
|
||||
usbinterface = None
|
||||
|
||||
@ -225,7 +226,7 @@ class USBHIDInterface(HIDInterface):
|
||||
while self.busy():
|
||||
# Wait for queue to open up, but drop this report on timeout
|
||||
# because the host isn't paying attention to us and this will deadlock if we wait forever
|
||||
if time.ticks_diff(time.ticks_ms(), start) > 5:
|
||||
if time.ticks_diff(time.ticks_ms(), start) > 10:
|
||||
return False
|
||||
machine.idle()
|
||||
self.send_report(data)
|
||||
@ -250,12 +251,17 @@ def createAndSendBarcodeReports(barcodeData):
|
||||
global usbinterface
|
||||
chunks = split(barcodeData, 56)
|
||||
for i, chunk in enumerate(chunks):
|
||||
isLastReport = len(chunks) - 1 == i
|
||||
lastByte = b'\x01'
|
||||
if len(chunks) - 1 == i:
|
||||
if isLastReport:
|
||||
lastByte = b'\x00'
|
||||
report = b'\x02' + bytes([len(chunk)]) + b'\x00\x00\x00' + pad_data(chunk, 56) + b'\x00' + bytes([getCurrentModeID()]) + lastByte
|
||||
if USBHID_ENABLED:
|
||||
if not usbinterface.send_data(report):
|
||||
if usbinterface.send_data(report):
|
||||
if not isLastReport:
|
||||
sleep_ms(50) # Wait a few milliseconds before sending the next report so it won't get dropped
|
||||
print(report)
|
||||
else:
|
||||
break # Stop sending barcode over USB, the host didn't get this chunk but it might get the next and only have half a barcode
|
||||
feedwatchdog()
|
||||
# Write barcode data to serial out for non-HID system compatibility
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user