diff --git a/README.md b/README.md index 79d9381..85d4368 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Badger2040 System II +> Forked from https://github.com/oneearedrabbit/badger-system-ii + Tired of boring badges that just blend in with the crowd? You want to show off your quirky personality and love of retro technology? You are looking for a fun project to bond with your engineering team? Look no further than the programmable e-ink badge! https://kruzenshtern.org/the-e-ink-badge-the-coolest-badge-you-didnt-know-you-needed/ diff --git a/scripts/convert.py b/scripts/convert.py new file mode 100644 index 0000000..d8613cc --- /dev/null +++ b/scripts/convert.py @@ -0,0 +1,136 @@ +#!/usr/bin/env python3 +""" +Converts images into a format suitable for display on Badger 2040. + +Optionally resizes images to 296x128 to fit the display. + +Crunches images down to dithered, 1bit colour depth. + +Outputs either in raw binary format or as a .py file for embedding into MicroPython. + +Output to py functionality is borrwed from data_to_py.py, Copyright (c) 2016 Peter Hinch +""" + +import io +import argparse +from PIL import Image, ImageEnhance +from pathlib import Path + + +PY_HEADER = """# Code generated by convert.py. +""" + +PY_FOOTER = """_mvdata = memoryview(_data) + +def data(): + return _mvdata + +""" + + +parser = argparse.ArgumentParser(description='Converts images into the format used by Badger2040.') +parser.add_argument('file', nargs="+", help='input files to convert') +parser.add_argument('--out_dir', type=Path, default=None, help='output directory') +parser.add_argument('--binary', action="store_true", help='output binary file for MicroPython') +parser.add_argument('--py', action="store_true", help='output .py file for MicroPython embedding') +parser.add_argument('--resize', action="store_true", help='force images to 296x128 pixels') + +options = parser.parse_args() + + +class ByteWriter(object): + bytes_per_line = 16 + + def __init__(self, stream, varname): + self.stream = stream + self.stream.write('{} =\\\n'.format(varname)) + self.bytecount = 0 # For line breaks + + def _eol(self): + self.stream.write("'\\\n") + + def _eot(self): + self.stream.write("'\n") + + def _bol(self): + self.stream.write("b'") + + # Output a single byte + def obyte(self, data): + if not self.bytecount: + self._bol() + self.stream.write('\\x{:02x}'.format(data)) + self.bytecount += 1 + self.bytecount %= self.bytes_per_line + if not self.bytecount: + self._eol() + + # Output from a sequence + def odata(self, bytelist): + for byt in bytelist: + self.obyte(byt) + + # ensure a correct final line + def eot(self): # User force EOL if one hasn't occurred + if self.bytecount: + self._eot() + self.stream.write('\n') + + +def convert_image(img): + if options.resize: + img = img.resize((296, 128)) # resize + try: + enhancer = ImageEnhance.Contrast(img) + img = enhancer.enhance(2.0) + except ValueError: + pass + img = img.convert("1") # convert to black and white + return img + + +def write_stream(header, footer, ip_stream, op_stream): + op_stream.write(header) + op_stream.write('\n') + data = ip_stream.read() + bw_data = ByteWriter(op_stream, '_data') + bw_data.odata(data) + bw_data.eot() + op_stream.write(footer) + + +# create map of images based on input filenames +for input_filename in options.file: + with Image.open(input_filename) as img: + img = convert_image(img) + + image_name = Path(input_filename).stem + + w, h = img.size + + output_data = [~b & 0xff for b in list(img.tobytes())] + + if options.binary: + if options.out_dir is not None: + output_filename = (options.out_dir / image_name).with_suffix(".bin") + else: + output_filename = Path(input_filename).with_suffix(".bin") + print(f"Saving to {output_filename}, {w}x{h}") + with open(output_filename, "wb") as out: + out.write(bytearray(output_data)) + elif options.py: + if options.out_dir is not None: + output_filename = (options.out_dir / image_name).with_suffix(".py") + else: + output_filename = Path(input_filename).with_suffix(".py") + print(f"Saving to {output_filename}, {w}x{h}") + with open(output_filename, "w") as out: + write_stream(PY_HEADER, PY_FOOTER, io.BytesIO(bytes(output_data)), out) + else: + image_code = '''\ +static const uint8_t {image_name}[{count}] = {{ + {byte_data} +}}; + '''.format(image_name=image_name, count=len(output_data), byte_data=", ".join(str(b) for b in output_data)) + + print(image_code) diff --git a/scripts/logo.bin b/scripts/logo.bin new file mode 100644 index 0000000..7f056ec Binary files /dev/null and b/scripts/logo.bin differ diff --git a/scripts/logo.png b/scripts/logo.png new file mode 100644 index 0000000..61bd07f Binary files /dev/null and b/scripts/logo.png differ diff --git a/scripts/mariano.jpeg b/scripts/mariano.jpeg new file mode 100644 index 0000000..72887e0 Binary files /dev/null and b/scripts/mariano.jpeg differ diff --git a/scripts/vimar-logo.png b/scripts/vimar-logo.png new file mode 100644 index 0000000..a074d7b Binary files /dev/null and b/scripts/vimar-logo.png differ diff --git a/src/images/logo.bin b/src/images/logo.bin new file mode 100644 index 0000000..7f056ec Binary files /dev/null and b/src/images/logo.bin differ diff --git a/src/images/logo.png b/src/images/logo.png new file mode 100644 index 0000000..61bd07f Binary files /dev/null and b/src/images/logo.png differ diff --git a/src/launcher.py b/src/launcher.py index 912c12a..ea6eea6 100644 --- a/src/launcher.py +++ b/src/launcher.py @@ -34,13 +34,13 @@ def draw_about(): # logo image = bytearray(int(32 * 32 / 8)) - open("images/{}".format("census.bin"), "r").readinto(image) + open("images/{}".format("logo.bin"), "r").readinto(image) display.image(image, 32, 32, 86, 56) - pprint(display, "Engineering", 125, 56, 0) - pprint(display, "Offsite", 125, 66, 0) - pprint(display, "Brooklyn", 125, 76, 0) - pprint(display, "2022", 125, 86, 0) + pprint(display, "AWS Summit", 125, 56, 0) + pprint(display, "---", 125, 66, 0) + pprint(display, "Milan (Italy)", 125, 76, 0) + pprint(display, "2024", 125, 86, 0) def render(): display.pen(15) diff --git a/src/qrcodes/qrcode.txt b/src/qrcodes/qrcode.txt index 095097c..d69e622 100644 --- a/src/qrcodes/qrcode.txt +++ b/src/qrcodes/qrcode.txt @@ -1,8 +1,7 @@ -https://getcensus.com/ -Census -* the leading reverse ETL -* no more CSV files -* sync data in real-time +https://marianosciacco.it/publications/qrfuzz-paper/ +Mariano Sciacco +* IoT & Cloud Engineer +* Vimar S.p.A. +* (AWS Summit 2024) -Scan this code to learn -more about Census. \ No newline at end of file +If You’re Scanning This, It’s Too Late! \ No newline at end of file diff --git a/src/widgets.py b/src/widgets.py index ae96c08..e5b73c7 100644 --- a/src/widgets.py +++ b/src/widgets.py @@ -226,10 +226,10 @@ def draw_border(display): display.line(1, 1, 1, 127) display.line(1, 127, 295, 127) display.line(295, 1, 295, 127) - display.image(bytearray((0xff, 0xff, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0xc0)), 8, 8, 0, 0) + display.image(bytearray((0xff, 0xff, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0xc0)), 2, 2, 0, 0) display.image(bytearray((0xff, 0xff, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x03)), 8, 8, 288, 0) display.image(bytearray((0x03, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0xff, 0xff)), 8, 8, 288, 120) - display.image(bytearray((0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xff, 0xff)), 8, 8, 0, 120) + display.image(bytearray((0xc0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xff, 0xff)), 2, 2, 0, 120) def map_value(input, in_min, in_max, out_min, out_max): return (((input - in_min) * (out_max - out_min)) / (in_max - in_min)) + out_min