From 550aa7a6d4fa94428c2ba8dfe748a7594c7eed73 Mon Sep 17 00:00:00 2001 From: gocivici Date: Mon, 8 Nov 2021 17:35:18 +0300 Subject: [PATCH] First commit --- Adafruit_Thermal.py | 734 ++++++++++++++++++++ QuantumDeathMachine.py | 75 ++ __pycache__/Adafruit_Thermal.cpython-37.pyc | Bin 0 -> 15594 bytes gfx/__pycache__/arrow.cpython-37.pyc | Bin 0 -> 4023 bytes gfx/arrow.py | 113 +++ 5 files changed, 922 insertions(+) create mode 100644 Adafruit_Thermal.py create mode 100755 QuantumDeathMachine.py create mode 100644 __pycache__/Adafruit_Thermal.cpython-37.pyc create mode 100644 gfx/__pycache__/arrow.cpython-37.pyc create mode 100644 gfx/arrow.py diff --git a/Adafruit_Thermal.py b/Adafruit_Thermal.py new file mode 100644 index 0000000..3de562a --- /dev/null +++ b/Adafruit_Thermal.py @@ -0,0 +1,734 @@ +#************************************************************************* +# This is a Python library for the Adafruit Thermal Printer. +# Pick one up at --> http://www.adafruit.com/products/597 +# These printers use TTL serial to communicate, 2 pins are required. +# IMPORTANT: On 3.3V systems (e.g. Raspberry Pi), use a 10K resistor on +# the RX pin (TX on the printer, green wire), or simply leave unconnected. +# +# Adafruit invests time and resources providing this open source code. +# Please support Adafruit and open-source hardware by purchasing products +# from Adafruit! +# +# Written by Limor Fried/Ladyada for Adafruit Industries. +# Python port by Phil Burgess for Adafruit Industries. +# MIT license, all text above must be included in any redistribution. +#************************************************************************* + +# This is pretty much a 1:1 direct Python port of the Adafruit_Thermal +# library for Arduino. All methods use the same naming conventions as the +# Arduino library, with only slight changes in parameter behavior where +# needed. This should simplify porting existing Adafruit_Thermal-based +# printer projects to Raspberry Pi, BeagleBone, etc. See printertest.py +# for an example. +# +# One significant change is the addition of the printImage() function, +# which ties this to the Python Imaging Library and opens the door to a +# lot of cool graphical stuff! +# +# TO DO: +# - Might use standard ConfigParser library to put thermal calibration +# settings in a global configuration file (rather than in the library). +# - Make this use proper Python library installation procedure. +# - Trap errors properly. Some stuff just falls through right now. +# - Add docstrings throughout! + +from serial import Serial +import time +import sys +import math + +class Adafruit_Thermal(Serial): + + resumeTime = 0.0 + byteTime = 0.0 + dotPrintTime = 0.0 + dotFeedTime = 0.0 + prevByte = '\n' + column = 0 + maxColumn = 32 + charHeight = 24 + lineSpacing = 8 + barcodeHeight = 50 + printMode = 0 + defaultHeatTime = 200 + firmwareVersion = 268 + writeToStdout = False + + def __init__(self, *args, **kwargs): + # NEW BEHAVIOR: if no parameters given, output is written + # to stdout, to be piped through 'lp -o raw' (old behavior + # was to use default port & baud rate). + baudrate = 19200 + if len(args) == 0: + self.writeToStdout = True + if len(args) == 1: + # If only port is passed, use default baud rate. + args = [ args[0], baudrate ] + elif len(args) == 2: + # If both passed, use those values. + baudrate = args[1] + + # Firmware is assumed version 2.68. Can override this + # with the 'firmware=X' argument, where X is the major + # version number * 100 + the minor version number (e.g. + # pass "firmware=264" for version 2.64. + self.firmwareVersion = kwargs.get('firmware', 268) + + if self.writeToStdout is False: + # Calculate time to issue one byte to the printer. + # 11 bits (not 8) to accommodate idle, start and + # stop bits. Idle time might be unnecessary, but + # erring on side of caution here. + self.byteTime = 11.0 / float(baudrate) + + Serial.__init__(self, *args, **kwargs) + + # Remainder of this method was previously in begin() + + # The printer can't start receiving data immediately + # upon power up -- it needs a moment to cold boot + # and initialize. Allow at least 1/2 sec of uptime + # before printer can receive data. + self.timeoutSet(0.5) + + self.wake() + self.reset() + + # Description of print settings from p. 23 of manual: + # ESC 7 n1 n2 n3 Setting Control Parameter Command + # Decimal: 27 55 n1 n2 n3 + # max heating dots, heating time, heating interval + # n1 = 0-255 Max heat dots, Unit (8dots), Default: 7 (64 dots) + # n2 = 3-255 Heating time, Unit (10us), Default: 80 (800us) + # n3 = 0-255 Heating interval, Unit (10us), Default: 2 (20us) + # The more max heating dots, the more peak current + # will cost when printing, the faster printing speed. + # The max heating dots is 8*(n1+1). The more heating + # time, the more density, but the slower printing + # speed. If heating time is too short, blank page + # may occur. The more heating interval, the more + # clear, but the slower printing speed. + + heatTime = kwargs.get('heattime', self.defaultHeatTime) + self.writeBytes( + 27, # Esc + 55, # 7 (print settings) + 11, # Heat dots + heatTime, # Lib default + 40) # Heat interval + + # Description of print density from p. 23 of manual: + # DC2 # n Set printing density + # Decimal: 18 35 n + # D4..D0 of n is used to set the printing density. + # Density is 50% + 5% * n(D4-D0) printing density. + # D7..D5 of n is used to set the printing break time. + # Break time is n(D7-D5)*250us. + # (Unsure of default values -- not documented) + + printDensity = 10 # 100% + printBreakTime = 2 # 500 uS + + self.writeBytes( + 18, # DC2 + 35, # Print density + (printBreakTime << 5) | printDensity) + self.dotPrintTime = 0.03 + self.dotFeedTime = 0.0021 + else: + self.reset() # Inits some vars + + # Because there's no flow control between the printer and computer, + # special care must be taken to avoid overrunning the printer's + # buffer. Serial output is throttled based on serial speed as well + # as an estimate of the device's print and feed rates (relatively + # slow, being bound to moving parts and physical reality). After + # an operation is issued to the printer (e.g. bitmap print), a + # timeout is set before which any other printer operations will be + # suspended. This is generally more efficient than using a delay + # in that it allows the calling code to continue with other duties + # (e.g. receiving or decoding an image) while the printer + # physically completes the task. + + # Sets estimated completion time for a just-issued task. + def timeoutSet(self, x): + self.resumeTime = time.time() + x + + # Waits (if necessary) for the prior task to complete. + def timeoutWait(self): + if self.writeToStdout is False: + while (time.time() - self.resumeTime) < 0: pass + + # Printer performance may vary based on the power supply voltage, + # thickness of paper, phase of the moon and other seemingly random + # variables. This method sets the times (in microseconds) for the + # paper to advance one vertical 'dot' when printing and feeding. + # For example, in the default initialized state, normal-sized text + # is 24 dots tall and the line spacing is 32 dots, so the time for + # one line to be issued is approximately 24 * print time + 8 * feed + # time. The default print and feed times are based on a random + # test unit, but as stated above your reality may be influenced by + # many factors. This lets you tweak the timing to avoid excessive + # delays and/or overrunning the printer buffer. + def setTimes(self, p, f): + # Units are in microseconds for + # compatibility with Arduino library + self.dotPrintTime = p / 1000000.0 + self.dotFeedTime = f / 1000000.0 + + # 'Raw' byte-writing method + def writeBytes(self, *args): + if self.writeToStdout: + for arg in args: + sys.stdout.write(bytes([arg])) + else: + for arg in args: + self.timeoutWait() + self.timeoutSet(len(args) * self.byteTime) + super(Adafruit_Thermal, self).write(bytes([arg])) + + # Override write() method to keep track of paper feed. + def write(self, *data): + for i in range(len(data)): + c = data[i] + if self.writeToStdout: + sys.stdout.write(c) + continue + if c != 0x13: + self.timeoutWait() + super(Adafruit_Thermal, self).write(c) + d = self.byteTime + if ((c == '\n') or + (self.column == self.maxColumn)): + # Newline or wrap + if self.prevByte == '\n': + # Feed line (blank) + d += ((self.charHeight + + self.lineSpacing) * + self.dotFeedTime) + else: + # Text line + d += ((self.charHeight * + self.dotPrintTime) + + (self.lineSpacing * + self.dotFeedTime)) + self.column = 0 + # Treat wrap as newline + # on next pass + c = '\n' + else: + self.column += 1 + self.timeoutSet(d) + self.prevByte = c + + # The bulk of this method was moved into __init__, + # but this is left here for compatibility with older + # code that might get ported directly from Arduino. + def begin(self, heatTime=defaultHeatTime): + self.writeBytes( + 27, # Esc + 55, # 7 (print settings) + 11, # Heat dots + heatTime, + 40) # Heat interval + + def reset(self): + self.writeBytes(27, 64) # Esc @ = init command + self.prevByte = '\n' # Treat as if prior line is blank + self.column = 0 + self.maxColumn = 32 + self.charHeight = 24 + self.lineSpacing = 6 + self.barcodeHeight = 50 + if self.firmwareVersion >= 264: + # Configure tab stops on recent printers + self.writeBytes(27, 68) # Set tab stops + self.writeBytes( 4, 8, 12, 16) # every 4 columns, + self.writeBytes(20, 24, 28, 0) # 0 is end-of-list. + + # Reset text formatting parameters. + def setDefault(self): + self.online() + self.justify('L') + self.inverseOff() + self.doubleHeightOff() + self.setLineHeight(30) + self.boldOff() + self.underlineOff() + self.setBarcodeHeight(50) + self.setSize('s') + self.setCharset() + self.setCodePage() + + def test(self): + self.write("Hello world!".encode('cp437', 'ignore')) + self.feed(2) + + def testPage(self): + self.writeBytes(18, 84) + self.timeoutSet( + self.dotPrintTime * 24 * 26 + + self.dotFeedTime * (6 * 26 + 30)) + + def setBarcodeHeight(self, val=50): + if val < 1: val = 1 + self.barcodeHeight = val + self.writeBytes(29, 104, val) + + UPC_A = 0 + UPC_E = 1 + EAN13 = 2 + EAN8 = 3 + CODE39 = 4 + I25 = 5 + CODEBAR = 6 + CODE93 = 7 + CODE128 = 8 + CODE11 = 9 + MSI = 10 + ITF = 11 + CODABAR = 12 + + def printBarcode(self, text, type): + + newDict = { # UPC codes & values for firmwareVersion >= 264 + self.UPC_A : 65, + self.UPC_E : 66, + self.EAN13 : 67, + self.EAN8 : 68, + self.CODE39 : 69, + self.ITF : 70, + self.CODABAR : 71, + self.CODE93 : 72, + self.CODE128 : 73, + self.I25 : -1, # NOT IN NEW FIRMWARE + self.CODEBAR : -1, + self.CODE11 : -1, + self.MSI : -1 + } + oldDict = { # UPC codes & values for firmwareVersion < 264 + self.UPC_A : 0, + self.UPC_E : 1, + self.EAN13 : 2, + self.EAN8 : 3, + self.CODE39 : 4, + self.I25 : 5, + self.CODEBAR : 6, + self.CODE93 : 7, + self.CODE128 : 8, + self.CODE11 : 9, + self.MSI : 10, + self.ITF : -1, # NOT IN OLD FIRMWARE + self.CODABAR : -1 + } + + if self.firmwareVersion >= 264: + n = newDict[type] + else: + n = oldDict[type] + if n == -1: return + self.feed(1) # Recent firmware requires this? + self.writeBytes( + 29, 72, 2, # Print label below barcode + 29, 119, 3, # Barcode width + 29, 107, n) # Barcode type + self.timeoutWait() + self.timeoutSet((self.barcodeHeight + 40) * self.dotPrintTime) + # Print string + if self.firmwareVersion >= 264: + # Recent firmware: write length byte + string sans NUL + n = len(text) + if n > 255: n = 255 + if self.writeToStdout: + sys.stdout.write((chr(n)).encode('cp437', 'ignore')) + for i in range(n): + sys.stdout.write(text[i].encode('utf-8', 'ignore')) + else: + super(Adafruit_Thermal, self).write((chr(n)).encode('utf-8', 'ignore')) + for i in range(n): + super(Adafruit_Thermal, + self).write(text[i].encode('utf-8', 'ignore')) + else: + # Older firmware: write string + NUL + if self.writeToStdout: + sys.stdout.write(text.encode('utf-8', 'ignore')) + else: + super(Adafruit_Thermal, self).write(text.encode('utf-8', 'ignore')) + self.prevByte = '\n' + + # === Character commands === + + INVERSE_MASK = (1 << 1) # Not in 2.6.8 firmware (see inverseOn()) + UPDOWN_MASK = (1 << 2) + BOLD_MASK = (1 << 3) + DOUBLE_HEIGHT_MASK = (1 << 4) + DOUBLE_WIDTH_MASK = (1 << 5) + STRIKE_MASK = (1 << 6) + + def setPrintMode(self, mask): + self.printMode |= mask + self.writePrintMode() + if self.printMode & self.DOUBLE_HEIGHT_MASK: + self.charHeight = 48 + else: + self.charHeight = 24 + if self.printMode & self.DOUBLE_WIDTH_MASK: + self.maxColumn = 16 + else: + self.maxColumn = 32 + + def unsetPrintMode(self, mask): + self.printMode &= ~mask + self.writePrintMode() + if self.printMode & self.DOUBLE_HEIGHT_MASK: + self.charHeight = 48 + else: + self.charHeight = 24 + if self.printMode & self.DOUBLE_WIDTH_MASK: + self.maxColumn = 16 + else: + self.maxColumn = 32 + + def writePrintMode(self): + self.writeBytes(27, 33, self.printMode) + + def normal(self): + self.printMode = 0 + self.writePrintMode() + + def inverseOn(self): + if self.firmwareVersion >= 268: + self.writeBytes(29, 66, 1) + else: + self.setPrintMode(self.INVERSE_MASK) + + def inverseOff(self): + if self.firmwareVersion >= 268: + self.writeBytes(29, 66, 0) + else: + self.unsetPrintMode(self.INVERSE_MASK) + + def upsideDownOn(self): + self.setPrintMode(self.UPDOWN_MASK) + + def upsideDownOff(self): + self.unsetPrintMode(self.UPDOWN_MASK) + + def doubleHeightOn(self): + self.setPrintMode(self.DOUBLE_HEIGHT_MASK) + + def doubleHeightOff(self): + self.unsetPrintMode(self.DOUBLE_HEIGHT_MASK) + + def doubleWidthOn(self): + self.setPrintMode(self.DOUBLE_WIDTH_MASK) + + def doubleWidthOff(self): + self.unsetPrintMode(self.DOUBLE_WIDTH_MASK) + + def strikeOn(self): + self.setPrintMode(self.STRIKE_MASK) + + def strikeOff(self): + self.unsetPrintMode(self.STRIKE_MASK) + + def boldOn(self): + self.setPrintMode(self.BOLD_MASK) + + def boldOff(self): + self.unsetPrintMode(self.BOLD_MASK) + + def justify(self, value): + c = value.upper() + if c == 'C': + pos = 1 + elif c == 'R': + pos = 2 + else: + pos = 0 + self.writeBytes(0x1B, 0x61, pos) + + # Feeds by the specified number of lines + def feed(self, x=1): + if self.firmwareVersion >= 264: + self.writeBytes(27, 100, x) + self.timeoutSet(self.dotFeedTime * self.charHeight) + self.prevByte = '\n' + self.column = 0 + + else: + # datasheet claims sending bytes 27, 100, works, + # but it feeds much more than that. So, manually: + while x > 0: + self.write('\n'.encode('cp437', 'ignore')) + x -= 1 + + # Feeds by the specified number of individual pixel rows + def feedRows(self, rows): + self.writeBytes(27, 74, rows) + self.timeoutSet(rows * dotFeedTime) + self.prevByte = '\n' + self.column = 0 + + def flush(self): + self.writeBytes(12) # ASCII FF + + def setSize(self, value): + c = value.upper() + if c == 'L': # Large: double width and height + size = 0x11 + self.charHeight = 48 + self.maxColumn = 16 + elif c == 'M': # Medium: double height + size = 0x01 + self.charHeight = 48 + self.maxColumn = 32 + else: # Small: standard width and height + size = 0x00 + self.charHeight = 24 + self.maxColumn = 32 + + self.writeBytes(29, 33, size) + prevByte = '\n' # Setting the size adds a linefeed + + # Underlines of different weights can be produced: + # 0 - no underline + # 1 - normal underline + # 2 - thick underline + def underlineOn(self, weight=1): + if weight > 2: weight = 2 + self.writeBytes(27, 45, weight) + + def underlineOff(self): + self.writeBytes(27, 45, 0) + + def printBitmap(self, w, h, bitmap, LaaT=False): + rowBytes = math.floor((w + 7) / 8) # Round up to next byte boundary + if rowBytes >= 48: + rowBytesClipped = 48 # 384 pixels max width + else: + rowBytesClipped = rowBytes + + # if LaaT (line-at-a-time) is True, print bitmaps + # scanline-at-a-time (rather than in chunks). + # This tends to make for much cleaner printing + # (no feed gaps) on large images...but has the + # opposite effect on small images that would fit + # in a single 'chunk', so use carefully! + if LaaT: maxChunkHeight = 1 + else: maxChunkHeight = 255 + + i = 0 + for rowStart in range(0, h, maxChunkHeight): + chunkHeight = h - rowStart + if chunkHeight > maxChunkHeight: + chunkHeight = maxChunkHeight + + # Timeout wait happens here + self.writeBytes(18, 42, chunkHeight, rowBytesClipped) + + for y in range(chunkHeight): + for x in range(rowBytesClipped): + if self.writeToStdout: + sys.stdout.write(bytes([bitmap[i]])) + else: + super(Adafruit_Thermal, + self).write(bytes([bitmap[i]])) + i += 1 + i += rowBytes - rowBytesClipped + self.timeoutSet(chunkHeight * self.dotPrintTime) + + self.prevByte = '\n' + + # Print Image. Requires Python Imaging Library. This is + # specific to the Python port and not present in the Arduino + # library. Image will be cropped to 384 pixels width if + # necessary, and converted to 1-bit w/diffusion dithering. + # For any other behavior (scale, B&W threshold, etc.), use + # the Imaging Library to perform such operations before + # passing the result to this function. + def printImage(self, image_file, LaaT=False): + from PIL import Image + image = Image.open(image_file) + if image.mode != '1': + image = image.convert('1') + + width = image.size[0] + height = image.size[1] + if width > 384: + width = 384 + rowBytes = math.floor((width + 7) / 8) + bitmap = bytearray(rowBytes * height) + pixels = image.load() + + for y in range(height): + n = y * rowBytes + x = 0 + for b in range(rowBytes): + sum = 0 + bit = 128 + while bit > 0: + if x >= width: break + if pixels[x, y] == 0: + sum |= bit + x += 1 + bit >>= 1 + bitmap[n + b] = sum + + self.printBitmap(width, height, bitmap, LaaT) + + # Take the printer offline. Print commands sent after this + # will be ignored until 'online' is called. + def offline(self): + self.writeBytes(27, 61, 0) + + # Take the printer online. Subsequent print commands will be obeyed. + def online(self): + self.writeBytes(27, 61, 1) + + # Put the printer into a low-energy state immediately. + def sleep(self): + self.sleepAfter(1) # Can't be 0, that means "don't sleep" + + # Put the printer into a low-energy state after + # the given number of seconds. + def sleepAfter(self, seconds): + if self.firmwareVersion >= 264: + self.writeBytes(27, 56, seconds & 0xFF, seconds >> 8) + else: + self.writeBytes(27, 56, seconds) + + def wake(self): + self.timeoutSet(0) + self.writeBytes(255) + if self.firmwareVersion >= 264: + time.sleep(0.05) # 50 ms + self.writeBytes(27, 118, 0) # Sleep off (important!) + else: + for i in range(10): + self.writeBytes(27) + self.timeoutSet(0.1) + + # Empty method, included for compatibility + # with existing code ported from Arduino. + def listen(self): + pass + + # Check the status of the paper using the printers self reporting + # ability. Doesn't match the datasheet... + # Returns True for paper, False for no paper. + def hasPaper(self): + if self.firmwareVersion >= 264: + self.writeBytes(27, 118, 0) + else: + self.writeBytes(29, 114, 0) + # Bit 2 of response seems to be paper status + stat = ord(self.read(1)) & 0b00000100 + # If set, we have paper; if clear, no paper + return stat == 0 + + def setLineHeight(self, val=32): + if val < 24: val = 24 + self.lineSpacing = val - 24 + + # The printer doesn't take into account the current text + # height when setting line height, making this more akin + # to inter-line spacing. Default line spacing is 32 + # (char height of 24, line spacing of 8). + self.writeBytes(27, 51, val) + + CHARSET_USA = 0 + CHARSET_FRANCE = 1 + CHARSET_GERMANY = 2 + CHARSET_UK = 3 + CHARSET_DENMARK1 = 4 + CHARSET_SWEDEN = 5 + CHARSET_ITALY = 6 + CHARSET_SPAIN1 = 7 + CHARSET_JAPAN = 8 + CHARSET_NORWAY = 9 + CHARSET_DENMARK2 = 10 + CHARSET_SPAIN2 = 11 + CHARSET_LATINAMERICA = 12 + CHARSET_KOREA = 13 + CHARSET_SLOVENIA = 14 + CHARSET_CROATIA = 14 + CHARSET_CHINA = 15 + + # Alters some chars in ASCII 0x23-0x7E range; see datasheet + def setCharset(self, val=0): + if val > 15: val = 15 + self.writeBytes(27, 82, val) + + CODEPAGE_CP437 = 0 # USA, Standard Europe + CODEPAGE_KATAKANA = 1 + CODEPAGE_CP850 = 2 # Multilingual + CODEPAGE_CP860 = 3 # Portuguese + CODEPAGE_CP863 = 4 # Canadian-French + CODEPAGE_CP865 = 5 # Nordic + CODEPAGE_WCP1251 = 6 # Cyrillic + CODEPAGE_CP866 = 7 # Cyrillic #2 + CODEPAGE_MIK = 8 # Cyrillic/Bulgarian + CODEPAGE_CP755 = 9 # East Europe, Latvian 2 + CODEPAGE_IRAN = 10 + CODEPAGE_CP862 = 15 # Hebrew + CODEPAGE_WCP1252 = 16 # Latin 1 + CODEPAGE_WCP1253 = 17 # Greek + CODEPAGE_CP852 = 18 # Latin 2 + CODEPAGE_CP858 = 19 # Multilingual Latin 1 + Euro + CODEPAGE_IRAN2 = 20 + CODEPAGE_LATVIAN = 21 + CODEPAGE_CP864 = 22 # Arabic + CODEPAGE_ISO_8859_1 = 23 # West Europe + CODEPAGE_CP737 = 24 # Greek + CODEPAGE_WCP1257 = 25 # Baltic + CODEPAGE_THAI = 26 + CODEPAGE_CP720 = 27 # Arabic + CODEPAGE_CP855 = 28 + CODEPAGE_CP857 = 29 # Turkish + CODEPAGE_WCP1250 = 30 # Central Europe + CODEPAGE_CP775 = 31 + CODEPAGE_WCP1254 = 32 # Turkish + CODEPAGE_WCP1255 = 33 # Hebrew + CODEPAGE_WCP1256 = 34 # Arabic + CODEPAGE_WCP1258 = 35 # Vietnam + CODEPAGE_ISO_8859_2 = 36 # Latin 2 + CODEPAGE_ISO_8859_3 = 37 # Latin 3 + CODEPAGE_ISO_8859_4 = 38 # Baltic + CODEPAGE_ISO_8859_5 = 39 # Cyrillic + CODEPAGE_ISO_8859_6 = 40 # Arabic + CODEPAGE_ISO_8859_7 = 41 # Greek + CODEPAGE_ISO_8859_8 = 42 # Hebrew + CODEPAGE_ISO_8859_9 = 43 # Turkish + CODEPAGE_ISO_8859_15 = 44 # Latin 3 + CODEPAGE_THAI2 = 45 + CODEPAGE_CP856 = 46 + CODEPAGE_CP874 = 47 + + # Selects alt symbols for 'upper' ASCII values 0x80-0xFF + def setCodePage(self, val=0): + if val > 47: val = 47 + self.writeBytes(27, 116, val) + + # Copied from Arduino lib for parity; may not work on all printers + def tab(self): + self.writeBytes(9) + self.column = (self.column + 4) & 0xFC + + # Copied from Arduino lib for parity; may not work on all printers + def setCharSpacing(self, spacing): + self.writeBytes(27, 32, spacing) + + # Overloading print() in Python pre-3.0 is dirty pool, + # but these are here to provide more direct compatibility + # with existing code written for the Arduino library. + def print(self, *args, **kwargs): + for arg in args: + self.write((str(arg)).encode('cp437', 'ignore')) + + # For Arduino code compatibility again + def println(self, *args, **kwargs): + for arg in args: + self.write((str(arg)).encode('cp437', 'ignore')) + self.write('\n'.encode('cp437', 'ignore')) + diff --git a/QuantumDeathMachine.py b/QuantumDeathMachine.py new file mode 100755 index 0000000..7d5917e --- /dev/null +++ b/QuantumDeathMachine.py @@ -0,0 +1,75 @@ + +from Adafruit_Thermal import * +from qiskit import QuantumCircuit, execute, Aer, IBMQ +import qiskit as q +from qiskit.tools.monitor import job_monitor, backend_overview +from qiskit.providers.ibmq import least_busy +import time +import warnings + +warnings.filterwarnings("ignore") + + +DeathList = ["Bees","Sour milk","Natural Causes","Monsters from\nthe Deep","In space,\nAlone","In Sleep","Peacefully","Pooping","Furnace","Rollercoaster","Extreme cold","Bear","Heat death of\nthe universe","Goose attack","sneezing","Boat accident"] + +provider = IBMQ.load_account() #load account from disk + +qc = q.QuantumCircuit(4,4) #5 qubits 5 classical bits +qc.h(0) +qc.h(1) +qc.h(2) +qc.h(3) +#qc.h(4) +qc.measure([0, 1, 2, 3],[0, 1, 2, 3]) + +print("\nAll backends overview:\n") +backend_overview() + +backend = least_busy(provider.backends(n_qubits=5, operational=True, simulator=False)) +print("\nLeast busy 5-qubit backend:", backend.name()) +#backend = provider.get_backend('ibmq_belem') + +shots = 1 +job = execute(qc, backend, shots=shots, memory=True) +job_monitor(job) +result = job.result() +dice=result.get_memory(qc) + +print("Received qubits: " + dice[0]) +print("Quantum dice roll result: " + str(int(dice[0],2))) +time.sleep(4) +printer = Adafruit_Thermal("/dev/serial0", 9600, timeout=5) +printer.wake() + +print("Printing Result..") +printer.justify('C') +printer.feed(1) +printer.setSize('L') # Set type size, accepts 'S', 'M', 'L' +#printer.println("---------------") +printer.setSize('M') +printer.println("This is how") +printer.setSize('L') +printer.println("YOU DIE") +import gfx.arrow as arrow +printer.printBitmap(arrow.width, arrow.height, arrow.data) +#printer.println("---------------") +printer.setSize("L") +#printer.justify('L') +#printer.feed(1) +printer.println("---------------") +#printer.println(DeathList[0]) +printer.println(DeathList[(int(dice[0],2))]) +printer.println("---------------") +#printer.println("Old Age,\nSurrounded by\nLoved Ones") +#printer.println("\uD83D\uDC80") +printer.feed(1) +printer.setSize("S") +printer.print("Your Qubits: ") +printer.println(dice) + +printer.feed(3) + + +printer.sleep() # Tell printer to sleep +#printer.wake() # Call wake() before printing again, even if reset +printer.setDefault() # Restore printer to defaults diff --git a/__pycache__/Adafruit_Thermal.cpython-37.pyc b/__pycache__/Adafruit_Thermal.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ffba3dae63cd53387596971bf3e5b5453af5f4e8 GIT binary patch literal 15594 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 G$o~Q$=Lp;Y literal 0 HcmV?d00001 diff --git a/gfx/__pycache__/arrow.cpython-37.pyc b/gfx/__pycache__/arrow.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef73c5aff14eef70705fbb5e8a42701f96bc72d7 GIT binary patch literal 4023 zcmeH~Jxjwt7{@O!wze9pRqOlP*g*r%q9U$}qAr~bUTlJGQ_>U_MBT(q-2DK4i*9}e z$s{;PH#bE@y?>e(b&*G$BsucCgyfeT&!4-HB~42*v0crc8^>A3?s3xGYB9zZ#YyE- zV~n#L<5EuIa@3*<{7D5AuKwaVk@a~7M%DQ5)o2rQq>*xrFk9j+tDR&e!gnP}R!3-c zk}NH>x=2 zS!r>9qxBF{mRnYeWDSR&MzRJ&tAk`^LMuVC`aI1q+GM(t?G=XlcPhVzjhiAu;r{_Peh+ZGCEvD9!0FVoMqvTbKUvACs9_WVaI{P!_L%)5l V=