segunda-feira, 28 de setembro de 2015

Usando um Port Expander com Arduino

O MCP 23017 é um port expander, ele permite que você tenha mais entradas e saída que normalmente tem na Arduino. Por outro lado permite que você estenda a comunicação com apenas 4 fios (dois do I2C, um de alimentação e outro do terra).

As dicas aqui contidas resolveram problemas que eu encontrei, mas podem não ser a melhor forma de resolve-los, não exite em contribuir nos comentários.

Os exemplos de código consideram o uso da biblioteca da Adafruit para o MCP 23017.

É importante que alguns detalhes sejam observados:

1 - Coloque um capacitor de 1µF em paralelo com o botão (caso você use). Ative, no código, o pull-up interno do MCP23017 que é de 100KΩ, então teremos um resistor em série com o capacitor, quando o botão está aberto. E o tempo de suavização (anti-debounce) será de 0,1s (τ = RC => τ = 100K*1µ => τ = 0,1s).


O uso deste capacitor (um em paralelo para cada botão) além do efeito desejado que é a suavização durante o acionamento tem um efeito indesejado: quando o circuito é energizado o capacitor está descarregado e irá parecer para o MCP 23017 que ocorreu um acionamento do botão. Para eliminar este efeito indesejado é necessário incluir um delay de 60ms (testado empiricamente como um tempo adequado  20ms não deu certo 30ms sim, então escolhi 60ms para ter folga ) e uma leitura para limpar o buffer, no código da Arduino no setup depois da inicialização do MCP 23017.




#define button1 13
#define led 0

void setup() { 

//inicializa o MCP23017     
mcp.begin(); // use default address 0
mcp.setupInterrupts(true, false, LOW); // mirror habilitado - cada interrupcao em INTA e espelhada em INTB
//saídas (só para mostrar com se faz)    
mcp.pinMode(led, OUTPUT);//pino 0  mcp_PinA0 configurado com saída    
//entradas    
mcp.pinMode(button1, INPUT); // pino 13 mcp_PinB5 button1 configurado com entrada
mcp.pullUp(button1, HIGH); // ativa pullup interno de 100K
mcp.setupInterruptPin(button1, FALLING); // gera interrupcao quando de sai de nivel alto para nivel baixo

//tratamento para o uso dos capacitores em paralelo com os botões    
delay(60);//pequena espera antes da leitura inicial 
mcp.getLastInterruptPinValue();//leitura inicial, para limpar o buffer






2 - Cuidados no código com a interrupção

A) Quando se trabalha com Interrupções, uma boa prática é realizar o mínimo possível dentro da função  (interrupt service routine (ISR)) chamada pela interrupção, preferencialmente mude uma variável booleana e trate no loop. IMPORTANTE  está variável global e volatile, por exemplo:



volatile boolean interruptHappen = false;


Normalmente no loop você terá uma chamada que trata a interrupção, algo como:


if(interruptHappen)
    handleInterrupt();


mas ainda não implemente desta forma, veja o item C).


B) Para evitar que ocorra uma interrupção enquanto a função handleInterrupt() deve desligar a interrupção no seu inicio e ligar no final:

void handleInterrupt(){
  detachInterrupt(arduinoInterrupt);
   ....
  attachInterrupt(arduinoInterrupt,intCallBack,FALLING); }


C) É recomendável que se limite o intervalo mínimo entre uma interrupção e a próxima (depois de experimentar uma instabilidade, que travava o funcionamento do MCP 23017, eu resolvi com este intervalo mínimo, equivale a um anti debounce de software para a interrupção.


//variávei globais
volatile unsigned long button_time = 0;  //anti debounce de software na interrupção
volatile unsigned long last_button_time = 0; //anti debounce de software na interrupção
volatile int buttonInterruptInterval = 100; //intervalo mínimo entre uma interrupção e outra, evita problema de debounce
volatile uint8_t mcpPin;

...
dentro do loop:

if (interrupted)
     {
     button_time = millis(); //Anti debounce de software para a interrupção
     mcpPin=mcp.getLastInterruptPin(); //lê qual pino foi acionado
     if (((button_time - last_button_time) > buttonInterruptInterval)&&(mcpPin==button1))//somente trata se for um botão válido e em intervalos superiores a 100ms
       {
       handleInterrupt();
       last_button_time = button_time;
       }
     else mcp.getLastInterruptPinValue();//senão limpa o bus (ignora o acionamento)
     }

D) A função hanleInterrupt() deve ser a mais direta possível, não adicione código que poderia estar em outra função, veja um exemplo:



void handleInterrupt()
   {
   detachInterrupt(digitalPinToInterrupt(PIN_INTERRUPT));//desativa a interrupção para evitar multiplos acionamentos
     
   if(mcpPin==button1) {código de botão 1();} // false = desligado
     
   while( ! (mcp.digitalRead(button1) );//espera o botão ser solto
     
   updateLedsProfile();
   cleanInterrupts();
   attachInterrupt(digitalPinToInterrupt(PIN_INTERRUPT), intCallBack, FALLING);//reativa a interrupção
   }



E) Estará sendo usada comunicação I2C, que é uma comunicação serial, logo recomendo uma implementação como a usada acima, no passo C uma variável global volatil mcpPin é carregada usando mcp.getLastInterruptPin() esta mesma variável é usada dentro do handleInterrupt() para definir a ação, ao invés de carregar novamente. A ideia é: seja simples recebeu uma interrupção identifique o botão e trate.


Informações sobre debounce podem ser encontradas em:
http://www.gammon.com.au/forum/?id=10945

Informações sobre interrupções podem ser encontradas em: https://www.arduino.cc/en/Reference/AttachInterrupt

Atenção: Quando se trabalha com delay() no loop pode ocorrer instabilidade na chamada da função através de interrupção, mesmo com acionamento LOW (por exemplo). Esta instabilidade aumenta caso a interrupção seja acionada por transição como FALLING.

segunda-feira, 20 de julho de 2015

Breakout Board para módulo HC-05 Bluetooth

O módulo Bluetooth HC-05 é barato e fácil de usar, existem vários sites com instruções.

Para se ter acesso ao pinos necessários você pode soldar fios diretamente, ou usar uma breakout board. Muitos já são vendidos soldados em uma.

Neste post eu disponibilizo o desenho de uma PCB que serve de breakout board.

Como o HC-05 se comunica com 3,3v é necessário um divisor resistivo (R1-10K R2-20K) para conectar o RX (3,3v) do módulo ao TX (5v) de uma Arduino Uno, por exemplo, já vi projetos que fazem este divisor com 1K 2K, mas eu prefiro trabalhar com 10K 20K.


Caso a intenção seja conectar o módulo a uma Arduino Due (que trabalha com 3,3v) este divisor não é necessário, logo não é necessário montar R1 e R2, mas é necessário ligar o pad 1 e 2 do JP1 para ligar diretamente o RX ao pin header SV1.


A PCB é single layer, somente o Top, como a figura abaixo;


O resultado final com o módulo soldado ficou assim:



Para testar o funcionamento eu liguei a breakout board a uma Arduino Leonardo:

Arduino Leonardo           Breakout HC-05
3,3v -------------------------- 3,3v
GND --------------------------- GND
TX ---------------------------- RX  (ATENÇÃO é TX com RX)
RX ---------------------------- TX  (ATENÇÃO é RX com TX)

O código para testar está disponível em:
https://github.com/Marchanjo/SimpleBreakoutHC-05/tree/master/Firmware/BluetoothHC05


Finalmente, basta instalar uma app de Terminal Bluetooth no seu celular Android, eu usei esta:
https://play.google.com/store/apps/details?id=ptah.apps.bluetoothterminal&hl=en


Quando o módulo Bluetooth HC-05  é alimentado (3,3v e GND) ele já aparece na procura Bluetooth do seu celular (o nome pode ser HC-05 ou linvor) e normalmente para parear se usa 1234.

Montagem:



Com a Arduino Leonardo executando o código e conectada ao módulo, quando você abrir o terminal e conectar ao HC-05 (depois de já ter pareado, normalmente a senha de pareamento é 1234), o terminal irá apresentar o texto "teste"a cada segundo, este teste indica a transmissão da Arduino para o Celular.

Agora para testar o sentido ao contrário, é necessário abrir o monitor serial da IDE da Arduino
e no Terminal do celular digitar um carácter e enviar (botão Send), este mesmo carácter irá aparecer no monitor serial da Arduino, indicando a transmissão do Celular para a Arduino.


Todos arquivos necessários para fazer a PCB e o código da Arduino estão disponíveis aqui:
https://github.com/Marchanjo/SimpleBreakoutHC-05











quarta-feira, 11 de março de 2015

Atualização do bootloader da Pro Micro

 A placa de desenvolvimento Pro Micro (compatível Arduino Leonardo)  é pequena, tem conector micro USB, tem baixo consumo de energia, em suma: ideal para de eletrônica vestível e de internet das coisas. 




Ela pode vir de fábrica com um bootloader desatualizado, que tem como característica demorar 8 segundos para executar o seu sketch depois de energizar a placa e depois do reset.

Dependendo do tipo de projeto isto é um problema, felizmente a nova versão do bootloader da Arduino Leonardo (que pode ser usado na Pro Micro) tem um comportamento um pouco diferente, mas que resolve este problema, quando você energiza a placa ela carrega seu sketch quase que imediatamente, e somente espera 8 segundos depois do reset. Mais informações aqui.

Para atualizar o bootloader em uma Arduino UNO ou Leonardo é fácil pois já existe um conector ICSP:




Neste link mais detalhes: atualização do bootloader


Mas para atualizar o bootloader da Pro Micro é necessário preparar um cabo que acesse os seguintes pinos:



Pinout da Pro Micro:


Eu resolvi soldar um cabo para que não ocorresse mal contato, mas de maneira superficial para facilitar a posterior retirada. A outra ponta deste cabo é um conector fêmea, para encaixar na no conector ICSP da USBtinyISP.




Com uma placa como a USBtinyISP (que você pode montar com as instruções deste link) é possível carregar o novo bootloader.

A posição do conector ICSP na USBtinyISP é indicada na figura abaixo:





Já com o cabo conectado é indicado o Vcc e o sinal MISO (pino1)



Agora basta abrir a IDE da Arduino (eu fiz este procedimento com a versão 1.6.0 e 1.6.1). Quando fiz no Linux (com root) funcionou perfeitamente.

Executando a IDE:

[user@localhost arduino-1.6.1]$ su root

[root@localhost arduino-1.6.1]# ./arduino 

Em Ferramentas, selecione a placa Arduino Leonardo:



Em Ferramentas, selecione o programador USBtinyISP:

Em Ferramentas, selecione Gravar Bootloader:



 irá demorar um pouco... mais ou menos um minuto para atualizar.

Gravação com sucesso:



IMPORTANTE: Tentei várias vezes este processo no Windows e sempre dava erro ao gravar o bootloader:

avrdude: verifying ...
avrdude: verification error, first mismatch at byte 0x7080
         0x00 != 0x30
avrdude: verification error; content mismatch


avrdude done.  Thank you.

Ainda não descobri a causa deste erro.










sexta-feira, 5 de dezembro de 2014

Sistema de Controle pelo Lábio - Mouse

O Sistema de Controle pelo Lábio é um mouse controlado pelo lábio, permitindo que pessoas com tetraplegia consigam acessar computadores, tablets e smartphones.

No meu doutorado avaliei a capacidade do lábio inferior controlar dispositivos de entrada que atuam como mouse ou controlam cadeiras e rodas motorizadas.

O artigo científico que trata o assunto está em acesso aberto (open science) em:
Human-Computer Interface Controlled by the Lip

Os dispositivos criados visam a ajudar pessoas com tetraplegia promovendo acesso ao computador, tablet, smartphone até controlando cadeiras de rodas motorizadas usando tecnologia de baixo custo e abertas.

Reportagem do Jornal Nacional com Marco Pellegrini usando o Sistema de Controle pelo Lábio apresentado no TOM-SP 2014, no vídeo é destacado a partir do 1 minuto  e 45 segundos:


 Jornal Nacional - Inventores criam tecnologias para inclusão de portadores de deficiência - Edição do dia 29/11/2014


Jornal Nacional - Inventores criam tecnologias para inclusão de portadores de deficiência - Edição do dia 29/11/2014





TOM "Tikkun Olam Makers" 2014 vídeo nacional




Vou apresentar duas configurações de hardware:

  • Controle do mouse por Bluetooth;
  • Controle do mouse com cabo.

Ambas versões utilizam a Pro Micro 5v 16Mhz (compatível com a Arduino Leonardo) que tem o microcontrolador ATmega32u4:

Versão Bluetooth


Esta versão é alimentada pela bateria, o PowerBoost 500 tem um conector micro USB onde é possível conectar o carregador de celulares (ou mesmo um cabo USB do computador) para carregar a bateria, ele gerencia a carga e descarga da bateria e ainda fornece os 5v para alimentar a Pro Micro. 

Detalhes da configuração do módulo Bluetooh Roving RN 42-HID no post:
http://marchanjo.blogspot.com.br/2012/11/mouse-bluetooth-usando-arduino-uno-e.html






Lista de Materiais


1- Pro Micro - 5V/16MHz - SparkfunAliExpress US$ 6,44, Lab de Garagem
1- Thumb Joystick - Sparkfun US$ 4,95, AliExpressLab de Garagem
1- Roving RN42-HID Bluetooth Module - BlueSMiRF HID  - Sparkfun US$ 24,95
1- PowerBoost 500 Charger - Rechargeable 5V Lipo USB Boost @ 500mA+ - Adafruit US$ 14,95
1- Lithium Ion Polymer Battery - 3.7v 500mAh -  Adafruit US$ 7,95
1- Switch

Hardware e Software

Ambas versões (Bluetooth e de baixo custo) compartilham o mesmo firmware, basta configurar a variável:

boolean bluetooth=true;

Arquivo em:



Versão de baixo custo (com fio)

Esta versão utiliza um benefício da placas que utilizam microcontrolador ATmega32u4: o código Arduino tem tratamento para mouse muito simples.



Lista de Materiais


1- Pro Micro - 5V/16MHz - SparkfunAliExpress US$ 6,44, Lab de Garagem
1- Thumb Joystick - Sparkfun US$ 4,95, AliExpressLab de Garagem
1- Cabo USB microB - Sparkfun, AliExpress US$ 0,85, Lab de Garagem
1- Cabo OTG (opcional para conectar em Smartphones/Tablets - Sparkfun US$ 2,95 



Hardware e Software

Ambas versões (Bluetooth e de baixo custo) compartilham o mesmo firmware, basta configurar a variável:

boolean bluetooth=false;

Arquivo em:






Creative Commons License
The hardware and the software are released under Creative Commons Attribution-ShareAlike 4.0 International License.

terça-feira, 18 de novembro de 2014

Mouse para os Pés - Foot Mouse

O Mouse para os pés (Foot Mouse) é um dispositivo para controlar o cursor do mouse através dos pés. Foi desenvolvido usando componentes de baixo custo visando a reprodução dos mesmos.

A base do seu funcionamento é a placa Pro Micro (compatível com a Arduino Leonardo - ATmega32u4) que facilita em muito o desenvolvimento de dispositivos que atuam como mouse.

Basta conectar o cabo USB microB (mesmo usado para carregar a maioria dos smartphones) num computador que o Foot Mouse é reconhecido como um mouse padrão. Com um cabo OTG (On-The-Go) é possível conectar em smartphones ou tablets compatíveis com este padrão.

Reportagem da TV Tribuna sobre o Mouse para os Pés:


 Projeto da USP inclui deficientes intelectuais no uso de computadores

http://g1.globo.com/sp/santos-regiao/jornal-tribuna-2edicao/videos/t/edicoes/v/projeto-da-usp-inclui-deficientes-intelectuais-no-uso-de-computadores/3839035/

Lista de Materiais


1- Pro Micro - 5V/16MHz - Sparkfun, AliExpress US$ 6,44, Lab de Garagem
2- Thumb Joystick - Sparkfun, AliExpress US$ 4,68, Lab de Garagem
2- Caixas Patola PB 114-2 - Mult Comercial
1- Cabo USB microB - Sparkfun, AliExpress US$ 0,85, Lab de Garagem
1- Cabo OTG (opcional para conectar em Smartphones/Tablets - Sparkfun US$ 2,95 
2- Botões de pressão
8- Extensores




Circuito





Software e Hardware



GitHub: https://github.com/Marchanjo/FootMouse



Montagem



Posição do centro dos furos nos dois gabinetes, o diâmetro dos furos devem ser compatíveis com os botões de pressão em um gabinete no outro com o thumb joystick.

Enquanto trabalhava furando os gabinetes eu encapei com fita adesiva para evitar arranhões acidentais.


























Creative Commons License
The hardware and the software are released under Creative Commons Attribution-ShareAlike 4.0 International License.