Filtro para leitura de ADC

screenshot.73
Durante muitos anos eu desenvolvo técnicas de filtros passa baixo por software em leitura de ADCs, para obter um sinal médio mais estável e mais funcional.

Existem diversas técnicas, já usei muitas.

Ao final das contas, ultimamente estou optando por uma técnica muito rápida e que ocupa pouco software, mesmo que ela faz uma média de 16 leituras.    Essa técnica, que vou chamar aqui de “MDM” (média das médias), vai ocupar o mesmo espaço em variáveis e praticamente a mesma quantidade de código para memorizar 1, 2, 4, 8, 16, 32 ou 64 leituras.

Para facilitar o software é interessante sempre optar por uma quantidade de amostragens que seja equivalente a 2^n, a fim de facilitar a divisão, que será feita usando só a instrução “shift-right”.

Uma técnica que eu vinha usando por anos era a do “buffer rotativo”, ou seja, eram alocados 32 bytes na memória, para 16 leituras (2 bytes cada), e um ponteiro que ficava rodando nesse buffer a cada nova leitura, substituindo a leitura mais antiga pela mais nova, então todos os 2×16 bytes eram somados e o total era dividido por 16, a fim de obter a média das ultimas mais recentes 16 leituras.

A técnica que apresentarei aqui hoje, a “MDM”, não é a média de 2^n leituras, mas é a média das médias infinitas, o que apresenta uma estabilidade muito maior, e na prática quase que independe de acumular 4, 8, ou 64 leituras, a média das médias será praticamente a mesma, o que mudará com mais ou menos leituras é a resolução do ultimo bit do valor a mostrar.

A idéia é diluir a medida atual num balde de “n” medidas anteriores, de forma a obter a média simples das leituras, mas sempre manter a média de “n” leituras anteriores.

Atenção ao detalhe, estarei mantendo A MÉDIA de “n” leituras anteriores, e não as “n” leituras anteriores.

No caso de um microcontrolador que possui um ADC de 10 bits, precisarei de dois bytes para armazenar o valor lido (VL) e a média das leituras (ML) , e também precisarei de outra variável que caiba a soma de “n” leituras (SL) de valor máximo do ADC, no caso de 10 bits, é 1024.

Portanto, precisarei de duas variável de 16 bits, e uma terceira de também 16 bits, para conter o valor máximo somado de 16 x 1024 = 16384.

Inicialmente carrego SL com a metade do valor máximo de 16 leituras, que é 8191 (0x1FFF). Pode ser qualquer valor, até 1 ou 16383, só não pode ser 0×0000 ou 0×8000, senão dá problemas na rotina.

Em seguida leio o ADC em VL, digamos que foi lido 0x13A.  Subtraio ML de SL e somo VL.

Portanto, a variavelzona SL terá :   0x1FFF – 0×0000 + 0x013A = SL = 0×2139.
Agora copio SL para ML e faço quatro shifts right em ML, obtendo o valor 0×213.
Nesse instante, o valor médio ML  será 0×213.

Leio novamente o ADC em VL, digamos que pela instabilidade foi lido 0x13D, subtraio ML de SL e adiciono VL, copio VL para ML, faço quatro shifts para a direita em ML, o que o divide por 16.
Vejamos, SL era 0×2139, subtrai 0×213 e somei 0x13D, agora SL = 0×2063, copio para ML e faço 4 shifts para a direita, resultando no novo valor médio ML de 0×0206.

Aproximadamente após 100 leituras e rodadas acima, o valor ML será a média simples das leituras do ADC, com grande estabilidade.

Uma centena de leituras parece muito, mas se a fizer a cada 5ms, significa 500ms para estabilizar a leitura.  A partir dai, as mudanças no sinal lido serão menores e poucas rodadas estabilizam.

Note que essa técnica funciona melhor quando o ADC roda continuamente, alimentando a rotina das médias.  A qualquer instante, para saber o valor da média das leituras, basta ler o valor de ML.

A teoria da rotina é que ao retirar a média das médias do valor de 16x médias, essa soma passa a ser 15x medias, e então soma-se o valor lido do ADC, e divide-se por 16, que seria o mesmo que subtrair 1/16 da média obtida e somar 1/16 do valor lido.  O problema é que fazendo dessa maneira, perde-se-ia quatro bits de baixa ordem do valor lido, e na prática seria como se eliminando os 4 bits de baixa ordem, obtendo estabilidade na marra com 6 bits do ADC.

Com a técnica acima, obtem-se a mesma estabilidade dos 6 bits da alta ordem nos 10 bits do ADC, o que é muito interessante.

Na tabela abaixo, feita no Excel, temos SL (que inicia com 0x1FFF), VL (um valor randomico entre 251 e 258) e ML (a média das médias).  Note que após aproximadamente 80 rodadas, ML já está estabilizando em torno de 256/255.


O gráfico abaixo da “perseguição” de “ML” com base em “VL”, mostra a aproximação sucessiva e a centralização em 254/255.

screenshot.76

Multiplicação Binário 2

Já expliquei em outro post como multiplicar em binário, mas agora explico uma nova maneira de multiplicar, que talvez seja até mais simples de entender e fazer, apesar de ser sempre a mesma coisa, ter a mesma base, e usar a mesma mecânica.

Consideremos que a nossa multiplicação tenha dois operadores, A e B.

Digamos que A=1537 e B=723

O resultado esperado é 1527 x 723 = 1104021

Vamos nomear uma variável R como sendo o resultado.

   1) R=0
   2) Shift A um bit para a direita
   3) Se ocorreu carry bit, ou seja, A “era” impar, some B em R
   4) Shift B um bit para a esquerda

   5) Repita 2-4 até A ser zero.

Pronto, R contém o resultado de A x B

A técnica é somar o valor atual de B em R, só quando A é impar, e desprezar B quando A é par.

Duvida? Veja:

                   A                         B                         R

Isso é muito simples, não é?

Ventilador na Placa de Motor de Passo TB6560AHQ

image.851

Olá, tenho uma daquelas placas Driver de Stepper Motor do eBay, para 4 motores, fabricados pela empresa chinesa www.huy68.com , ela usa o chip Toshiba TB6560AHQ, que é uma dupla ponte de potência, capaz de fornecer 3.5A @ 40Vdc aos motores .

Essa placa contém um dissipador único e longo sobre os chips, com um ventilador de 40mm, 12Vdc, que roda a toda velocidade, todo o tempo.  Ele é barulhento e não faz tanto vento, o que é comum para ventiladores de baixo custo como esse.  Além disso, o ventilador é alimentado pelo regulador 12Vdc exitente na placa. O ventilador consome entre 100 a 120 mA, parece pouca corrente, mas se o usuário alimenta a placa com os 24Vdc recomendados, o regulador LM7812 irá se dissipar a tensão e corrente extra, de até 1,5W apenas para alimentar o ventilador, energia e calor desperdiçado.

Devido a esse pequeno problema de projeto, o LM7812 fica desnecessariamente quente.

image.853

Além disso, este regulador 12Vcc, alimenta o regulador LM7805 que fornece o +5Vdc para os foto-acopladores e os chips TB6560AHQ.  Qualquer consumo nos +5V irá dissipar ainda mais calor no regulador LM7812.

O LM7812 é instalado em um pequeno dissipador negro, que pode não refrigerar adequadamente o regulador com a placa em funcionamento. Você pode ver os dois dissipadores negros na foto à direita, com os respectivos reguladores parafusados. O fios vermelho e preto no pequeno conector branco são os que alimentam o ventilador com 12Vdc.

Então, inicialmente eu cortei um fio do ventilador e inserí 6 diodos 1N4007 em série, para reduzir os 12Vdc ao ventilador, o que resultou em 8Vdc.  Isso reduziu a velocidade, o barulho e a energia consumida, baixando um pouco a temperatura do LM7812, mas não foi suficiente.

Air Flow do duto para as 7805 e 7812 os reguladores

Então, eu criei uma canaleta de fluxo de ar feito com cartão de papel (cartões de visita), de forma a orientar o ar empurrado pelo ventilador para os lados do dissipador maior, e no final (parte de baixo da foto) fiz o duto virar à esquerda e continuar ar sobre os dissipadores de calor LM7805 e LM7812.  Dava para sentir o ar mais frio fluindo sobre os dissipadores dos reguladores 7805 e 7812, que os refrigerava melhor, mas não o ideal.

Mas essa foi uma solução feia e trabalhosa.

Então eu pensei para mover o regulador LM7812 para o dissipador maior dos TB6560AHQ, que possui o ventilador.   Então eu dessoldei oLM7812, soldei três fios longos (vermelhos na foto) e movi o LM7812 para entre duasduas aletas do radiador do dissipador maior.

A 7812 foi deslocada da sua posição original, para ser inserido entre duas aletas do dissipador de calor grande. Eu lambusei o LM7812 com um pouco de pasta térmica branca e o inserí entre as aletas do dissipador. Foi necessário usar uma chave de fenda para abrir um pouco as aletas, o LM7812 entrou justo e ficou bem preso. Não foi necessário nenhum parafuso de fixação, pois é impossível remove-lo sem forçar as aletas com uma ferramenta qualquer.  Com as aletas forçadas abertas, a trazeira do LM7812 assentou certinho sobre uma aleta e a pasta térmica.  Assim a transferência térmica do LM7812 ficou muito melhor que quando no seu pequeno dissipador original.

Okay, o problema do LM7812 foi resolvido, agora precisei resolver a velocidade da rotação do ventilador.  Eu pensei em duas possíveis soluções, a primeira usar um simples circuito de três op-amps, gerando onda quadrada, convertendo em triangular, comparando com uma tensão sobre um NTC e gerando um PWM que alimentaria o ventilador.

A tensão dividida entre um resistor fixo de 10kΩ e o NTC, varia em torno de 6Vdc com 75°F.  Quando a temperatura sobe, a tensão no NTC é reduzida.  O terceiro op-amp compara a tensão do NTC com a forma de onda triangular, e quando a triangular for maior que a do NTC, isso alimentará o ventilador.  Quanto maior a temperatura sobre o NTC, mais tempo a triangular é maior que a tensão do NTC, e mais tempo o ventilador é alimentado. Essa comparação ocorre milhares de vezes por segundo, gerando um controle por PWM sobre o ventilador. Como a saída deste op-amp alimenta a base de um transistor PNP que alimenta o ventilador, , quanto mais largoé este pulso, mais rápido gira o ventilador.

Ao redor de  90°F a tensão NTC é cerca de 4.8Vdc, menor que a parte inferior da tensão da forma de onda triangular, de modo que a saída do terceiro op-amp será constante, aplicando-se energia 100% ao ventilador, com a intenção entre 75 e 80°F.

Se a temperatura do dissipador cair abaixo de 75°F, o ventilador irá parar de girar, reduzindo o consumo de energia e barulho. Essa idéia é boa, mas usa 9 resistores a bordo, requer alguns ajustes para funcionar nas temperatura desejada e não é exatamente “alta tecnologia”, é uma solução analógica simples.

Abaixo o esquema dessa solução analógica, ela funciona muito bem.   Eu desenvolvi o esquemático no simulator da Linear Technology CAD (LTspiceIV), então montei num protoboard e testei adequadamente. Funcionou muito bem, de acordo com o esperado.

image.855

Mas eu tinha a segunda idéia.

Apesar da solução analógica acima funcionando muito bem, eu sempre procuro ver se não é possível resolver o problema usando um microcontrolador, pois as vezes isso economiza componentes e o ajuste é feito por software, o que as vezes é mais fácil.

Por ser pequeno, o Atmel AtTiny13 atendia muito bem a solução, resuzindo diversos componentes usados na solução analógica.  A solução com o AtTiny13 usa só dois resistores, um para formar o divisor resistivo com o NTC, e outro em série com a base do transistor PNP, que alimenta o ventilador.

Claro que a solução usando o AtTiny13, requer +5Vdc, e que, apesar disso existir na placa, iria requerer mais um fio entre a placa e a plaquinha do AtTiny.   Chegando na plaquinha do AtTiny eu já tinha “terra”, “+12V”, e os fios do ventilador.  A solução foi usar um LM78L05, involucro TO92, pequeno suficiente para não causar nenhum incomodo ao projeto em questões de tamanho.  O consumo do AtTiny é muito pequeno, portanto o 78L05 atende perfeitamente sem aquecer.

A placa de controle. Veja o NTC no lado direito, protegido com fita kapton.

À esquerda uma foto do prototipo contendo o AtTiny13, seis pinos de programação ISP, dois resistores, um capacitor, o regulador 78L05, e o transistor BDxxx para alimentar o ventilador.  Saindo ao lado direito da plaquinha, dois fios, amarelo e vermelho, liga ao NTC protegido por fica Kepton.  A idéia é enfiar esse NTC no fundo da canaleta do dissipador e captar a temperatura mais próxima aos chips TB6560AHQ.

Então, a emenda do divisor resistivo entre o resistor 10kΩ ligado à +5Vdc e o NTC ligado à terra, vai diretamente ligado à uma entrada ADC (conversor analógico-digital) do AtTiny1. A idéia aqui é escrever um programa simples no AtTiny que lê o ADC, que utilizando a função Timer / Contador à bordo, controla pulsos na forma PWM que alimenta a base do transistor PNP que alimenta o ventilador.   O programa lê o ADC, e enquanto o valor estiver dentro de uma certa faixa de valores, liga o PWM com diferentes larguras de pulso, de acordo com a temperatura lida pelo ADC.

Sendo programável, isso se torna muito mais maleável que a solução analógica usando os tres op-amps acima. Uma das desvantagens do sistema analógico é que o ventilador inicia a rodar muito lentamente, e as vezes nem parte adequadamente com pequena diferença térmica.  Usando o AtTiny13, eu posso dar um tranco maior no ventilador para iniciar a rodar e reduzir o PWM para mante-lo lentamente, se for o caso de pequena diferença térmica.

A placa de controle que está sendo instalado, consulte o regulador 78L05 eo corpo transistor BDxxx acontecendo entre duas aletas do dissipador de calor.

A foto ao lado mostra a pequena placa protótipo sendo instalada. Note do corpo do transistor BDxxx indo entre as aletas do dissipador de calor, juntamente com o corpo do TO92 78L05. Ambos entram apertados nas aletas, ficando bem presos. Ambos os transistores descem isolados bem para dentro das aletas, servindo tanto como suporte à plaquinha protótipo, quanto dissipando o possível calor gerao pelo BDxxx e o 78L05.

A fita Kepton amarela no dissipador é para prevenir os pinos ISP tocarem o aluminio.  Numa possível placa final, esses pinos não existiriam. A altura do corpo DIP8 do AtTiny13 serve como espaçador entre o topo das aletas do dissipador e a placa protóripo.

Foi usado um BDxxx para alimentar o ventilador, claro que eu testei com um TO92 2N4103, que funcionou bem, mas pensando em situações ainda não previstas, decidi manter o BDxxx que aguenta maior abuso e também um ventilador maior, um mesmo um segundo ventilador em paralelo, se necessário.

O próximo passo seria produzir uma PCI profissional, que irá alojar também os reguladores 7812 e 7805, e coloca-la à venda no website http://www.urkit.com, por um preço baixo.

image.854

À direita você pode ver a placa sobre o dissipador de calor, na placa final acredito que um simples parafuso a fixaria ao dissipador.

No software do AtTiny13, fiz com que, ao alimentar a placa com energia, o ventilador ligasse tres vezes em máxima rpm por um ou dois segundos, como sinalizador de que o ventilador e a plaquinha de controle estão funcionando adequadamente.  O problema é que ao alimentar a placa, no início o dissipador está frio e o ventilador irá demorar algum tempo para ligar, e só o fará após o dissipador aquecer. Se existir algum problema, o operador pode não peerceber.  Assim, ao ligar, o operador ouvirá as tres acelerações do ventilador e saberá estar funcionando.

Penso que para um prototipo até que ficou funcional.

Wiring Pen

Existe um tipo especial de fio magnético (fio esmaltado) que derrete o esmalte com a temperatura do ferro de solda.  Esse fio é especial para fabricar protótipos de circuito impresso, e evita descascar uma pancada de fios para tal.  Basta encostar a ponta do fio no ponto a soldar, encostar o ferro de solda e pronto, o esmalte queima / recolhe, e a solda adere ao cobre.

Parece algo mágico, não é? Não, não é bem assim.  Precisa dar uma apertada no fio, esfregar a ponta do ferro de solda e a temperatura tem que estar um pouquinho acima do usual.  Também que o esmalte não queima ou recolhe assim tão limpo, fica lixo do esmalte sobre o cobre.

Dá um pouco de trabalho, mas ainda assim compensa usa-los ao invés de fios com ponta descascada, etc.

Esse fio chama-se “Magnetic Wire Solder” ou “Magnetic Wire Solderable”.  Existe à venda em diversos lugares, principalmente no eBay, é só um tiquinho mais caro mais caro que o fio esmaltado comum.

Bem, até ai tudo bem.

Mas para facilitar o uso e solda desse fio, eu montei uma ferramentinha que permite aplicar o fio com melhor precisão.  Isso até existe comercialmente para vender, e chama-se “Wiring Pen”, que em português se traduz para “Caneta de Passar Fio”.

Eu fiz a minha, porque as comerciais são de plástico injetado e custam mais de $30, um roubo e tanto.

Usei o corpo de canetas um pouquinho mais grossas, removi o interior, fiz um furinho to topo para passar o fio para dentro dela, na ponta colei com durepoxy agulhas de injeção com a ponta serrada, usei um clip prendedor de papel, uma bucha de parede e um carretel de linha de máquina de costura, uma capinha plástica de ponta de ferro de estante sobre a ponta da bucha, para evitar o carretel sair.  Beleza… Funciona muito bem.   O carretel não pode ficar soldo na bucha, e não fica, o que evita do fio desenrolar todo. As fotos abaixo explicam melhor.

DSCF0713s

Uma pequena entortada no Clip de papel para que ele vestisse melhor sobre o corpo da caneta, veja nas laterais.  Na orelha do clip, entrou a bucha plástica de parede, sobre ela o carretel, depois as duas orelhas do clip de papel são levantadas e o terminador plástico segura tudo no lugar.  Um carretel desses de máquina de costura cabe diversos metros de fio, isso dá para meses de brincadeira.

DSCF0724s

Elástico em volta dos bracinhos do clip de papel para manter as orelhas fechadas, sim ou não, o elástico prende melhor o carretel e realmente evita dele girar fácil.  As vezes você precisa do fio sair com mais dificuldade lá na ponta para poder rotear ele melhor no protótipo.  Eu também escrevi com caneta permanente o número AWG do fio no corpo do clip.  Na prática o fio 34 é mais dificil de usar, e o 27 é um tiquinho grosso demais, mas para barramentos de tensão e terra o 27 vai bem e dá mais ‘segurança’ mental.  O AWG 31 é ‘pau-prá-toda-obra’ e é o que mais uso.

DSCF0727s

Aqui dá para ver as pontas das agulhas de injeção.  Usei duas medidas diferentes de agulhas, veja que o fio mais fino usa uma agulha mais fina.  Não é tão importante, mas eu as tinha à mão.  Infelizmente para passar o fio pela agulha tem que desmontar a caneta, então eu tomo cuidado de não deixar o fio entrar de volta.

Ferramenta Agulha

Recentemente comprei diversos pacotes de agulhas para as máquinas de costura, overlock e overstitch da patroa, e vieram 40 agulhas erradas, muito espessas (120/19) e recobertas por titanium. Nenhum tipo de costura que ela faz usará essas agulhas gigantes e próprias para costurar couro de 4mm ou mais, então ficaram comigo.

Rapidamente as converti em uso na bancada. Sempre tem uso, raspar algo, limpar PCI suja, furar, cutucar ou enxotar visita chata.

Inicialmente fiz usando uma seringa plástica, ficou bom, principalmente porque a agulha ficou retractil. Depois procurei uma caneta plástica adequada, mas todas tem o corpo muito fino, ruim de manusear, então encontrei os markers permanente secos… “quem guarda o que não presta, tem o que precisa”.

Uso o mesmo tipo de seringa para graxas de todo tipo a usar em mecanismos pequenos. Também uso seringa para solda em fio, enrolado dentro dela, fica fácil de segurar ao soldar. Pretendo também fabricar um “wiring pen” com esse mesmo corpo de caneta, para rotear PCI prototipo usando os fios esmaltados soldáveis que chegarão essa semana, AWG de 26 a 34.

Para quem não sabe, existem fios esmaltados que a capa isolante derrete na ponta do soldador, permitindo soldar sem descasca-la. Isso é muito prático para reparar PCI ou fabricar protótipos. Aquele japonezinho maluco que fez um zilhão de fios assim, postado aqui há meses atrás, usa esse tipo de canetinha e fio.

Alguém pode perguntar: mas por que então não usar a seringa com própria agulha de injeção? Porque é muito frágil e dobra… agulha de máquina de costura, principalmente essa ai com capa de titanium… nem a pau, a ponta não entorta nem por decreto.

O que é aquela coisa azul enrolada no corpo da agulha, próximo ao embolo da seringa? fita isolante. Pensei em evoluir para epoxy… mas funcionou tão bem, não desliza sozinho e mantém a agulha firme. Tirei a escrita da caneta (Rekord) com acetona e marquei com fita isolante azul para saber que não é mais uma caneta.

 

imageb1

imageb2

imageb3

Timer Fotografico AVR

O Rodrigo Pinheiro Matias, colega da PICLISTBR, teve a idéia de criar um Temporizador Fotográfico usando um AVR AtMega8, e escreveu o código na linguagem C.

Ele fez o layout da plaquinha PCI e lançou o trabalho dele na PICLISTBR para comentários e sugestões. Eu olhei o código do programa em C que ele escreveu, e literalmente achei muito complicado para pouca coisa. De verdade a programação C é assim mesmo. Para coisas pequenas ela fica muito grande. Então eu resolvi ajudar o Rodrigo, e me divertir ao mesmo tempo, e prometi a ele reescrever o firmware desse mesmo temporizador, com exatamente as mesmas funções, em Assembly.

Esse temporizador permite programar de 1 a 99 minutos, para tal utiliza tres teclas, uma para incrementar o tempo selecionado em minutos, outra para decrementar e uma terceira para dar inicio ao processo do temporizador, acionar o relay e decrementar os minutos.

Ao decrementar até zero, o relay é desligado e o LED pisca indefinamente para informar o usuário. Claro que a terceira tecla não faz nada se o temporizador está com zero minutos programado. Se o contador já estiver no limite de 99 minutos, a tecla #1  não incrementará se pressionada, e piscará o LED tres vezes como informação de limite. O mesmo para a tecla #2 que decrementa, se o contador estiver com zero, essa tecla não irá decrementar, e piscará o LED tres vezes para informar o usuário do limite. Não apertei muito o código, e ocupou em torno de 240 bytes na Flash, uma ninharia.

Abaixo o texto do código em assembly, e ao final o link para fazer download do arquivo hex a gravar na Flash do AtMega8. Fuses são H-Fuse:D9, L-Fuse:64, que basicamente seleciona Clock interno de 8MHz.

Essa versão de software (1.0) roda na mesma plaquinha desenhada pelo Rodrigo.A próxima versão, 7.1, permitirá incluir dois displays de sete segmentos para mostrar o valor do timer e nessa nova versão, haverá mudança de pinos para as teclas e LED, e não rodará na plaquinha atual.

Update: 28 Março 2014
O codigo fonte abaixo já é o novo, com 2 displays 7 Segmentos, e 398 bytes de código. Leia no texto abaixo a forma de uso e funcionamento.

IDE para AVRs

.

Considerando que a versão 4.19 do AVRStudio é a mais estável, menor e mais ágil de todas as existentes, e considerando que o AVRStudio é a ferramenta mais completa existente para programar AVRs em Assembly ou C, e também para simular (que permite ver o conteudo de registradores, status, cpu, contar instruções, medir tempo de execução, etc) e programar os chips, eu diria que não existe nada melhor para tal.

Porém, com o tempo eu fui descobrindo que, se não necessitar de simuladores ou debuggers sofisticados, certas associações de softwares independentes podem resultar numa solução rápida e que, não substitui o AVRStudio, porém dentro de certo ponto de vista é bem mais funcional. Eu tenho usado uma solução assim. Ao longo do tempo fui otimizando essa solução, e parece que, a que eu uso atualmente é a mais viável, ao menos para o meu uso, e da forma que eu desenvolvo meus softwares. Note também, que eu uso isso no Windows8 64 bits, portanto irá rodar em qualquer ambiente Windows, XP, 7, etc. Abaixo, os softwares necessários para montar essa IDE, faça download e instale os links em vermelho.

.

Programmers Notepad 2

O link direto do download do instalador da versão 2.2:
http://www.ustr.net/avrfiles/pn2342350.exe

link: http://www.pnotepad.org/

Esse é o editor de texto, que uso como editor dos arquivos assembly. Ele permite configurar macros que irão disparar o assemblador e o programador do AVR, num único shortcut do teclado. Ele também possui uma tela de mensagens embutida, onde o assemblador irá mostrar o resultado da compilação, possiveis erros de digitação ou código, e também o resultado da gravação do AVR via ISP na porta USB do PC. Mais abaixo eu mostro como configurar as macros dele.

.

AVR_ASM2

Link para download:
http://www.ustr.net/avrfiles/avrasm2.exe

Esse é o assemblador AVR para o arquivos escritos na linguagem assembly no Programmers Notepad 2. Ele é chamado por uma linha de comando, diretamente de uma macro dentro do editor. Ele pode também ser chamado por uma linha de comando na tela DOS de “command” do Windows. O AVRASM2.EXE é o mesmo assemblador usado internamente no AVRStudio 4.19, mas graças à Atmel te-lo feito avulso, você pode usa-lo independentemente.

Aqui o link da Atmel com instruções de uso, syntax e opções: Aqui o link de um arquivo PDF com mais instruções sobre o assemblador e uso.

.

AVRDUDE

Link para download
http://www.ustr.net/avrfiles/avrdude61.zip

Esse é o programa interface que lê, grava, muda fuses, etc, nos AVRs via porta USB no PC e a plaquinha USBASP, via comunicação ISP (6 pinos) nos AVRs.

.

USBASP

Essa plaquinha, abaixo, conhecida como USBASP, pode ser comprada no eBay, DX, AliExpress ou outro local, por valores abaixo de $4, e quase sempre com frete grátis para o Brasil ou outro local.

A pláquinha acima hoje é produzida aos borbulhões na China e vendida para todo lado, por preço que acaba sendo até mais barato que comprar só o AVR nela soldado, e ainda vem com cabo multivias de 10 fios e dois conectores. Uma ponta do cabo vai conectado na USBASP e a outra é conectado na PCI ou protoboard, de 10 pinos conectados aos 6 pinos do AVR a programar.

Faça download do driver para Windows aqui:
www.ustr.net/avrfiles/usbasp_windrvr.rar

Um AVR requer seis pinos para programa-lo via ISP. Existe um padrão de seis fios e dez fios, sendo que no de dez fios/pinos, quatro ficam inutilizados. Abaixo a imagem superior do conector na PCI, 10 e 6 pinos. O pino #2 de ambos, é +5V, que é a alimentação VCC da placa onde esse conector está soldado. Pode-se usar esses +5V para alimentar o circuito do outro lado do cabo, mas não é recomendado, pois cada circuito deve possuir alimentação própria. O conector de 10 pinos na trazeira do USBASP possui +5Vcc nesse pino, e é proveniente do conector USB do PC. Essa tensão ali existente não possui muita capacidade de corrente e deve-se alimentar com +5V independente o circuito do AVR a ser programado, para evitar sobrecarga de corrente no USB do PC. Claro que, sabendo-se que se o AVR sendo programado e seu circuito em volta não consumir mais de 50 ou 60mA, pode-se conectar à essa tensão sem problemas.

Algumas plaquinhas USBASP como a acima, possuem jumper para selecionar +5V ou +3.3V nesse pino #2, ambas as tensões são provenientes do USB do PC.

É muito fácil confundir o que é o pino #1 com o pino #2, pois esse conector por cima é invertido por baixo e o cabo inverte tudo ainda mais. Para tirar duvidas, sempre olhe a solda do conector e procure pelo pino do canto que está soldado ao plano de terra, esse será pino #10 ou #6. Alguns conectores tem soldados em curto para terra os pinos 4, 6, 8 e 10, para promover melhor redução de ruido no cabo.

Caso no seu circuito você queira usar ISP de 6 pinos (eu o faço) terá que sempre usar um pequeno adaptador de 10 para 6 pinos. Esse adaptador pode ser feito em casa, eu fiz alguns, mas também comprei alguns do eBay, pois custam menos de $3 e são mais práticos.

10 Pin to 6 Pin Adapter Board for AVRISP USBASP STK500 High Quality

O esquemático original da USBASP e software é do alemão Thomas Fischl, website original.

Para poder usar a plaquinha USBASP, encontrada à venda no eBay, DX e AliExpress por menos de $4 dólares, deve-se instalar o driver de software para o Windows, para que esse reconheça a tal placa conectada em porta USB. Notar que no Windows8 se tem que desabilitar o bloqueio de instalação de drivers sem assinatura válida, caso contrário a USBASP não é instalada na lista de dispositivos do Windows. Isso é feito com uma pre-seleção e reboot, link do procedimento.

 

.

KHAZAMA

Khazama é o sobrenome do Iraniano que escreveu essa aplicação para o Windows. Ela é pequena e funciona muito bem, permite lêr, gravar (flash e/ou eeprom e fuses) num AVR, usando um USBASP. A interface é gráfica, portanto não dá para automatiza-la dentro do Programmer’s Notepad 2, via macro. Mas ela serve muito bem para operações rapidinhas que não necessitem carregaro Programmers Notepad, etc. Com ela, dá para lêr e ver o conteudo da Flash e Eeprom, no buffer do Khazama, fácil e simples. Considero um programa gráfico dos melhores existentes, e o uso frequentemente.

Link:
http://www.ustr.net/avrfiles/KhazamaAVRProgrammer.rar

screenshot.70

… breve interrupção de digitação para trabalhar e correr atrás do din-din. … hoje à noite continuo.

Protocolo RC-5 Infravermelho no AVR

Abaixo o código em assembly mais enxuto para receber RC-5 no AVR (AtMega8) rodando com clock interno de 8MHz.    Esse circuito pode ser implementado num chip pequeno como um AtTiny13, porque mesmo com os 8 pinos, usando dois para +VCC e Terra e um para a entrada do Modulo receptor de IR, ainda sobrariam 5 pinos para mostrar até 32 comandos do Controle Remoto. 

O Código do RC-5 está contido a partir do label IRC5A, e ocupa somente 19 instruções, recebendo o comando do controle remoto e postando nos pinos da porta B.  No caso de usar o AtTiny teria que mudar os pinos de porta utilizados aqui.  Somente 19 instruções, até hoje eu não vi nenhum outro código para decodificar RC-5 que tenha 19 instruções ou menos.

Multiplicação em Binário

September 09, 2013

Okay, para entender multiplicação em binário é necessário primeiro entender adição e subtração em binário, e sobre isso eu já escrevi no post anterior.  Se você tem duvidas sobre esse assunto, recomendo ler e entender sobre isso antes de mergulhar aqui.

Primeiro vale definir que aqui usaremos 10 bits, como os dez dedos das mãos e daremos a esses bits os nomes de Bit1, Bt2, até Bit10, sendo o Bit1 o bit mais à direita, e o Bit10 o mais à esquerda.  O Bit1 terá o valor de 1, o Bit2 terá valor 2, o Bit3 terá valor 4, e assim por diante, dobrando o valor, até que o Bit10 terá o valor 512. Todos os bits levantados somarão o valor 1023, todos os bits baixados = 0.

BIT10  BIT9  BIT8  BIT7  BIT6  BIT5  BIT4  BIT3  BIT2  BIT1
512    256   128   64    32    16     8     4     2     1

Para iniciar, vou rever aqui com vocês como se faz uma multiplicação tradicional em decimal no papel e lápis.

Vamos multiplicar 25 x 76

        2  5
        7  6
        –  -     Multiplica-se Cruzado
        3  0     = Cinco vezes Seis
     3  5  -     = Cinco vezes Sete
     1  2  -     = Dois vezes Seis
  1  4  -  -     = Dois vezes Sete
  –  -  -  -     Soma-se os resultados individuais
  1  9  0  0     Resultado

Okay, explicarei de outra maneira.

Veja, em decimal os numeros vão de zero a 9, portanto para a mesma posição (digito) podem ocorrer dez variações do valor.  Eu quero dizer que ao ter o número 35, para a mesma posição do “5″ pode-se ter de 30 a 39, portanto dez variações no dígito das unidades.

Em binário não é assim, é mais simples, pois binário só entender ZERO e UM, portanto para cada posição de bit, só teremos duas possíveis variações de valor.  O binário  ”10″ (2 em decimal) pode variar o bit mais a direita entre zero e um, portanto a “outra” combinação seria “11″ (3 em decimal) e só.

Então vejamos a outra maneira de multiplicar em decimal que imediatamente vai fazer você entender a multiplicação em binário.

325 x 76  (em decimal)

Okay, sem multiplicar, só somando.  Primeiro vamos somar 5 vezes o número 76, e depois 2 vezes o número 760, e 3 vezes 7600.   Mas de onde vieram o zero do 760 e os dois zeros do 7600? vieram do Vinte  e do Trezentos, olhe bem, 325 é Trezentos + Vinte + Cinco.   Deslocar o 76 uma vez para a esquerda e transforma-lo em 760 e soma-lo 2 vezes, é o mesmo que somar vinte vezes o 76.

Uma outra forma de entender é pensar assim:  Trezentos e Vinte e Cinco é 300 + 20 + 5.   Observe os zeros do trezentos e o zero do vinte.

Tanto faz multiplicar 325 x 76, ou (300 x 76) + (20 x 76) + (5 x 76), certo?
e também é o mesmo que passar os zeros para o 76, e ficaria assim:
(3 x 7600) + (2 x 760) + (5 x 76), correto?

Então seria assim:

Percebeu que eu sempre uso o valor “76″ para as unidades (5), “760″ para as dezenas (2), e “7699″ para as centenas (3)?

Ai está o truque da multiplicação em binário.  Acima, em decimal, terá que somar tantas vezes quanto for o número da unidade, dezena, centena, milhar, etc, e pode ir de zero a nove.   Em binário só existem duas combinações, zero e um.  Portanto, se for zero não soma, se for um soma e pronto, acabou para aquela posição de bit.  Abaixo entenderá com mais detalhes.

Treze em decimal é  0x0D em hexadecimal, ou 0b1101 em binário

Cinco em decimal é 0×05 em hexadecimal, ou 0b0101 em binário

Então vamos multiplicar 0x0D x 0×05

Assim como na multiplicação em decimal, note que as multiplicações individuais do cruzado se deslocam para a esquerda sempre que se multiplica um digito que está mais para a esquerda, na verdade se escreve o resultado da multiplicação exatamente na mesma coluna que se está multiplicando.

No processo binário é muito parecido, porém se desloca toda a linha superior ao observar cada bit da linha inferior, e se esse bit da linha inferior for um (1) soma-se a linha superior ao resultado, caso seja zero, continua-se movendo a linha superior para a esquerda até acabarem os bits da linha inferior.

Lembre-se de passar os zeros do 300 e do 20 para o 76, aqui abaixo é o mesmo, conforme vamos tirando bits do multiplicador (vemelho), estamos enfiando zeros na Linha Superior (azul).

Veja:

[raw]

Linha Superior Multiplicador
- – - – 1 1 0 1 0 1 0 1
Olhe o ultimo bit à direita do Multiplicador acima (em vermelho), se for um (1), soma-se a Linha Superior ao  Resultado. Desloca-se a linha superior uma posição para à esquerda, enfia-se um zero à direita, desloca-se o Multiplicador (acima) um bit à direita, ou seja, elimina-se o bit mais à direita do Multiplicador.  Nesse caso, o ultimo bit à direita do Multiplicador acima é “1″, então os bits da Linha Superior “1101″ são adicionados ao Resultado.
- – - 1 1 0 1 0 0 1 0
Olhe o ultimo bit à direita do Multiplicador acima (em vermelho), como é zero (0), os bits da Linha Superior “11010″ não será adicionado ao Resultado.  Porém a Linha Superior será deslocada um bit à esquerda, e o ultimo bit to Multiplicador (acima em vermelho) será eliminado.
- – 1 1 0 1 0 0 0 1
Olhe o ultimo bit à direita do Multiplicador acima (em vermelho), como é um (1), os bits da Linha Superior “110100″ (com os dois ultimos bits em azul) serão adicionados ao Resultado.  Então a Linha Superior será deslocada um bit à esquerda, e o ultimo bit to Multiplicador (acima em vermelho) será eliminado.
- 1 1 0 1 0 0 0 0
Olhe o ultimo bit à direita do Multiplicador acima (em vermelho), como é zero (0), nada será adicionado ao Resultado, e como ele é o último bit do Multiplicador, a operação está encerrada e o Resultado é o valor da multiplicação entre a Linha Superior e o Multiplicador.
- – - – 1 1 0 1                                                                                                                                                                                                                                      À esquerda as somas ao Resultado das quatro operações acima.  Os bits (1) do Resultado são 1 e 64, que somados formam 65 em decimal, portanto está correta a multiplicação.
- – - 0 0 0 0 0
- – 1 1 0 1 0 0
- 0 0 0 0 0 0 0
- – - – - – - – -
- 0 1 0 0 0 0 1

[/raw]

Percebeu como é simples e fácil?
Basta ir olhando para os bits da linha inferior.  Para cada bit que você olha mais para a esquerda, enfia um zero ao final da linha superior.  Se o bit que olhou na linha inferior é 1, some a linha superior no resultado.  É só isso.

Ao fazer isso em Assembly, usa-se deslocar para a direita a linha de baixo, se ocorreu “carry bit”, ou seja, o bit mais à direita da linha de baixo era “1″, e o carry bit é “1″, então soma-se a linha superior ao registrador do resultado.  Se o bit mais à direita da linha de baixo era “0″ e agora o carry bit é zero então não se soma nada ao resultado.  Então shifta-se toda a linha superior um bit à esquerda, independente dela ter sido somada ao resultado ou não.   Repete-se essa sequência até a linha de baixo só ter zeros.

Pronto, o registrador de resultados já terá o valor da multiplicação.  Veja que essa técnica funciona para qualquer quantiadade de bits ou bytes, basta ter espaço para shiftar para a esquerda a linha superior e ter espaço no registrador de resultados para ir fazendo as somas.

Soma e Subtração em Binário

Atendendo a um amigo que pediu para explicar como multiplicar e dividir em assembly.

Antes de mais nada é importante entender muito bem o sistema binário e hexadecimal, e vou explicar primeiro a somar e subtrair em binário, no próximo post veremos multiplicação e no outro divisão.

Pense nos 5 dedos da sua mão direita, com eles você pode contar de 1 a 5, é o que aprendeu na escola. Isso significa que pode contar 5 coisas, digamos, bananas.  Na verdade, consegue contar 6, se imaginar que com todos os dedos fechados pode significar a sexta ou a primeira banana.   Mas isso é só para dar partida na sua cabeça, tudo pode ser diferente.

Bem, então pense que eu posso fazer você contar 32 bananas só com os 5 dedos da mão direita. Opa, como é que é? Pois é, essa é a forma de contagem binária.

Vamos aproveitar para dar nomes e valores aos dedos da mão direita.

Mão direita – Nome do Dedo Valor do Dedo
Mínimo 1
Anelar 2
Médio 4
Indicador16 8
Polegar 16

Hmmm, veja que a partir do mínimo que vale “1″, os valores dos outros dedos são sempre o dobro do anterior.  Significa que ao levantar o polegar e fazer o “sinal de positivo”, está mostrando o numero 16.

Ao fazer o “V” de vitória com o indicador e médio, está mostrando 12, que é a soma deles (8 e 4).

Ao fechar o polegar e levantar os outros 4 dedos (como quem mostra o numero 4), em binário estará mostrando 15, que é a soma de 1+2+4+8.

Interessante, não?

Veja, o numero decimal 7 é representado pelos tres dedos, mínimo, anelar e médio. Para subtrair 2, basta fechar o dedo anelar (que vale 2) e ver o que restou levantado, o médio (4) e o mínimo (1), cuja soma é 5.

Bacana, não é? Pois é.  Isso é binário e pode-se fazer somas, subtrações e até multiplicações e divisões.

Quer ver? Faça o “V” de vitória, indicador e médio, que é 12 (8+4).
Dividir por 2 ?  basta mover esse “V” um dedo para a direita, vai levantar o médio e o anelar.  Quanto valem? 2 + 4 = 6… ora, 12 / 2 = 6.

Volte novamente a fazer o “V” da vitória, que é 12.  Agora vamos dividir por 4, ora, dividir por 4 requer deslocar o “V” duas posições para a direita, vai então fazer o “V” com o anelar e o mínimo.  Vale quanto? 1+2 =3

Ahaa… 12 / 4 = 3

Simples?  Pois é, então multiplicação é o contrário, ao multiplicar por 2 desloca o V para a esquerda um dedo, multiplicar por 4, desloca o V dois dedos, e por ai vai.

Hmmm, mas só dá para contar até 31 com uma mão ?  Sim, se incluir o zero (todos os dedos baixos) conta-se 32 movimentos.

Mas se usar a mão esquerda junto com a direita, sendo o polegar da esquerda então valendo o dobro do polegar da direita, 32, então o dedo mínimo da mão esquerda vai valer o máximo de todos os dedos, irá valer 512, vejamos:

DICA: Você pode até fazer anéis de papel e vesti-los nos dedos, cada um com o valor acima, para entender direitinho essa coisa de “binário”.

Uau, então se levantar só os dois polegares, estarei mostrando 32 + 16 = 48  em binário?  Sim, com só dois dedos, mostrará 48.

Note que o mínimo direito só vale “1″, mas é ele quem determina se a contagem binária dos dedos será “par” ou “impar”… até ele que vale menos é super importante.  Por outro lado, o mínimo esquerdo é o que tem mais valor, 512, por estar mais à esquerda de todos os outros dedos.

E se levantar os cinco dedos direitos, como dizendo “olá” para o amigo, está mostrando 16+8+4+2+1 = 31… e se levantar todos os dedos só da mão esquerda, estará mostrando 512 + 256+ 128 + 64 + 32 = 992, e se levantar todos os dedos das duas mãos, estará mostrando 1023.

Portanto, “Olá!!!” com a mão direita… 31, com a mão esquerda… 992

Okay, você está curioso.  E se a pessoa não tiver o mínimo da mão esquerda? bem, nesse caso ele só contará até 511, e só contará até a metade dos 1023 e o apelido “meia conta” poderá grudar nele.

Se estiver com todos os dedos levantados e deslocar isso um dedo para a direita, o que ocorre?
Obviamente que o dedo mínimo esquerdo (512) vai baixar, porque não existe nenhum dedo à esquerda dele para ser copiado para ele, mas todos os outros dedos movem para a direita, e todos continuarão levantados.  O que acontece com o mínimo direito (1) ao ser deslocado para a direita? ele some, porque não existe nenhum dedo à direita dele para copia-lo.   Então todos os dedos permanecem levantados, exceto o mínimo esquerdo (512), e agora temos 9 dedos levantados, que somando valem 511, exatamente o mesmo de todos os 10 dedos (1023) menos o 512 do mínimo da esquerda que baixou.

Opa, 511 é um a menos do valor 512 do mínimo esquerdo.  Certo, pois se somar um nessa conta dos nove dedos levantados, não existe lugar para esse “um” entrar e ele corre e levanta o mínimo esquerdo e derruba todos os 9 dedos que estavam lentados e a soma passa a ser 511+1 = 512.

Vamos esquecer os dedos e ver da forma binária, mas vamos só usar 4 bits (bits=dedos), e vamos dar nomes à esses bits, 8, 4, 2, 1.

 Bit  8  4  2  1
      — – — –
      0  1  0  0  < Valor decimal 4, só o bit 4 está levantado
      1  0  1  1  < Valor decimal 11, 8 + 2 + 1
      1  0  0  0  < Valor decimal 0, nenhum bit levantado
      1  1  1  1  < valor decimal 15, todos os bits levantados

Que tal então darmos nomes diferentes para cada uma dessas combinações?  Veja, são 16 combinações e uma boa parte delas é conhecida, de zero a nove, mas ainda existem a 11, 12, 13, 14 e 15.   Para facilitar vamos nomear essas combinações acima de nove em A, B, C, D, E, F.   Então vai ficar assim:

HEXADECIMAL
8 4 2 1 < bits
– - – -
0 0 0 0 = 0
0 0 0 1 = 1
0 0 1 0 = 2
0 0 1 1 = 3
0 1 0 0 = 4
0 1 0 1 = 5
0 1 1 0 = 6
0 1 1 1 = 7
1 0 0 0 = 8
1 0 0 1 = 9
1 0 1 0 = A
1 0 1 1 = B
1 1 0 0 = C
1 1 0 1 = D
1 1 1 0 = E
1 1 1 1 = F

Muito bem, agora temos o nome desses numeros de zero a 15, que é de zero a F.

Parabéns, acabou de parender HEXADECIMAL, uma forma de contar de zero a 15 (F) com quatro bits.
Só para fixar, “A” + 1 é o que? é “B”, e 7 + 3 o que é? não é 10, é “A”, lembre-se, estamos falando de hexadecimal, e não mais decimal, okay?

A forma usual de representar um valor qualquer em hexadecimal é incluindo “0x“, ou “$” atrás do numero:

“5″ em hexadecimal pode ser representado assim:
0×5 ou 0×05 ou $5 ou $05

“5″ em binário é “0101″ e deve ser representado com “0b” atrás dos bits:
0b0101

“5″ em decimal pode ser representado basicamente como “5″, mas para evitar confusão usaremos “0d” atrás do numero:
0d05

Ah sim, “atrás” do número é do lado esquerdo, também chamado de “prefixo”, pois o que vem a frente é à direita do número, chamado de “sufixo”.

Okay, eu também não concordo com isso, mas já fui severamente acusado de usar isso errado.

Observe a combinação de bits, olhe o “E” e olhe o “7″.  Se deslocar o 7 um bit para a esquerda, ele vira “E”, e se deslocar o “C” uma vez para a direita? vira 6.  E se deslocar mais uma vez para a direita? vira 3.  E se deslocar mais uma vez para a direita? vira 1.  Ué? 3 dividido por 2 resulta em 1?  Pois é, não tem como representar meio bit, pois o certo seria 1,5 mas não dá.  Binário só conta inteiros, a menos que se defina isso diferente, verá isso mais a frente.

 Parabéns, já descobriu como dividir e multiplicar em binário…

 Opa, mas e se eu quiser multiplicar por 3 e não só por 2, 4, 8, etc?

O segredo está em somar resultados parciais.  Você faz o mesmo em decimal no papel e lápis. Mas isso veremos no próximo post desse blog, Multiplicando e Dividindo em Binário.

SOMA EM BINÁRIO
8 4 2 1  <–  Bits0 1 1 0  = 6
0 0 0 1  = 1 +
——-

Okay, mas como somamos Bits?  É fácil, basta seguir uma regrinha simples que só usa “0″ e “1″.

0  +  0  =  0
0  +  1  =  1
1  +  0  =  1
1  +  1  =  10

Oooopa, 1+1 = 10? não seria 2 ?  Bem, seria “2” se fosse em decimal, mas aqui estamos somando em binário e binário só tem zeros e uns.  Lembre-se agora cada bit só pode ser representado por “0″ ou “1″. Lembre-se dos dedos levantados ou baixados.  

Para facilitar pense assim:

Binário     Decimal

00    =    0
01    =    1
10    =    2
11    =    3

Então vamos fazer a tal soma ai acima:

8 4 2 1  <–  Bits
——- 
0 1 1 0  = 6 
0 0 0 1  = 1 + 
- – - - 
      1 = 0 + 1 
    1   = 1 + 0
  1     = 1 + 0 
0       = 0 + 0 
- – - – baixando e somando tudo 
0 1 1 1 = 7

Esse foi fácil, vamos complicar?

8 4 2 1  <–  Bits 
——- 
0 1 1 0  = 6    (Bits da Linha de Cima)
0 0 1 0  = 2 +  (Bits da Linha de Baixo)
- – - –  
      0 = 0 + 0  (Bit1C + Bit1B)
  1 0   = 1 + 1  (Bit2C + Bit2B) ocorreu “vai um”
  1     = 1 + 0  (Bit4C + Bit4B)
0       = 0 + 0  (Bit8C + Bit8B)
- – - – baixando e somando tudo 
1 0 0 0 = 8

Ooopa, que raios é Bit4C ???

Vamos fazer uma convenção aqui.

A soma aí acima tem 4 bits, 8, 4, 2 e 1, vamos chamar cada coluna dessa de Bit8 Bit4 Bit2 e Bit1. Como estamos lidando com duas linhas, vamos chama-las de linha de cima e linha de baixo, então teremos Bit8C, Bit4C, Bit2C e Bit1C (os quatro bits de cima), e BIt8B, Bit4B, Bit2B, Bit1B (os quatro bits de baixo), e também teremos os quatro bits do resultado, Bit8R, Bit4R, Bit2R e Bit1R.
Se fossemos falar em voz alta a soma acima, seria assim, começando pela direita para a esquerda:

(Bit1C + Bit1B) Zero mais Zero igual a zero, (Bit2C + Bit2B) um mais um é igual a zero e “vai um” à esquerda, esse “vai um” é somado com os Bit4C + Bit4B, então, UM (que foi), mais um (Bit4C), mais zero (Bit4B), igual a zero e “vai um” à esquerda, que quando somado com os zeros (Bit8C + Bit8B); o UM (que foi), mais zero, mais zero, é UM, que aparece embaixo como Bit8R.

Soma em binário é bem simples, basta pegar a idéia.

SUBTRAÇÃO

Subtração é exatamente o inverso, vejamos:

8 4 2 1  <–  Bits
——-
0 1 1 0  = 6
0 0 0 1  = 1 –
- – - -

Vamos olhar como se olha em subtrair em decimal.  O Bit1B deverá ser subtraido do Bit1C, mas não dá para subtrair um de zero, então empresta-se o próximo bit à esquerda na linha de cima (Bit2C), então estaríamos subtraindo o valor “1″ (Bit1B) dos dois bits valor “1″ e “0″ (Bit2C Bit1C) da linha de cima, veja:

8 4 2 1  <–  Bits
——-
0 1 1 0  = 6
0 0 0 1  = 1 –
- – - -

Agora dá, pois “1 0” em binário, (Bit2C e Bit1C), significa “2″ em decimal, e o valor “1″ (Bit1B) pode ser subtraido.

Então binário “10 – 1″  é o que?
Veja, “10″ em binário é “2″ em decimal, certo?  Então, em decimal 2-1 = 1, okay?
Então, em binário “10 – 1″ = “1″
Ficou claro? para ir em frente isso TEM que ficar claro.

Então o valor binário “1”  (Bit1B) subtraindo do valor binário “10” (Bit2C Bit1C) resulta em valor binário “1″ (Bit1R), mas emprestou um da esquerda, lembre-se disso, exatamente como se faz em decimal, e fica assim:

8 4 2 1  <–  Bits
——-
0 1 1 0  = 6
0 0 0 1  = 1 –
- – - –
      1

Agora, o um emprestado é somado na nossa mente na posição certa, (Bit2B), ficando assim:

8 4 2 1  <–  Bits
——-
0 1 1 0  = 6
0 0 1 1  = 1 –
- – - –  
    0 1

Então, agora os dois Bit2C e Bit2B, valor binário “1“,  se anulam, e sobra zero em Bit2R.

O resto vai fácil, os dois bits4, 1 – 0 = 1 e zero – zero (os dois bits 8) = 0, o que resulta em:

8 4 2 1  <–  Bits
——-
0 1 1 0  = 6
0 0 0 1  = 1 –
- – - –  
0 1 0 1 = 5

Opa, 6 – 1 = 5.  Simples, não?

Bem, creio que deu para entender, no próximo post veremos multiplicação e divisão.

 

AVR Testador de Componentes

 

posted by Wagner Lipnharski @ 6:29pmFriday 8 March 2013.

Recentemente na Alemanha um colega desenvolveu um testador de transistores, usando um AtMega8 e seis resistores.  Ele media o ganho e polarização e indicava num LCD.  Semanas foram passando e ele percebeu que poderia também medir resistores, diodos, tensões, e inclusive capacitores.

A coisa cresceu e chamou a atenção de muita gente boa em software e hardware.  Foi criado um thread no forum alemão, e muita gente palpitou e a coisa evoluiu.  Como foi feito na modalidade “open source”, alguns outros colegas aproveitaram e fizeram as suas próprias alterações e implementações.  Surgindo então algumas diferentes versões na net.

Como não poderia deixar de ser, os chineses copiaram a idéia, produziram PCBs montados e os vendem no eBay por valor em torno de $15, o que no fundo é bom e barato.
Abaixo, fotos copiadas do eBay e da net, só para fins ilustrativos, o usuário montou a plaquinha do testador embaixo do LCD, e pode-se ver o teste do resistor de 10 ohms, ligado aos pinos 3 e 1 do conector de teste.
Acima e abaixo, a plaquinha visível, onde dá para ver todos os componentes usados, incluindo transistores que fazer o power on e auto power off após um certo de tempo de inatividade.  Esses componentes de controle de power podem ser eliminados, desde que se use uma chavinha on/off para desconectar a bateria de 9V.
O diagrama desse testador é bem simples, veja a imagem abaixo e o link para o arquivo PDF do diagrama expandido.  Veja que o lado esquerdo contém os transistores e componentes da seção de power on/off que podem ser eliminadas, coisa que explicarei mais a frente.

 

Clique aqui para diagrama expandido.

 

Esse final de semana continuo esse blog, postando versão de software mais moderna com mais funções, e mudanças no circuito, a permitir melhores e mais poderosas funções.  Aguarde.

Zoom na tela do Windows 7

As vezes é aquela letrinha, ou aquele desenho, figura, ou pequeno detalhe na imagem, que é muito pequena na tela do monitor, e que se gostaria de ver aumentada (zoom) na tela do Windows.

Nas versões antigas do Windows se usava algum utilitário especial para fazer o tal “zoom” da imagem.

Na versão Windows 7, por acidente, ontem eu descobri que isso é nativo, chama-se “Magnifier”.

Pressione Tecla Windows e a tecla “+” simultaneamente… aha!- então sucessivos “Tecla Windows” e “+” ou “-” para controlar a quantidade de zoom requerida.

Ao mesmo tempo irá abrir uma telinha pequena do (Magnifier Options) controle da “lupa”, para acabar com o zoom, clique o “X” daquela telinha, ou o “X” da tela do zoom.

O tamanho da tela do zoom pode ser manuseado, pode-se arrastar as laterais para qualquer tamanho, inclusive full-screen.

AtMega128 vs At89s8252 firmware

Pois é, estou desenvolvendo um firmware para uma máquina nova, usando o AtMega128 (Atmel) 16MHz com 256kBytes SRAM externa, 1MB Eeprom externa, etc, mas cada nova rotina deve ser testada, e para isso tem que gravar a Flash do AtMega toda vez… tá bom, a flash dele suporta 10 mil regravações, mas é um saco pensar nisso.   O AtMega128 que estou usando é um TQFP64 soldado na placa de teste, tá bom, é só dessoldar e meter outro, mas, é um saco pensar nisso.

Na época do 8051, usava-se eprom externa, que beleza.  Tinha que apagar, gravar, os cambal, demorava mais, até um dia eu fazer uma engenhoca com SRAM e um código minusculo em eprom.  Na verdade fiz um bootloader, na época que nem se pensava nesse nome.  O código mínimo fazia o 8051 rodar a UART na velocidade mais alta possível aceita pelo PC e esse despejava o novo código a rodar via serial, o 8051 recebia, gravava na SRAM externa e ao final ele mesmo virava um flip-flop e substituia a eprom pela SRAM e o novo código entrava no ar.   Muito rápido e funcional.

Não dá para fazer isso com os AtMega, exceto com um novo chip AVR32 que permite rodar código de memória externa.

A grande vantagem de usar o AtMega128, com 128kBytes de Flash, é que me deixa respirar.   Escrevendo tudo em assembly, é claro, pois *não existe* nenhuma outra linguagem de programação que se possa considerar séria… rsrs… eu sempre me preocupo em reduzir código, reutilizar código, se o mesmo trecho será usado mais de uma vez – passa a ser subrotina, etc e tal.  Essa “neura” consome tempo, e sempre se pensa em fazer um grande código com uma memória flash minuscula.  Não é à toa que tudo o que eu já escrevi na vida, e tem coisa muito complexa, nunca passou de 7kBytes.   Mas agora, com 128kBytes de flash à disposição, eu respiro e a coisa mudou de cor e cheiro, agora eu não mais me preocupo em economizar espaço, nem de Flash, nem de SRAM, e agora eu deito e rolo, me preocupo sim com velocidade de processamento, e tenho medido tudo para garantir que nada mantenha o AtMega ocupado fora do razoável.

Para ter uma idéia, ainda estou na dúvida sobre controlar os displays de sete segmentos, 20 no total, com refresh de 100Hz do AtMega, usando chips 74HC595 e transistores, ou o Max7219, que faz o serviço de refresh sozinho, mas, a rotina do refresh para o HC595 toma só 3.5 microsegundos. Isso é nada, certo?  Simples, eu não faço o bit-bang de mandar bit a bit, eu uso o dispositivo interno do AtMega chamado SPI, é um tipo de serial que pode transmitir a velocidades altíssimas, de no máximo Clock/2, ou seja, 16MHz/2 = 8Mbps, eu soco o byte no registrador da SPI e ela faz o serviço sujo.  Ou seja, 3.5us a cada 10ms, é um overhead de somente 0.035%, com isso garanto que o AtMega estará 99.965% do tempo livre para outras coisas.

Então, com a nova liberdade de flash do AtMega128, hoje eu entendo porque muita gente não gosta de Assembly e prefere C, pois não precisa se preocupar muito com a maneira que o código final ficará, o tamanho dele, a performance, etc.  É mais fácil, mais livre e menos preocupante.

Agora, veja só.   Esse novo firmware que estou escrevendo, parti do scratch, reescrevendo algo que foi escrito para o At89S8252, um 8051 da Atmel, em 1997.  Já está 98% pronto, escrevi em torno de 5 mil linhas de código em assembly e comentários, em menos de 2 semanas, e está ocupando menos de 5kBytes de código, contra os 7k do 8051.

É estranho, que mesmo não me preocupando em economizar espaço, o que escrevo hoje fica menor que o anterior, e então penso, ou o mesmo tipo de código para o 8051 ocupa mais memória que os AVRs, ou depois de 16 anos eu aprendi naturalmente a escrever de forma mais produtiva e inteligente.  Creio que ambos.

O custo de um AtMega128 compensa, pois passa-se a ter 6 e meia portas de 8 bits, (mais de 50 pinos de I/O), 8 ADCs, alguns podendo ser programados para entrada complementar, duas USARTs, PWM de pancada, 128k de Flash, 4k de SRAM interna, 4k de eeprom interna e permite usar SRAM ou I/Os externos como o 8051 o fazia, e acessa-se esses I/Os ou memória externa como uma extensão da interna, maravilha, além de uma carrada de outros dispositivos internos disponíveis.  Ou seja, o AtMega128 vem carregado com tudo que pode, exceto USB e Ethernet.

Eu iniciei nos AVRs brincando com o At90S2313, depois passei para o AtMega8 e naturalmente sai matando o AtMega128.

Tudo bem que uma série de novos chips da concorrência rodam a mais de 50MHz e possuem muita flash, principalmente os novos ARMs da vida.

Mas é muito gostoso trabalhar com um AVR rodando a 16MHz (16 MIPS) e ver a coisa zunir bits à torto e direito.

AVRibe, o protótipo fácil.

Olha só, eu faço muito teste em breadboard, desse tipo abaixo, barra simples, dupla, tripla, o que precisar.  Já fiz muita coisa nesses boards, digital, analógica, e principalmente com microcontroladores.

Mas sempre que uso um microcontrolador, comumente um AVR (Atmel) tipo At90S2313 ou AtMega8, ou AtMega48 ou AtMega88, é um tal de espeta o chip e liga todos os fios e conector enjambrado para fazer a conexão com a gravação ISP, antes de qualquer outra coisa.  Precisava algo mais prático.
Então resolvi fazer uma plaquinha “esperta” de desenvolvimento, que dou o nome de “AVRibe” (averibe) que contenha todo o necessário para o AVR rodar mesmo sem o uso do breadboard, e a idéia é espetar a “AVRibe” no breadboard só mesmo para ter os pinos de I/O e tensões ali disponíveis.
Ficou muito bom e recomendo algo assim para todos.
No do At90S2313 até instalei um segundo jumper de seleção de 5V e 3V, e para gerar os 3V soldei ao AVRibe uma bateria CR123A de 3V e que dura uma eternidade.   Eu quase não uso 3V, mas os displays de Celular da Nokia, tipo 3310, e alguns outros chips, como memória serial, etc, usam 3V e é um saco, então preparei o AVRibe do 2313 para tal.
Na plaquinha tem o soquete para o microcontrolador, cristal, regulador de 5V (7805), jumper de power, referência de 2.5V, LEDs indicativos e conector macho para o jack de uma simples fontezinha 9V 500mA.  Claro que não podia faltar os 6 pinos do conector ISP para conectar o gravador USBASP.
No AVRibe abaixo, com o AtMega8, a construção foi a mesma do At90S2313, porém sem a bateria de 3V, mas contendo jack de power, regulador 7805, uma referência de 2.5V (LM385-2V5), botão de reset e jumper de power (servindo como switch), capacitores, bobininha de filtro para o AVCC, etc.  Note que eu uso barrinha de pinos na parte de baixo, para espetar no breadboard, e uso dois pinos a mais, um de cada lado, para também levar o 2.5V de referência e o segundo para reforçar o terra, e obviamente 6 pinos para o ISP de gravação via USBASP.
Com certeza absoluta eu deveria ter feito isso há muito tempo atrás.
Ah sim, essa coisa branca enrolada nos fios coloridos, é a própria capa do cabinho de onde os fios foram retirados, que foi cortada helicoidalmente com uma tesolurinha, como descascar uma laranja… fica bom para juntar os fios, não fica?

Descascador de Fio – A missão !!!

Bem, um dia a gente passa por essas coisas.  Mesmo tendo alguns alicates descascadores de fio e usa-los, me apareceu uma dor no cotovelo direito, e que, ficou muito claro que foi causada pelo golpe, mesmo fraco, de descascar dezenas de fios para usar no breadboard.  O golpe no cotovelo é fraco, mas na minha idade isso causa problemas de nervos, musculos, junta, sei lá.

Resolvi comprar o que sempre quiz, um alicate que descasque o fio sozinho, na verdade eu queria um elétrico, mas seria muita frescura.  Só busco aliviar a dor no cotovelo e não quero outra.
Procurei, mas infelizmente todos os bons alicates custam muuuito caro, coisa de mais de 150 dólares… ui, doeu o cotovelo e o bolso.
Encontrei na Harbor Freight um baratinho de $9.99, mas que, obviamente, não funciona.  Mas tem tudo para funcionar, mas o projeto é uma desgraça e ele funciona ao contrário, morde demais onde não precisa e corta o fio, apesar de ser intitulado “automático”.
Okay, é automático para fios de maior bitola, fios 16 para baixo, mas para fios 22 e 24, esquece, corta e descasca ao contrário, uma zorra.
Já estava com o alicate no carro para devolver na HF, quando me deu o estalo de descobrir o problema e acertar a mecânica dele, pois afinal de contas ele tem todas as partes de um alicate bom e caro, mas faltam algumas coisas, como por exemplo, o ajuste de espessura de fio, e um melhor sistema de segurar o fio a descascar.
Fiquei brincando com ele e analisando o funcionamento, por uns 10 minutos e entendi o que estava faltando, bem como a forma de resolver.
Tá bom, precisou fazer dois furos na furadeira de coluna, arrancar uma peça fora que não serve para nada, e inserir dois parafusos e adaptar uma molinha.  Pronto, agora tem regulagem de espessura de fio, não mais corta o fio e não arregaça tudo, descasca igualzinho à um profissional bem mais caro.
Subo a foto e as mudanças amanhã.
Abaixo o original da HF:
Então eu fiz um furo inclinado no dedido à direita e inseri um parafuso limitador de curso, assim eu ajusto no parafuso a folga que eu quero na lamina descascadora e isso evita cortar o fio.   Eu deveria ter feito o furo 1 a 2mm para a esquerda, usei uma porquinha para aumentar a área de contato, mas ficou bom, veja abaixo.  Note que o ajuste dessa folga no parafuso é unicamente feito para fios finos, AWG24 ou menor, portanto, até daria para fazer um ajuste bom e colar o parafuso o parafuso em definitivo com Locktite ou algo assim.
Removi a chapinha de pressão atrás, fiz um outro furo no dedão oposto, inseri um parafusinho (allen preto), e usando o próprio parafuso que segurava a chapinha removida, prendi a tal mola que força o fechamento dos dedos.  Veja:
A mola não pode ser muito forte, mas o suficiente para que o dedo esquerdo segure firme o fio a descascar.   Então agora o parafuso amarelo do outro lado, o que supostamente deveria ajustar a tensão da ferramenta, perdeu o uso, só não o removi porque o dia que precisar dele ou da mola ou do pino interno, sei onde estão.
A mola está meio torta porque inicialmente pensei que ela estaria um pouco dura demais, e dei uma esticadinha de leve, esticou de mais… torci um tiquinho para dar a tensão correta.  O alicate ficou funcionando bem, mas um dia eu ainda vou mudar aqueles dentes do dedo esquerdo que seguram o fio, aquilo machuca a capa do fio, são muito afiados.
Wagner

AVR Assembly – Adição com valor imediato

posted by Wagner Lipnharski @ 1:58pm, Thursday 4 April 2013.

O instruçtion set da familia AVR não possui uma instrução de adição em um registrador com um valor imediato.

Por exemplo, você queira somar o valor fixo “6″ no registrador R18, pela lógica seria a instrução ADDI R14, 0×06, ou, ADI R14, 0×06, mas essa instrução não existe, mas existe a instrução ADD R18, Rnn. Para faze-la, se tem que carregar o valor 0×06 em outro registrador, por exemplo, LDI R20, 0×06, e então efetuar a soma ADD R18, R20.

Mas lembrar que somar +6 é o mesmo que subtrair -6, pois “menos com menos resulta em mais”.

Então, ADDI R18, 0×06 é quase o mesmo que SUBI R18, -0×06, e essa instrução existe.

Outro exemplo, 7+1 é o mesmo que 7-255, o resultado sempre será 8.

Lembrar que -6 também pode ser escrito como 0-6, ou seja, 0xFA.

Então, pode-se escrever SUBI R18, -6 ou SUBI R18, 0xFA.

A diferença entre a suposta ADDI R18, 6 e a SUBI R18, 0xFA, é o carry bit.
Se R18 tivesse um conteúdo de 3, ao somar 6 resultaria em 9, sem carry bit, pois o resultado da soma não ultrapassou 255 e não virou o carry bit. Mas ao subrair 254 (-6 ou 0xFA) de 3, o resultado será 2, 1, 0 -1 -2 -3 ….. até chegar ao 9 esperado, na verdade -9, e o sinal negativo ai é o carry bit que ficou ligado. É só ignorar o carry bit, ou prestar a atenção e tomar a atitude correta com relação ao carry bit.

A forma de fazer o carry bit assumir o valor correto após essa “soma” feita subtração, é comparar o resultado com o valor “6″ que deveria ter sido somado.

Então após a SUBI R18, -6, a instrução Compare Imediate “CPI R18, 6″ fará o serviço correto no carry bit. Veja, como o R18 antes da subtração era “3″, somando 6 ela irá para “9″, e o carry bit deveria estar desligado, mas devido à subtração de -6, ele ficou ligado “indevidamente” para o que se destina. Ao comparar o resultado de R18 com 6, e R18 é 9, o carry bit ficará baixo, pois 9 é maior que 6. Nessa comparação de R18 com 6, o carry bit só ficará ligado quando R18 for entre zero e cinco, ou seja, menor que o valor “6″, e isso só irá ocorrer após a suposta soma com “6″, se o R18 original fosse entre 0xF9 e 0xFF, e a suposta soma com 6 fosse efetivamente gerar o carry bit.

Então, para não usar um segundo registrador para fazer a soma imediata, pode-se sim usar o SUBI R18, -6 ou SUBI R18, 0xF9, mas para acertar o carry bit, em seguida teremos que usar CPI R18, 6.

Mas, necessitando fazer uma soma de valor constante (imediato) à um numero que use mais de 8 bits, ou seja, mais um byte, pode-se fazer toda a operação de soma usando o SUBI, e o SBCI (subtract com valor imediato e com carry) e com isso resolve tudo ao contrário e obtendo o valor certo ao final. Por exemplo 3 bytes, R18, R19 e R20, somando o valor 6 e que propagasse o valor nos 24 bits, considerando que R18 seja o byte de menor ordem, ficaria assim:

SUBI R18, -6
SBCI R19, -1
SBCI R20, -1

Ao subtrair -1 de um número qualquer, ele soma um, mas a instrução SBCI irá também considerar o carry bit na subtração. Se o carry bit estiver desligado, ele irá efetivamente subtrair -1, ou seja, somar 1 no registrador R19 ou R20, no exemplo acima. O carry bit só estará desligado se a instrução anterior efetivamente criaria um carry numa soma, tipo, somar 0x00FF + 0×0004 = 0×103, mas na subi ou sbci tal carry não existiria. Então, o SBCI Rxx, -1 irá só subtrair efetivamente -1 do registrador quando o carry bit estiver desligado, e ele só está desligado quando precisa propagar o carry que não ocorreu.

Ou seja, numa subtração de número negativo, o carry bit funciona ao contrário. Se o carry estiver desligado é porque precisa somar 1 no byte à esquerda, se o carry estiver ligado é porque não precisa somar 1.
Então, é o mesmo que seria (mas não existe):

ADI R18, 6
ADCI R19, 0
ADCI R20, 0

Onde o carry bit se propaga para os bytes de mais alta ordem, e transforma, por exemplo, 00|05|FE + 6 em 00|06|04.

A restrição é que devido à definição de bits nas instruções, a instrução SUBI e SBCI só funcionam nos registradores R16 a R31

AVR Assembly – Salto sem Label

posted by Wagner Lipnharski @ 3:07pmThursday 4 April 2013.

Em AVR Assembly, as vezes você precisa fazer o program counter saltar as próximas duas instruções, para frente ou para trás, muitas vezes usados em comparações, ou contadores de tempo, e obviamente precisa usar um label para dizer para onde o program counter tem que pular.

Exemplo de uma rotina simples perdedora de tempo.
        LDI   R20, 10
A1:   DEC  R20
        BRNE A1
        …
R20 é carregado com valor 10 e é decrementado até zero antes de ir em frente.  O “BRNE A1″, diz que se após decrementar R20 na instrução “DEC R20″ resultar em R20 diferente de zero, para saltar para o label A1, que está uma instrução acima e irá decrementar novamente, mantendo o loop até R20 chegar à zero, quando o BRNE não irá saltar e ir em frente.
Mas isso requer o label A1:  na instrução DEC R20.
As vezes o uso de labels simples como esse incomoda o programador, e gostaríamos de só dizer ao assembly para saltar para tantas instruçòes para trás ou para frente, sem usar o label.
No Assembly do AVR isso é possível, usando o PC (Program Counter), e ficaria assim:
        LDI   R20, 10
        DEC  R20
        BRNE PC-1
        …
Acima se vê o “BRNE PC-1″, que significa “BRanch Not Equal”, ou seja, “Salte se o resultado anterior for diferente de zero”, para a posição do Program Counter, ou seja, “aqui”, menos uma instrução, então saltará para a instrução anterior, que é onde se quer.
Pode-se usar a faixa de 7 bits completa, ou seja, PC-127 a PC+126, e obviamente RJMP PC, BRNE PC, BREQ PC, fará a instrução saltar para ela mesma e com isso fazer o AVR entrar em loop, saindo só com uma interrupção (se ativada) ou reset.
Apesar desse truque ser muito útil, tem-se que tomar Extremo cuidado ao usa-lo.  Imagine a seguinte rotina:
        LDI   R20, 10
        SBI PortB,3
        NOP
        CBI PortB,3
        DEC  R20
        BRNE PC-4
Que fará o pino 3 da portaB subir e descer 10 vezes, com um pequeno delay de uma instrução NOP enquanto o pino estiver com nível alto, e o BRNE PC-4 fará o loop de volta para SBI PortB,3, pois é a quarta instrução para trás.
Se inserirmos ou removermos uma instrução nesse loop, mudando a quantidade de instruções entre o “SBI PortB,3″ e a “BRNE PC-4″, o valor “PC-4″ deverá ser mudado de acordo, e é comum esquecermos disso.
Exemplo, imagine que o pulso no pino 3 ficou muito curto e se quer aumentar um tililim, então mudamos a rotina para ter DUAS instruções NOP entre o nível do pino subir e descer.
        LDI   R20, 10
        SBI PortB,3
        NOP
        NOP
        CBI PortB,3
        DEC  R20
        BRNE PC-4
Se não atualizarmos o “PC-4″ para “PC-5″, o que irá ocorrer?  o salto PC-4 cairá no primeiro NOP, e não mais no “SBI PortB,3″, a rotina irá rodar, mas o pino 3 nunca subirá de nível.  Então o correto deveria ser:
        LDI   R20, 10
        SBI PortB,3
        NOP
        NOP
        CBI PortB,3
        DEC  R20
        BRNE PC-5
Também temos que prestar atenção para instruções que usam duas posições de memória, são raras, mas existem.   Digamos que ai no meio exista uma instrução grande, do tipo LDS R21, 0×1234, carregando R21 da posição de memória externa 0×1234.  Essa instrução consome 4 bytes, duas posições de memória, pois precisa de dois bytes só para conter o valor do endereço 0×1234, mais o opcode, mais o código do registrador R21.  Usando o espaço de duas posições na memória de código, essa instrução em especial deve ser contada como “duas posições” e não uma só.
Então observe que se eu trocar um dos NOPs por LDS R21, 0×1234, o PC-5 deverá ser PC-6, porque apesar de ter só cinco instruções de SBI PortB,3 ao BRNE, essas instruções ocuparam seis posições de memória, e o PC-n não conta instruções, mas converte isso para endereço físico de memória.
        LDI   R20, 10
        SBI PortB,3
        NOP
        LDS  R21, 0×1234
        CBI PortB,3
        DEC  R20
        BRNE PC-6

Tecnologia imita a Natureza

posted by Wagner Lipnharski @ 5:51pmFriday 5 April 2013.

Aqui em Orlando, atrás da minha casa existe um lago, onde muitos patos “Mallard” o visitam durante o inverno.  Não é à toa que o meu pequeno bairro chama-se “Mallard Cove”.

 As vezes eu fico fascinado com o voo desses pássaros, que me lembram algumas cenas de aviões militares.   Veja abaixo e compare a semelhança.
 
 
 
 
 

CAPACITORES

posted by Wagner Lipnharski @ 6:55pmFriday 3 May 2013.

Abaixo um texto coletado sobre capacitores, parte da net, parte traduzida, parte de livros e parte de experiência pessoal.

DEFINIÇÃO:

Rigidez dielétrica : A capacidade do dielétrico para suportar uma certa tensão sem um arco ou a ocorrência de curto-circuito. Quanto maior a força dielétrica, o capacitor suportará maior tensão elétrica.

Absorção dielétrica : Um efeito onde parte da carga armazenada em um capacitor não aparece imediatamente após a descarga, porém vaza lentamente com o passar do tempo. Alguns materiais dielétricos possuem uma espécie de efeito esponja.   É o equivalente à água que mantém a esponja úmida mesmo após você torce-la.  Absorção dielétrica não é uma característica desejável.

Resistência série equivalente (ESR) : Na prática todos os capacitores possuem uma certa resistência em série, devido a fios, materiais, etc.  Baixo ESR é uma característica desejável.

Indutância Série : Na prática capacitores possuem indutância série devido as técnicas de construção utilizadas. A indutância mínima seria o mesmo que um condutor (fio) o mesmo comprimento que o capacitor. Muitas vezes esse valor é muito maior. Com um indutor em série com o capacitor, resulta em um circuito ressonante de série. O capacitor irá ressonar nessa freqüência. Indutância série não é uma característica desejável.  Os capacitores de indutância série mais baixas são usualmente os tipos SMD cerâmicos e tântalo.

Coeficiente de temperatura : Na prática os capacitores variam um pouco o seu valor com a mudança de temperatura. Alguns variam apenas uma pequena quantidade, alguns bastante. O coeficiente de temperatura (mudança na capacitância vs mudança de temperatura) não é sempre linear.

Polaridade : Capacitores que podem ser operados com segurança com apenas uma polaridade DC são chamados capacitores “polarizados”, que podem ser operados sem considerar a polaridade são “não-polarizados”. Às vezes capacitores “polarizados” são combinados de forma especial para permitir uma limitada capacidade de lidar com polaridade reversível, e são chamados de “bipolares”.

Ripple de corrente : A quantidade de corrente AC, que um capacitor pode suportar e quantas vezes ele pode suportar. Nem todos os capacitores são classificados para a corrente de ripple. Esta especificação é aplicada principalmente para capacitores que lidam com correntes AC, ou capacitores de DC com grandes componentes de AC (freqüentemente encontrados em fontes de alimentação switching e equipamentos industriais, tais como motor drives etc).

+++++++++++++++++++++++++

MATERIAIS DIELÉTRICOS :

A maioria dos capacitores são nomeados com base no material usado em seu dielétrico.

Ar : O material dielétrico original. Receptores de rádio de tempo antigo usado variável capacitores feitos de pilhas de placas paralelas com ar entre eles. O ar é um bom dielétrico, que varia ligeiramente com a umidade e partículas em suspensão. Capacitores com dielétricos de ar são impraticáveis para valores para além de algumas centenas de picofarads devido ao seu tamanho crescente. Caps de ar são não polarizados.

Cerâmica monolítica : Materiais cerâmicos fazem um bom dielétrico. Eles podem ser usados para valores de baixas picofarads até geralmente ao redor de um microfarad. Os pequenos valores são geralmente “monolíticos”, eles são feitos de um único dielétrico (geralmente em forma de disco) metal chapeado em ambos os lados do disco, e leads anexados.  Eles também são avaliados pelo coeficiente de temperatura.

COG ou capacitores NPO (zero negativo-positivo) são o mais estável com temperatura, mas geralmente estão disponíveis apenas na gama picofarad. Eles são maiores para determinados valores de capacitância. Há capacitores de coeficiente de temperatura especial para compensação de circuitos. Esses casos são raros.

X7R capacitores têm um maior coeficiente de temperatura, mas estão disponíveis em maiores capacitâncias.  Eles são menores em tamanho que NPO. O tempco não não linear e são difíceis de ajusta-los para linearidade, mas os valores variam para mais ou menos alguns poucos percentos entre 0 a 100 graus Celsius.

Capacitores Z5U dão os maiores valores de capacitância por um menor volume.. O tempco é terrível, muitas vezes caindo para -50% do valor no-20 graus e + 100 graus Celsius (em relação a 25 ° C). Usado apenas para aplicações não-críticas como bypass em fontes de alimentação.

Cerâmica empilhados : Existem capacitores que são fabricados empilhando várias capacitores monolíticos em um único pacote. Eles possuem maior capacitância do que um disco de semelhante classificação. O desempenho ainda está relacionada ao material dieléctrico, que poderia possuir um tempco e caracteristica de tensão boa ou ruim.

Cerâmica (em geral) : Para pequenos valores e altas tensões, capacitores de cerâmicas são os melhores.  Eles são geralmente muito baixos na indutância série, e geralmente o ESR não é um problema. Esteja ciente de seus coeficientes de temperatura.  Alguns materiais cerâmicos apresentam alguns efeitos piezoelétricos, eles podem ser eletricamente sensíveis a vibrações e choques. A maioria das cerâmicas têm baixa absorção dielétrica. Caps cerâmicos são não polarizados.

Mica : Muito bom, dielétrico muito estável, feito a mica mineral, com placas chapeadas ou depositadas em ambos os lados (muitas vezes prata, daí o nome “prateado mica”).  Desempenham melhor do que as capacitores de cerâmicas na série NPO.  Capacitores de Mica são produzidos para a faixa de picofarads, e a faixa de tensão é para milhares de volts.  Capacitores de mica são não polarizados.

Tântalo : Um dielétrico capaz de produzir  alta capacitância em um espaço muito pequeno. Capacitores de tântalo são feitos de duas construções, úmido e seco. Capacitores de tântalo úmido possuem um eletrolito líquido que forma o dielétrico. Esses foram quase que totalmente substituidos por tântalo sêco.   Esses usam um material pó esférico de tântalo com um revestimento dielétrico externa.  Eles são “aglomerados” juntos para formar um material quase contínuo com valor de alta capacitância por unidade de volume. Eles têm indutância série razoavelmente baixa e muito baixo ESR.

AVISO: capacitores de tântalo são RAIVOSAMENTE polares. Invertendo a polaridade DC mesmo por um breve período de tempo fará com que eles ao calor e auto-destruição.  Ccapacitores de tântalo são mais comuns em baixas tensões e valores abaixo alguns microfarads. Tensões elevadas e grandes (> 5-10uF) valores os tornam excessivamente custosos.  Seu ESR baixo e indutância série os torna perfeitamente adequados à serviços de bypass de fontes de alimentação. A corrente de fuga é geralmente muito baixa, muito melhor do que os eletrolíticos.  Eles devem ser evitados em circuitos de acoplamento de áudio (região bipolar).

Eletrolítico : Capacitores eletrolíticos possuem esse nome por causa dos produtos químicos usados para formar o dielétrico.  Capacitores eletrolíticos têm placas enroladas com uma longa e fina tira de papel alumínio.  O dielétrico é um fino (vários átomos densamente) revestimento de óxido de alumínio (um excelente isolante).  O óxido de alumínio é formado por uma reação química entre o eletrólito e o alumínio, na presença de um campo elétrico. Este dielétrico formado dá os capacitores algumas únicas vantagens e desvantagens. Capacitores eletrolíticos podem ter grandes capacidades por espaço de unidade, uma vez que o dielétrico é muito fino. O dielétrico pode ser adaptado para suportar tensões até cerca de 450 VCC, o limite superior para caps eletrolíticos. As desvantagens do eletrolítico vêm do eletrólito, e como o dielétrico é formado. O eletrólito irá secar no tempo, fazendo com que os capacitores para gradualmente diminuir a capacitância.  Usar o capacitor além suas classificações (tensão, polaridade ou corrente de ripple) vai aumentar a pressão interna no capacitor até que libere a pressão (vent)  e perde eletrólitos  ou explode. O outro problema é que, se o capacitor eletrolítico não é usado por um longo tempo, o dielétrico se torna mais fino, diminuindo a tensão que ele pode suportar. O dielétrico precisa de um campo elétrico (carga) a fim de manter a sua força. Eletrolíticos armazenados sem uso (em armazenamento ou em equipamentos não utilizados) podem ter suas camadas dielétricas restauradas aplicando lentamente o aumento dos níveis de tensão DC. O procedimento pode levar dias. Eletrolíticos sofrem de envelhecimento acelerado em temperaturas elevadas. Uma regra é que sua vida é cortada ao meio para cada aumento de 10 graus Celsius acima do ambiente (25 ° C). Por todas estas razões, eletrolíticos têm vida limitada e o usuário pode esperar para substituí-los em algum momento no futuro.  Excessivo ruido de 60Hz (humm) em uma fonte de alimentação ou imagens de rolamento instável em um monitor são frequentemente sinais de um eletrolítico chegando ao fim da sua vida útil. Capacitores eletrolíticos têm uma quantidade substancial de escapamento e absorção dielétrica. Isso pode ser um problema em circuitos de temporização e muitas vezes limita a sua utilização. Alguns projetos (como o temporizador 555) minimizam essas falhas, usando o capacitor em tensões de funcionamento onde esse fator aparece de forma mínima. A estabilidade de temperatura de eletrolíticos é pobre e raramente especificado.

Eletrolíticos polarizados : A forma mais comum de capacitores eletrolíticos. Estes estão disponíveis nos tamanhos acima de 1uF até Farads, e disponíveis a suportar tensões de 5 a 450 Vcc.  Existem tipos especiais que trabalham em faixa extendida de desempenho, geralmente especificado para temperaturas mais altas, maior corrente de ripple, baixa ESR e maior confiabilidade. Todas estas classificações geralmente resultam em um componente fisicamente maior.  Existem eletrolíticos “selados” para aplicações em temporização, mas eles são raros.

Eletrolíticos bi-polar : Estas são uma variedade especial de capacitor eletrolítico que são usados em aplicativos que misturaram polaridade, tais como o acoplamento de aplicações de áudio. Fisicamente, eles são feitos de dois eletrolíticos polares ligados em série nos seus terminais negativos. Eles são geralmente duas vezes tão grandes quanto um eletrolítico polarizado para o mesmo valor de tensão e capacitância. Usos comuns em Crossovers econômicos em alto-falantes.

Supercaps (bateria) : Estas são capacitores eletrolíticos que são especializados para os tempos de descarga longa com cargas de corrente muito baixas. Eles são usados por aplicativos de backup de memória no lugar de baterias Ni-Cad ou lítio.

O uso principal para capacitores eletrolíticos é para alimentação, filtragem e bypass. Usos menores são para acoplamento em operação unipolar de áudio (onde um terminal é sempre mais positivo do que o outro) ou aplicações não-críticas de cronometragens.

Capacitores de filme : Capacitores de filme são os membros mais incompreendidos da família de capacitores.  Eles são nomeados após o material usado como o dielétrico. Eles vêm em duas variedades de físicas, a construção de Filme e Película, ou construção de Filme Metalizado.  Eles estão disponíveis em valores em torno de .0005uF (500pF) para vários microfarads e tensões de em torno de 10VDC a vários milhares de VCC.   Existem capacitores de filme para aplicações especiais podem ir até vários milhares de microfarads, nesse caso possuem maior tamanho e preço. A maioria das capacitores de filme tem ótima estabilidade em variações de temperatura, e com baixa absorção dielétrica. Por via de regra são capacitores não polarizados e têm boa resposta de AC.  Indutância série varia de baixo a alto, dependendo da geometria da construção. Em sua forma mais simples, eles são construídos de duas peças de alumínio, separadas por um “filme” do material dielétrico. Isso é chamado de construção de filme e papel alumínio e é o maior e mais robusto na maioria dos casos. Alguns capacitores de filme têm uma camada de metalização, geralmente de alumínio, depositada em ambos os lados do filme. Isso é chamado de película metalizada e é geralmente menor e mais caro. Ambos os tipos têm desempenho semelhante.

Filme de poliéster (Mylar) : O material dielétrico mais comum em uso. É de baixo custo e os tipos existentes são em filme e papel alumínio metalizado.  As faixas de tensões suportadas vai de 50VDC Mylar 200VDC (até 1000VDC).  Mylar sofre absorção dieléctrica (. 2%), que o torna inadequado para aplicações tais como capacitores de temporização de VCO e aplicativos de Sample and Hold. Capacitores de poliéster não tem um coeficiente de temperatura linear, sua capacitância aumenta em alta temperatura e diminui em baixas.  A forma geral da curva é semelhante a uma letra horizontal “S”. Entre 25-85 graus Celsius têm um coeficiente de temperatura crescente. Eles são úteis para áudio, acoplamento, circuitos de temporização semi-critical, controles de tom, usos gerais. Faixa de temperatura é de 125 graus Celsius.

Filme de poliestireno : Santo Graal dos capacitores de filme, poliestireno tem as características elétricas mais desejáveis. Com coeficientes de temperatura tão baixos quanto 30-40ppm (especial) e normalmente inferior a 120ppm (standard), eles têm excelente linearidade de coeficiente de temperatura na faixa de temperatura que qualquer equipamento já trabalhou nesse planeta. Absorção dieléctrica (. 02%) é o mais baixo encontrado em qualquer variedade de capacitor. Isto faz a escolha de capacitores de poliestireno o primeiro para todos os circuitos de tempo crítico, tais como clocks de VCO e FCR e todos os os circuitos de Sample/Hold. Capacitores de poliestireno não toleram temperaturas altas (máximo de 85 graus Celsius), portanto eles não estão disponíveis na forma metalizado. Descuido ao soldar podem destrui-los facilmente, e em muitos casos não são adequados à produção automatizada. Há um rumor persistente que o único fabricante no mundo que continava a produzir capacitores de filme de poliestireno cessou a produção. Ainda há estoque no mercado, mas as pessoas também são aconselhadas a armazena-los por garantia. Há alguns novos capacitores de policarbonato que se aproximam do desempenho de poliestireno.

Filme de polipropileno : Capacitores de polipropileno são usados no lugar de poliestireno. Ligeiramente maior do que o poliéster (Mylar), são eletricamente superiores e um pouco maior em tamanho. Eles têm um coeficiente de temperatura linear, negativa de-150 ppm (e especial-250 ppm para compensação de bobinas em aplicações de filtro). Se o coeficiente de temperatura negativo é desejável, eles são usados no lugar de poliestireno. Absorção dieléctrica é 0.02% e a escala de temperatura é de até 105 graus Celsius no máximo.

Película do policarbonato : Capacitores de policarbonato são outra boa opção para substituição de poliestireno. O tempco e estabilidade de temperatura não são tão bons como poliestireno. São lineares em uma faixa limitada de temperatura (25-85 graus Celsius). Além desse intervalo não são lineares (semelhante a capacitores de poliéster).  Capacitores de policarbonato suportam temperaturas muito mais altas (máximo de 125 graus Celsius) do que o poliestireno, então podem ser construidos com película metalizada.  As gamas de tensão chegam a alguns milhares de volts. Estas capacitores são mais adequadas para aplicações de sincronismo e acoplamento crítico e podem ser usados sempre que o poliestireno é a escolha preferida, com uma ligeira diminuição no desempenho. Capacitores de policarbonato têm uma quantidade moderada de sensibilidade de umidade e absorção dieléctrica é em torno de 0.08%. Capacitores de policarbonato são cerca de 12% maior do que o poliéster (Mylar).

Filme polysulfone : As mesmas especificações como policarbonato, mas com as classificações de temperatura ainda maiores. Estes são usados onde o desempenho de alta temperatura é obrigatório (máx. 150 graus Celsius) e raramente são usados para aplicações gerais. Eles têm um coeficiente de temperatura razoavelmente linear de 25 graus Celsius e acima, mas que cai ligeiramente a baixas temperaturas. Capacitores de Polysulfone possuem uma pequena sensibilidade a umidade e absorção dieléctrica é em torno de 0.08%.

Filme de Teflon : Teflon trabalha bem como poliestireno e é bom também para altas temperaturas. Eles são duas vezes o tamanho de um capacitor de poliéster (Mylar), e o preço elevado torna sua utilização incomum para todos, e servem mais apropriadamente para aplicativos mais essenciais (leia aeroespacial). A dificuldade em fazer qualquer coisa a aderir ao filme faz a metalização impraticável. Teflon é impermeável à umidade e tem absorção dieléctrica ao redor de 0.02%.

TB6560AHQ Driver Board – Fan Speed Control

image.851

Hello, I have one of those eBay boards, a stepper motor driver for 4 motors, manufactured by the chinese www.huy68.com, it uses the dual full bridge chip Toshiba TB6560AHQ, that is able to supply 3.5A @ 40Vdc to the motors.

The board contains a single long heatsink over the chips, with a single 40mm 12Vdc fan, that runs at full speed all the time, nosy and low air flow, as usual for those cheap $1 fans.

Also, the fan is powered by the 12Vdc regulator on board.  The fan consumes from 100 to 120mA, it seems small, but if the user feeds the board with the recommended 24Vdc or higher, the 12Vdc regulator (LM7812) will dissipate the extra voltage and current, from 1 to 1.5W just to feed the fan, what is power and heat wasted.

Because of that, the LM7812 regulator gets unnecessarily warm.

image.853

Also, this 12Vdc regulator, feeds power to the +5V regulador, the LM7805, that supplies the logic voltage to the TB6560AHQ chips, it also consumes some power, that of course comes through the LM7812 regulator, heating it even more.

The LM7812 is installed in a single black small heatsink, that may get really hot under heavy use. You can see both black heatsinks at the picture on the right, with both, the LM7805 and LM7812 regulators.  The red and black wire in the connector is the wires that feed the fan with +12Vdc.

So, initially I cut one wire of the fan and inserted 6 series 1N4007 diodes, to drop the voltage to the fan from 12V to around 8Vdc, this reduced the fan speed and the power consumed, but it was not enough.

Air Flow Duct to the 7805 and 7812 regulators

Even so, I produced a air flow duct made with ticker paper (business cards) in a way to guide the air pushed by the fan to the sides of the large heatsink, and at the back side I made the duct to turn left and carry the air over the LM7805 and LM7812 heatsinks.  You could feel the cool air flowing over the 7805 and 7812, It helped somehow to keep the regulators cooler than usual.

But that is a ugly and not so nice solution.

Then I thought to move the LM7812 regulator to the same large heatsink, by the way, the large heatsink has the fan cooling thing off.  Then I removed the LM7812 from the solder pads, soldered three long tick wires (red in the picture) and moved the LM7812 to between two fins of the large aluminum radiator.

The 7812 was moved from its original position to be inserted in between two fins of the large heatsink. I used a little of the white thermal paste and just inserted the LM7812 between the fins.  It was needed to little pry open the fins with a screwdriver so the LM7812 could enter there.  There was no need for screw the regulator, the tied position between the fins are enough to hold it in there forever.  As the fins were forced open, the back side of the LM7812 with the thermal paste touched nicely the fin, the front side (epoxy) got not so good contact, but it doesn’t matter.  Thermal transfer is better than in the original position on the board.

Okay, the LM7812 problem is fixed, now about the fan speed. I though to use one of two approaches, first, use a simple three op-amp circuit, the first generating a square wave, the second using such square wave to charge and discharge a capacitor and producing a triangle waveform, and the third, to compare such the voltage of the triangle wave with a voltage divided by a NTC (negative temperature coefficient) resistor, measuring the temperature of the heatsink. The triangle waveform rides from 5 to 5.8Vdc.

The voltage divider between the NTC and the 10k resistor, creates around 6Vdc when in 75 degrees Fahrenheit. As the temperature increases in the heatsink, the NTC drops its resistance, and the voltage in the divider also comes down, going deep into the range of the triangle waveform.  The third op-amp will sense it and generate a digital pulse at its output.  The width of the pulse is proportional of how deep the NTC voltage is among in middle of the triangle waveform voltage.  As the output of this op-amp drives a transistor and the transistor feeds the fan, as wider is this pulse, the faster runs the fan.

Around 90°F the NTC voltage is around 4.8Vdc, lower that the bottom part of the triangle waveform voltage, so the output of the third op-amp will be steady, applying full power to the fan, that will refrigerate the heatsink and will keep it a little warm between 75 and 80°F.

If the heatsink cools down below 75°F the fan stops completely, saving energy and noise.  This idea is nice, but it uses 9 resistors on board, requires some adjustments for the temperatures and it is not exactly high-tech.

Below is the schematics for the analog solution, it works VERY WELL.  I developed it in the Linear Technology CAD simullator (LTspiceIV), then assembled it in a protoboard for testing purposes. The two op-amps to the left generates a square then triangle shaped waveform, its ramp voltage is then compared against a fixed voltage at the third op-amp.  This “fixed-voltage”, is dependent of temperature, since it comes from a voltage divider between a fixed resistor and a NTC.  The result of such comparison drives a PNP transistor that feeds the fan. If the NTC is below certain temperature, the triangle never reaches such voltage and the third op-amp never triggers the PNP, the fan stay stopped.  As the temperature in the NTC goes higher, the voltage at the + pin of the third op-amp goes lower, now matching some point of the triangle at the – pin, driving the PNP and the fan. The trigger temperature is defined by the selection of the NTC and the resistor on top of it.

image.855

But I had another idea.

Dispite the analog solution above working very well, I always seek another solution using a tinny microcontroller, sometimes is possible, sometimes not.  Whenever possible and using less components, and possible less problems, I try to develop and test it.

To be small, I thought about the Atmel AtTiny13, saving parts and several resistors.  With the AtTiny13, I only use 2 resistors, one to produce the voltage divider with the NTC, and another to limit the current from the AtTiny13 to the base of the power transmistor that feeds the fan.  Of course, the solution using the AtTiny requires 5V for it, and I have only 12V on the fan wires.  The solution is to use a small LM7805 close to the AtTiny13, the LM78L05, a TO92 package, enough small to not cause any harm to the idea.  Okay, the driver board has +5V, but it would be another wire coming to this fan control board, and I want it as clean as possible, having several 78L05 in the drawer, why not?

The control board. See the NTC at the right side, protected with kapton tape.

At the left you can see the small prototype PCI with the AtTiny13, 6 pins ISD for reprograming it, two resistors, a capacitor, the 78L05 regulator, at the left side the BDxxx transistor, and at the right side (yellow and red wires) is the NTC (protected with Kepton tape).

So now the 10k resistor and the NTC have the center connected to one of the ADC (Analog to Digital Converter) onboard of the AtTiny.  It has ADC mux inputs, I used just one.   The idea here is to write a simple AVR assembly program that reads the ADC and use the onboard Timer/Counter function as PWM to generate the pulses that goes to the power transistor feeding the fan.   The code reads the ADC, and while inside a certain range of values, turn on the PWM, with different widths according to the values read from the ADC.  Now this is programmable, I can setup whatever I want, different from the 3 op-amps idea above.  I can even define the start of the PWM with a certain width in the pulse, so the fan will effectively “start to run” slowly but will start.  The solution with the 3 op-amps can do something like that, using a positive feedback to the last op-amp, but the final result is somehow not so good.

So, I used the AtTiny13 solution, and the result is as in the pictures.

The control board being installed, see the 78L05 regulator and the BDxxx transistor body going in between two fins of the heatsink.

The left picture shows the small prototype board being installed. Note the body of the BDxxx transistor going in between the fins of the heatsink, along with the TO92 body of the 78L05.  Both enter also tied fins, needing a little pry with a screwdriver.  Both transistores goes entirely down between those two fins, with no electric contact at all.

 This is good, the BDxxx is able to transfer any heat to the heatsink, and also holds the small board in place, no screw, nothing.

The yellow Kepton tape on the heatsink is to isolate the ISP pins on board to electrically short to the heatsink aluminum.  The body of the AtTiny13 serves as a spacer between the fins and the circuit board.

Of course, I used a BDxxx transistor to drive the fan.  I tested nicely using a small TO92 2N4103 transistor, and it worked well, but I was afraid of the future unforseen situations, then I changed the driver transistor to a BDxxx unit, capable to drive a larger fan, dissipating more heat if necessary.

The BDxxx transistor was soldered in the small board in a way that when the board is over the large heatsink, the BDxxx body goes inside two fins, also refrigerating as necessary.  See the pictures.

Next step is to produce a professional small Printed Circuit Board, that will hold also the LM7812 and LM7805  regulators and put is available for sale at http://www.urkit.com, for a low price, so you can do this modification to your stepper motor driver board.

image.854

At the right you can see the board over the heatsink. A necessary installation screw will hold the board to the heatsink.

 

For a prototype it is enough

 

Wagner.