diff --git a/.github/workflows/githubci.yml b/.github/workflows/githubci.yml index 08266b81..d4281600 100644 --- a/.github/workflows/githubci.yml +++ b/.github/workflows/githubci.yml @@ -7,8 +7,7 @@ jobs: strategy: fail-fast: false matrix: - arduino-platform: ["cpb", "cpc", "cpx_ada", "esp32", "esp8266", "feather32u4", "feather_m0_express", "feather_m4_express", "feather_rp2040", "flora", "funhouse", "gemma", "gemma_m0", "hallowing_m0", "hallowing_m4_tinyusb", "magtag", "metro_m0", "metro_m0_tinyusb", "metro_m4", "metro_m4_tinyusb", "monster_m4sk", "monster_m4sk_tinyusb", "neokeytrinkey_m0", "neotrellis_m4", "nrf52832", "nrf52840", "protrinket_5v", "proxlighttrinkey_m0", "pybadge", "pygamer", "pyportal", "qt2040_trinkey", "qtpy_m0", "rotarytrinkey_m0", "slidetrinkey_m0", "trinket_m0", "uno", "trinket_5v" ] - # "trinket_5v", was removed + arduino-platform: ["cpb", "cpc", "cpx_ada", "esp32", "esp8266", "feather32u4", "feather_m0_express", "feather_m4_express", "feather_rp2040", "flora", "funhouse", "gemma", "gemma_m0", "hallowing_m0", "hallowing_m4_tinyusb", "magtag", "metro_m0", "metro_m0_tinyusb", "metro_m4", "metro_m4_tinyusb", "monster_m4sk", "monster_m4sk_tinyusb", "neokeytrinkey_m0", "neotrellis_m4", "nrf52832", "nrf52840", "protrinket_5v", "proxlighttrinkey_m0", "pybadge", "pygamer", "pyportal", "qt2040_trinkey", "qtpy_m0", "rotarytrinkey_m0", "slidetrinkey_m0", "trinket_m0", "uno", "trinket_5v", "ledglasses_nrf52840" ] runs-on: ubuntu-18.04 steps: @@ -39,6 +38,34 @@ jobs: - name: test platforms run: python3 ci/build_platform.py ${{ matrix.arduino-platform }} + - name: Upload build artifacts + uses: actions/upload-artifact@v2 + with: + name: ${{ github.event.repository.name }}.${{ github.sha }} + path: | + build/*.hex + build/*.bin + build/*.uf2 + + - name: Zip release files + if: startsWith(github.ref, 'refs/tags/') + run: | + if [ -d build ]; then + ( + echo "Built from Adafruit Learning System Guides `git describe --tags` for ${{ matrix.arduino-platform }}" + echo "Source code: https://github.com/adafruit/" + echo "Adafruit Learning System: https://learn.adafruit.com/" + ) > build/README.txt + cd build && zip -9 -o ${{ matrix.arduino-platform }}.zip *.hex *.bin *.uf2 *.txt + fi + + - name: Create release + if: startsWith(github.ref, 'refs/tags/') + uses: softprops/action-gh-release@v1 + with: + files: build/${{ matrix.arduino-platform }}.zip + fail_on_unmatched_files: false + body: "Select the zip file corresponding to your board from the list below." pylint: runs-on: ubuntu-latest diff --git a/3D_Printed_LED_Microphone_Flag/.circuitpython.skip b/3D_Printed_LED_Microphone_Flag/.circuitpython.skip deleted file mode 100644 index 672652b6..00000000 --- a/3D_Printed_LED_Microphone_Flag/.circuitpython.skip +++ /dev/null @@ -1 +0,0 @@ -3D_Printed_LED_Microphone_Flag/3D_Printed_LED_Microphone_Flag.py 137: Consider using tuple unpacking for swapping variables (consider-swap-variables) diff --git a/3D_Printed_LED_Microphone_Flag/.gemma_m0.generate b/3D_Printed_LED_Microphone_Flag/.gemma_m0.generate new file mode 100644 index 00000000..e69de29b diff --git a/3D_Printed_LED_Microphone_Flag/code.py b/3D_Printed_LED_Microphone_Flag/code.py index d9589020..38f1abda 100644 --- a/3D_Printed_LED_Microphone_Flag/code.py +++ b/3D_Printed_LED_Microphone_Flag/code.py @@ -124,9 +124,7 @@ def fscale(originalmin, originalmax, newbegin, newend, inputvalue, curve): def drawLine(fromhere, to): if fromhere > to: - fromheretemp = fromhere - fromhere = to - to = fromheretemp + to, fromhere = fromhere, to for index in range(fromhere, to): strip[index] = (0, 0, 0) diff --git a/3D_Printed_Unicorn_Horn/.gemma_m0.generate b/3D_Printed_Unicorn_Horn/.gemma_m0.generate new file mode 100644 index 00000000..e69de29b diff --git a/3D_Printed_Unicorn_Horn/.gemma_m0.test.only b/3D_Printed_Unicorn_Horn/.gemma_m0.test.only new file mode 100644 index 00000000..e69de29b diff --git a/Arduino_Ethernet_SD_Card/SDcardTest/SDcardTest.ino b/Arduino_Ethernet_SD_Card/SDcardTest/SDcardTest.ino index 18445c47..3b64c689 100644 --- a/Arduino_Ethernet_SD_Card/SDcardTest/SDcardTest.ino +++ b/Arduino_Ethernet_SD_Card/SDcardTest/SDcardTest.ino @@ -14,7 +14,7 @@ created 28 Mar 2011 by Limor Fried modified 9 Apr 2012 by Tom Igoe - modified 12 Apr 2018 by Mike Barela + modified 12 Apr 2018 by Anne Barela */ // include the SD library: #include diff --git a/Arduino_Ethernet_SD_Card/SDfileList/SDfileList.ino b/Arduino_Ethernet_SD_Card/SDfileList/SDfileList.ino index 0371075a..ed0b1b84 100644 --- a/Arduino_Ethernet_SD_Card/SDfileList/SDfileList.ino +++ b/Arduino_Ethernet_SD_Card/SDfileList/SDfileList.ino @@ -12,7 +12,7 @@ created Nov 2010 by David A. Mellis modified 9 Apr 2012 by Tom Igoe modified 2 Feb 2014 by Scott Fitzgerald - modified 12 Apr 2018 by Mike Barela + modified 12 Apr 2018 by Anne Barela This example code is in the public domain. diff --git a/CLUE_Rock_Paper_Scissors/advanced/clue-multi-rpsgame/code.py b/CLUE_Rock_Paper_Scissors/advanced/code.py similarity index 100% rename from CLUE_Rock_Paper_Scissors/advanced/clue-multi-rpsgame/code.py rename to CLUE_Rock_Paper_Scissors/advanced/code.py diff --git a/CLUE_Rock_Paper_Scissors/advanced/rps_advertisements/code.py b/CLUE_Rock_Paper_Scissors/advanced/rps_advertisements.py similarity index 100% rename from CLUE_Rock_Paper_Scissors/advanced/rps_advertisements/code.py rename to CLUE_Rock_Paper_Scissors/advanced/rps_advertisements.py diff --git a/CLUE_Rock_Paper_Scissors/advanced/rps_audio/code.py b/CLUE_Rock_Paper_Scissors/advanced/rps_audio.py similarity index 100% rename from CLUE_Rock_Paper_Scissors/advanced/rps_audio/code.py rename to CLUE_Rock_Paper_Scissors/advanced/rps_audio.py diff --git a/CLUE_Rock_Paper_Scissors/advanced/rps_comms/code.py b/CLUE_Rock_Paper_Scissors/advanced/rps_comms.py similarity index 100% rename from CLUE_Rock_Paper_Scissors/advanced/rps_comms/code.py rename to CLUE_Rock_Paper_Scissors/advanced/rps_comms.py diff --git a/CLUE_Rock_Paper_Scissors/advanced/rps_crypto/code.py b/CLUE_Rock_Paper_Scissors/advanced/rps_crypto.py similarity index 100% rename from CLUE_Rock_Paper_Scissors/advanced/rps_crypto/code.py rename to CLUE_Rock_Paper_Scissors/advanced/rps_crypto.py diff --git a/CLUE_Rock_Paper_Scissors/advanced/rps_crypto_chacha/code.py b/CLUE_Rock_Paper_Scissors/advanced/rps_crypto_chacha.py similarity index 100% rename from CLUE_Rock_Paper_Scissors/advanced/rps_crypto_chacha/code.py rename to CLUE_Rock_Paper_Scissors/advanced/rps_crypto_chacha.py diff --git a/CLUE_Rock_Paper_Scissors/advanced/rps_display/code.py b/CLUE_Rock_Paper_Scissors/advanced/rps_display.py similarity index 100% rename from CLUE_Rock_Paper_Scissors/advanced/rps_display/code.py rename to CLUE_Rock_Paper_Scissors/advanced/rps_display.py diff --git a/CPX_Marble_Maze/README.md b/CPX_Marble_Maze/README.md index 8182243d..0068ad53 100644 --- a/CPX_Marble_Maze/README.md +++ b/CPX_Marble_Maze/README.md @@ -13,7 +13,7 @@ Then you should be able to see the **CIRCUITPY** drive when connected via USB. CircuitPython resources are at https://CircuitPython.Org/ -Code written by Dano Wall and Mike Barela for Adafruit Industries. +Code written by Dano Wall and Anne Barela for Adafruit Industries. MIT License, please attribute. diff --git a/Chirping_Plush_Owl_Toy/Chirping_Plush_Owl_Toy.ino b/Chirping_Plush_Owl_Toy/Chirping_Plush_Owl_Toy.ino index e1378601..a76b4114 100644 --- a/Chirping_Plush_Owl_Toy/Chirping_Plush_Owl_Toy.ino +++ b/Chirping_Plush_Owl_Toy/Chirping_Plush_Owl_Toy.ino @@ -2,7 +2,7 @@ Chirp Owl written by Becky Stern and T Main for Adafruit Industries Tutorial: http://learn.adafruit.com/chirping-plush-owl-toy/ -Includes animal sounds by Mike Barela +Includes animal sounds by Anne Barela http://learn.adafruit.com/adafruit-trinket-modded-stuffed-animal/animal-sounds based in part on Debounce diff --git a/Chirping_Plush_Owl_Toy/code.py b/Chirping_Plush_Owl_Toy/code.py index 05f52bec..0605c34b 100644 --- a/Chirping_Plush_Owl_Toy/code.py +++ b/Chirping_Plush_Owl_Toy/code.py @@ -1,7 +1,7 @@ # Chirp Owl written by Becky Stern and T Main for Adafruit Industries # Tutorial: http://learn.adafruit.com/chirping-plush-owl-toy/ -# Includes animal sounds by Mike Barela +# Includes animal sounds by Anne Barela # http://learn.adafruit.com/adafruit-trinket-modded-stuffed-animal/animal-sounds # based in part on Debounce # created 21 November 2006 diff --git a/CircuitPython_Display_Text/colormask_example/code.py b/CircuitPython_Display_Text/colormask_example/code.py index f4ffffa8..519c689e 100644 --- a/CircuitPython_Display_Text/colormask_example/code.py +++ b/CircuitPython_Display_Text/colormask_example/code.py @@ -44,7 +44,7 @@ rainbow_bitmap = displayio.Bitmap( rainbow_palette = displayio.Palette(255) for i in range(0, 255): - rainbow_palette[i] = int("".join("%02x" % i for i in colorwheel(i)), 16) + rainbow_palette[i] = colorwheel(i) for y in range(rainbow_bitmap.height): for x in range(rainbow_bitmap.width): diff --git a/CircuitPython_Pico_PIO_Neopixel/neopio.py b/CircuitPython_Pico_PIO_Neopixel/neopio.py index a163c161..f3692708 100644 --- a/CircuitPython_Pico_PIO_Neopixel/neopio.py +++ b/CircuitPython_Pico_PIO_Neopixel/neopio.py @@ -1,7 +1,7 @@ # SPDX-FileCopyrightText: 2016 Damien P. George # SPDX-FileCopyrightText: 2017 Scott Shawcroft for Adafruit Industries # SPDX-FileCopyrightText: 2019 Carter Nelson -# SPDX-FileCopyrightText: 2019 Roy Hooper +# SPDX-FileCopyrightText: 2019 Rose Hooper # SPDX-FileCopyrightText: 2020 Jeff Epler # # SPDX-License-Identifier: MIT @@ -10,7 +10,7 @@ `neopio` - Neopixel strip driver using RP2040's PIO =================================================== -* Author(s): Damien P. George, Scott Shawcroft, Carter Nelson, Roy Hooper, Jeff Epler +* Author(s): Damien P. George, Scott Shawcroft, Carter Nelson, Rose Hooper, Jeff Epler """ import adafruit_pioasm diff --git a/CircuitPython_Simple_Wordclock/README.md b/CircuitPython_Simple_Wordclock/README.md index 430b87db..9d007bf3 100644 --- a/CircuitPython_Simple_Wordclock/README.md +++ b/CircuitPython_Simple_Wordclock/README.md @@ -14,7 +14,7 @@ Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from [Adafruit](https://www.adafruit.com)! -MIT license, designed and guide written by Dano Wall, code by Mike Barela +MIT license, designed and guide written by Dano Wall, code by Anne Barela All text above, and the splash screen below must be included in any redistribution diff --git a/CircuitPython_Simple_Wordclock/set_clock/code.py b/CircuitPython_Simple_Wordclock/set_clock/code.py index 4062e6aa..a11ddea1 100644 --- a/CircuitPython_Simple_Wordclock/set_clock/code.py +++ b/CircuitPython_Simple_Wordclock/set_clock/code.py @@ -1,5 +1,5 @@ # Write the time for the Adafruit DS3231 real-time clock. -# Limor Fried/Mike Barela for Adafruit Industries +# Limor Fried/Anne Barela for Adafruit Industries import time import board diff --git a/CircuitPython_Slideshow/README.md b/CircuitPython_Slideshow/README.md index e76386dc..12bf9581 100644 --- a/CircuitPython_Slideshow/README.md +++ b/CircuitPython_Slideshow/README.md @@ -10,7 +10,7 @@ Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from [Adafruit](https://www.adafruit.com)! -MIT license, guide written by Mike Barela, code by Limor Fried +MIT license, guide written by Anne Barela, code by Limor Fried All text above, and the splash screen below must be included in any redistribution diff --git a/CircuitPython_Templates/i2c_find_pins/code.py b/CircuitPython_Templates/i2c_find_pins/code.py index ddb6bea8..52bb1dd4 100644 --- a/CircuitPython_Templates/i2c_find_pins/code.py +++ b/CircuitPython_Templates/i2c_find_pins/code.py @@ -29,6 +29,10 @@ def get_unique_pins(): "LED", "SWITCH", "BUTTON", + "ACCELEROMETER_INTERRUPT", + "VOLTAGE_MONITOR", + "MICROPHONE_CLOCK", + "MICROPHONE_DATA", ] if p in dir(board) ] diff --git a/Circuit_Playground_Express_IR_Treasure_Hunt/CPX_Treasure/code.py b/Circuit_Playground_Express_IR_Treasure_Hunt/CPX_Treasure/code.py index e414c9c2..d689760f 100644 --- a/Circuit_Playground_Express_IR_Treasure_Hunt/CPX_Treasure/code.py +++ b/Circuit_Playground_Express_IR_Treasure_Hunt/CPX_Treasure/code.py @@ -1,6 +1,5 @@ import time import board -import pwmio import pulseio import adafruit_irremote import neopixel @@ -12,9 +11,8 @@ TRANSMIT_DELAY = 15 # change this as desired to affect game dynamics, or just l # Create NeoPixel object to indicate status pixels = neopixel.NeoPixel(board.NEOPIXEL, 10) -# Create a 'pwmio' output, to send infrared signals on the IR transmitter @ 38KHz -pwm = pwmio.PWMOut(board.IR_TX, frequency=38000, duty_cycle=2 ** 15) -pulseout = pulseio.PulseOut(pwm) +# Create a 'pulseio' output, to send infrared signals on the IR transmitter @ 38KHz +pulseout = pulseio.PulseOut(board.IR_TX, frequency=38000, duty_cycle=2 ** 15) # Create an encoder that will take numbers and turn them into IR pulses encoder = adafruit_irremote.GenericTransmit(header=[9500, 4500], diff --git a/Circuit_Playground_Express_IR_Zombie_Game/code.py b/Circuit_Playground_Express_IR_Zombie_Game/code.py index b80989a6..3322d3b2 100755 --- a/Circuit_Playground_Express_IR_Zombie_Game/code.py +++ b/Circuit_Playground_Express_IR_Zombie_Game/code.py @@ -1,6 +1,5 @@ import time import pulseio -import pwmio import board import adafruit_irremote import digitalio @@ -22,9 +21,8 @@ pulsein = pulseio.PulseIn(board.IR_RX, maxlen=120, idle_state=True) # Create a decoder that will take pulses and turn them into numbers decoder = adafruit_irremote.GenericDecode() -# Create a 'pwmio' output, to send infrared signals on the IR transmitter @ 38KHz -pwm = pwmio.PWMOut(board.IR_TX, frequency=38000, duty_cycle=2 ** 15) -pulseout = pulseio.PulseOut(pwm) +# Create a 'pulseio' output, to send infrared signals on the IR transmitter @ 38KHz +pulseout = pulseio.PulseOut(board.IR_TX, frequency=38000, duty_cycle=2 ** 15) # Create an encoder that will take numbers and turn them into NEC IR pulses encoder = adafruit_irremote.GenericTransmit(header=[9500, 4500], one=[550, 550], zero=[550, 1700], trail=0) diff --git a/Circuit_Playground_Express_LuckyCat/code.py b/Circuit_Playground_Express_LuckyCat/code.py index 4f6a3c2f..ecfe39ee 100644 --- a/Circuit_Playground_Express_LuckyCat/code.py +++ b/Circuit_Playground_Express_LuckyCat/code.py @@ -1,5 +1,5 @@ # Lucky Cat Maneki-neko with Circuit Playground Express -# Mike Barela for Adafruit Industries, MIT License +# Anne Barela for Adafruit Industries, MIT License import time import board diff --git a/Circuit_Playground_Express_and_IR/CPX_IR_CPX_transmit/code.py b/Circuit_Playground_Express_and_IR/CPX_IR_CPX_transmit/code.py index db9a5b66..524c4d0e 100644 --- a/Circuit_Playground_Express_and_IR/CPX_IR_CPX_transmit/code.py +++ b/Circuit_Playground_Express_and_IR/CPX_IR_CPX_transmit/code.py @@ -2,12 +2,10 @@ import time from adafruit_circuitplayground.express import cpx import adafruit_irremote import pulseio -import pwmio import board -# Create a 'pwmio' output, to send infrared signals on the IR transmitter @ 38KHz -pwm = pwmio.PWMOut(board.IR_TX, frequency=38000, duty_cycle=2 ** 15) -pulseout = pulseio.PulseOut(pwm) +# Create a 'pulseio' output, to send infrared signals on the IR transmitter @ 38KHz +pulseout = pulseio.PulseOut(board.IR_TX, frequency=38000, duty_cycle=2 ** 15) # Create an encoder that will take numbers and turn them into NEC IR pulses encoder = adafruit_irremote.GenericTransmit(header=[9500, 4500], one=[550, 550], zero=[550, 1700], trail=0) diff --git a/Cirecuit_Playground_Express_Pinata/code.py b/Cirecuit_Playground_Express_Pinata/code.py index c96b4f9a..d9d2e498 100644 --- a/Cirecuit_Playground_Express_Pinata/code.py +++ b/Cirecuit_Playground_Express_Pinata/code.py @@ -1,5 +1,5 @@ # Circuit Playground Express Piñata by Dano Wall for Adafruit Industries -# CircuitPython code by Mike Barela for Adafruit Industries, MIT License +# CircuitPython code by Anne Barela for Adafruit Industries, MIT License import time import random import board diff --git a/Close_Encounters_Hat/Close_Encounters_Hat.ino b/Close_Encounters_Hat/Close_Encounters_Hat.ino index d8039d59..1685f5dd 100644 --- a/Close_Encounters_Hat/Close_Encounters_Hat.ino +++ b/Close_Encounters_Hat/Close_Encounters_Hat.ino @@ -1,7 +1,7 @@ /* Close Encounters hat with 10 neopixels by Leslie Birch for Adafruit Industries. Notes play with each corresponding light. -Based on code by Becky Stern, Mike Barela and T Main for Adafruit Industries +Based on code by Becky Stern, Anne Barela and T Main for Adafruit Industries http://learn.adafruit.com/adafruit-trinket-modded-stuffed-animal/animal-sounds */ diff --git a/Crickit_CPX_Marionette/code.py b/Crickit_CPX_Marionette/code.py index 3fef7e5e..e96aa4ab 100644 --- a/Crickit_CPX_Marionette/code.py +++ b/Crickit_CPX_Marionette/code.py @@ -1,6 +1,6 @@ # CircuitPython for the Adafruit Learning System Tutorial # Universal Marionette Kit -# Project by Dano Wall, code by Mike Barela for Adafruit Industries +# Project by Dano Wall, code by Anne Barela for Adafruit Industries # MIT License import time from adafruit_crickit import crickit diff --git a/Crickit_Stumblebot/code.py b/Crickit_Stumblebot/code.py index 12c2d9d0..9dc17a22 100644 --- a/Crickit_Stumblebot/code.py +++ b/Crickit_Stumblebot/code.py @@ -1,6 +1,6 @@ # Stumble Bot, coded in CircuitPython # Using an Adafruit Circuit Playground Express, Crickit, and 2 servos -# Dano Wall, Mike Barela for Adafruit Industries, MIT License, May, 2018 +# Dano Wall, Anne Barela for Adafruit Industries, MIT License, May, 2018 # import time from digitalio import DigitalInOut, Direction, Pull diff --git a/Crickit_microbit_MicroPython/main.py b/Crickit_microbit_MicroPython/main.py index 2557c0a4..770ff1c7 100644 --- a/Crickit_microbit_MicroPython/main.py +++ b/Crickit_microbit_MicroPython/main.py @@ -1,6 +1,6 @@ # main.py - code to test the Adafruit CRICKIT board with # the BBC micro:bit and MicroPython (NOT CircuitPython) -# MIT License by Limor Fried and Mike Barela, 2019 +# MIT License by Limor Fried and Anne Barela, 2019 # This code requires the seesaw.py module as a driver import time import seesaw diff --git a/EyeLights_Accelerometer_Tap/EyeLights_Accelerometer_Tap/.ledglasses_nrf52840.generate b/EyeLights_Accelerometer_Tap/EyeLights_Accelerometer_Tap/.ledglasses_nrf52840.generate new file mode 100644 index 00000000..e69de29b diff --git a/EyeLights_Accelerometer_Tap/EyeLights_Accelerometer_Tap/.ledglasses_nrf52840.test.only b/EyeLights_Accelerometer_Tap/EyeLights_Accelerometer_Tap/.ledglasses_nrf52840.test.only new file mode 100644 index 00000000..e69de29b diff --git a/EyeLights_Accelerometer_Tap/EyeLights_Accelerometer_Tap/EyeLights_Accelerometer_Tap.ino b/EyeLights_Accelerometer_Tap/EyeLights_Accelerometer_Tap/EyeLights_Accelerometer_Tap.ino new file mode 100644 index 00000000..ab8a762f --- /dev/null +++ b/EyeLights_Accelerometer_Tap/EyeLights_Accelerometer_Tap/EyeLights_Accelerometer_Tap.ino @@ -0,0 +1,136 @@ +// SPDX-FileCopyrightText: 2021 Phil Burgess for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +/* +ACCELEROMETER INPUT DEMO: while the LED Glasses Driver has a perfectly +good clicky button for input, this code shows how one might instead use +the onboard accelerometer for interactions*. + +Worn normally, the LED rings are simply lit a solid color. +TAP the eyeglass frames to cycle among a list of available colors. +LOOK DOWN to light the LED rings bright white -- for navigating steps +or finding the right key. LOOK BACK UP to return to solid color. +This uses only the rings, not the matrix portion. + +* Like, if you have big ol' monster hands, that little button can be + hard to click, y'know? +*/ + +#include // For LED driver +#include // For accelerometer +#include // For m/s^2 accel units + +Adafruit_LIS3DH accel; +Adafruit_EyeLights_buffered glasses; // Buffered for smooth animation + +// Here's a list of colors that we cycle through when tapped, specified +// as {R,G,B} values from 0-255. These are intentionally a bit dim -- +// both to save battery and to make the "ground light" mode more dramatic. +// Rather than primary color red/green/blue sequence which is just so +// over-done at this point, let's use some HALLOWEEN colors! +uint8_t colors[][3] = { + {27, 9, 0}, // Orange + {12, 0, 24}, // Purple + {5, 31, 0}, // Green +}; +#define NUM_COLORS (sizeof colors / sizeof colors[0]) // List length +uint8_t looking_down_color[] = {255, 255, 255}; // Max white + +uint8_t color_index = 0; // Begin at first color in list +uint8_t *target_color; // Pointer to color we're aiming for +float interpolated_color[] = {0.0, 0.0, 0.0}; // Current color along the way +float filtered_y; // De-noised accelerometer reading +bool looking_down; // Set true when glasses are oriented downward +sensors_event_t event; // For accelerometer conversion +uint32_t last_tap_time = 0; // For accelerometer tap de-noising + +// Crude error handler, prints message to Serial console, flashes LED +void err(char *str, uint8_t hz) { + Serial.println(str); + pinMode(LED_BUILTIN, OUTPUT); + for (;;) digitalWrite(LED_BUILTIN, (millis() * hz / 500) & 1); +} + +void setup() { // Runs once at program start... + + // Initialize hardware + Serial.begin(115200); + if (! accel.begin()) err("LIS3DH not found", 5); + if (! glasses.begin()) err("IS3741 not found", 2); + + // Configure accelerometer and get initial state + accel.setClick(1, 100); // Set threshold for single tap + accel.getEvent(&event); // Current accel in m/s^2 + // Check accelerometer to see if we've started in the looking-down state, + // set the target color (what we're aiming for) appropriately. Only the + // Y axis is needed for this. + filtered_y = event.acceleration.y; + looking_down = (filtered_y > 5.0); + // If initially looking down, aim for the look-down color, + // else aim for the first item in the color list. + target_color = looking_down ? looking_down_color : colors[color_index]; + + // Configure glasses for max brightness, enable output + glasses.setLEDscaling(0xFF); + glasses.setGlobalCurrent(0xFF); + glasses.enable(true); +} + +void loop() { // Repeat forever... + + // interpolated_color blends from the prior to the next ("target") + // LED ring colors, with a pleasant ease-out effect. + for(uint8_t i=0; i<3; i++) { // R, G, B + interpolated_color[i] = interpolated_color[i] * 0.97 + target_color[i] * 0.03; + } + // Convert separate red, green, blue to "packed" 24-bit RGB value + uint32_t rgb = ((int)interpolated_color[0] << 16) | + ((int)interpolated_color[1] << 8) | + (int)interpolated_color[2]; + // Fill both rings with packed color, then refresh the LEDs. + glasses.left_ring.fill(rgb); + glasses.right_ring.fill(rgb); + glasses.show(); + + // The look-down detection only needs the accelerometer's Y axis. + // This works with the Glasses Driver mounted on either temple, + // with the glasses arms "open" (as when worn). + accel.getEvent(&event); + // Smooth the accelerometer reading the same way RGB colors are + // interpolated. This avoids false triggers from jostling around. + filtered_y = filtered_y * 0.97 + event.acceleration.y * 0.03; + + // The threshold between "looking down" and "looking up" depends + // on which of those states we're currently in. This is an example + // of hysteresis in software...a change of direction requires a + // little extra push before it takes, which avoids oscillating if + // there was just a single threshold both ways. + if (looking_down) { // Currently in the looking-down state... + (void)accel.getClick(); // Discard any taps while looking down + if (filtered_y < 3.5) { // Have we crossed the look-up threshold? + target_color = colors[color_index]; // Back to list color + looking_down = false; // We're looking up now! + } + } else { // Currently in the looking-up state... + if (filtered_y > 5.0) { // Crossed the look-down threshold? + target_color = looking_down_color; // Aim for white + looking_down = true; // We're looking down now! + } else if (accel.getClick()) { + // No look up/down change, but the accelerometer registered + // a tap. Compare this against the last time we sensed one, + // and only do things if it's been more than half a second. + // This avoids spurious double-taps that can occur no matter + // how carefully the tap threshold was set. + uint32_t now = millis(); + uint32_t elapsed = now - last_tap_time; + if (elapsed > 500) { + // A good tap was detected. Cycle to the next color in + // the list and note the time of this tap. + color_index = (color_index + 1) % NUM_COLORS; + target_color = colors[color_index]; + last_tap_time = now; + } + } + } +} diff --git a/EyeLights_Accelerometer_Tap/code.py b/EyeLights_Accelerometer_Tap/EyeLights_Accelerometer_Tap_CircuitPython/code.py similarity index 93% rename from EyeLights_Accelerometer_Tap/code.py rename to EyeLights_Accelerometer_Tap/EyeLights_Accelerometer_Tap_CircuitPython/code.py index ed98bba4..87647dfd 100644 --- a/EyeLights_Accelerometer_Tap/code.py +++ b/EyeLights_Accelerometer_Tap/EyeLights_Accelerometer_Tap_CircuitPython/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2021 Phil Burgess for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ ACCELEROMETER INPUT DEMO: while the LED Glasses Driver has a perfectly good clicky button for input, this code shows how one might instead use @@ -50,14 +54,6 @@ target_color = (255, 255, 255) if looking_down else colors[color_index] interpolated_color = (0, 0, 0) # LEDs off at startup, they'll ramp up -def fill_color(color): - """Given an (R,G,B) tuple, fill both LED rings with this color.""" - # Convert tuple to a 'packed' 24-bit value - packed = (int(color[0]) << 16) | (int(color[1]) << 8) | int(color[2]) - for i in range(24): - glasses.left_ring[i] = glasses.right_ring[i] = packed - - while True: # Loop forever... # The try/except here is because VERY INFREQUENTLY the I2C bus will @@ -75,7 +71,14 @@ while True: # Loop forever... interpolated_color[2] * 0.85 + target_color[2] * 0.15, ) # Fill both rings with interpolated_color, then refresh the LEDs. - fill_color(interpolated_color) + # fill_color(interpolated_color) + packed = ( + (int(interpolated_color[0]) << 16) + | (int(interpolated_color[1]) << 8) + | int(interpolated_color[2]) + ) + glasses.left_ring.fill(packed) + glasses.right_ring.fill(packed) glasses.show() # The look-down detection only needs the accelerometer's Y axis. diff --git a/EyeLights_Audio_Spectrum/EyeLights_Audio_Spectrum/.ledglasses_nrf52840.generate b/EyeLights_Audio_Spectrum/EyeLights_Audio_Spectrum/.ledglasses_nrf52840.generate new file mode 100644 index 00000000..e69de29b diff --git a/EyeLights_Audio_Spectrum/EyeLights_Audio_Spectrum/.ledglasses_nrf52840.test.only b/EyeLights_Audio_Spectrum/EyeLights_Audio_Spectrum/.ledglasses_nrf52840.test.only new file mode 100644 index 00000000..e69de29b diff --git a/EyeLights_Audio_Spectrum/EyeLights_Audio_Spectrum/EyeLights_Audio_Spectrum.ino b/EyeLights_Audio_Spectrum/EyeLights_Audio_Spectrum/EyeLights_Audio_Spectrum.ino new file mode 100644 index 00000000..729275af --- /dev/null +++ b/EyeLights_Audio_Spectrum/EyeLights_Audio_Spectrum/EyeLights_Audio_Spectrum.ino @@ -0,0 +1,239 @@ +// SPDX-FileCopyrightText: 2021 Phil Burgess for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +/* +AUDIO SPECTRUM LIGHT SHOW for Adafruit EyeLights (LED Glasses + Driver). +Uses onboard microphone and a lot of math to react to music. +REQUIRES Adafruit_ZeroFFT LIBRARY, install via Arduino Library manager. +*/ + +#include // For LED driver +#include // For microphone +#include // For math + +// FFT/SPECTRUM CONFIG ---- + +#define NUM_SAMPLES 512 // Audio & FFT buffer, MUST be a power of two +#define SPECTRUM_SIZE (NUM_SAMPLES / 2) // Output spectrum is 1/2 of FFT output +// Bottom of spectrum tends to be noisy, while top often exceeds musical +// range and is just harmonics, so clip both ends off: +#define LOW_BIN 5 // Lowest bin of spectrum that contributes to graph +#define HIGH_BIN 150 // Highest bin " + +// GLOBAL VARIABLES ------- + +Adafruit_EyeLights_buffered glasses; // LED matrix is buffered for smooth animation +extern PDMClass PDM; // Microphone +short audio_buf[3][NUM_SAMPLES]; // Audio input buffers, 16-bit signed +uint8_t active_buf = 0; // Buffer # into which audio is currently recording +volatile int samples_read = 0; // # of samples read into current buffer thus far +volatile bool mic_on = false; // true when reading from mic, false when full/stopped +float spectrum[SPECTRUM_SIZE]; // FFT results are stored & further processed here +float dynamic_level = 10.0; // For adapting to changing audio volume +int frames; // For frames-per-second calculation +uint32_t start_time; // Ditto + +struct { // Values associated with each column of the matrix + int first_bin; // First spectrum bin index affecting column + int num_bins; // Number of spectrum bins affecting column + float *bin_weights; // List of spectrum bin weightings + uint32_t color; // GFX-style 'RGB565' color for column + float top; // Current column top position + float dot; // Current column 'falling dot' position + float velocity; // Current velocity of falling dot +} column_table[18]; + +// Crude error handler, prints message to Serial console, flashes LED +void err(char *str, uint8_t hz) { + Serial.println(str); + pinMode(LED_BUILTIN, OUTPUT); + for (;;) digitalWrite(LED_BUILTIN, (millis() * hz / 500) & 1); +} + +void setup() { // Runs once at program start... + + Serial.begin(115200); + //while(!Serial); + if (! glasses.begin()) err("IS3741 not found", 2); + + // FFT/SPECTRUM SETUP ----- + + uint8_t spectrum_bits = (int)log2f((float)SPECTRUM_SIZE); // e.g. 8 = 256 bin spectrum + // Scale LOW_BIN and HIGH_BIN to 0.0 to 1.0 equivalent range in spectrum + float low_frac = log2f((float)LOW_BIN) / (float)spectrum_bits; + float frac_range = log2((float)HIGH_BIN) / (float)spectrum_bits - low_frac; + // Serial.printf("%d %f %f\n", spectrum_bits, low_frac, frac_range); + + // To keep the display lively, tables are precomputed where each column of + // the matrix (of which there are few) is the sum value and weighting of + // several bins from the FFT spectrum output (of which there are many). + // The tables also help visually linearize the output so octaves are evenly + // spaced, as on a piano keyboard, whereas the source spectrum data is + // spaced by frequency in Hz. + + for (int column=0; column<18; column++) { + // Determine the lower and upper frequency range for this column, as + // fractions within the scaled 0.0 to 1.0 spectrum range. 0.95 below + // creates slight frequency overlap between columns, looks nicer. + float lower = low_frac + frac_range * ((float)column / 18.0 * 0.95); + float upper = low_frac + frac_range * ((float)(column + 1) / 18.0); + float mid = (lower + upper) * 0.5; // Center of lower-to-upper range + float half_width = (upper - lower) * 0.5 + 1e-2; // 1/2 of lower-to-upper range + // Map fractions back to spectrum bin indices that contribute to column + int first_bin = int(pow(2, (float)spectrum_bits * lower) + 1e-4); + int last_bin = int(pow(2, (float)spectrum_bits * upper) + 1e-4); + //Serial.printf("%d %d %d\n", column, first_bin, last_bin); + float total_weight = 0.0; // Accumulate weight for this bin + int num_bins = last_bin - first_bin + 1; + // Allocate space for bin weights for column, stop everything if out of RAM. + column_table[column].bin_weights = (float *)malloc(num_bins * sizeof(float)); + if (column_table[column].bin_weights == NULL) err("Malloc fail", 10); + for (int bin_index = first_bin; bin_index <= last_bin; bin_index++) { + // Find distance from column's overall center to individual bin's + // center, expressed as 0.0 (bin at center) to 1.0 (bin at limit of + // lower-to-upper range). + float bin_center = log2f((float)bin_index + 0.5) / (float)spectrum_bits; + float dist = fabs(bin_center - mid) / half_width; + if (dist < 1.0) { // Filter out a few math stragglers at either end + // Bin weights have a cubic falloff curve within range: + dist = 1.0 - dist; // Invert dist so 1.0 is at center + float bin_weight = (((3.0 - (dist * 2.0)) * dist) * dist); + column_table[column].bin_weights[bin_index - first_bin] = bin_weight; + total_weight += bin_weight; + } + } + //Serial.println(column); + // Scale bin weights so total is 1.0 for each column, but then mute + // lower columns slightly and boost higher columns. It graphs better. + for (int i=0; i 0) ? log((float)audio_data[i]) : 0.0; + } + + // Find min & max range of spectrum bin values, with limits. + float lower = spectrum[LOW_BIN], upper = spectrum[LOW_BIN]; + for (int i=LOW_BIN+1; i<=HIGH_BIN; i++) { + if (spectrum[i] < lower) lower = spectrum[i]; + if (spectrum[i] > upper) upper = spectrum[i]; + } + //Serial.printf("%f %f\n", lower, upper); + if (upper < 2.5) upper = 2.5; + + // Adjust dynamic level to current spectrum output, keeps the graph + // 'lively' as ambient volume changes. Sparkle but don't saturate. + if (upper > dynamic_level) { + // Got louder. Move level up quickly but allow initial "bump." + dynamic_level = dynamic_level * 0.5 + upper * 0.5; + } else { + // Got quieter. Ease level down, else too many bumps. + dynamic_level = dynamic_level * 0.75 + lower * 0.25; + } + + // Apply vertical scale to spectrum data. Results may exceed + // matrix height...that's OK, adds impact! + float scale = 15.0 / (dynamic_level - lower); + for (int i=LOW_BIN; i<=HIGH_BIN; i++) { + spectrum[i] = (spectrum[i] - lower) * scale; + } + + // Clear screen, filter and draw each column of the display... + glasses.fill(0); + for(int column=0; column<18; column++) { + int first_bin = column_table[column].first_bin; + // Start BELOW matrix and accumulate bin weights UP, saves math + float column_top = 7.0; + for (int bin_offset=0; bin_offset= NUM_SAMPLES) { // Buffer full? + mic_on = false; // Stop and + samples_read = 0; // reset counter for next time + } + } else { + // Mic is off (code is busy) - must read but discard data. + // audio_buf[2] is a 'bit bucket' for this. + PDM.read(audio_buf[2], bytes_to_read); + } + } +} diff --git a/EyeLights_Audio_Spectrum/code.py b/EyeLights_Audio_Spectrum/EyeLights_Audio_Spectrum_CircuitPython/code.py similarity index 98% rename from EyeLights_Audio_Spectrum/code.py rename to EyeLights_Audio_Spectrum/EyeLights_Audio_Spectrum_CircuitPython/code.py index e3027f70..0ec5cb2a 100755 --- a/EyeLights_Audio_Spectrum/code.py +++ b/EyeLights_Audio_Spectrum/EyeLights_Audio_Spectrum_CircuitPython/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2021 Phil Burgess for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ AUDIO SPECTRUM LIGHT SHOW for Adafruit EyeLights (LED Glasses + Driver). Uses onboard microphone and a lot of math to react to music. diff --git a/EyeLights_BMP_Animation/code.py b/EyeLights_BMP_Animation/code.py new file mode 100755 index 00000000..f49412ec --- /dev/null +++ b/EyeLights_BMP_Animation/code.py @@ -0,0 +1,64 @@ +# SPDX-FileCopyrightText: 2021 Phil Burgess for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +""" +EyeLightsAnim example for Adafruit EyeLights (LED Glasses + Driver). +The accompanying eyelights_anim.py provides pre-drawn frame-by-frame +animation from BMP images. Sort of a catch-all for modest projects that may +want to implement some animation without having to express that animation +entirely in code. The idea is based upon two prior projects: + +https://learn.adafruit.com/32x32-square-pixel-display/overview +learn.adafruit.com/circuit-playground-neoanim-using-bitmaps-to-animate-neopixels + +The 18x5 matrix and the LED rings are regarded as distinct things, fed from +two separate BMPs (or can use just one or the other). The former guide above +uses the vertical axis for time (like a strip of movie film), while the +latter uses the horizontal axis for time (as in audio or video editing). +Despite this contrast, the same conventions are maintained here to avoid +conflicting explanations...what worked in those guides is what works here, +only the resolutions are different. See also the example BMPs. +""" + +import time +import board +from busio import I2C +import adafruit_is31fl3741 +from adafruit_is31fl3741.adafruit_ledglasses import LED_Glasses +from eyelights_anim import EyeLightsAnim + + +# HARDWARE SETUP ----------------------- + +i2c = I2C(board.SCL, board.SDA, frequency=1000000) + +# Initialize the IS31 LED driver, buffered for smoother animation +glasses = LED_Glasses(i2c, allocate=adafruit_is31fl3741.MUST_BUFFER) +glasses.show() # Clear any residue on startup +glasses.global_current = 20 # Just middlin' bright, please + + +# ANIMATION SETUP ---------------------- + +# Two indexed-color BMP filenames are specified: first is for the LED matrix +# portion, second is for the LED rings -- or pass None for one or the other +# if not animating that part. The two elements, matrix and rings, share a +# few LEDs in common...by default the rings appear "on top" of the matrix, +# or you can optionally pass a third argument of False to have the rings +# underneath. There's that one odd unaligned pixel between the two though, +# so this may only rarely be desirable. +anim = EyeLightsAnim(glasses, "matrix.bmp", "rings.bmp") + + +# MAIN LOOP ---------------------------- + +# This example just runs through a repeating cycle. If you need something +# else, like ping-pong animation, or frames based on a specific time, the +# anim.frame() function can optionally accept two arguments: an index for +# the matrix animation, and an index for the rings. + +while True: + anim.frame() # Advance matrix and rings by 1 frame and wrap around + glasses.show() # Update LED matrix + time.sleep(0.02) # Pause briefly diff --git a/EyeLights_BMP_Animation/eyelights_anim.py b/EyeLights_BMP_Animation/eyelights_anim.py new file mode 100755 index 00000000..e8e6780c --- /dev/null +++ b/EyeLights_BMP_Animation/eyelights_anim.py @@ -0,0 +1,145 @@ +# SPDX-FileCopyrightText: 2021 Phil Burgess for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +""" +EyeLightsAnim provides EyeLights LED glasses with pre-drawn frame-by-frame +animation from BMP images. Sort of a catch-all for modest projects that may +want to implement some animation without having to express that animation +entirely in code. The idea is based upon two prior projects: + +https://learn.adafruit.com/32x32-square-pixel-display/overview +learn.adafruit.com/circuit-playground-neoanim-using-bitmaps-to-animate-neopixels + +The 18x5 matrix and the LED rings are regarded as distinct things, fed from +two separate BMPs (or can use just one or the other). The former guide above +uses the vertical axis for time (like a strip of movie film), while the +latter uses the horizontal axis for time (as in audio or video editing). +Despite this contrast, the same conventions are maintained here to avoid +conflicting explanations...what worked in those guides is what works here, +only the resolutions are different.""" + +import displayio +import adafruit_imageload + + +def gamma_adjust(palette): + """Given a color palette that was returned by adafruit_imageload, apply + gamma correction and place results back in original palette. This makes + LED brightness and colors more perceptually linear, to better match how + the source BMP might've appeared on screen.""" + + for index, entry in enumerate(palette): + palette[index] = sum( + [ + int(((((entry >> shift) & 0xFF) / 255) ** 2.6) * 255 + 0.5) << shift + for shift in range(16, -1, -8) + ] + ) + + +class EyeLightsAnim: + """Class encapsulating BMP image-based frame animation for the matrix + and rings of an LED_Glasses object.""" + + def __init__(self, glasses, matrix_filename, ring_filename, rings_on_top=True): + """Constructor for EyeLightsAnim. Accepts an LED_Glasses object and + filenames for two indexed-color BMP images: first is a "sprite + sheet" for animating on the matrix portion of the glasses, second is + a pixels-over-time graph for the rings portion. Either filename may + be None if not used. Because the matrix and rings share some pixels + in common, the last argument determines the "stacking order" - which + of the two bitmaps is drawn later or "on top." Default of True + places the rings over the matrix, False gives the matrix priority. + It's possible to use transparent palette indices but that may be + more trouble than it's worth.""" + + self.glasses = glasses + self.matrix_bitmap = self.ring_bitmap = None + self.rings_on_top = rings_on_top + + if matrix_filename: + self.matrix_bitmap, self.matrix_palette = adafruit_imageload.load( + matrix_filename, bitmap=displayio.Bitmap, palette=displayio.Palette + ) + if (self.matrix_bitmap.width < glasses.width) or ( + self.matrix_bitmap.height < glasses.height + ): + raise ValueError("Matrix bitmap must be at least 18x5 pixels") + gamma_adjust(self.matrix_palette) + self.tiles_across = self.matrix_bitmap.width // glasses.width + self.tiles_down = self.matrix_bitmap.height // glasses.height + self.matrix_frames = self.tiles_across * self.tiles_down + self.matrix_frame = self.matrix_frames - 1 + + if ring_filename: + self.ring_bitmap, self.ring_palette = adafruit_imageload.load( + ring_filename, bitmap=displayio.Bitmap, palette=displayio.Palette + ) + if self.ring_bitmap.height < 48: + raise ValueError("Ring bitmap must be at least 48 pixels tall") + gamma_adjust(self.ring_palette) + self.ring_frames = self.ring_bitmap.width + self.ring_frame = self.ring_frames - 1 + + def draw_matrix(self, matrix_frame=None): + """Draw the matrix portion of EyeLights from one frame of the matrix + bitmap "sprite sheet." Can either request a specific frame index + (starting from 0), or pass None (or no arguments) to advance by one + frame, "wrapping around" to beginning if needed. For internal use by + library; user code should call frame(), not this function.""" + + if matrix_frame: # Go to specific frame + self.matrix_frame = matrix_frame + else: # Advance one frame forward + self.matrix_frame += 1 + self.matrix_frame %= self.matrix_frames # Wrap to valid range + + xoffset = self.matrix_frame % self.tiles_across * self.glasses.width + yoffset = self.matrix_frame // self.tiles_across * self.glasses.height + + for y in range(self.glasses.height): + y1 = y + yoffset + for x in range(self.glasses.width): + idx = self.matrix_bitmap[x + xoffset, y1] + if not self.matrix_palette.is_transparent(idx): + self.glasses.pixel(x, y, self.matrix_palette[idx]) + + def draw_rings(self, ring_frame=None): + """Draw the rings portion of EyeLights from one frame of the rings + bitmap graph. Can either request a specific frame index (starting + from 0), or pass None (or no arguments) to advance by one frame, + 'wrapping around' to beginning if needed. For internal use by + library; user code should call frame(), not this function.""" + + if ring_frame: # Go to specific frame + self.ring_frame = ring_frame + else: # Advance one frame forward + self.ring_frame += 1 + self.ring_frame %= self.ring_frames # Wrap to valid range + + for y in range(24): + idx = self.ring_bitmap[self.ring_frame, y] + if not self.ring_palette.is_transparent(idx): + self.glasses.left_ring[y] = self.ring_palette[idx] + idx = self.ring_bitmap[self.ring_frame, y + 24] + if not self.ring_palette.is_transparent(idx): + self.glasses.right_ring[y] = self.ring_palette[idx] + + def frame(self, matrix_frame=None, ring_frame=None): + """Draw one frame of animation to the matrix and/or rings portions + of EyeLights. Frame index (starting from 0) for matrix and rings + respectively can be passed as arguments, or either/both may be None + to advance by one frame, 'wrapping around' to beginning if needed. + Because some pixels are shared in common between matrix and rings, + the "stacking order" -- which of the two appears "on top", is + specified as an argument to the constructor.""" + + if self.matrix_bitmap and self.rings_on_top: + self.draw_matrix(matrix_frame) + + if self.ring_bitmap: + self.draw_rings(ring_frame) + + if self.matrix_bitmap and not self.rings_on_top: + self.draw_matrix(matrix_frame) diff --git a/EyeLights_BMP_Animation/matrix.bmp b/EyeLights_BMP_Animation/matrix.bmp new file mode 100755 index 00000000..d497da88 Binary files /dev/null and b/EyeLights_BMP_Animation/matrix.bmp differ diff --git a/EyeLights_BMP_Animation/rings.bmp b/EyeLights_BMP_Animation/rings.bmp new file mode 100755 index 00000000..ae010bbe Binary files /dev/null and b/EyeLights_BMP_Animation/rings.bmp differ diff --git a/EyeLights_Blinky_Eyes/EyeLights_Blinky_Eyes/.ledglasses_nrf52840.test.only b/EyeLights_Blinky_Eyes/EyeLights_Blinky_Eyes/.ledglasses_nrf52840.test.only new file mode 100644 index 00000000..e69de29b diff --git a/EyeLights_Blinky_Eyes/EyeLights_Blinky_Eyes/EyeLights_Blinky_Eyes.ino b/EyeLights_Blinky_Eyes/EyeLights_Blinky_Eyes/EyeLights_Blinky_Eyes.ino new file mode 100644 index 00000000..f145a0ad --- /dev/null +++ b/EyeLights_Blinky_Eyes/EyeLights_Blinky_Eyes/EyeLights_Blinky_Eyes.ino @@ -0,0 +1,326 @@ +// SPDX-FileCopyrightText: 2021 Phil Burgess for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +/* +MOVE-AND-BLINK EYES for Adafruit EyeLights (LED Glasses + Driver). + +I'd written a very cool squash-and-stretch effect for the eye movement, +but unfortunately the resolution is such that the pupils just look like +circles regardless. I'm keeping it in despite the added complexity, +because this WILL look great later on a bigger matrix or a TFT/OLED, +and this way the hard parts won't require a re-write at such time. +It's a really adorable effect with enough pixels. +*/ + +#include // For LED driver + +// CONFIGURABLES ------------------------ + +#define RADIUS 3.4 // Size of pupil (3X because of downsampling later) + +uint8_t eye_color[3] = { 255, 128, 0 }; // Amber pupils +uint8_t ring_open_color[3] = { 75, 75, 75 }; // Color of LED rings when eyes open +uint8_t ring_blink_color[3] = { 50, 25, 0 }; // Color of LED ring "eyelid" when blinking + +// Some boards have just one I2C interface, but some have more... +TwoWire *i2c = &Wire; // e.g. change this to &Wire1 for QT Py RP2040 + +// GLOBAL VARIABLES --------------------- + +Adafruit_EyeLights_buffered glasses(true); // Buffered spex + 3X canvas +GFXcanvas16 *canvas; // Pointer to canvas object + +// Reading through the code, you'll see a lot of references to this "3X" +// space. This is referring to the glasses' optional "offscreen" drawing +// canvas that's 3 times the resolution of the LED matrix (i.e. 15 pixels +// tall instead of 5), which gets scaled down to provide some degree of +// antialiasing. It's why the pupils have soft edges and can make +// fractional-pixel motions. + +float cur_pos[2] = { 9.0, 7.5 }; // Current position of eye in canvas space +float next_pos[2] = { 9.0, 7.5 }; // Next position " +bool in_motion = false; // true = eyes moving, false = eyes paused +uint8_t blink_state = 0; // 0, 1, 2 = unblinking, closing, opening +uint32_t move_start_time = 0; // For animation timekeeping +uint32_t move_duration = 0; +uint32_t blink_start_time = 0; +uint32_t blink_duration = 0; +float y_pos[13]; // Coords of LED ring pixels in canvas space +uint32_t ring_open_color_packed; // ring_open_color[] as packed RGB integer +uint16_t eye_color565; // eye_color[] as a GFX packed '565' value +uint32_t frames = 0; // For frames-per-second calculation +uint32_t start_time; + +// These offsets position each pupil on the canvas grid and make them +// fixate slightly (converge on a point) so they're not always aligned +// the same on the pixel grid, which would be conspicuously pixel-y. +float x_offset[2] = { 5.0, 31.0 }; +// These help perform x-axis clipping on the rasterized ellipses, +// so they don't "bleed" outside the rings and require erasing. +int box_x_min[2] = { 3, 33 }; +int box_x_max[2] = { 21, 51 }; + +#define GAMMA 2.6 // For color correction, shouldn't need changing + + +// HELPER FUNCTIONS --------------------- + +// Crude error handler, prints message to Serial console, flashes LED +void err(char *str, uint8_t hz) { + Serial.println(str); + pinMode(LED_BUILTIN, OUTPUT); + for (;;) digitalWrite(LED_BUILTIN, (millis() * hz / 500) & 1); +} + +// Given an [R,G,B] color, apply gamma correction, return packed RGB integer. +uint32_t gammify(uint8_t color[3]) { + uint32_t rgb[3]; + for (uint8_t i=0; i<3; i++) { + rgb[i] = uint32_t(pow((float)color[i] / 255.0, GAMMA) * 255 + 0.5); + } + return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2]; +} + +// Given two [R,G,B] colors and a blend ratio (0.0 to 1.0), interpolate between +// the two colors and return a gamma-corrected in-between color as a packed RGB +// integer. No bounds clamping is performed on blend value, be nice. +uint32_t interp(uint8_t color1[3], uint8_t color2[3], float blend) { + float inv = 1.0 - blend; // Weighting of second color + uint8_t rgb[3]; + for(uint8_t i=0; i<3; i++) { + rgb[i] = (int)((float)color1[i] * blend + (float)color2[i] * inv); + } + return gammify(rgb); +} + +// Rasterize an arbitrary ellipse into the offscreen 3X canvas, given +// foci point1 and point2 and with area determined by global RADIUS +// (when foci are same point; a circle). Foci and radius are all +// floating point values, which adds to the buttery impression. 'rect' +// is a bounding rect of which pixels are likely affected. Canvas is +// assumed cleared before arriving here. +void rasterize(float point1[2], float point2[2], int rect[4]) { + float perimeter, d; + float dx = point2[0] - point1[0]; + float dy = point2[1] - point1[1]; + float d2 = dx * dx + dy * dy; // Dist between foci, squared + if (d2 <= 0.0) { + // Foci are in same spot - it's a circle + perimeter = 2.0 * RADIUS; + d = 0.0; + } else { + // Foci are separated - it's an ellipse. + d = sqrt(d2); // Distance between foci + float c = d * 0.5; // Center-to-foci distance + // This is an utterly brute-force way of ellipse-filling based on + // the "two nails and a string" metaphor...we have the foci points + // and just need the string length (triangle perimeter) to yield + // an ellipse with area equal to a circle of 'radius'. + // c^2 = a^2 - b^2 <- ellipse formula + // a = r^2 / b <- substitute + // c^2 = (r^2 / b)^2 - b^2 + // b = sqrt(((c^2) + sqrt((c^4) + 4 * r^4)) / 2) <- solve for b + float c2 = c * c; + float b2 = (c2 + sqrt((c2 * c2) + 4 * (RADIUS * RADIUS * RADIUS * RADIUS))) * 0.5; + // By my math, perimeter SHOULD be... + // perimeter = d + 2 * sqrt(b2 + c2); + // ...but for whatever reason, working approach here is really... + perimeter = d + 2 * sqrt(b2); + } + + // Like I'm sure there's a way to rasterize this by spans rather than + // all these square roots on every pixel, but for now... + for (int y=rect[1]; ydrawPixel(x, y, eye_color565); + } + } + } +} + + +// ONE-TIME INITIALIZATION -------------- + +void setup() { + // Initialize hardware + Serial.begin(115200); + if (! glasses.begin(IS3741_ADDR_DEFAULT, i2c)) err("IS3741 not found", 2); + + canvas = glasses.getCanvas(); + if (!canvas) err("Can't allocate canvas", 5); + + i2c->setClock(1000000); // 1 MHz I2C for extra butteriness + + // Configure glasses for reduced brightness, enable output + glasses.setLEDscaling(0xFF); + glasses.setGlobalCurrent(20); + glasses.enable(true); + + // INITIALIZE TABLES & OTHER GLOBALS ---- + + // Pre-compute the Y position of 1/2 of the LEDs in a ring, relative + // to the 3X canvas resolution, so ring & matrix animation can be aligned. + for (uint8_t i=0; i<13; i++) { + float angle = (float)i / 24.0 * M_PI * 2.0; + y_pos[i] = 10.0 - cos(angle) * 12.0; + } + + // Convert some colors from [R,G,B] (easier to specify) to packed integers + ring_open_color_packed = gammify(ring_open_color); + eye_color565 = glasses.color565(eye_color[0], eye_color[1], eye_color[2]); + + start_time = millis(); // For frames-per-second math +} + +// MAIN LOOP ---------------------------- + +void loop() { + canvas->fillScreen(0); + + // The eye animation logic is a carry-over from like a billion + // prior eye projects, so this might be comment-light. + uint32_t now = micros(); // 'Snapshot' the time once per frame + + float upper, lower, ratio; + + // Blink logic + uint32_t elapsed = now - blink_start_time; // Time since start of blink event + if (elapsed > blink_duration) { // All done with event? + blink_start_time = now; // A new one starts right now + elapsed = 0; + blink_state++; // Cycle closing/opening/paused + if (blink_state == 1) { // Starting new blink... + blink_duration = random(60000, 120000); + } else if (blink_state == 2) { // Switching closing to opening... + blink_duration *= 2; // Opens at half the speed + } else { // Switching to pause in blink + blink_state = 0; + blink_duration = random(500000, 4000000); + } + } + if (blink_state) { // If currently in a blink... + float ratio = (float)elapsed / (float)blink_duration; // 0.0-1.0 as it closes + if (blink_state == 2) ratio = 1.0 - ratio; // 1.0-0.0 as it opens + upper = ratio * 15.0 - 4.0; // Upper eyelid pos. in 3X space + lower = 23.0 - ratio * 8.0; // Lower eyelid pos. in 3X space + } + + // Eye movement logic. Two points, 'p1' and 'p2', are the foci of an + // ellipse. p1 moves from current to next position a little faster + // than p2, creating a "squash and stretch" effect (frame rate and + // resolution permitting). When motion is stopped, the two points + // are at the same position. + float p1[2], p2[2]; + elapsed = now - move_start_time; // Time since start of move event + if (in_motion) { // Currently moving? + if (elapsed > move_duration) { // If end of motion reached, + in_motion = false; // Stop motion and + memcpy(&p1, &next_pos, sizeof next_pos); // set everything to new position + memcpy(&p2, &next_pos, sizeof next_pos); + memcpy(&cur_pos, &next_pos, sizeof next_pos); + move_duration = random(500000, 1500000); // Wait this long + } else { // Still moving + // Determine p1, p2 position in time + float delta[2]; + delta[0] = next_pos[0] - cur_pos[0]; + delta[1] = next_pos[1] - cur_pos[1]; + ratio = (float)elapsed / (float)move_duration; + if (ratio < 0.6) { // First 60% of move time, p1 is in motion + // Easing function: 3*e^2-2*e^3 0.0 to 1.0 + float e = ratio / 0.6; // 0.0 to 1.0 + e = 3 * e * e - 2 * e * e * e; + p1[0] = cur_pos[0] + delta[0] * e; + p1[1] = cur_pos[1] + delta[1] * e; + } else { // Last 40% of move time + memcpy(&p1, &next_pos, sizeof next_pos); // p1 has reached end position + } + if (ratio > 0.3) { // Last 70% of move time, p2 is in motion + float e = (ratio - 0.3) / 0.7; // 0.0 to 1.0 + e = 3 * e * e - 2 * e * e * e; // Easing func. + p2[0] = cur_pos[0] + delta[0] * e; + p2[1] = cur_pos[1] + delta[1] * e; + } else { // First 30% of move time + memcpy(&p2, &cur_pos, sizeof cur_pos); // p2 waits at start position + } + } + } else { // Eye is stopped + memcpy(&p1, &cur_pos, sizeof cur_pos); // Both foci at current eye position + memcpy(&p2, &cur_pos, sizeof cur_pos); + if (elapsed > move_duration) { // Pause time expired? + in_motion = true; // Start up new motion! + move_start_time = now; + move_duration = random(150000, 250000); + float angle = (float)random(1000) / 1000.0 * M_PI * 2.0; + float dist = (float)random(750) / 100.0; + next_pos[0] = 9.0 + cos(angle) * dist; + next_pos[1] = 7.5 + sin(angle) * dist * 0.8; + } + } + + // Draw the raster part of each eye... + for (uint8_t e=0; e<2; e++) { + // Each eye's foci are offset slightly, to fixate toward center + float p1a[2], p2a[2]; + p1a[0] = p1[0] + x_offset[e]; + p2a[0] = p2[0] + x_offset[e]; + p1a[1] = p2a[1] = p1[1]; + // Compute bounding rectangle (in 3X space) of ellipse + // (min X, min Y, max X, max Y). Like the ellipse rasterizer, + // this isn't optimal, but will suffice. + int bounds[4]; + bounds[0] = max(int(min(p1a[0], p2a[0]) - RADIUS), box_x_min[e]); + bounds[1] = max(max(int(min(p1a[1], p2a[1]) - RADIUS), 0), (int)upper); + bounds[2] = min(int(max(p1a[0], p2a[0]) + RADIUS + 1), box_x_max[e]); + bounds[3] = min(int(max(p1a[1], p2a[1]) + RADIUS + 1), 15); + rasterize(p1a, p2a, bounds); // Render ellipse into buffer + } + + // If the eye is currently blinking, and if the top edge of the eyelid + // overlaps the bitmap, draw lines across the bitmap as if eyelids. + if (blink_state and upper >= 0.0) { + int iu = (int)upper; + canvas->drawLine(box_x_min[0], iu, box_x_max[0] - 1, iu, eye_color565); + canvas->drawLine(box_x_min[1], iu, box_x_max[1] - 1, iu, eye_color565); + } + + glasses.scale(); // Smooth filter 3X canvas to LED grid + + // Matrix and rings share a few pixels. To make the rings take + // precedence, they're drawn later. So blink state is revisited now... + if (blink_state) { // In mid-blink? + for (uint8_t i=0; i<13; i++) { // Half an LED ring, top-to-bottom... + float a = min(max(y_pos[i] - upper + 1.0, 0.0), 3.0); + float b = min(max(lower - y_pos[i] + 1.0, 0.0), 3.0); + ratio = a * b / 9.0; // Proximity of LED to eyelid edges + uint32_t packed = interp(ring_open_color, ring_blink_color, ratio); + glasses.left_ring.setPixelColor(i, packed); + glasses.right_ring.setPixelColor(i, packed); + if ((i > 0) && (i < 12)) { + uint8_t j = 24 - i; // Mirror half-ring to other side + glasses.left_ring.setPixelColor(j, packed); + glasses.right_ring.setPixelColor(j, packed); + } + } + } else { + glasses.left_ring.fill(ring_open_color_packed); + glasses.right_ring.fill(ring_open_color_packed); + } + + glasses.show(); + + frames += 1; + elapsed = millis() - start_time; + Serial.println(frames * 1000 / elapsed); +} diff --git a/EyeLights_Blinky_Eyes/EyeLights_Blinky_Eyes_CircuitPython/code.py b/EyeLights_Blinky_Eyes/EyeLights_Blinky_Eyes_CircuitPython/code.py new file mode 100755 index 00000000..1925ef2b --- /dev/null +++ b/EyeLights_Blinky_Eyes/EyeLights_Blinky_Eyes_CircuitPython/code.py @@ -0,0 +1,338 @@ +# SPDX-FileCopyrightText: 2021 Phil Burgess for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +""" +MOVE-AND-BLINK EYES for Adafruit EyeLights (LED Glasses + Driver). + +I'd written a very cool squash-and-stretch effect for the eye movement, +but unfortunately the resolution and frame rate are such that the pupils +just look like circles regardless. I'm keeping it in despite the added +complexity, because CircuitPython devices WILL get faster, LED matrix +densities WILL improve, and this way the code won't require a re-write +at such a later time. It's a really adorable effect with enough pixels. +""" + +import math +import random +import time +from supervisor import reload +import board +from busio import I2C +import adafruit_is31fl3741 +from adafruit_is31fl3741.adafruit_ledglasses import LED_Glasses + + +# CONFIGURABLES ------------------------ + +eye_color = (255, 128, 0) # Amber pupils +ring_open_color = (75, 75, 75) # Color of LED rings when eyes open +ring_blink_color = (50, 25, 0) # Color of LED ring "eyelid" when blinking + +radius = 3.4 # Size of pupil (3X because of downsampling later) + +# Reading through the code, you'll see a lot of references to this "3X" +# space. What it's referring to is a bitmap that's 3 times the resolution +# of the LED matrix (i.e. 15 pixels tall instead of 5), which gets scaled +# down to provide some degree of antialiasing. It's why the pupils have +# soft edges and can make fractional-pixel motions. +# Because of the way the downsampling is done, the eyelid edge when drawn +# across the eye will always be the same hue as the pupils, it can't be +# set independently like the ring blink color. + +gamma = 2.6 # For color adjustment. Leave as-is. + + +# CLASSES & FUNCTIONS ------------------ + + +class Eye: + """Holds per-eye positional data; each covers a different area of the + overall LED matrix.""" + + def __init__(self, left, xoff): + self.left = left # Leftmost column on LED matrix + self.x_offset = xoff # Horizontal offset (3X space) to fixate + + def smooth(self, data, rect): + """Scale bitmap (in 'data') to LED array, with smooth 1:3 + downsampling. 'rect' is a 4-tuple rect of which pixels get + filtered (anything outside is cleared to 0), saves a few cycles.""" + # Quantize bounds rect from 3X space to LED matrix space. + rect = ( + rect[0] // 3, # Left + rect[1] // 3, # Top + (rect[2] + 2) // 3, # Right + (rect[3] + 2) // 3, # Bottom + ) + for y in range(rect[1]): # Erase rows above top + for x in range(6): + glasses.pixel(self.left + x, y, 0) + for y in range(rect[1], rect[3]): # Each row, top to bottom... + pixel_sum = bytearray(6) # Initialize row of pixel sums to 0 + for y1 in range(3): # 3 rows of bitmap... + row = data[y * 3 + y1] # Bitmap data for current row + for x in range(rect[0], rect[2]): # Column, left to right + x3 = x * 3 + # Accumulate 3 pixels of bitmap into pixel_sum + pixel_sum[x] += row[x3] + row[x3 + 1] + row[x3 + 2] + # 'pixel_sum' will now contain values from 0-9, indicating the + # number of set pixels in the corresponding section of the 3X + # bitmap. 'colormap' expands the sum to 24-bit RGB space. + for x in range(rect[0]): # Erase any columns to left + glasses.pixel(self.left + x, y, 0) + for x in range(rect[0], rect[2]): # Column, left to right + glasses.pixel(self.left + x, y, colormap[pixel_sum[x]]) + for x in range(rect[2], 6): # Erase columns to right + glasses.pixel(self.left + x, y, 0) + for y in range(rect[3], 5): # Erase rows below bottom + for x in range(6): + glasses.pixel(self.left + x, y, 0) + + +# pylint: disable=too-many-locals +def rasterize(data, point1, point2, rect): + """Rasterize an arbitrary ellipse into the 'data' bitmap (3X pixel + space), given foci point1 and point2 and with area determined by global + 'radius' (when foci are same point; a circle). Foci and radius are all + floating point values, which adds to the buttery impression. 'rect' is + a 4-tuple rect of which pixels are likely affected. Data is assumed 0 + before arriving here; no clearing is performed.""" + + dx = point2[0] - point1[0] + dy = point2[1] - point1[1] + d2 = dx * dx + dy * dy # Dist between foci, squared + if d2 <= 0: + # Foci are in same spot - it's a circle + perimeter = 2 * radius + d = 0 + else: + # Foci are separated - it's an ellipse. + d = d2 ** 0.5 # Distance between foci + c = d * 0.5 # Center-to-foci distance + # This is an utterly brute-force way of ellipse-filling based on + # the "two nails and a string" metaphor...we have the foci points + # and just need the string length (triangle perimeter) to yield + # an ellipse with area equal to a circle of 'radius'. + # c^2 = a^2 - b^2 <- ellipse formula + # a = r^2 / b <- substitute + # c^2 = (r^2 / b)^2 - b^2 + # b = sqrt(((c^2) + sqrt((c^4) + 4 * r^4)) / 2) <- solve for b + b2 = ((c ** 2) + (((c ** 4) + 4 * (radius ** 4)) ** 0.5)) * 0.5 + # By my math, perimeter SHOULD be... + # perimeter = d + 2 * ((b2 + (c ** 2)) ** 0.5) + # ...but for whatever reason, working approach here is really... + perimeter = d + 2 * (b2 ** 0.5) + + # Like I'm sure there's a way to rasterize this by spans rather than + # all these square roots on every pixel, but for now... + for y in range(rect[1], rect[3]): # For each row... + y5 = y + 0.5 # Pixel center + dy1 = y5 - point1[1] # Y distance from pixel to first point + dy2 = y5 - point2[1] # " to second + dy1 *= dy1 # Y1^2 + dy2 *= dy2 # Y2^2 + for x in range(rect[0], rect[2]): # For each column... + x5 = x + 0.5 # Pixel center + dx1 = x5 - point1[0] # X distance from pixel to first point + dx2 = x5 - point2[0] # " to second + d1 = (dx1 * dx1 + dy1) ** 0.5 # 2D distance to first point + d2 = (dx2 * dx2 + dy2) ** 0.5 # " to second + if (d1 + d2 + d) <= perimeter: + data[y][x] = 1 # Point is inside ellipse + + +def gammify(color): + """Given an (R,G,B) color tuple, apply gamma correction and return + a packed 24-bit RGB integer.""" + rgb = [int(((color[x] / 255) ** gamma) * 255 + 0.5) for x in range(3)] + return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2] + + +def interp(color1, color2, blend): + """Given two (R,G,B) color tuples and a blend ratio (0.0 to 1.0), + interpolate between the two colors and return a gamma-corrected + in-between color as a packed 24-bit RGB integer. No bounds clamping + is performed on blend value, be nice.""" + inv = 1.0 - blend # Weighting of second color + return gammify([color1[x] * blend + color2[x] * inv for x in range(3)]) + + +# HARDWARE SETUP ----------------------- + +# Manually declare I2C (not board.I2C() directly) to access 1 MHz speed... +i2c = I2C(board.SCL, board.SDA, frequency=1000000) + +# Initialize the IS31 LED driver, buffered for smoother animation +glasses = LED_Glasses(i2c, allocate=adafruit_is31fl3741.MUST_BUFFER) +glasses.show() # Clear any residue on startup +glasses.global_current = 20 # Just middlin' bright, please + + +# INITIALIZE TABLES & OTHER GLOBALS ---- + +# This table is for mapping 3x3 averaged bitmap values (0-9) to +# RGB colors. Avoids a lot of shift-and-or on every pixel. +colormap = [] +for n in range(10): + colormap.append(gammify([n / 9 * eye_color[x] for x in range(3)])) + +# Pre-compute the Y position of 1/2 of the LEDs in a ring, relative +# to the 3X bitmap resolution, so ring & matrix animation can be aligned. +y_pos = [] +for n in range(13): + angle = n / 24 * math.pi * 2 + y_pos.append(10 - math.cos(angle) * 12) + +# Pre-compute color of LED ring in fully open (unblinking) state +ring_open_color_packed = gammify(ring_open_color) + +# A single pre-computed scanline of "eyelid edge during blink" can be +# stuffed into the 3X raster as needed, avoids setting pixels manually. +eyelid = ( + b"\x01\x01\x00\x01\x01\x00\x01\x01\x00" b"\x01\x01\x00\x01\x01\x00\x01\x01\x00" +) # 2/3 of pixels set + +# Initialize eye position and move/blink animation timekeeping +cur_pos = next_pos = (9, 7.5) # Current, next eye position in 3X space +in_motion = False # True = eyes moving, False = eyes paused +blink_state = 0 # 0, 1, 2 = unblinking, closing, opening +move_start_time = move_duration = blink_start_time = blink_duration = 0 + +# Two eye objects. The first starts at column 1 of the matrix with its +# pupil offset by +2 (in 3X space), second at column 11 with -2 offset. +# The offsets make the pupils fixate slightly (converge on a point), so +# the two pupils aren't always aligned the same on the pixel grid, which +# would be conspicuously pixel-y. +eyes = [Eye(1, 2), Eye(11, -2)] + +frames, start_time = 0, time.monotonic() # For frames/second calculation + + +# MAIN LOOP ---------------------------- + +while True: + # The try/except here is because VERY INFREQUENTLY the I2C bus will + # encounter an error when accessing the LED driver, whether from bumping + # around the wires or sometimes an I2C device just gets wedged. To more + # robustly handle the latter, the code will restart if that happens. + try: + + # The eye animation logic is a carry-over from like a billion + # prior eye projects, so this might be comment-light. + now = time.monotonic() # 'Snapshot' the time once per frame + + # Blink logic + elapsed = now - blink_start_time # Time since start of blink event + if elapsed > blink_duration: # All done with event? + blink_start_time = now # A new one starts right now + elapsed = 0 + blink_state += 1 # Cycle closing/opening/paused + if blink_state == 1: # Starting new blink... + blink_duration = random.uniform(0.06, 0.12) + elif blink_state == 2: # Switching closing to opening... + blink_duration *= 2 # Opens at half the speed + else: # Switching to pause in blink + blink_state = 0 + blink_duration = random.uniform(0.5, 4) + if blink_state: # If currently in a blink... + ratio = elapsed / blink_duration # 0.0-1.0 as it closes + if blink_state == 2: + ratio = 1.0 - ratio # 1.0-0.0 as it opens + upper = ratio * 15 - 4 # Upper eyelid pos. in 3X space + lower = 23 - ratio * 8 # Lower eyelid pos. in 3X space + + # Eye movement logic. Two points, 'p1' and 'p2', are the foci of an + # ellipse. p1 moves from current to next position a little faster + # than p2, creating a "squash and stretch" effect (frame rate and + # resolution permitting). When motion is stopped, the two points + # are at the same position. + elapsed = now - move_start_time # Time since start of move event + if in_motion: # Currently moving? + if elapsed > move_duration: # If end of motion reached, + in_motion = False # Stop motion and + p1 = p2 = cur_pos = next_pos # Set to new position + move_duration = random.uniform(0.5, 1.5) # Wait this long + else: # Still moving + # Determine p1, p2 position in time + delta = (next_pos[0] - cur_pos[0], next_pos[1] - cur_pos[1]) + ratio = elapsed / move_duration + if ratio < 0.6: # First 60% of move time + # p1 is in motion + # Easing function: 3*e^2-2*e^3 0.0 to 1.0 + e = ratio / 0.6 # 0.0 to 1.0 + e = 3 * e * e - 2 * e * e * e + p1 = (cur_pos[0] + delta[0] * e, cur_pos[1] + delta[1] * e) + else: # Last 40% of move time + p1 = next_pos # p1 has reached end position + if ratio > 0.3: # Last 60% of move time + # p2 is in motion + e = (ratio - 0.3) / 0.7 # 0.0 to 1.0 + e = 3 * e * e - 2 * e * e * e # Easing func. + p2 = (cur_pos[0] + delta[0] * e, cur_pos[1] + delta[1] * e) + else: # First 40% of move time + p2 = cur_pos # p2 waits at start position + else: # Eye is stopped + p1 = p2 = cur_pos # Both foci at current eye position + if elapsed > move_duration: # Pause time expired? + in_motion = True # Start up new motion! + move_start_time = now + move_duration = random.uniform(0.15, 0.25) + angle = random.uniform(0, math.pi * 2) + dist = random.uniform(0, 7.5) + next_pos = ( + 9 + math.cos(angle) * dist, + 7.5 + math.sin(angle) * dist * 0.8, + ) + + # Draw the raster part of each eye... + for eye in eyes: + # Allocate/clear the 3X bitmap buffer + bitmap = [bytearray(6 * 3) for _ in range(5 * 3)] + # Each eye's foci are offset slightly, to fixate toward center + p1a = (p1[0] + eye.x_offset, p1[1]) + p2a = (p2[0] + eye.x_offset, p2[1]) + # Compute bounding rectangle (in 3X space) of ellipse + # (min X, min Y, max X, max Y). Like the ellipse rasterizer, + # this isn't optimal, but will suffice. + bounds = ( + max(int(min(p1a[0], p2a[0]) - radius), 0), + max(int(min(p1a[1], p2a[1]) - radius), 0, int(upper)), + min(int(max(p1a[0], p2a[0]) + radius + 1), 18), + min(int(max(p1a[1], p2a[1]) + radius + 1), 15, int(lower) + 1), + ) + rasterize(bitmap, p1a, p2a, bounds) # Render ellipse into buffer + # If the eye is currently blinking, and if the top edge of the + # eyelid overlaps the bitmap, draw a scanline across the bitmap + # and update the bounds rect so the whole width of the bitmap + # is scaled. + if blink_state and upper >= 0: + bitmap[int(upper)] = eyelid + bounds = (0, int(upper), 18, bounds[3]) + eye.smooth(bitmap, bounds) # 1:3 downsampling for eye + + # Matrix and rings share a few pixels. To make the rings take + # precedence, they're drawn later. So blink state is revisited now... + if blink_state: # In mid-blink? + for i in range(13): # Half an LED ring, top-to-bottom... + a = min(max(y_pos[i] - upper + 1, 0), 3) + b = min(max(lower - y_pos[i] + 1, 0), 3) + ratio = a * b / 9 # Proximity of LED to eyelid edges + packed = interp(ring_open_color, ring_blink_color, ratio) + glasses.left_ring[i] = glasses.right_ring[i] = packed + if 0 < i < 12: + i = 24 - i # Mirror half-ring to other side + glasses.left_ring[i] = glasses.right_ring[i] = packed + else: + glasses.left_ring.fill(ring_open_color_packed) + glasses.right_ring.fill(ring_open_color_packed) + + glasses.show() # Buffered mode MUST use show() to refresh matrix + + except OSError: # See "try" notes above regarding rare I2C errors. + print("Restarting") + reload() + + frames += 1 + elapsed = time.monotonic() - start_time + print(frames / elapsed) diff --git a/EyeLights_Bluetooth_Scroller/.ledglasses_nrf52840.generate b/EyeLights_Bluetooth_Scroller/.ledglasses_nrf52840.generate new file mode 100644 index 00000000..e69de29b diff --git a/EyeLights_Bluetooth_Scroller/.ledglasses_nrf52840.test.only b/EyeLights_Bluetooth_Scroller/.ledglasses_nrf52840.test.only new file mode 100644 index 00000000..e69de29b diff --git a/EyeLights_Bluetooth_Scroller/EyeLights_Bluetooth_Scroller.ino b/EyeLights_Bluetooth_Scroller/EyeLights_Bluetooth_Scroller.ino new file mode 100644 index 00000000..d810cd44 --- /dev/null +++ b/EyeLights_Bluetooth_Scroller/EyeLights_Bluetooth_Scroller.ino @@ -0,0 +1,202 @@ +// SPDX-FileCopyrightText: 2021 Phil Burgess for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +/* +BLUETOOTH SCROLLING MESSAGE for Adafruit EyeLights (LED Glasses + Driver). +Use BLUEFRUIT CONNECT app on iOS or Android to connect to LED glasses. +Use the app's UART input to enter a new message. +Use the app's Color Picker (under "Controller") to change text color. +This is based on the glassesdemo-3-smooth example from the +Adafruit_IS31FL3741 library, with Bluetooth additions on top. If this +code all seems a bit too much, you can start with that example (or the two +that precede it) to gain an understanding of the LED glasses basics, then +return here to see what the extra Bluetooth layers do. +*/ + +#include // For LED driver +#include // For Bluetooth communication +#include // Smooth scrolly font for glasses + +// These items are over in the packetParser.cpp tab: +extern uint8_t packetbuffer[]; +extern uint8_t readPacket(BLEUart *ble, uint16_t timeout); +extern int8_t packetType(uint8_t *buf, uint8_t len); +extern float parsefloat(uint8_t *buffer); +extern void printHex(const uint8_t * data, const uint32_t numBytes); + +// GLOBAL VARIABLES ------- + +// 'Buffered' glasses for buttery animation, +// 'true' to allocate a drawing canvas for smooth graphics: +Adafruit_EyeLights_buffered glasses(true); +GFXcanvas16 *canvas; // Pointer to glasses' canvas object +// Because 'canvas' is a pointer, always use -> when calling +// drawing functions there. 'glasses' is an object in itself, +// so . is used when calling its functions. + +char message[51] = "Run Bluefruit Connect app"; // Scrolling message +int16_t text_x; // Message position on canvas +int16_t text_min; // Leftmost position before restarting scroll + +BLEUart bleuart; // Bluetooth low energy UART + +int8_t last_packet_type = 99; // Last BLE packet type, init to nonsense value + +// ONE-TIME SETUP --------- + +void setup() { // Runs once at program start... + + Serial.begin(115200); + //while(!Serial); + + // Configure and start the BLE UART service + Bluefruit.begin(); + Bluefruit.setTxPower(4); + bleuart.begin(); + startAdv(); // Set up and start advertising + + if (!glasses.begin()) err("IS3741 not found", 2); + + canvas = glasses.getCanvas(); + if (!canvas) err("Can't allocate canvas", 5); + + // Configure glasses for full brightness and enable output + glasses.setLEDscaling(0xFF); + glasses.setGlobalCurrent(0xFF); + glasses.enable(true); + + // Set up for scrolling text, initialize color and position + canvas->setFont(&EyeLightsCanvasFont); + canvas->setTextWrap(false); // Allow text to extend off edges + canvas->setTextColor(glasses.color565(0x303030)); // Dim white to start + reposition_text(); // Sets up initial position & scroll limit +} + +// Crude error handler, prints message to Serial console, flashes LED +void err(char *str, uint8_t hz) { + Serial.println(str); + pinMode(LED_BUILTIN, OUTPUT); + for (;;) digitalWrite(LED_BUILTIN, (millis() * hz / 500) & 1); +} + +// Set up, start BLE advertising +void startAdv(void) { + // Advertising packet + Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); + Bluefruit.Advertising.addTxPower(); + + // Include the BLE UART (AKA 'NUS') 128-bit UUID + Bluefruit.Advertising.addService(bleuart); + + // Secondary Scan Response packet (optional) + // Since there is no room for 'Name' in Advertising packet + Bluefruit.ScanResponse.addName(); + + // Start Advertising + // - Enable auto advertising if disconnected + // - Interval: fast mode = 20 ms, slow mode = 152.5 ms + // - Timeout for fast mode is 30 seconds + // - Start(timeout) with timeout = 0 will advertise forever (until connected) + // + // For recommended advertising interval + // https://developer.apple.com/library/content/qa/qa1931/_index.html + Bluefruit.Advertising.restartOnDisconnect(true); + Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms + Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode + Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds +} + +// MAIN LOOP -------------- + +void loop() { // Repeat forever... + // The packet read timeout (9 ms here) also determines the text + // scrolling speed -- if no data is received over BLE in that time, + // the function exits and returns here with len=0. + uint8_t len = readPacket(&bleuart, 9); + if (len) { + int8_t type = packetType(packetbuffer, len); + // The Bluefruit Connect app can return a variety of data from + // a phone's sensors. To keep this example relatively simple, + // we'll only look at color and text, but here's where others + // would go if we were to extend this. See Bluefruit library + // examples for the packet data formats. packetParser.cpp + // has a couple functions not used in this code but that may be + // helpful in interpreting these other packet types. + switch(type) { + case 0: // Accelerometer + Serial.println("Accel"); + break; + case 1: // Gyro: + Serial.println("Gyro"); + break; + case 2: // Magnetometer + Serial.println("Mag"); + break; + case 3: // Quaternion + Serial.println("Quat"); + break; + case 4: // Button + Serial.println("Button"); + break; + case 5: // Color + Serial.println("Color"); + // packetbuffer[2] through [4] contain R, G, B byte values. + // Because the drawing canvas uses lower-precision '565' color, + // and because glasses.scale() applies gamma correction and may + // quantize the dimmest colors to 0, set a brightness floor here + // so text isn't invisible. + for (uint8_t i=2; i<=4; i++) { + if (packetbuffer[i] < 0x20) packetbuffer[i] = 0x20; + } + canvas->setTextColor(glasses.color565(glasses.Color( + packetbuffer[2], packetbuffer[3], packetbuffer[4]))); + break; + case 6: // Location + Serial.println("Location"); + break; + default: // -1 + // Packet is not one of the Bluefruit Connect types. Most programs + // will ignore/reject it as not valud, but in this case we accept + // it as a freeform string for the scrolling message. + if (last_packet_type != -1) { + // If prior data was a packet, this is a new freeform string, + // initialize the message string with it... + strncpy(message, (char *)packetbuffer, 20); + } else { + // If prior data was also a freeform string, concatenate this onto + // the message (up to the max message length). BLE packets can only + // be so large, so long strings are broken into multiple packets. + uint8_t message_len = strlen(message); + uint8_t max_append = sizeof message - 1 - message_len; + strncpy(&message[message_len], (char *)packetbuffer, max_append); + len = message_len + max_append; + } + message[len] = 0; // End of string NUL char + Serial.println(message); + reposition_text(); // Reset text off right edge of canvas + } + last_packet_type = type; // Save packet type for next pass + } else { + last_packet_type = 99; // BLE read timeout, reset last type to nonsense + } + + canvas->fillScreen(0); // Clear the whole drawing canvas + // Update text to new position, and draw on canvas + if (--text_x < text_min) { // If text scrolls off left edge, + text_x = canvas->width(); // reset position off right edge + } + canvas->setCursor(text_x, canvas->height()); + canvas->print(message); + glasses.scale(); // 1:3 downsample canvas to LED matrix + glasses.show(); // MUST call show() to update matrix +} + +// When new message text is assigned, call this to reset its position +// off the right edge and calculate column where scrolling resets. +void reposition_text() { + uint16_t w, h, ignore; + canvas->getTextBounds(message, 0, 0, (int16_t *)&ignore, (int16_t *)&ignore, &w, &ignore); + text_x = canvas->width(); + text_min = -w; // Off left edge this many pixels +} diff --git a/EyeLights_Bluetooth_Scroller/packetParser.cpp b/EyeLights_Bluetooth_Scroller/packetParser.cpp new file mode 100644 index 00000000..82b6cd01 --- /dev/null +++ b/EyeLights_Bluetooth_Scroller/packetParser.cpp @@ -0,0 +1,119 @@ +#include + +// packetbuffer holds inbound data +#define READ_BUFSIZE 20 +uint8_t packetbuffer[READ_BUFSIZE + 1]; // +1 is for NUL string terminator + +/**************************************************************************/ +/*! + @brief Casts the four bytes at the specified address to a float. + @param ptr Pointer into packet buffer. + @returns Floating-point value. +*/ +/**************************************************************************/ +float parsefloat(uint8_t *ptr) { + float f; // Make a suitably-aligned float variable, + memcpy(&f, ptr, 4); // because in-buffer instance might be misaligned! + return f; // (You can't always safely parse in-place) +} + +/**************************************************************************/ +/*! + @brief Prints a series of bytes in 0xNN hexadecimal notation. + @param buf Pointer to array of byte data. + @param len Data length in bytes. +*/ +/**************************************************************************/ +void printHex(const uint8_t *buf, const uint32_t len) { + for (uint32_t i=0; i < len; i++) { + Serial.print(F("0x")); + if (buf[i] <= 0xF) Serial.write('0'); // Zero-pad small values + Serial.print(buf[i], HEX); + if (i < (len - 1)) Serial.write(' '); // Space between bytes + } + Serial.println(); +} + +static const struct { // Special payloads from Bluefruit Connect app... + char id; // Packet type identifier + uint8_t len; // Size of complete, well-formed packet of this type +} _app_packet[] = { + {'A', 15}, // Accelerometer + {'G', 15}, // Gyro + {'M', 15}, // Magnetometer + {'Q', 19}, // Quaterion + {'B', 5}, // Button + {'C', 6}, // Color + {'L', 15}, // Location +}; +#define NUM_PACKET_TYPES (sizeof _app_packet / sizeof _app_packet[0]) +#define SHORTEST_PACKET_LEN 5 // Button, for now + +/**************************************************************************/ +/*! + @brief Given packet data, identify if it's one of the known + Bluefruit Connect app packet types. + @param buf Pointer to packet data. + @param len Size of packet in bytes. + @returns Packet type index (0 to NUM_PACKET_TYPES-1) if recognized, + -1 if unrecognized. +*/ +/**************************************************************************/ +int8_t packetType(uint8_t *buf, uint8_t len) { + if ((len >= SHORTEST_PACKET_LEN) && (buf[0] == '!')) { + for (int8_t type=0; typeavailable()) { + char c = ble->read(); + if (c == '!') { // '!' resets buffer to start + len = 0; + xsum = 255; + } + packetbuffer[len++] = c; + // Stop when buffer's full or packet type recognized + if ((len >= READ_BUFSIZE) || + ((type = packetType(packetbuffer, len)) >= 0)) break; + start_time = now; // Reset timeout on char received + xsum -= c; // Not last char, do checksum math + type = -1; // Reset packet type finder + } + } while((now - start_time) < timeout); + + // If packet type recognized, verify checksum (else freeform string) + if ((type >= 0) && (xsum != packetbuffer[len-1])) { // Last byte = checksum + Serial.print("Packet checksum mismatch: "); + printHex(packetbuffer, len); + return 0; + } + + packetbuffer[len] = 0; // Terminate packet string + + return len; // Checksum is valid for packet, or it's a freeform string +} diff --git a/EyeLights_Fire/EyeLights_Fire/.ledglasses_nrf52840.test.only b/EyeLights_Fire/EyeLights_Fire/.ledglasses_nrf52840.test.only new file mode 100644 index 00000000..e69de29b diff --git a/EyeLights_Fire/EyeLights_Fire/EyeLights_Fire.ino b/EyeLights_Fire/EyeLights_Fire/EyeLights_Fire.ino new file mode 100644 index 00000000..1eb43c69 --- /dev/null +++ b/EyeLights_Fire/EyeLights_Fire/EyeLights_Fire.ino @@ -0,0 +1,135 @@ +// SPDX-FileCopyrightText: 2021 Phil Burgess for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +/* +FIRE EFFECT for Adafruit EyeLights (LED Glasses + Driver). +A demoscene classic that produces a cool analog-esque look with +modest means, iteratively scrolling and blurring raster data. +*/ + +#include // For LED driver + +Adafruit_EyeLights_buffered glasses; // Buffered for smooth animation + +// The raster data is intentionally one row taller than the LED matrix. +// Each frame, random noise is put in the bottom (off matrix) row. There's +// also an extra column on either side, to avoid needing edge clipping when +// neighboring pixels (left, center, right) are averaged later. +float data[6][20]; // 2D array where elements are accessed as data[y][x] + +// Each element in the raster is a single value representing brightness. +// A pre-computed lookup table maps these to RGB colors. This one happens +// to have 32 elements, but as we're not on an actual paletted hardware +// framebuffer it could be any size really (with suitable changes throughout). +uint32_t colormap[32]; +#define GAMMA 2.6 + +// Crude error handler, prints message to Serial console, flashes LED +void err(char *str, uint8_t hz) { + Serial.println(str); + pinMode(LED_BUILTIN, OUTPUT); + for (;;) digitalWrite(LED_BUILTIN, (millis() * hz / 500) & 1); +} + +void setup() { // Runs once at program start... + + // Initialize hardware + Serial.begin(115200); + if (! glasses.begin()) err("IS3741 not found", 2); + + // Configure glasses for reduced brightness, enable output + glasses.setLEDscaling(0xFF); + glasses.setGlobalCurrent(20); + glasses.enable(true); + + memset(data, 0, sizeof data); + + for(uint8_t i=0; i<32; i++) { + float n = i * 3.0 / 31.0; // 0.0 <= n <= 3.0 from start to end of map + float r, g, b; + if (n <= 1) { // 0.0 <= n <= 1.0 : black to red + r = n; // r,g,b are initially calculated 0 to 1 range + g = b = 0.0; + } else if (n <= 2) { // 1.0 <= n <= 2.0 : red to yellow + r = 1.0; + g = n - 1.0; + b = 0.0; + } else { // 2.0 <= n <= 3.0 : yellow to white + r = g = 1.0; + b = n - 2.0; + } + // Gamma correction linearizes perceived brightness, then scale to + // 0-255 for LEDs and store as a 'packed' RGB color. + colormap[i] = (uint32_t(pow(r, GAMMA) * 255.0) << 16) | + (uint32_t(pow(g, GAMMA) * 255.0) << 8) | + uint32_t(pow(b, GAMMA) * 255.0); + } +} + +// Linearly interpolate a range of brightnesses between two LEDs of +// one eyeglass ring, mapping through the global color table. LED range +// is non-inclusive; the first and last LEDs (which overlap matrix pixels) +// are not set. led2 MUST be > led1. LED indices may be >= 24 to 'wrap +// around' the seam at the top of the ring. +void interp(bool isRight, int led1, int led2, float level1, float level2) { + int span = led2 - led1 + 1; // Number of LEDs + float delta = level2 - level1; // Difference in brightness + for (int led = led1 + 1; led < led2; led++) { // For each LED in-between, + float ratio = (float)(led - led1) / span; // interpolate brightness level + uint32_t color = colormap[min(31, int(level1 + delta * ratio))]; + if (isRight) glasses.right_ring.setPixelColor(led % 24, color); + else glasses.left_ring.setPixelColor(led % 24, color); + } +} + +void loop() { // Repeat forever... + // At the start of each frame, fill the bottom (off matrix) row + // with random noise. To make things less strobey, old data from the + // prior frame still has about 1/3 'weight' here. There's no special + // real-world significance to the 85, it's just an empirically- + // derived fudge factor that happens to work well with the size of + // the color map. + for (uint8_t x=1; x<19; x++) { + data[5][x] = 0.33 * data[5][x] + 0.67 * ((float)random(1000) / 1000.0) * 85.0; + } + // If this were actual SRS BZNS 31337 D3M0SC3N3 code, great care + // would be taken to avoid floating-point math. But with few pixels, + // and so this code might be less obtuse, a casual approach is taken. + + // Each row (except last) is then processed, top-to-bottom. This + // order is important because it's an iterative algorithm...the + // output of each frame serves as input to the next, and the steps + // below (looking at the pixels below each row) are what makes the + // "flames" appear to move "up." + for (uint8_t y=0; y<5; y++) { // Current row of pixels + float *y1 = &data[y + 1][0]; // One row down + for (uint8_t x = 1; x < 19; x++) { // Skip left, right columns in data + // Each pixel is sort of the average of the three pixels + // under it (below left, below center, below right), but not + // exactly. The below center pixel has more 'weight' than the + // others, and the result is scaled to intentionally land + // short, making each row bit darker as they move up. + data[y][x] = (y1[x] + ((y1[x - 1] + y1[x + 1]) * 0.33)) * 0.35; + glasses.drawPixel(x - 1, y, glasses.color565(colormap[min(31, int(data[y][x]))])); + // Remember that the LED matrix uses GFX-style "565" colors, + // hence the round trip through color565() here, whereas the LED + // rings (referenced in interp()) use NeoPixel-style 24-bit colors + // (those can reference colormap[] directly). + } + } + + // That's all well and good for the matrix, but what about the extra + // LEDs in the rings? Since these don't align to the pixel grid, + // rather than trying to extend the raster data and filter it in + // somehow, we'll fill those arcs with colors interpolated from the + // endpoints where rings and matrix intersect. Maybe not perfect, + // but looks okay enough! + interp(false, 7, 17, data[4][8], data[4][1]); // Left ring bottom + interp(false, 21, 29, data[0][2], data[1][8]); // Left ring top + interp(true, 7, 17, data[4][18], data[4][11]); // Right ring bottom + interp(true, 19, 27, data[1][11], data[0][17]); // Right ring top + + glasses.show(); + delay(25); +} diff --git a/EyeLights_Fire/EyeLights_Fire_CircuitPython/code.py b/EyeLights_Fire/EyeLights_Fire_CircuitPython/code.py new file mode 100755 index 00000000..5c4bc670 --- /dev/null +++ b/EyeLights_Fire/EyeLights_Fire_CircuitPython/code.py @@ -0,0 +1,131 @@ +# SPDX-FileCopyrightText: 2021 Phil Burgess for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +""" +FIRE EFFECT for Adafruit EyeLights (LED Glasses + Driver). +A demoscene classic that produces a cool analog-esque look with +modest means, iteratively scrolling and blurring raster data. +""" + +import random +from supervisor import reload +import board +from busio import I2C +import adafruit_is31fl3741 +from adafruit_is31fl3741.adafruit_ledglasses import LED_Glasses + + +# HARDWARE SETUP --------- + +# Manually declare I2C (not board.I2C() directly) to access 1 MHz speed... +i2c = I2C(board.SCL, board.SDA, frequency=1000000) + +# Initialize the IS31 LED driver, buffered for smoother animation +glasses = LED_Glasses(i2c, allocate=adafruit_is31fl3741.MUST_BUFFER) +glasses.show() # Clear any residue on startup +glasses.global_current = 20 # Just middlin' bright, please + + +# INITIALIZE TABLES ------ + +# The raster data is intentionally one row taller than the LED matrix. +# Each frame, random noise is put in the bottom (off matrix) row. There's +# also an extra column on either side, to avoid needing edge clipping when +# neighboring pixels (left, center, right) are averaged later. +data = [[0] * (glasses.width + 2) for _ in range(glasses.height + 1)] +# (2D array where elements are accessed as data[y][x], initialized to 0) + +# Each element in the raster is a single value representing brightness. +# A pre-computed lookup table maps these to RGB colors. This one happens +# to have 32 elements, but as we're not on an actual paletted hardware +# framebuffer it could be any size really (with suitable changes throughout). +gamma = 2.6 +colormap = [] +for n in range(32): + n *= 3 / 31 # 0.0 <= n <= 3.0 from start to end of map + if n <= 1: # 0.0 <= n <= 1.0 : black to red + r = n # r,g,b are initially calculated 0 to 1 range + g = b = 0 + elif n <= 2: # 1.0 <= n <= 2.0 : red to yellow + r = 1 + g = n - 1 + b = 0 + else: # 2.0 <= n <= 3.0 : yellow to white + r = g = 1 + b = n - 2 + r = int((r ** gamma) * 255) # Gamma correction linearizes + g = int((g ** gamma) * 255) # perceived brightness, then + b = int((b ** gamma) * 255) # scale to 0-255 for LEDs and + colormap.append((r << 16) | (g << 8) | b) # store as 'packed' RGB color + + +# UTILITY FUNCTIONS ----- + + +def interp(ring, led1, led2, level1, level2): + """Linearly interpolate a range of brightnesses between two LEDs of + one eyeglass ring, mapping through the global color table. LED range + is non-inclusive; the first and last LEDs (which overlap matrix pixels) + are not set. led2 MUST be > led1. LED indices may be >= 24 to 'wrap + around' the seam at the top of the ring.""" + span = led2 - led1 + 1 # Number of LEDs + delta = level2 - level1 # Difference in brightness + for led in range(led1 + 1, led2): # For each LED in-between, + ratio = (led - led1) / span # interpolate brightness level + ring[led % 24] = colormap[min(31, int(level1 + delta * ratio))] + + +# MAIN LOOP ------------- + +while True: + # The try/except here is because VERY INFREQUENTLY the I2C bus will + # encounter an error when accessing the LED driver, whether from bumping + # around the wires or sometimes an I2C device just gets wedged. To more + # robustly handle the latter, the code will restart if that happens. + try: + + # At the start of each frame, fill the bottom (off matrix) row + # with random noise. To make things less strobey, old data from the + # prior frame still has about 1/3 'weight' here. There's no special + # real-world significance to the 85, it's just an empirically- + # derived fudge factor that happens to work well with the size of + # the color map. + for x in range(1, 19): + data[5][x] = 0.33 * data[5][x] + 0.67 * random.random() * 85 + # If this were actual SRS BZNS 31337 D3M0SC3N3 code, great care + # would be taken to avoid floating-point math. But with few pixels, + # and so this code might be less obtuse, a casual approach is taken. + + # Each row (except last) is then processed, top-to-bottom. This + # order is important because it's an iterative algorithm...the + # output of each frame serves as input to the next, and the steps + # below (looking at the pixels below each row) are what makes the + # "flames" appear to move "up." + for y in range(5): # Current row of pixels + y1 = data[y + 1] # One row down + for x in range(1, 19): # Skip left, right columns in data + # Each pixel is sort of the average of the three pixels + # under it (below left, below center, below right), but not + # exactly. The below center pixel has more 'weight' than the + # others, and the result is scaled to intentionally land + # short, making each row bit darker as they move up. + data[y][x] = (y1[x] + ((y1[x - 1] + y1[x + 1]) * 0.33)) * 0.35 + glasses.pixel(x - 1, y, colormap[min(31, int(data[y][x]))]) + + # That's all well and good for the matrix, but what about the extra + # LEDs in the rings? Since these don't align to the pixel grid, + # rather than trying to extend the raster data and filter it in + # somehow, we'll fill those arcs with colors interpolated from the + # endpoints where rings and matrix intersect. Maybe not perfect, + # but looks okay enough! + interp(glasses.left_ring, 7, 17, data[4][8], data[4][1]) + interp(glasses.left_ring, 21, 29, data[0][2], data[2][8]) + interp(glasses.right_ring, 7, 17, data[4][18], data[4][11]) + interp(glasses.right_ring, 19, 27, data[2][11], data[0][17]) + + glasses.show() # Buffered mode MUST use show() to refresh matrix + + except OSError: # See "try" notes above regarding rare I2C errors. + print("Restarting") + reload() diff --git a/EyeLights_Googly_Rings/EyeLights_Googly_Rings/.ledglasses_nrf52840.generate b/EyeLights_Googly_Rings/EyeLights_Googly_Rings/.ledglasses_nrf52840.generate new file mode 100644 index 00000000..e69de29b diff --git a/EyeLights_Googly_Rings/EyeLights_Googly_Rings/.ledglasses_nrf52840.test.only b/EyeLights_Googly_Rings/EyeLights_Googly_Rings/.ledglasses_nrf52840.test.only new file mode 100644 index 00000000..e69de29b diff --git a/EyeLights_Googly_Rings/EyeLights_Googly_Rings/EyeLights_Googly_Rings.ino b/EyeLights_Googly_Rings/EyeLights_Googly_Rings/EyeLights_Googly_Rings.ino new file mode 100644 index 00000000..c955083f --- /dev/null +++ b/EyeLights_Googly_Rings/EyeLights_Googly_Rings/EyeLights_Googly_Rings.ino @@ -0,0 +1,113 @@ +// SPDX-FileCopyrightText: 2021 Phil Burgess for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +/* +GOOGLY EYES for Adafruit EyeLight LED glasses + driver. Pendulum physics +simulation using accelerometer and math. This uses only the rings, not the +matrix portion. Adapted from Bill Earl's STEAM-Punk Goggles project: +https://learn.adafruit.com/steam-punk-goggles +*/ + +#include // For LED driver +#include // For accelerometer +#include // For m/s^2 accel units + +Adafruit_LIS3DH accel; +Adafruit_EyeLights_buffered glasses; // Buffered for smooth animation + +// A small class for our pendulum simulation. +class Pendulum { +public: + // Constructor. Pass pointer to EyeLights ring, and a 3-byte color array. + Pendulum(Adafruit_EyeLights_Ring_buffered *r, uint8_t *c) { + ring = r; + color = c; + // Initial pendulum position, plus axle friction, are randomized + // so rings don't spin in perfect lockstep. + angle = random(1000); + momentum = 0.0; + friction = 0.94 + random(300) * 0.0001; // Inverse friction, really + } + + // Given a pixel index (0-23) and a scaling factor (0.0-1.0), + // interpolate between LED "off" color (at 0.0) and this item's fully- + // lit color (at 1.0) and set pixel to the result. + void interp(uint8_t pixel, float scale) { + // Convert separate red, green, blue to "packed" 24-bit RGB value + ring->setPixelColor(pixel, + (int(color[0] * scale) << 16) | + (int(color[1] * scale) << 8) | + int(color[2] * scale)); + } + + // Given an accelerometer reading, run one cycle of the pendulum + // physics simulation and render the corresponding LED ring. + void iterate(sensors_event_t &event) { + // Minus here is because LED pixel indices run clockwise vs. trigwise. + // 0.006 is just an empirically-derived scaling fudge factor that looks + // good; smaller values for more sluggish rings, higher = more twitch. + momentum = momentum * friction - 0.006 * + (cos(angle) * event.acceleration.z + + sin(angle) * event.acceleration.x); + angle += momentum; + + // Scale pendulum angle into pixel space + float midpoint = fmodf(angle * 12.0 / M_PI, 24.0); + + // Go around the whole ring, setting each pixel based on proximity + // (this is also to erase the prior position)... + for (uint8_t i=0; i<24; i++) { + float dist = fabs(midpoint - (float)i); // Pixel to pendulum distance... + if (dist > 12.0) // If it crosses the "seam" at top, + dist = 24.0 - dist; // take the shorter path. + if (dist > 5.0) // Not close to pendulum, + ring->setPixelColor(i, 0); // erase pixel. + else if (dist < 2.0) // Close to pendulum, + interp(i, 1.0); // solid color + else // Anything in-between, + interp(i, (5.0 - dist) / 3.0); // interpolate + } + } +private: + Adafruit_EyeLights_Ring_buffered *ring; // -> glasses ring + uint8_t *color; // -> array of 3 uint8_t's [R,G,B] + float angle; // Current position around ring + float momentum; // Current 'oomph' + float friction; // A scaling constant to dampen motion +}; + +Pendulum pendulums[] = { + Pendulum(&glasses.left_ring, (uint8_t[3]){0, 20, 50}), // Cerulean blue, + Pendulum(&glasses.right_ring, (uint8_t[3]){0, 20, 50}), // 50 is plenty bright! +}; +#define N_PENDULUMS (sizeof pendulums / sizeof pendulums[0]) + +// Crude error handler, prints message to Serial console, flashes LED +void err(char *str, uint8_t hz) { + Serial.println(str); + pinMode(LED_BUILTIN, OUTPUT); + for (;;) digitalWrite(LED_BUILTIN, (millis() * hz / 500) & 1); +} + +void setup() { // Runs once at program start... + + // Initialize hardware + Serial.begin(115200); + if (! accel.begin()) err("LIS3DH not found", 5); + if (! glasses.begin()) err("IS3741 not found", 2); + + // Configure glasses for max brightness, enable output + glasses.setLEDscaling(0xFF); + glasses.setGlobalCurrent(0xFF); + glasses.enable(true); +} + +void loop() { // Repeat forever... + sensors_event_t event; + accel.getEvent(&event); // Read accelerometer once + for (uint8_t i=0; i dynamic_level: + # Got louder. Move level up quickly but allow initial "bump." + dynamic_level = upper * 0.7 + dynamic_level * 0.3 + else: + # Got quieter. Ease level down, else too many bumps. + dynamic_level = dynamic_level * 0.5 + lower * 0.5 + + # Apply vertical scale to spectrum data. Results may exceed + # matrix height...that's OK, adds impact! + #data = (spectrum - lower) * (7 / (dynamic_level - lower)) + data = (spectrum - lower) * ((glasses.height + 2) / (dynamic_level - lower)) + + for column, element in enumerate(column_table): + # Start BELOW matrix and accumulate bin weights UP, saves math + first_bin = element[0] + column_top = glasses.height + 1 + for bin_offset, weight in enumerate(element[1]): + column_top -= data[first_bin + bin_offset] * weight + + if column_top < element[3]: # Above current falling dot? + element[3] = column_top - 0.5 # Move dot up + element[4] = 0 # and clear out velocity + else: + element[3] += element[4] # Move dot down + element[4] += 0.2 # and accelerate + + column_top = int(column_top) # Quantize to pixel space + for row in range(column_top): # Erase area above column + glasses.pixel(column, row, 0) + for row in range(column_top, glasses.height): # Draw column + glasses.pixel(column, row, element[2]) + glasses.pixel(column, int(element[3]), 0xE08080) # Draw peak dot + + glasses.show() # Buffered mode MUST use show() to refresh matrix + + frames += 1 + # print(frames / (monotonic() - start_time), "FPS") + + except OSError: # See "try" notes above regarding rare I2C errors. + print("Restarting") + reload() diff --git a/Feather_Sense_Audio_Visualizer_13x9_RGB_LED_Matrix/code.py b/Feather_Sense_Audio_Visualizer_13x9_RGB_LED_Matrix/waterfall_visualizer/code.py similarity index 100% rename from Feather_Sense_Audio_Visualizer_13x9_RGB_LED_Matrix/code.py rename to Feather_Sense_Audio_Visualizer_13x9_RGB_LED_Matrix/waterfall_visualizer/code.py diff --git a/Grand_Central_Robot_Xylophone/code.py b/Grand_Central_Robot_Xylophone/code.py index 1d4a6f4e..c365dba8 100644 --- a/Grand_Central_Robot_Xylophone/code.py +++ b/Grand_Central_Robot_Xylophone/code.py @@ -1,5 +1,5 @@ # Adafruit Grand Central Robot Xylophone Demo Program -# Dano Wall and Mike Barela for Adafruit Industries +# Dano Wall and Anne Barela for Adafruit Industries # MIT License import time diff --git a/Halloween_Countdown_Matrix/code.py b/Halloween_Countdown_Matrix/code.py index 750f66a8..ea28ccc4 100755 --- a/Halloween_Countdown_Matrix/code.py +++ b/Halloween_Countdown_Matrix/code.py @@ -2,7 +2,7 @@ import time import board from adafruit_matrixportal.matrixportal import MatrixPortal -EVENT_YEAR = 2020 +EVENT_YEAR = 2021 EVENT_MONTH = 10 EVENT_DAY = 31 EVENT_HOUR = 17 diff --git a/IrRobotControl/glove/code.py b/IrRobotControl/glove/code.py index f81b783f..866a60de 100644 --- a/IrRobotControl/glove/code.py +++ b/IrRobotControl/glove/code.py @@ -2,7 +2,6 @@ import time import busio import board import pulseio -import pwmio import adafruit_irremote import adafruit_lis3dh @@ -26,9 +25,8 @@ TRANSMIT_DELAY = 0.1 i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA) sensor = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19) -# Create a 'pwmio' output, to send infrared signals on the IR transmitter @ 38KHz -pwm = pwmio.PWMOut(board.IR_TX, frequency=38000, duty_cycle=2 ** 15) -pulseout = pulseio.PulseOut(pwm) +# Create a 'pulseio' output, to send infrared signals on the IR transmitter @ 38KHz +pulseout = pulseio.PulseOut(board.IR_TX, frequency=38000, duty_cycle=2 ** 15) # Create an encoder that will take numbers and turn them into IR pulses encoder = adafruit_irremote.GenericTransmit(header=[9500, 4500], diff --git a/MagTag_Google_Calendar/authenticator/code.py b/MagTag_Google_Calendar/authenticator.py similarity index 100% rename from MagTag_Google_Calendar/authenticator/code.py rename to MagTag_Google_Calendar/authenticator.py diff --git a/MagTag_Progress_Displays/fonts/leaguespartan.license b/MagTag_Progress_Displays/weblate_translated_percent/fonts/leaguespartan.license similarity index 100% rename from MagTag_Progress_Displays/fonts/leaguespartan.license rename to MagTag_Progress_Displays/weblate_translated_percent/fonts/leaguespartan.license diff --git a/MagTag_Progress_Displays/fonts/leaguespartan11.bdf b/MagTag_Progress_Displays/weblate_translated_percent/fonts/leaguespartan11.bdf similarity index 100% rename from MagTag_Progress_Displays/fonts/leaguespartan11.bdf rename to MagTag_Progress_Displays/weblate_translated_percent/fonts/leaguespartan11.bdf diff --git a/MagTag_Progress_Displays/fonts/leaguespartan18.bdf b/MagTag_Progress_Displays/weblate_translated_percent/fonts/leaguespartan18.bdf similarity index 100% rename from MagTag_Progress_Displays/fonts/leaguespartan18.bdf rename to MagTag_Progress_Displays/weblate_translated_percent/fonts/leaguespartan18.bdf diff --git a/MagTag_Progress_Displays/fonts/epilogue.license b/MagTag_Progress_Displays/year_progress_percent/fonts/epilogue.license similarity index 100% rename from MagTag_Progress_Displays/fonts/epilogue.license rename to MagTag_Progress_Displays/year_progress_percent/fonts/epilogue.license diff --git a/MagTag_Progress_Displays/fonts/epilogue18.bdf b/MagTag_Progress_Displays/year_progress_percent/fonts/epilogue18.bdf similarity index 100% rename from MagTag_Progress_Displays/fonts/epilogue18.bdf rename to MagTag_Progress_Displays/year_progress_percent/fonts/epilogue18.bdf diff --git a/Make_It_Talk/code.py b/Make_It_Talk/code.py index cff84e1e..6111b465 100644 --- a/Make_It_Talk/code.py +++ b/Make_It_Talk/code.py @@ -2,7 +2,7 @@ # Coded for Circuit Playground Express but it may be # modified for any CircuitPython board with changes to # button, thermister and audio board definitions. -# Mike Barela for Adafruit Industries, MIT License +# Anne Barela for Adafruit Industries, MIT License import time import board diff --git a/Make_It_Twist_Potentiometer/analog-read/analog-read.ino b/Make_It_Twist_Potentiometer/analog-read/analog-read.ino index 970e97b2..0b97d245 100644 --- a/Make_It_Twist_Potentiometer/analog-read/analog-read.ino +++ b/Make_It_Twist_Potentiometer/analog-read/analog-read.ino @@ -1,5 +1,5 @@ // Simple read analog potentiometer on Circuit Playground Express or other board with pin change -// Mike Barela for Adafruit Industries 9/2018 +// Anne Barela for Adafruit Industries 9/2018 #define ANALOGPIN A1 // For Circuit Playground Express diff --git a/Make_It_Twist_Potentiometer/potentiometer-neopixels/potentiometer-neopixels.ino b/Make_It_Twist_Potentiometer/potentiometer-neopixels/potentiometer-neopixels.ino index cf62046f..f92e7a1e 100644 --- a/Make_It_Twist_Potentiometer/potentiometer-neopixels/potentiometer-neopixels.ino +++ b/Make_It_Twist_Potentiometer/potentiometer-neopixels/potentiometer-neopixels.ino @@ -1,5 +1,5 @@ // Read analog potentiometer on Circuit Playground Express or other board with changes -// Mike Barela for Adafruit Industries 9/2018 based on +// Anne Barela for Adafruit Industries 9/2018 based on // NeoPixel Ring simple sketch (c) 2013 Shae Erisson // released under the GPLv3 license to match the rest of the AdaFruit NeoPixel library diff --git a/Mini_Chair_Swing_Ride/code.py b/Mini_Chair_Swing_Ride/code.py index edfe0591..46b4b21d 100644 --- a/Mini_Chair_Swing_Ride/code.py +++ b/Mini_Chair_Swing_Ride/code.py @@ -1,5 +1,5 @@ # Isaac Wellish -# Code adapted from Mike Barela's Hello World of Robotics and +# Code adapted from Anne Barela's Hello World of Robotics and # Make it Move with Crickit guides at learn.adafruit.com # Power must be plugged into right side of motor 1 on CRICKIT # to turn counter clock wise diff --git a/Music_Box_with_Crickit/code.py b/Music_Box_with_Crickit/code.py index f0cfc375..b2a83de6 100644 --- a/Music_Box_with_Crickit/code.py +++ b/Music_Box_with_Crickit/code.py @@ -1,4 +1,4 @@ -# Music Box code in CircuitPython - Dano Wall and Mike Barela +# Music Box code in CircuitPython - Dano Wall and Anne Barela # Revised by Ladyada 2019-01-16 from adafruit_crickit import crickit diff --git a/NeoTrellis_Paint/code.py b/NeoTrellis_Paint/code.py index 21ad785c..ee43661f 100644 --- a/NeoTrellis_Paint/code.py +++ b/NeoTrellis_Paint/code.py @@ -1,7 +1,7 @@ # Simple paint program for Trellis M4 Express # Press any button it will cycle through a palette of colors! # -# Mike Barela for Adafruit Industries November, 2018 +# Anne Barela for Adafruit Industries November, 2018 # import time import adafruit_trellism4 diff --git a/NeoTrellis_Soundbox/README.md b/NeoTrellis_Soundbox/README.md index 67c7957f..1fcaf2f3 100644 --- a/NeoTrellis_Soundbox/README.md +++ b/NeoTrellis_Soundbox/README.md @@ -8,7 +8,7 @@ Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from [Adafruit](https://www.adafruit.com)! -MIT license, code by Mike Barela, project by the Ruiz Brothers +MIT license, code by Anne Barela, project by the Ruiz Brothers All text above, and the splash screen below must be included in any redistribution diff --git a/NeoTrellis_Soundbox/code.py b/NeoTrellis_Soundbox/code.py index fc2693f9..0cdc1ca7 100644 --- a/NeoTrellis_Soundbox/code.py +++ b/NeoTrellis_Soundbox/code.py @@ -1,5 +1,5 @@ # NeoTrellis Soundbox Remix - CircuitPython -# Noe and Pedro Ruiz, code by Mike Barela +# Noe and Pedro Ruiz, code by Anne Barela # for Adafruit Industries, MIT License import time diff --git a/PaperCraft_Gems/code.py b/PaperCraft_Gems/code.py index 9498a448..0b8f87c0 100644 --- a/PaperCraft_Gems/code.py +++ b/PaperCraft_Gems/code.py @@ -4,7 +4,7 @@ https://learn.adafruit.com/no-solder-papercraft-crystal-light-strand Circuit Playground Bluetooth with LED strand attached runs 4 different variable animation modes. -Code by Roy Hooper using Adafruit's LED Animation Library: +Code by Rose Hooper using Adafruit's LED Animation Library: https://learn.adafruit.com/circuitpython-led-animations/overview """ # pylint: disable=attribute-defined-outside-init diff --git a/Pico_Four_Keypad/code.py b/Pico_Four_Keypad/code.py new file mode 100644 index 00000000..73fe3747 --- /dev/null +++ b/Pico_Four_Keypad/code.py @@ -0,0 +1,47 @@ +# SPDX-FileCopyrightText: 2021 john park for Adafruit Industries +# SPDX-License-Identifier: MIT +# Pico Four Key USB HID Keypad + +import board +from digitalio import DigitalInOut, Pull +from adafruit_debouncer import Debouncer +import usb_hid +from adafruit_hid.keyboard import Keyboard +from adafruit_hid.keycode import Keycode + +kpd = Keyboard(usb_hid.devices) + +# define buttons +num_keys = 4 +pins = ( + board.GP0, + board.GP1, + board.GP2, + board.GP3 +) + +keys = [] +for pin in pins: + tmp_pin = DigitalInOut(pin) + tmp_pin.pull = Pull.UP + keys.append(Debouncer(tmp_pin)) + +keymap = { + (0): ("Select all", [Keycode.GUI, Keycode.A]), + (1): ("Cut", [Keycode.GUI, Keycode.X]), + (2): ("Copy", [Keycode.GUI, Keycode.C]), + (3): ("Paste", [Keycode.GUI, Keycode.V]) +} + +print("\nWelcome to keypad") +print("keymap:") +for k in range(num_keys): + print("\t", (keymap[k][0])) + + +while True: + for i in range(num_keys): + keys[i].update() + if keys[i].fell: + print(keymap[i][0]) + kpd.send(*keymap[i][1]) diff --git a/PyGamer_Bounce_Game/README.md b/PyGamer_Bounce_Game/README.md index 4995a925..5d3c22a0 100644 --- a/PyGamer_Bounce_Game/README.md +++ b/PyGamer_Bounce_Game/README.md @@ -8,10 +8,10 @@ All the required libraries are listed at https://learn.adafruit.com/adafruit-pyb Two files in the bounce directory: bounce.ino (the game) and logo.h (data for the Adafruit logo used on the splash screen). Load both into the Arduino IDE. -Mike Barela, June 3, 2019 for Adafruit Industries +Anne Barela, June 3, 2019 for Adafruit Industries This is a mod of game by R0D0T posted on http://r0d0t.tumblr.com/post/29641975900 and Hackaday http://hackaday.com/2012/10/01/fantastic-programming-makes-this-arduino-gaming-device-something-special/ -which was published for Arduino Esplora by Mike Barela 2013 +which was published for Arduino Esplora by Anne Barela 2013 Support Open Source development by buying your materials at [Adafruit.com](https://www.adafruit.com/). diff --git a/PyGamer_Bounce_Game/bounce/bounce.ino b/PyGamer_Bounce_Game/bounce/bounce.ino index 16d5e339..ec62caa5 100644 --- a/PyGamer_Bounce_Game/bounce/bounce.ino +++ b/PyGamer_Bounce_Game/bounce/bounce.ino @@ -1,10 +1,10 @@ // Adafruit Arcada based Level Bounce Game // -// Mike Barela, June 3, 2019 for Adafruit Industries +// Anne Barela, June 3, 2019 for Adafruit Industries // // Mod of game by R0D0T posted on http://r0d0t.tumblr.com/post/29641975900 and // Hackaday http://hackaday.com/2012/10/01/fantastic-programming-makes-this-arduino-gaming-device-something-special/ -// which was published for Arduino Esplora by Mike Barela 2013 +// which was published for Arduino Esplora by Anne Barela 2013 #include #include diff --git a/ROB_Control/code.py b/ROB_Control/code.py index 5fd20d46..ea84a33d 100644 --- a/ROB_Control/code.py +++ b/ROB_Control/code.py @@ -1,6 +1,6 @@ # Nintendo R.O.B. control with Accelerometer, code in CircuitPython # Using an Adafruit Circuit Playground Express board with an IR LED -# Mike Barela for Adafruit Industries, MIT License, May, 2018 +# Anne Barela for Adafruit Industries, MIT License, May, 2018 # Acknowledgement to info at http://atariage.com/forums/topic/177286 # -any-interest-in-nes-rob-homebrews/ and Limor Ladyada Fried diff --git a/Stumblebot/code.py b/Stumblebot/code.py index 29be3661..6e2b784f 100644 --- a/Stumblebot/code.py +++ b/Stumblebot/code.py @@ -1,6 +1,6 @@ # Stumble bot, coded in CircuitPython # Using an Adafruit Circuit Playground Express, Crickit, and 2 servos -# Dano Wall, Mike Barela for Adafruit Industries, MIT License, May, 2018 +# Dano Wall, Anne Barela for Adafruit Industries, MIT License, May, 2018 # import time import board diff --git a/Tilemap_Game_With_CircuitPython/basic_movement/code.py b/Tilemap_Game_With_CircuitPython/basic_movement/code.py index 7413fba5..2a1604ee 100644 --- a/Tilemap_Game_With_CircuitPython/basic_movement/code.py +++ b/Tilemap_Game_With_CircuitPython/basic_movement/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 FoamyGuy for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import board import displayio import adafruit_imageload diff --git a/Tilemap_Game_With_CircuitPython/basic_movement_transparent_sprite/code.py b/Tilemap_Game_With_CircuitPython/basic_movement_transparent_sprite/code.py index 233ae7f3..00696faf 100644 --- a/Tilemap_Game_With_CircuitPython/basic_movement_transparent_sprite/code.py +++ b/Tilemap_Game_With_CircuitPython/basic_movement_transparent_sprite/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 FoamyGuy for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import board import displayio import adafruit_imageload diff --git a/Tilemap_Game_With_CircuitPython/basic_rendering/code.py b/Tilemap_Game_With_CircuitPython/basic_rendering/code.py index 1c27e82e..2e010ce7 100644 --- a/Tilemap_Game_With_CircuitPython/basic_rendering/code.py +++ b/Tilemap_Game_With_CircuitPython/basic_rendering/code.py @@ -1,3 +1,8 @@ +# SPDX-FileCopyrightText: 2019 Carter Nelson for Adafruit Industries +# SPDX-FileCopyrightText: 2020 FoamyGuy for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import board import displayio import adafruit_imageload diff --git a/Tilemap_Game_With_CircuitPython/code.py b/Tilemap_Game_With_CircuitPython/code.py index 1885dba0..afd182fa 100644 --- a/Tilemap_Game_With_CircuitPython/code.py +++ b/Tilemap_Game_With_CircuitPython/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 FoamyGuy for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import time import random import gc diff --git a/Tilemap_Game_With_CircuitPython/tilegame_assets/__init__.py b/Tilemap_Game_With_CircuitPython/tilegame_assets/__init__.py index e69de29b..58d656b4 100644 --- a/Tilemap_Game_With_CircuitPython/tilegame_assets/__init__.py +++ b/Tilemap_Game_With_CircuitPython/tilegame_assets/__init__.py @@ -0,0 +1,4 @@ +# SPDX-FileCopyrightText: 2018 Limor Fried/ladyada for Adafruit Industries +# SPDX-FileCopyrightText: 2019 Brennen Bearnes for Adafruit Industries +# +# SPDX-License-Identifier: MIT diff --git a/Tilemap_Game_With_CircuitPython/tilegame_assets/fun_facts.py b/Tilemap_Game_With_CircuitPython/tilegame_assets/fun_facts.py index ac2647b8..fdc1c0cd 100644 --- a/Tilemap_Game_With_CircuitPython/tilegame_assets/fun_facts.py +++ b/Tilemap_Game_With_CircuitPython/tilegame_assets/fun_facts.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 FoamyGuy for Adafruit Industries +# +# SPDX-License-Identifier: MIT + # pylint: disable=line-too-long # Fun facts to be read to the player by Minerva FACTS = [ diff --git a/Tilemap_Game_With_CircuitPython/tilegame_assets/states.py b/Tilemap_Game_With_CircuitPython/tilegame_assets/states.py index 3de05b70..bed51224 100644 --- a/Tilemap_Game_With_CircuitPython/tilegame_assets/states.py +++ b/Tilemap_Game_With_CircuitPython/tilegame_assets/states.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 FoamyGuy for Adafruit Industries +# +# SPDX-License-Identifier: MIT + # State machine constants # playing the game: draw the map, listen for D-pad buttons to move player diff --git a/Tilemap_Game_With_CircuitPython/tilegame_assets/text_helper.py b/Tilemap_Game_With_CircuitPython/tilegame_assets/text_helper.py index 5c84dd93..581386a2 100644 --- a/Tilemap_Game_With_CircuitPython/tilegame_assets/text_helper.py +++ b/Tilemap_Game_With_CircuitPython/tilegame_assets/text_helper.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 FoamyGuy for Adafruit Industries +# +# SPDX-License-Identifier: MIT + def wrap_nicely(string, max_chars): """ From: https://www.richa1.com/RichardAlbritton/circuitpython-word-wrap-for-label-text/ A helper that will return the string with word-break wrapping. diff --git a/Tilemap_Game_With_CircuitPython/tilegame_assets/tiles.py b/Tilemap_Game_With_CircuitPython/tilegame_assets/tiles.py index 9e3c0ea1..35c10615 100644 --- a/Tilemap_Game_With_CircuitPython/tilegame_assets/tiles.py +++ b/Tilemap_Game_With_CircuitPython/tilegame_assets/tiles.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 FoamyGuy for Adafruit Industries +# +# SPDX-License-Identifier: MIT + from tilegame_assets.states import ( STATE_MAPWIN, STATE_LOST_SPARKY, diff --git a/Tilt_Controlled_Servo_Driver/code.py b/Tilt_Controlled_Servo_Driver/code.py index a4271ce0..ec693232 100644 --- a/Tilt_Controlled_Servo_Driver/code.py +++ b/Tilt_Controlled_Servo_Driver/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 Melissa LeBlanc-Williams for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ In this Demo we will drive two servos based on the Tilt along the Y and Z axis of the BNO055 9-Degrees of Freedom IMU Sensor. This could easily be extended diff --git a/Tiny_Music_Visualizer/Piccolo/Piccolo.ino b/Tiny_Music_Visualizer/Piccolo/Piccolo.ino index abf6d6c2..1d357795 100644 --- a/Tiny_Music_Visualizer/Piccolo/Piccolo.ino +++ b/Tiny_Music_Visualizer/Piccolo/Piccolo.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Phillip Burgess/paintyourdragon for Adafruit Industries +// +// SPDX-License-Identifier: BSD + /* PICCOLO is a tiny Arduino-based audio visualizer. Hardware requirements: diff --git a/Tiny_Music_Visualizer/Piccolo/ffft.h b/Tiny_Music_Visualizer/Piccolo/ffft.h index a684f3ad..7f837bd1 100644 --- a/Tiny_Music_Visualizer/Piccolo/ffft.h +++ b/Tiny_Music_Visualizer/Piccolo/ffft.h @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Phillip Burgess/paintyourdragon for Adafruit Industries +// +// SPDX-License-Identifier: BSD + #ifndef FFT_N #define FFT_N 128 /* Number of samples (64,128,256,512). */ #endif /* FFT_N */ diff --git a/Track_Your_Treats/Track_Your_Treats/Track_Your_Treats.ino b/Track_Your_Treats/Track_Your_Treats/Track_Your_Treats.ino index 51a6256f..5ff5d941 100644 --- a/Track_Your_Treats/Track_Your_Treats/Track_Your_Treats.ino +++ b/Track_Your_Treats/Track_Your_Treats/Track_Your_Treats.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Tony DiCola for Adafruit Industries +// +// SPDX-License-Identifier: MIT + // Track Your Treats - Ultimate GPS Shield Halloween Candy Route Tracker // Author: Tony DiCola // diff --git a/Track_Your_Treats/Track_Your_Treats_FONA808/Track_Your_Treats_FONA808.ino b/Track_Your_Treats/Track_Your_Treats_FONA808/Track_Your_Treats_FONA808.ino index 6243f08e..480fe908 100644 --- a/Track_Your_Treats/Track_Your_Treats_FONA808/Track_Your_Treats_FONA808.ino +++ b/Track_Your_Treats/Track_Your_Treats_FONA808/Track_Your_Treats_FONA808.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Tony DiCola for Adafruit Industries +// +// SPDX-License-Identifier: MIT + // Track Your Treats - FONA808 Shield & Adafruit IO Halloween Candy Route Tracker // Author: Tony DiCola // diff --git a/Trash_Panda/code.py b/Trash_Panda/code.py index af638c01..b42184b2 100644 --- a/Trash_Panda/code.py +++ b/Trash_Panda/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Limor Fried/ladyada for Adafruit Industries +# +# SPDX-License-Identifier: MIT + # Code for the Trash Panda tutorial with Adafruit Crickit and Circuit Playground Express import time import board diff --git a/TrelliBird/bird.py b/TrelliBird/bird.py index ad10c246..40b8902b 100644 --- a/TrelliBird/bird.py +++ b/TrelliBird/bird.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Dave Astels for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ FlappyBird type game for the NeoTrellisM4 diff --git a/TrelliBird/code.py b/TrelliBird/code.py index ced21702..02cb1366 100644 --- a/TrelliBird/code.py +++ b/TrelliBird/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Dave Astels for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ FlappyBird type game for the NeoTrellisM4 diff --git a/TrelliBird/color_names.py b/TrelliBird/color_names.py index 86adc345..27665f7a 100644 --- a/TrelliBird/color_names.py +++ b/TrelliBird/color_names.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Dave Astels for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ RGB Color Names diff --git a/TrelliBird/game.py b/TrelliBird/game.py index 430a73db..4949ddd1 100644 --- a/TrelliBird/game.py +++ b/TrelliBird/game.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Dave Astels for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ FlappyBird type game for the NeoTrellisM4 diff --git a/TrelliBird/post.py b/TrelliBird/post.py index 2090c511..2b56cc27 100644 --- a/TrelliBird/post.py +++ b/TrelliBird/post.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Dave Astels for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ FlappyBird type game for the NeoTrellisM4 diff --git a/TrellisM4_Simple_MIDI_UART/code.py b/TrellisM4_Simple_MIDI_UART/code.py index 0a45e53f..77270367 100644 --- a/TrellisM4_Simple_MIDI_UART/code.py +++ b/TrellisM4_Simple_MIDI_UART/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 John Park for Adafruit Industries +# +# SPDX-License-Identifier: MIT + # Simple example of sending MIDI via UART to classic DIN-5 (not USB) synth import adafruit_trellism4 diff --git a/Trellis_M4_Synth_Design/Design_Tool_Synth_TrellisM4/Design_Tool_Synth_TrellisM4.ino b/Trellis_M4_Synth_Design/Design_Tool_Synth_TrellisM4/Design_Tool_Synth_TrellisM4.ino index 0f8ae9ec..1afee295 100644 --- a/Trellis_M4_Synth_Design/Design_Tool_Synth_TrellisM4/Design_Tool_Synth_TrellisM4.ino +++ b/Trellis_M4_Synth_Design/Design_Tool_Synth_TrellisM4/Design_Tool_Synth_TrellisM4.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2018 John Park for Adafruit Industries +// +// SPDX-License-Identifier: MIT + /* Audio library demonstration - pocket synth with C major scale and 4 wave types */ //each row is a different waveform, envelope, and effect set in major scale // row 0 sine, soft attack, long release ADSR diff --git a/Trellis_M4_Synth_Design/ToneSweep_TrellisM4/ToneSweep_TrellisM4.ino b/Trellis_M4_Synth_Design/ToneSweep_TrellisM4/ToneSweep_TrellisM4.ino index c913f8bc..ce3ce47a 100644 --- a/Trellis_M4_Synth_Design/ToneSweep_TrellisM4/ToneSweep_TrellisM4.ino +++ b/Trellis_M4_Synth_Design/ToneSweep_TrellisM4/ToneSweep_TrellisM4.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2018 John Park for Adafruit Industries +// +// SPDX-License-Identifier: MIT + /* Audio Library on Trellis M4 Demo of the audio sweep function. diff --git a/Trellis_M4_Synth_Design/Waveform_Mod_TrellisM4/Waveform_Mod_TrellisM4.ino b/Trellis_M4_Synth_Design/Waveform_Mod_TrellisM4/Waveform_Mod_TrellisM4.ino index 9bac09b1..9987883b 100644 --- a/Trellis_M4_Synth_Design/Waveform_Mod_TrellisM4/Waveform_Mod_TrellisM4.ino +++ b/Trellis_M4_Synth_Design/Waveform_Mod_TrellisM4/Waveform_Mod_TrellisM4.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2018 John Park for Adafruit Industries +// +// SPDX-License-Identifier: MIT + // Trellis M4 Audio Workshop // shows how to alter pitch with accelerometer // Waveform Mod diff --git a/Trinket_Gemma_Blinky_Eyes/Trinket_Gemma_Blinky_Eyes.ino b/Trinket_Gemma_Blinky_Eyes/Trinket_Gemma_Blinky_Eyes.ino index 22cc2e2c..be91f55b 100644 --- a/Trinket_Gemma_Blinky_Eyes/Trinket_Gemma_Blinky_Eyes.ino +++ b/Trinket_Gemma_Blinky_Eyes/Trinket_Gemma_Blinky_Eyes.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries +// +// SPDX-License-Identifier: GPLv3 + /* Name: Blinking Eyes - based on code by Brad Blumenthal, MAKE Magazine License: GPLv3 diff --git a/Trinket_Gemma_Blinky_Eyes/code.py b/Trinket_Gemma_Blinky_Eyes/code.py index 58fae097..2e09bf1c 100644 --- a/Trinket_Gemma_Blinky_Eyes/code.py +++ b/Trinket_Gemma_Blinky_Eyes/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries +# +# SPDX-License-Identifier: GPLv3 + """ Blinking Eyes - based on code by Brad Blumenthal, MAKE Magazine License: GPLv3 diff --git a/Trinket_Gemma_IR_Control/IR_reader/IR_reader.ino b/Trinket_Gemma_IR_Control/IR_reader/IR_reader.ino index 66fd0624..d1e8290d 100644 --- a/Trinket_Gemma_IR_Control/IR_reader/IR_reader.ino +++ b/Trinket_Gemma_IR_Control/IR_reader/IR_reader.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2018 Limor Fried/ladyada for Adafruit Industries +// +// SPDX-License-Identifier: CC-BY-SA-3.0 + /* Trinket/Gemma compatible Raw IR decoder sketch This sketch/program uses an Adafruit Trinket or Gemma ATTiny85 based mini microcontroller and a PNA4602 to diff --git a/Trinket_Gemma_IR_Control/IR_reader/code.py b/Trinket_Gemma_IR_Control/IR_reader/code.py index 29c9d21b..c8cb36be 100644 --- a/Trinket_Gemma_IR_Control/IR_reader/code.py +++ b/Trinket_Gemma_IR_Control/IR_reader/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import time import adafruit_irremote diff --git a/Trinket_Gemma_IR_Control/Trinket_Gemma_IR_Control/Trinket_Gemma_IR_Control.ino b/Trinket_Gemma_IR_Control/Trinket_Gemma_IR_Control/Trinket_Gemma_IR_Control.ino index 1a34a5b8..939bf971 100644 --- a/Trinket_Gemma_IR_Control/Trinket_Gemma_IR_Control/Trinket_Gemma_IR_Control.ino +++ b/Trinket_Gemma_IR_Control/Trinket_Gemma_IR_Control/Trinket_Gemma_IR_Control.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries +// +// SPDX-License-Identifier: MIT + /* Trinket/Gemma compatible IR read sketch This sketch/program uses an Adafruit Trinket or Gemma ATTiny85 based mini microcontroller and a PNA4602 or TSOP38238 to diff --git a/Trinket_Gemma_IR_Control/Trinket_Gemma_IR_Control/code.py b/Trinket_Gemma_IR_Control/Trinket_Gemma_IR_Control/code.py index 676935f9..fa9d397b 100644 --- a/Trinket_Gemma_IR_Control/Trinket_Gemma_IR_Control/code.py +++ b/Trinket_Gemma_IR_Control/Trinket_Gemma_IR_Control/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ IR codes for button 0, 1, 2, 3 these were acquired from the Adafruit Mini Remote Control #389 diff --git a/Trinket_Gemma_Mini_Theramin/Trinket_Gemma_Mini_Theramin.ino b/Trinket_Gemma_Mini_Theramin/Trinket_Gemma_Mini_Theramin.ino index 5b5abe1e..c4e7a1c7 100644 --- a/Trinket_Gemma_Mini_Theramin/Trinket_Gemma_Mini_Theramin.ino +++ b/Trinket_Gemma_Mini_Theramin/Trinket_Gemma_Mini_Theramin.ino @@ -1,7 +1,7 @@ -// SPDX-FileCopyrightText: 2017 Anne Barela for Adafruit Industries +// SPDX-FileCopyrightText: 2017 Limor Fried/ladyada for Adafruit Industries +// SPDX-FileCopyrightText: 2017 Phillip Burgess for Adafruit Industries // // SPDX-License-Identifier: MIT -// /* Adafruit Trinket/Gemma Example: Simple Theramin Read the voltage from a Cadmium Sulfide (CdS) photocell voltage diff --git a/Trinket_Gemma_Mini_Theramin/code.py b/Trinket_Gemma_Mini_Theramin/code.py index 572443b6..a4ed0751 100644 --- a/Trinket_Gemma_Mini_Theramin/code.py +++ b/Trinket_Gemma_Mini_Theramin/code.py @@ -1,3 +1,8 @@ +# SPDX-FileCopyrightText: 2017 Limor Fried/ladyada for Adafruit Industries +# SPDX-FileCopyrightText: 2017 Phillip Burgess for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ Adafruit Trinket/Gemma Example: Simple Theramin Read the voltage from a Cadmium Sulfide (CdS) photocell voltage diff --git a/Trinket_Gemma_Servo_Control/Trinket_Gemma_Servo_Control.ino b/Trinket_Gemma_Servo_Control/Trinket_Gemma_Servo_Control.ino index 0a003c1c..11ddc724 100644 --- a/Trinket_Gemma_Servo_Control/Trinket_Gemma_Servo_Control.ino +++ b/Trinket_Gemma_Servo_Control/Trinket_Gemma_Servo_Control.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries +// +// SPDX-License-Identifier: MIT + /******************************************************************* SoftServo sketch for Adafruit Trinket. Turn the potentiometer knob to set the corresponding position on the servo diff --git a/Trinket_Gemma_Servo_Control/code.py b/Trinket_Gemma_Servo_Control/code.py index c58b1ab2..80c16924 100644 --- a/Trinket_Gemma_Servo_Control/code.py +++ b/Trinket_Gemma_Servo_Control/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries +# +# SPDX-License-Identifier: MIT + # Trinket Gemma Servo Control # for Adafruit M0 boards diff --git a/Trinket_Gemma_Space_Invader_Pendant/Trinket_Gemma_Space_Invader_Pendant.ino b/Trinket_Gemma_Space_Invader_Pendant/Trinket_Gemma_Space_Invader_Pendant.ino index e3a058fe..2d9972d3 100644 --- a/Trinket_Gemma_Space_Invader_Pendant/Trinket_Gemma_Space_Invader_Pendant.ino +++ b/Trinket_Gemma_Space_Invader_Pendant/Trinket_Gemma_Space_Invader_Pendant.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries +// +// SPDX-License-Identifier: MIT + // Trinket/Gemma + LED matrix backpack jewelry. Plays animated // sequence on LED matrix. Press reset button to display again, // or add optional momentary button between pin #1 and +V. diff --git a/Trinket_Gemma_Space_Invader_Pendant/anim.h b/Trinket_Gemma_Space_Invader_Pendant/anim.h index ad4f4821..c31f94b6 100644 --- a/Trinket_Gemma_Space_Invader_Pendant/anim.h +++ b/Trinket_Gemma_Space_Invader_Pendant/anim.h @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries +// +// SPDX-License-Identifier: MIT + // Animation data for Trinket/Gemma + LED matrix backpack jewelry. // Edit this file to change the animation; it's unlikely you'll need // to edit the source code. diff --git a/Trinket_Gemma_Space_Invader_Pendant/code.py b/Trinket_Gemma_Space_Invader_Pendant/code.py index ab02bed1..8b93f402 100644 --- a/Trinket_Gemma_Space_Invader_Pendant/code.py +++ b/Trinket_Gemma_Space_Invader_Pendant/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Phillip Burgess/paintyourdragon for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import time import adafruit_ht16k33.matrix diff --git a/Trinket_Modded_Stuffed_Animal/Trinket_Modded_Stuffed_Animal.ino b/Trinket_Modded_Stuffed_Animal/Trinket_Modded_Stuffed_Animal.ino index 804ddd37..0a86019a 100644 --- a/Trinket_Modded_Stuffed_Animal/Trinket_Modded_Stuffed_Animal.ino +++ b/Trinket_Modded_Stuffed_Animal/Trinket_Modded_Stuffed_Animal.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2018 Phillip Burgess/paintyourdragon for Adafruit Industries +// +// SPDX-License-Identifier: MIT + /******************************************************************* Adafruit Animal - control code for toy animal animation diff --git a/Trinket_Modded_Stuffed_Animal/code.py b/Trinket_Modded_Stuffed_Animal/code.py index 50770d24..8da76c6b 100644 --- a/Trinket_Modded_Stuffed_Animal/code.py +++ b/Trinket_Modded_Stuffed_Animal/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import time import analogio import board diff --git a/Trinket_Pro_Fire_Pendant/FirePendant/FirePendant.ino b/Trinket_Pro_Fire_Pendant/FirePendant/FirePendant.ino index 417d466d..aa26663d 100644 --- a/Trinket_Pro_Fire_Pendant/FirePendant/FirePendant.ino +++ b/Trinket_Pro_Fire_Pendant/FirePendant/FirePendant.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Phillip Burgess/paintyourdragon for Adafruit Industries +// +// SPDX-License-Identifier: MIT + //-------------------------------------------------------------------------- // Animated flame for Adafruit Pro Trinket. Uses the following parts: // - Pro Trinket microcontroller (adafruit.com/product/2010 or 2000) diff --git a/Trinket_Pro_Fire_Pendant/FirePendant/data.h b/Trinket_Pro_Fire_Pendant/FirePendant/data.h index 71f5f777..ac9f14ae 100644 --- a/Trinket_Pro_Fire_Pendant/FirePendant/data.h +++ b/Trinket_Pro_Fire_Pendant/FirePendant/data.h @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Phillip Burgess/paintyourdragon for Adafruit Industries +// +// SPDX-License-Identifier: MIT + // Data derived from Free Stock Video by user 'dietolog' on Videezy.com const uint8_t PROGMEM anim[] = { diff --git a/Trinket_Question_Block_Sound_Jewelry/Trinket_Question_Block_Sound_Jewelry.ino b/Trinket_Question_Block_Sound_Jewelry/Trinket_Question_Block_Sound_Jewelry.ino index 5186cdbf..2957a2bf 100644 --- a/Trinket_Question_Block_Sound_Jewelry/Trinket_Question_Block_Sound_Jewelry.ino +++ b/Trinket_Question_Block_Sound_Jewelry/Trinket_Question_Block_Sound_Jewelry.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2018 Phillip Burgess/paintyourdragon for Adafruit Industries +// +// SPDX-License-Identifier: MIT + /* ----------------------------------------------------------------------- Super Mario Bros-inspired coin sound for Adafruit Trinket & Gemma. @@ -173,4 +177,4 @@ ISR(TIMER0_COMPA_vect) { // Bit 0 of count indicates high or low side of square wave. // OCR1A sets average speaker pos, quietness adjusts amplitude. OCR1A = (count++ & 1) ? 255 - quietness : quietness; -} \ No newline at end of file +} diff --git a/Trinket_Question_Block_Sound_Jewelry/code.py b/Trinket_Question_Block_Sound_Jewelry/code.py index c621a98d..1c3e7102 100644 --- a/Trinket_Question_Block_Sound_Jewelry/code.py +++ b/Trinket_Question_Block_Sound_Jewelry/code.py @@ -1,3 +1,8 @@ +# SPDX-FileCopyrightText: 2017 Limor Fried/ladyada for Adafruit Industries +# SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import time import board import simpleio diff --git a/Trinket_React_Counter/TrinketReactCounter_14segment/TrinketReactCounter_14segment.ino b/Trinket_React_Counter/TrinketReactCounter_14segment/TrinketReactCounter_14segment.ino index 2466f819..03ffdf55 100644 --- a/Trinket_React_Counter/TrinketReactCounter_14segment/TrinketReactCounter_14segment.ino +++ b/Trinket_React_Counter/TrinketReactCounter_14segment/TrinketReactCounter_14segment.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Tony DiCola for Adafruit Industries +// +// SPDX-License-Identifier: MIT + // Adafruit Trinket React Counter Sketch - 14-segment quad alpha display // // Use a 14-segment quad alphanumeric LED backpack to display the diff --git a/Trinket_React_Counter/TrinketReactCounter_7segment/TrinketReactCounter_7segment.ino b/Trinket_React_Counter/TrinketReactCounter_7segment/TrinketReactCounter_7segment.ino index 79d93180..0c2a1c6c 100644 --- a/Trinket_React_Counter/TrinketReactCounter_7segment/TrinketReactCounter_7segment.ino +++ b/Trinket_React_Counter/TrinketReactCounter_7segment/TrinketReactCounter_7segment.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Tony DiCola for Adafruit Industries +// +// SPDX-License-Identifier: MIT + // Adafruit Trinket React Counter Sketch - 7-segment display // // Use a 7-segment LED backpack to display the number of times a diff --git a/Trinket_Ultrasonic_Rangefinder/Trinket_Ultrasonic_Rangefinder.ino b/Trinket_Ultrasonic_Rangefinder/Trinket_Ultrasonic_Rangefinder.ino index 789fbb87..43ddb7ef 100644 --- a/Trinket_Ultrasonic_Rangefinder/Trinket_Ultrasonic_Rangefinder.ino +++ b/Trinket_Ultrasonic_Rangefinder/Trinket_Ultrasonic_Rangefinder.ino @@ -1,3 +1,8 @@ +// SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries +// SPDX-FileCopyrightText: 2018 Anne Barela for Adafruit Industries +// +// SPDX-License-Identifier: MIT + /* Demonstration sketch for Adafruit LCD backpack using MCP23008 I2C expander and Maxbotic LV-EZ1 Ultrasonic Sensor @@ -18,7 +23,7 @@ by Bruce Allen and Bill Gentles Version 2.0 Adds Arduino IDE 1.6.7 and greater Wire support - Mike Barela for Adafruit Industries + Anne Barela for Adafruit Industries */ // include the library code diff --git a/Trinket_Ultrasonic_Rangefinder/code.py b/Trinket_Ultrasonic_Rangefinder/code.py index ba801063..3efd313d 100644 --- a/Trinket_Ultrasonic_Rangefinder/code.py +++ b/Trinket_Ultrasonic_Rangefinder/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Mikey Sklar for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ This Code uses the: * Adafruit LCD backpack using MCP23008 I2C expander diff --git a/Turtle_BLE_CPB_Crickit_Rover/code.py b/Turtle_BLE_CPB_Crickit_Rover/code.py index b19699e3..e07544a1 100644 --- a/Turtle_BLE_CPB_Crickit_Rover/code.py +++ b/Turtle_BLE_CPB_Crickit_Rover/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 John Park for Adafruit Industries +# +# SPDX-License-Identifier: MIT + # Circuit Playground Bluefruit Rover # Use with the Adafruit BlueFruit LE Connect app # Works with CircuitPython 5.0.0-beta.0 and later diff --git a/Twitch_On_Air_Sign/ESP8266_OnAirSign/ESP8266_OnAirSign.ino b/Twitch_On_Air_Sign/ESP8266_OnAirSign/ESP8266_OnAirSign.ino index c8f04e3e..75f01f78 100644 --- a/Twitch_On_Air_Sign/ESP8266_OnAirSign/ESP8266_OnAirSign.ino +++ b/Twitch_On_Air_Sign/ESP8266_OnAirSign/ESP8266_OnAirSign.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2018 Limor Fried for Adafruit Industries +// +// SPDX-License-Identifier: MIT + /* * Simple HTTP get webclient test */ diff --git a/Twitch_On_Air_Sign/WINC1500_OnAirSign/WINC1500_OnAirSign.ino b/Twitch_On_Air_Sign/WINC1500_OnAirSign/WINC1500_OnAirSign.ino index 22dc6e06..f5e2630b 100644 --- a/Twitch_On_Air_Sign/WINC1500_OnAirSign/WINC1500_OnAirSign.ino +++ b/Twitch_On_Air_Sign/WINC1500_OnAirSign/WINC1500_OnAirSign.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2018 Limor Fried for Adafruit Industries +// +// SPDX-License-Identifier: MIT + #include #include #include diff --git a/Twitter_API/code.py b/Twitter_API/code.py index 6e2e9f86..06c3edaf 100644 --- a/Twitter_API/code.py +++ b/Twitter_API/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 Dave Astels for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ Twitter API for PyPortal. diff --git a/USB_NeXT_Keyboard/USB_NeXT_Keyboard/USB_NeXT_Keyboard.ino b/USB_NeXT_Keyboard/USB_NeXT_Keyboard/USB_NeXT_Keyboard.ino index 5bd280a0..1c547cf0 100644 --- a/USB_NeXT_Keyboard/USB_NeXT_Keyboard/USB_NeXT_Keyboard.ino +++ b/USB_NeXT_Keyboard/USB_NeXT_Keyboard/USB_NeXT_Keyboard.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Limor Fried/ladyada for Adafruit Industries +// +// SPDX-License-Identifier: BSD + // NeXT non-ADB Keyboard to USB converter // This will take an older NeXT keyboard, talk to it, and turn the keycodes into a USB keyboard // Requires an Arduino Micro for the USB portion - but could be ported to another micro fairly easily diff --git a/USB_NeXT_Keyboard/USB_NeXT_Keyboard/nextkeyboard.h b/USB_NeXT_Keyboard/USB_NeXT_Keyboard/nextkeyboard.h index dcbe21e8..15381ff3 100644 --- a/USB_NeXT_Keyboard/USB_NeXT_Keyboard/nextkeyboard.h +++ b/USB_NeXT_Keyboard/USB_NeXT_Keyboard/nextkeyboard.h @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 1997 Juergen Hannken-Illjes for The NetBSD Foundation +// +// SPDX-License-Identifier: Berkeley + #include "wsksymdef.h" /* $NetBSD: wskbdmap_next.c,v 1.5 2008/04/28 20:23:30 martin Exp $ */ diff --git a/USB_NeXT_Keyboard/USB_NeXT_Keyboard/wsksymdef.h b/USB_NeXT_Keyboard/USB_NeXT_Keyboard/wsksymdef.h index 748ae5c8..8032ebf4 100644 --- a/USB_NeXT_Keyboard/USB_NeXT_Keyboard/wsksymdef.h +++ b/USB_NeXT_Keyboard/USB_NeXT_Keyboard/wsksymdef.h @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 1997 Juergen Hannken-Illjes for The NetBSD Foundation +// +// SPDX-License-Identifier: Berkeley + /* $OpenBSD: wsksymdef.h,v 1.32 2008/06/26 05:42:19 ray Exp $ */ /* $NetBSD: wsksymdef.h,v 1.34.4.1 2000/07/07 09:49:54 hannken Exp $ */ diff --git a/USB_SNES_Gamepad/teensySNES_Portal/teensySNES_Portal.ino b/USB_SNES_Gamepad/teensySNES_Portal/teensySNES_Portal.ino index eebc6de3..71365c23 100644 --- a/USB_SNES_Gamepad/teensySNES_Portal/teensySNES_Portal.ino +++ b/USB_SNES_Gamepad/teensySNES_Portal/teensySNES_Portal.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries +// +// SPDX-License-Identifier: MIT + const int pinAnalogXInput = 3; const int pinAnalogYInput = 1; const int pinAnalogZInput = 2; diff --git a/USB_SNES_Gamepad/teensySNES_onebutton/teensySNES_onebutton.ino b/USB_SNES_Gamepad/teensySNES_onebutton/teensySNES_onebutton.ino index 77bfa02a..d261bbcb 100644 --- a/USB_SNES_Gamepad/teensySNES_onebutton/teensySNES_onebutton.ino +++ b/USB_SNES_Gamepad/teensySNES_onebutton/teensySNES_onebutton.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Limor Fried/ladyada for Adafruit Industries +// +// SPDX-License-Identifier: MIT + const int pinBtnUp = 0; const int pinLEDOutput = 11; diff --git a/USB_SNES_Gamepad/teensySNES_stellakey/teensySNES_stellakey.ino b/USB_SNES_Gamepad/teensySNES_stellakey/teensySNES_stellakey.ino index 764bb679..c2239a5a 100644 --- a/USB_SNES_Gamepad/teensySNES_stellakey/teensySNES_stellakey.ino +++ b/USB_SNES_Gamepad/teensySNES_stellakey/teensySNES_stellakey.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Limor Fried/ladyada for Adafruit Industries +// +// SPDX-License-Identifier: MIT + #define KEYREPEAT 85 // delay when repeating characters #define KEYDELAY 200 // delay from first to second character const int pinAnalogXInput = 3; diff --git a/USB_SNES_Gamepad/teensySNES_test1/teensySNES_test1.ino b/USB_SNES_Gamepad/teensySNES_test1/teensySNES_test1.ino index 50f5e86e..ad1758fc 100644 --- a/USB_SNES_Gamepad/teensySNES_test1/teensySNES_test1.ino +++ b/USB_SNES_Gamepad/teensySNES_test1/teensySNES_test1.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Limor Fried/ladyada for Adafruit Industries +// +// SPDX-License-Identifier: MIT + #define REPEATRATE 100 // milliseconds const int pinBtnUp = 0; diff --git a/USB_SNES_Gamepad/teensySNES_test2/teensySNES_test2.ino b/USB_SNES_Gamepad/teensySNES_test2/teensySNES_test2.ino index 4d0d629b..a581e81a 100644 --- a/USB_SNES_Gamepad/teensySNES_test2/teensySNES_test2.ino +++ b/USB_SNES_Gamepad/teensySNES_test2/teensySNES_test2.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries +// +// SPDX-License-Identifier: MIT + const int pinAnalogXInput = 3; const int pinAnalogYInput = 1; const int pinAnalogZInput = 2; diff --git a/Ukulele/code.py b/Ukulele/code.py index 3fe70bbe..e22366db 100644 --- a/Ukulele/code.py +++ b/Ukulele/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Erin St. Blaine for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ LED Ukulele with Feather Sense and PropMaker Wing Adafruit invests time and resources providing this open source code. diff --git a/UnicornHorn_CapacitiveTouch/UnicornHorn_CapacitiveTouch.ino b/UnicornHorn_CapacitiveTouch/UnicornHorn_CapacitiveTouch.ino index e6befb15..276a7ff8 100644 --- a/UnicornHorn_CapacitiveTouch/UnicornHorn_CapacitiveTouch.ino +++ b/UnicornHorn_CapacitiveTouch/UnicornHorn_CapacitiveTouch.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2018 Erin St. Blaine for Adafruit Industries +// +// SPDX-License-Identifier: MIT + #include "Adafruit_FreeTouch.h" #include "FastLED.h" diff --git a/VOTE_Keyboard/code.py b/VOTE_Keyboard/code.py index 66008b14..4f78e38c 100755 --- a/VOTE_Keyboard/code.py +++ b/VOTE_Keyboard/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Collin Cunningham for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import board from digitalio import DigitalInOut, Direction, Pull import usb_hid diff --git a/Vertical_Garden_Barometer/code.py b/Vertical_Garden_Barometer/code.py index 09ff27c1..c59818ad 100755 --- a/Vertical_Garden_Barometer/code.py +++ b/Vertical_Garden_Barometer/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Erin St. Blaine for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ Read the barometric reading in the air Visualize air reading changes over time as a color animation on a NeoPixel strip diff --git a/Visualizer_Touch_Control/code.py b/Visualizer_Touch_Control/code.py index e64b03dd..6d5d0be1 100644 --- a/Visualizer_Touch_Control/code.py +++ b/Visualizer_Touch_Control/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2021 John Park for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import time import board import busio diff --git a/Voice2Json_Edge_Detection/demo.py b/Voice2Json_Edge_Detection/demo.py index ac3e034d..de64fc95 100644 --- a/Voice2Json_Edge_Detection/demo.py +++ b/Voice2Json_Edge_Detection/demo.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import os import subprocess import random diff --git a/Wave_Freq_Generator/code.py b/Wave_Freq_Generator/code.py index 0cdf6125..5594ad94 100644 --- a/Wave_Freq_Generator/code.py +++ b/Wave_Freq_Generator/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Dave Astels for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ Main signal generator code. diff --git a/Wave_Freq_Generator/display.py b/Wave_Freq_Generator/display.py index cfef7b7d..451e2162 100644 --- a/Wave_Freq_Generator/display.py +++ b/Wave_Freq_Generator/display.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Dave Astels for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ Display code for signal generator. diff --git a/Wave_Freq_Generator/generator.py b/Wave_Freq_Generator/generator.py index 5dc72183..5424cf85 100644 --- a/Wave_Freq_Generator/generator.py +++ b/Wave_Freq_Generator/generator.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Dave Astels for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ Outpout generator code for signal generator. diff --git a/Wave_Freq_Generator/shapes.py b/Wave_Freq_Generator/shapes.py index 21c37ee8..02b4868e 100644 --- a/Wave_Freq_Generator/shapes.py +++ b/Wave_Freq_Generator/shapes.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Dave Astels for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ Signal generator wave shapes. diff --git a/Wearable_BLE_Temperature_Monitor/Wearable_BLE_Temperature_Monitor.ino b/Wearable_BLE_Temperature_Monitor/Wearable_BLE_Temperature_Monitor.ino index 92b7fd30..0e37a3ca 100644 --- a/Wearable_BLE_Temperature_Monitor/Wearable_BLE_Temperature_Monitor.ino +++ b/Wearable_BLE_Temperature_Monitor/Wearable_BLE_Temperature_Monitor.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2020 Brent Rubell for Adafruit Industries +// +// SPDX-License-Identifier: MIT + /********************************************************************* Learn Guide: BLE Temperature Monitoring Armband diff --git a/Weather_Display_Matrix/code.py b/Weather_Display_Matrix/code.py index 2d3823ed..ef9e3d70 100644 --- a/Weather_Display_Matrix/code.py +++ b/Weather_Display_Matrix/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 John Park for Adafruit Industries +# +# SPDX-License-Identifier: MIT + # Matrix Weather display # For Metro M4 Airlift with RGB Matrix shield, 64 x 32 RGB LED Matrix display diff --git a/Weather_Display_Matrix/openweather_graphics.py b/Weather_Display_Matrix/openweather_graphics.py index 19c09a05..29066296 100644 --- a/Weather_Display_Matrix/openweather_graphics.py +++ b/Weather_Display_Matrix/openweather_graphics.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 John Park for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import time import displayio from adafruit_display_text.label import Label diff --git a/Welcome_to_CircuitPython/code.py b/Welcome_to_CircuitPython/code.py index d9e9e26f..80d8b8c1 100755 --- a/Welcome_to_CircuitPython/code.py +++ b/Welcome_to_CircuitPython/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2021 Kattni Rembor for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ Blink example for boards with ONLY a NeoPixel LED (e.g. without a built-in red LED). Includes QT Py and various Trinkeys. diff --git a/Window_Skull_Matrix/code.py b/Window_Skull_Matrix/code.py index 3d6694c1..4b82a09a 100644 --- a/Window_Skull_Matrix/code.py +++ b/Window_Skull_Matrix/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 John Park for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ WINDOW SKULL for Adafruit Matrix Portal: animated spooky eyes and servomotor jaw """ diff --git a/Window_Skull_Matrix/eyes/skull_bigger/data.py b/Window_Skull_Matrix/eyes/skull_bigger/data.py index 3930369a..2f734247 100755 --- a/Window_Skull_Matrix/eyes/skull_bigger/data.py +++ b/Window_Skull_Matrix/eyes/skull_bigger/data.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 John Park for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ Configuration data for the skull eyes """ # Photo by Lina White on Unsplash: https://unsplash.com/photos/K9nxgkYf-RI EYE_PATH = __file__[:__file__.rfind('/') + 1] diff --git a/Wire_Wrap_Necklace/code.py b/Wire_Wrap_Necklace/code.py index 85a69f4e..f97ddd89 100644 --- a/Wire_Wrap_Necklace/code.py +++ b/Wire_Wrap_Necklace/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Erin St. Blaine for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ FancyLED Necklace Insert Code Written by Phil Burgess and Erin St Blaine for Adafruit Industries diff --git a/Yoga_Pose_Chime/code.py b/Yoga_Pose_Chime/code.py index d3174eb4..2806bddc 100644 --- a/Yoga_Pose_Chime/code.py +++ b/Yoga_Pose_Chime/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 John Park for Adafruit Industries +# +# SPDX-License-Identifier: MIT + # Yoga pose timer # Requires CLUE with solenoid transistor driver circuit diff --git a/adafruitio-adt7410/adafruit_io_adt7410.py b/adafruitio-adt7410/adafruit_io_adt7410.py index c952cd54..9e2f0414 100644 --- a/adafruitio-adt7410/adafruit_io_adt7410.py +++ b/adafruitio-adt7410/adafruit_io_adt7410.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 Brent Rubell for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ 'adafruit_io_adt7410.py' ================================== diff --git a/adafruitio-adt7410/adafruitio-adt7410.ino b/adafruitio-adt7410/adafruitio-adt7410.ino index 22298497..27d071b7 100644 --- a/adafruitio-adt7410/adafruitio-adt7410.ino +++ b/adafruitio-adt7410/adafruitio-adt7410.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Brent Rubell for Adafruit Industries +// +// SPDX-License-Identifier: MIT + // Adafruit IO ADT7410 Example // // Adafruit invests time and resources providing this open source code. @@ -171,4 +175,4 @@ void loop() { delay(1000); } -} \ No newline at end of file +} diff --git a/adafruitio-temp-motion-wing/adafruitio-temp-motion-wing.ino b/adafruitio-temp-motion-wing/adafruitio-temp-motion-wing.ino index 951057d7..56c7d1ea 100644 --- a/adafruitio-temp-motion-wing/adafruitio-temp-motion-wing.ino +++ b/adafruitio-temp-motion-wing/adafruitio-temp-motion-wing.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Brent Rubell for Adafruit Industries +// +// SPDX-License-Identifier: MIT + // Adafruit IO - Analog Devices ADT7410 + ADXL343 Example // // Adafruit invests time and resources providing this open source code. diff --git a/adalogger/adalogger.ino b/adalogger/adalogger.ino index 638cd502..87d8fbdd 100644 --- a/adalogger/adalogger.ino +++ b/adalogger/adalogger.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Limor Fried/ladyada for Adafruit Industries +// +// SPDX-License-Identifier: MIT + #include #include @@ -71,4 +75,4 @@ void loop() { digitalWrite(8, LOW); delay(100); -} \ No newline at end of file +} diff --git a/color_touch_pendant/color_touch_pendant.ino b/color_touch_pendant/color_touch_pendant.ino index 8e620168..1c4fdfdc 100644 --- a/color_touch_pendant/color_touch_pendant.ino +++ b/color_touch_pendant/color_touch_pendant.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2018 Erin St. Blaine for Adafruit Industries +// +// SPDX-License-Identifier: MIT + // Code by Erin St. Blaine for Adafruit Industries // Color Touch Pendant Tutorial: https://learn.adafruit.com/color-touch-pendant-necklace/introduction // Two neopixel rings connected on pin 1 will cycle through gradient colors when the pendant is touched. For Gemma M0. diff --git a/eink_FeatherWing_stand/code.py b/eink_FeatherWing_stand/code.py index 221a6f6c..ed5b5fcc 100644 --- a/eink_FeatherWing_stand/code.py +++ b/eink_FeatherWing_stand/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 Noe Ruiz for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import digitalio import busio import board diff --git a/fauxmo_guide/fauxmo-basic/fauxmo-basic.ino b/fauxmo_guide/fauxmo-basic/fauxmo-basic.ino index 9d604b1a..0fd25c69 100644 --- a/fauxmo_guide/fauxmo-basic/fauxmo-basic.ino +++ b/fauxmo_guide/fauxmo-basic/fauxmo-basic.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Brent Rubell for Adafruit Industries +// +// SPDX-License-Identifier: MIT + #include #include #include diff --git a/fauxmo_guide/fauxmo-relay-neopixel/fauxmo-relay-neopixel.ino b/fauxmo_guide/fauxmo-relay-neopixel/fauxmo-relay-neopixel.ino index 6e8a448e..8dda0ced 100644 --- a/fauxmo_guide/fauxmo-relay-neopixel/fauxmo-relay-neopixel.ino +++ b/fauxmo_guide/fauxmo-relay-neopixel/fauxmo-relay-neopixel.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2019 Brent Rubell for Adafruit Industries +// +// SPDX-License-Identifier: MIT + #include #include #include @@ -139,4 +143,4 @@ uint32_t Wheel(byte WheelPos) WheelPos -= 170; return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3); } -} \ No newline at end of file +} diff --git a/library.deps b/library.deps index 8c5a03cc..20dde3b3 100644 --- a/library.deps +++ b/library.deps @@ -1 +1 @@ -depends=Adafruit ILI9341, Adafruit BusIO, SD, Adafruit NeoPixel, Adafruit VS1053 Library, Adafruit BluefruitLE nRF51, Adafruit seesaw Library, Ethernet, Adafruit IO Arduino, FastLED, Adafruit LiquidCrystal, Adafruit SoftServo, TinyWireM, Adafruit AM radio library, WaveHC, Adafruit LED Backpack Library, MAX31850 OneWire, Adafruit VC0706 Serial Camera Library, RTClib, Adafruit SleepyDog Library, Adafruit Thermal Printer Library, Adafruit Zero I2S Library, Adafruit EPD, Adafruit SSD1351 library, Adafruit FONA Library, Adafruit Motor Shield V2 Library, Adafruit NeoMatrix, Adafruit Soundboard library, Adafruit Circuit Playground, ArduinoJson, Adafruit TCS34725, Adafruit Pixie, Adafruit GPS Library, TinyGPS, WiFi101, Adafruit DotStar, Adafruit Si7021 Library, Adafruit WS2801 Library, Mouse, Keyboard, Time, IRremote, Adafruit LSM9DS0 Library, Adafruit Arcada Library, MIDIUSB, PubSubClient, Adafruit LIS2MDL, Adafruit NeoPXL8, Adafruit MCP23017 Arduino Library, Adafruit MLX90640, LiquidCrystal, Adafruit NeoTrellis M4 Library, RGB matrix Panel, Adafruit MLX90614 Library, Adafruit RGB LCD Shield Library, MAX6675 library, Adafruit MP3, Adafruit Keypad, Adafruit Arcada GifDecoder, Keypad, Neosegment, Encoder, Adafruit TiCoServo, Adafruit Trellis Library, FauxmoESP, Adafruit LSM303 Accel, Adafruit LSM303DLH Mag, Adafruit LSM303DLHC, CapacitiveSensor, Adafruit Zero PDM Library, Adafruit DMA neopixel library, elapsedMillis, DST RTC, Adafruit SHARP Memory Display, Adafruit SPIFlash, BSEC Software Library, WiiChuck, Adafruit DPS310, Adafruit AHTX0, RotaryEncoder, Adafruit MCP9808 Library, LSM303, Adafruit Protomatter, HID-Project +depends=Adafruit ILI9341, Adafruit BusIO, SD, Adafruit NeoPixel, Adafruit VS1053 Library, Adafruit BluefruitLE nRF51, Adafruit seesaw Library, Ethernet, Adafruit IO Arduino, FastLED, Adafruit LiquidCrystal, Adafruit SoftServo, TinyWireM, Adafruit AM radio library, WaveHC, Adafruit LED Backpack Library, MAX31850 OneWire, Adafruit VC0706 Serial Camera Library, RTClib, Adafruit SleepyDog Library, Adafruit Thermal Printer Library, Adafruit Zero I2S Library, Adafruit EPD, Adafruit SSD1351 library, Adafruit FONA Library, Adafruit Motor Shield V2 Library, Adafruit NeoMatrix, Adafruit Soundboard library, Adafruit Circuit Playground, ArduinoJson, Adafruit TCS34725, Adafruit Pixie, Adafruit GPS Library, TinyGPS, WiFi101, Adafruit DotStar, Adafruit Si7021 Library, Adafruit WS2801 Library, Mouse, Keyboard, Time, IRremote, Adafruit LSM9DS0 Library, Adafruit Arcada Library, MIDIUSB, PubSubClient, Adafruit LIS2MDL, Adafruit NeoPXL8, Adafruit MCP23017 Arduino Library, Adafruit MLX90640, LiquidCrystal, Adafruit NeoTrellis M4 Library, RGB matrix Panel, Adafruit MLX90614 Library, Adafruit RGB LCD Shield Library, MAX6675 library, Adafruit MP3, Adafruit Keypad, Adafruit Arcada GifDecoder, Keypad, Neosegment, Encoder, Adafruit TiCoServo, Adafruit Trellis Library, FauxmoESP, Adafruit LSM303 Accel, Adafruit LSM303DLH Mag, Adafruit LSM303DLHC, CapacitiveSensor, Adafruit Zero PDM Library, Adafruit DMA neopixel library, elapsedMillis, DST RTC, Adafruit SHARP Memory Display, Adafruit SPIFlash, BSEC Software Library, WiiChuck, Adafruit DPS310, Adafruit AHTX0, RotaryEncoder, Adafruit MCP9808 Library, LSM303, Adafruit Protomatter, HID-Project, Adafruit IS31FL3741 Library diff --git a/lightbox/code.py b/lightbox/code.py index 39759811f..6750323e 100644 --- a/lightbox/code.py +++ b/lightbox/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 Dave Astels for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ Lightbox driver program. diff --git a/lorawan_sensing_network/lora_device/code.py b/lorawan_sensing_network/lora_device/code.py index 1ea063f8..91f1575d 100644 --- a/lorawan_sensing_network/lora_device/code.py +++ b/lorawan_sensing_network/lora_device/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 Brent Rubell for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ lora_device.py diff --git a/lorawan_sensing_network/lora_gateway/code.py b/lorawan_sensing_network/lora_gateway/code.py index 6bd5f436..92ed09c4 100644 --- a/lorawan_sensing_network/lora_gateway/code.py +++ b/lorawan_sensing_network/lora_gateway/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 Brent Rubell for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ Adafruit IO LoRa Gateway diff --git a/lorawan_sensing_network/ttn_feather_node/code.py b/lorawan_sensing_network/ttn_feather_node/code.py index 3d03a3ab..a6fb139a 100644 --- a/lorawan_sensing_network/ttn_feather_node/code.py +++ b/lorawan_sensing_network/ttn_feather_node/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 Brent Rubell for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import time import board import busio diff --git a/neoMatrixMkI/neoMatrixMkI.ino b/neoMatrixMkI/neoMatrixMkI.ino index 6b194e18..ce32cb90 100644 --- a/neoMatrixMkI/neoMatrixMkI.ino +++ b/neoMatrixMkI/neoMatrixMkI.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2017 John Park for Adafruit Industries +// +// SPDX-License-Identifier: MIT + #include "Arduino.h" #include "Keypad.h" #include "Neosegment.h" diff --git a/oshwa_magtag_display/bmps/oshwa_full.bmp b/oshwa_magtag_display/bmps/oshwa_full.bmp new file mode 100644 index 00000000..b12d84f8 Binary files /dev/null and b/oshwa_magtag_display/bmps/oshwa_full.bmp differ diff --git a/oshwa_magtag_display/code.py b/oshwa_magtag_display/code.py new file mode 100644 index 00000000..48d8ba9e --- /dev/null +++ b/oshwa_magtag_display/code.py @@ -0,0 +1,189 @@ +# SPDX-FileCopyrightText: 2021 Dylan Herrada for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +import random +import ssl +import gc +import wifi +import socketpool +import adafruit_requests as requests +from adafruit_magtag.magtag import MagTag + +# Get wifi details and more from a secrets.py file +try: + from secrets import secrets +except ImportError: + print("WiFi secrets are kept in secrets.py, please add them there!") + raise + +# Initialize magtag object +magtag = MagTag() + +magtag.set_background("bmps/oshwa_full.bmp") + +# Set up WiFi +wifi.radio.connect(secrets["ssid"], secrets["password"]) +print(f"Connected to {secrets['ssid']}!") +print("My IP address is", wifi.radio.ipv4_address) + +socket = socketpool.SocketPool(wifi.radio) +https = requests.Session(socket, ssl.create_default_context()) + +# Paste your API token below +TOKEN = "YOUR_API_TOKEN" + + +def font_width_to_dict(font): + # Reads the font file to determine how wide each character is + # Used to avoid bad wrapping breaking the QR code + chars = {} + with open(font, "r") as file: + for line in file: + if "FONTBOUNDINGBOX" in line: + size = int(line.split(" ")[1]) + if "ENCODING" in line and "_ENCODING" not in line: + character = chr(int(line.split(" ")[1][:-1])) + chars[character] = None + if "SWIDTH" in line: + swidth = (int(line.split(" ")[1]) / 1000) * size + if "DWIDTH" in line: + chars[character] = int(int(line.split(" ")[1]) + swidth) + return chars + + +def wrap(text, max_width, max_lines, font): + # Used to wrap the title and description to avoid breaking the QR code + lines = [] + ellipsis = 3 * font["."] + line = "" + line_width = 0 + for word in text.split(" "): + for character in word: + line_width += font[character] + if ( + len(lines) + 1 != max_lines + or sum(font[i] for i in word) + line_width <= max_width + ): + if line_width > max_width: + print(str(line_width) + line) + line_width = sum(font[i] for i in word) + lines.append(line.strip()) + line = word + " " + break + else: + for char_1 in word: + if line_width + ellipsis + font[char_1] > max_width: + line = line + "..." + print(str(line_width) + line) + lines.append(line) + return "\n".join(lines[:max_lines]) + line = line + char_1 + line_width += font[char_1] + + else: + line = line + word + " " + + lines.append(line.strip()) + return "\n".join(lines[:max_lines]) + + +# Get first 300 items, saving only the OSHWA UIDs. The first 300 are also used to find the +# number of requests that will need to be made. +# This was done this way since if the items themselves were all asked for and stored, the MagTag +# would run out of memory. If we just got the number of total projects and chose a random number, +# that also wouldn't work as you can only get individual projects with an OSHWA UID and these UIDs +# are prefixed by the country they were registered in, thus making getting it with a simple number +# in-between 1 and the total number of registered projects impossible. +URL = "https://certificationapi.oshwa.org/api/projects?limit=300" + +print(URL) + +payload = {} +headers = {"Content-Type": "application/json", "Authorization": f"Bearer {TOKEN}"} + +oshwaID = [] + +print("Getting number of projects and first set of 300 projects") +with https.get(URL, headers=headers, data=payload) as response: + R_JSON = response.json() + total = int(R_JSON["total"]) + print(f"{total} Projects") + for i in R_JSON["items"]: + oshwaID.append(i["oshwaUid"]) + R_JSON.clear() + R_JSON = None + gc.collect() + +# Gets the rest of the OSHWA UIDs +print(len(oshwaID)) +for i in range(int(total / 300)): + print(f"Getting request {i+2}") + url = ( + f"https://certificationapi.oshwa.org/api/projects?limit=300&offset={3*(i+1)}00" + ) + with https.get(url, headers=headers, data=payload) as response: + R_JSON = response.json() + for item in R_JSON["items"]: + oshwaID.append(item["oshwaUid"]) + R_JSON.clear() + R_JSON = None + gc.collect() + print(f"{len(oshwaID)} IDs gathered") + +# Select the UID that will be displayed +selected = random.choice(oshwaID) + +# Get the project that will be displayed +url = f"https://certificationapi.oshwa.org/api/projects/{selected}" +response = https.get(url, headers=headers, data=payload) + +selected = response.json()[0] + +# Filters out characters that the API or the MagTag itself isn't handling correctly +for char in range(1, 32): + selected["projectDescription"].replace(chr(char), "") + +selected["projectDescription"] = ( + selected["projectDescription"] + .replace("'", "'") + .replace("&#x27;", "'") + .replace("/", "/") + .replace(""", '"') + .replace("’", "'") +) + +# Add the two text fields +magtag.add_text( + text_font="fonts/Arial-Bold-12.bdf", + text_position=(5, 0), + text_scale=1, + line_spacing=0.7, + text_anchor_point=(0, 0), +) + +magtag.add_text( + text_font="fonts/ArialMT-9.bdf", + text_position=(5, 38), + text_scale=1, + line_spacing=0.6, + text_anchor_point=(0, 0), +) + +# Create the QR code +url = f"https://certification.oshwa.org/{selected['oshwaUid'].lower()}.html" +magtag.graphics.qrcode(url, qr_size=4, x=173, y=3) + +# Prepare to wrap the text correctly by getting the width of each character for every font +arial_12 = font_width_to_dict("fonts/Arial-Bold-12.bdf") +arial_9 = font_width_to_dict("fonts/ArialMT-9.bdf") + +# Set the text. On some characters, this fails. If so, run the whole file again in 5 seconds +try: + magtag.set_text(wrap(selected["projectName"], 545, 2, arial_12), 0, False) + magtag.set_text(wrap(selected["projectDescription"], 530, 19, arial_9), 1) + magtag.exit_and_deep_sleep(3600) +except Exception: # pylint: disable=broad-except + print("Could not set title or description: unsupported glyphs.") + print("Trying again in 10 seconds.") + magtag.exit_and_deep_sleep(10) diff --git a/oshwa_magtag_display/fonts/Arial-Bold-12.bdf b/oshwa_magtag_display/fonts/Arial-Bold-12.bdf new file mode 100644 index 00000000..672399a7 --- /dev/null +++ b/oshwa_magtag_display/fonts/Arial-Bold-12.bdf @@ -0,0 +1,6131 @@ +STARTFONT 2.1 +COMMENT +COMMENT Converted from OpenType font "arialbd.ttf" by "otf2bdf 3.0". +COMMENT +FONT -FreeType-Arial-Bold-R-Normal--17-120-100-100-P-89-ISO10646-1 +SIZE 12 100 100 +FONTBOUNDINGBOX 34 26 -9 -8 +STARTPROPERTIES 19 +FOUNDRY "FreeType" +FAMILY_NAME "Arial" +WEIGHT_NAME "Bold" +SLANT "R" +SETWIDTH_NAME "Normal" +ADD_STYLE_NAME "" +PIXEL_SIZE 17 +POINT_SIZE 120 +RESOLUTION_X 100 +RESOLUTION_Y 100 +SPACING "P" +AVERAGE_WIDTH 89 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" +FONT_ASCENT 15 +FONT_DESCENT 3 +COPYRIGHT "© 2017 The Monotype Corporation. All Rights Reserved. Hebrew OpenType Layout logic copyright © 2003 & 2007, Ralph Hancock & John Hudson. This layout logic for Biblical Hebrew is open source software under the MIT License; see embedded license description for details." +_OTF_FONTFILE "arialbd.ttf" +_OTF_PSNAME "Arial-BoldMT" +ENDPROPERTIES +CHARS 318 +STARTCHAR 0020 +ENCODING 32 +SWIDTH 300 0 +DWIDTH 5 0 +BBX 0 0 0 0 +BITMAP +ENDCHAR +STARTCHAR 0021 +ENCODING 33 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 2 12 2 0 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +00 +C0 +C0 +ENDCHAR +STARTCHAR 0022 +ENCODING 34 +SWIDTH 480 0 +DWIDTH 8 0 +BBX 6 4 1 8 +BITMAP +CC +CC +CC +CC +ENDCHAR +STARTCHAR 0023 +ENCODING 35 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 10 12 0 0 +BITMAP +0D80 +0D80 +1B00 +FFC0 +FFC0 +1B00 +3600 +FFC0 +FFC0 +3600 +6C00 +6C00 +ENDCHAR +STARTCHAR 0024 +ENCODING 36 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 15 1 -2 +BITMAP +10 +38 +7C +D6 +D0 +F0 +78 +3C +1E +D6 +D6 +7C +38 +10 +10 +ENDCHAR +STARTCHAR 0025 +ENCODING 37 +SWIDTH 960 0 +DWIDTH 16 0 +BBX 15 12 0 0 +BITMAP +7830 +CC60 +CC60 +CCC0 +CD80 +7980 +033C +0366 +0666 +0666 +0C66 +183C +ENDCHAR +STARTCHAR 0026 +ENCODING 38 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 11 12 1 0 +BITMAP +3E00 +7F00 +6300 +6300 +3E00 +3C00 +6C80 +CEC0 +C780 +C3C0 +7FE0 +3C40 +ENDCHAR +STARTCHAR 0027 +ENCODING 39 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 2 4 1 8 +BITMAP +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 0028 +ENCODING 40 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 4 15 1 -3 +BITMAP +30 +60 +60 +60 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +60 +60 +60 +30 +ENDCHAR +STARTCHAR 0029 +ENCODING 41 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 4 15 1 -3 +BITMAP +C0 +60 +60 +60 +30 +30 +30 +30 +30 +30 +30 +60 +60 +60 +C0 +ENDCHAR +STARTCHAR 002A +ENCODING 42 +SWIDTH 420 0 +DWIDTH 7 0 +BBX 5 5 1 7 +BITMAP +20 +F8 +20 +50 +D8 +ENDCHAR +STARTCHAR 002B +ENCODING 43 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 8 1 2 +BITMAP +18 +18 +18 +FF +FF +18 +18 +18 +ENDCHAR +STARTCHAR 002C +ENCODING 44 +SWIDTH 300 0 +DWIDTH 5 0 +BBX 2 5 1 -3 +BITMAP +C0 +C0 +40 +40 +80 +ENDCHAR +STARTCHAR 002D +ENCODING 45 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 5 2 1 3 +BITMAP +F8 +F8 +ENDCHAR +STARTCHAR 002E +ENCODING 46 +SWIDTH 300 0 +DWIDTH 5 0 +BBX 2 2 1 0 +BITMAP +C0 +C0 +ENDCHAR +STARTCHAR 002F +ENCODING 47 +SWIDTH 300 0 +DWIDTH 5 0 +BBX 5 12 0 0 +BITMAP +18 +18 +30 +30 +30 +30 +60 +60 +60 +60 +C0 +C0 +ENDCHAR +STARTCHAR 0030 +ENCODING 48 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 12 0 0 +BITMAP +3C +7E +E7 +C3 +C3 +C3 +C3 +C3 +C3 +E7 +7E +3C +ENDCHAR +STARTCHAR 0031 +ENCODING 49 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 5 12 1 0 +BITMAP +18 +38 +78 +D8 +98 +18 +18 +18 +18 +18 +18 +18 +ENDCHAR +STARTCHAR 0032 +ENCODING 50 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 12 0 0 +BITMAP +3C +7E +E3 +C3 +03 +06 +0E +1C +38 +60 +FF +FF +ENDCHAR +STARTCHAR 0033 +ENCODING 51 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 12 0 0 +BITMAP +3E +7F +E3 +03 +1E +1E +07 +03 +C3 +E7 +7E +3C +ENDCHAR +STARTCHAR 0034 +ENCODING 52 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 12 0 0 +BITMAP +06 +0E +0E +1E +36 +36 +66 +C6 +FF +FF +06 +06 +ENDCHAR +STARTCHAR 0035 +ENCODING 53 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 12 0 0 +BITMAP +7E +7E +60 +C0 +FC +FE +C7 +03 +C3 +E7 +7E +3C +ENDCHAR +STARTCHAR 0036 +ENCODING 54 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 12 0 0 +BITMAP +3E +7F +63 +C0 +DC +FE +E7 +C3 +C3 +63 +7E +3C +ENDCHAR +STARTCHAR 0037 +ENCODING 55 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 12 0 0 +BITMAP +FF +FF +06 +0C +0C +18 +18 +18 +30 +30 +30 +30 +ENDCHAR +STARTCHAR 0038 +ENCODING 56 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 12 0 0 +BITMAP +3C +7E +C3 +C3 +C3 +7E +7E +C3 +C3 +C3 +7E +3C +ENDCHAR +STARTCHAR 0039 +ENCODING 57 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 12 0 0 +BITMAP +3C +7E +C6 +C3 +C3 +E7 +7F +3B +03 +C6 +FE +7C +ENDCHAR +STARTCHAR 003A +ENCODING 58 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 2 9 2 0 +BITMAP +C0 +C0 +00 +00 +00 +00 +00 +C0 +C0 +ENDCHAR +STARTCHAR 003B +ENCODING 59 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 2 12 2 -3 +BITMAP +C0 +C0 +00 +00 +00 +00 +00 +C0 +C0 +40 +40 +80 +ENDCHAR +STARTCHAR 003C +ENCODING 60 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 9 0 1 +BITMAP +01 +07 +1E +78 +E0 +78 +1E +07 +01 +ENDCHAR +STARTCHAR 003D +ENCODING 61 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 9 6 0 3 +BITMAP +FF80 +FF80 +0000 +0000 +FF80 +FF80 +ENDCHAR +STARTCHAR 003E +ENCODING 62 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 9 0 1 +BITMAP +80 +E0 +78 +1E +07 +1E +78 +E0 +80 +ENDCHAR +STARTCHAR 003F +ENCODING 63 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +3C +7E +E3 +C3 +07 +0E +1C +18 +18 +00 +18 +18 +ENDCHAR +STARTCHAR 0040 +ENCODING 64 +SWIDTH 1020 0 +DWIDTH 17 0 +BBX 16 16 1 -4 +BITMAP +07E0 +1FF8 +381C +776C +6FE6 +ECE6 +D8E6 +D8C6 +D8CE +D9DC +DFF8 +6EF0 +7007 +381E +1FFC +07F0 +ENDCHAR +STARTCHAR 0041 +ENCODING 65 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 11 12 0 0 +BITMAP +0E00 +0E00 +1B00 +1B00 +1B00 +3180 +3180 +3F80 +7FC0 +60C0 +60C0 +C060 +ENDCHAR +STARTCHAR 0042 +ENCODING 66 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 12 1 0 +BITMAP +FF00 +FF80 +C180 +C180 +C180 +FF00 +FF80 +C0C0 +C0C0 +C0C0 +FF80 +FF00 +ENDCHAR +STARTCHAR 0043 +ENCODING 67 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 12 1 0 +BITMAP +1F00 +7F80 +61C0 +E080 +C000 +C000 +C000 +C000 +E080 +61C0 +7F80 +1F00 +ENDCHAR +STARTCHAR 0044 +ENCODING 68 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 12 1 0 +BITMAP +FE00 +FF80 +C180 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C180 +FF80 +FE00 +ENDCHAR +STARTCHAR 0045 +ENCODING 69 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 9 12 1 0 +BITMAP +FF80 +FF80 +C000 +C000 +C000 +FF80 +FF80 +C000 +C000 +C000 +FF80 +FF80 +ENDCHAR +STARTCHAR 0046 +ENCODING 70 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +FF +FF +C0 +C0 +C0 +FE +FE +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 0047 +ENCODING 71 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 11 12 1 0 +BITMAP +1F80 +7FC0 +60E0 +E040 +C000 +C000 +C3E0 +C3E0 +E060 +60E0 +7FE0 +1F80 +ENDCHAR +STARTCHAR 0048 +ENCODING 72 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 12 1 0 +BITMAP +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +FFC0 +FFC0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +ENDCHAR +STARTCHAR 0049 +ENCODING 73 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 2 12 1 0 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 004A +ENCODING 74 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 12 0 0 +BITMAP +03 +03 +03 +03 +03 +03 +03 +03 +C3 +E7 +7E +3C +ENDCHAR +STARTCHAR 004B +ENCODING 75 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 12 1 0 +BITMAP +C0C0 +C180 +C300 +C600 +CC00 +DE00 +F700 +E300 +C380 +C180 +C0C0 +C0C0 +ENDCHAR +STARTCHAR 004C +ENCODING 76 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +FF +FF +ENDCHAR +STARTCHAR 004D +ENCODING 77 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 11 12 1 0 +BITMAP +E0E0 +E0E0 +F1E0 +F1E0 +D160 +DB60 +DB60 +DB60 +CE60 +CE60 +CE60 +C460 +ENDCHAR +STARTCHAR 004E +ENCODING 78 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 12 1 0 +BITMAP +C0C0 +E0C0 +F0C0 +F0C0 +D8C0 +CCC0 +CCC0 +C6C0 +C3C0 +C3C0 +C1C0 +C0C0 +ENDCHAR +STARTCHAR 004F +ENCODING 79 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 11 12 1 0 +BITMAP +1F00 +7FC0 +60C0 +E060 +C060 +C060 +C060 +C060 +C060 +60C0 +7FC0 +1F00 +ENDCHAR +STARTCHAR 0050 +ENCODING 80 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 9 12 1 0 +BITMAP +FE00 +FF00 +C380 +C180 +C380 +FF00 +FE00 +C000 +C000 +C000 +C000 +C000 +ENDCHAR +STARTCHAR 0051 +ENCODING 81 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 11 13 1 -1 +BITMAP +1F00 +7FC0 +60C0 +E060 +C060 +C060 +C060 +C060 +C6E0 +63C0 +7FC0 +1EC0 +0060 +ENDCHAR +STARTCHAR 0052 +ENCODING 82 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 11 12 1 0 +BITMAP +FF00 +FF80 +C1C0 +C0C0 +C1C0 +FF80 +FE00 +C700 +C380 +C180 +C1C0 +C0E0 +ENDCHAR +STARTCHAR 0053 +ENCODING 83 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 9 12 1 0 +BITMAP +3E00 +7F00 +E380 +C180 +F000 +7E00 +1F00 +0380 +C180 +E380 +7F00 +3E00 +ENDCHAR +STARTCHAR 0054 +ENCODING 84 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 10 12 0 0 +BITMAP +FFC0 +FFC0 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +ENDCHAR +STARTCHAR 0055 +ENCODING 85 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 12 1 0 +BITMAP +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +E1C0 +7F80 +3F00 +ENDCHAR +STARTCHAR 0056 +ENCODING 86 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 11 12 0 0 +BITMAP +C060 +60C0 +60C0 +60C0 +3180 +3180 +3B80 +1B00 +1B00 +0E00 +0E00 +0E00 +ENDCHAR +STARTCHAR 0057 +ENCODING 87 +SWIDTH 1020 0 +DWIDTH 17 0 +BBX 17 12 0 0 +BITMAP +C1C180 +E1C180 +63E300 +636300 +636300 +377600 +363600 +363600 +1E3E00 +1C1C00 +1C1C00 +1C1C00 +ENDCHAR +STARTCHAR 0058 +ENCODING 88 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 9 12 1 0 +BITMAP +C180 +E380 +6300 +3600 +3E00 +1C00 +1C00 +3E00 +3600 +6300 +E380 +C180 +ENDCHAR +STARTCHAR 0059 +ENCODING 89 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 10 12 0 0 +BITMAP +C0C0 +E1C0 +6180 +3300 +3300 +1E00 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +ENDCHAR +STARTCHAR 005A +ENCODING 90 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 9 12 0 0 +BITMAP +7F80 +7F80 +0300 +0600 +0E00 +0C00 +1800 +3800 +3000 +6000 +FF80 +FF80 +ENDCHAR +STARTCHAR 005B +ENCODING 91 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 4 15 1 -3 +BITMAP +F0 +F0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +F0 +F0 +ENDCHAR +STARTCHAR 005C +ENCODING 92 +SWIDTH 300 0 +DWIDTH 5 0 +BBX 5 12 0 0 +BITMAP +C0 +C0 +60 +60 +60 +60 +30 +30 +30 +30 +18 +18 +ENDCHAR +STARTCHAR 005D +ENCODING 93 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 4 15 1 -3 +BITMAP +F0 +F0 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +F0 +F0 +ENDCHAR +STARTCHAR 005E +ENCODING 94 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 7 1 5 +BITMAP +18 +3C +3C +66 +66 +66 +C3 +ENDCHAR +STARTCHAR 005F +ENCODING 95 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 9 2 0 -3 +BITMAP +FF80 +FF80 +ENDCHAR +STARTCHAR 0060 +ENCODING 96 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 3 2 1 10 +BITMAP +C0 +60 +ENDCHAR +STARTCHAR 0061 +ENCODING 97 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 9 1 0 +BITMAP +7C +FE +C6 +1E +7E +E6 +C6 +FE +7B +ENDCHAR +STARTCHAR 0062 +ENCODING 98 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +C0 +C0 +C0 +DC +FE +E7 +C3 +C3 +C3 +E7 +FE +DC +ENDCHAR +STARTCHAR 0063 +ENCODING 99 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 9 1 0 +BITMAP +3C +7E +E6 +C0 +C0 +C0 +E6 +7E +3C +ENDCHAR +STARTCHAR 0064 +ENCODING 100 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +03 +03 +03 +3B +7F +E7 +C3 +C3 +C3 +E7 +7F +3B +ENDCHAR +STARTCHAR 0065 +ENCODING 101 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 9 1 0 +BITMAP +38 +7C +C6 +FE +FE +C0 +E6 +7C +38 +ENDCHAR +STARTCHAR 0066 +ENCODING 102 +SWIDTH 300 0 +DWIDTH 5 0 +BBX 6 12 0 0 +BITMAP +3C +7C +60 +F8 +F8 +60 +60 +60 +60 +60 +60 +60 +ENDCHAR +STARTCHAR 0067 +ENCODING 103 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 -3 +BITMAP +3B +7F +E7 +C3 +C3 +C3 +E7 +7F +3B +C3 +FF +7E +ENDCHAR +STARTCHAR 0068 +ENCODING 104 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +C0 +C0 +C0 +DE +FF +E3 +C3 +C3 +C3 +C3 +C3 +C3 +ENDCHAR +STARTCHAR 0069 +ENCODING 105 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 2 12 1 0 +BITMAP +C0 +C0 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 006A +ENCODING 106 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 4 15 -1 -3 +BITMAP +30 +30 +00 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +F0 +E0 +ENDCHAR +STARTCHAR 006B +ENCODING 107 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +C0 +C0 +C0 +C6 +CC +D8 +F8 +FC +EC +CC +C6 +C6 +ENDCHAR +STARTCHAR 006C +ENCODING 108 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 2 12 1 0 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 006D +ENCODING 109 +SWIDTH 840 0 +DWIDTH 14 0 +BBX 12 9 1 0 +BITMAP +DCE0 +FFF0 +E730 +C630 +C630 +C630 +C630 +C630 +C630 +ENDCHAR +STARTCHAR 006E +ENCODING 110 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 9 1 0 +BITMAP +DE +FF +E3 +C3 +C3 +C3 +C3 +C3 +C3 +ENDCHAR +STARTCHAR 006F +ENCODING 111 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 9 1 0 +BITMAP +3C +7E +E7 +C3 +C3 +C3 +E7 +7E +3C +ENDCHAR +STARTCHAR 0070 +ENCODING 112 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 -3 +BITMAP +DC +FE +E7 +C3 +C3 +C3 +E7 +FE +DC +C0 +C0 +C0 +ENDCHAR +STARTCHAR 0071 +ENCODING 113 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 -3 +BITMAP +3B +7F +E7 +C3 +C3 +C3 +E7 +7F +3B +03 +03 +03 +ENDCHAR +STARTCHAR 0072 +ENCODING 114 +SWIDTH 420 0 +DWIDTH 7 0 +BBX 6 9 1 0 +BITMAP +DC +FC +E0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 0073 +ENCODING 115 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 9 1 0 +BITMAP +7C +FE +C6 +F0 +7C +0E +C6 +FE +7C +ENDCHAR +STARTCHAR 0074 +ENCODING 116 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 5 12 0 0 +BITMAP +20 +60 +60 +F8 +F8 +60 +60 +60 +60 +60 +78 +38 +ENDCHAR +STARTCHAR 0075 +ENCODING 117 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 9 1 0 +BITMAP +C3 +C3 +C3 +C3 +C3 +C3 +C7 +FF +7B +ENDCHAR +STARTCHAR 0076 +ENCODING 118 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 9 1 0 +BITMAP +C6 +C6 +C6 +6C +6C +6C +38 +38 +38 +ENDCHAR +STARTCHAR 0077 +ENCODING 119 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 13 9 0 0 +BITMAP +C718 +C718 +6730 +6DB0 +6DB0 +6DB0 +38E0 +38E0 +38E0 +ENDCHAR +STARTCHAR 0078 +ENCODING 120 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 9 1 0 +BITMAP +C6 +EE +6C +38 +38 +38 +6C +EE +C6 +ENDCHAR +STARTCHAR 0079 +ENCODING 121 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 9 12 0 -3 +BITMAP +C180 +C180 +6300 +6300 +3600 +3600 +3E00 +1C00 +1C00 +1800 +7800 +7000 +ENDCHAR +STARTCHAR 007A +ENCODING 122 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 9 1 0 +BITMAP +FE +FE +0C +1C +38 +70 +60 +FE +FE +ENDCHAR +STARTCHAR 007B +ENCODING 123 +SWIDTH 420 0 +DWIDTH 7 0 +BBX 6 15 1 -3 +BITMAP +1C +3C +30 +30 +30 +30 +E0 +E0 +30 +30 +30 +30 +30 +3C +1C +ENDCHAR +STARTCHAR 007C +ENCODING 124 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 2 16 1 -4 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 007D +ENCODING 125 +SWIDTH 420 0 +DWIDTH 7 0 +BBX 6 15 0 -3 +BITMAP +E0 +F0 +30 +30 +30 +30 +1C +1C +30 +30 +30 +30 +30 +F0 +E0 +ENDCHAR +STARTCHAR 007E +ENCODING 126 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 9 3 0 4 +BITMAP +7880 +FF80 +8F00 +ENDCHAR +STARTCHAR 00A0 +ENCODING 160 +SWIDTH 300 0 +DWIDTH 5 0 +BBX 0 0 0 0 +BITMAP +ENDCHAR +STARTCHAR 00A1 +ENCODING 161 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 2 12 2 -3 +BITMAP +C0 +C0 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 00A2 +ENCODING 162 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 15 0 -3 +BITMAP +02 +02 +04 +3E +7E +EB +C8 +D0 +D3 +F7 +7E +3C +20 +40 +40 +ENDCHAR +STARTCHAR 00A3 +ENCODING 163 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 9 12 0 0 +BITMAP +1E00 +3F00 +6380 +6180 +6000 +FC00 +FC00 +3000 +3000 +7900 +FF80 +4700 +ENDCHAR +STARTCHAR 00A4 +ENCODING 164 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 9 9 0 1 +BITMAP +2200 +7F00 +FF80 +6300 +6300 +6300 +FF80 +7F00 +2200 +ENDCHAR +STARTCHAR 00A5 +ENCODING 165 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 12 0 0 +BITMAP +C3 +66 +66 +24 +3C +3C +FF +18 +FF +18 +18 +18 +ENDCHAR +STARTCHAR 00A6 +ENCODING 166 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 2 16 1 -4 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +00 +00 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 00A7 +ENCODING 167 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 16 0 -4 +BITMAP +3C +7E +66 +70 +38 +7C +CE +C7 +E3 +73 +3E +1C +0E +66 +7E +3C +ENDCHAR +STARTCHAR 00A8 +ENCODING 168 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 6 2 0 10 +BITMAP +CC +CC +ENDCHAR +STARTCHAR 00A9 +ENCODING 169 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 12 12 0 0 +BITMAP +0F00 +30C0 +4020 +4F20 +9090 +9010 +9010 +9090 +4F20 +4020 +30C0 +0F00 +ENDCHAR +STARTCHAR 00AA +ENCODING 170 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 5 6 0 6 +BITMAP +70 +D8 +38 +D8 +D8 +78 +ENDCHAR +STARTCHAR 00AB +ENCODING 171 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 8 1 1 +BITMAP +36 +6C +6C +D8 +D8 +6C +6C +36 +ENDCHAR +STARTCHAR 00AC +ENCODING 172 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 9 6 0 3 +BITMAP +FF80 +FF80 +0180 +0180 +0180 +0180 +ENDCHAR +STARTCHAR 00AD +ENCODING 173 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 5 2 1 3 +BITMAP +F8 +F8 +ENDCHAR +STARTCHAR 00AE +ENCODING 174 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 12 12 0 0 +BITMAP +0F00 +30C0 +4020 +4E20 +8910 +8910 +8E10 +8910 +4920 +4020 +30C0 +0F00 +ENDCHAR +STARTCHAR 00AF +ENCODING 175 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 9 2 0 13 +BITMAP +FF80 +FF80 +ENDCHAR +STARTCHAR 00B0 +ENCODING 176 +SWIDTH 420 0 +DWIDTH 7 0 +BBX 5 5 1 7 +BITMAP +70 +88 +88 +88 +70 +ENDCHAR +STARTCHAR 00B1 +ENCODING 177 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 11 0 0 +BITMAP +18 +18 +18 +FF +FF +18 +18 +18 +00 +FF +FF +ENDCHAR +STARTCHAR 00B2 +ENCODING 178 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 5 6 0 6 +BITMAP +70 +D8 +18 +30 +60 +F8 +ENDCHAR +STARTCHAR 00B3 +ENCODING 179 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 5 6 0 6 +BITMAP +70 +D8 +30 +18 +D8 +70 +ENDCHAR +STARTCHAR 00B4 +ENCODING 180 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 3 2 1 10 +BITMAP +60 +C0 +ENDCHAR +STARTCHAR 00B5 +ENCODING 181 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 -3 +BITMAP +C3 +C3 +C3 +C3 +C3 +C3 +E7 +FF +DB +C0 +C0 +C0 +ENDCHAR +STARTCHAR 00B6 +ENCODING 182 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 9 16 0 -4 +BITMAP +3F80 +7F80 +FB00 +FB00 +FB00 +FB00 +7B00 +1B00 +1B00 +1B00 +1B00 +1B00 +1B00 +1B00 +1B00 +1B00 +ENDCHAR +STARTCHAR 00B7 +ENCODING 183 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 2 2 2 5 +BITMAP +C0 +C0 +ENDCHAR +STARTCHAR 00B8 +ENCODING 184 +SWIDTH 300 0 +DWIDTH 5 0 +BBX 4 3 0 -3 +BITMAP +70 +30 +E0 +ENDCHAR +STARTCHAR 00B9 +ENCODING 185 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 4 6 0 6 +BITMAP +30 +F0 +30 +30 +30 +30 +ENDCHAR +STARTCHAR 00BA +ENCODING 186 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 5 6 1 6 +BITMAP +70 +D8 +D8 +D8 +D8 +70 +ENDCHAR +STARTCHAR 00BB +ENCODING 187 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 8 1 1 +BITMAP +D8 +6C +6C +36 +36 +6C +6C +D8 +ENDCHAR +STARTCHAR 00BC +ENCODING 188 +SWIDTH 840 0 +DWIDTH 14 0 +BBX 14 12 0 0 +BITMAP +30C0 +F0C0 +3180 +3180 +3300 +3300 +0618 +0638 +0C58 +1898 +18FC +3018 +ENDCHAR +STARTCHAR 00BD +ENCODING 189 +SWIDTH 840 0 +DWIDTH 14 0 +BBX 13 12 0 0 +BITMAP +30C0 +F0C0 +3180 +3180 +3300 +3300 +0670 +0CD8 +0C18 +1830 +1860 +30F8 +ENDCHAR +STARTCHAR 00BE +ENCODING 190 +SWIDTH 840 0 +DWIDTH 14 0 +BBX 14 12 0 0 +BITMAP +7060 +D8C0 +30C0 +1980 +D980 +7300 +0618 +0638 +0C58 +0C98 +18FC +1818 +ENDCHAR +STARTCHAR 00BF +ENCODING 191 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 -3 +BITMAP +18 +18 +00 +18 +18 +38 +70 +E0 +C3 +C7 +7E +3C +ENDCHAR +STARTCHAR 00C0 +ENCODING 192 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 11 15 0 0 +BITMAP +0C00 +0600 +0000 +0E00 +0E00 +1B00 +1B00 +1B00 +3180 +3180 +3F80 +7FC0 +60C0 +60C0 +C060 +ENDCHAR +STARTCHAR 00C1 +ENCODING 193 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 11 15 0 0 +BITMAP +0300 +0600 +0000 +0E00 +0E00 +1B00 +1B00 +1B00 +3180 +3180 +3F80 +7FC0 +60C0 +60C0 +C060 +ENDCHAR +STARTCHAR 00C2 +ENCODING 194 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 11 15 0 0 +BITMAP +0E00 +1B00 +0000 +0E00 +0E00 +1B00 +1B00 +1B00 +3180 +3180 +3F80 +7FC0 +60C0 +60C0 +C060 +ENDCHAR +STARTCHAR 00C3 +ENCODING 195 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 11 15 0 0 +BITMAP +1C80 +1380 +0000 +0E00 +0E00 +1B00 +1B00 +1B00 +3180 +3180 +3F80 +7FC0 +60C0 +60C0 +C060 +ENDCHAR +STARTCHAR 00C4 +ENCODING 196 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 11 15 0 0 +BITMAP +1980 +1980 +0000 +0E00 +0E00 +1B00 +1B00 +1B00 +3180 +3180 +3F80 +7FC0 +60C0 +60C0 +C060 +ENDCHAR +STARTCHAR 00C5 +ENCODING 197 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 11 15 0 0 +BITMAP +0600 +0900 +0900 +0E00 +0E00 +1B00 +1B00 +1B00 +3180 +3180 +3F80 +7FC0 +60C0 +60C0 +C060 +ENDCHAR +STARTCHAR 00C6 +ENCODING 198 +SWIDTH 1020 0 +DWIDTH 17 0 +BBX 17 12 -1 0 +BITMAP +03FF80 +07FF80 +06C000 +0CC000 +0CC000 +18FF80 +18FF80 +3FC000 +3FC000 +60C000 +60FF80 +C0FF80 +ENDCHAR +STARTCHAR 00C7 +ENCODING 199 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 15 1 -3 +BITMAP +1F00 +7F80 +61C0 +E080 +C000 +C000 +C000 +C000 +E080 +61C0 +7F80 +1F00 +0E00 +0600 +1C00 +ENDCHAR +STARTCHAR 00C8 +ENCODING 200 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 9 15 1 0 +BITMAP +1800 +0C00 +0000 +FF80 +FF80 +C000 +C000 +C000 +FF80 +FF80 +C000 +C000 +C000 +FF80 +FF80 +ENDCHAR +STARTCHAR 00C9 +ENCODING 201 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 9 15 1 0 +BITMAP +0600 +0C00 +0000 +FF80 +FF80 +C000 +C000 +C000 +FF80 +FF80 +C000 +C000 +C000 +FF80 +FF80 +ENDCHAR +STARTCHAR 00CA +ENCODING 202 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 9 15 1 0 +BITMAP +1C00 +3600 +0000 +FF80 +FF80 +C000 +C000 +C000 +FF80 +FF80 +C000 +C000 +C000 +FF80 +FF80 +ENDCHAR +STARTCHAR 00CB +ENCODING 203 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 9 15 1 0 +BITMAP +3300 +3300 +0000 +FF80 +FF80 +C000 +C000 +C000 +FF80 +FF80 +C000 +C000 +C000 +FF80 +FF80 +ENDCHAR +STARTCHAR 00CC +ENCODING 204 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 3 15 0 0 +BITMAP +C0 +60 +00 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +ENDCHAR +STARTCHAR 00CD +ENCODING 205 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 3 15 1 0 +BITMAP +60 +C0 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 00CE +ENCODING 206 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 5 15 0 0 +BITMAP +70 +D8 +00 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +ENDCHAR +STARTCHAR 00CF +ENCODING 207 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 6 15 -1 0 +BITMAP +CC +CC +00 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR 00D0 +ENCODING 208 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 11 12 0 0 +BITMAP +7F00 +7FC0 +60C0 +6060 +6060 +FC60 +6060 +6060 +6060 +60C0 +7FC0 +7F00 +ENDCHAR +STARTCHAR 00D1 +ENCODING 209 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +3900 +2700 +0000 +C0C0 +E0C0 +F0C0 +F0C0 +D8C0 +CCC0 +CCC0 +C6C0 +C3C0 +C3C0 +C1C0 +C0C0 +ENDCHAR +STARTCHAR 00D2 +ENCODING 210 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 11 15 1 0 +BITMAP +0C00 +0600 +0000 +1F00 +7FC0 +60C0 +E060 +C060 +C060 +C060 +C060 +C060 +60C0 +7FC0 +1F00 +ENDCHAR +STARTCHAR 00D3 +ENCODING 211 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 11 15 1 0 +BITMAP +0600 +0C00 +0000 +1F00 +7FC0 +60C0 +E060 +C060 +C060 +C060 +C060 +C060 +60C0 +7FC0 +1F00 +ENDCHAR +STARTCHAR 00D4 +ENCODING 212 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 11 15 1 0 +BITMAP +0E00 +1B00 +0000 +1F00 +7FC0 +60C0 +E060 +C060 +C060 +C060 +C060 +C060 +60C0 +7FC0 +1F00 +ENDCHAR +STARTCHAR 00D5 +ENCODING 213 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 11 15 1 0 +BITMAP +1C80 +1380 +0000 +1F00 +7FC0 +60C0 +E060 +C060 +C060 +C060 +C060 +C060 +60C0 +7FC0 +1F00 +ENDCHAR +STARTCHAR 00D6 +ENCODING 214 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 11 15 1 0 +BITMAP +1980 +1980 +0000 +1F00 +7FC0 +60C0 +E060 +C060 +C060 +C060 +C060 +C060 +60C0 +7FC0 +1F00 +ENDCHAR +STARTCHAR 00D7 +ENCODING 215 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 6 7 2 2 +BITMAP +84 +CC +78 +30 +78 +CC +84 +ENDCHAR +STARTCHAR 00D8 +ENCODING 216 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 12 13 1 0 +BITMAP +0020 +1F30 +7FE0 +61C0 +C1E0 +C360 +C660 +CC60 +D860 +F060 +70C0 +FFC0 +9F00 +ENDCHAR +STARTCHAR 00D9 +ENCODING 217 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +1800 +0C00 +0000 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +E1C0 +7F80 +3F00 +ENDCHAR +STARTCHAR 00DA +ENCODING 218 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +0600 +0C00 +0000 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +E1C0 +7F80 +3F00 +ENDCHAR +STARTCHAR 00DB +ENCODING 219 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +0E00 +1B00 +0000 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +E1C0 +7F80 +3F00 +ENDCHAR +STARTCHAR 00DC +ENCODING 220 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +3300 +3300 +0000 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +E1C0 +7F80 +3F00 +ENDCHAR +STARTCHAR 00DD +ENCODING 221 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 10 15 0 0 +BITMAP +0600 +0C00 +0000 +C0C0 +E1C0 +6180 +3300 +3300 +1E00 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +ENDCHAR +STARTCHAR 00DE +ENCODING 222 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 9 12 1 0 +BITMAP +C000 +C000 +FE00 +FF00 +C380 +C180 +C180 +C380 +FF00 +FE00 +C000 +C000 +ENDCHAR +STARTCHAR 00DF +ENCODING 223 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +7C +FE +C6 +C6 +CC +CC +CE +C6 +C3 +CB +DF +CE +ENDCHAR +STARTCHAR 00E0 +ENCODING 224 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 12 1 0 +BITMAP +30 +18 +00 +7C +FE +C6 +1E +7E +E6 +C6 +FE +7B +ENDCHAR +STARTCHAR 00E1 +ENCODING 225 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 12 1 0 +BITMAP +0C +18 +00 +7C +FE +C6 +1E +7E +E6 +C6 +FE +7B +ENDCHAR +STARTCHAR 00E2 +ENCODING 226 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 12 1 0 +BITMAP +38 +6C +00 +7C +FE +C6 +1E +7E +E6 +C6 +FE +7B +ENDCHAR +STARTCHAR 00E3 +ENCODING 227 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 12 1 0 +BITMAP +72 +4E +00 +7C +FE +C6 +1E +7E +E6 +C6 +FE +7B +ENDCHAR +STARTCHAR 00E4 +ENCODING 228 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 12 1 0 +BITMAP +66 +66 +00 +7C +FE +C6 +1E +7E +E6 +C6 +FE +7B +ENDCHAR +STARTCHAR 00E5 +ENCODING 229 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 14 1 0 +BITMAP +18 +24 +24 +18 +00 +7C +FE +C6 +1E +7E +E6 +C6 +FE +7B +ENDCHAR +STARTCHAR 00E6 +ENCODING 230 +SWIDTH 900 0 +DWIDTH 15 0 +BBX 13 9 1 0 +BITMAP +3DE0 +7FF0 +C618 +1FF8 +7FF8 +E600 +C718 +FFF0 +79E0 +ENDCHAR +STARTCHAR 00E7 +ENCODING 231 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 -3 +BITMAP +3C +7E +E6 +C0 +C0 +C0 +E6 +7E +3C +38 +18 +70 +ENDCHAR +STARTCHAR 00E8 +ENCODING 232 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +30 +18 +00 +38 +7C +C6 +FE +FE +C0 +E6 +7C +38 +ENDCHAR +STARTCHAR 00E9 +ENCODING 233 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +18 +30 +00 +38 +7C +C6 +FE +FE +C0 +E6 +7C +38 +ENDCHAR +STARTCHAR 00EA +ENCODING 234 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +38 +6C +00 +38 +7C +C6 +FE +FE +C0 +E6 +7C +38 +ENDCHAR +STARTCHAR 00EB +ENCODING 235 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +66 +66 +00 +38 +7C +C6 +FE +FE +C0 +E6 +7C +38 +ENDCHAR +STARTCHAR 00EC +ENCODING 236 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 3 12 0 0 +BITMAP +C0 +60 +00 +60 +60 +60 +60 +60 +60 +60 +60 +60 +ENDCHAR +STARTCHAR 00ED +ENCODING 237 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 3 12 1 0 +BITMAP +60 +C0 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 00EE +ENCODING 238 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 5 12 0 0 +BITMAP +70 +D8 +00 +60 +60 +60 +60 +60 +60 +60 +60 +60 +ENDCHAR +STARTCHAR 00EF +ENCODING 239 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 6 12 -1 0 +BITMAP +CC +CC +00 +30 +30 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR 00F0 +ENCODING 240 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +1A +0C +16 +3A +7F +E7 +C3 +C3 +C3 +E7 +7E +3C +ENDCHAR +STARTCHAR 00F1 +ENCODING 241 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +72 +4E +00 +DE +FF +E3 +C3 +C3 +C3 +C3 +C3 +C3 +ENDCHAR +STARTCHAR 00F2 +ENCODING 242 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +18 +0C +00 +3C +7E +E7 +C3 +C3 +C3 +E7 +7E +3C +ENDCHAR +STARTCHAR 00F3 +ENCODING 243 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +0C +18 +00 +3C +7E +E7 +C3 +C3 +C3 +E7 +7E +3C +ENDCHAR +STARTCHAR 00F4 +ENCODING 244 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +1C +36 +00 +3C +7E +E7 +C3 +C3 +C3 +E7 +7E +3C +ENDCHAR +STARTCHAR 00F5 +ENCODING 245 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +72 +4E +00 +3C +7E +E7 +C3 +C3 +C3 +E7 +7E +3C +ENDCHAR +STARTCHAR 00F6 +ENCODING 246 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +66 +66 +00 +3C +7E +E7 +C3 +C3 +C3 +E7 +7E +3C +ENDCHAR +STARTCHAR 00F7 +ENCODING 247 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 8 0 2 +BITMAP +18 +18 +00 +FF +FF +00 +18 +18 +ENDCHAR +STARTCHAR 00F8 +ENCODING 248 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 10 1 0 +BITMAP +02 +3B +7E +EF +CB +DB +F3 +E7 +7E +DC +ENDCHAR +STARTCHAR 00F9 +ENCODING 249 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +30 +18 +00 +C3 +C3 +C3 +C3 +C3 +C3 +C7 +FF +7B +ENDCHAR +STARTCHAR 00FA +ENCODING 250 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +0C +18 +00 +C3 +C3 +C3 +C3 +C3 +C3 +C7 +FF +7B +ENDCHAR +STARTCHAR 00FB +ENCODING 251 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +1C +36 +00 +C3 +C3 +C3 +C3 +C3 +C3 +C7 +FF +7B +ENDCHAR +STARTCHAR 00FC +ENCODING 252 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +66 +66 +00 +C3 +C3 +C3 +C3 +C3 +C3 +C7 +FF +7B +ENDCHAR +STARTCHAR 00FD +ENCODING 253 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 9 15 0 -3 +BITMAP +0600 +0C00 +0000 +C180 +C180 +6300 +6300 +3600 +3600 +3E00 +1C00 +1C00 +1800 +7800 +7000 +ENDCHAR +STARTCHAR 00FE +ENCODING 254 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 15 1 -3 +BITMAP +C0 +C0 +C0 +DC +FE +E7 +C3 +C3 +C3 +E7 +FE +DC +C0 +C0 +C0 +ENDCHAR +STARTCHAR 00FF +ENCODING 255 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 9 15 0 -3 +BITMAP +3300 +3300 +0000 +C180 +C180 +6300 +6300 +3600 +3600 +3E00 +1C00 +1C00 +1800 +7800 +7000 +ENDCHAR +STARTCHAR 0100 +ENCODING 256 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 11 15 0 0 +BITMAP +1F80 +1F80 +0000 +0E00 +0E00 +1B00 +1B00 +1B00 +3180 +3180 +3F80 +7FC0 +60C0 +60C0 +C060 +ENDCHAR +STARTCHAR 0101 +ENCODING 257 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 12 1 0 +BITMAP +7E +7E +00 +7C +FE +C6 +1E +7E +E6 +C6 +FE +7B +ENDCHAR +STARTCHAR 0102 +ENCODING 258 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 11 15 0 0 +BITMAP +1100 +0E00 +0000 +0E00 +0E00 +1B00 +1B00 +1B00 +3180 +3180 +3F80 +7FC0 +60C0 +60C0 +C060 +ENDCHAR +STARTCHAR 0103 +ENCODING 259 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 12 1 0 +BITMAP +44 +38 +00 +7C +FE +C6 +1E +7E +E6 +C6 +FE +7B +ENDCHAR +STARTCHAR 0104 +ENCODING 260 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 11 15 0 -3 +BITMAP +0E00 +0E00 +1B00 +1B00 +1B00 +3180 +3180 +3F80 +7FC0 +60C0 +60C0 +C060 +0040 +00C0 +00E0 +ENDCHAR +STARTCHAR 0105 +ENCODING 261 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 12 1 -3 +BITMAP +7C +FE +C6 +1E +7E +E6 +C6 +FE +7B +02 +06 +07 +ENDCHAR +STARTCHAR 0106 +ENCODING 262 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +0600 +0C00 +0000 +1F00 +7F80 +61C0 +E080 +C000 +C000 +C000 +C000 +E080 +61C0 +7F80 +1F00 +ENDCHAR +STARTCHAR 0107 +ENCODING 263 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +0C +18 +00 +3C +7E +E6 +C0 +C0 +C0 +E6 +7E +3C +ENDCHAR +STARTCHAR 0108 +ENCODING 264 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +0E00 +1B00 +0000 +1F00 +7F80 +61C0 +E080 +C000 +C000 +C000 +C000 +E080 +61C0 +7F80 +1F00 +ENDCHAR +STARTCHAR 0109 +ENCODING 265 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +38 +6C +00 +3C +7E +E6 +C0 +C0 +C0 +E6 +7E +3C +ENDCHAR +STARTCHAR 010A +ENCODING 266 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +0C00 +0C00 +0000 +1F00 +7F80 +61C0 +E080 +C000 +C000 +C000 +C000 +E080 +61C0 +7F80 +1F00 +ENDCHAR +STARTCHAR 010B +ENCODING 267 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +18 +18 +00 +3C +7E +E6 +C0 +C0 +C0 +E6 +7E +3C +ENDCHAR +STARTCHAR 010C +ENCODING 268 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +1B00 +0E00 +0000 +1F00 +7F80 +61C0 +E080 +C000 +C000 +C000 +C000 +E080 +61C0 +7F80 +1F00 +ENDCHAR +STARTCHAR 010D +ENCODING 269 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +6C +38 +00 +3C +7E +E6 +C0 +C0 +C0 +E6 +7E +3C +ENDCHAR +STARTCHAR 010E +ENCODING 270 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +3600 +1C00 +0000 +FE00 +FF80 +C180 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C180 +FF80 +FE00 +ENDCHAR +STARTCHAR 010F +ENCODING 271 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 11 12 1 0 +BITMAP +0360 +0360 +0320 +3B40 +7F00 +E700 +C300 +C300 +C300 +E700 +7F00 +3B00 +ENDCHAR +STARTCHAR 0110 +ENCODING 272 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 11 12 0 0 +BITMAP +7F00 +7FC0 +60C0 +6060 +6060 +FC60 +6060 +6060 +6060 +60C0 +7FC0 +7F00 +ENDCHAR +STARTCHAR 0111 +ENCODING 273 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 9 12 1 0 +BITMAP +0300 +1F80 +0300 +3B00 +7F00 +E700 +C300 +C300 +C300 +E700 +7F00 +3B00 +ENDCHAR +STARTCHAR 0112 +ENCODING 274 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 9 15 1 0 +BITMAP +3F00 +3F00 +0000 +FF80 +FF80 +C000 +C000 +C000 +FF80 +FF80 +C000 +C000 +C000 +FF80 +FF80 +ENDCHAR +STARTCHAR 0113 +ENCODING 275 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +7E +7E +00 +38 +7C +C6 +FE +FE +C0 +E6 +7C +38 +ENDCHAR +STARTCHAR 0114 +ENCODING 276 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 9 15 1 0 +BITMAP +2200 +1C00 +0000 +FF80 +FF80 +C000 +C000 +C000 +FF80 +FF80 +C000 +C000 +C000 +FF80 +FF80 +ENDCHAR +STARTCHAR 0115 +ENCODING 277 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +44 +38 +00 +38 +7C +C6 +FE +FE +C0 +E6 +7C +38 +ENDCHAR +STARTCHAR 0116 +ENCODING 278 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 9 15 1 0 +BITMAP +0C00 +0C00 +0000 +FF80 +FF80 +C000 +C000 +C000 +FF80 +FF80 +C000 +C000 +C000 +FF80 +FF80 +ENDCHAR +STARTCHAR 0117 +ENCODING 279 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +18 +18 +00 +38 +7C +C6 +FE +FE +C0 +E6 +7C +38 +ENDCHAR +STARTCHAR 0118 +ENCODING 280 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 9 15 1 -3 +BITMAP +FF80 +FF80 +C000 +C000 +C000 +FF80 +FF80 +C000 +C000 +C000 +FF80 +FF80 +0100 +0300 +0380 +ENDCHAR +STARTCHAR 0119 +ENCODING 281 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 -3 +BITMAP +38 +7C +C6 +FE +FE +C0 +E6 +7C +38 +08 +18 +1C +ENDCHAR +STARTCHAR 011A +ENCODING 282 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 9 15 1 0 +BITMAP +3600 +1C00 +0000 +FF80 +FF80 +C000 +C000 +C000 +FF80 +FF80 +C000 +C000 +C000 +FF80 +FF80 +ENDCHAR +STARTCHAR 011B +ENCODING 283 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +6C +38 +00 +38 +7C +C6 +FE +FE +C0 +E6 +7C +38 +ENDCHAR +STARTCHAR 011C +ENCODING 284 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 11 15 1 0 +BITMAP +0E00 +1B00 +0000 +1F80 +7FC0 +60E0 +E040 +C000 +C000 +C3E0 +C3E0 +E060 +60E0 +7FE0 +1F80 +ENDCHAR +STARTCHAR 011D +ENCODING 285 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 15 1 -3 +BITMAP +1C +36 +00 +3B +7F +E7 +C3 +C3 +C3 +E7 +7F +3B +C3 +FF +7E +ENDCHAR +STARTCHAR 011E +ENCODING 286 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 11 15 1 0 +BITMAP +1100 +0E00 +0000 +1F80 +7FC0 +60E0 +E040 +C000 +C000 +C3E0 +C3E0 +E060 +60E0 +7FE0 +1F80 +ENDCHAR +STARTCHAR 011F +ENCODING 287 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 15 1 -3 +BITMAP +22 +1C +00 +3B +7F +E7 +C3 +C3 +C3 +E7 +7F +3B +C3 +FF +7E +ENDCHAR +STARTCHAR 0120 +ENCODING 288 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 11 15 1 0 +BITMAP +0600 +0600 +0000 +1F80 +7FC0 +60E0 +E040 +C000 +C000 +C3E0 +C3E0 +E060 +60E0 +7FE0 +1F80 +ENDCHAR +STARTCHAR 0121 +ENCODING 289 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 15 1 -3 +BITMAP +18 +18 +00 +3B +7F +E7 +C3 +C3 +C3 +E7 +7F +3B +C3 +FF +7E +ENDCHAR +STARTCHAR 0122 +ENCODING 290 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 11 17 1 -5 +BITMAP +1F80 +7FC0 +60E0 +E040 +C000 +C000 +C3E0 +C3E0 +E060 +60E0 +7FE0 +1F80 +0000 +0600 +0600 +0200 +0400 +ENDCHAR +STARTCHAR 0123 +ENCODING 291 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 17 1 -3 +BITMAP +08 +10 +18 +18 +00 +3B +7F +E7 +C3 +C3 +C3 +E7 +7F +3B +C3 +FF +7C +ENDCHAR +STARTCHAR 0124 +ENCODING 292 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +0E00 +1B00 +0000 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +FFC0 +FFC0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +ENDCHAR +STARTCHAR 0125 +ENCODING 293 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 15 1 0 +BITMAP +1C +36 +00 +C0 +C0 +C0 +DE +FF +E3 +C3 +C3 +C3 +C3 +C3 +C3 +ENDCHAR +STARTCHAR 0126 +ENCODING 294 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 12 12 0 0 +BITMAP +6060 +FFF0 +FFF0 +6060 +6060 +7FE0 +7FE0 +6060 +6060 +6060 +6060 +6060 +ENDCHAR +STARTCHAR 0127 +ENCODING 295 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 9 12 0 0 +BITMAP +6000 +FC00 +6000 +6F00 +7F80 +7180 +6180 +6180 +6180 +6180 +6180 +6180 +ENDCHAR +STARTCHAR 0128 +ENCODING 296 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 6 15 -1 0 +BITMAP +E4 +9C +00 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR 0129 +ENCODING 297 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 6 12 -1 0 +BITMAP +E4 +9C +00 +30 +30 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR 012A +ENCODING 298 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 6 15 -1 0 +BITMAP +FC +FC +00 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR 012B +ENCODING 299 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 6 12 -1 0 +BITMAP +FC +FC +00 +30 +30 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR 012C +ENCODING 300 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 5 15 0 0 +BITMAP +88 +70 +00 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +ENDCHAR +STARTCHAR 012D +ENCODING 301 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 5 12 0 0 +BITMAP +88 +70 +00 +60 +60 +60 +60 +60 +60 +60 +60 +60 +ENDCHAR +STARTCHAR 012E +ENCODING 302 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 3 15 0 -3 +BITMAP +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +40 +C0 +E0 +ENDCHAR +STARTCHAR 012F +ENCODING 303 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 3 15 0 -3 +BITMAP +60 +60 +00 +60 +60 +60 +60 +60 +60 +60 +60 +60 +40 +C0 +E0 +ENDCHAR +STARTCHAR 0130 +ENCODING 304 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 2 15 1 0 +BITMAP +C0 +C0 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 0131 +ENCODING 305 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 2 9 1 0 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 0132 +ENCODING 306 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 11 12 1 0 +BITMAP +C060 +C060 +C060 +C060 +C060 +C060 +C060 +C060 +D860 +DCE0 +CFC0 +C780 +ENDCHAR +STARTCHAR 0133 +ENCODING 307 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 15 1 -3 +BITMAP +C6 +C6 +00 +C6 +C6 +C6 +C6 +C6 +C6 +C6 +C6 +C6 +06 +1E +1C +ENDCHAR +STARTCHAR 0134 +ENCODING 308 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 9 15 0 0 +BITMAP +0700 +0D80 +0000 +0300 +0300 +0300 +0300 +0300 +0300 +0300 +0300 +C300 +E700 +7E00 +3C00 +ENDCHAR +STARTCHAR 0135 +ENCODING 309 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 6 15 -1 -3 +BITMAP +38 +6C +00 +30 +30 +30 +30 +30 +30 +30 +30 +30 +30 +F0 +E0 +ENDCHAR +STARTCHAR 0136 +ENCODING 310 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 17 1 -5 +BITMAP +C0C0 +C180 +C300 +C600 +CC00 +DE00 +F700 +E300 +C380 +C180 +C0C0 +C0C0 +0000 +0C00 +0C00 +0400 +0800 +ENDCHAR +STARTCHAR 0137 +ENCODING 311 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 17 1 -5 +BITMAP +C0 +C0 +C0 +C6 +CC +D8 +F8 +FC +EC +CC +C6 +C6 +00 +18 +18 +08 +10 +ENDCHAR +STARTCHAR 0138 +ENCODING 312 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 8 9 1 0 +BITMAP +C7 +CE +DC +F8 +F8 +EC +CE +C6 +C3 +ENDCHAR +STARTCHAR 0139 +ENCODING 313 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 15 1 0 +BITMAP +18 +30 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +FF +FF +ENDCHAR +STARTCHAR 013A +ENCODING 314 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 3 15 1 0 +BITMAP +60 +C0 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 013B +ENCODING 315 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 17 1 -5 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +FF +FF +00 +18 +18 +08 +10 +ENDCHAR +STARTCHAR 013C +ENCODING 316 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 2 17 1 -5 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +00 +C0 +C0 +40 +80 +ENDCHAR +STARTCHAR 013D +ENCODING 317 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +C3 +C3 +C1 +C1 +C2 +C0 +C0 +C0 +C0 +C0 +FF +FF +ENDCHAR +STARTCHAR 013E +ENCODING 318 +SWIDTH 420 0 +DWIDTH 7 0 +BBX 6 12 1 0 +BITMAP +CC +CC +C4 +C8 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 013F +ENCODING 319 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +C0 +C0 +C0 +C0 +C6 +C6 +C0 +C0 +C0 +C0 +FF +FF +ENDCHAR +STARTCHAR 0140 +ENCODING 320 +SWIDTH 420 0 +DWIDTH 7 0 +BBX 5 12 1 0 +BITMAP +C0 +C0 +C0 +C0 +C0 +D8 +D8 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 0141 +ENCODING 321 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 9 12 0 0 +BITMAP +6000 +6000 +6400 +6800 +7000 +6000 +6000 +E000 +6000 +6000 +7F80 +7F80 +ENDCHAR +STARTCHAR 0142 +ENCODING 322 +SWIDTH 240 0 +DWIDTH 4 0 +BBX 4 12 0 0 +BITMAP +60 +60 +60 +60 +70 +60 +60 +E0 +60 +60 +60 +60 +ENDCHAR +STARTCHAR 0143 +ENCODING 323 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +0600 +0C00 +0000 +C0C0 +E0C0 +F0C0 +F0C0 +D8C0 +CCC0 +CCC0 +C6C0 +C3C0 +C3C0 +C1C0 +C0C0 +ENDCHAR +STARTCHAR 0144 +ENCODING 324 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +0C +18 +00 +DE +FF +E3 +C3 +C3 +C3 +C3 +C3 +C3 +ENDCHAR +STARTCHAR 0145 +ENCODING 325 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 17 1 -5 +BITMAP +C0C0 +E0C0 +F0C0 +F0C0 +D8C0 +CCC0 +CCC0 +C6C0 +C3C0 +C3C0 +C1C0 +C0C0 +0000 +0C00 +0C00 +0400 +0800 +ENDCHAR +STARTCHAR 0146 +ENCODING 326 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 14 1 -5 +BITMAP +DE +FF +E3 +C3 +C3 +C3 +C3 +C3 +C3 +00 +18 +18 +08 +10 +ENDCHAR +STARTCHAR 0147 +ENCODING 327 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +1B00 +0E00 +0000 +C0C0 +E0C0 +F0C0 +F0C0 +D8C0 +CCC0 +CCC0 +C6C0 +C3C0 +C3C0 +C1C0 +C0C0 +ENDCHAR +STARTCHAR 0148 +ENCODING 328 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +36 +1C +00 +DE +FF +E3 +C3 +C3 +C3 +C3 +C3 +C3 +ENDCHAR +STARTCHAR 0149 +ENCODING 329 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 11 12 0 0 +BITMAP +C000 +C000 +4000 +5BC0 +9FE0 +1C60 +1860 +1860 +1860 +1860 +1860 +1860 +ENDCHAR +STARTCHAR 014A +ENCODING 330 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 12 1 0 +BITMAP +CF00 +FF80 +E1C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C1C0 +CF80 +CF00 +ENDCHAR +STARTCHAR 014B +ENCODING 331 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 13 1 -4 +BITMAP +DE +FF +E3 +C3 +C3 +C3 +C3 +C3 +C3 +03 +03 +0F +0E +ENDCHAR +STARTCHAR 014C +ENCODING 332 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 11 15 1 0 +BITMAP +1F80 +1F80 +0000 +1F00 +7FC0 +60C0 +E060 +C060 +C060 +C060 +C060 +C060 +60C0 +7FC0 +1F00 +ENDCHAR +STARTCHAR 014D +ENCODING 333 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +7E +7E +00 +3C +7E +E7 +C3 +C3 +C3 +E7 +7E +3C +ENDCHAR +STARTCHAR 014E +ENCODING 334 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 11 15 1 0 +BITMAP +1100 +0E00 +0000 +1F00 +7FC0 +60C0 +E060 +C060 +C060 +C060 +C060 +C060 +60C0 +7FC0 +1F00 +ENDCHAR +STARTCHAR 014F +ENCODING 335 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +22 +1C +00 +3C +7E +E7 +C3 +C3 +C3 +E7 +7E +3C +ENDCHAR +STARTCHAR 0150 +ENCODING 336 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 11 15 1 0 +BITMAP +0D80 +1B00 +0000 +1F00 +7FC0 +60C0 +E060 +C060 +C060 +C060 +C060 +C060 +60C0 +7FC0 +1F00 +ENDCHAR +STARTCHAR 0151 +ENCODING 337 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +36 +6C +00 +3C +7E +E7 +C3 +C3 +C3 +E7 +7E +3C +ENDCHAR +STARTCHAR 0152 +ENCODING 338 +SWIDTH 1020 0 +DWIDTH 17 0 +BBX 16 12 0 0 +BITMAP +3DFF +7FFF +E380 +C180 +C180 +C1FF +C1FF +C180 +C180 +E380 +7FFF +3DFF +ENDCHAR +STARTCHAR 0153 +ENCODING 339 +SWIDTH 900 0 +DWIDTH 15 0 +BBX 13 9 1 0 +BITMAP +3CE0 +7FF0 +E718 +C3F8 +C3F8 +C300 +E798 +7FF0 +3CE0 +ENDCHAR +STARTCHAR 0154 +ENCODING 340 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 11 15 1 0 +BITMAP +0600 +0C00 +0000 +FF00 +FF80 +C1C0 +C0C0 +C1C0 +FF80 +FE00 +C700 +C380 +C180 +C1C0 +C0E0 +ENDCHAR +STARTCHAR 0155 +ENCODING 341 +SWIDTH 420 0 +DWIDTH 7 0 +BBX 6 12 1 0 +BITMAP +18 +30 +00 +DC +FC +E0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 0156 +ENCODING 342 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 11 17 1 -5 +BITMAP +FF00 +FF80 +C1C0 +C0C0 +C1C0 +FF80 +FE00 +C700 +C380 +C180 +C1C0 +C0E0 +0000 +0C00 +0C00 +0400 +0800 +ENDCHAR +STARTCHAR 0157 +ENCODING 343 +SWIDTH 420 0 +DWIDTH 7 0 +BBX 6 14 1 -5 +BITMAP +DC +FC +E0 +C0 +C0 +C0 +C0 +C0 +C0 +00 +C0 +C0 +40 +80 +ENDCHAR +STARTCHAR 0158 +ENCODING 344 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 11 15 1 0 +BITMAP +3600 +1C00 +0000 +FF00 +FF80 +C1C0 +C0C0 +C1C0 +FF80 +FE00 +C700 +C380 +C180 +C1C0 +C0E0 +ENDCHAR +STARTCHAR 0159 +ENCODING 345 +SWIDTH 420 0 +DWIDTH 7 0 +BBX 6 12 1 0 +BITMAP +D8 +70 +00 +DC +FC +E0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 015A +ENCODING 346 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 9 15 1 0 +BITMAP +0C00 +1800 +0000 +3E00 +7F00 +E380 +C180 +F000 +7E00 +1F00 +0380 +C180 +E380 +7F00 +3E00 +ENDCHAR +STARTCHAR 015B +ENCODING 347 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +18 +30 +00 +7C +FE +C6 +F0 +7C +0E +C6 +FE +7C +ENDCHAR +STARTCHAR 015C +ENCODING 348 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 9 15 1 0 +BITMAP +1C00 +3600 +0000 +3E00 +7F00 +E380 +C180 +F000 +7E00 +1F00 +0380 +C180 +E380 +7F00 +3E00 +ENDCHAR +STARTCHAR 015D +ENCODING 349 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +38 +6C +00 +7C +FE +C6 +F0 +7C +0E +C6 +FE +7C +ENDCHAR +STARTCHAR 015E +ENCODING 350 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 9 15 1 -3 +BITMAP +3E00 +7F00 +E380 +C180 +F000 +7E00 +1F00 +0380 +C180 +E380 +7F00 +3E00 +1C00 +0C00 +3800 +ENDCHAR +STARTCHAR 015F +ENCODING 351 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 -3 +BITMAP +7C +FE +C6 +F0 +7C +0E +C6 +FE +7C +38 +18 +70 +ENDCHAR +STARTCHAR 0160 +ENCODING 352 +SWIDTH 660 0 +DWIDTH 11 0 +BBX 9 15 1 0 +BITMAP +3600 +1C00 +0000 +3E00 +7F00 +E380 +C180 +F000 +7E00 +1F00 +0380 +C180 +E380 +7F00 +3E00 +ENDCHAR +STARTCHAR 0161 +ENCODING 353 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +6C +38 +00 +7C +FE +C6 +F0 +7C +0E +C6 +FE +7C +ENDCHAR +STARTCHAR 0162 +ENCODING 354 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 10 15 0 -3 +BITMAP +FFC0 +FFC0 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +0E00 +0600 +1C00 +ENDCHAR +STARTCHAR 0163 +ENCODING 355 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 5 15 0 -3 +BITMAP +20 +60 +60 +F8 +F8 +60 +60 +60 +60 +60 +78 +38 +38 +18 +70 +ENDCHAR +STARTCHAR 0164 +ENCODING 356 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 10 15 0 0 +BITMAP +1B00 +0E00 +0000 +FFC0 +FFC0 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +ENDCHAR +STARTCHAR 0165 +ENCODING 357 +SWIDTH 480 0 +DWIDTH 8 0 +BBX 8 12 0 0 +BITMAP +23 +63 +61 +FA +F8 +60 +60 +60 +60 +60 +78 +38 +ENDCHAR +STARTCHAR 0166 +ENCODING 358 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 10 12 0 0 +BITMAP +FFC0 +FFC0 +0C00 +0C00 +0C00 +7F80 +7F80 +0C00 +0C00 +0C00 +0C00 +0C00 +ENDCHAR +STARTCHAR 0167 +ENCODING 359 +SWIDTH 360 0 +DWIDTH 6 0 +BBX 5 12 0 0 +BITMAP +20 +60 +60 +F8 +F8 +60 +F8 +F8 +60 +60 +78 +38 +ENDCHAR +STARTCHAR 0168 +ENCODING 360 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +3900 +2700 +0000 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +E1C0 +7F80 +3F00 +ENDCHAR +STARTCHAR 0169 +ENCODING 361 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +72 +4E +00 +C3 +C3 +C3 +C3 +C3 +C3 +C7 +FF +7B +ENDCHAR +STARTCHAR 016A +ENCODING 362 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +3F00 +3F00 +0000 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +E1C0 +7F80 +3F00 +ENDCHAR +STARTCHAR 016B +ENCODING 363 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +7E +7E +00 +C3 +C3 +C3 +C3 +C3 +C3 +C7 +FF +7B +ENDCHAR +STARTCHAR 016C +ENCODING 364 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +1100 +0E00 +0000 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +E1C0 +7F80 +3F00 +ENDCHAR +STARTCHAR 016D +ENCODING 365 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +22 +1C +00 +C3 +C3 +C3 +C3 +C3 +C3 +C7 +FF +7B +ENDCHAR +STARTCHAR 016E +ENCODING 366 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +0C00 +1200 +1200 +CCC0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +E1C0 +7F80 +3F00 +ENDCHAR +STARTCHAR 016F +ENCODING 367 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 14 1 0 +BITMAP +18 +24 +24 +18 +00 +C3 +C3 +C3 +C3 +C3 +C3 +C7 +FF +7B +ENDCHAR +STARTCHAR 0170 +ENCODING 368 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 15 1 0 +BITMAP +1B00 +3600 +0000 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +E1C0 +7F80 +3F00 +ENDCHAR +STARTCHAR 0171 +ENCODING 369 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +36 +6C +00 +C3 +C3 +C3 +C3 +C3 +C3 +C7 +FF +7B +ENDCHAR +STARTCHAR 0172 +ENCODING 370 +SWIDTH 720 0 +DWIDTH 12 0 +BBX 10 15 1 -3 +BITMAP +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +C0C0 +E1C0 +7F80 +3F00 +0400 +0C00 +0E00 +ENDCHAR +STARTCHAR 0173 +ENCODING 371 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 8 12 1 -3 +BITMAP +C3 +C3 +C3 +C3 +C3 +C3 +C7 +FF +7B +02 +06 +07 +ENDCHAR +STARTCHAR 0174 +ENCODING 372 +SWIDTH 1020 0 +DWIDTH 17 0 +BBX 17 15 0 0 +BITMAP +01C000 +036000 +000000 +C1C180 +E1C180 +63E300 +636300 +636300 +377600 +363600 +363600 +1E3E00 +1C1C00 +1C1C00 +1C1C00 +ENDCHAR +STARTCHAR 0175 +ENCODING 373 +SWIDTH 780 0 +DWIDTH 13 0 +BBX 13 12 0 0 +BITMAP +0700 +0D80 +0000 +C718 +C718 +6730 +6DB0 +6DB0 +6DB0 +38E0 +38E0 +38E0 +ENDCHAR +STARTCHAR 0176 +ENCODING 374 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 10 15 0 0 +BITMAP +0E00 +1B00 +0000 +C0C0 +E1C0 +6180 +3300 +3300 +1E00 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +ENDCHAR +STARTCHAR 0177 +ENCODING 375 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 9 15 0 -3 +BITMAP +1C00 +3600 +0000 +C180 +C180 +6300 +6300 +3600 +3600 +3E00 +1C00 +1C00 +1800 +7800 +7000 +ENDCHAR +STARTCHAR 0178 +ENCODING 376 +SWIDTH 600 0 +DWIDTH 10 0 +BBX 10 15 0 0 +BITMAP +3300 +3300 +0000 +C0C0 +E1C0 +6180 +3300 +3300 +1E00 +0C00 +0C00 +0C00 +0C00 +0C00 +0C00 +ENDCHAR +STARTCHAR 0179 +ENCODING 377 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 9 15 0 0 +BITMAP +0600 +0C00 +0000 +7F80 +7F80 +0300 +0600 +0E00 +0C00 +1800 +3800 +3000 +6000 +FF80 +FF80 +ENDCHAR +STARTCHAR 017A +ENCODING 378 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +0C +18 +00 +FE +FE +0C +1C +38 +70 +60 +FE +FE +ENDCHAR +STARTCHAR 017B +ENCODING 379 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 9 15 0 0 +BITMAP +0C00 +0C00 +0000 +7F80 +7F80 +0300 +0600 +0E00 +0C00 +1800 +3800 +3000 +6000 +FF80 +FF80 +ENDCHAR +STARTCHAR 017C +ENCODING 380 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +18 +18 +00 +FE +FE +0C +1C +38 +70 +60 +FE +FE +ENDCHAR +STARTCHAR 017D +ENCODING 381 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 9 15 0 0 +BITMAP +1B00 +0E00 +0000 +7F80 +7F80 +0300 +0600 +0E00 +0C00 +1800 +3800 +3000 +6000 +FF80 +FF80 +ENDCHAR +STARTCHAR 017E +ENCODING 382 +SWIDTH 540 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +6C +38 +00 +FE +FE +0C +1C +38 +70 +60 +FE +FE +ENDCHAR +ENDFONT diff --git a/oshwa_magtag_display/fonts/ArialMT-9.bdf b/oshwa_magtag_display/fonts/ArialMT-9.bdf new file mode 100644 index 00000000..99fb0676 --- /dev/null +++ b/oshwa_magtag_display/fonts/ArialMT-9.bdf @@ -0,0 +1,2668 @@ +STARTFONT 2.1 +FONT -FontForge-Arial-Book-R-Normal--9-90-75-75-P-46-ISO10646-1 +SIZE 9 75 75 +FONTBOUNDINGBOX 25 18 -7 -5 +COMMENT "Generated by fontforge, http://fontforge.sourceforge.net" +COMMENT "(c) 2017 The Monotype Corporation. All Rights Reserved. " +COMMENT "" +COMMENT "Hebrew OpenType Layout logic copyright (c) 2003 & 2007, Ralph Hancock & John Hudson. This layout logic for Biblical Hebrew is open source software under the MIT License; see embedded license description for details." +STARTPROPERTIES 40 +FOUNDRY "FontForge" +FAMILY_NAME "Arial" +WEIGHT_NAME "Book" +SLANT "R" +SETWIDTH_NAME "Normal" +ADD_STYLE_NAME "" +PIXEL_SIZE 9 +POINT_SIZE 90 +RESOLUTION_X 75 +RESOLUTION_Y 75 +SPACING "P" +AVERAGE_WIDTH 46 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" +FONTNAME_REGISTRY "" +CHARSET_COLLECTIONS "ASCII ISOLatin1Encoding ISO8859-2 ISO8859-5 ISO8859-7 ISO8859-9 ISO8859-8 ISO8859-6 ISO8859-4 ISO10646-1" +FONT_NAME "ArialMT" +FACE_NAME "Arial" +COPYRIGHT "(c) 2017 The Monotype Corporation. All Rights Reserved. " +FONT_VERSION "7.00" +FONT_ASCENT 7 +FONT_DESCENT 2 +UNDERLINE_POSITION -1 +UNDERLINE_THICKNESS 1 +X_HEIGHT 4 +CAP_HEIGHT 6 +RAW_ASCENT 799 +RAW_DESCENT 200 +NORM_SPACE 3 +RELATIVE_WEIGHT 40 +RELATIVE_SETWIDTH 50 +SUPERSCRIPT_X 0 +SUPERSCRIPT_Y 4 +SUPERSCRIPT_SIZE 5 +SUBSCRIPT_X 0 +SUBSCRIPT_Y 1 +SUBSCRIPT_SIZE 5 +FIGURE_WIDTH 5 +AVG_LOWERCASE_WIDTH 49 +AVG_UPPERCASE_WIDTH 65 +ENDPROPERTIES +CHARS 4604 +STARTCHAR space +ENCODING 32 +SWIDTH 277 0 +DWIDTH 3 0 +BBX 1 1 0 0 +BITMAP +00 +ENDCHAR +STARTCHAR exclam +ENCODING 33 +SWIDTH 277 0 +DWIDTH 3 0 +BBX 1 7 1 0 +BITMAP +80 +80 +80 +80 +80 +00 +80 +ENDCHAR +STARTCHAR quotedbl +ENCODING 34 +SWIDTH 354 0 +DWIDTH 3 0 +BBX 3 2 0 5 +BITMAP +A0 +A0 +ENDCHAR +STARTCHAR numbersign +ENCODING 35 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 0 0 +BITMAP +50 +50 +F0 +50 +F0 +A0 +A0 +ENDCHAR +STARTCHAR dollar +ENCODING 36 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +70 +A8 +A0 +70 +28 +A8 +70 +20 +ENDCHAR +STARTCHAR percent +ENCODING 37 +SWIDTH 889 0 +DWIDTH 8 0 +BBX 6 7 1 0 +BITMAP +48 +B0 +50 +10 +28 +34 +28 +ENDCHAR +STARTCHAR ampersand +ENCODING 38 +SWIDTH 666 0 +DWIDTH 6 0 +BBX 6 7 0 0 +BITMAP +30 +48 +48 +70 +94 +88 +74 +ENDCHAR +STARTCHAR quotesingle +ENCODING 39 +SWIDTH 190 0 +DWIDTH 2 0 +BBX 1 2 0 5 +BITMAP +80 +80 +ENDCHAR +STARTCHAR parenleft +ENCODING 40 +SWIDTH 333 0 +DWIDTH 3 0 +BBX 3 9 0 -2 +BITMAP +20 +40 +80 +80 +80 +80 +80 +40 +20 +ENDCHAR +STARTCHAR parenright +ENCODING 41 +SWIDTH 333 0 +DWIDTH 3 0 +BBX 3 9 0 -2 +BITMAP +80 +40 +20 +20 +20 +20 +20 +40 +80 +ENDCHAR +STARTCHAR asterisk +ENCODING 42 +SWIDTH 389 0 +DWIDTH 4 0 +BBX 3 3 0 4 +BITMAP +E0 +40 +A0 +ENDCHAR +STARTCHAR plus +ENCODING 43 +SWIDTH 583 0 +DWIDTH 5 0 +BBX 5 5 0 0 +BITMAP +20 +20 +F8 +20 +20 +ENDCHAR +STARTCHAR comma +ENCODING 44 +SWIDTH 277 0 +DWIDTH 3 0 +BBX 1 2 1 -1 +BITMAP +80 +80 +ENDCHAR +STARTCHAR hyphen +ENCODING 45 +SWIDTH 333 0 +DWIDTH 3 0 +BBX 2 1 0 2 +BITMAP +C0 +ENDCHAR +STARTCHAR period +ENCODING 46 +SWIDTH 277 0 +DWIDTH 3 0 +BBX 1 1 1 0 +BITMAP +80 +ENDCHAR +STARTCHAR slash +ENCODING 47 +SWIDTH 277 0 +DWIDTH 3 0 +BBX 3 7 0 0 +BITMAP +20 +20 +40 +40 +40 +80 +80 +ENDCHAR +STARTCHAR zero +ENCODING 48 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 0 0 +BITMAP +60 +90 +90 +90 +90 +90 +E0 +ENDCHAR +STARTCHAR one +ENCODING 49 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 2 7 1 0 +BITMAP +40 +C0 +40 +40 +40 +40 +40 +ENDCHAR +STARTCHAR two +ENCODING 50 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 0 0 +BITMAP +60 +90 +10 +20 +20 +40 +F0 +ENDCHAR +STARTCHAR three +ENCODING 51 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 0 0 +BITMAP +60 +90 +10 +20 +10 +90 +60 +ENDCHAR +STARTCHAR four +ENCODING 52 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 5 7 0 0 +BITMAP +10 +30 +50 +90 +F8 +10 +10 +ENDCHAR +STARTCHAR five +ENCODING 53 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 0 0 +BITMAP +70 +40 +E0 +90 +10 +90 +60 +ENDCHAR +STARTCHAR six +ENCODING 54 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 0 0 +BITMAP +60 +90 +E0 +90 +90 +90 +60 +ENDCHAR +STARTCHAR seven +ENCODING 55 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 0 0 +BITMAP +F0 +10 +20 +20 +40 +40 +40 +ENDCHAR +STARTCHAR eight +ENCODING 56 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 0 0 +BITMAP +60 +90 +90 +60 +90 +90 +60 +ENDCHAR +STARTCHAR nine +ENCODING 57 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 0 0 +BITMAP +60 +90 +90 +90 +70 +90 +60 +ENDCHAR +STARTCHAR colon +ENCODING 58 +SWIDTH 277 0 +DWIDTH 3 0 +BBX 1 5 1 0 +BITMAP +80 +00 +00 +00 +80 +ENDCHAR +STARTCHAR semicolon +ENCODING 59 +SWIDTH 277 0 +DWIDTH 3 0 +BBX 1 6 1 -1 +BITMAP +80 +00 +00 +00 +80 +80 +ENDCHAR +STARTCHAR less +ENCODING 60 +SWIDTH 583 0 +DWIDTH 5 0 +BBX 3 5 1 1 +BITMAP +20 +40 +80 +40 +20 +ENDCHAR +STARTCHAR equal +ENCODING 61 +SWIDTH 583 0 +DWIDTH 5 0 +BBX 4 3 0 2 +BITMAP +F0 +00 +F0 +ENDCHAR +STARTCHAR greater +ENCODING 62 +SWIDTH 583 0 +DWIDTH 5 0 +BBX 3 5 1 1 +BITMAP +80 +40 +20 +40 +80 +ENDCHAR +STARTCHAR question +ENCODING 63 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 5 7 0 0 +BITMAP +70 +88 +08 +30 +20 +00 +20 +ENDCHAR +STARTCHAR at +ENCODING 64 +SWIDTH 1015 0 +DWIDTH 9 0 +BBX 8 9 1 -2 +BITMAP +3C +42 +95 +AD +A9 +AA +BC +43 +3C +ENDCHAR +STARTCHAR A +ENCODING 65 +SWIDTH 666 0 +DWIDTH 6 0 +BBX 7 7 0 0 +BITMAP +10 +28 +28 +44 +7C +44 +82 +ENDCHAR +STARTCHAR B +ENCODING 66 +SWIDTH 666 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +E0 +90 +90 +F0 +90 +90 +E0 +ENDCHAR +STARTCHAR C +ENCODING 67 +SWIDTH 722 0 +DWIDTH 7 0 +BBX 5 7 1 0 +BITMAP +70 +88 +80 +80 +80 +88 +70 +ENDCHAR +STARTCHAR D +ENCODING 68 +SWIDTH 722 0 +DWIDTH 7 0 +BBX 5 7 1 0 +BITMAP +F0 +88 +88 +88 +88 +88 +F0 +ENDCHAR +STARTCHAR E +ENCODING 69 +SWIDTH 666 0 +DWIDTH 6 0 +BBX 5 7 1 0 +BITMAP +F8 +80 +80 +F8 +80 +80 +F8 +ENDCHAR +STARTCHAR F +ENCODING 70 +SWIDTH 610 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +F0 +80 +80 +E0 +80 +80 +80 +ENDCHAR +STARTCHAR G +ENCODING 71 +SWIDTH 777 0 +DWIDTH 7 0 +BBX 5 7 1 0 +BITMAP +70 +88 +80 +98 +88 +88 +70 +ENDCHAR +STARTCHAR H +ENCODING 72 +SWIDTH 722 0 +DWIDTH 7 0 +BBX 5 7 1 0 +BITMAP +88 +88 +88 +F8 +88 +88 +88 +ENDCHAR +STARTCHAR I +ENCODING 73 +SWIDTH 277 0 +DWIDTH 3 0 +BBX 1 7 1 0 +BITMAP +80 +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR J +ENCODING 74 +SWIDTH 500 0 +DWIDTH 5 0 +BBX 4 7 0 0 +BITMAP +10 +10 +10 +10 +10 +90 +E0 +ENDCHAR +STARTCHAR K +ENCODING 75 +SWIDTH 666 0 +DWIDTH 6 0 +BBX 5 7 1 0 +BITMAP +88 +90 +A0 +C0 +A0 +90 +88 +ENDCHAR +STARTCHAR L +ENCODING 76 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 1 0 +BITMAP +80 +80 +80 +80 +80 +80 +F0 +ENDCHAR +STARTCHAR M +ENCODING 77 +SWIDTH 833 0 +DWIDTH 7 0 +BBX 7 7 0 0 +BITMAP +82 +C6 +C6 +AA +AA +AA +92 +ENDCHAR +STARTCHAR N +ENCODING 78 +SWIDTH 722 0 +DWIDTH 7 0 +BBX 5 7 1 0 +BITMAP +88 +C8 +C8 +A8 +98 +98 +88 +ENDCHAR +STARTCHAR O +ENCODING 79 +SWIDTH 777 0 +DWIDTH 7 0 +BBX 5 7 1 0 +BITMAP +70 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR P +ENCODING 80 +SWIDTH 666 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +F0 +90 +90 +F0 +80 +80 +80 +ENDCHAR +STARTCHAR Q +ENCODING 81 +SWIDTH 777 0 +DWIDTH 7 0 +BBX 5 7 1 0 +BITMAP +70 +88 +88 +88 +88 +90 +78 +ENDCHAR +STARTCHAR R +ENCODING 82 +SWIDTH 722 0 +DWIDTH 7 0 +BBX 5 7 1 0 +BITMAP +F0 +88 +88 +F0 +90 +88 +88 +ENDCHAR +STARTCHAR S +ENCODING 83 +SWIDTH 666 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +60 +90 +80 +60 +10 +90 +60 +ENDCHAR +STARTCHAR T +ENCODING 84 +SWIDTH 610 0 +DWIDTH 5 0 +BBX 5 7 0 0 +BITMAP +F8 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR U +ENCODING 85 +SWIDTH 722 0 +DWIDTH 7 0 +BBX 5 7 1 0 +BITMAP +88 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR V +ENCODING 86 +SWIDTH 666 0 +DWIDTH 6 0 +BBX 7 7 0 0 +BITMAP +82 +82 +44 +44 +28 +28 +10 +ENDCHAR +STARTCHAR W +ENCODING 87 +SWIDTH 943 0 +DWIDTH 9 0 +BBX 9 7 0 0 +BITMAP +8880 +9480 +5500 +5500 +5500 +5500 +2200 +ENDCHAR +STARTCHAR X +ENCODING 88 +SWIDTH 666 0 +DWIDTH 5 0 +BBX 5 7 0 0 +BITMAP +88 +50 +50 +20 +50 +50 +88 +ENDCHAR +STARTCHAR Y +ENCODING 89 +SWIDTH 666 0 +DWIDTH 7 0 +BBX 5 7 1 0 +BITMAP +88 +50 +50 +20 +20 +20 +20 +ENDCHAR +STARTCHAR Z +ENCODING 90 +SWIDTH 610 0 +DWIDTH 6 0 +BBX 6 7 0 0 +BITMAP +FC +08 +10 +20 +40 +80 +FC +ENDCHAR +STARTCHAR bracketleft +ENCODING 91 +SWIDTH 277 0 +DWIDTH 3 0 +BBX 2 9 1 -2 +BITMAP +C0 +80 +80 +80 +80 +80 +80 +80 +C0 +ENDCHAR +STARTCHAR backslash +ENCODING 92 +SWIDTH 277 0 +DWIDTH 3 0 +BBX 3 7 0 0 +BITMAP +80 +80 +40 +40 +40 +20 +20 +ENDCHAR +STARTCHAR bracketright +ENCODING 93 +SWIDTH 277 0 +DWIDTH 3 0 +BBX 2 9 0 -2 +BITMAP +C0 +40 +40 +40 +40 +40 +40 +40 +C0 +ENDCHAR +STARTCHAR asciicircum +ENCODING 94 +SWIDTH 469 0 +DWIDTH 3 0 +BBX 3 3 0 4 +BITMAP +40 +A0 +A0 +ENDCHAR +STARTCHAR underscore +ENCODING 95 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 5 1 0 -2 +BITMAP +F8 +ENDCHAR +STARTCHAR grave +ENCODING 96 +SWIDTH 333 0 +DWIDTH 3 0 +BBX 2 2 0 5 +BITMAP +80 +40 +ENDCHAR +STARTCHAR a +ENCODING 97 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 5 0 0 +BITMAP +F0 +10 +70 +90 +F0 +ENDCHAR +STARTCHAR b +ENCODING 98 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 0 0 +BITMAP +80 +80 +E0 +90 +90 +90 +E0 +ENDCHAR +STARTCHAR c +ENCODING 99 +SWIDTH 500 0 +DWIDTH 5 0 +BBX 4 5 0 0 +BITMAP +60 +90 +80 +90 +60 +ENDCHAR +STARTCHAR d +ENCODING 100 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 0 0 +BITMAP +10 +10 +70 +90 +90 +90 +70 +ENDCHAR +STARTCHAR e +ENCODING 101 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 5 0 0 +BITMAP +60 +90 +F0 +80 +70 +ENDCHAR +STARTCHAR f +ENCODING 102 +SWIDTH 277 0 +DWIDTH 4 0 +BBX 3 7 0 0 +BITMAP +20 +40 +E0 +40 +40 +40 +40 +ENDCHAR +STARTCHAR g +ENCODING 103 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 0 -2 +BITMAP +70 +90 +90 +90 +70 +90 +60 +ENDCHAR +STARTCHAR h +ENCODING 104 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 0 0 +BITMAP +80 +80 +E0 +90 +90 +90 +90 +ENDCHAR +STARTCHAR i +ENCODING 105 +SWIDTH 222 0 +DWIDTH 2 0 +BBX 1 7 0 0 +BITMAP +80 +00 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR j +ENCODING 106 +SWIDTH 222 0 +DWIDTH 2 0 +BBX 2 9 -1 -2 +BITMAP +40 +00 +40 +40 +40 +40 +40 +40 +80 +ENDCHAR +STARTCHAR k +ENCODING 107 +SWIDTH 500 0 +DWIDTH 5 0 +BBX 4 7 0 0 +BITMAP +80 +80 +90 +A0 +E0 +A0 +90 +ENDCHAR +STARTCHAR l +ENCODING 108 +SWIDTH 222 0 +DWIDTH 2 0 +BBX 1 7 0 0 +BITMAP +80 +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR m +ENCODING 109 +SWIDTH 833 0 +DWIDTH 8 0 +BBX 7 5 0 0 +BITMAP +FC +92 +92 +92 +92 +ENDCHAR +STARTCHAR n +ENCODING 110 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 5 0 0 +BITMAP +E0 +90 +90 +90 +90 +ENDCHAR +STARTCHAR o +ENCODING 111 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 5 0 0 +BITMAP +60 +90 +90 +90 +60 +ENDCHAR +STARTCHAR p +ENCODING 112 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 0 -2 +BITMAP +E0 +90 +90 +90 +E0 +80 +80 +ENDCHAR +STARTCHAR q +ENCODING 113 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 0 -2 +BITMAP +70 +90 +90 +90 +70 +10 +10 +ENDCHAR +STARTCHAR r +ENCODING 114 +SWIDTH 333 0 +DWIDTH 3 0 +BBX 3 5 0 0 +BITMAP +E0 +80 +80 +80 +80 +ENDCHAR +STARTCHAR s +ENCODING 115 +SWIDTH 500 0 +DWIDTH 5 0 +BBX 4 5 0 0 +BITMAP +70 +80 +60 +10 +E0 +ENDCHAR +STARTCHAR t +ENCODING 116 +SWIDTH 277 0 +DWIDTH 3 0 +BBX 3 6 -1 0 +BITMAP +40 +E0 +40 +40 +40 +60 +ENDCHAR +STARTCHAR u +ENCODING 117 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 5 0 0 +BITMAP +90 +90 +90 +90 +70 +ENDCHAR +STARTCHAR v +ENCODING 118 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +88 +50 +50 +50 +20 +ENDCHAR +STARTCHAR w +ENCODING 119 +SWIDTH 722 0 +DWIDTH 6 0 +BBX 5 5 0 0 +BITMAP +A8 +A8 +A8 +A8 +50 +ENDCHAR +STARTCHAR x +ENCODING 120 +SWIDTH 500 0 +DWIDTH 5 0 +BBX 4 5 0 0 +BITMAP +90 +60 +40 +60 +90 +ENDCHAR +STARTCHAR y +ENCODING 121 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 5 7 0 -2 +BITMAP +88 +50 +50 +50 +20 +20 +40 +ENDCHAR +STARTCHAR z +ENCODING 122 +SWIDTH 500 0 +DWIDTH 4 0 +BBX 3 5 0 0 +BITMAP +E0 +20 +40 +80 +E0 +ENDCHAR +STARTCHAR braceleft +ENCODING 123 +SWIDTH 333 0 +DWIDTH 3 0 +BBX 3 9 0 -2 +BITMAP +60 +40 +40 +40 +80 +40 +40 +40 +60 +ENDCHAR +STARTCHAR bar +ENCODING 124 +SWIDTH 259 0 +DWIDTH 3 0 +BBX 1 8 1 -1 +BITMAP +80 +80 +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR braceright +ENCODING 125 +SWIDTH 333 0 +DWIDTH 3 0 +BBX 3 9 0 -2 +BITMAP +C0 +40 +40 +40 +20 +40 +40 +40 +C0 +ENDCHAR +STARTCHAR asciitilde +ENCODING 126 +SWIDTH 583 0 +DWIDTH 5 0 +BBX 4 2 0 2 +BITMAP +D0 +B0 +ENDCHAR +STARTCHAR space.dup1 +ENCODING 160 +SWIDTH 277 0 +DWIDTH 3 0 +BBX 1 1 0 0 +BITMAP +00 +ENDCHAR +STARTCHAR exclamdown +ENCODING 161 +SWIDTH 333 0 +DWIDTH 3 0 +BBX 1 7 1 -2 +BITMAP +80 +00 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR cent +ENCODING 162 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 9 0 -2 +BITMAP +20 +20 +60 +B0 +A0 +D0 +60 +40 +40 +ENDCHAR +STARTCHAR sterling +ENCODING 163 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 5 7 0 0 +BITMAP +30 +48 +40 +E0 +40 +40 +F8 +ENDCHAR +STARTCHAR currency +ENCODING 164 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 4 1 1 +BITMAP +F0 +90 +90 +F0 +ENDCHAR +STARTCHAR yen +ENCODING 165 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 5 7 0 0 +BITMAP +88 +50 +50 +F8 +20 +F8 +20 +ENDCHAR +STARTCHAR brokenbar +ENCODING 166 +SWIDTH 259 0 +DWIDTH 3 0 +BBX 1 8 1 -1 +BITMAP +80 +80 +80 +00 +00 +80 +80 +80 +ENDCHAR +STARTCHAR section +ENCODING 167 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 9 0 -2 +BITMAP +E0 +90 +40 +A0 +90 +50 +20 +90 +70 +ENDCHAR +STARTCHAR dieresis +ENCODING 168 +SWIDTH 333 0 +DWIDTH 3 0 +BBX 3 1 0 6 +BITMAP +A0 +ENDCHAR +STARTCHAR copyright +ENCODING 169 +SWIDTH 736 0 +DWIDTH 7 0 +BBX 7 7 0 0 +BITMAP +7C +82 +9A +A2 +9A +82 +7C +ENDCHAR +STARTCHAR ordfeminine +ENCODING 170 +SWIDTH 370 0 +DWIDTH 3 0 +BBX 3 3 0 4 +BITMAP +E0 +60 +E0 +ENDCHAR +STARTCHAR guillemotleft +ENCODING 171 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 4 1 0 +BITMAP +50 +A0 +A0 +50 +ENDCHAR +STARTCHAR logicalnot +ENCODING 172 +SWIDTH 583 0 +DWIDTH 5 0 +BBX 4 3 0 2 +BITMAP +F0 +10 +10 +ENDCHAR +STARTCHAR hyphen.dup2 +ENCODING 173 +SWIDTH 333 0 +DWIDTH 3 0 +BBX 2 1 0 2 +BITMAP +C0 +ENDCHAR +STARTCHAR registered +ENCODING 174 +SWIDTH 736 0 +DWIDTH 7 0 +BBX 7 7 0 0 +BITMAP +7C +82 +B2 +BA +AA +82 +7C +ENDCHAR +STARTCHAR macron +ENCODING 175 +SWIDTH 552 0 +DWIDTH 5 0 +BBX 5 1 0 7 +BITMAP +F8 +ENDCHAR +STARTCHAR degree +ENCODING 176 +SWIDTH 399 0 +DWIDTH 4 0 +BBX 3 3 1 4 +BITMAP +E0 +A0 +E0 +ENDCHAR +STARTCHAR plusminus +ENCODING 177 +SWIDTH 548 0 +DWIDTH 5 0 +BBX 5 6 0 0 +BITMAP +20 +20 +F8 +20 +20 +F8 +ENDCHAR +STARTCHAR uni00B2 +ENCODING 178 +SWIDTH 333 0 +DWIDTH 3 0 +BBX 3 3 0 4 +BITMAP +E0 +40 +E0 +ENDCHAR +STARTCHAR uni00B3 +ENCODING 179 +SWIDTH 333 0 +DWIDTH 3 0 +BBX 3 3 0 4 +BITMAP +E0 +40 +E0 +ENDCHAR +STARTCHAR acute +ENCODING 180 +SWIDTH 333 0 +DWIDTH 3 0 +BBX 2 2 1 5 +BITMAP +40 +80 +ENDCHAR +STARTCHAR mu +ENCODING 181 +SWIDTH 576 0 +DWIDTH 5 0 +BBX 4 7 0 -2 +BITMAP +90 +90 +90 +90 +F0 +80 +80 +ENDCHAR +STARTCHAR paragraph +ENCODING 182 +SWIDTH 537 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +78 +D0 +D0 +D0 +50 +50 +50 +50 +ENDCHAR +STARTCHAR periodcentered +ENCODING 183 +SWIDTH 333 0 +DWIDTH 3 0 +BBX 1 1 1 3 +BITMAP +80 +ENDCHAR +STARTCHAR cedilla +ENCODING 184 +SWIDTH 333 0 +DWIDTH 3 0 +BBX 2 3 0 -3 +BITMAP +40 +40 +C0 +ENDCHAR +STARTCHAR uni00B9 +ENCODING 185 +SWIDTH 333 0 +DWIDTH 3 0 +BBX 2 3 1 4 +BITMAP +40 +C0 +40 +ENDCHAR +STARTCHAR ordmasculine +ENCODING 186 +SWIDTH 365 0 +DWIDTH 3 0 +BBX 3 3 0 4 +BITMAP +E0 +A0 +E0 +ENDCHAR +STARTCHAR guillemotright +ENCODING 187 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 4 0 0 +BITMAP +A0 +50 +50 +A0 +ENDCHAR +STARTCHAR onequarter +ENCODING 188 +SWIDTH 833 0 +DWIDTH 8 0 +BBX 6 7 1 0 +BITMAP +44 +C8 +50 +10 +24 +4C +84 +ENDCHAR +STARTCHAR onehalf +ENCODING 189 +SWIDTH 833 0 +DWIDTH 8 0 +BBX 7 7 1 0 +BITMAP +44 +C8 +50 +10 +2E +44 +8E +ENDCHAR +STARTCHAR threequarters +ENCODING 190 +SWIDTH 833 0 +DWIDTH 8 0 +BBX 7 7 0 0 +BITMAP +E2 +44 +E8 +08 +12 +26 +22 +ENDCHAR +STARTCHAR questiondown +ENCODING 191 +SWIDTH 610 0 +DWIDTH 6 0 +BBX 4 7 1 -2 +BITMAP +20 +00 +20 +60 +80 +90 +60 +ENDCHAR +STARTCHAR Agrave +ENCODING 192 +SWIDTH 666 0 +DWIDTH 6 0 +BBX 7 10 0 0 +BITMAP +10 +08 +00 +10 +28 +28 +44 +7C +44 +82 +ENDCHAR +STARTCHAR Aacute +ENCODING 193 +SWIDTH 666 0 +DWIDTH 6 0 +BBX 7 10 0 0 +BITMAP +08 +10 +00 +10 +28 +28 +44 +7C +44 +82 +ENDCHAR +STARTCHAR Acircumflex +ENCODING 194 +SWIDTH 666 0 +DWIDTH 6 0 +BBX 7 10 0 0 +BITMAP +18 +34 +00 +10 +28 +28 +44 +7C +44 +82 +ENDCHAR +STARTCHAR Atilde +ENCODING 195 +SWIDTH 666 0 +DWIDTH 6 0 +BBX 7 10 0 0 +BITMAP +28 +50 +00 +10 +28 +28 +44 +7C +44 +82 +ENDCHAR +STARTCHAR Adieresis +ENCODING 196 +SWIDTH 666 0 +DWIDTH 6 0 +BBX 7 9 0 0 +BITMAP +28 +00 +10 +28 +28 +44 +7C +44 +82 +ENDCHAR +STARTCHAR Aring +ENCODING 197 +SWIDTH 666 0 +DWIDTH 6 0 +BBX 7 9 0 0 +BITMAP +38 +28 +38 +28 +28 +44 +7C +44 +82 +ENDCHAR +STARTCHAR AE +ENCODING 198 +SWIDTH 1000 0 +DWIDTH 9 0 +BBX 9 7 0 0 +BITMAP +1F80 +2800 +2800 +4F80 +7800 +8800 +8F80 +ENDCHAR +STARTCHAR Ccedilla +ENCODING 199 +SWIDTH 722 0 +DWIDTH 7 0 +BBX 5 10 1 -3 +BITMAP +70 +88 +80 +80 +80 +88 +70 +10 +10 +30 +ENDCHAR +STARTCHAR Egrave +ENCODING 200 +SWIDTH 666 0 +DWIDTH 6 0 +BBX 5 10 1 0 +BITMAP +20 +10 +00 +F8 +80 +80 +F8 +80 +80 +F8 +ENDCHAR +STARTCHAR Eacute +ENCODING 201 +SWIDTH 666 0 +DWIDTH 6 0 +BBX 5 10 1 0 +BITMAP +10 +20 +00 +F8 +80 +80 +F8 +80 +80 +F8 +ENDCHAR +STARTCHAR Ecircumflex +ENCODING 202 +SWIDTH 666 0 +DWIDTH 6 0 +BBX 5 10 1 0 +BITMAP +20 +50 +00 +F8 +80 +80 +F8 +80 +80 +F8 +ENDCHAR +STARTCHAR Edieresis +ENCODING 203 +SWIDTH 666 0 +DWIDTH 6 0 +BBX 5 9 1 0 +BITMAP +50 +00 +F8 +80 +80 +F8 +80 +80 +F8 +ENDCHAR +STARTCHAR Igrave +ENCODING 204 +SWIDTH 277 0 +DWIDTH 3 0 +BBX 2 10 1 0 +BITMAP +80 +40 +00 +80 +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR Iacute +ENCODING 205 +SWIDTH 277 0 +DWIDTH 3 0 +BBX 2 10 0 0 +BITMAP +40 +80 +00 +40 +40 +40 +40 +40 +40 +40 +ENDCHAR +STARTCHAR Icircumflex +ENCODING 206 +SWIDTH 277 0 +DWIDTH 3 0 +BBX 3 10 -1 0 +BITMAP +40 +A0 +00 +20 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR Idieresis +ENCODING 207 +SWIDTH 277 0 +DWIDTH 3 0 +BBX 3 9 0 0 +BITMAP +A0 +00 +40 +40 +40 +40 +40 +40 +40 +ENDCHAR +STARTCHAR Eth +ENCODING 208 +SWIDTH 722 0 +DWIDTH 7 0 +BBX 6 7 0 0 +BITMAP +78 +44 +44 +F4 +44 +44 +78 +ENDCHAR +STARTCHAR Ntilde +ENCODING 209 +SWIDTH 722 0 +DWIDTH 7 0 +BBX 5 10 1 0 +BITMAP +50 +A0 +00 +88 +C8 +C8 +A8 +98 +98 +88 +ENDCHAR +STARTCHAR Ograve +ENCODING 210 +SWIDTH 777 0 +DWIDTH 7 0 +BBX 5 10 1 0 +BITMAP +20 +10 +00 +70 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR Oacute +ENCODING 211 +SWIDTH 777 0 +DWIDTH 7 0 +BBX 5 10 1 0 +BITMAP +10 +20 +00 +70 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR Ocircumflex +ENCODING 212 +SWIDTH 777 0 +DWIDTH 7 0 +BBX 5 10 1 0 +BITMAP +20 +50 +00 +70 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR Otilde +ENCODING 213 +SWIDTH 777 0 +DWIDTH 7 0 +BBX 5 10 1 0 +BITMAP +50 +A0 +00 +70 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR Odieresis +ENCODING 214 +SWIDTH 777 0 +DWIDTH 7 0 +BBX 5 9 1 0 +BITMAP +50 +00 +70 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR multiply +ENCODING 215 +SWIDTH 583 0 +DWIDTH 5 0 +BBX 5 5 0 1 +BITMAP +88 +70 +20 +70 +88 +ENDCHAR +STARTCHAR Oslash +ENCODING 216 +SWIDTH 777 0 +DWIDTH 7 0 +BBX 5 7 1 0 +BITMAP +78 +90 +98 +A8 +C8 +48 +F0 +ENDCHAR +STARTCHAR Ugrave +ENCODING 217 +SWIDTH 722 0 +DWIDTH 7 0 +BBX 5 10 1 0 +BITMAP +40 +20 +00 +88 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR Uacute +ENCODING 218 +SWIDTH 722 0 +DWIDTH 7 0 +BBX 5 10 1 0 +BITMAP +20 +40 +00 +88 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR Ucircumflex +ENCODING 219 +SWIDTH 722 0 +DWIDTH 7 0 +BBX 5 10 1 0 +BITMAP +20 +50 +00 +88 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR Udieresis +ENCODING 220 +SWIDTH 722 0 +DWIDTH 7 0 +BBX 5 9 1 0 +BITMAP +28 +00 +88 +88 +88 +88 +88 +88 +70 +ENDCHAR +STARTCHAR Yacute +ENCODING 221 +SWIDTH 666 0 +DWIDTH 7 0 +BBX 5 10 1 0 +BITMAP +10 +20 +00 +88 +50 +50 +20 +20 +20 +20 +ENDCHAR +STARTCHAR Thorn +ENCODING 222 +SWIDTH 666 0 +DWIDTH 6 0 +BBX 5 7 1 0 +BITMAP +80 +F0 +88 +88 +88 +F0 +80 +ENDCHAR +STARTCHAR germandbls +ENCODING 223 +SWIDTH 610 0 +DWIDTH 6 0 +BBX 4 7 1 0 +BITMAP +40 +A0 +A0 +C0 +B0 +D0 +A0 +ENDCHAR +STARTCHAR agrave +ENCODING 224 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 8 0 0 +BITMAP +40 +20 +00 +F0 +10 +70 +90 +F0 +ENDCHAR +STARTCHAR aacute +ENCODING 225 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 8 0 0 +BITMAP +20 +40 +00 +F0 +10 +70 +90 +F0 +ENDCHAR +STARTCHAR acircumflex +ENCODING 226 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 8 0 0 +BITMAP +20 +50 +00 +F0 +10 +70 +90 +F0 +ENDCHAR +STARTCHAR atilde +ENCODING 227 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 8 0 0 +BITMAP +50 +A0 +00 +F0 +10 +70 +90 +F0 +ENDCHAR +STARTCHAR adieresis +ENCODING 228 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 0 0 +BITMAP +50 +00 +F0 +10 +70 +90 +F0 +ENDCHAR +STARTCHAR aring +ENCODING 229 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 9 0 0 +BITMAP +70 +50 +70 +00 +F0 +10 +70 +90 +F0 +ENDCHAR +STARTCHAR ae +ENCODING 230 +SWIDTH 889 0 +DWIDTH 8 0 +BBX 7 5 0 0 +BITMAP +EC +12 +7E +90 +EE +ENDCHAR +STARTCHAR ccedilla +ENCODING 231 +SWIDTH 500 0 +DWIDTH 5 0 +BBX 4 8 0 -3 +BITMAP +60 +90 +80 +90 +60 +20 +20 +60 +ENDCHAR +STARTCHAR egrave +ENCODING 232 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 8 0 0 +BITMAP +40 +20 +00 +60 +90 +F0 +80 +70 +ENDCHAR +STARTCHAR eacute +ENCODING 233 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 8 0 0 +BITMAP +20 +40 +00 +60 +90 +F0 +80 +70 +ENDCHAR +STARTCHAR ecircumflex +ENCODING 234 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 8 0 0 +BITMAP +20 +50 +00 +60 +90 +F0 +80 +70 +ENDCHAR +STARTCHAR edieresis +ENCODING 235 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 0 0 +BITMAP +A0 +00 +60 +90 +F0 +80 +70 +ENDCHAR +STARTCHAR igrave +ENCODING 236 +SWIDTH 277 0 +DWIDTH 2 0 +BBX 2 8 0 0 +BITMAP +80 +40 +00 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR iacute +ENCODING 237 +SWIDTH 277 0 +DWIDTH 2 0 +BBX 2 8 -1 0 +BITMAP +40 +80 +00 +40 +40 +40 +40 +40 +ENDCHAR +STARTCHAR icircumflex +ENCODING 238 +SWIDTH 277 0 +DWIDTH 2 0 +BBX 3 8 0 0 +BITMAP +C0 +A0 +00 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR idieresis +ENCODING 239 +SWIDTH 277 0 +DWIDTH 2 0 +BBX 3 7 -1 0 +BITMAP +A0 +00 +40 +40 +40 +40 +40 +ENDCHAR +STARTCHAR eth +ENCODING 240 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 0 0 +BITMAP +60 +20 +70 +90 +90 +90 +60 +ENDCHAR +STARTCHAR ntilde +ENCODING 241 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 8 0 0 +BITMAP +50 +A0 +00 +E0 +90 +90 +90 +90 +ENDCHAR +STARTCHAR ograve +ENCODING 242 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 8 0 0 +BITMAP +40 +20 +00 +60 +90 +90 +90 +60 +ENDCHAR +STARTCHAR oacute +ENCODING 243 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 8 0 0 +BITMAP +20 +40 +00 +60 +90 +90 +90 +60 +ENDCHAR +STARTCHAR ocircumflex +ENCODING 244 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 8 0 0 +BITMAP +20 +50 +00 +60 +90 +90 +90 +60 +ENDCHAR +STARTCHAR otilde +ENCODING 245 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 8 0 0 +BITMAP +50 +A0 +00 +60 +90 +90 +90 +60 +ENDCHAR +STARTCHAR odieresis +ENCODING 246 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 0 0 +BITMAP +A0 +00 +60 +90 +90 +90 +60 +ENDCHAR +STARTCHAR divide +ENCODING 247 +SWIDTH 548 0 +DWIDTH 5 0 +BBX 5 5 0 0 +BITMAP +20 +00 +F8 +00 +20 +ENDCHAR +STARTCHAR oslash +ENCODING 248 +SWIDTH 610 0 +DWIDTH 5 0 +BBX 4 5 0 0 +BITMAP +70 +B0 +D0 +D0 +E0 +ENDCHAR +STARTCHAR ugrave +ENCODING 249 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 8 0 0 +BITMAP +40 +20 +00 +90 +90 +90 +90 +70 +ENDCHAR +STARTCHAR uacute +ENCODING 250 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 8 0 0 +BITMAP +20 +40 +00 +90 +90 +90 +90 +70 +ENDCHAR +STARTCHAR ucircumflex +ENCODING 251 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 8 0 0 +BITMAP +40 +A0 +00 +90 +90 +90 +90 +70 +ENDCHAR +STARTCHAR udieresis +ENCODING 252 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 7 0 0 +BITMAP +50 +00 +90 +90 +90 +90 +70 +ENDCHAR +STARTCHAR yacute +ENCODING 253 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 5 10 0 -2 +BITMAP +10 +20 +00 +88 +50 +50 +50 +20 +20 +40 +ENDCHAR +STARTCHAR thorn +ENCODING 254 +SWIDTH 556 0 +DWIDTH 5 0 +BBX 4 9 0 -2 +BITMAP +80 +80 +E0 +90 +90 +90 +E0 +80 +80 +ENDCHAR +STARTCHAR ydieresis +ENCODING 255 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 5 9 0 -2 +BITMAP +50 +00 +88 +50 +50 +50 +20 +20 +40 +ENDCHAR +ENDFONT diff --git a/pi_radio/radio_lorawan.py b/pi_radio/radio_lorawan.py index 545f9454..d8b5bc53 100755 --- a/pi_radio/radio_lorawan.py +++ b/pi_radio/radio_lorawan.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Brent Rubell for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ Example for using the RFM9x Radio with Raspberry Pi and LoRaWAN diff --git a/pi_radio/radio_rfm69.py b/pi_radio/radio_rfm69.py index cf7651de..86fe5045 100644 --- a/pi_radio/radio_rfm69.py +++ b/pi_radio/radio_rfm69.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Brent Rubell for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ Example for using the RFM69HCW Radio with Raspberry Pi. diff --git a/pi_radio/radio_rfm9x.py b/pi_radio/radio_rfm9x.py index c0c903ea..31ea4296 100755 --- a/pi_radio/radio_rfm9x.py +++ b/pi_radio/radio_rfm9x.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Brent Rubell for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ Example for using the RFM9x Radio with Raspberry Pi. diff --git a/pi_radio/rfm69_check.py b/pi_radio/rfm69_check.py index 636d68bd..11e23f75 100644 --- a/pi_radio/rfm69_check.py +++ b/pi_radio/rfm69_check.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Brent Rubell for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ Wiring Check, Pi Radio w/RFM69 diff --git a/pi_radio/rfm9x_check.py b/pi_radio/rfm9x_check.py index 148294a6..8cf18e12 100644 --- a/pi_radio/rfm9x_check.py +++ b/pi_radio/rfm9x_check.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Brent Rubell for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ Wiring Check, Pi Radio w/RFM9x diff --git a/pi_rplidar/display_lidar_pi.py b/pi_rplidar/display_lidar_pi.py index 68abc30d..813f5db2 100644 --- a/pi_rplidar/display_lidar_pi.py +++ b/pi_rplidar/display_lidar_pi.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 Dave Astels for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ Consume LIDAR measurement file and create an image for display. diff --git a/pylint_check.sh b/pylint_check.sh index b250129f..119742c5 100755 --- a/pylint_check.sh +++ b/pylint_check.sh @@ -3,8 +3,9 @@ PYLINT="`type -p pylint3 2>/dev/null || type -p pylint`" echo "Using pylint bin at $PYLINT" +# Use * as the default argument to avoid descending into hidden directories like .git function find_pyfiles() { - if [ $# -eq 0 ]; then set -- .; fi + if [ $# -eq 0 ]; then set -- *; fi for f in $(find "$@" -type f -iname '*.py'); do if [ ! -e "$(dirname $f)/.circuitpython.skip" ]; then echo "$f" diff --git a/pyportal_pet_planter/code.py b/pyportal_pet_planter/code.py index 9b107998..1b462977 100755 --- a/pyportal_pet_planter/code.py +++ b/pyportal_pet_planter/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Brent Rubell for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import time import board diff --git a/pyportal_weather_station/code.py b/pyportal_weather_station/code.py index 477c0dc4..4dfa86d1 100755 --- a/pyportal_weather_station/code.py +++ b/pyportal_weather_station/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 Brent Rubell for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ PyPortal Weather Station ============================================== diff --git a/pyportal_weather_station/weatherstation_helper.py b/pyportal_weather_station/weatherstation_helper.py index 9e692dc9..94731031 100755 --- a/pyportal_weather_station/weatherstation_helper.py +++ b/pyportal_weather_station/weatherstation_helper.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2019 Brent Rubell for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ Helper file for pyportal_weatherstation.py diff --git a/raver_bandolier/code.py b/raver_bandolier/code.py index 3fbc750a..62ee82ef 100644 --- a/raver_bandolier/code.py +++ b/raver_bandolier/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2017 Mikey Skylar for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import time from rainbowio import colorwheel import board diff --git a/rp2040_ble_airlift/ble-bluefruit-color-picker-rp2040/code.py b/rp2040_ble_airlift/ble-bluefruit-color-picker-rp2040/code.py index 56b94ca1..d27b963d 100644 --- a/rp2040_ble_airlift/ble-bluefruit-color-picker-rp2040/code.py +++ b/rp2040_ble_airlift/ble-bluefruit-color-picker-rp2040/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2021 Brent Rubell for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import board import neopixel diff --git a/rp2040_ble_airlift/ble-bluefruit-uart-echo-rp2040/code.py b/rp2040_ble_airlift/ble-bluefruit-uart-echo-rp2040/code.py index a4bc7a22..c9537b3d 100755 --- a/rp2040_ble_airlift/ble-bluefruit-uart-echo-rp2040/code.py +++ b/rp2040_ble_airlift/ble-bluefruit-uart-echo-rp2040/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2021 Brent Rubell for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import board from adafruit_ble import BLERadio from adafruit_ble.advertising.standard import ProvideServicesAdvertisement diff --git a/seesaw/code.py b/seesaw/code.py index 419c63ab..0dd47eb8 100644 --- a/seesaw/code.py +++ b/seesaw/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2018 Dan Halbert for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import time import board diff --git a/simple_strand_palettes/simple_strand_palettes.ino b/simple_strand_palettes/simple_strand_palettes.ino index 86f79826..fbdf5f77 100644 --- a/simple_strand_palettes/simple_strand_palettes.ino +++ b/simple_strand_palettes/simple_strand_palettes.ino @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2017 Erin St. Blaine for Adafruit Industries +// +// SPDX-License-Identifier: MIT + #include "FastLED.h" diff --git a/ufo/code.py b/ufo/code.py index 11b930e1..56469c34 100644 --- a/ufo/code.py +++ b/ufo/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2017 John Park for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """ UFO Flying Saucer with Circuit Playground Express https://learn.adafruit.com/ufo-circuit-playground-express/ diff --git a/ulab_Crunch_Numbers_Fast/benchmark/code.py b/ulab_Crunch_Numbers_Fast/benchmark/code.py index 4aa6ef7b..8335be64 100644 --- a/ulab_Crunch_Numbers_Fast/benchmark/code.py +++ b/ulab_Crunch_Numbers_Fast/benchmark/code.py @@ -1,3 +1,8 @@ +# SPDX-FileCopyrightText: 2020 Jeff Epler for Adafruit Industries +# SPDX-FileCopyrightText: 2020 Zoltán Vörös for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import time import math from ulab import numpy as np diff --git a/ulab_Crunch_Numbers_Fast/cluebarometer/code.py b/ulab_Crunch_Numbers_Fast/cluebarometer/code.py index d45362e4..5d002b6b 100644 --- a/ulab_Crunch_Numbers_Fast/cluebarometer/code.py +++ b/ulab_Crunch_Numbers_Fast/cluebarometer/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Jeff Epler for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import time import adafruit_bmp280 diff --git a/ulab_Crunch_Numbers_Fast/cluepulse/code.py b/ulab_Crunch_Numbers_Fast/cluepulse/code.py index 8b2fae3d..cb880cc4 100644 --- a/ulab_Crunch_Numbers_Fast/cluepulse/code.py +++ b/ulab_Crunch_Numbers_Fast/cluepulse/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Jeff Epler for Adafruit Industries +# +# SPDX-License-Identifier: MIT + import time import adafruit_apds9960.apds9960 diff --git a/ulab_Crunch_Numbers_Fast/ledwave/code.py b/ulab_Crunch_Numbers_Fast/ledwave/code.py index f82d23f0..a751a514 100644 --- a/ulab_Crunch_Numbers_Fast/ledwave/code.py +++ b/ulab_Crunch_Numbers_Fast/ledwave/code.py @@ -1,3 +1,6 @@ +# SPDX-FileCopyrightText: 2020 Jeff Epler for Adafruit Industries +# +# SPDX-License-Identifier: MIT import random import board diff --git a/ulab_Crunch_Numbers_Fast/waterfall/code.py b/ulab_Crunch_Numbers_Fast/waterfall/code.py index 353c276a..a2dec218 100644 --- a/ulab_Crunch_Numbers_Fast/waterfall/code.py +++ b/ulab_Crunch_Numbers_Fast/waterfall/code.py @@ -1,3 +1,7 @@ +# SPDX-FileCopyrightText: 2020 Jeff Epler for Adafruit Industries +# +# SPDX-License-Identifier: MIT + """Waterfall FFT demo adapted from https://teaandtechtime.com/fft-circuitpython-library/ to work with ulab on Adafruit CLUE"""