Índice:

IoT facilitada: ESP-MicroPython-MQTT-ThingSpeak: 12 etapas
IoT facilitada: ESP-MicroPython-MQTT-ThingSpeak: 12 etapas

Vídeo: IoT facilitada: ESP-MicroPython-MQTT-ThingSpeak: 12 etapas

Vídeo: IoT facilitada: ESP-MicroPython-MQTT-ThingSpeak: 12 etapas
Vídeo: Comprove no-de e HIVEMQ 2024, Julho
Anonim
IoT facilitada: ESP-MicroPython-MQTT-ThingSpeak
IoT facilitada: ESP-MicroPython-MQTT-ThingSpeak

Em meu tutorial anterior, MicroPython no ESP usando Jupyter, aprendemos como instalar e executar o MicroPython em um dispositivo ESP. Usando o Jupyter Notebook como nosso ambiente de desenvolvimento, também aprendemos a ler a partir de sensores (Temperatura, Umidade e Luminosidade). Usamos diversos protocolos e métodos de comunicação, Analógico, Digital, 1-Fio e I2C, este último para exibir nossos dados capturados dados em um display OLED.

Agora, neste tutorial usando um protocolo MQTT, obteremos todos os dados capturados, enviando-os para um serviço IoT, ThingSpeak.com e para um aplicativo móvel (Thingsview), onde podemos registrar e brincar com os dados.

Aqui, o diagrama de blocos do nosso projeto:

Imagem
Imagem

Etapa 1: BoM - Lista de materiais

  1. NodeMCU - US $ 8,39
  2. Sensor DHT22 de Temperatura e Umidade Relativa - US $ 9,95
  3. Sensor de temperatura à prova d'água DS18B20 - US $ 5,95
  4. Display OLED SSD1366 - US $ 8,99 (opcional)
  5. LDR (1x)
  6. LEDs (1x) (opcional)
  7. Botão (1x)
  8. Resistor 4K7 ohm (2x)
  9. Resistor 10K ohm (1x)
  10. Resistor 220 ohm (1x)

Etapa 2: o Hw

O Hw
O Hw

O Hw que usaremos aqui basicamente é o mesmo usado no tutorial: Micropython em ESP usando Jupyter. Consulte-o para todas as conexões HW.

A exceção é o Servo, que não será usado neste projeto.

Acima você pode ver o HW completo. Conecte os dispositivos conforme mostrado lá.

Etapa 3: Micropython, REPL, Jupyter

Micropython, REPL, Jupyter
Micropython, REPL, Jupyter
Micropython, REPL, Jupyter
Micropython, REPL, Jupyter

Você deve ter um intérprete Micropython carregado em seu dispositivo ESP. Uma vez carregado, você deve programar seu ESP usando qualquer uma das formas / IDEs disponíveis, como:

  • REPL
  • Notebook Jupyter
  • Mu
  • ESPCut (somente Windows)
  • … etc

Em meu tutorial, Micropython sobre ESP usando Jupyter, detalhei como baixar e instalar o interpretador MicroPython, ESPTool para gerenciar dispositivos ESP e como usar o Notebook Jupyter como um ambiente de desenvolvimento. Fique à vontade para usar o que for mais confortável para você.

Normalmente faço todo o desenvolvimento no Jupyter Notebook e, quando obtenho o código final, copio-o para o Geany e o carrego em meu ESP usando o Ampy.

Etapa 4: Sensores

Sensores
Sensores

Vamos instalar as bibliotecas, definir GPIO, criar objetos, funções para todos os sensores individualmente:

A. DHT (Temperatura e Umidade)

Vamos instalar a biblioteca DHT e criar um objeto:

de dht import DHT22

da importação da máquina Pin dht22 = DHT22 (Pin (12))

Agora, crie uma função para ler o sensor DHT:

def readDht ():

dht22.measure () return dht22.temperature (), dht22.humidity () Função DHT de teste

imprimir (readDht ())

O resultado deve ser, por exemplo:

(17.7, 43.4)

B. DS18B20 (temperatura externa)

Vamos instalar as bibliotecas e criar um objeto:

importar onewire, ds18x20

import time # Define qual pino o dispositivo de 1 fio será conectado ==> pino 2 (D4) dat = Pin (2) # crie o objeto onewire ds = ds18x20. DS18X20 (onewire. OneWire (dat)) Procure dispositivos no bu

sensores = ds.scan ()

imprimir ('dispositivos encontrados:', sensores)

O resultado impresso não é muito importante, o que vamos precisar é o primeiro sensor detectado: sensores [0]. E agora, podemos construir uma função para ler os dados do sensor:

def readDs ():

ds.convert_temp () time.sleep_ms (750) return ds.read_temp (sensores [0])

É sempre importante testar o sensor usando a função criada

imprimir (readDs ()) Se você obtiver um valor de temperatura, seu código está correto

17.5

C. LDR (Luminosidade)

O LDR usará o pino analógico do nosso ESP (é apenas um no caso do ESP8266 e vários no ESP32).

Consulte meu tutorial ESP32 para obter detalhes.

O mesmo que antes:

# biblioteca de importação

da máquina import ADC # Define object adc = ADC (0) Uma função simples: adc.read () pode ser usada para ler o valor ADC. Mas lembre-se que o ADC interno irá converter tensões entre 0 e 3,3 V em valores digitais correspondentes, variando de 0 a 1023. Uma vez que estamos interessados em "Luminosidade", vamos considerar a luz Máxima como o valor máximo capturado pelo sensor (no meu caso 900) e luz mínima que no meu caso é 40. Tendo esses valores podemos "mapear" o valor de 40 a 900 em 0 a 100% de luminosidade. Para isso, vamos criar uma nova função

def readLdr ():

lumPerct = (adc.read () - 40) * (10/86) # converter em porcentagem ("mapa") volta de retorno (lumPerct)

Você deve testar a função usando print (readLDR ()). O resultado deve ser um número inteiro entre o e 100.

D. Botão (entrada digital)

Aqui estamos usando um Push-Button como sensor digital, mas poderia ser um "eco" de um atuador (Uma bomba que foi LIGADA / DESLIGADA, por exemplo).

# define o pino 13 como uma entrada e ativa um resistor pull-up interno:

button = Pin (13, Pin. IN, Pin. PULL_UP) # Função para ler o estado do botão: def readBut (): return button.value ()

Você pode testar o botão lendo a função print (readBut ()). Sem pressionar, o resultado deve ser "1". Pressionando o botão, o resultado deve ser "0"

Etapa 5: captura e exibição local de todos os dados do sensor

Captura e exibição local de todos os dados do sensor
Captura e exibição local de todos os dados do sensor

Agora que criamos uma função para cada sensor, vamos criar a última que irá ler todos eles ao mesmo tempo:

def colectData ():

temp, hum, = readDht () extTemp = readDs () lum = readLdr () butSts = readBut () return temp, hum, extTemp, lum, butSts Agora se você usar

imprimir (colectData ())

Resultará em uma tupla que inclui todos os dados capturados dos sensores:

(17.4, 45.2, 17.3125, 103, 1)

Também podemos, opcionalmente, mostrar esses dados em um display local:

# importar biblioteca e criar objeto i2c

da máquina import I2C i2c = I2C (scl = Pin (5), sda = Pin (4)) # importar biblioteca e criar objeto oled import ssd1306 i2c = I2C (scl = Pin (5), sda = Pin (4)) oled = ssd1306. SSD1306_I2C (128, 64, i2c, 0x3c) # criar uma função: def displayData (temp, hum, extTemp, lum, butSts): oled.fill (0) oled.text ("Temp:" + str (temp) + "oC", 0, 4) oled.text ("Hum:" + str (hum) + "%", 0, 16) oled.text ("ExtTemp:" + str (extTemp) + "oC", 0, 29) oled.text ("Lumin:" + str (lum) + "%", 0, 43) oled.text ("Button:" + str (butSts), 0, 57) oled.show () # exibir dados usando a função displayData (temp, hum, extTemp, lum, butSts)

Como opção, também incluirei o LED para LIGAR quando começarmos a ler os sensores, desligando depois que os dados forem exibidos. Isso ajudará a confirmar se o programa está funcionando quando tivermos o ESP desconectado do PC e executado automaticamente.

Portanto, a função principal seria:

# Função principal para ler todos os sensores

def main (): # exibe dados com uma função led.on () temp, hum, extTemp, lum, butSts = colectData () displayData (temp, hum, extTemp, lum, butSts) led.off ()

Assim, executando main (), obteremos os dados do sensor exibidos no OLED conforme mostrado na imagem.

Etapa 6: Executar o código da estação local na inicialização do ESP

Execução do código da estação local na inicialização do ESP
Execução do código da estação local na inicialização do ESP

Podemos ter tudo o que foi desenvolvido até agora em um único arquivo para ser executado pelo nosso ESP.

Vamos abrir qualquer editor de texto e colar todo o código:

# import bibliotecas gerais

da importação da máquina Pin import time # define o pino 0 como saída led = Pin (0, Pin. OUT) # DHT from dht import DHT22 dht22 = DHT22 (Pin (12)) # Função para ler DHT def readDht (): dht22.measure () return dht22.temperature (), dht22.humidity () # DS18B20 import onewire, ds18x20 # Defina qual pino o dispositivo de 1 fio será conectado ==> pino 2 (D4) dat = Pino (2) # Crie o onewire objeto ds = ds18x20. DS18X20 (onewire. OneWire (dat)) # procura dispositivos nos sensores de barramento = ds.scan () # função para ler DS18B20 def readDs (): ds.convert_temp () time.sleep_ms (750) return round (ds.read_temp (sensores [0]), 1) # LDR da importação da máquina ADC # Define o objeto adc = ADC (0) #função para ler a luminosidade def readLdr (): lumPerct = (adc.read () - 40) * (10/86) # converter em porcentagem ("mapa") retorno (lumPerct) # definir o pino 13 como uma entrada e ativar um resistor pull-up interno: botão = Pin (13, Pin. IN, Pin. PULL_UP) # Função para ler o estado do botão: def readBut (): return button.value () # Função para ler todos os dados: def cole ctData (): temp, hum, = readDht () extTemp = readDs () lum = readLdr () butSts = readBut () retornar temp, hum, extTemp, lum, butSts # importar biblioteca e criar o objeto i2c da máquina import I2C i2c = I2C (scl = Pin (5), sda = Pin (4)) # importar biblioteca e criar objeto oled import ssd1306 i2c = I2C (scl = Pin (5), sda = Pin (4)) oled = ssd1306. SSD1306_I2C (128, 64, i2c, 0x3c) # criar uma função: def displayData (temp, hum, extTemp, lum, butSts): oled.fill (0) oled.text ("Temp:" + str (temp) + "oC", 0, 4) oled.text ("Hum:" + str (hum) + "%", 0, 16) oled.text ("ExtTemp:" + str (extTemp) + "oC", 0, 29) oled. text ("Lumin:" + str (lum) + "%", 0, 43) oled.text ("Button:" + str (butSts), 0, 57) oled.show () # Função principal para ler todos os sensores def main (): # exibe dados com uma função led.on () temp, hum, extTemp, lum, butSts = colectData () displayData (temp, hum, extTemp, lum, butSts) led.off () '' '- ----- execute a função principal -------- '' 'main ()

Salve-o, por exemplo, como localData.py.

Para executar este código diretamente em seu terminal, você precisará do Ampy.

Primeiro, no Terminal, vamos informar ao Ampy nossa porta serial:

export AMPY_PORT = / dev / tty. SLAB_USBtoUART

Agora, podemos ver os arquivos que estão dentro do nosso diretório raiz do ESP:

ampy ls

Como resposta, obteremos boot.py, que é o primeiro arquivo que será executado no sistema.

Agora, vamos usar o Ampy para carregar nosso script python LocalData.py como /main.py, para que o script seja executado logo após a inicialização:

ampy put localData.py / main / py

Se usarmos o comando amp ls agora, você verá 2 arquivos dentro do ESP.: boot.py e main.py

Reinicializar o ESP fará com que o programa localData.py seja executado automaticamente, exibindo os dados do sensor no visor.

A tela de impressão do Terminal acima mostra o que fizemos.

Com o código acima, o display será mostrado apenas uma vez, mas podemos definir um loop na função main (), que mostrará os dados a cada intervalo de tempo definido (PUB_TIME_SEC), e por exemplo, até pressionarmos o botão:

# loop obtendo dados até que o botão seja pressionado

enquanto button.value (): led.on () temp, hum, extTemp, lum, butSts = colectData () displayData (temp, hum, extTemp, lum, butSts) led.off () time.sleep (PUB_TIME_SEC)

A variável PUB_TIME_SEC deve ser declarada no momento em que você deseja suas amostras.

Para aprimorar mais nosso código, seria bom informar que sairemos do loop, para isso definiremos 2 novas funções gerais, uma para limpar o display e outra para piscar o LED um determinado número de vezes.

# Clear display:

def displayClear (): oled.fill (0) oled.show () # cria uma função de piscar def blinkLed (num): para i no intervalo (0, num): led.on () sleep (0,5) led.off () dormir (0,5)

Então, podemos agora, reescrever nossa função main ():

enquanto button.value ():

led.on () temp, hum, extTemp, lum, butSts = colectData () displayData (temp, hum, extTemp, lum, butSts) led.off () time.sleep (PUB_TIME_SEC) blinkLed (3) displayClear ()

O código final pode ser baixado do meu GitHub: localData.py e também do Jupyter Notebook usado para o desenvolvimento do código completo: Jupyter Local Data Development.

Etapa 7: Conectando o ESP ao WiFi local

Conectando o ESP ao WiFi local
Conectando o ESP ao WiFi local

O módulo de rede é usado para configurar a conexão sem fio. Existem duas interfaces WiFi, uma para a estação (quando o ESP8266 se conecta a um roteador) e uma para o ponto de acesso (para outros dispositivos se conectarem ao ESP8266). Aqui, nosso ESP será conectado à rede local. Vamos chamar a biblioteca e definir nossas credenciais de rede:

rede de importação

WiFi_SSID = "SEU SSID" WiFi_PASS = "SUA SENHA"

A função abaixo pode ser usada para conectar o ESP à sua rede local:

def do_connect ():

wlan = network. WLAN (network. STA_IF) wlan.active (True) se não wlan.isconnected (): print ('conectando à rede…') wlan.connect (WiFi_SSID, WiFi_SSID) enquanto não wlan.isconnected (): pass print ('configuração de rede:', wlan.ifconfig ())

Executando a função, você pode obter como resultado o endereço IP:

do_connect ()

O resultado será:

configuração de rede: ('10.0.1.2 ',' 255.255.255.0 ', '10.0.1.1', '10.0.1.1 ')

Onde, no meu caso, 10.0.1.2, é o endereço IP do ESP.

Etapa 8: The ThingSpeak

The ThingSpeak
The ThingSpeak

Neste ponto, aprendemos como capturar dados de todos os sensores, exibindo-os em nosso OLED. Agora, é hora de ver como enviar esses dados para uma plataforma IoT, o ThingSpeak.

Vamos começar!

Primeiro, você deve ter uma conta no ThinkSpeak.com. Em seguida, siga as instruções para criar um canal e anote o ID do canal e a chave de API de gravação.

Acima você pode ver os 5 campos que serão utilizados em nosso Canal.

Etapa 9: Protocolo MQTT e conexão ThingSpeak

Protocolo MQTT e conexão ThingSpeak
Protocolo MQTT e conexão ThingSpeak

MQTT é uma arquitetura de publicação / assinatura desenvolvida principalmente para conectar largura de banda e dispositivos com restrição de energia em redes sem fio. É um protocolo simples e leve que roda em soquetes TCP / IP ou WebSockets. MQTT sobre WebSockets pode ser protegido com SSL. A arquitetura publicar / assinar permite que as mensagens sejam enviadas por push para os dispositivos clientes sem que o dispositivo precise consultar continuamente o servidor.

O broker MQTT é o ponto central de comunicação e é responsável por despachar todas as mensagens entre os remetentes e os destinatários legítimos. Um cliente é qualquer dispositivo que se conecta ao broker e pode publicar ou assinar tópicos para acessar as informações. Um tópico contém as informações de roteamento para o broker. Cada cliente que deseja enviar mensagens as publica em um determinado tópico, e cada cliente que deseja receber mensagens se inscreve em um determinado tópico. O corretor entrega todas as mensagens com o tópico correspondente aos clientes apropriados.

ThingSpeak ™ tem um broker MQTT no URL mqtt.thingspeak.com e porta 1883. O broker ThingSpeak suporta publicação MQTT e assinatura MQTT.

Em nosso caso, usaremos: MQTT Publish

Imagem
Imagem

A figura descreve a estrutura do tópico. A Write API Key é necessária para publicar. O corretor reconhece um CONNECTrequest correto com CONNACK.

O protocolo MQTT é compatível com uma biblioteca integrada nos binários Micropython - este protocolo pode ser usado para enviar dados de seu ESP8266, por WIFI, para um banco de dados em nuvem gratuito.

Vamos usar a biblioteca umqtt.simple:

from umqtt.simple import MQTTClient

E conhecendo nosso SERVER ID, é possível criar nosso objeto cliente MQTT:

SERVER = "mqtt.thingspeak.com"

client = MQTTClient ("umqtt_client", SERVER)

Agora, tendo suas credenciais ThingSpeak em mãos:

CHANNEL_ID = "ID DO SEU CANAL"

WRITE_API_KEY = "SUA CHAVE AQUI"

Vamos criar nosso "Tópico" MQTT:

tópico = "canais /" + CHANNEL_ID + "/ publicar /" + WRITE_API_KEY

Vamos enviar nossos dados para o ThingSpeak IoT Service, usando a função criada e associar sua resposta a variáveis de dados específicas:

temp, hum, extTemp, lum, butSts = colectData ()

Com essas variáveis atualizadas, podemos criar nosso "Payload MQTT":

payload = "field1 =" + str (temp) + "& field2 =" + str (hum) + "& field3 =" + str (extTemp) + "& field4 =" + str (lum) + "& field5 =" + str (butSts)

E é isso! Estamos prontos para enviar dados ao ThinsSpeak, simplesmente usando as 3 linhas de código abaixo:

client.connect ()

client.publish (tópico, carga útil) client.disconnect ()

Agora, se você for à página do seu canal (como a minha acima), verá que cada um dos 5 campos terá dados relacionados aos seus sensores.

Etapa 10: registrador de dados do sensor

Sensor Data Logger
Sensor Data Logger

Agora que sabemos que com apenas algumas linhas de código é possível fazer upload de dados para um serviço IoT, vamos criar uma função de loop para fazer isso automaticamente em um intervalo regular de tempo (semelhante ao que fizemos com "Dados locais ").

Usando a mesma variável (PUB_TIME_SEC), declarada antes, uma função principal simples para capturar dados continuamente, registrando-os em nosso canal seria:

enquanto verdadeiro:

temp, hum, extTemp, lum, butSts = colectData () payload = "field1 =" + str (temp) + "& field2 =" + str (hum) + "& field3 =" + str (extTemp) + "& field4 =" + str (lum) + "& field5 =" + str (butSts) client.connect () client.publish (topic, payload) client.disconnect () time.sleep (PUB_TIME_SEC)

Observe que apenas a "carga útil" deve ser atualizada, uma vez que o "tópico" está relacionado à credencial de nosso canal e não será alterado.

Olhando para a página do seu canal ThingSpeak, você observará que os dados serão carregados continuamente para cada campo. Você pode cobrir o LDR, colocar sua mão nos sensores de temp / hum, pressionar o botão, etc. e ver como o canal será automaticamente "registrar" esses dados para análise futura.

Normalmente, para registro de dados, devemos tentar usar o mínimo de energia possível, portanto, não usaríamos o LED ou o monitor localmente. Além disso, é comum com os dispositivos ESP colocá-los em "hibernação", onde o microprocessador ficará em seu estado de energia mínima até o momento de capturar os dados e enviá-los para a plataforma IoT.

Mas, uma vez que aqui a ideia é aprender, vamos incluir também o display e o LED como fizemos antes. Fazendo isso, nossa função de "logger" será:

enquanto button.value ():

led.on () temp, hum, extTemp, lum, butSts = colectData () displayData (temp, hum, extTemp, lum, butSts) led.off () temp, hum, extTemp, lum, butSts = colectData () carga útil = "field1 =" + str (temp) + "& field2 =" + str (hum) + "& field3 =" + str (extTemp) + "& field4 =" + str (lum) + "& field5 =" + str (butSts) cliente.connect () client.publish (topic, payload) client.disconnect () time.sleep (PUB_TIME_SEC) blinkLed (3) displayClear ()

O script microPython completo pode ser encontrado aqui: dataLoggerTS_EXT.py e o bloco de notas Jupyter que foi usado para desenvolvimento também pode ser encontrado aqui: IoT ThingSpeak Data Logger EXT.ipynb.

Para fazer upload do script no ESP, em seu terminal, use o comando:

ampy put dataLoggerTS.py /main.py

E pressione o botão ESP - reset. Você terá o ESP capturando dados e registrando-os em ThingSpeak.com até que a parte inferior seja mantida pressionada (espere o LED piscar 3 vezes e o OLED desligar).

Etapa 11: O aplicativo ThingView

O aplicativo ThingView
O aplicativo ThingView

Os dados registrados podem ser visualizados diretamente no site ThingSpeak.com ou por meio de um APP, por exemplo, ThingsView!

ThingView é um APP desenvolvido pela CINETICA, que permite visualizar seus canais ThingSpeak de forma fácil, basta inserir o ID do canal e pronto.

Para canais públicos, o aplicativo respeitará as configurações de sua janela: cor, escala de tempo, tipo de gráfico e número de resultados. A versão atual suporta gráficos de linha e coluna, os gráficos de spline são exibidos como gráficos de linha.

Para canais privados, os dados serão exibidos usando as configurações padrão, pois não há como ler as configurações das janelas privadas apenas com a chave API.

O aplicativo ThingView pode ser baixado para ANDROID e IPHONE.

Etapa 12: Conclusão

Conclusão
Conclusão

Como sempre, espero que este projeto possa ajudar outras pessoas a encontrar seu caminho para o emocionante mundo da eletrônica!

Para obter detalhes e o código final, visite meu depósito do GitHub: IoT_TS_MQTT

Para mais projetos, visite meu blog: MJRoBot.org

Saludos do sul do mundo!

Vejo você no meu próximo instrutível!

Obrigado, Marcelo

Recomendado: