En el mundo de los microcontroladores las conexiones seriales son de uso común sin embargo cuando la conexión es cableada tenemos la limitación de la distancia y el montaje del propio cable. Una conexión mediante LORA permite extender el alcance y ademas no tenemos los problemas generados por el propio cable.
Este simple ejemplo envía a un microcontrolador PIC18F4620 dos comandos, uno para poner un pin a nivel alto y otro para desactivar el mismo pin.
Las órdenes son generadas desde un código Python que se ejecuta en una placa Raspberry PI que los envía a un transmisor LORA.

El código para el PIC ha sido escrito en Mikro C para PIC y es el siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*******************************************************************************
**  Descripción  : Recibe comandos de un enlace LORA.
**  Target       : 40 PIN PIC18F4620 
**  Compiler     : MikroC para PIC v 7.1
**  XTAL         : 40MHZ - (XTAL 10Mhz con PLLx4)
**  www.firtec.com.ar
********************************************************************************/
// Pines asignados al LCD
sbit LCD_RS at LATE1_bit;
sbit LCD_EN at LATE2_bit;
sbit LCD_D4 at LATD4_bit;
sbit LCD_D5 at LATD5_bit;
sbit LCD_D6 at LATD6_bit;
sbit LCD_D7 at LATD7_bit;
 
sbit LCD_RS_Direction at TRISE1_bit;
sbit LCD_EN_Direction at TRISE2_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
 
 
// Variables del programa
 volatile char Dato = 0, bandera = 0, Kbhit=0;
 
 
void ISR_UART() iv 0x0008 ics ICS_AUTO {
char txt[15];
  if (PIR1.RCIF) {         
    Dato = Uart1_Read() & 0xFF;   // Lee dato recibido
 
 
    if(Dato == '4')
     {
       PORTB.B0 = 0;
       bandera = 1;
      }
      if(Dato == '5')
      {
        PORTB.B0 = 1;
        bandera = 2;
      }
    PIR1.RCIF=0;           // Borra bandera de interrupción
    }
  }
 
 
/**********************************************************
*   Esta función ajusta los valores por defecto de la
*   pantalla LCD y coloca los carteles iniciales.
**********************************************************/
void Display_Init(){
  LCD_Init();
  LCD_Cmd(_LCD_CLEAR);
  Lcd_Cmd(_LCD_CURSOR_OFF);
  Lcd_Out(1,1,"Comandos por LORA");
  delay_ms(2000);
  
}
/**********************************************************
*  Esta es la función principal del programa.
*  Configura pines, comparadores, canales analógicos y se
*  llama al resto de las funciones.
**********************************************************/
void main() {
  char k = 0, t;
  TRISB0_bit  = 0;
  CMCON |=7;
  ADCON1 = 0x0f;
  Display_Init();
  UART1_Init(9600); 
  INTCON.GIE = 1;
  INTCON.PEIE = 1;
  PIE1.RCIE = 1;
  Lcd_Out(2,1,"LED: ??");
  while (1) {
          if(bandera == 1) {
                     Lcd_Out(2,5,"Apagado     ");
                     bandera = 0;
                     }
          if(bandera == 2) {
                     Lcd_Out(2,5,"Encendido");
                     bandera = 0;
                     }
    }
  }

Su funcionamiento es muy sencillo, LORA solo envía dos posibles datos, el carácter "4" o el "5" que son usados para encender o apagar un LED conectado en el pin RB0 del PIC.
Por otro lado tenemos el código Python corriendo en Raspberry PI con dos botones encargados de enviar los respectivos comandos para actuar sobre el pin del microcontrolador.

El código para Python 3 es el siguiente.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# =========================================================================
# - Controla el estado de un pin del Microcontrolador.
# - El control se hace enviando comandos por un enlace LORA.
# - Firtec Argentina
# - www.firtec.com.ar
# ==========================================================================
 
import errno
import time
from serial import Serial
from tkinter import *
from tkinter import ttk
from tkinter import ttk, font
 
puerto = Serial("/dev/ttyS0", baudrate=9600, timeout=0.2)
 
if puerto.isOpen() == False:
    puerto.open()
 
puerto.flushInput()
puerto.flushOutput()
 
def apagar( ):
        puerto.write(b'4')
        
def encender( ):
        puerto.write(b'5')
        
class Aplicacion():
    def __init__(self):
        global addr
        global sock
        global ventana
        global label_IP_remoto
        ventana = Tk()
        ventana.title(' Comandos LORA')
        ventana.config(bg="Steel Blue") 
        ventana.geometry("390x230") 
        ventana.resizable(0,0)      
        self.fuente = font.Font(weight='bold')  
        label_firtec = Label(ventana, text="www.firtec.com.ar", bg="Steel Blue", fg="white", font=self.fuente)
        label_firtec.place(x=100, y=150)
        label_rotulo_texto = Label(ventana, text="Enviando comandos por LORA", bg="Steel Blue", fg="white", font=self.fuente)#font=("Helvetica", 12))
        label_rotulo_texto.place(x=45, y=20)
        self.fuente = font.Font(slant='italic')  
        boton_0 = Button(ventana,font=self.fuente, text=' Encender LED ', command=encender)  # Boton del LED
        boton_0.pack()
        boton_0.place(x=20, y=70)    # Coordenada del Botón 1
        boton_1 = Button(ventana,font=self.fuente, text='  Apagar LED  ', command=apagar)  # Boton del LED
        boton_1.pack()
        boton_1.place(x=200, y=70)    # Coordenada del Botón 2
        ventana.mainloop()
 
def main():
    
    mi_app = Aplicacion()
    return 0
 
if __name__ == '__main__':
    main() 

 Resultado obtenido con el ejemplo.