Mar-08-2023, 12:08 PM
Hello guys!
I built Armachat from the link below
https://github.com/bobricius/Armachat-circuitpython
https://hackaday.io/project/183657-armac...-messenger
It works on raspberry pico, ST7789V display, LoRa module and 30 buttons.
After assebly and run programm i get this message
Second, if I understand correctly, problem in label.py file, but it's a standard library...
code.py
I think I'm making some stupid mistake, but I can't find where.
I built Armachat from the link below
https://github.com/bobricius/Armachat-circuitpython
https://hackaday.io/project/183657-armac...-messenger
It works on raspberry pico, ST7789V display, LoRa module and 30 buttons.
After assebly and run programm i get this message
Error:Traceback (most recent call last)
File "code.py", line 43, in <module>
File "<string>", line 15, in <module>
File "lib/adafruit_display_text/label.py", line 30 in <module>
First of all what is "File "<string>""? Where i can find it?Second, if I understand correctly, problem in label.py file, but it's a standard library...
code.py
import time import board import busio import terminalio import displayio import os import microcontroller from config import * from picomputer import * import digitalio hidden_ID = ['.', '_', 'TRASH', 'boot_out.txt', 'main.py', 'code.py', 'menu.py', 'main.txt', 'code.txt', 'boot.py'] # List of file name elements and names we do not want to see #pnt20"1234567890123456789") print("/~~~~Doomsday~~~~~\\") print("| Operating System|") print("\__Select program_/") def file_filter(data): for y in hidden_ID: filtered_data = [x for x in data if not x.startswith(y)] data = filtered_data filtered_data = [x for x in data if x[-3:] == '.py' or x[-4:] == '.txt' ] return sorted(filtered_data) menu_options = file_filter(os.listdir()) max_length = len(menu_options) for i in range(0, max_length, 1): print( "[{}] {}".format(i, menu_options[i])) #pnt20"1234567890123456789") print("[Press number 0-9]",end="") while True: keys=getKey(1) if keys: try: selected =int(keys[0]) except Exception: selected = 0 if selected<max_length: exec(open(menu_options[selected]).read()) print("Program finished ... rebooting ....") microcontroller.reset()label.py
# SPDX-FileCopyrightText: 2019 Scott Shawcroft for Adafruit Industries # # SPDX-License-Identifier: MIT """ `adafruit_display_text.label` ==================================================== Displays text labels using CircuitPython's displayio. * Author(s): Scott Shawcroft Implementation Notes -------------------- **Hardware:** **Software and Dependencies:** * Adafruit CircuitPython firmware for the supported boards: https://circuitpython.org/downloads """ __version__ = "0.0.0+auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_Display_Text.git" from displayio import Bitmap, Palette, TileGrid from adafruit_display_text import LabelBase try: from typing import Optional, Tuple from fontio import FontProtocol except ImportError: pass class Label(LabelBase): # pylint: disable=too-many-instance-attributes """A label displaying a string of text. The origin point set by ``x`` and ``y`` properties will be the left edge of the bounding box, and in the center of a M glyph (if its one line), or the (number of lines * linespacing + M)/2. That is, it will try to have it be center-left as close as possible. :param font: A font class that has ``get_bounding_box`` and ``get_glyph``. Must include a capital M for measuring character size. :type font: ~FontProtocol :param str text: Text to display :param int|Tuple(int, int, int) color: Color of all text in HEX or RGB :param int|Tuple(int, int, int)|None background_color: Color of the background, use `None` for transparent :param float line_spacing: Line spacing of text to display :param bool background_tight: Set `True` only if you want background box to tightly surround text. When set to 'True' Padding parameters will be ignored. :param int padding_top: Additional pixels added to background bounding box at top. This parameter could be negative indicating additional pixels subtracted from the background bounding box. :param int padding_bottom: Additional pixels added to background bounding box at bottom. This parameter could be negative indicating additional pixels subtracted from the background bounding box. :param int padding_left: Additional pixels added to background bounding box at left. This parameter could be negative indicating additional pixels subtracted from the background bounding box. :param int padding_right: Additional pixels added to background bounding box at right. This parameter could be negative indicating additional pixels subtracted from the background bounding box. :param Tuple(float, float) anchor_point: Point that anchored_position moves relative to. Tuple with decimal percentage of width and height. (E.g. (0,0) is top left, (1.0, 0.5): is middle right.) :param Tuple(int, int) anchored_position: Position relative to the anchor_point. Tuple containing x,y pixel coordinates. :param int scale: Integer value of the pixel scaling :param bool base_alignment: when True allows to align text label to the baseline. This is helpful when two or more labels need to be aligned to the same baseline :param Tuple(int, str) tab_replacement: tuple with tab character replace information. When (4, " ") will indicate a tab replacement of 4 spaces, defaults to 4 spaces by tab character :param str label_direction: string defining the label text orientation. There are 5 configurations possibles ``LTR``-Left-To-Right ``RTL``-Right-To-Left ``TTB``-Top-To-Bottom ``UPR``-Upwards ``DWR``-Downwards. It defaults to ``LTR``""" def __init__(self, font: FontProtocol, **kwargs) -> None: self._background_palette = Palette(1) self._added_background_tilegrid = False super().__init__(font, **kwargs) text = self._replace_tabs(self._text) self._width = len(text) self._height = self._font.get_bounding_box()[1] # Create the two-color text palette self._palette[0] = 0 self._palette.make_transparent(0) if text is not None: self._reset_text(str(text)) def _create_background_box(self, lines: int, y_offset: int) -> TileGrid: """Private Class function to create a background_box :param lines: int number of lines :param y_offset: int y pixel bottom coordinate for the background_box""" left = self._bounding_box[0] if self._background_tight: # draw a tight bounding box box_width = self._bounding_box[2] box_height = self._bounding_box[3] x_box_offset = 0 y_box_offset = self._bounding_box[1] else: # draw a "loose" bounding box to include any ascenders/descenders. ascent, descent = self._ascent, self._descent if self._label_direction in ("UPR", "DWR", "TTB"): box_height = ( self._bounding_box[3] + self._padding_top + self._padding_bottom ) x_box_offset = -self._padding_bottom box_width = ( (ascent + descent) + int((lines - 1) * self._width * self._line_spacing) + self._padding_left + self._padding_right ) else: box_width = ( self._bounding_box[2] + self._padding_left + self._padding_right ) x_box_offset = -self._padding_left box_height = ( (ascent + descent) + int((lines - 1) * self._height * self._line_spacing) + self._padding_top + self._padding_bottom ) if self._base_alignment: y_box_offset = -ascent - self._padding_top else: y_box_offset = -ascent + y_offset - self._padding_top box_width = max(0, box_width) # remove any negative values box_height = max(0, box_height) # remove any negative values if self._label_direction == "UPR": movx = left + x_box_offset movy = -box_height - x_box_offset elif self._label_direction == "DWR": movx = left + x_box_offset movy = x_box_offset elif self._label_direction == "TTB": movx = left + x_box_offset movy = x_box_offset else: movx = left + x_box_offset movy = y_box_offset background_bitmap = Bitmap(box_width, box_height, 1) tile_grid = TileGrid( background_bitmap, pixel_shader=self._background_palette, x=movx, y=movy, ) return tile_grid def _set_background_color(self, new_color: Optional[int]) -> None: """Private class function that allows updating the font box background color :param int new_color: Color as an RGB hex number, setting to None makes it transparent """ if new_color is None: self._background_palette.make_transparent(0) if self._added_background_tilegrid: self._local_group.pop(0) self._added_background_tilegrid = False else: self._background_palette.make_opaque(0) self._background_palette[0] = new_color self._background_color = new_color lines = self._text.rstrip("\n").count("\n") + 1 y_offset = self._ascent // 2 if self._bounding_box is None: # Still in initialization return if not self._added_background_tilegrid: # no bitmap is in the self Group # add bitmap if text is present and bitmap sizes > 0 pixels if ( (len(self._text) > 0) and ( self._bounding_box[2] + self._padding_left + self._padding_right > 0 ) and ( self._bounding_box[3] + self._padding_top + self._padding_bottom > 0 ) ): self._local_group.insert( 0, self._create_background_box(lines, y_offset) ) self._added_background_tilegrid = True else: # a bitmap is present in the self Group # update bitmap if text is present and bitmap sizes > 0 pixels if ( (len(self._text) > 0) and ( self._bounding_box[2] + self._padding_left + self._padding_right > 0 ) and ( self._bounding_box[3] + self._padding_top + self._padding_bottom > 0 ) ): self._local_group[0] = self._create_background_box( lines, self._y_offset ) else: # delete the existing bitmap self._local_group.pop(0) self._added_background_tilegrid = False def _update_text(self, new_text: str) -> None: # pylint: disable=too-many-branches,too-many-statements x = 0 y = 0 if self._added_background_tilegrid: i = 1 else: i = 0 tilegrid_count = i if self._base_alignment: self._y_offset = 0 else: self._y_offset = self._ascent // 2 if self._label_direction == "RTL": left = top = bottom = 0 right = None elif self._label_direction == "LTR": right = top = bottom = 0 left = None else: top = right = left = 0 bottom = 0 for character in new_text: if character == "\n": y += int(self._height * self._line_spacing) x = 0 continue glyph = self._font.get_glyph(ord(character)) if not glyph: continue position_x, position_y = 0, 0 if self._label_direction in ("LTR", "RTL"): bottom = max(bottom, y - glyph.dy + self._y_offset) if y == 0: # first line, find the Ascender height top = min(top, -glyph.height - glyph.dy + self._y_offset) position_y = y - glyph.height - glyph.dy + self._y_offset if self._label_direction == "LTR": right = max(right, x + glyph.shift_x, x + glyph.width + glyph.dx) if x == 0: if left is None: left = 0 else: left = min(left, glyph.dx) position_x = x + glyph.dx else: left = max( left, abs(x) + glyph.shift_x, abs(x) + glyph.width + glyph.dx ) if x == 0: if right is None: right = 0 else: right = max(right, glyph.dx) position_x = x - glyph.width elif self._label_direction == "TTB": if x == 0: if left is None: left = 0 else: left = min(left, glyph.dx) if y == 0: top = min(top, -glyph.dy) bottom = max(bottom, y + glyph.height, y + glyph.height + glyph.dy) right = max( right, x + glyph.width + glyph.dx, x + glyph.shift_x + glyph.dx ) position_y = y + glyph.dy position_x = x - glyph.width // 2 + self._y_offset elif self._label_direction == "UPR": if x == 0: if bottom is None: bottom = -glyph.dx if y == 0: # first line, find the Ascender height bottom = min(bottom, -glyph.dy) left = min(left, x - glyph.height + self._y_offset) top = min(top, y - glyph.width - glyph.dx, y - glyph.shift_x) right = max(right, x + glyph.height, x + glyph.height - glyph.dy) position_y = y - glyph.width - glyph.dx position_x = x - glyph.height - glyph.dy + self._y_offset elif self._label_direction == "DWR": if y == 0: if top is None: top = -glyph.dx top = min(top, -glyph.dx) if x == 0: left = min(left, -glyph.dy) left = min(left, x, x - glyph.dy - self._y_offset) bottom = max(bottom, y + glyph.width + glyph.dx, y + glyph.shift_x) right = max(right, x + glyph.height) position_y = y + glyph.dx position_x = x + glyph.dy - self._y_offset if glyph.width > 0 and glyph.height > 0: face = TileGrid( glyph.bitmap, pixel_shader=self._palette, default_tile=glyph.tile_index, tile_width=glyph.width, tile_height=glyph.height, x=position_x, y=position_y, ) if self._label_direction == "UPR": face.transpose_xy = True face.flip_x = True if self._label_direction == "DWR": face.transpose_xy = True face.flip_y = True if tilegrid_count < len(self._local_group): self._local_group[tilegrid_count] = face else: self._local_group.append(face) tilegrid_count += 1 if self._label_direction == "RTL": x = x - glyph.shift_x if self._label_direction == "TTB": if glyph.height < 2: y = y + glyph.shift_x else: y = y + glyph.height + 1 if self._label_direction == "UPR": y = y - glyph.shift_x if self._label_direction == "DWR": y = y + glyph.shift_x if self._label_direction == "LTR": x = x + glyph.shift_x i += 1 if self._label_direction == "LTR" and left is None: left = 0 if self._label_direction == "RTL" and right is None: right = 0 if self._label_direction == "TTB" and top is None: top = 0 while len(self._local_group) > tilegrid_count: # i: self._local_group.pop() if self._label_direction == "RTL": # pylint: disable=invalid-unary-operand-type # type-checkers think left can be None self._bounding_box = (-left, top, left - right, bottom - top) if self._label_direction == "TTB": self._bounding_box = (left, top, right - left, bottom - top) if self._label_direction == "UPR": self._bounding_box = (left, top, right, bottom - top) if self._label_direction == "DWR": self._bounding_box = (left, top, right, bottom - top) if self._label_direction == "LTR": self._bounding_box = (left, top, right - left, bottom - top) self._text = new_text if self._background_color is not None: self._set_background_color(self._background_color) def _reset_text(self, new_text: str) -> None: current_anchored_position = self.anchored_position self._update_text(str(self._replace_tabs(new_text))) self.anchored_position = current_anchored_position def _set_font(self, new_font: FontProtocol) -> None: old_text = self._text current_anchored_position = self.anchored_position self._text = "" self._font = new_font self._height = self._font.get_bounding_box()[1] self._update_text(str(old_text)) self.anchored_position = current_anchored_position def _set_line_spacing(self, new_line_spacing: float) -> None: self._line_spacing = new_line_spacing self.text = self._text # redraw the box def _set_text(self, new_text: str, scale: int) -> None: self._reset_text(new_text) def _set_label_direction(self, new_label_direction: str) -> None: self._label_direction = new_label_direction self._update_text(str(self._text)) def _get_valid_label_directions(self) -> Tuple[str, ...]: return "LTR", "RTL", "UPR", "DWR", "TTB"According to the instructions, I just have to load the files onto the board and everything will work.
I think I'm making some stupid mistake, but I can't find where.