Apresentando texto com LEGO Powered Up

Para os mais especializados em mecânica e electrónica em LEGO.
Avatar do Utilizador
CyberX
Sócio
Sócio
Mensagens: 4513
Registado: 10 mar 2014, 20:09
Localização: Mira Sintra
Contacto:

Apresentando texto com LEGO Powered Up

Mensagem por CyberX »

Quando o SPIKE e o Robot Inventor foram apresentados, alguns dos que esperavam que a evolução do MINDSTORMS EV3 corrigisse pequenos inc+ómodos como o display do EV3 não ter uma luz de fundo ficaram chocados - nem display havia.

Não é algo que costume usar - nalguns programas mais puxados até desligo completamente o display para libertar recursos - mas admito que nalgumas situações pode dar jeito apresentar algum tipo de output. Talvez por isso a LEGO tenha colocado a matriz de LEDs 5x5, com algum jeitinho conseguem-se escrever coisas como no inevitável 'Hello World' que fiz há já uns 4 anos:



Entretanto consegui acumular 4 elementos ColorLightMatrix 3x3. Individualmente nunca lhes dei muita atenção, 9 leds RGB... caros como o raio... para que raio pode servir isto?

Ah bem com 4 conseguimos 6x6. Um hub Technic tem 4 fichas por isso consegue controlar isto. E se conseguimos mostrar caracteres em grelhas 5x5 tb conseguimos em 6x6. E lá dei por mim como no tempo do ZX Spectrum a fazer sprites em grelhas quadriculadas, só que 6x6 em vez de 8x8 e em python em vez de BASIC.




o programa em si não é muito complicado mas foi um bocado monótono ter de implementar os caracteres todos um a um (por agora os digitos, as maiúsculas e 3 símbolos). Criei um ficheiro só com a definição dos caracteres, deste género:

Código: Selecionar todos

chr_null = [
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0]
]

chr_0 = [
    [0,0,1,1,0,0],
    [0,1,0,0,1,0],
    [0,1,0,0,1,0],
    [0,1,0,0,1,0],
    [0,1,0,0,1,0],
    [0,0,1,1,0,0]
]
e importo este ficheiro a partir do programa principal como se fosse uma library (bem, tecnicamente é uma library)

depois criei algumas funções que "partem" a grelha 6x6 em 4 grelhas 3x3, convertem os 0 e 1 para a cor nula (OFF) e branca e enviam para os 4 dispositivos ColorLightMatrix; e uma função que recebe um caracter e se fizer parte dos implementados mostra (convertendo minúsculas em maiúsculas) e se não fizer parte mostra um caracter nulo (que depois numa animação funciona como um espaço).

depois o que deu algum trabalho foi o "scroll" lateral: criei uma função que pega numa string e constrói uma grelha de 6 linhas e (6x comprimentos da string) colunas (na verdade 7x para acomodar um espaço vazio que me dá jeito no final do scroll) e outra função que percorre estra grelha num sentido ou noutro e extrai um bloco 6x6 para apresentar

Ainda tenho de arrumar o código antes de o publicar no github.

A ideia é dedicar um hub para exibição de texto, usando o broadcast entre hubs. Tendo uma pipa de massa podemos juntar vários e fazer um display LCD maior (2 hubs: 6x12, 4 hubs: 6x18... se alguém quiser patrocinar é só dizer :D )

Quando tiver um bocadinho de tempo vou tentar integrar com o Jogo do Galo.
Jorge Pereira
«De génio, criança e louco... porquê só 1 pouco?»
Avatar do Utilizador
Conchas
Direcção
Direcção
Mensagens: 16115
Registado: 26 jan 2007, 15:20
Localização: Feijó (Almada) / Sesimbra
Contacto:

Re: Apresentando texto com LEGO Powered Up

Mensagem por Conchas »

Curioso que estamos a trabalhar na mesma coisa!

Tenho feito varias funções para apresentar animações numa unica matriz 3x3, com scroll lateral (esquerda, direita) e vertical (cima, baixo).
E ontem mesmo passei pela Arabot em Santarém para levantar mais 5 Matrizes 3x3, para com um SP (6 portas) trabalhar em configurações: 1x1 ou 1x6 ou 1x1 a 6x1, e 2x2, 2x3 ou 3x2.
Já tenho escritas várias das funções necessárias em Python. São muito engraçados estes desafios e tentar escrever o código das formas mais compactas possiveis. :D

O meu interesse tem sido mais as animações pictoricas e menos o display de strings em scroll, mas posso expandir por aí também.
FCorreia

#EUusoOmeuLUGBULKnosEVENTOSdaPLUG

We are working to build a better :plug:
LEGO Fan, a lifelong experience - Play Well (Leg Godt)

Oeiras :brincka: 2026, 24-26 de Abril
Avatar do Utilizador
CyberX
Sócio
Sócio
Mensagens: 4513
Registado: 10 mar 2014, 20:09
Localização: Mira Sintra
Contacto:

Re: Apresentando texto com LEGO Powered Up

Mensagem por CyberX »

"animações pictóricas"... suponho que tenhas definido sprites ou algo semelhante. Texto é apenas uma forma de sprite portanto vai dar ao mesmo, excepto que strings de texto têm de ser separadas em caracteres individuais mas no teu caso não deve ser muito diferente de teres um sprite maior que a dimensão física (excepto que eu vou sempre assumir que as strings têm sempre uma linha de texto - neste caso 6 pixeis de altura - e preocupar-me apenas com a horizontal apenas quando um sprite genérico pode expandir-se tb na vertical)

"São muito engraçados estes desafios e tentar escrever o código das formas mais compactas possiveis"

Não tenho tido qualquer preocupação com isso - o hub Technic tem resmas de capacidade, as minhas duas únicas preocupações têm sido zelar pela minha sanidade mental:
- repartir o código por vários ficheiros, nunca fui adepto de páginas e páginas de código
- estruturar o código (incluindo um mínimo de comentários) para quando voltar a olhar para isto daqui a 6 meses não ter aquela expressão de boi a olhar para um palácio

Mas ontem tive um bloqueiozito interessante, mais de 2 horas: criei uma variável do tipo array (uma lista de listas) e quando lhe inseria o conteúdo de outro apareciam coisas estranhas nos LEDs, fui fazendo debug até perceber que o problema estava na forma como inicializava o array e na forma como o python lida com representações internas de objectos. E tudo por causa de ter inicializado o array com um código compacto que encontrei na net.
Jorge Pereira
«De génio, criança e louco... porquê só 1 pouco?»
Avatar do Utilizador
Conchas
Direcção
Direcção
Mensagens: 16115
Registado: 26 jan 2007, 15:20
Localização: Feijó (Almada) / Sesimbra
Contacto:

Re: Apresentando texto com LEGO Powered Up

Mensagem por Conchas »

Sim sprites!
Nunca tinha usado esse termo.

A minha preocupação com o código não é pela eficiência mas pelo desafio. E gosto de código criptico. Expressões complexas de uma linha, adoro!...

Por acaso o scroll vertical é mais simples de implementar, se bem que com matrizes LED lado a lado a coisa começa logo a complicar... ;D
FCorreia

#EUusoOmeuLUGBULKnosEVENTOSdaPLUG

We are working to build a better :plug:
LEGO Fan, a lifelong experience - Play Well (Leg Godt)

Oeiras :brincka: 2026, 24-26 de Abril
Avatar do Utilizador
Conchas
Direcção
Direcção
Mensagens: 16115
Registado: 26 jan 2007, 15:20
Localização: Feijó (Almada) / Sesimbra
Contacto:

Re: Apresentando texto com LEGO Powered Up

Mensagem por Conchas »

CyberX Escreveu: 06 abr 2025, 01:25 A ideia é dedicar um hub para exibição de texto, usando o broadcast entre hubs. Tendo uma pipa de massa podemos juntar vários e fazer um display LCD maior (2 hubs: 6x12, 4 hubs: 6x18... se alguém quiser patrocinar é só dizer :D )
E achas que isso vai funcionar, depois das queixas que tens levantado quanto à mensagens de broadcast perdidas entre hubs?
FCorreia

#EUusoOmeuLUGBULKnosEVENTOSdaPLUG

We are working to build a better :plug:
LEGO Fan, a lifelong experience - Play Well (Leg Godt)

Oeiras :brincka: 2026, 24-26 de Abril
Avatar do Utilizador
CyberX
Sócio
Sócio
Mensagens: 4513
Registado: 10 mar 2014, 20:09
Localização: Mira Sintra
Contacto:

Re: Apresentando texto com LEGO Powered Up

Mensagem por CyberX »

Sim.

Se não estiver preocupado com latência, basta-me fazer o broadcast durante tempo suficiente. Diria que 300 ms é mais do que suficiente (3 transmissões).

As minhas reclamações têm um contexto concreto: música. Não posso querer tocar um xylofone de 12 notas com 12 motores repartidos por 3 hubs Technic a um ritmo moderadamente elevado se um dos hubs não receber o comando certo. Mas posso mandar uma mensagem "Hello world" a cada 10 segundos na boa, com latências inferiores a 1 segundo, ninguém repara - melhor até que enviar a mesma mensagem a um EV3 para ser convertida para voz, a latẽncia do processo é a mesma mas acresce a latência do python a invocar um comando externo (o espeak) que mesmo usando chamadas de sistema operativo em vezd e usar a library nativa do ev3dev2 atrasam 1 a 2 segundos.

Entretanto publiquei uma versão minimamente arrumada do que já fiz:

https://github.com/JorgePe/matrix_6x6

com suporte para 2 cores (ink e paper) mas sem video - fica uma porcaria no meu telemóvel baratucho.
Jorge Pereira
«De génio, criança e louco... porquê só 1 pouco?»
Avatar do Utilizador
CyberX
Sócio
Sócio
Mensagens: 4513
Registado: 10 mar 2014, 20:09
Localização: Mira Sintra
Contacto:

Re: Apresentando texto com LEGO Powered Up

Mensagem por CyberX »

Versão ainda mais arrumada, tudo dentro de um módulo just plug and play:

para se poder utilizar é só importar tudo o que vem no módulo e definir um objecto da classe Matrix:

Código: Selecionar todos

from matrix_6x6 import *
matrix = Matrix(Port.A, Port.B, Port.C, Port.D)
neste caso estamos a usar as 4 portas do Technic hub dispostas desta maneira:

D | C
- - -
B | A

(mas também podiam ser as primeiras 4 portas de um Robot Inventor ou Spike, supostamente funcionará
do mesmo modo mas não tenho nada por aqui para comprovar)

depois é invocar o método show() para exibir texto (seja um caracter parado ou vários em movimento)
ou o método clear() para apagar tudo:

Código: Selecionar todos

# show a static '1' in White over Black
matrix.show('1', 'N', 0, (Color.WHITE, Color.BLACK) )

# turns all pixels OFF
matrix.clear()

# show a '1' scrolling to Left in Yellow over Black
matrix.show('1', 'L', 250, (Color.YELLOW, Color.BLACK) )
Jorge Pereira
«De génio, criança e louco... porquê só 1 pouco?»
Avatar do Utilizador
AVCampos
Sócio
Sócio
Mensagens: 13795
Registado: 27 fev 2007, 19:26
Localização: Barreiro
Contacto:

Re: Apresentando texto com LEGO Powered Up

Mensagem por AVCampos »

Só para chatear e arriscar-me a levar com um train weight na tola... e que tal flexibilizar a biblioteca para também poder usar 2 matrizes (para o hub de Cidade ou libertar 2 portas do hub Technic para outras coisas) ou 6 (para mais resolução usando o SP)? ;D A resolução vertical seria a mesma, só variaria o número de pixels a scrollar.
Avatar do Utilizador
CyberX
Sócio
Sócio
Mensagens: 4513
Registado: 10 mar 2014, 20:09
Localização: Mira Sintra
Contacto:

Re: Apresentando texto com LEGO Powered Up

Mensagem por CyberX »

AVCampos Escreveu: 08 abr 2025, 18:50 Só para chatear e arriscar-me a levar com um train weight na tola... e que tal flexibilizar a biblioteca para também poder usar 2 matrizes (para o hub de Cidade ou libertar 2 portas do hub Technic para outras coisas) ou 6 (para mais resolução usando o SP)? ;D A resolução vertical seria a mesma, só variaria o número de pixels a scrollar.
hmm... é uma pena não ser fazerem bigornas de aço com studs :D

com 2 ColorLightMatrix tens apenas 6x3 pixeis... é possível fazer scroll lateral mas não é possível mostrar caracteres estáticos (a menos que altera a fonte, mas a maior parte dos caracteres vão ficar estranhos, tenta lá fazer um M, N, H, W só com 3 pixeis de largura

mas posso fazer a modificação, não deve custar muito, é essencialmente alterar a função que tenho que parte o sprite 6x6 em 4 sub-sprites 3x3:

Código: Selecionar todos

    def split(self, sprite):
        """
        splits a 6x6 sprite in 4 patterns of 3x3 pixels
        using this arrangement
        D | C
        - - -
        B | A
        each pattern is a list of 12 pixels (0/1, not colors)
        """
        patternD = sprite[0][0:3] + sprite[1][0:3] + sprite[2][0:3]
        patternC = sprite[0][3:6] + sprite[1][3:6] + sprite[2][3:6]
        patternB = sprite[3][0:3] + sprite[4][0:3] + sprite[5][0:3]
        patternA = sprite[3][3:6] + sprite[4][3:6] + sprite[5][3:6]

        return( (patternA, patternB, patternC, patternD) )
e depois alterar a largura da sliding window para 3 pixeis em vez de 6.

Vou experimentar, não se perde nada, depois conto.

Idem para aumentar para 6x9 mas não tenho como experimentar, neste momento nem tenho nenhum hub de 6 portas nem tenho 6 ColorLightMatrix.

Agora experimentar isto num City Hub... é possível que funcione mas é arriscado, tem menos capacidade de processamento e menos memória que o Technic Hub. Se funcionar, então também poderia funcionar num BOOST (Move Hub) que também tem 2 portas livres. E desses tenho aí uns quantos guardados para se um dia me der para aumentar a cobra pitónica.

2 B continued :)
Jorge Pereira
«De génio, criança e louco... porquê só 1 pouco?»
Avatar do Utilizador
CyberX
Sócio
Sócio
Mensagens: 4513
Registado: 10 mar 2014, 20:09
Localização: Mira Sintra
Contacto:

Re: Apresentando texto com LEGO Powered Up

Mensagem por CyberX »

Caracteres estáticos esquece
Caracteres em scroll... com alguma caridade aceita-se:



No BOOST, a compilar/upload:

"This program is too big. Compiled size is 4,618 bytes but the hub can only fit 3,940 bytes.
Try removing unused code or making names and strings smaller."

depois de reduzir os nomes às variáveis até ficarem ininteligiveis, removi os sprites todos menos os 10 digitos
e já faz upload... mas ao executar dá:

MemoryError:

não tenho pachorra para isto... era uma demonstração académica interessante mas fiquemos por aqui
Jorge Pereira
«De génio, criança e louco... porquê só 1 pouco?»
Avatar do Utilizador
CyberX
Sócio
Sócio
Mensagens: 4513
Registado: 10 mar 2014, 20:09
Localização: Mira Sintra
Contacto:

Re: Apresentando texto com LEGO Powered Up

Mensagem por CyberX »

só para acabar: o mesmo código ultra-reduzido a uma fonte de 10 digitos corre no City Hub.

Mas se quiser extender com 26 caracteres e 3 simbolos... kaput

MemoryError: memory allocation failed, allocating %u bytes
(a carregar fontes)

retirando os 3 simbolos melhorou ligeiramente:

MemoryError: memory allocation
(a criar a matrix interna representando 1 (um!) caracter )

mas tive de tirar do W ao Z para conseguir executar:



se não podes mostrar um minimo de 10 digitos e 26 caracteres... esquece.
Jorge Pereira
«De génio, criança e louco... porquê só 1 pouco?»
Avatar do Utilizador
CyberX
Sócio
Sócio
Mensagens: 4513
Registado: 10 mar 2014, 20:09
Localização: Mira Sintra
Contacto:

Re: Apresentando texto com LEGO Powered Up

Mensagem por CyberX »

Para comparação dos vários hubs:
https://pybricks.com/learn/getting-star ... -you-need/

o que interessa aqui:

Código: Selecionar todos

			Prime hub*	Essential	Technic	City	BOOST
			Inventor hub 	 hub 		hub 	Hub 	Move Hub
Total storage** 	256Kb 		256Kb 		16Kb 	16Kb 	4Kb
Total RAM*** 		320Kb 		320Kb 		64Kb 	32Kb 	16Kb

(**) The storage is also the maximum size of your program.
(***) Working memory holds a copy of your program and system variables. The remainder is available for variables in your own code.
Como uma fonte de 32 sprites cabe à tangente no City Hub e o Technic Hub tem o dobro da RAM __talvez__ consiga uma fonte de 64 sprites mas se quiser exibir strings muito grandes vou precisar de melhorar a eficiência do código já que estou a renderizar a string toda para depois fazer a amostragem do que vai ser o bloco visivel, teria de fazer uma renderização parcial de 2 caracteres apenas e reconstruí-la a cada scroll.
Jorge Pereira
«De génio, criança e louco... porquê só 1 pouco?»
Avatar do Utilizador
AVCampos
Sócio
Sócio
Mensagens: 13795
Registado: 27 fev 2007, 19:26
Localização: Barreiro
Contacto:

Re: Apresentando texto com LEGO Powered Up

Mensagem por AVCampos »

Para utilizar menos espaço, considerando que cada pixel só pode estar aceso ou apagado (ou seja, ignorando as cores dos LEDs das matrizes), fez-me lembrar também a mim a construção de User Defined Graphics no Spectrum (no meu caso Timex TC2068): porque não codificar cada linha como um único valor numérico (de preferência unsigned byte, não sei de cor se o Pybricks permite isso) que o programa descodifica em bits individuais para os LEDs? Isso introduz algum overhead no programa, mas para números grandes de sprites pode compensar.

Tenho também ideia de que run-length encoding é eficiente para imagens monocromáticas, mas é capaz de ser demasiado puxado aqui...
Avatar do Utilizador
CyberX
Sócio
Sócio
Mensagens: 4513
Registado: 10 mar 2014, 20:09
Localização: Mira Sintra
Contacto:

Re: Apresentando texto com LEGO Powered Up

Mensagem por CyberX »

sim, armazenar um byte por linha, 6 linhas daria 6 bytes por sprite
antes de começar andei a ver uns geradores online de fontes para arduino que o fazem mas como são quase todos para 8x8 acabei por fazer o meu próprio código de raiz e como manipular um array é mais fácil que manipular um vector de 6 bytes...

lá terá de ser mas vai obrigar-me a criar funções intermédias ou para extrair os 6 bytes para uma matriz 6x6 ou para lidar com bit operations directamente sobre os 6 bytes. Mais uma vez, ter uma matrix 6x6 é mais fácil para lidar com o slideshow como o criei (matriz também).

O python tem uma estrutura de dados bytes e outra bytearray que podem ajudar mas não sei até que ponto o micropython implementa os métodos do python completo. Tenho de ver.

RLE é que não, valha-me Murphy!

Decisões, decisões.
Jorge Pereira
«De génio, criança e louco... porquê só 1 pouco?»
Avatar do Utilizador
CyberX
Sócio
Sócio
Mensagens: 4513
Registado: 10 mar 2014, 20:09
Localização: Mira Sintra
Contacto:

Re: Apresentando texto com LEGO Powered Up

Mensagem por CyberX »

Não foi dificil converter de array 6x6 para uma lista de 6 bytes 90% do traballho foi copiar a representação para uma folha de cálculo e daplicar algumas fórmulas a algumas celuas para converter na nova

A boa notícia é que o City Hub funciona agora com a fonte completa sem sequer ser necessário reduzir os nomes das variáveis.

A notícia menos boa é que o Move hub não se queixa de nada mas depois não executa, Memory Error sem dizer onde.
Reduzi a fonte a 10 digitos apenas e o erro muda para TypeError mas também sem dizer onde.

Vou deixar cair o Move Hub e tentar não deixar cair o City Hub, pelo menos para já. Não porque tenha qualquer tipo de interesse em usá-lo mas porque a ideia de fazer alguma coisa só com 2 ColorLightMatrix em vez de 4 não é má e quem tenha um set Spike Essentials já só terá de arranjar um ColorLightMatrix adicional para poder usar o meu código.

Ainda não fundi o código mas não deve faltar muito.
Jorge Pereira
«De génio, criança e louco... porquê só 1 pouco?»
Responder