LoRa com Maix Bit para Aplicações a Longa Distância com IA

O LoRa junto com o Maix Bit pode ser uma boa opção para aplicações que necessitam enviar a longa distância os objetos identificados pela IA.

O que é LoRa?

LoRa é uma tecnologia de rede de área ampla de baixa potência. Baseia-se em técnicas de modulação de espectro de propagação derivadas da tecnologia chirp spread spectrum.

Fonte: Suntech

Como Usar o LoRa?

Qualquer nova tecnologia pode parecer extremamente difícil, mas no caso do LoRa que foi usado para este post, utiliza comunicação UART simples. Ainda mais quando tem post já dedicado de como usar o LoRa E32915T30D com Arduino.

LoRA E32915T30D
LoRa E32915T30D

UART do Maix Bit

O Maix Bit tem três interfaces de comunicação UART, porém apenas uma fica em um barramento de fácil utilização (Tx3 e Rx3) como mostra a imagem abaixo:

Pinout da comunicação UART do Maix Bit

Precisa usar o LoRa em outra Serial?

Caso seja necessário o uso de outra ou mais portas seriais no Maix bit, será necessário fazer uma “pequena gambiarra” para usufruir das três UARTs disponíveis. Embora a imagem abaixo já deixe claro qual modificação é necessária fazer, ainda assim para saber usar é recomendado ler este post clicando aqui.

Modificação no Maix bit para Comunicação UART

Diagrama LoRa com Maix Bit

Assim como o Arduino, o Maix bit seguirá a mesma lógica de conexão com o LoRa, a única diferença é que o Maix Bit tem três UARTs dedicadas, ao contrário do Arduino que usa uma UART simulada.

Código do LoRa com Maix Bit

Embora a comunicação UART seja simples, uma comunicação muito sem intervalo de tempo com o LoRa poderá ficar auto incrementando a mensagem impedindo o envio. No entanto, o código a seguir já tem esse intervalo bem definido.

import sensor,image,lcd,time
import KPU as kpu
import ujson
from fpioa_manager import fm
from machine import UART
from board import board_info
from fpioa_manager import fm

fm.register(12, fm.fpioa.UART2_TX, force=True)
fm.register(13, fm.fpioa.UART2_RX, force=True)

uart_B = UART(UART.UART2, 9600, 8, 0, 0, timeout=1000, read_buf_len=4096)

lcd.init(freq=15000000)
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_vflip(1)
sensor.set_hmirror(0)
sensor.run(1)
clock = time.clock()
classes = ['aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog', 'horse', 'motorbike', 'person', 'pottedplant', 'sheep', 'sofa', 'train', 'tvmonitor']
task = kpu.load("/sd/20class.kmodel") 
anchor = (1.889, 2.5245, 2.9465, 3.94056, 3.99987, 5.3658, 5.155437, 6.92275, 6.718375, 9.01025)
a = kpu.init_yolo2(task, 0.5, 0.3, 5, anchor)
ltime = 0

while(True):
    clock.tick()
    img = sensor.snapshot()
    code = kpu.run_yolo2(task, img)
    
    rank_array = ([0 for x in range(80)])
    all_area   = ([0 for x in range(80)])
    location_x   = ([0 for x in range(80)])   
    location_y   = ([0 for x in range(80)])
    
    if code:
        number_obj = 0
        count = 0
        for i in code:
            a = img.draw_rectangle(i.rect())
            
            centroid_x = int(i.w() / 2)
            centroid_y = int(i.h() / 2)
            
            location_x[number_obj] = i.x() + centroid_x
            location_y[number_obj] = i.y() + centroid_y
            
            all_area[number_obj] = i.w() * i.h()
            
            #a = img.draw_circle(location_x[number_obj], location_y[number_obj], 3, color=(255, 255, 255), fill=True)
            
            a = lcd.display(img)
            number_obj += 1
            for i in code:
                lcd.draw_string(i.x(), i.y(), classes[i.classid()], lcd.RED, lcd.WHITE)
                lcd.draw_string(i.x(), i.y()+12, '%f'%i.value(), lcd.RED, lcd.WHITE)
    
        id_area = 0
        for j in range(number_obj):
            if all_area[j] > rank_array[0]:
                rank_array[0]= all_area[j]
                id_area = j    

    if rank_array[0] > 0:
        a = img.draw_circle(location_x[id_area], location_y[id_area], 3, color=(255, 0, 0), fill=True)
        percent_location_x = int(location_x[id_area] * 100 / 320)
        percent_location_y = int(location_y[id_area] * 100 / 240)
        json_map = {}
        json_map["x"] = percent_location_x
        json_map["y"] = percent_location_y
        json_percent_location = ujson.dumps(json_map)   
        #print(json_percent_location) 
        
        if time.ticks_ms() - ltime > 1500 or ltime == 0:
            uart_B.write(json_percent_location.encode('utf-8'))
            #uart_B.write("\n")
            print(json_percent_location)
            ltime = time.ticks_ms()
        
        count += 1
    a = lcd.display(img)
a = kpu.deinit(task)
uart_B.deinit()
del uart_B

Funcionamento Prático

Por fim, o funcionamento. O vídeo a seguir demonstra o Maix Bit reconhecendo os objetos e enviado a localização dos objetos identificados com base na distância através do transceptor LoRa. Em seguida a informação chega ao outro LoRa que está com o Arduino e display OLED.