Exemplos de Código: Introdução à IoT e LoRaWAN

 

1. Simulação Básica de Sensor IoT (Arduino/ESP32)

// Simulação simples de sensor de temperatura/umidade
#include <DHT.h>

#define DHTPIN 4
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

void setup() {
    Serial.begin(115200);
    dht.begin();
    Serial.println("Sensor IoT iniciado - Simulando coleta de dados");
}

void loop() {
    // Leitura dos sensores
    float temperatura = dht.readTemperature();
    float umidade = dht.readHumidity();

    // Verificação de leitura válida
    if (isnan(temperatura) || isnan(umidade)) {
        Serial.println("Erro na leitura do sensor!");
        return;
    }

    // Exibição dos dados
    Serial.print("Temperatura: ");
    Serial.print(temperatura);
    Serial.print("°C | Umidade: ");
    Serial.print(umidade);
    Serial.println("%");

    // Simulação do fluxo IoT: Sensor → Processamento → "Transmissão"
    Serial.println("--- Fluxo IoT ---");
    Serial.println("1. Dados coletados do sensor físico");
    Serial.println("2. Processamento local (validação, formatação)");
    Serial.println("3. Preparação para transmissão LoRaWAN");
    Serial.println("4. Aguardando próxima leitura...");
    Serial.println();

    delay(5000); // 5 segundos entre leituras
}

2. Demonstração de Comunicação Básica LoRa (ESP32 + Módulo LoRa)

#include <SPI.h>
#include <LoRa.h>

// Pinos para ESP32
#define SS 18
#define RST 14
#define DIO0 26

void setup() {
    Serial.begin(115200);

    // Inicialização do módulo LoRa
    LoRa.setPins(SS, RST, DIO0);

    if (!LoRa.begin(915E6)) { // Frequência Brasil (915 MHz)
        Serial.println("Erro ao iniciar LoRa!");
        while (1);
    }

    Serial.println("Módulo LoRa iniciado com sucesso!");
    Serial.println("Frequência: 915 MHz (AU915_0 - Brasil)");
    Serial.println("Pronto para demonstrar comunicação básica");
}

void loop() {
    // Simulação de envio de dados
    Serial.println("Enviando pacote de dados...");

    LoRa.beginPacket();
    LoRa.print("Olá LoRaWAN! Pacote de teste #");
    LoRa.print(millis() / 1000);
    LoRa.endPacket();

    Serial.println("Pacote enviado!");

    // Verificação de pacotes recebidos
    int packetSize = LoRa.parsePacket();
    if (packetSize) {
        Serial.println("Pacote recebido!");

        while (LoRa.available()) {
            Serial.print((char)LoRa.read());
        }

        Serial.print("' com RSSI ");
        Serial.println(LoRa.packetRssi());
    }

    delay(10000); // 10 segundos entre transmissões
}

3. Simulação de Arquitetura IoT Básica (Python)

import time
import random
import json

class IoTSimulator:
    def __init__(self):
        self.devices = []
        self.gateways = []
        self.data_buffer = []

    def add_device(self, device_id, device_type):
        """Adiciona um dispositivo IoT simulado"""
        device = {
            'id': device_id,
            'type': device_type,
            'status': 'active',
            'last_reading': None
        }
        self.devices.append(device)
        print(f"Dispositivo {device_id} ({device_type}) adicionado")

    def add_gateway(self, gateway_id, location):
        """Adiciona um gateway LoRaWAN simulado"""
        gateway = {
            'id': gateway_id,
            'location': location,
            'connected_devices': 0,
            'status': 'online'
        }
        self.gateways.append(gateway)
        print(f"Gateway {gateway_id} em {location} adicionado")

    def simulate_sensor_reading(self, device_id):
        """Simula leitura de sensor"""
        device = next((d for d in self.devices if d['id'] == device_id), None)
        if not device:
            return None

        if device['type'] == 'temperature':
            reading = round(random.uniform(20, 35), 1)
            unit = '°C'
        elif device['type'] == 'humidity':
            reading = round(random.uniform(30, 80), 1)
            unit = '%'
        elif device['type'] == 'soil_moisture':
            reading = round(random.uniform(10, 90), 1)
            unit = '%'
        else:
            reading = random.randint(0, 100)
            unit = 'units'

        timestamp = time.time()
        data_point = {
            'device_id': device_id,
            'timestamp': timestamp,
            'value': reading,
            'unit': unit,
            'device_type': device['type']
        }

        device['last_reading'] = data_point
        return data_point

    def transmit_to_gateway(self, device_id):
        """Simula transmissão de dados para gateway"""
        data = self.simulate_sensor_reading(device_id)
        if not data:
            return False

        # Simular transmissão LoRaWAN
        print("
--- Transmissão LoRaWAN ---"        print(f"Dispositivo: {data['device_id']}")
        print(f"Dados: {data['value']} {data['unit']}")
        print("Protocolo: LoRaWAN Classe A"
        print("Frequência: 915 MHz (AU915_0)"
        print("Status: Transmitido com sucesso"
        # Adicionar ao buffer de dados
        self.data_buffer.append(data)
        return True

    def process_gateway_data(self, gateway_id):
        """Simula processamento de dados no gateway"""
        gateway = next((g for g in self.gateways if g['id'] == gateway_id), None)
        if not gateway:
            return False

        if self.data_buffer:
            data = self.data_buffer.pop(0)
            print("
--- Processamento no Gateway ---"            print(f"Gateway: {gateway_id} ({gateway['location']})")
            print(f"Processando dados de: {data['device_id']}")
            print("Dados enviados para Network Server"
            gateway['connected_devices'] = len([d for d in self.devices if d['status'] == 'active'])
            return True
        return False

    def display_system_status(self):
        """Exibe status do sistema IoT"""
        print("\n=== STATUS DO SISTEMA IoT ===")
        print(f"Dispositivos ativos: {len([d for d in self.devices if d['status'] == 'active'])}")
        print(f"Gateways online: {len([g for g in self.gateways if g['status'] == 'online'])}")
        print(f"Dados no buffer: {len(self.data_buffer)}")

        print("\n--- Dispositivos ---")
        for device in self.devices:
            status = "✓" if device['status'] == 'active' else "✗"
            print(f"{status} {device['id']} ({device['type']})")

        print("\n--- Gateways ---")
        for gateway in self.gateways:
            status = "✓" if gateway['status'] == 'online' else "✗"
            print(f"{status} {gateway['id']} - {gateway['location']} (Dispositivos: {gateway['connected_devices']})")

# Demonstração do simulador
def main():
    iot = IoTSimulator()

    # Adicionar dispositivos e gateways
    iot.add_device("TEMP_001", "temperature")
    iot.add_device("HUM_001", "humidity")
    iot.add_device("SOIL_001", "soil_moisture")
    iot.add_gateway("GW_BRASILIA", "Brasília-DF")
    iot.add_gateway("GW_SAO_PAULO", "São Paulo-SP")

    # Simular operações IoT
    print("\n=== INICIANDO SIMULAÇÃO IoT ===")

    for i in range(5):
        print(f"\n--- Ciclo {i+1} ---")

        # Simular transmissões
        for device in iot.devices:
            iot.transmit_to_gateway(device['id'])
            time.sleep(0.5)

        # Processar dados nos gateways
        for gateway in iot.gateways:
            iot.process_gateway_data(gateway['id'])

        iot.display_system_status()
        time.sleep(2)

if __name__ == "__main__":
    main()

4. Link Budget Calculator (Python)

import math

class LoRaLinkBudgetCalculator:
    def __init__(self):
        # Constantes LoRa
        self.c = 299792458  # Velocidade da luz (m/s)

    def calculate_fspl(self, distance_km, frequency_mhz):
        """Calcula Free Space Path Loss"""
        # FSPL = 20log(d) + 20log(f) + 32.44
        fspl = 20 * math.log10(distance_km) + 20 * math.log10(frequency_mhz) + 32.44
        return round(fspl, 2)

    def get_receiver_sensitivity(self, sf, bw_khz):
        """Retorna sensibilidade do receptor baseada em SF e BW"""
        # Valores típicos para LoRa
        sensitivities = {
            (7, 125): -124,
            (8, 125): -127,
            (9, 125): -130,
            (10, 125): -133,
            (11, 125): -135,
            (12, 125): -137,
            (8, 500): -122,
            (9, 500): -126,
            (10, 500): -129,
            (11, 500): -133,
            (12, 500): -137
        }
        return sensitivities.get((sf, bw_khz), -130)  # Default

    def calculate_link_budget(self, tx_power_dbm, tx_antenna_gain_dbi,
                            rx_antenna_gain_dbi, cable_losses_db,
                            distance_km, frequency_mhz, sf, bw_khz,
                            additional_losses_db=0):
        """
        Calcula o link budget completo
        Retorna: (potência_recebida, margem_link, sucesso_comunicacao)
        """

        # 1. Potência efetiva de transmissão (EIRP)
        eirp = tx_power_dbm + tx_antenna_gain_dbi

        # 2. Free Space Path Loss
        fspl = self.calculate_fspl(distance_km, frequency_mhz)

        # 3. Potência recebida
        received_power = eirp - fspl - cable_losses_db - additional_losses_db + rx_antenna_gain_dbi

        # 4. Sensibilidade do receptor
        sensitivity = self.get_receiver_sensitivity(sf, bw_khz)

        # 5. Margem de link
        link_margin = received_power - sensitivity

        # 6. Avaliação de sucesso
        success = link_margin > 0

        return round(received_power, 2), round(link_margin, 2), success

# Exemplo de uso
def exemplo_link_budget():
    calculator = LoRaLinkBudgetCalculator()

    # Cenário: Sensor agrícola a 5km de distância
    config = {
        'tx_power_dbm': 20,        # 100mW
        'tx_antenna_gain_dbi': 2,  # Antena pequena
        'rx_antenna_gain_dbi': 5,  # Antena gateway
        'cable_losses_db': 2,      # Cabos e conectores
        'distance_km': 5,          # 5km de distância
        'frequency_mhz': 915,      # AU915
        'sf': 10,                  # SF10 para bom equilíbrio
        'bw_khz': 125,             # BW padrão
        'additional_losses_db': 10 # Obstáculos (árvores, etc.)
    }

    received_power, link_margin, success = calculator.calculate_link_budget(**config)

    print("=== CÁLCULO DE LINK BUDGET ===")
    print(f"Distância: {config['distance_km']} km")
    print(f"Frequência: {config['frequency_mhz']} MHz")
    print(f"SF: {config['sf']}, BW: {config['bw_khz']} kHz")
    print(f"FSPL: {calculator.calculate_fspl(config['distance_km'], config['frequency_mhz'])} dB")
    print(f"Potência recebida: {received_power} dBm")
    print(f"Sensibilidade receptor: {calculator.get_receiver_sensitivity(config['sf'], config['bw_khz'])} dBm")
    print(f"Margem de link: {link_margin} dB")
    print(f"Comunicação: {'POSSÍVEL' if success else 'NÃO POSSÍVEL'}")

    return success

exemplo_link_budget()

5. Comparação Visual de Tecnologias LPWAN (Python com Matplotlib)

import matplotlib.pyplot as plt
import numpy as np

# Dados para comparação de tecnologias LPWAN
tecnologias = ['LoRaWAN', 'Sigfox', 'NB-IoT', 'Wi-Fi HaLow']
alcance = [10, 10, 10, 0.5]  # km
consumo = [5, 5, 3, 2]  # escala 1-5 (5 = menor consumo)
custo = [3, 4, 2, 3]  # escala 1-5 (1 = menor custo)
taxa_dados = [0.05, 0.001, 0.1, 50]  # kbps

# Criar gráfico de radar
fig, ax = plt.subplots(figsize=(10, 8), subplot_kw=dict(projection='polar'))

# Ângulos para cada categoria
categorias = ['Alcance (km)', 'Consumo de Energia', 'Custo', 'Taxa de Dados (kbps)']
angulos = np.linspace(0, 2 * np.pi, len(categorias), endpoint=False).tolist()
angulos += angulos[:1]  # Fechar o círculo

# Plotar cada tecnologia
cores = ['blue', 'red', 'green', 'orange']
for i, (tech, cor) in enumerate(zip(tecnologias, cores)):
    valores = [alcance[i], consumo[i], custo[i], taxa_dados[i]]
    valores += valores[:1]  # Fechar o círculo

    ax.plot(angulos, valores, 'o-', linewidth=2, label=tech, color=cor)
    ax.fill(angulos, valores, alpha=0.25, color=cor)

# Configurar gráfico
ax.set_xticks(angulos[:-1])
ax.set_xticklabels(categorias)
ax.set_ylim(0, 55)
ax.set_title('Comparação de Tecnologias LPWAN\nLoRaWAN vs Concorrentes', size=16, fontweight='bold', pad=20)
ax.legend(loc='upper right', bbox_to_anchor=(1.2, 1.0))
ax.grid(True)

# Adicionar anotações
ax.annotate('Melhor para IoT\nremoto', xy=(0, 10), xytext=(0.5, 12),
            arrowprops=dict(facecolor='blue', shrink=0.05))
ax.annotate('Melhor para\ndados simples', xy=(np.pi/2, 5), xytext=(2, 7),
            arrowprops=dict(facecolor='red', shrink=0.05))

plt.tight_layout()
plt.show()

print("\n=== ANÁLISE COMPARATIVA ===")
print("LoRaWAN se destaca em:")
print("✓ Maior alcance (até 10+ km)")
print("✓ Menor consumo de energia")
print("✓ Melhor custo-benefício para aplicações IoT")
print("✓ Adequado para Brasil (região AU915_0)")
print("\nConcorrentes:")
print("• Sigfox: Simplicidade, mas limitado a dados muito simples")
print("• NB-IoT: Boa integração celular, mas menor alcance")
print("• Wi-Fi HaLow: Alta velocidade, mas curto alcance")

Comentários