Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add magtag support #39

Merged
merged 6 commits into from
Nov 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Introduction
:target: https://github.com/adafruit/Adafruit_CircuitPython_PyBadger/actions/
:alt: Build Status

Badge-focused CircuitPython helper library for PyBadge, PyBadge LC, PyGamer and CLUE.
Badge-focused CircuitPython helper library for PyBadge, PyBadge LC, PyGamer, CLUE, and Mag Tag.


Dependencies
Expand Down
2 changes: 2 additions & 0 deletions adafruit_pybadger/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@
from .pyportal import pyportal as pybadger
elif "Circuit Playground Bluefruit" in os.uname().machine:
from .cpb_gizmo import cpb_gizmo as pybadger
elif "MagTag with ESP32S2" in os.uname().machine:
from .mag_tag import mag_tag as pybadger
116 changes: 116 additions & 0 deletions adafruit_pybadger/mag_tag.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# The MIT License (MIT)
#
# Copyright (c) 2020 Tim C for Adafruit Industries
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
"""
`adafruit_pybadger.mag_tag`
================================================================================

Badge-focused CircuitPython helper library for Mag Tag.


* Author(s): Kattni Rembor, Tim C

Implementation Notes
--------------------

**Hardware:**

* `Adafruit Mag Tag <https://www.adafruit.com/product/4800>`_

**Software and Dependencies:**

* Adafruit CircuitPython firmware for the supported boards:
https://github.com/adafruit/circuitpython/releases

"""

from collections import namedtuple
import board

# import digitalio
# from gamepad import GamePad
import neopixel
from adafruit_pybadger.pybadger_base import PyBadgerBase

__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PyBadger.git"

Buttons = namedtuple("Buttons", "a b c d")


class MagTag(PyBadgerBase):
"""Class that represents a single Mag Tag."""

_neopixel_count = 4

def __init__(self):
super().__init__()

# NeoPixels
self._neopixels = neopixel.NeoPixel(
board.NEOPIXEL, self._neopixel_count, brightness=1, pixel_order=neopixel.GRB
)

# self._buttons = GamePad(
# ,
# digitalio.DigitalInOut(board.BUTTON_B),
# digitalio.DigitalInOut(board.BUTTON_C),
# digitalio.DigitalInOut(board.BUTTON_D),
# )

@property
def button(self):
"""The buttons on the board.

Example use:

.. code-block:: python

from adafruit_pybadger import pybadger

while True:
if pybadger.button.a:
print("Button A")
elif pybadger.button.b:
print("Button B")
"""
# button_values = self._buttons.get_pressed()
# return Buttons(
# button_values & PyBadgerBase.BUTTON_B, button_values & PyBadgerBase.BUTTON_A,
# button_values & PyBadgerBase.BUTTON_START, button_values & PyBadgerBase.BUTTON_SELECT
# )

@property
def _unsupported(self):
"""This feature is not supported on Mag Tag."""
raise NotImplementedError("This feature is not supported on Mag Tag.")

# The following is a list of the features available in other PyBadger modules but
# not available for Mag Tag. If called while using a Mag Tag, they will result in the
# NotImplementedError raised in the property above.
play_file = _unsupported
light = _unsupported
acceleration = _unsupported
button = _unsupported


mag_tag = MagTag() # pylint: disable=invalid-name
"""Object that is automatically created on import."""
34 changes: 24 additions & 10 deletions adafruit_pybadger/pybadger_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,26 @@
import board
from micropython import const
import digitalio

try:
import audiocore
except ImportError:
import audioio as audiocore
from adafruit_bitmap_font import bitmap_font
import displayio
from adafruit_display_shapes.rect import Rect
from adafruit_display_text import label
import terminalio
import adafruit_miniqr

AUDIO_ENABLED = False
try:
import audiocore

AUDIO_ENABLED = True
except ImportError:
try:
import audioio as audiocore

AUDIO_ENABLED = True
except ImportError:
# Allow to work with no audio
pass
__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PyBadger.git"

Expand Down Expand Up @@ -685,11 +693,17 @@ def _sine_sample(length):
yield int(tone_volume * math.sin(2 * math.pi * (i / length)) + shift)

def _generate_sample(self, length=100):
if self._sample is not None:
return
self._sine_wave = array.array("H", PyBadgerBase._sine_sample(length))
self._sample = self._audio_out(board.SPEAKER) # pylint: disable=not-callable
self._sine_wave_sample = audiocore.RawSample(self._sine_wave)
if AUDIO_ENABLED:
if self._sample is not None:
return
self._sine_wave = array.array("H", PyBadgerBase._sine_sample(length))
# pylint: disable=not-callable
self._sample = self._audio_out(
board.SPEAKER
) # pylint: disable=not-callable
self._sine_wave_sample = audiocore.RawSample(self._sine_wave)
else:
print("Required audio modules were missing")

def _enable_speaker(self, enable):
if not hasattr(board, "SPEAKER_ENABLE"):
Expand Down
Binary file added examples/Blinka_MagTag.bmp
Binary file not shown.
3 changes: 3 additions & 0 deletions examples/Blinka_MagTag.bmp.license
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# SPDX-FileCopyrightText: BLINKA is a registered trademark of Adafruit, LLC. The design is exclusive property of Adafruit, LLC
#
# SPDX-License-Identifier: MIT
101 changes: 101 additions & 0 deletions examples/pybadger_magtag_simpletest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
"""Simpletest example using the Mag Tag.
Use the A, B, and C buttons to change between examples."""
import time
import board
import digitalio
from adafruit_pybadger import pybadger


def try_refresh():
""" Attempt to refresh the display. Catch 'refresh too soon' error
and retry after waiting 10 seconds.
"""
try:
board.DISPLAY.refresh()
except RuntimeError as too_soon_error:
# catch refresh too soon
print(too_soon_error)
print("waiting before retry refresh()")
time.sleep(10)
board.DISPLAY.refresh()


print("wait before anything")
time.sleep(5)

btn_a = digitalio.DigitalInOut(board.BUTTON_A)
btn_a.direction = digitalio.Direction.INPUT
btn_a.pull = digitalio.Pull.UP

btn_b = digitalio.DigitalInOut(board.BUTTON_B)
btn_b.direction = digitalio.Direction.INPUT
btn_b.pull = digitalio.Pull.UP

btn_c = digitalio.DigitalInOut(board.BUTTON_C)
btn_c.direction = digitalio.Direction.INPUT
btn_c.pull = digitalio.Pull.UP

prev_a = btn_a.value
prev_b = btn_b.value
prev_c = btn_c.value

SHOWING = "badge"

pybadger.show_badge(
name_string="Blinka", hello_scale=2, my_name_is_scale=2, name_scale=3
)

try_refresh()

print("after show, going to loop")

neopixel_pwr = digitalio.DigitalInOut(board.NEOPIXEL_POWER)
neopixel_pwr.direction = digitalio.Direction.OUTPUT
neopixel_pwr.value = False
pybadger.pixels.fill(0x000022)

while True:

cur_a = btn_a.value
cur_b = btn_b.value
cur_c = btn_c.value

if prev_a and not cur_a:
pybadger.pixels.fill(0x000000)
neopixel_pwr.value = True
if SHOWING != "badge":
print("changing to badge")
SHOWING = "badge"
pybadger.show_badge(
name_string="Mag Tag", hello_scale=2, my_name_is_scale=2, name_scale=3
)
try_refresh()

if prev_b and not cur_b:
pybadger.pixels.fill(0x000000)
neopixel_pwr.value = True
if SHOWING != "qr":
print("changing to qr")
SHOWING = "qr"
pybadger.show_qr_code(data="https://www.adafruit.com/product/4800")
try_refresh()

if prev_c and not cur_c:
pybadger.pixels.fill(0x000000)
neopixel_pwr.value = True
if SHOWING != "card":
print("changing to card")
SHOWING = "card"
pybadger.show_business_card(
image_name="Blinka_MagTag.bmp",
name_string="Blinka",
name_scale=2,
email_string_one="blinka@",
email_string_two="adafruit.com",
)
# show_business_card() calls refresh() internally

prev_a = cur_a
prev_b = cur_b
prev_c = cur_c
time.sleep(1)