Sensor de presença PIR com registradores do Atmega328p

Eletrônica Arduino 17 de Novembro de 2019 às 13:49

No artigo anterior foi explanado como os registradores do Atmega328p funcionam internamente e na programação em C/C++, e foi desenvolvido um código para piscar um LED utilizando o Atmel Studio 7, AVRDude e USBasp. Neste artigo será apresentado como programar um sensor PIR utilizando a mesma metodologia, e expandindo os conhecimentos na arquitetura AVR.

Para realizar este artigo de forma efetiva, é obrigatório a leitura do artigo anterior "Programando o Atmega328p com registradores", onde apresentamos correções de possíveis erros com o gravador USBasp, e teoria/prática das portas I/O do microcontrolador Atmega328p.

O sensor PIR DYP-ME003 ou de presença é utilizado principalmente para o acionamento de lâmpadas por meio de um relé. O sensor é ativado em nível alto (HIGH) quando uma pessoa, animal ou objeto passa em uma área de 5-7 metros de distância e em um ângulo de 100 graus. O sensor é desativado em nivel baixo (LOW) automaticamente por um delay próprio que pode ser ajustado pelo potenciômetro "Time" entre 5-300 segundos, e o potenciômetro "Sensitive" ajusta a sensibilidade de detecção do sensor PIR.

Montagem

Para este artigo utilize uma placa Arduino Uno ou um Arduino Standalone Atmega328p, ambos com conexão ICSP.

Este projeto podemos montar ele de duas formas, um com LED ou um módulo relé. Para isso separe a lista de materiais necessários abaixo.

Projeto principal

  • 1 Arduino Uno ou Standalone Atmega328p.
  • 1 Gravador AVR USBasp com cabo ICSP 10 pinos
  • 1 Sensor PIR
  • 1 Protoboard pequeno
  • Fios jumpers

Projeto com LED

  • 1 LED
  • 1 Resistor de 220R

Projeto com módulo relé

Adaptador para USBasp e Arduino Uno ICSP.

Programando o Atmega328p

Abra o Atmel Studio 7 e crie um projeto com o nome de "SensorPir" e selecione o microcontrolador Atmega328p.

Copie e cole este código abaixo, compile e grave o código utilizando o gravador USBasp, em Tools/AVRDude USBasp.

/*
 * SensorPir.cpp
 *
 * Created: 27/09/2019 16:55:40
 * Author : tecdicas
 */ 

#define F_CPU 16000000UL // Cristal de 16MHz
#include <avr/io.h>

int main(void)
{
    DDRD &= ~(1 << DDD3); // Configura o PD3 como INPUT (sensor PIR)
    DDRD |= (1 << DDD4); // Configura o PD4 como OUTPUT (LED/Relé)
	
    while (1) 
    {
        bool pir = (PIND & (1 << PIND3)); // Ler o valor do PIR
		
        if(pir == false)
        {
            PORTD &= ~(1 << PORTD4); // Desliga LED/Relé
        }
        else
        {
            PORTD |= (1 << PORTD4); // Liga LED/Relé
        }
    }
}

Se a compilação for bem sucedida..

Build succeeded.
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========

E se a gravação for bem sucedida..

avrdude.exe: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude.exe: Device signature = 0x1e950f
avrdude.exe: NOTE: FLASH memory has been specified, an erase cycle will be performed
             To disable this feature, specify the -D option.
avrdude.exe: erasing chip
avrdude.exe: reading input file "D:\Projetos\AtmelStudio\SensorPir\SensorPir\Debug\SensorPir.hex"
avrdude.exe: writing flash (148 bytes):

Writing | ################################################## | 100% 0.07s

avrdude.exe: 148 bytes of flash written
avrdude.exe: verifying flash memory against D:\Projetos\AtmelStudio\SensorPir\SensorPir\Debug\SensorPir.hex:
avrdude.exe: load data flash data from input file D:\Projetos\AtmelStudio\SensorPir\SensorPir\Debug\SensorPir.hex:
avrdude.exe: input file D:\Projetos\AtmelStudio\SensorPir\SensorPir\Debug\SensorPir.hex contains 148 bytes
avrdude.exe: reading on-chip flash data:

Reading | ################################################## | 100% 0.05s

avrdude.exe: verifying ...
avrdude.exe: 148 bytes of flash verified

avrdude.exe: safemode: Fuses OK

avrdude.exe done.  Thank you.

Ajuste os potenciômetros da forma que preferir, onde o LED ou relé irão ligar e desligar conforme a detecção do sensor PIR.

Analisando o código

Vamos analisar a forma em que os registradores foram utilizados na programação em C/C++.

Direções das portas

Dentro da estrutura int main() configuramos a porta PD3 como INPUT, utilizando o registrador DDRD, e o terceiro bit DDD3 setamos como 0/falso utilizando a técnica Bitwise de NAND. A porta PD4 foi configurada como OUTPUT, utilizando também o registrador DDRD, e o quarto bit DDD4 setamos como 1/verdadeiro, utilizando o mesmo método de bitwise, porém com a lógica OR.

DDRD &= ~(1 << DDD3); // Configura o PD3 como INPUT (sensor PIR)
DDRD |= (1 << DDD4); // Configura o PD4 como OUTPUT (LED/Relé)
Registrador DDRD - Atmega328p.

O código equivalente utilizando a "linguagem Arduino" seria:

pinMode(3, INPUT);
pinMode(4, OUTPUT);

Leitura da porta input

Dentro da estrutura while (1) realizamos a leitura da porta PD3 setada como INPUT com o registrador PIND, e setamos o terceiro bit PIND3 como 1/verdadeiro. Fisicamente é a conexão com o sensor PIR, e guardamos o estado de false ou true dentro da variável do tipo bool pir.

bool pir = (PIND & (1 << PIND3)); // Ler o valor do PIR
Registrador PIND - Atmega328p.

O código equivalente utilizando a "linguagem Arduino" seria:

bool pir = digitalRead(3);

Estados da porta output

Com o valor obtido da porta PD3 e armazenado na variável pir, os estados da porta PD4 são definidos por uma estrutura condicional IF ELSE, se a variável pir for igual a false, desligamos o LED/Relé utilizando o registrador PORTD e o quarto bit como 0/falso utilizando o bitwise NAND. Então se a variável for igual a verdadeiro, ligamos o LED/Relé utilizando novamente o registrador PORTD com o quarto bit em 1/verdadeiro com o bitwise OR.

if(pir == false)
{
    PORTD &= ~(1 << PORTD4); // Desliga LED/Relé
}
else
{
    PORTD |= (1 << PORTD4); // Liga LED/Relé
}
Registrador PORTD - Atmega328p.

O código equivalente utilizando a "linguagem Arduino" seria:

if(pir == false)
{
    digitalWrite(4, LOW);
}
else
{
    digitalWrite(4, HIGH);
}

Referência

  1. ATMEGA328P: 8-bit AVR Microcontroller with 32K Bytes In-System Programmable Flash - Datasheet Atmel.