from machine import Pin, PWM, I2C #Manipulação das GPIOs
from time import sleep_ms, ticks_ms
import network #Conexão com a rede e access point
import socket #Construção da página web
#As linhas abaixo são opcionais:
import esp #Para usar na remoção de mensagens de sistema do ESP
import gc #Para remoção dos objetos não usados
esp.osdebug(None) #Desliga as mensagens de debug da espressif
gc.collect() #Garbage Collector - Limpa os objetos não usados da memória do microcontrolador
#Configuração dos componentes do sistema
#Observação: os botões serão configurados como um INPUT_PULLUP, ou seja, seu valor lógico começa como 1(True)
botao1 = Pin(15, Pin.IN, Pin.PULL_UP) #Botão que ativa e desativa(o único que desativa) o alarme(sirene e estrobo)
#Estrobo:
led1 = Pin(2,Pin.OUT) #Led 1 do pisca-pisca
led2 = Pin(4,Pin.OUT) #Led 2 do pisca-pisca
#Sirene:
som = PWM(Pin(5,Pin.OUT), freq = 500, duty_u16 = 65535//2)
botao2 = Pin(18, Pin.IN, Pin.PULL_UP) #Botão de pânico(Solta uma mensagem no LCD e ativa o alarme, porém não o desativa)
#Configuração dos sensores:
#Sensor de abertura de janelas:
botao3 = Pin(13, Pin.IN, Pin.PULL_UP)
#Sensor de presença na área externa:
botao4 = Pin(14, Pin.IN, Pin.PULL_UP)
#Sensor perimétrico IR nos muros:
botao5 = Pin(26, Pin.IN, Pin.PULL_UP)
#Sensor de abertura de porta social/serviço:
botao6 = Pin(33, Pin.IN, Pin.PULL_UP)
#Sensor de abertura do portão:
botao7 = Pin(34, Pin.IN, Pin.PULL_UP)
#Variáveis auxiliares
rep = 0 #Evitar repique dos botões
t = 0 #Temporização
bot = True #Botões
a_leds = True #LEDs do estrobo
i = 0 #Variável auxiliar de controle do alarme
toca_alarme = False
#Web página
wlan = network.WLAN(network.STA_IF) #Criação da station interface
wlan.active(True) #Ativação de interface
#Ajustanso as funções:
#Função que controla os botões:
#Definindo a interrupção:
#handler para a leitura do botão:
def apertouobotao(pino):
#Trazendo as variáveis para dentro da função:
global rep
global bot
global t
global toca_alarme
#Configuração da lógica do aperto dos botões:
#Botão do alarme:
if ((ticks_ms() - rep) > 200): #O valor do repique é 200 milissegundos, o que significa dizer que o aperto dos botões só funciona após os 200 milissegundos se passarem
rep = ticks_ms()
#Lógica para a ativação do alarme:
if ((botao1.value == bot) or (botao2.value == bot) or (botao3.value != bot) or (botao4.value != bot) or (botao5.value != bot) or (botao6.value != bot) or (botao7.value != bot) ): #A condição leva em consideraçaõ os estados de todos os botões para ativar o alarme, sendo os botões 1 e 2 como True pois suas interrupções serão do tipo rising e o resto dos botões como False pois suas interrupções serão do tipo falling
toca_alarme = True
#Configurando o que cada botão faz:
#Botão de pânico:
if (botao2.value == bot):
lcd.putstr("ALERTA, INVASAO!LIGANDO PARA 190!")
#Sensor de abertura de janelas:
if (botao3.value != bot): #Pega o valor oposto ao valor do botão 2 já que ele está com o tipo de interrupção oposta
print("Invasão pelas janelas detectada!")
#Sensor de presença na área externa:
if(botao4.value != bot):
print("Presença na área externa detectada!")
#Sensor perimétrico IR nos muros:
if (botao5.value != bot):
print("Invasão pelos muros detectada!")
#Sensor de abertura de porta social/serviço:
if (botao6.value != bot):
print("Invasão pela porta de social/serviço detectada!")
#Sensor de abertura do portão:
if (botao7.value != bot):
print("Invasão pelo portão detectada!")
#Lógica para a desativação do alarme:
elif (botao1.value != bot): #O alarme apenas é desligado quando o valor lógico do botão for diferente de quando seu valor liga o alarme
led1.value(0)
led2.value(0)
som.duty_u16(0)
print("Alarme desligado.")
#Ajusta as interrupções dos botões do alarme e de pânico e os seus respectivos handlers. Já que a interrupção está como rising o aperto do botão só vai contar após ele ser solto, pois como ele começa em com o valor lógico de 1, quando é apertado ele vai para 0 e quando é solto volta para 1:
botao1.irq(trigger = Pin.IRQ_RISING, handler = apertouobotao)
botao2.irq(trigger = Pin.IRQ_RISING, handler = apertouobotao)
#Ajusta a interrupções dos sensores e o seus respectivo handlers. Já que a interrupção está como falling o aperto do botão só conta quando ele é pressionado, pois como ele começa com o valor lógico de 1, quando é apertado ele vai para 0, diferentemente do botão do alarme:
botao3.irq(trigger = Pin.IRQ_FALLING, handler = apertouobotao)
botao4.irq(trigger = Pin.IRQ_FALLING, handler = apertouobotao)
botao5.irq(trigger = Pin.IRQ_FALLING, handler = apertouobotao)
botao6.irq(trigger = Pin.IRQ_FALLING, handler = apertouobotao)
botao7.irq(trigger = Pin.IRQ_FALLING, handler = apertouobotao)
#Função que se conecta à rede:
def conectar(rede,senha):
global wlan
if (not wlan.isconnected()):
wlan.connect(rede,senha)
while (not wlan.isconnected()):
pass
return True
#Função que disponibiliza acesso a outros dispositivos:
def disponibilizaracesso(nomerede):
#Ajustando o access point (AP):
ap = network.WLAN(network.AP_IF) #Criando a interface do access point
ap.active(True)
ap.config(max_clients=5)
ap.config(ssid = 'RedeESP32', authmode=network.AUTH_WPA_WPA2_PSK, password = 'ESP32_Senha123')
if (ap.active()):
saida = True
else:
saida = False
return saida
#Função que mostra a página de acordo com o led da placa:
def pagina():
if (led1.value()) :
estado = "Sistema de Segurança Ativado"
else:
estado = "Sistema de Segurança Desativado"
html = """
<html>
<head>
<title>Gerenciamento de Segurança Residencial</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="icon" href="data:,">
<style>
html{font-family: Helvetica; display:inline-block; margin: 0px auto; text-align: center;}
h1{color: #020402; padding: 4vh;}
p{font-size: 1.5rem;}
.button{
background-color: #F80000;
border-radius: 10px;
padding: 16px 40px;
font-size: 30px;
margin: 2px;
}
.button2{background-color: #48f800;}
</style>
</head><body> <h1>Gerenciamento de Segurança Residencial</h1>
<p> <strong>""" + estado + """</strong></p>
<p><a href="/?ligaLED"><button class="button">Ativar botão de pânico</button></a></p>
<p><a href="/?desligaLED"><button class="button button2">Desativar botão de pânico</button></a></p></body></html>"""
return html
print('ESP32 iniciado!')
if conectar('A14 de Kaike','Kaike767'):
print('Conectado à rede:', wlan.ifconfig())
#Criando um socket para ficar ouvindo os requests de página (porta 80):
#Observação: a resposta ao request será o envio da página na variável html
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #Criando um socket TCP/IP
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #Deixa reutilizar um IP
s.bind(('',80)) #Ajusta para receber conexões de um determinado IP (vazio para qualquer IP) na porta 80
s.listen(4) #Número máximo de conexões recebidas=4
'''
if disponibilizaracesso('coice de preá'):
print('rede ',nomerede,' disponível!')
'''
#Loop pra ficar ouvindo requisições e lendo a interação dos usuários com o servidorzinho:
while True:
if toca_alarme:
if ((ticks_ms() - t) < 500): #Controla o ciclo do alarme em que o pisca-pisca acontece a cada meio segundo juntamente com a frequência do som do alarme que muda nesse mesmo intervalo de tempo, por isso o valor dessa subtração está menor que 500 millisegundos, já que esse if aciona a primeira parte do ciclo
t = ticks_ms()
led1.value(1)
led2.value(0)
som.duty_u16(65535//2)
som.freq(250)
print("Alarme ligado.")
elif ((ticks_ms() - t) > 500): #Aqui, como o valor de ticks_ms - t > 500, será acionada a segunda parte do ciclo
t = ticks_ms()
led1.value(not led1.value()) #Pega o valor oposto do valor do led1(led1 = 1 fica led1 = 0)
led2.value(not led2.value()) #led2 = 0 fica led2 = 1
som.duty_u16(65535//2)
som.freq(300)
conexao, endr = s.accept() #Método para aceitar a conexão, salvando em endr o endereço, enquanto conexao fica com a troca de pacotes do socket s
print('Conexão recebida de %s' % str(endr))
request = conexao.recv(1024)
request = str(request)
print('Solicitação recebida: %s' % request)
#Lendo se houve request para apagar e acender o LED:
led_on = request.find('/?ligaLED')
led_off = request.find('/?desligaLED')
if (led_on == 6):
a_leds = True #Define a variável auxiliar booleana do led como True porque ela vai ser utilizada para a parte do código que controla o estrobo
if (led_off == 6):
led1.value(0)
led2.value(0)
som.duty_u16(0)
if (a_leds == True): #Controla o estrobo
i = i + 1
led1.value(i%2)
led2.value(not led1.value())
som.duty_u16(65535//2)
if (i%2 == 0):
som.freq(250)
else:
som.freq(300)
resposta = pagina() #Carrega em "resposta" a página atualizada pela função "pagina"
#Finalmente, manda a página atualizada pro acessante:
conexao.send('HTTP/1.1 200 OK\n')
conexao.send('Content-Type: text/html\n')
conexao.send('Connection: close\n\n')
conexao.sendall(resposta)
conexao.close() #E encerra a conexão!