Desenvolvedores procurados! Estamos procurando desenvolvedores talentosos de React e C ++ para ajudar neste projeto. Confira o código e, se você estiver interessado, entre em contato com [email protected].

Davepl, 19/09/2021
O NightDRIVERSTRIP é um pacote de código -fonte para criar um programa flash que você carrega para o microcontrolador ESP32. Ele pode acionar até 8 canais de LEDs no estilo WS2812b conectados aos pinos de chip e exibir cores e padrões e projetos sofisticados. Existem inúmeros efeitos incorporados que podem ser configurados para serem mostrados na tira de LED, incluindo efeitos de áudio/música/batida reativa para módulos equipados com um microfone. Opcionalmente, ele também pode receber dados de cores para os LEDs em um formato simples compactado (ou não compactado) LZ (ou não compactado) sobre um soquete TCP/IP aberto por padrão na porta 49152. O ESP32 mantém seu relógio sincronizado usando o NTP.
Nightriver pode conduzir as tiras do estilo WS2812B e matrizes no estilo Hub75.
Mais recentemente, um instalador da web foi adicionado ao projeto com o qual a maioria dos projetos de notícias pode ser exibida em dispositivos suportados, usando nada além de um navegador da web. Consulte a próxima seção se é assim que você gostaria de começar.
Foi disponibilizado um aplicativo da Web que pode ser usado para instalar a maioria dos projetos de noturso em dispositivos suportados. Isso permitirá que você exiba rapidamente um projeto no seu dispositivo ESP32, conecte -o ao WiFi e comece a usá -lo sem ter que trabalhar imediatamente com o código -fonte.
Observe que o instalador requer um navegador que suporta serial da Web. No momento da redação deste artigo, os navegadores que incluem esse suporte são versões recentes do Chrome, Edge e Opera.
Siga estas etapas para piscar e, se suportado, configure o WiFi no seu dispositivo:
Conecte seu dispositivo ao seu computador com um cabo USB.
Navegue até o seguinte URL no seu navegador: https://plummersoftwarellc.github.io/nightDriversTrip. Deve então mostrar uma tela que se parece com o seguinte: 
Selecione seu dispositivo (como "M5StickC Plus") na lista suspensa. Um segundo suspenso com projetos suportados nesse dispositivo aparecerá.
Selecione o projeto que você deseja piscar no segundo suspenso. Quando você o fizer, um botão Connect aparecerá abaixo dele. Observe que o rótulo de cada projeto inclui uma indicação dos principais recursos ativados na construção em questão. A legenda para cada uma das letras do recurso é mostrada abaixo do suspensão do projeto.
Clique no botão Conectar. Uma caixa de diálogo vai pedir para você selecionar uma porta serial. Dependendo do seu sistema, ele pode mostrar apenas uma ou uma lista deles. Caso o múltiplo seja mostrado, geralmente será o chamado claramente de "porta serial USB (COMN)". Selecione a porta correta e clique em Conectar.
Uma nova caixa de diálogo será exibida. Uma das opções que ele oferece é "Instalar <Project> para <vices>". Clique nessa opção.
Uma caixa de diálogo mostrará perguntando se você deseja apagar o dispositivo. Verifique a caixa se for a primeira vez que você pisca o NightDRIVERSTRIP no seu dispositivo ou deseja piscar uma instalação limpa. Isso redefinirá todas as configurações para seus padrões. Observe que a configuração do WiFi será limpa, se você optar por apagar ou não. Clique em Avançar.
Agora você será solicitado a confirmar que deseja exibir o dispositivo. Clique em Instalar.
Uma caixa de diálogo aparecerá mostrando o progresso da instalação. Geralmente, isso leva cerca de 2 minutos. Quando o piscar estiver concluído, clique em Avançar.
Neste ponto, quatro coisas podem acontecer:
Se o seu dispositivo não suportar WiFi, você poderá pular para o ponto 12.
Na caixa de diálogo Informações de conexão WiFi, selecione ou digite seu SSID e senha. Clique em Conectar. Em alguns casos, a caixa de diálogo WiFi Connection aparece novamente depois que uma conexão bem -sucedida foi realmente feita. Nesse caso, clique em Skip. Também é possível que um tempo limite seja relatado enquanto o WiFi está realmente conectado com sucesso. Nesse caso, clique em voltar.
Agora, aparecerá uma caixa de diálogo que mostrará os detalhes do projeto que você exibiu. Ele também fornecerá opções para piscar novamente e mostrar os logs e console do dispositivo. Além disso, se o seu dispositivo suportar WiFi, as opções estarão disponíveis para visitar o aplicativo da Web do dispositivo (desde que o servidor da Web no dispositivo também esteja ativado) ou altere as configurações WiFi. Observe que, se você exibiu uma imagem de dispositivo que inclui o servidor da Web/aplicativo da Web, pode levar um minuto ou mais para que a conexão com a rede WiFi tenha sido feita.
Se você deseja alterar a configuração do WiFi em um dispositivo já piscado, use as seguintes etapas:
Conecte seu dispositivo ao seu computador com um cabo USB.
Navegue até o seguinte URL no seu navegador: https://plummersoftwarellc.github.io/nightDriversTrip.
Selecione seu dispositivo (como "M5StickC Plus") na lista suspensa. Um segundo suspenso com projetos suportados nesse dispositivo aparecerá.
Selecione o projeto que você exibiu anteriormente, no segundo suspensão. Quando você o fizer, um botão Connect aparecerá abaixo dele.
Clique no botão Conectar. Uma caixa de diálogo vai pedir para você selecionar uma porta serial. Dependendo do seu sistema, ele pode mostrar apenas uma ou uma lista deles. Caso o múltiplo seja mostrado, geralmente será o chamado claramente de "porta serial USB (COMN)". Selecione a porta correta e clique em Conectar.
Uma nova caixa de diálogo será exibida. Se ainda não mostrar as opções "Connectar a Wi-Fi" ou "Altere o Wi-Fi", abra a janela "Logs & Console" e aguarde até que as linhas de log apareçam. Em seguida, feche a janela clicando em volta. Quando a opção "Conectar ao Wi-Fi" ou "Alterar Wi-Fi" for mostrada, clique nele.
Na caixa de diálogo Informações de conexão WiFi, selecione ou digite seu SSID e senha. Clique em Conectar. Em alguns casos, a caixa de diálogo WiFi Connection aparece novamente depois que uma conexão bem -sucedida foi realmente feita. Nesse caso, clique em Skip. Também é possível que um tempo limite seja relatado enquanto o WiFi está realmente conectado com sucesso. Nesse caso, clique em voltar.
As imagens incluídas no instalador são criadas usando o estado atual do código -fonte neste repositório. Se houver algo em que você gostaria de mudar (a configuração) do projeto que você deseja usar, é hora de passar para o próximo estágio.
Como o próximo estágio exigirá rapidamente algum conhecimento da estrutura do aplicativo que é o NightriversStrip, este pode ser um bom momento para ler a introdução à base de código da noite.
Em dispositivos com Wi -Fi, o NightDRIVERSTRIP pode iniciar um servidor da web que hospeda a interface do usuário da Web que faz parte do projeto. Ele pode ser usado para visualizar e alterar qual efeito está em execução e obter estatísticas de desempenho ao vivo do dispositivo.
Quando o dispositivo é iniciado com o servidor da web ativado, a interface do usuário da web pode ser acessada abrindo um navegador da web e digitando o endereço IP do seu dispositivo na barra de endereços. Uma vez carregado, os ícones à esquerda da tela podem ser usados para atingir as visualizações dentro e fora da interface do usuário.
Mais informações sobre a interface do usuário da web podem ser encontradas em seu próprio readme.md.
Além da interface do usuário da web, o servidor da web também publica uma API do tipo Rest. Entre outros, uma variedade de definições de configuração pode ser lida e alterada usando -a. Mais informações sobre a API estão disponíveis em REST_API.MD.
Eu recomendo que você faça o seguinte:
DEMO . Algumas dicas sobre o que é necessário para fazer isso podem ser encontradas abaixo.globals.h ou do arquivo plataformio.ini, como WiFi e WebServer. Veja o recurso Define abaixo. Verifique se o seu SSID e a senha do Wi -Fi estão definidos incluem/segredos.h, que podem ser criados fazendo uma cópia de incluir/secrets.example.h.
Por favor, certifique -se de configurá -los em incluir/segredos.h, não incluem/secrets.example.h!
Habilite WiFi definindo o atabilable_wifi Definir como 1 em globals.h.
# define ENABLE_WIFI 1Isso também pode ser configurado no arquivo Platformio.ini, conforme descrito na seção Define o recurso abaixo.
Estes definem permitem as principais características do NightRiversStrip. Defina -os no Build_Flags ou em globals.hi. Nota: Alguns definem são específicos da placa, isso é observado abaixo.
| Recurso Definir | Descrição |
|---|---|
| Enable_wifi | Conecte -se ao wifi |
| Incoming_wifi_enabled | Aceitar dados e comandos de cores recebidos |
| Enable_webserver | Ligue o servidor interno da web |
| Time_before_local | Quantos segundos antes da lâmpada se destacam e mostram conteúdo local |
| Enable_ntp | Defina o relógio da web |
| Enable_ota | Aceite as atualizações do Flash Air |
| Hardware específico | Descrição | Placas suportadas |
|---|---|---|
| Use_m5Display | Ativar estatísticas exibidas no LCD incorporado | M5STICK-C e M5STICK-C Plus |
| Use_oled | Ativar estatísticas exibidas no OLED embutido | Heltec WiFi Kit 32 |
| Use_lcd | Habilitar estatísticas exibidas no ILI9341 LCD externo | Wrover32 |
| Use_tftspi | Ativar estatísticas exibidas no TTGO externo LCD | Esp32Dev |
| Enable_audio | Ouça o áudio do microfone e processe -o | M5STICK-C e M5STICK-C Plus |
| Enable_remote | IR Controle remoto | Requer hardware IR |
Exemplo em plataformio.ini (prefixo as bandeiras com -D , por exemplo, ENABLE_WIFI=1 se torna -DENABLE_WIFI=1 )
build_flags = - DENABLE_WIFI =1exemplo em globals.h:
# define ENABLE_WIFI 1 Para adicionar novos efeitos, você:
LEDStripEffect (ou de uma classe de efeito existente) e as coisas boas acontecem na única função importante, Draw() . Confira o que os efeitos embutidos fazem, mas, em suma, você está basicamente atraindo uma variedade de objetos CRGB que representam um trigêmeo de cores de 24 bits. Depois de terminar, a matriz CRGB é enviada aos LEDs e você será solicitado o próximo quadro imediatamente. Seu método de desenho deve levar algum lugar em torno de 30ms, idealmente, e deve delay() para dormir para o saldo, se for mais rápido. Você pode desenhar repetidamente basicamente em um loop ocupado, mas não é necessário.#define para sua classe de efeito aos effects.h . Cada classe de efeito precisa de apenas um número de efeito e verifique se o número que você escolher ainda não é usado por outra classe de efeito! Mais informações sobre o link entre uma classe de efeito e seu número de efeito associado podem ser encontradas em effects.h .LoadEffectFactories() no effects.cpp (na seção de configuração de compilação, como DEMO ). A macro ADD_EFFECT() espera o número do efeito e o nome do seu novo efeito como parâmetros. Quaisquer parâmetros adicionais são passados para o construtor do efeito quando for criado. Existe uma instância global EffectManager que primeiro cria a tabela de efeitos de um arquivo JSON no SPIFFs, se presente. Em seguida, adiciona outros efeitos registrados em LoadEffectFactories() , mas não incluídos no arquivo JSON. Em seguida, ele gira entre esses efeitos a uma taxa controlada por DEFAULT_EFFECT_INTERVAL . Os efeitos não são notificados quando se tornam ativos ou não, são solicitados apenas a desenhar quando necessário.
Cada canal de LEDs possui uma instância LEDStripGfx associada a ele. _GFX[0] é o LEDStripGfx associado ao LED_PIN0 e assim por diante. Você pode obter o buffer LED do PIN0 chamando _GFX[0]->leds() e ele conterá _GFX[0]->GetLEDCount Pixels. Você pode atrair o buffer sem tocar nos bytes crus chamando fill_solid , fill_rainbow , setPixel e outras funções de desenho.
A configuração mais simples, DEMO , pressupõe que você tenha uma única faixa de 144 LEDs e uma fonte de alimentação conectada ao seu ESP32. Ele inicializa, encontra um único RainbowFillEffect na função LoadEffectFactories() e chama repetidamente seu método Draw() para atualizar a matriz CRGB antes de enviá -la para os LEDs. Se estiver funcionando corretamente, ele deve desenhar uma paleta de arco -íris de rolagem na tira de LED.
Essa configuração mais simples, chamada aqui simplesmente 'demonstração', é fornecida por um ambiente de construção específico da placa. A lista desses ambientes pode ser vista executando 'Python3 Tools/SHOW_ENVS.PY', que diria ao leitor que, até o momento da redação, as variações específicas de hardware da 'demonstração' incluem:
Esses tipos de construção podem ser escolhidos pelo argumento '-e' para PIO ou em uma opção de menu dentro do código Platformio IDE/vs.
A tabela de efeitos é persistida em um arquivo JSON em SPIFFs em intervalos regulares, para manter o estado dos efeitos (e, de fato, toda a lista de efeitos) nas reinicializações. Isso está em grande parte na preparação para atualizações futuras do NightRiversTrip, onde a composição da configuração da lista de efeitos dos efeitos individuais pode ser alterada usando o aplicativo da Web do dispositivo. Os pontos de extremidade da API para facilitar isso já estão disponíveis e estão prontos para uso (consulte a interface da web e API do dispositivo, abaixo.)
Isso faz com que uma substituição de SerializeToJSON() e um construtor desserializador correspondente devem ser fornecidos para efeitos que necessidade (ou desejam) persistirem mais do que as propriedades que são (de) serializadas de/para JSON pelo LEDStripEffect por padrão.
Ao longo do projeto, a biblioteca usada para o manuseio JSON e a serialização (DE) é Arduinojson. Entre outros, isso significa que:
De acordo com a Convenção em Arduinojson, as funções SerializeToJSON() devem retornar true exceto quando uma função Arduinojson (como JsonObject::set() ) retorna false para indicar que ficou sem memória de buffer. Qualquer função SerializeToJSON() que retorna false desencadeará um aumento no tampão de serialização geral e uma reinicialização do processo de serialização.
A memória necessária para a operação de serialização de uma instância de classe individual precisa ser reservada com antecedência , criando:
StaticJsonDocument< tampão de buffer >() que se reserva memória na pilha. Isso pode ser usado para tamanhos de buffer pequeno (menor que 1024 bytes) apenas.AllocatedJsonDocument( tamanho do buffer ) que reserva memória na pilha.Quanta memória é realmente necessária depende do número, tipo e conteúdo das (de) propriedades serializadas e é efetivamente um jogo de adivinhação - o que significa que os valores que você verá em toda a base de código também são suposições educadas. Quando as propriedades que são serializadas pela última vez não são exibidas no JSON que é gerado, é razoável assumir que o processo de serialização ficou sem memória de buffer e que a memória do buffer precisa ser aumentada.
Para entender melhor os detalhes relacionados à serialização JSON (DE), você pode considerar uma olhada nos respectivos tutoriais na seção "Primeiro contato" da documentação Arduinojson.
Por exemplo, durante o desenvolvimento, a lista de efeitos (JSON-Peristits) em sua placa pode sair da sincronização com os efeitos que você adiciona em efeito.cpp (na função LoadEffectFactories() especificamente) a um ponto que se torna confuso ou irritante. Se isso acontecer, você pode redefinir a lista de efeitos na placa para o padrão, através da rede. Para que isso funcione, a placa deve ser conectada ao WiFi e o servidor da web deve estar em execução.
A redefinição pode ser feita executando uma postagem de formulário HTTP em http: // <posity_ip>/redefinir com os seguintes campos set: efetsconfig = 1 e placa = 1. Em sistemas com enrolamento "regular" disponível, o comando a seguir deve fazer o truque:
curl -d " effectsConfig=1&board=1 " -X POST http:// < device_IP > /resetÉ possível que a capacidade de executar esta redefinição seja adicionada em uma atualização futura à interface do usuário da web.
Além disso, também é possível "ignorar" a lista de efeitos persistentes e sempre carregar a lista de efeitos padrão na inicialização. Documentação sobre como fazer isso está disponível no topo da função LoadEffectFactories() mencionada.
Se você desenvolver um efeito que exija que os dados sejam retirados da Internet, poderá registrar uma função de leitor de rede na classe NetworkReader , que está disponível na referência global g_ptrSystem->NetworkReader() . Você pode usar os PatternSubscribers ou efeitos PatternWeather como fontes de inspiração. Patternstocks puxa as cotações de ações ao vivo (atraso de 15 minutos) de um servidor privado.
O projeto pode ser construído usando o Platformio. Há um IDE de plataforma disponível, construído sobre o código do Visual Studio. Incluídos estão as ferramentas principais da plataforma de linha de comando. Eles também podem ser instalados por conta própria, se você preferir não usar o IDE.
Para compilar o aplicativo front-end (que faz parte de cada compilação da plataforma), é necessária uma versão recente do NodeJS com o NPM. Eles podem ser baixados no site do NodeJS. Instruções para maneiras suportadas de instalar NodeJs também estão disponíveis lá. Por favor, leia e siga -os.
Observe que a instalação do NodeJS usando o gerenciador de pacotes padrão do sistema operacional/distribuição provavelmente o deixará com uma versão NodeJS muito mais antiga do que você precisa.
O aplicativo foi testado na versão 16.15.1 e 18.17.1 do nó com o NPM versão 8.13.2; Versões mais recentes também devem funcionar em princípio.
Para detalhes sobre o trabalho com o aplicativo front -end, consulte o site/readme.md.
Quando o IDE ou o núcleo são instalados, o NightDRIVERSTRIP pode ser construído a partir de um shell de comando inserindo o diretório do projeto/repositório e emitindo o seguinte comando:
pio run -e demo
Isso criará a config demo .
Se você receber um erro de que
pionão foi encontrado, pode ser necessário adicioná -lo ao seu caminho.
Para criar todas as configurações disponíveis, use o seguinte comando (isso pode demorar um pouco):
pio run
Para construir e fazer upload do sistema de arquivos que pode ser usado por efeitos (embora atualmente nenhum o faça), você precisará criar e fazer upload da imagem SPIFFs no flash da sua plataforma usando o Platformio. Você pode fazer isso usando a interface do usuário da plataforma ou usando a ferramenta de linha de comando pio :
pio run --target buildfs --environment <project name>
pio run --target uploadfs --environment <project name>
Este repositório inclui vários scripts para executar várias tarefas durante ou após a construção de projetos. Eles estão incluídos no diretório tools . Observe que os scripts esperam ser iniciados no diretório principal do projeto. Então, usando:
tools/buddybuild.shEm vez de:
cd tools
./buddybuild.shEscreva algo simples para enviar dados coloridos para o soquete. O formato é muito básico: qual canal, quantos LEDs você está desenhando, quando desenhá -lo e os próprios dados de cores. Você pode enviar dados não compactados com um registro de data e hora zero, desde que envie o cabeçalho correto antes dos dados, o que é muito simples. Os dados com um registro de registro zero serão desenhados imediatamente sem buffer.
| Bytes | FUNÇÃO | |
|---|---|---|
| 0, 1 | CommandId | (Defina -o como 3, que é WIFI_COMMAND_PIXELDATA64 ) |
| 2, 3 | Canalidado | (Defina -o como 1 para canal único, embora 0 também funcione por razões históricas) |
| 4 - 7 | Comprimento | (Número de PIXELS de 24 bits sendo definidos) |
| 8 - 15 | Segundos | (Defina -o para 0) |
| 16 - 24 | Micros | (Defina -o para 0) |
| 25+ | Rgb | (Dados de cores RGB de 24 bits, um por PIXEL especificado em comprimento acima) |
Se construído com ENABLE_WIFI e INCOMING_WIFI_ENABLED , se o chip puder obter uma conexão WiFi e o endereço DHCP, ele abrirá um soquete na porta 49152 e aguarde os pacotes formados conforme descrito acima.
Gere uma série de 24 quadros por segundo (ou 30 se abaixo de 500 LEDs) e defina o registro de data e hora como "agora" mais 1/2 por segundo. Envie -os para o chip sobre o Wi -Fi e eles serão desenhados 1/2 segundos a partir de agora em um fluxo constante à medida que os registros de data e hora que você deu a cada pacote veio.
Divulgação completa: Como associado da Amazon, a PlummerSsoftwarellc recebe comissão de compras qualificadas. Não é adicionado ao preço de compra e não aumenta seu custo. Além disso, todos os lucros 2021 do Dave's Garage Channel, que incluem essas vendas, irão para o UW Autism Center.
Em vez de produzir um conjunto complexo de diretrizes, eis o que espero que a colaboração de código aberto trará para o projeto: que as pessoas adicionam recursos importantes e corrigem defeitos e deficiências no código. Ao adicionar recursos, eles farão isso de uma maneira consistente com a maneira como as coisas são feitas no código existente. Eles resistem ao desejo de rearmar e reescrever tudo em sua própria imagem e, em vez disso, se esforçam para maximizar a melhoria funcional, reduzindo o thrash e a mudança do código -fonte.
Vamos considerar a nomeação inconsistente, que deve ser corrigida. Alguns são camelcase, outros são pszhungarian e assim por diante, dependendo da fonte. Eu preferiria que tudo fosse atualizado para um único TBD padrão. Até que o TBD seja determinado, eu me inclino para o padrão Win32.
Ao trabalhar em uma função, trabalhe no estilo da função. Ao trabalhar em uma aula, trabalhe no estilo da classe. Ao trabalhar em um arquivo, trabalhe no estilo do arquivo. Se esses forem inconsistentes, faça o que minimize as alterações. As mudanças estilísticas só devem ser introduzidas após a discussão no grupo e geralmente devem entrar em contato com essa mudança de estilo em todo o projeto.
Em seguida, vamos considerar o #define para controlar a construção. Pode haver maneiras melhores e mais elegantes de fazer as coisas. Pode haver plataformas de configuração inteiras. Mas eu prefiro simplificar. E eu defino mais simples ser "o mínimo que um programador de C ++ experiente precisa aprender antes de ser construtivo com o código em questão". Não quero aprender uma nova biblioteca de classes, se eu puder evitá -la!
Uma vida inteira de codificação me ensinou a errar pelo lado da simplicidade; portanto, não introduza construções de modelos variádicos, a menos que eles reduzam comprovadamente o código -fonte. Qualquer coisa que cresça a complexidade e o comprimento do código deve ser suspeita.
Adicione o que você quiser e/ou precisa realizar seus sonhos de LED. Consertar meus erros. Preencha as lacunas óbvias no meu conhecimento. O que quer que tenha mais piscar a menor parte do meu voto. Você só obtém tanta piscar de olhos adicionais para todos os bytes de código e programa. Esse retorno é medido em BlinkenPerbit, a quantidade de grandiosidade piscante que o código adiciona dividido pelo impacto na fonte (e binária).
Para replicar, construa o projeto Mesmerizer. Em seguida, exclua o PIO/Build_Cache e construa novamente, dedicando tempo para a segunda compilação.
ASUS 7995WX [96-CORE, 192-Thread]-> [Davepl, 02/11/2024] 20,73 segundos
HP Z6 G5A, 7995WX, 128GB [96-Core, 192-Thread]-> [Davepl 29/11/2023] 25.270 segundos
3970X, 128GB [32-Core, 64-Thread] Windows11+WSL2/Ubuntu02.04LTS-> [Davepl 29/11/2023] 34.292 segundos
MAC M1 Ultra Studio [10 núcleos, 20 Thread]-> [Davepl 29/11/2023] 48.368 segundos
Hora de criar a configuração do Spectrum ( pio run -e spectrum ). Assume uma construção limpa depois que tudo foi instalado e baixado.
AMD 3970 32 -CORES, 128 GB, RAID SSD -> [Davepl 19/09/2021] 12,93 segundos (executando sob WSL)
AMD 5950X 16 -CORES, 64 GB, SSD -> [Davepl 09/19/2021] 16,90 segundos
Apple MacBook Pro M1 Max, 8+2 núcleos, 64 GB, 4TB SSD -> [Davepl 15/12/2021] 20,90 segundos
Apple MacBook Air M2, 16 GB, 256 GB SSD -> [VAASKI 28/02/2023] 56,17 segundos
MacBook Pro 2020, 8 núcleos 2,4 GHz I9, 64 GB, 4TB SSD -> [Davepl 09/19/2021] 34,09 segundos
MAC MINI, 4 CORES AFF, 16GB -> [Davepl 09/09/2021] 39,06 segundos
Mac Pro, 6 núcleos, 3,5 GHz, 64 GB, 1TB SSD -> [Davepl 09/19/2021] 48,42 segundos
Xeon Silver, 20 núcleos, 2,1 GHz, 16 GB VM -> [Davepl 10/10/2022] 53,11 segundos
Raspberry Pi 4, Ubuntu LTS de 64 bits, 4 núcleo, 4 GB -> [Davepl 23/09/2021] 6 min 25 segundos
Jetson Nano 2G, 4 braço principal A57 -> [Davepl 10/04/2021] 2 min 56 segundos