ArduinoDIYProgramação

Impressora com Arduino e OpenCV

Impressora matricial - Impressora com Arduino

Gosto de fazer coisas mais elaboradas, mas confesso que dessa vez o artigo está indo um pouquinho além do desejável para makers. Não que você não consiga reproduzir, mas introduzi algumas dificuldades do  tempo em que eu escrevia artigos simplesmente visando mostrar algo funcionando. Atualmente desejo que esses passos sejam reproduzidos e, como estou utilizando parte de um projeto antigo (e não finalizado – uma CNC que virou uma impressora com Arduino), será necessário  contar com  sua paciência e perseverança, ok?

CNC, impressora, ploter

Todos eles tem semelhanças; utilizam 3 eixos (X,Y,Z). Mas as semelhanças acabam por aqui, porque o artigo de hoje (impressora com Arduinoo) não utiliza um protocolo padrão. Não quer dizer que inventei um  protocolo melhor, apenas que resolvi cortar caminho e ir direto ao ponto. Não deve ser de forma alguma  mais  eficiente, mas dá uma maior liberdade quanto ao uso, então, o que você não vai encontrar nesse projeto é G-code. Na verdade, esse projeto funciona mais como uma impressora, imprimindo linha a linha – e se movimento mais como um scanner.

Impressora matricial



Lembro-me nos anos 80 das impressoras matriciais, que tinham múltiplas cabeças para que a impressão fosse mais rápida. Essa impressora com Arduino é justamente uma impressora matricial, mas por ser de apenas 1 cabeça (1 caneta), é muito, muito lenta. Mas isso não nos impede de sentir o prazer da criação, hum? Imagine se na época que as impressoras eram raras (ou não existiam), fazer uma com uma microcontroladora significaria ganhar um mercado! Ou no mínimo, ganhar muitos adeptos.

Como essa impressora com Arduino funciona?

A impressora tradicional doméstica da atualidade funciona um  pouco diferente (estou me referindo ao comportamento mecânico. A tecnologia está a anos luz desse brinquedo). A folha é tracionada para a cabeça de impressão, que se desloca em apenas 1 eixo. A impressora desse artigo se parece mais com uma CNC e até poderia ser (outra vez, me refiro à parte mecânica), mas por não usar G-code, não se comporta da mesma maneira e também não tem a mesma eficiência.

A parte mecânica da impressora com Arduino desse artigo possui os 3 eixos, X, Y e Z. No eixo X, tentei utilizar uma cremalheira no motor de passo que move o carro da caneta. O propósito inicial era de ser utilizado em uma CNC, por isso a base foi feita de forma muito mais robusta e de maior precisão, mas tudo o que você precisa fazer é uma base também com cremalheira ou com barra roscada. Essa plataforma inicial foi parte do artigo sobre a montagem de uma CNC, cujo artigo se encontra nesse link. Os motores  de passo estão sendo controlados pelo EasyDriver, cujo artigo relacionado pode ser visto clicando aqui.

Não é meu objetivo final fazê-lo com Arduino e tão logo seja possível, vou migrar para ESP8266 e assim transferir a imagem por WiFi invés de serial, mas também poderia ser feito com qualquer rádio frequência, como por exemplo, o Whisper Node. Claro que nesse último caso, seriam necessários 2 deles, para transmissão e para recepção. A vantagem é que a impressora pode ficar a uma distância de até 1km em campo aberto. Utilizando um PCF8574, já daria pra resolver a questão de GPIO.

Quando essa impressora com Arduino é ligada, a plataforma é alinhada no canto superior esquerdo. Nessa fase inicial não desenvolvi ainda um programa gráfico para interagir, portanto os passos  serão um pouco braçais, mas farei o máximo de esforço possível para liberar um programa multiplataforma para a interação com a impressora e se eu inserir um ESP8266 no projeto, o programa será feito para Android. Primeiro, deve-se selecionar a imagem  que deseje transferir para ela; atualmente utilizando Arduino, portanto, a transferência será via serial. Talvez eu tente implementar um RF qualquer, mas meu desejo mesmo é migrar para o ESP8266 ou ESP32, ainda estou na dúvida. Utilizando o  CV-GUI ( Computing Vision – Graphical User Interface – que você lê a respeito nesse outro artigo), seleciona-se a melhor condição; alto-contraste binário, limites de linha ou algo parecido. Depois, lê-se todos os pixels da imagem com o OpenCV e transmite-se linha a linha para a impressora via  serial, como citado anteriormente. Isto é, cada linha do desenho será enviada com um separador para essa impressora com Arduino, que por sua vez fará um parsing  da string, converterá para bool, char ou int e então  enviará o comando para os controles. A caneta será controlada por um servo motor, apenas para erguer e tocar a caneta na base. Mais adiante mostro os detalhes da construção desse carro. Inclusive, fiz uma modificação recente nesse período de 1 mês que estou escrevendo esse artigo e ficou bem simples e interessante.

carro - impressora com Arduino
Carro – impressora com Arduino

Você pode utilizar qualquer imagem em preto e branco se quiser simplificar, mas deverá ler os pixels para montar o array linha-a-linha de qualquer modo. Por essa razão estou disponibilizando também um código com OpenCV apenas para gerar o arquivo binário da imagem.

Pré-requisitos

Você precisará já ter lido a respeito de motor de passo, controladora, interrupções e openCV para entender o funcionamento do conjunto, senão o artigo poderá lhe parecer pobre, apesar da densidade. Se não leu os artigos relacionados a esse projeto, sugiro as seguintes leituras:

Controlador EasyDriver

Motor de passo com ULN2003

Motor de passo com Arduino

Controle de servo motor

Estou citando essas referências porque não poderei entrar em  tantos detalhes novamente, senão esse artigo virará um  livro.

Lista de materiais

Infelizmente esse não é um projeto escolar. Os custos são um pouco elevados, mas você pode ir adquirindo as partes aos poucos. Do conjunto, o mais caro são os motores de passo e as barras lisas, chamadas de “eixo retificado”, feito em aço inox 304 e por isso, caras.  O mais chato de achar é o reed switch (substituido, como você verá mais adiante), utilizado para fazer os limitadores, que garantirão que os motores não tentem deslocar os eixos além dos limites. A vantagem do reed switch em relação às chaves de fim de curso é a durabilidade. Imagine um desenho de 100 linhas (100 pixels na vertical); a cada linha, o sensor da esquerda e direita serão tocados e até o final da impressão do desenho serão 100 acionamentos da chave de fim de curso da coluna. Com o reed switch, não existe contato físico, daí “dura até acabar”. Já para as linhas, considere apenas 1 toque por desenho em cada sensor, o que prolongará a vida útil da chave de fim de curso.


Da parte mecânica, as barras são as mais chatas e caras, por isso eu recomendo faça esse projeto utilizando como plataforma o mecanismo de leitores de DVD, que você deve encontrar bem baratinho na Sta Efigênia, na sucata da rua dos Andradas (São Paulo – Centro) ou na pior das hipóteses, pelo mercado livre (com um frente que é 2 vezes o preço de um drive de DVD velho). Se utilizar esse tipo de mecanismo, economizará uma bela grana com os motores de passo, barras e controladores, mas seu desenho ficará bastante limitado quanto ao tamanho. A barra roscada foi adquirida em uma casa de ferragens, mas o passo é comum, feito para qualquer outro propósito que não uma CNC; ela é baratíssima, porém a vida útil dela é bastante curta, ela oxidará com o passar do tempo. Minha sugestão é que o projeto seja flexível o suficiente para substituição de peças. Uma sugestão é que invés de barra roscada você utilize correias. O custo é baixíssimo e seria bem melhor para esse projeto.

O Arduino teve que ser o Mega devido à necessidade de muitos GPIO, mas se eu conseguir manipular os pinos do EasyDriver com um PCF8574, vou migrar o projeto pra ESP8266 e me livrar dessa limitação. De qualquer modo, para reproduzir esse projeto você precisará dos seguintes materiais:

Testar cada componente

É necessário testar cada componente individualmente para não ter um problema maior depois. Pode parecer chato, mas é fundamental para isolar problemas e bugs. Outra questão muito importante em relação a testes, é saber se a parte mecânica se comportará adequadamente. Por exemplo, não fiz nenhum projeto, nenhum rascunho e não tirei nenhuma medida para fazer a parte mecânica  da cremalheira. Simplesmente fiz os alinhamentos e colei cada parte em seu lugar. A cremalheira é de um conjunto de peças plásticas vendida para robótica e são da pior qualidade. O material é disforme e assimétrico, tive um  trabalho razoável para deixar as cremalheiras (que são divididas em partes pequenas) alinhadas a contento. Como esse motor não fará esforço algum, não é necessário também exagerar nos cuidados, mas testar o alinhamento é fundamental; é necessário garantir que não haverá encavalamentos.

Uma coisa interessante em relação à cremalheira é que ela não foi presa à base, ela se deslocava para mover o carro da caneta. O motor de passo que a controla está preso sobre a mesma superfície (a plataforma superior), apenas com cola quente; lembre-se que não há esforço nesse motor, mas é certo que não falta torque para movimentar a cremalheira. Ainda, acredito que valha a pena citar que o conjunto da cremalheira ficou levíssimo. Eu não esperava por isso, fiquei bastante satisfeito inicialmente, até imprimir algumas linhas e perceber que sim, pode-se usar cremalheiras, mas não essa tranqueira que você vê nas fotos. Isso não serve nem pra projeto de ciências do quinto ano (não menosprezando o quinto ano, apenas não há exigências técnicas elevadas nessa fase da vida).

O nivelamento  da engrenagem do motor de passo é feita com um pouco de atrito  extra, para que haja pressão da  engrenagem sobre  a cremalheira. O que permite isso é o palito de churrasco na ponta do motor de passo, que oferece uma certa flexibilidade, mas se ficar flexível demais e o movimento da cremalheira demandar esforço, o deslocamento da cremalheira pode ser tardio e acentuado. O primeiro teste que fiz foi manual, onde passei a cremalheira por baixo da engrenagem e fui girando o eixo para tracionar a cremalheira. Fiz isso por repetidas vezes para analisar se algo deveria ser corrigido. Quando satisfeito, iniciei o teste com o próprio motor, utilizando micro-passo e pouco movimento, até me sentir confortável com o funcionamento. Faria o mesmo com a base; aliás, fiz quando a projetei.

Antes do próximo tópico, enfatizo que o conjunto de barras é sem dúvida a melhor solução, permitindo inclusive que se faça uma CNC desse mesmo mecanismo e, apesar do projeto  ter sido iniciado sem parâmetros prévios, funcionará bem, mesmo se parecendo com um scanner. Mas para o próximo projeto já prometo de antemão a devida coerência do formato do projeto, o importante aqui é a prova de conceito e a biblioteca, que servirá para qualquer modelo, seja com barras ou com leitores de DVD. Resumidamente, você tem 3 opções; cremalheira, barra roscada ou correias.

Aquecimento  dos motores de passo

Você pode ler detalhes a respeito no artigo do EasyDriver, onde explico  as duas formas de funcionamento do motor de passo. Claro que se for utilizado por um periodo prolongado ele tende a aquecer, mas não deve ser nada significativo, porém utilizando a frenagem do motor, a cola quente não será o suficiente para manter o motor de passo preso à plataforma superior, pois esse motor pode chegar fácil à 70º. Minha recomendação é que você utilize adequadamente o pino Enable do  EasyDriver como recomendado no código de exemplo do artigo supracitado e quando o motor não estiver em uso (por exemplo, quando estiver movimentando apenas 1 eixo), utilize o pino Sleep. O código que estou utilizando para esse artigo esta disponível no github, citado mais adiante, preocupe-se apenas em entender como o EasyDriver funciona.

Para concluir esse tópico, preciso deixa claro também que essa técnica utilizada para evitar o aquecimento dos motores pode ser um tiro no pé, dependendo da forma do tracionamento. No caso da cremalheira, o descanso acontecia inicialmente entre a troca de dentes, na mudança do dedendum e addendum. Aí ocorria o pior dos casos, que era um ciclo incompleto da transição. para resolver, bastou remover esse descanso. Porém, todavia, entretanto, como substitui pelas barras (e mais uma vez me desculpo por apresentar um projeto com esse custo), pude tornar a fazer o descanso, pois na rosca não existe esse problema, uma vez que não importa a posição do passo, onde o motor parar, alí ficará.

Ainda acho que o melhor seria a utilização de correias. O custo é baixíssimo e por informações de um amigo que está utilizando correias em uma impressora 3D, é totalmente confiável.

Porque utilizar servo motor?

Eu tenho outro motor de passo aqui, mas sem sombra de dúvidas é mais simples mandar a posição do servo para subir ou descer X%. No caso, programei o deslocamento do servo motor de 0 (para caneta em cima) e 45 (para caneta em baixo). A alimentação desse servo motor pode ser feito diretamente no Arduino  e assim poupamos wiring. Posteriormente eu pretendo colocar um pirógrafo na ponta de desenho e nesse caso será necessário algo com mais robustez porque o peso da ponta do pirógrafo é bem maior que a de uma caneta.

Para utilizar um motor de passo (caso pretenda fazer extrusão de material), tem que incluir a calibragem do eixo vertical, que deve ser executada todas as vezes que utilizar o brinquedo e pra piorar, tem que ser feito manualmente. Eu pretendo fazer essa inclusão também, mas vou por partes, senão esse artigo que está sendo escrito há mais de um mês será publicado na web 3.0 (e acredito que sem hipérboles).

Palitos de sorvete?

Sim, daria para fazer inclusive a plataforma com palitos de sorvete. Veja o artigo do robô seguidor de linha feito totalmente com palitos de sorvete. Mas no momento estou utilizando apenas para algumas partes, como as guias, o suporte da caneta e  trilho das rolemãs da plataforma superior. Não tenha o preconceito que eu já tive, pois formando um “sanduiche” de palitos colados você pode ter uma chapa de madeira tão boa quanto um MDF (ou até melhor). A questão é custo/benefício.

Suporte da caneta

Esse suporte pode ser feito de muitas maneiras diferentes. Eu assisti um único video sobre uma CNC que vi em um dos grupos do facebook, não quis assistir outros para não influenciar minhas ideias, ainda que a minha não seja (e não é) uma das melhores. Também, como iniciei o projeto errado, não quis me desmotivar por causa dos erros de projeto. E no final, tenho orgulho do mesmo jeito, afinal desenhei cada uma das peças no CAD, depois recortei cada peça de madeira em casa e só por ser um trabalho 100% manual já tem seu mérito.

Andar nos trilhos

Como a caneta precisa subir e descer sem folga (para não haver deslocamento da ponta), fiz um trilho para ela com palitos de sorvete e os prendi com palito de churrasco.  Não é bonito, mas ficou ótimo! E não só pelo fato de não haver jogo, mas com isso já consegui um espaço para grudar o servo motor. Basicamente, fiz 2 cerquilhas com o espaço de 1 palito entre as laterais. Depois, grudei com cola quente as duas cerquilhas alinhadas para poder fazer os furos para os palitos de churrasco. Removi a cola quente, encaixei as cerquilhas com a caneta dentro, de modo que pude testar o quão próximo seria necessário deixá-las sem que houvesse atrito entre a caneta e o suporte. Após, passei super-cola nos palitos de churrasco para garantir que não haja novos deslocamentos. Os excessos já podem ser cortados agora. Mas não cortei nada até testar, porque se eu precisasse de alguma solução pra algum problema, o material poderia ser algo auxiliar.

Montagem do carro - impressora com Arduino
Montagem do carro – impressora com Arduino

Quando o suporte ficou pronto, coloquei ele na cremalheira. Como você pode notar, fiz diversos furos na cremalheira e passei  palito de churrasco. Utilizei esses palitos como encaixe para o suporte de caneta e, depois de encaixado, colei o suporte por esses palitos utilizando super-cola. Quando encaixei a cremalheira no lugar novamente para testar, percebi que a parte de baixo do suporte de caneta auxiliou um pouco mais na estabilidade da cremalheira, reduzindo a vibração. Mesmo que ficasse vibrando não haveria problemas pois o desenho é feito por pontilhismo.

Suporte com cremalheira - impressora com Arduino
Suporte com cremalheira – impressora com Arduino
carro montado na base - impressora com Arduino
carro montado na base – impressora com Arduino

 

“Pra baixo, todo o santo ajuda”

Fiquei um tempo pensando como baixar a caneta. Servo motor empurrando para baixo? Motor de passo pequeno? Limitador com infravermelho? – Digo que para utilizar caneta, não é necessário nenhum esforço, basta soltar a caneta e a gravidade cuida do resto. Foi por isso que resolvi utilizar o servo motor apenas para erguer a caneta e quando necessário baixar, o suporte do servo motor apenas sai do caminho. Mas para que seja possível levantar a caneta novamente, a distância entre o suporte do servo e uma alavanca presa à caneta deve ser não mais que suficiente para essa retomada, apenas isso.

Programas



Para seu uso, foram necessários alguns programas para cada uma das tarefas envolvidas. Todos eles, disponíveis dentro do diretório da biblioteca, detalhado em seguida.

Biblioteca

Não ficou tão simples quanto eu esperava, porque descobri tardiamente que as interrupções não funcionariam de forma oculta. A partir daí, o restante ficou até simples, mas acabou exigindo um bocado de código inicial no sketch e para seu uso, criei sketches de exemplo para cada uma das fases de utilização.

Tudo o que você precisa fazer quanto à instalação é copiá-la para o diretório Arduino/libraries.

CalibratePixelsDistance

Esse sketch deve ser o primeiro a se utilizar. Não importa o tamanho da impressora, nem o passo do motor, nem o passo da barra roscada ou o passo da cremalheira. Independente do modo que sua impressora funcione, com esse sketch você consegue definir quantos passos são necessários para deslocar 1 pixel. Essa resolução está diretamente relacionada a mais um fator; a espessura da caneta. No video eu explico em detalhes a relação da resolução de impressão com o tamanho do pixel. Todos os sketches de exemplo estão devidamente comentados para que você possa utilizá-los sem que haja dúvidas.

PrintOneLine

Esse sketch eu fiz pela necessidade que senti de ter um teste prévio da configuração. Com ele, você conseguirá experimentar o alinhamento da impressora e a calibragem a partir dos parâmetros gerados com o primeiro sketch. Do mesmo modo, o próprio sketch contém toda a informação necessária sobre seu uso.

PrintRetangle

Esse é um sketch simples para testar a qualidade da impressão em relação a jogo nos eixos X, Y e Z. No meu caso especificamente foi muito necessário, porque fiz a prova de conceito mais abusada de todas. Utilizar uma cremalheira de peças plásticas mal acabadas foi um risco que assumi propositalmente afim de ter um recurso diferente nessa brincadeira. Não recomendo a ninguém que utilize esse recurso ou pelo menos que não use o mesmo conjunto de peças plásticas que utilizei. Essa parte do projeto poderia inclusive ser mais simples, mais barato e muito mais preciso. Isso eu mostrarei em outro artigo, onde faremos outro projeto desses que servirá como impressora ou como CNC, com um custo muito inferior a esse projeto, além de ter uma qualidade muito superior; acredite, essa prova de conceito foi necessária para amadurecer o conceito para mim mesmo.

PrintImage

Esse é um sketch pronto para você simplesmente imprimir a imagem, sem precisar adicionar um Byte sequer ao código (desde que esteja utilizando o mesmo wiring). Tudo o que você precisa fazer é subir o sketch e interagir com o programa sendImage.py. Os detalhes de preparação de uma imagem estão contidos dentro do arquivo README.txt no diretório extras da biblioteca.

Estrutura de diretórios da biblioteca

Dei uma estudada na documentação relacionada à criação de bibliotecas para Arduino e criei tudo no padrão recomendado. A estrutura é a segunte:

bbPrinter

Esse é o nome da biblioteca. É estranho, mas não sou bom para nomes. Esse é o primeiro nível de diretório. Dentro dele estão 2 arquivos importantes;  o keywords.txt, utilizado para marcar as palavras reservadas (no video eu falo a respeito e mostro também) e o arquivo library.properties, que é o arquivo necessário para padronizar a biblioteca, de forma que ela possa estar contida dentro de um repositório que permita sua instalação a partir da IDE do Arduino.

Examples

Dentro desse diretório estão contidos os sketches que você encontrará depois no submenu Examples da IDE do Arduino.

Src

Dentro desse diretório está a classe bbPrinter. Todo o código está comentado no formato necessário para gerar a documentação em PDF, HTML ou Latex utilizando o Doxygen.

Dentro desse diretório está também o arquivo keywords.txt, cujo arquivo contém as palavras reservadas que ficarão marcadas na hora em que estiver escrevendo código, para evitar conflitos.

Extras

Dentro desse diretório estão os scripts Python para converter uma imagem para preto e branco dentro dos limites definidos. Se precisar mudar o threshold, apenas edite-o e faça tantos testes quanto necessário for.  O valor padrão não será eficiente para todas as imagens, por isso, é fundamental que você experimente variar os valores.

O segundo script python é o que gerará um arquivo de mapeamento da imagem. No video estou mostrando sua utilização.

O arquivo doxyfile utilizado para gerar a documentação também está nesse diretório. Para gerar a documentação, você precisará ter o doxygen instalado em seu computador.

Programas de interação com a impressora

myPrinter.py

Esse programa faz a interface com a impressora. Mais ao final do artigo explico como utilizá-lo.

prepareImageToMap.py

Esse script converte uma imagem qualquer em uma imagem preta e branca com os respectivos limites especificados pelo usuário. Veja mais detalhes ao final do artigo.

convertToMap.py

Esse script converte a imagem tratada anteriormente em um arquivo de matriz binária, cujo arquivo será passado para a impressora.

Problemas

Problemas não faltaram e ainda não faltam. Primeiramente, ao escolher o uso de uma cremalheira invés das tradicionais barras, inseri toda a imprecisão que o material oferece. Incluí a cremalheira sem suporte nos trilhos, de modo que ela chacoalha para frente e para trás. A caneta escolhida é marcador de texto de quadro branco, uma belíssima porcaria que seca antes de terminar o desenho.

Pra ter uma ideia da quantidade de problemas que deu, olhe só a impressão de um retângulo antes e depois (considere a partir da primeira linha longa, impresso sobre um papel de rascunho do fluxograma):

antes -impressora com Arduino
Antes – impressora com Arduino
depois - impressora com Arduino
Depois – impressora com Arduino

Perceba a quantidade de problemas:

  • A espessura dos pixels variam conforme a caneta vai secando.
  • O jogo da cremalheira desloca a linha a ponto de fazer aquela “barriga” no final da primeira linha.
  • O deslocamento do início e fim de linha é causado pelo retorno da engrenagem da cremalheira.

Apesar de parecer bastante ruim, o “depois” não está tão mal se olhar no tamanho natural. O pixel de cima é de uma ponta de quadro branco e o “depois” é uma canetinha escolar de ponta fininha, mas a imagem ficou escalonada então não dá pra ter noção real da espessura do pixel. No video fica bem nítido.

Fora isso, ainda tive diversos problemas lógicos, como o controle do motor. Fui obrigado a remover o descanso do motor da cremalheira porque estava gerando mais passos falsos ainda. Uma variável de controle de direção estava sendo atribuida de forma errada e às vezes a linha seguia na mesma direção invés de retornar – mas isso trata-se de bug, só não pude deixar de citar porque às vezes parece que o projeto é feito de forma simples e direta, mas só estando por trás dos bastidores pra saber o quanto de anti-depressivo é necessário para suportar a dor da frustração.

Troquei os reed switch do eixo X por chaves de final de curso porque não tinha um lugar bom pra colocar reed switch com os imãs de neodimio. Por conta disso, tive que fazer uma adaptação no código, porque não sei ainda a razão, mas estavam acontecendo duas interrupções ao final do curso, mesmo usando FALLING no ISR.

Como chegou nesse ponto, não tem mais correção que seja viável, somente trocando o mecanísmo de impressão da coluna. E lá vamos nós para mais uns dias de trabalho. Antes de seguir, permita-me mostrar o primeiro resultado com ambas as faces; boa e ruim. Boa, porque o programa realmente funcionou como esperado. Ruim, porque o hardware não funcionou como esperado e me levou às mudanças:

Acho que deu pra reparar no tamanho do desalinhamento nos últimos 6 pixels, hum? Mas agora está tudo lindo (dá pra melhorar, dá sim).

Download

Você pode pegar a biblioteca diretamente no github do projeto. Tudo o que você precisa fazer é copiar o diretório para dentro do diretório libraries do Arduino. Mais uma vez cito que no menu Examples você encontrará tudo pronto para utilizar a impressora, só faça seu projeto mecânico como desejar. Inclusive, essa biblioteca servirá para o próximo artigo relacionado, que será uma CNC, mas pode ser uma impressora portátil.

E atualizando esse post hoje, dia 30 de Agosto de 2017, a biblioteca agora se encontra disponível no repositório oficial do Arduino, basta ir ao library manager da interface e procurar por bbPrinter!

Resultados - impressora com Arduino
Resultados – impressora com Arduino

Estou finalizando já uma nova versão, 250% mais rápido. infelizmente eu não filmei a impressão, mas essa imagem com o dobro do tamanho levou menos da metade do tempo para ser impressa:

Esse cavalo foi baseado nessa imagem:

Imagem original - impressora com Arduino
Imagem original – impressora com Arduino

Eu reduzi bastante a tolerância com o script de conversão, dava pra ter mais detalhes, mas eu quis fazer com o mínimo possível. A imagem previamente ao mapa binário ficou assim:

Conversão para preto e branco - impressora com Arduino
Conversão para preto e branco – impressora com Arduino

E no script de mapa binário também reduzi a tolerância, resultando em:

Mapa binário - impressora com Arduino
Mapa binário – impressora com Arduino

Claro que devido às dimensões do caracter e a configuração do terminal, a imagem aparece distorcida no terminal.

Virtualenv

Agora tem outra parte da utilização dessa impressora. É necessário preparar a imagem para que seja impressa e esse processo é feito com um recurso simples da visão computacional, utilizando OpenCV. O código foi todo desenvolvido em Python e a melhor maneira de evitar conflitos e problemas diversos é utilizando virtualenv. Se você não sabe como fazê-lo, siga esse tutorial.

O Leonardo Lontra (colaborador ativo do OpenCV) criou um script para auxiliar com o virtualenv. Copie e cole o código em um arquivo chamado virtualenv_alias:

Após ter salvo o arquivo, inclua-o em seu .bashrc (considerando que seu shell é o bash). Ao final dele, adicione uma linha assim:

Abra um novo terminal ou recarregue o seu .bashrc:

Agora você já pode usufruir das funções do script.

Criar um virtualenv com virtualenv_alias

Para criar o virtualenv, utilize esse comando:

Quando for utilizar o virtualenv, chame-o através do menu:

Nesse menu você poderá escolher entre os virtualenvs criados por você:

menuvirtualenv - impressora com Arduino
menuvirtualenv – impressora com Arduino

Os detalhes de uso dos scripts OpenCV estão detalhados no video.

Teste inicial

Fiz o teste inicial imprimindo um retângulo. Com isso, pude perceber que havia um erro lógico no deslocamento, que pude corrigir rapidamente. A caneta de quadro branco foi substituida por uma canetinha escolar, mas usei o corpo da caneta de quadro branco porque fiz o cursor do carro utilizando as dimensões dela como parâmetro. Não ficou nada mal para o tanto de improvisos que fiz para concluir o projeto  da impressora com Arduino sem as ferramentas utilizadas inicialmente.

O código que utilizei para o teste inicial foi esse:

Esse exemplo estará disponível no menu bbPrinter > Examples.

Para a barra roscada que utilizei, a distância entre pixels especificada está suficiente, mas ela variará dependendo do passo da barra roscada ou ainda, se utilizar correias invés de barra roscada, os ajustes serão completamente diferentes.

Passo da barra roscada

Utilizar uma barra roscada comum tem algumas vantagens; ela é extremamente barata e o passo fica extremamente fino. Em contrapartida, utilizar uma barra dessas colocará em prova sua paciência, porque o deslocamento será extremamente lento. Tanto que foram necessários cortes no video de apresentação mais abaixo, além de acelerar o video para não ficar muito grande.

Ambiente de impressão



Na preparação da imagem, não se esqueça de preparar o virtualenv. Você precisará de uma instalação da biblioteca OpenCV para fazer a manipulação da imagem. Outras dependências podem ser necessárias, basta suprí-las conforme a ocorrência.

Preparação da imagem

Selecione uma imagem qualquer. Ela deverá ser convertida para preto e branco ou escala de cinza. Esse é o primeiro passo.

Execute o script prepareImageToMap.py passando como parâmetro o arquivo de entrada e o arquivo de saída. O arquivo de saída não deve ter o mesmo nome do arquivo de entrada. Nesse arquivo você pode ajustar o threshold para obter um resultado mais adequado para sua imagem ou foto, Faça vários testes até chegar em um resultado que te agrade.

Execute o script convertToMap.py passando como parâmetro o arquivo de entrada e o arquivo de saída. Sugiro que o arquivo de saída tenha a extensão .bin para ficar claro que se trata da matriz binária.

Resultado da conversão

Na imagem abaixo você pode ver a imagem normal em preto e branco (uma silhoueta de lobo) e ao lado, a matriz impressa no terminal, para comparativo.

Matriz - Impressora com Arduino
Matriz – Impressora com Arduino

Imprimindo

Tudo o que você precisa fazer é subir o sketch no Arduino e executar o script myPrinter.py, disponível no diretório bbPrinter/extras. Antes de executar o script, edite-o e coloque a respectiva porta serial no parâmetro uport. A imagem deve ser passada como parâmetro para o script ou você pode deixar estático:

Se preferir a melhor opção, basta mudar o script para:

A imagem abaixo é da execução do script, mas está na IDE do PyCharm, que uso pra desenvolver em Python. A saída que você verá no terminal é a mesma do rodapé.

Interface - Impressora com Arduino
Interface – Impressora com Arduino

Bug

Não sei se é um bug e nem onde encontrá-lo ainda, mas pode ser necessário executar esse script uma vez, interrompê-lo e iniciá-lo novamente para que a impressão inicie. Em futuras versões devo dar uma solução para isso, a biblioteca tem vários TODO, tem muita coisa pra melhorar, mas já estou disponibilizando funcional como você vê no video.

Resolução

A resolução pode ser bem melhor do que essa, aproximadamente 400% melhor. Essa imagem de teste foi reduzida para 48 pixels de largura, é uma silhoueta, mas poderia ser uma fotografia devidamente ajustada com até 200 pixels de largura. Tenha em mente que uma imagem grande quando reduzida tende a perder resolução. A matriz da imagem impressa nesse exemplo está no diretório bbPrinter/extras/lobo.bin. O resultado dessa impressão ficou assim:

Impressão final - Impressora com Arduino
Impressão final – Impressora com Arduino

 

Como colaborar com o código

Você pode baixar a biblioteca, fazer as devidas implementações e subir o código para aprovação. Esse código será experimentado e, passando pelo teste real nessa impressora, implemento e dou os créditos.

Video de impressão

Tentei colocar o máximo possível de informações visuais no video, mas em dado momento do processo a bateria do smartphone acabou e não pude mostrar a conclusão da impressão “ao vivo”, mas é essa que aí está na imagem destacada do artigo.

Espero que tenha gostado e não deixei de assinar o news letter no ínicio da página à direita, assim como dar like na nossa página (também na coluna da direita).

 

Inscreva-se no nosso newsletter, alí em cima à direita e receba novos posts por email.

Siga-nos no Do bit Ao Byte no Facebook.

Prefere twitter? @DobitAoByte.

Inscreva-se no nosso canal Do bit Ao Byte Brasil no YouTube.

Nossos grupos:

Arduino BR – https://www.facebook.com/groups/microcontroladorarduinobr/
Raspberry Pi BR – https://www.facebook.com/groups/raspberrybr/
Orange Pi BR – https://www.facebook.com/groups/OrangePiBR/
Odroid BR – https://www.facebook.com/groups/odroidBR/
Sistemas Embarcados BR – https://www.facebook.com/groups/SistemasEmbarcadosBR/
MIPS BR – https://www.facebook.com/groups/MIPSBR/
Do Bit ao Byte – https://www.facebook.com/groups/dobitaobyte/

Próximo post a caminho!

2 comments
  1. Como adicionar porta serial no Wine • Do bit Ao Byte

    […] Latest news Como adicionar porta serial no Wine Controlar motor de passo com A4988 Programar para Android com Qt Rede mesh com Arduino e Raspberry usando NRF24L01 Comunicação do Raspberry com Arduino utilizando NRF24L01 Configurar um servidor NTP no Raspberry Pi Como renomear interface de rede no Debian Stretch ESP8266 gateway mesh com NRF24L01 e MySensors Raspberry Pi Gateway com MySensors Impressora com Arduino e OpenCV […]

  2. Como fazer uma CNC com drive de DVD velho • Do bit Ao Byte

    […] Esse controlador (A4988) é mais preciso que o EasyDriver, podendo controlar até 1/16 avos de passo contra 1/8 do EasyDriver. O próprio shield deveria auxiliar nesse controle, porque abaixo de cada um dos controladores estão dispostos 3 slots para jumpers e a combinação  deles te dá a velocidade final. No EasyDriver temos MS1 e MS2. No A4988 temos MS1, MS2 e MS3. Se estiver procurando um tutorial para o EasyDriver, recomendo esse artigo. Também, se não leu sobre a impressora matricial que fiz com ele, recomendo esse outro artigo. […]

Comments are closed.

%d blogueiros gostam disto: