IoT com Python e Raspberry Pi: criando protótipos físicos
1. Fundamentos do Ecossistema IoT com Raspberry Pi
O Raspberry Pi revolucionou a prototipagem IoT ao oferecer um computador completo do tamanho de um cartão de crédito. Modelos como Raspberry Pi 4 e 5 oferecem GPIO de 40 pinos, Wi-Fi, Bluetooth e processamento suficiente para executar Python e bibliotecas de hardware simultaneamente. A plataforma permite conectar sensores, atuadores e módulos de comunicação, formando a base de protótipos físicos funcionais.
No contexto embarcado, Python se destaca pela simplicidade e pelas bibliotecas especializadas:
RPi.GPIO: controle direto dos pinos GPIOgpiozero: abstração de alto nível para sensores e atuadoressmbus: comunicação I2C com dispositivos externosspidev: interface SPI para conversores ADC e sensores rápidos
A arquitetura típica de um protótipo IoT segue o fluxo: sensores capturam dados do ambiente → processamento local no Raspberry Pi → atuadores executam ações físicas → conectividade envia informações para a nuvem ou rede local.
2. Configuração do Ambiente de Desenvolvimento
Para começar, instale o Raspberry Pi OS Lite (sem ambiente gráfico) para maior desempenho e menor consumo. Após a instalação inicial, habilite as interfaces de hardware:
sudo raspi-config
# Navegue para: Interface Options → I2C, SPI, GPIO → Enable
Crie um ambiente Python virtual isolado para cada projeto:
python -m venv iot_env
source iot_env/bin/activate
pip install RPi.GPIO gpiozero smbus2 paho-mqtt flask
Este ambiente mantém as dependências organizadas e evita conflitos entre projetos.
3. Leitura de Sensores com Python
Sensor de presença PIR (digital)
from gpiozero import MotionSensor
import time
pir = MotionSensor(17)
while True:
if pir.motion_detected:
print("Movimento detectado!")
time.sleep(0.5)
Sensor analógico com MCP3008 (SPI)
import spidev
import time
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1350000
def ler_adc(canal):
r = spi.xfer2([1, (8 + canal) << 4, 0])
return ((r[1] & 3) << 8) + r[2]
while True:
valor = ler_adc(0)
tensao = (valor / 1023.0) * 3.3
print(f"Tensão no pino 0: {tensao:.2f}V")
time.sleep(1)
Sensor BME280 (I2C) - temperatura, umidade e pressão
import smbus2
import bme280
bus = smbus2.SMBus(1)
address = 0x76
calib_params = bme280.load_calibration_params(bus, address)
def ler_bme280():
data = bme280.sample(bus, address, calib_params)
return data.temperature, data.humidity, data.pressure
temp, hum, press = ler_bme280()
print(f"Temp: {temp:.1f}°C | Umidade: {hum:.1f}% | Pressão: {press:.1f}hPa")
4. Controle de Atuadores e Saídas
Acionamento de LED com proteção
from gpiozero import LED
from time import sleep
led = LED(18)
while True:
led.on()
sleep(1)
led.off()
sleep(1)
Servomotor com PWM preciso (pigpio)
import pigpio
import time
pi = pigpio.pi()
servo_pin = 12
pi.set_servo_pulsewidth(servo_pin, 1500) # posição central
time.sleep(1)
pi.set_servo_pulsewidth(servo_pin, 1000) # 0 graus
time.sleep(1)
pi.set_servo_pulsewidth(servo_pin, 2000) # 180 graus
pi.stop()
Display LCD I2C 16x2
from RPLCD.i2c import CharLCD
import time
lcd = CharLCD(i2c_expander='PCF8574', address=0x27, port=1, cols=16, rows=2)
lcd.write_string("IoT com Python")
lcd.cursor_pos = (1, 0)
lcd.write_string("Raspberry Pi")
time.sleep(5)
lcd.clear()
5. Comunicação e Conectividade IoT
MQTT com Mosquitto e paho-mqtt
import paho.mqtt.client as mqtt
import json
def on_connect(client, userdata, flags, rc):
print("Conectado ao broker MQTT")
client = mqtt.Client()
client.on_connect = on_connect
client.connect("broker.hivemq.com", 1883, 60)
# Publicar dados de sensores
dados = {"temperatura": 25.3, "umidade": 68.2}
client.publish("casa/sensor/temperatura", json.dumps(dados))
client.loop_forever()
API REST com Flask
from flask import Flask, jsonify
import bme280
app = Flask(__name__)
@app.route('/api/sensores')
def sensores():
temp, hum, press = ler_bme280()
return jsonify({
"temperatura": round(temp, 1),
"umidade": round(hum, 1),
"pressao": round(press, 1)
})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
6. Tratamento de Eventos e Automação
Interrupção GPIO com callback
from gpiozero import Button
from signal import pause
def botao_pressionado():
print("Botão pressionado! Executando ação...")
botao = Button(2, pull_up=True)
botao.when_pressed = botao_pressionado
pause()
Agendamento de tarefas com schedule
import schedule
import time
def coletar_dados():
temp, hum, press = ler_bme280()
print(f"Coleta automática: {temp}°C, {hum}%")
schedule.every(10).minutes.do(coletar_dados)
while True:
schedule.run_pending()
time.sleep(1)
7. Depuração, Logging e Boas Práticas
Use logs estruturados para monitorar o sistema:
import logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[logging.FileHandler('iot.log'), logging.StreamHandler()]
)
logger = logging.getLogger('IoT_Prototype')
logger.info("Sistema iniciado com sucesso")
Proteção de circuitos: sempre use resistores de pull-up/pull-down em entradas flutuantes, diodos flyback em motores e drivers de potência para cargas indutivas. Organize o código em módulos separados (sensores.py, atuadores.py, comunicacao.py) para reutilização.
8. Estudo de Caso: Estação Meteorológica IoT Completa
import bme280
import smbus2
import paho.mqtt.client as mqtt
from gpiozero import LED
from RPLCD.i2c import CharLCD
import time
import json
import logging
logging.basicConfig(level=logging.INFO)
# Configuração dos componentes
bus = smbus2.SMBus(1)
address = 0x76
calib_params = bme280.load_calibration_params(bus, address)
lcd = CharLCD(i2c_expander='PCF8574', address=0x27, port=1, cols=16, rows=2)
led_indicador = LED(18)
# Configuração MQTT
client = mqtt.Client()
client.connect("broker.hivemq.com", 1883, 60)
def ler_sensor():
try:
data = bme280.sample(bus, address, calib_params)
return data.temperature, data.humidity, data.pressure
except Exception as e:
logging.error(f"Erro no sensor: {e}")
return None, None, None
def atualizar_lcd(temp, hum, press):
lcd.clear()
lcd.write_string(f"Temp: {temp:.1f}C")
lcd.cursor_pos = (1, 0)
lcd.write_string(f"Umid: {hum:.1f}%")
def enviar_mqtt(temp, hum, press):
dados = {"temperatura": round(temp, 1), "umidade": round(hum, 1), "pressao": round(press, 1)}
try:
client.publish("estacao/dados", json.dumps(dados))
logging.info("Dados enviados via MQTT")
except Exception as e:
logging.error(f"Falha MQTT: {e}")
def main():
logging.info("Estação meteorológica iniciada")
while True:
temp, hum, press = ler_sensor()
if temp is not None:
atualizar_lcd(temp, hum, press)
enviar_mqtt(temp, hum, press)
led_indicador.blink(on_time=0.5, off_time=0.5, n=3)
time.sleep(60)
if __name__ == "__main__":
main()
Expansões possíveis: adicionar bateria LiPo com carregador, implementar modo sleep para economia de energia, armazenar dados localmente em SQLite para análise offline.
Referências
- Documentação oficial RPi.GPIO — Guia completo da biblioteca para controle de GPIO no Raspberry Pi
- gpiozero: API de alto nível para GPIO — Documentação oficial com exemplos de sensores e atuadores
- paho-mqtt: cliente MQTT para Python — Biblioteca para comunicação MQTT com exemplos de publicação e assinatura
- Tutorial BME280 com Raspberry Pi — Guia prático para leitura do sensor BME280 via I2C
- Flask: criando APIs REST — Documentação oficial para criação de endpoints HTTP no Raspberry Pi