Due to high demand expect some shipping delays at this time, orders may not ship for 3-4 business days. On MLK Day no orders will be shipped.
0

Scrolling Text - LED GlassesIS31FL3741 I2C Driver
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Re: Scrolling Text - LED GlassesIS31FL3741 I2C Driver

by dastels on Fri Nov 19, 2021 6:36 pm

Yes. I just hacked up this:
Code: Select all | TOGGLE FULL SIZE
import time
import board
from busio import I2C
import adafruit_is31fl3741
from adafruit_is31fl3741.adafruit_ledglasses import LED_Glasses
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService
from adafruit_bluefruit_connect.packet import Packet
from adafruit_bluefruit_connect.color_packet import ColorPacket


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

glasses.left_ring.fill(0x880000)
glasses.right_ring.fill(0x008800)
glasses.show()

print("Setting up BLE")

ble = BLERadio()
uart = UARTService()
advertisement = ProvideServicesAdvertisement(uart)

print("BLE set up")

while True:
    print("Advertising")
    ble.start_advertising(advertisement)
    while not ble.connected:
        pass
    print("Connected")
    ble.stop_advertising()

    while ble.connected:
        if uart.in_waiting:
            raw_bytes = uart.read(uart.in_waiting)
            try:
                packet = Packet.from_bytes(raw_bytes)
                if isinstance(packet, ColorPacket):
                    rgb_int = packet.color[0] << 16 | packet.color[1] << 8 | packet.color[2]
                    glasses.right_ring.fill(rgb_int)
                    glasses.left_ring.fill(rgb_int)
                    glasses.show()
            except ValueError:
                text = raw_bytes.decode().strip()
                print("RX:", text)

It check the bytes received for being a packet... if it isn't a valid packet it converts it to text.

Dave

dastels
 
Posts: 8367
Joined: Tue Oct 20, 2015 3:22 pm

Re: Scrolling Text - LED GlassesIS31FL3741 I2C Driver

by Powderjockey on Mon Nov 22, 2021 4:37 pm

Thanks again Dave. I entered some text int he BLE app, but nothing shows up on the glasses.

can the matrix code be used with these glasses? It seems as the code is very limited to just want the driver board can do. Am I right there?

Powderjockey
 
Posts: 170
Joined: Fri Mar 31, 2017 10:14 pm

Re: Scrolling Text - LED GlassesIS31FL3741 I2C Driver

by GCM on Mon Nov 22, 2021 7:22 pm

dpn982 wrote:Here is what I have in the lib folder:

Screenshot 2021-11-14 224723.png


There doesn't seem to be much in the way of documentation on this box posted yet. I have been piecing together stuff from examples that I found in the circuitpython libs zip. Not sure if all the things that I put in the libs folder are needed or not, but it works with them all in there.


I too can not get the board to show up on the app. I know I need to add the blue tooth services to the board. but I don't know where to
to find them. can anyone point out the location where I can done load the needed services for the board.

Is it me, or all the box instructions like--- being locked in an escape room trying to find all the clues?

GCM
 
Posts: 4
Joined: Wed Jun 02, 2021 4:09 pm

Re: Scrolling Text - LED GlassesIS31FL3741 I2C Driver

by Powderjockey on Mon Nov 22, 2021 7:57 pm

Code: Select all | TOGGLE FULL SIZE
import time
import board
from busio import I2C
import adafruit_is31fl3741
from adafruit_is31fl3741.adafruit_ledglasses import LED_Glasses
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService
from adafruit_bluefruit_connect.packet import Packet
from adafruit_bluefruit_connect.color_packet import ColorPacket


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

glasses.left_ring.fill(0x880000)
glasses.right_ring.fill(0x008800)
glasses.show()

print("Setting up BLE")

ble = BLERadio()
uart = UARTService()
advertisement = ProvideServicesAdvertisement(uart)

print("BLE set up")

while True:
    print("Advertising")
    ble.start_advertising(advertisement)
    while not ble.connected:
        pass
    print("Connected")
    ble.stop_advertising()

    while ble.connected:
        if uart.in_waiting:
            packet = Packet.from_stream(uart)
            if isinstance(packet, ColorPacket):
                rgb_int = packet.color[0] << 16 | packet.color[1] << 8 | packet.color[2]
                glasses.right_ring.fill(rgb_int)
                glasses.left_ring.fill(rgb_int)
                glasses.show()


This will get it so the BLE app will find the device. It's a starting point.

Powderjockey
 
Posts: 170
Joined: Fri Mar 31, 2017 10:14 pm

Re: Scrolling Text - LED GlassesIS31FL3741 I2C Driver

by dastels on Mon Nov 22, 2021 8:46 pm

Powderjockey wrote:Thanks again Dave. I entered some text int he BLE app, but nothing shows up on the glasses.

can the matrix code be used with these glasses? It seems as the code is very limited to just want the driver board can do. Am I right there?


You are correct, it's not a general matrix like some other products. You don't need the glasses controller board as it's an I2C interface to the display board, but the controller does have the advantage of being designed to fit on the frame of a pair of glasses.

Dave

dastels
 
Posts: 8367
Joined: Tue Oct 20, 2015 3:22 pm

Re: Scrolling Text - LED GlassesIS31FL3741 I2C Driver

by steve220 on Fri Nov 26, 2021 11:12 am

So I am also playing around with these glasses, but haven't tried the BLE yet. Is it true that we're limited to filling the rings and/or matrix or creating a bitmap to be displayed?
There's no way to address an individual LED? I've been wading through the example code, but get lost in some of the math :-)

Edit, I can get the BLE working with no problem and can use the color picker to change colors. I can also get the UART to send text and print it in the serial panel in MU.
Last edited by steve220 on Fri Nov 26, 2021 11:27 am, edited 1 time in total.

steve220
 
Posts: 36
Joined: Sat Sep 16, 2017 10:52 pm

Re: Scrolling Text - LED GlassesIS31FL3741 I2C Driver

by dastels on Fri Nov 26, 2021 11:19 am

You can set the color of individual LEDs. There are several examples/projects that do so. This is a decent example: https://learn.adafruit.com/adafruit-eyelights-led-glasses-and-driver/googly-eye-rings and this is a more involved one: https://learn.adafruit.com/adafruit-eyelights-led-glasses-and-driver/fire.

Dave

dastels
 
Posts: 8367
Joined: Tue Oct 20, 2015 3:22 pm

Re: Scrolling Text - LED GlassesIS31FL3741 I2C Driver

by steve220 on Fri Nov 26, 2021 11:56 am

Thanks! I got it working. I'm pretty new with circuitpython (coming from arduino IDE) and am struggling a bit with the lack of documentation regarding available functions/methods and the arguments needed. Any thoughts on the best way to learn that for each library?

steve220
 
Posts: 36
Joined: Sat Sep 16, 2017 10:52 pm

Re: Scrolling Text - LED GlassesIS31FL3741 I2C Driver

by dastels on Fri Nov 26, 2021 2:22 pm

Start with the read the docs. They're better than nothing. For the glasses, look at https://circuitpython.readthedocs.io/projects/is31fl3741/en/latest/api.html, which is what the glasses library is built on.

The other thing is to look at the library code, itself. That's definitive, and can help with learning the language. https://github.com/adafruit/Adafruit_CircuitPython_IS31FL3741, and starting at https://github.com/adafruit/Adafruit_CircuitPython_IS31FL3741/blob/main/adafruit_is31fl3741/adafruit_ledglasses.py

Dave

dastels
 
Posts: 8367
Joined: Tue Oct 20, 2015 3:22 pm

Re: Scrolling Text - LED GlassesIS31FL3741 I2C Driver

by petronivs on Sun Nov 28, 2021 9:54 pm

dastels wrote:Start with the read the docs. They're better than nothing. For the glasses, look at https://circuitpython.readthedocs.io/projects/is31fl3741/en/latest/api.html, which is what the glasses library is built on.

The other thing is to look at the library code, itself. That's definitive, and can help with learning the language. https://github.com/adafruit/Adafruit_CircuitPython_IS31FL3741, and starting at https://github.com/adafruit/Adafruit_CircuitPython_IS31FL3741/blob/main/adafruit_is31fl3741/adafruit_ledglasses.py

Dave


Thanks for the links to the documentation on the libraries. I didn't see them in the instructions page.

petronivs
 
Posts: 14
Joined: Tue Oct 07, 2014 10:05 pm

Re: Scrolling Text - LED GlassesIS31FL3741 I2C Driver

by tonyhansen on Tue Nov 30, 2021 12:12 am

I've been playing around with the circuit python BLE code, trying to create the equivalent of the arduino text scroller code in circuit python.

It turns out that the arduino code does packet creation totally differently, allowing for the UART stream not identifiable as a Packet to be collected into the string to be displayed.

I started looking at adafruit_bluefruit_connect/packet.py to add similar code, but this code here is ALWAYS getting triggered:

Code: Select all | TOGGLE FULL SIZE
adafruit_bluefruit_connect/packet.py

    @classmethod
    def from_stream(cls, stream):
            . . .
            start = stream.read(1)
            if not start:
                # Timeout: nothing read.
                return None


In other words, when the text string is received from the Adafruit bluetooth app, that read ALWAYS returns None instead of the string of characters.

Does anyone have a clue how to get stream.read(1) to actually return the text characters that were typed into the bluetooth app?

Failing that, does anyone have an alternate version of the adafruit_bluefruit_connect Packet library that can be used with the bluetooth app that can read and return those strings?

tonyhansen
 
Posts: 27
Joined: Fri Nov 29, 2013 12:37 am

Re: Scrolling Text - LED GlassesIS31FL3741 I2C Driver

by tonyhansen on Tue Nov 30, 2021 12:28 am

PS. If I read the characters myself using uart.read(1), I can indeed get all of the characters from the bluetooth app.

But the Packet library does not seem capable of doing that.

Looks like I'll be implementing a replacement to the Packet library to make this work.

tonyhansen
 
Posts: 27
Joined: Fri Nov 29, 2013 12:37 am

Re: Scrolling Text - LED GlassesIS31FL3741 I2C Driver

by dpn982 on Tue Nov 30, 2021 9:57 am

I am not able to get the scrolling text working yet, but here is what I came up with (I made a custom app in flutter because I wanted to pass 2 colors, still a work in progress):

I actually pass the colors and text as just plain text to the glasses and then parse them out.

Android App: https://github.com/dpn982/led_glasses_dart
Circuitpython Script: https://github.com/dpn982/led_glasses_python

Those repos should be public, let me know if you can't see them

-Dave

dpn982
 
Posts: 10
Joined: Mon Feb 10, 2014 2:29 pm

Re: Scrolling Text - LED GlassesIS31FL3741 I2C Driver

by tonyhansen on Tue Nov 30, 2021 10:34 am

I've been making progress with a fork of adafruit_bluefruit_connect/packet.py that has a new TextPacket.py that I wrote, along with modifications to Packet.py to support it.

I've successfully used the adafruit bluetooth app and sent text to my led glasses circuit python app for scrolling. :)

I'll share my code soon.

tonyhansen
 
Posts: 27
Joined: Fri Nov 29, 2013 12:37 am

Re: Scrolling Text - LED GlassesIS31FL3741 I2C Driver

by tonyhansen on Tue Nov 30, 2021 1:49 pm

Ok, I have a working BLE-controlled text scroller controlled by the Adafruit bluetooth app.

Download the source code for adafruit_bluefruit_connect/packet.py (https://circuitpython.org/libraries) and add that to your lib/adafruit_bluefruit_connect directory.

In packet.py, find this line (currently line 104):

Code: Select all | TOGGLE FULL SIZE
            # Didn't find a packet start. Loop and try again.

and change it to this:
Code: Select all | TOGGLE FULL SIZE
            # Didn't find a packet start.
            else:
                text_packet_cls = cls._type_to_class.get(b"TX", None)
                # Is TextPacket registered?
                # If so, read an entire line and pass that to TextPacket
                if text_packet_cls:
                    ln = stream.readline()
                    packet = bytes(start + ln)
                    return text_packet_cls(packet)

                # else loop and try again.


Add this new text_packet.py:
Code: Select all | TOGGLE FULL SIZE
# SPDX-FileCopyrightText: 2021 Tony Hansen
#
# SPDX-License-Identifier: MIT

"""
`adafruit_bluefruit_connect.text_packet`
====================================================

Bluefruit Connect App text data packet.

* Author(s): Tony Hansen for Adafruit Industries

"""

import struct

from .packet import Packet


class TextPacket(Packet):
    """A packet containing a text string."""

    _TYPE_HEADER = b"TX"

    def __init__(self, text):
        """Construct a TextPacket from a binary string."""
        if isinstance(text, bytes):
            self._text = text.strip()
        else:
            raise ValueError("Text must be a bytes string")

    @property
    def text(self):
        """Return the text associated with the object."""
        return self._text

# Register this class with the superclass. This allows the user to import only what is needed.
TextPacket.register_packet_type()


In your code, add another import line:

Code: Select all | TOGGLE FULL SIZE
from adafruit_bluefruit_connect.text_packet import TextPacket


In your application loop, add another test for the Packet type and do whatever you want with the text. Note that packet.text is a bytes string.
Code: Select all | TOGGLE FULL SIZE
                elif isinstance(packet, TextPacket):
                    # print(f"text returned: '{packet.text}'")
                    set_display(packet.text)


By the way, the way the sample code at https://learn.adafruit.com/circuitpython-ble-libraries-on-any-computer/ble-uart-example and used above by @PowderJockey will block until your app attaches, and freeze when the app detaches. If you want to also scroll text or do other animation, a different way of writing that loop is like this:

Code: Select all | TOGGLE FULL SIZE
# Four BLE states to worry about:
#
# ! advertising, ! ble.connected
#     start advertising
#     in_advertising <= true
#
# ! advertising, ble.connected
#     process packet
#
# advertising, ble.connected
#     stop advertising
#     in_advertising <= false
#
# advertising, ! ble.connected
#     do nothing

# initialize the state machine
in_advertising = False

# initialize the timer
prev_time = time.monotonic_ns()

while True:
    if not in_advertising:
        if not ble.connected:
            #print("Advertising")
            ble.start_advertising(advertisement)
            in_advertising = True

        else:
            if uart.in_waiting:
                packet = None
                try:
                    packet = Packet.from_stream(uart)
                except Exception as e:
                    print(f"Packet failed: {e}")

                if isinstance(packet, ColorPacket):
                    # do stuff with color packet.color
                elif isinstance(packet, AccelerometerPacket):
                    # do stuff with packet.x, packet.y and packet.z
      elif isinstance(packet, ButtonPacket):
                    # do stuff with packet.button
                elif isinstance(packet, TextPacket):
                    # do stuff with packet.text

    else: # in_advertising
        if ble.connected:
            # print("Connected")
            ble.stop_advertising()
            in_advertising = False

        # else loop until we ARE connected

    # every 0.15 seconds, advance the ticker
    cur_time = time.monotonic_ns()
    if cur_time - prev_time > 150_000_000:
        scroll_text()
        prev_time = cur_time

tonyhansen
 
Posts: 27
Joined: Fri Nov 29, 2013 12:37 am

Please be positive and constructive with your questions and comments.