2025 Autor: John Day | [email protected]. Última modificação: 2025-01-13 06:58
Por arduinocelentanoFollow Mais do autor:
Esta é uma lâmpada de baixo custo com quatro modos.
1. Faísca de arco-íris. Uma faísca de luz sobe vez após vez e muda gradualmente a cor.
2. Brilho do arco-íris. Um brilho estável que muda gradualmente de cor.
3. Simulação de velas.
4. Desligado.
Você pode alternar entre os modos tocando em um botão de toque na parte superior. O modo atual é salvo na memória EEPROM após o desligamento.
Quão pequeno é o ATtiny13?
A ideia era obter recursos máximos do hardware mínimo, algo mais complexo do que uma chave automatizada ou termômetro, um projeto próximo a este minúsculo microcontrolador. Afinal, as restrições fazem você pensar criativo, certo? Bem, parecia que no começo.
O mais desafiador neste projeto foi enfiar todo o código em ATtiny13. O microcontrolador possui 1K bytes de flash e apenas 64 bytes de RAM. Sim, quando digo “bytes”, quero dizer aqueles que consistem em oito bits. 64 bytes para todas as variáveis locais e pilha de chamadas. Para deixar claro, considere que temos que controlar 8 LEDs RGB. Cada um deles é definido por 3 bytes (um para o canal vermelho, verde e azul respectivamente). Então, apenas para armazenar o estado de 8 LEDs, precisaremos implementar uma matriz de 8 estruturas de 3 bytes cada e um ponteiro para o início desta matriz levaria mais um byte. Assim, 25 de 64 bytes estão fora. Acabamos de usar 39% de RAM e ainda não começamos. Além disso, para armazenar sete cores básicas do arco-íris, você precisará de 7 × 3 = 21 bytes, portanto, 72% da RAM estão fora. Bem, quanto às cores básicas, eu exagero: não precisamos de todas elas ao mesmo tempo na RAM e elas nunca mudam, então podem ser implementadas como um array constante a ser armazenado em flash em vez de RAM. De qualquer forma, dá uma impressão geral sobre o hardware usado.
Lembrando a declaração de Knuth sobre a otimização prematura, comecei fazendo um protótipo de três modos de lâmpada separadamente para ver o que acontece. Eu os testei separadamente para ter certeza de que funcionam corretamente e que cada um se encaixa no meu microcontrolador. Demorou algumas noites para conseguir e tudo correu bem … até que tentei colocá-los juntos na instrução switch. O utilitário avr-size relatou um tamanho de seção de texto de 1,5 Kb (com o sinalizador -s do avr-gcc). Naquele momento minha intenção original era pegar um ATtiny25 com flash de 2Kb e isso poderia ter sido o final feliz da história.
Mas, de alguma forma, senti que, após uma otimização considerável, conseguiria reduzir aquele código ruim para 1Kb. No entanto, demorou mais uma semana para perceber que é impossível e mais uma semana para realizá-lo de qualquer maneira. Tive que cortar um arco-íris em cinco cores básicas (sem diferença visual significativa). Eu me livrei das instruções case e usei uma cadeia de if-then-if para diminuir o tamanho do código binário. A animação Fire precisa de um gerador de números pseudoaleatórios que é bastante volumoso, então implementei uma versão simplificada do LFSR com valor inicial constante. Eu não me importo com a duração do ciclo completo de PRNG e apenas procurando um equilíbrio de descida entre o tamanho do código e "animação de fogo realista". Eu também implementei uma série de pequenas otimizações que não consigo lembrar agora e até consegui piscar todos os modos além de disparar no chip. Quando fiquei sem ideias, meu código total era de cerca de 1200 bytes.
Eu tirei um tempo limite e li muito sobre otimização de código AVR. Eu estava perto de desistir e reescrever tudo em linguagem assembly, mas dei a última chance. Durante a corrida de otimização final, cortei um arco-íris em três cores básicas e fiz outras para serem calculadas em tempo real, inspecionei tudo e segui as recomendações de otimização do AVR e, finalmente …
avrdude: escrita em flash (1004 bytes):
Escrevendo | ############################################################### | 100% 0.90s
Não é preciso dizer que usei quase toda a RAM e apenas um byte de EEPROM para armazenar o modo atual. Não quero dizer que esta seja uma implementação ideal e definitiva. Ele simplesmente funciona e se encaixa no microcontrolador. Tenho certeza, você poderia fazer melhor. Eu realmente sou. Só quero compartilhar a diversão de resolver um problema aparentemente impraticável que você considera quase impossível no início. “Assim, hackear significa explorar os limites do que é possível…” --Richard Stallman.
Suprimentos:
1x ATtiny13 MCU ($ 0,28 = $ 0,24 para MCU no pacote SOP-8 e $ 0,04 para o adaptador DIP8)
8 LEDs RGB WS2812 (eu recomendo uma placa ou um pedaço de faixa de LED) ($ 0,42)
1x botão de toque TTP223 ($ 0,10)
1x adaptador micro USB para DIP ($ 0,14)
1 resistor de 10kΩ (<$ 0,01)
1x capacitor de cerâmica 100nF (<$ 0,01)
1x capacitor eletrolítico de 10-47µF (<$ 0,01)
Total <$ 0,97
Etapa 1: configuração do software
Você precisará do conjunto de ferramentas avr-gcc para compilar o código-fonte e do utilitário avrdude para enviar a ROM do microcontrolador. O processo de instalação é bastante simples e direto, mas depende do seu sistema operacional. Se você usa algum tipo de GNU / Linux, provavelmente já possui os pacotes apropriados em sua árvore de repositório. O código-fonte deste projeto pode ser baixado aqui:
github.com/arduinocelentano/t13_ws2812_lamp
Você também precisará de uma biblioteca light_ws2812:
github.com/cpldcpu/light_ws2812
Depois de obter o conjunto de ferramentas avr-gcc e as fontes do projeto, execute seu terminal e digite o seguinte código:
caminho do cd / para / projeto
faço
Etapa 2: Programação do microcontrolador
Se você tiver algum tipo de programador USBASP, basta conectá-lo ao Attiny de acordo com sua pinagem. Normalmente ficaria assim, mas eu recomendo fortemente que você verifique sua pinagem real!
Alternativamente, você pode usar uma placa Arduino como programador. Abra o Arduino IDE e encontre o exemplo do Arduino ISP no menu “Arquivo → Exemplos”. Depois de fazer o upload do esboço, sua placa Arduino atua como um programador. Os comentários no código do esboço fornecem uma pista para a pinagem.
Agora corra
fazer flash
para piscar o MCU e
fazer fusível
para definir os bits do fusível.