terça-feira, março 08, 2022

Comandando LEDs RGB "endereçáveis" com a PIO do Raspberry Pi Pico - Detalhes Sobre as Temporizações

Ao preparar a minha live sobre o uso de LEDs RGB "endereçáveis" com o Raspberry Pi Pico, me deparei com uma divergência entre os tempos calculados para o programa exemplo da Raspberry Pi Foundation e os tempos indicados no datasheet do WS2812B. Este post relata o que eu estudei depois sobre o assunto.

Você assistiu a live, certo?


Resumindo a questão, os LEDs RGB que estamos falando recebem os dados serialmente, com zeros e uns determinados pelos tempos em que o sinal fica alto e baixo. Os valores abaixo são do datasheet do WS2812B (que é encontrado em vários sites):


Para gerar estes tempos é usado a PIO do Pi Pico. O código exemplo oficial é o seguinte:
.define public T1 2
.define public T2 5
.define public T3 3

.wrap_target
bitloop:
    out x, 1       side 0 [T3 - 1] ; Side-set still takes place when instruction stalls
    jmp !x do_zero side 1 [T1 - 1] ; Branch on the bit we shifted out. Positive pulse
do_one:
    jmp  bitloop   side 1 [T2 - 1] ; Continue driving high, for a long pulse
do_zero:
    nop            side 0 [T2 - 1] ; Or drive low, for a short pulse
.wrap
Uma análise deste programa revela os seguintes tempos, considerando que o clock configurado é de 8MHz:
  • T0H = T1 / 8 = 0,25 us
  • T0L = (T2 + T3) / 8 = 1 us
  • T1H = (T1 + T2)  /  8 = 0,875 us
  • T1L = T3 / 8 =0,375 us
Na minha live comentei que a combinação T1=3, T2=4 e T3=3 geraria tempos mais próximos dos contidos no datasheet do WS2812B. Posteriormente observei os sinais com um osciloscópio e confirmei os dados.

Sinal com os valores padrão ("um" seguido de "zero")

Sinal com os meus valores ("um" seguido de "zero")


Será que a Raspberry Foundation comeu bola? Uma busca nos issues do github levou a uma discussão bastante completa. Resumindo os pontos levantados nela:
  • Os meus cálculos e medidas estão corretos (ufa!)
  • Além do WS2812B são comuns os LEDs RGBs WS2812 e SK6812, que usam temporizações diferentes
  • Os valores que eu determinei (3, 4, 3) é mais apropriado que os valores padrão para o WS2812B, mas menos apropriados para os outros LEDs.
  • Existe uma certa desconfiança com relação ao valores indicados nos datasheets. Na prática os LEDs parecem aceitar variações bem maiores que as indicadas.
  • Os valores 3, 3, 4 parecem atender melhor os três LEDs
  • Os valores 2, 2, 2, com clock de 4,8MHz, baseados na ideia que o importante é manter uma relação de 1/3 x 2/3 nos sinais, funcionaram na prática
A tabela abaixo (baseada em uma feita por Andrew Scheller) resume os dados:



Pessoalmente gostei mais dos valores 3, 3, 4, mas aparentemente funciona bem com todos eles.

Nenhum comentário: