Manual

do

Maker

.

com

Leitura digital para controle de open e close

Leitura digital para controle de open e close

Os últimos posts mostram recursos que serão aplicados ao projeto do cofrinho eletrônico, mas precisamente nesse post ainda há algo importante a tratar - A abertura e o fechamento da plataforma por onde desliza a moeda. Nesse post vou apenas descrever a ideia, a percepção da abertura e fechamento e um exemplo de código. Todo o resto descrito aqui será implementado já no próximo post.

Se estivéssemos utilizando um servo motor ou um motor de passo, Não seria necessário esse trabalho, mas o custo se elevaria, afinal - "qualidade infinita, custo infinito". E mais, só dá trabalho da primeira vez, depois é só replicar (exceto as calibragens, tanto do motor quanto do LDR do sensor de moedas)!

Então deixando a preguiça de lado, vejamos o cenário; as portas B foram reservadas para as moedas, ainda há espaço no RB2 e RB3, mas invés de utilizar IOC, vamos utilizar a leitura digital nas portas RA0 e RA7. Talvez você se pergunte o porque utilizar duas portas nesse momento. Até poderia utilizar apenas uma, mas os pinos estão aí para serem utilizados e isso facilitará no tratamento lógico.

Esses dois pinos ajudarão na localização do posicionamento da porta, de uma forma a escolher. Se estiver em cima, estará fechado, então uma variável OPEN_CLOSE é marcada como 0. O loop principal verifica se o estado da porta é aberto (1), então verifica o nível lógico de RA7. Se a porta estiver realmente aberta, então faz um delay de 1 segundo, passa OPEN_CLOSE para 0 e lê o pino RA0 até que a porta esteja fechada. O estado da porta é mudado na interrupção. Isto quer dizer que a porta pode estar fechada, mas recebeu um pedido para abrir, então o estado da porta é validado e sua abertura é efetuada. Após 1 segundo, ela é fechada.

A abertura e fechamento pode ser feita através de uma função chamada pela interrupção. Então não precisará estar em um loop. Nesse caso pode ser mais simples:

  • Função recebe parâmetro OPEN (1)
  • abre
  • espera 1 segundo
  • fecha

As portas RA serão utilizadas para verificar o nível lógico. Assim economiza-se processamento (por não haver polling) e também economiza memória, como a qual seria utilizada para a variável OPEN_CLOSE. Vou pela segunda opção.

Essa foi a lógica no nível macro, agora entrando em mais detalhes, os passos seriam:

  • Chamar a função, que:
  • verifica a porta que fará a leitura (parametro da função 0 ou 1, para abrir ou fechar)
  • liga o motor até que a interrupção de opened aconteça
  • desliga o motor
  • delay de 1 segundo
  • liga o motor até que a interrupção de closed aconteça.
  • desliga o motor

O restante do tratamento é feito pela função interrupts, sendo que esssa parte já está pronta, então simplesmente adicionamos código para uma funcionalidade específica.

Porque "quase interrupção"

Esse tipo de tratamento exemplificado nesse post não é uma interrupção propriamente dito. As interrupções do hardware são tratados via flags do próprio hardware, enquanto fazer a leitura de sinal de um pino necessita ainda outros tratamentos.

Se você leu os posts sobre interrupções e os posts sobre IOC, pode lhe ser um pouco complicado de imediato, mas é mais simples tratar as interrupções do hardware do que fazer polling. Mas ainda assim não é polling também porque a verificação do nível de sinal só será executada quando solicitada pela interrupção, então o trabalho no código pode-se dizer que é intermediário.

Leitura digital

Para uma leitura digital, o trabalho não é tão grande e vou criar aqui um código pequeno apenas para exemplificar.


sbit CLOSED_TRIS at TRISA0_bit;
sbit CLOSED      at RA0_bit;

sbit OPENED_TRIS at TRISA7_bit;
sbit OPENED      at RA7_bit;

sbit LED_VERDE_TRIS at TRISA1_bit;
sbit LED_VERDE      at RA1_bit;

void main(){
    ANSELA = 0;
    C1ON_bit = 0; //desativar comparadores
    C2ON_bit = 0;
    //configura as portas
    OPENED_TRIS    = 0;
    CLOSED_TRIS    = 0;
    LED_VERDE_TRIS = 0;
    LED_VERDE      = 0;
    //Desativar conversor AD
    ADCON0 = 0;
    ADCON1 = 0;
    //Desativar pull-ups (default, mas estou enfatizando, depois explico)
    WPUB = 0x00;
    WPUA = 0x00;

    while (1){
      if (OPENED){
        LED_VERDE = ~LED_VERDE;
        Delay_ms(1000);
        OPENED = 0;
        Delay_ms(1000);
      }
  }
}

Com um LED (não necessariamente verde) na porta RA1, você poderá visualizar essa mudança de estado graças a esse loop criado para teste.

Repare que a leitura aqui é digital, então não precisamos ler valores para uma variável, apenas ver se o estado foi para HIGH. Depois disso deve-se baixar o pino novamente e pronto.

Pull-up

Quando necessita-se de um nível de sinal estável, deve-se utilizar resistores de pull-up ou no caso desse modelo de PIC, seu próprio recurso interno de pull-up.

No código sobre IOC eu levantei todos os WPUB, mas isso foi um erro. Isso eu descobri lendo sobre os pull-ups no datasheet, e nele está descrito que os WPUx são desabilitados automaticamente quando os pinos são colocados em output. Não sei para quantos modelos isso vale, mas para esse é assim.

Além disso, se for usar pull-ups em algum outro caso onde seja válido, é necessário habilitá-lo com WPUEN = 1.

O hardware

Como foi visto em outro post, a plataforma provisória foi revestida com papel alumínio de um bombom. Para fazer a interrupção da porta aberta, será necessário revestir a parte de baixo da base também, logo, comerei outro bombom.

A base é mantida com 5v não aterrado, enquanto os pinos do sensor de moedas são conectados aos pinos da MCU. Como a base já tem o sinal, o único trabalho será posicionar contatos para as mudanças de estado de RA0 e RA7.

Não tenho certeza de que seja necessário, mas se quiser limitar a 20mA, use um resistor de 15ohms ou menos para não conectar diretamente os 5v à MCU. Particularmente, não utilizarei na base assim como não utilizarei também nas interrupções das moedas.

Outra coisa muito importante que não falei é que essa MCU tem sensor capacitivo responsivo a variação de frequência ao contato - e estão aí habilitados no IOC. Se você segurar um fio jumper na mão em uma das pontas e tocar a outra no pino com IOC devidamente configurado, você obterá a mesma resposta que enviando um sinal de 5v. Então, pode não ser uma má ideia colocar resistores nesses pinos, mas fica a seu critério.

Enfim, esse é o código de exemplo para a leitura digital. A função será implementada no próximo post onde já veremos a abertura e fechamento automático na interrupção das moedas.

Se gostou, não deixe de compartilhar; dê seu like no video e inscreva-se no nosso canal Manual do Maker Brasil no YouTube.

Próximo post a caminho!

Nome do Autor

Djames Suhanko

Autor do blog "Do bit Ao Byte / Manual do Maker".

Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.