Skip to content

Commit 75a9e42

Browse files
author
sasilva1998
committed
transferencia de repo lora
0 parents  commit 75a9e42

11 files changed

+921
-0
lines changed

README.md

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
Estos códigos han sido recopilados de otro repositorio con el fin de mejorar su uso, para que el único script que se maneje como librería sea lora.py, será mejorado con el tiempo.
2+
Referencia: https://github.com/lemariva/uPyLora
3+
4+
En el repositorio se puede encontrar:
5+
6+
* códigos: contiene todos los scripts utilizados para dar uso del chip sx1276
7+
8+
* config_lora.py
9+
10+
* controller.py
11+
12+
* controller_esp32.py
13+
14+
* esp32lora.bin
15+
16+
* sx127x.py
17+
18+
* lora.py
19+
20+
De los cuales en el que nos concentramos es el de lora.py el cual tiene la clase con sus métodos, facilitando el uso del chip. Para este caso se ha especificado que la frecuencia usada es de 915 MHz, configurado en el archivo `sx127x.py`, en caso de que se desee una frecuencia distinta es necesario que sea cambiado en el script y luego volver ha formar el .bin o tan solo ingresar los scripts necesarios en el ESP.
21+
22+
* ejemplos: contiene ejemplos sobre como debe ser usada la clase, para enviar y recibir datos, además de la subida de datos a un servicio web como el de ubidots.
23+
24+
# lora.py
25+
26+
Principalmente este archivo, se ha creado para instanciar un objeto especificado como LoRa, el cual tendra todos los metodos necesarios para enviar y recibir código. Los pines que se usan para la comunicación con el chip de LoRa son los mismo especificados en la documentación de HelTec y TTGO los cuales hacen placas de desarrollo con el microcontrolador ESP32 agregandole un chip sx127x con antena. A continuación se encontrará como usar la librería con sus métodos:
27+
28+
## Construcción de clase LoRa
29+
30+
El script contiene a LoRa el cual es una clase para poder inicializar el uso del chip sx127x. Se puede inicializar de la siguiente manera:
31+
32+
~~~~ python
33+
from lora import LoRa
34+
35+
lora = LoRa()
36+
37+
#si se desea un filtrado de los mensajes
38+
lora = LoRa(header='header')
39+
~~~~
40+
41+
Además para la recepción de datos periódicas la cual se maneja con el metodo de wait_msg(), se puede especificar un periodo, para que despues de haber llegado un mensaje, especificar cuanto tiempo se quiere que pase hasta recibir uno nuevo, de la siguiente manera:
42+
43+
44+
~~~~ python
45+
#sin header
46+
lora = LoRa(period=2)
47+
48+
#con header
49+
lora= LoRa(header='header',period=2)
50+
~~~~
51+
52+
## Metodos
53+
54+
### send('mensaje', spheader = 'headerespecifico')
55+
56+
Es el método especificado para enviar datos, de manera que el primer parametro es para especificar que dato se quiere enviar y el segundo en caso que se quiera mandar con un header específico.
57+
~~~~ python
58+
#sin header especifico
59+
lora.send('hola')
60+
61+
#con header especifico
62+
lora.send('hola', spheader = 'headersp')
63+
~~~~
64+
La variables de un header especifico ha sido agregado en caso de que en algún momento se necesite enviar un mensaje con un header distinto o especifico.
65+
66+
### set_callback(cb)
67+
68+
Al igual que un objeto de mqtt para un subscribe, utilizamos el mismo concepto para callbacks, de manera que una vez instanciado el objeto de lora, se especifica que funcion se quiere que se ejecute cuando llegue un mensaje:
69+
70+
~~~~ python
71+
#cb corresponde al nombre de la funcion usada como callback
72+
#que debe tener como parametro una variable que sera el mensaje
73+
lora.set_callback(cb)
74+
~~~~
75+
76+
### wait_msg()
77+
~~~~ python
78+
lora.wait_msg()
79+
~~~~
80+
Una vez que ya esta especificado nuestro callback, wait_msg se encarga para que en segundo plano se escuche los mensajes entrantes y que nuestro callback se ejecute. En el caso de que en al instanciar la clase LoRa, se especifique un valor para la variable period, una vez que se recibe un mensaje, tendra que pasar el tiempo (en segundos) especificado para que otro mensaje sea aceptado.
81+
82+
### receive_msg()
83+
~~~~ python
84+
lora.receive_msg()
85+
~~~~
86+
Parecido a wait_msg() se encarga de recibir un mensaje en un momento especifico, por una sola vez y se ejecuta el callback cuando llegue el mensaje.
87+
88+
89+
# Licencia
90+
91+
<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"><img alt="Licencia de Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">uPyLoRa</span> by <a xmlns:cc="http://creativecommons.org/ns#" href="https://github.com/FunPythonEC/LibreriasDesarrolladas/tree/master/uPyLoRa" property="cc:attributionName" rel="cc:attributionURL">Steven Silva</a> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Reconocimiento-CompartirIgual 4.0 Internacional License</a>.<br />Creado a partir de la obra en <a xmlns:dct="http://purl.org/dc/terms/" href="https://github.com/lemariva/uPyLora" rel="dct:source">https://github.com/lemariva/uPyLora</a>.

codigos/config_lora.py

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import sys
2+
import os
3+
import time
4+
import machine
5+
import ubinascii
6+
7+
def mac2eui(mac):
8+
mac = mac[0:6] + 'fffe' + mac[6:]
9+
return hex(int(mac[0:2], 16) ^ 2)[2:] + mac[2:]
10+
11+
def get_millis():
12+
millisecond = time.ticks_ms()
13+
return millisecond
14+
15+
def get_nodename():
16+
uuid = ubinascii.hexlify(machine.unique_id()).decode()
17+
node_name = "ESP_" + uuid
18+
return node_name

codigos/controller.py

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
from time import sleep
2+
3+
4+
class Controller:
5+
6+
class Mock:
7+
pass
8+
9+
ON_BOARD_LED_PIN_NO = None
10+
ON_BOARD_LED_HIGH_IS_ON = True
11+
GPIO_PINS = []
12+
13+
PIN_ID_FOR_LORA_RESET = None
14+
15+
PIN_ID_FOR_LORA_SS = None
16+
PIN_ID_SCK = None
17+
PIN_ID_MOSI = None
18+
PIN_ID_MISO = None
19+
20+
PIN_ID_FOR_LORA_DIO0 = None
21+
PIN_ID_FOR_LORA_DIO1 = None
22+
PIN_ID_FOR_LORA_DIO2 = None
23+
PIN_ID_FOR_LORA_DIO3 = None
24+
PIN_ID_FOR_LORA_DIO4 = None
25+
PIN_ID_FOR_LORA_DIO5 = None
26+
27+
28+
def __init__(self,
29+
pin_id_led = ON_BOARD_LED_PIN_NO,
30+
on_board_led_high_is_on = ON_BOARD_LED_HIGH_IS_ON,
31+
pin_id_reset = PIN_ID_FOR_LORA_RESET,
32+
blink_on_start = (2, 0.5, 0.5)):
33+
34+
self.pin_led = self.prepare_pin(pin_id_led)
35+
self.on_board_led_high_is_on = on_board_led_high_is_on
36+
self.pin_reset = self.prepare_pin(pin_id_reset)
37+
self.reset_pin(self.pin_reset)
38+
self.transceivers = {}
39+
self.blink_led(*blink_on_start)
40+
41+
42+
def add_transceiver(self,
43+
transceiver,
44+
pin_id_ss = PIN_ID_FOR_LORA_SS,
45+
pin_id_RxDone = PIN_ID_FOR_LORA_DIO0,
46+
pin_id_RxTimeout = PIN_ID_FOR_LORA_DIO1,
47+
pin_id_ValidHeader = PIN_ID_FOR_LORA_DIO2,
48+
pin_id_CadDone = PIN_ID_FOR_LORA_DIO3,
49+
pin_id_CadDetected = PIN_ID_FOR_LORA_DIO4,
50+
pin_id_PayloadCrcError = PIN_ID_FOR_LORA_DIO5):
51+
transceiver.blink_led = self.blink_led
52+
transceiver.pin_ss = self.prepare_pin(pin_id_ss)
53+
transceiver.pin_RxDone = self.prepare_irq_pin(pin_id_RxDone)
54+
transceiver.pin_RxTimeout = self.prepare_irq_pin(pin_id_RxTimeout)
55+
transceiver.pin_ValidHeader = self.prepare_irq_pin(pin_id_ValidHeader)
56+
transceiver.pin_CadDone = self.prepare_irq_pin(pin_id_CadDone)
57+
transceiver.pin_CadDetected = self.prepare_irq_pin(pin_id_CadDetected)
58+
transceiver.pin_PayloadCrcError = self.prepare_irq_pin(pin_id_PayloadCrcError)
59+
60+
self.spi = self.prepare_spi(self.get_spi())
61+
transceiver.transfer = self.spi.transfer
62+
63+
transceiver.init()
64+
65+
self.transceivers[transceiver.name] = transceiver
66+
return transceiver
67+
68+
69+
def prepare_pin(self, pin_id, in_out = None):
70+
reason = '''
71+
# a pin should provide:
72+
# .pin_id
73+
# .low()
74+
# .high()
75+
# .value() # read input.
76+
# .irq() # (ESP8266/ESP32 only) ref to the irq function of real pin object.
77+
'''
78+
raise NotImplementedError(reason)
79+
80+
81+
def prepare_irq_pin(self, pin_id):
82+
reason = '''
83+
# a irq_pin should provide:
84+
# .set_handler_for_irq_on_rising_edge() # to set trigger and handler.
85+
# .detach_irq()
86+
'''
87+
raise NotImplementedError(reason)
88+
89+
90+
def get_spi(self):
91+
reason = '''
92+
# initialize SPI interface
93+
'''
94+
raise NotImplementedError(reason)
95+
96+
97+
def prepare_spi(self, spi):
98+
reason = '''
99+
# a spi should provide:
100+
# .close()
101+
# .transfer(pin_ss, address, value = 0x00)
102+
'''
103+
raise NotImplementedError(reason)
104+
105+
106+
def led_on(self, on = True):
107+
self.pin_led.high() if self.on_board_led_high_is_on == on else self.pin_led.low()
108+
109+
110+
def blink_led(self, times = 1, on_seconds = 0.1, off_seconds = 0.1):
111+
for i in range(times):
112+
self.led_on(True)
113+
sleep(on_seconds)
114+
self.led_on(False)
115+
sleep(off_seconds)
116+
117+
118+
def reset_pin(self, pin, duration_low = 0.05, duration_high = 0.05):
119+
pin.low()
120+
sleep(duration_low)
121+
pin.high()
122+
sleep(duration_high)
123+
124+
125+
def __exit__(self):
126+
self.spi.close()

codigos/controller_esp32.py

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
from machine import Pin, SPI, reset
2+
from controller import Controller
3+
4+
5+
class ESP32Controller(Controller):
6+
7+
# LoRa config
8+
PIN_ID_FOR_LORA_RESET = 14
9+
10+
PIN_ID_FOR_LORA_SS = 18
11+
PIN_ID_SCK = 5
12+
PIN_ID_MOSI = 27
13+
PIN_ID_MISO = 19
14+
15+
PIN_ID_FOR_LORA_DIO0 = 26
16+
PIN_ID_FOR_LORA_DIO1 = None
17+
PIN_ID_FOR_LORA_DIO2 = None
18+
PIN_ID_FOR_LORA_DIO3 = None
19+
PIN_ID_FOR_LORA_DIO4 = None
20+
PIN_ID_FOR_LORA_DIO5 = None
21+
22+
23+
# ESP config
24+
ON_BOARD_LED_PIN_NO = 2
25+
ON_BOARD_LED_HIGH_IS_ON = True
26+
GPIO_PINS = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
27+
12, 13, 14, 15, 16, 17, 18, 19, 21, 22,
28+
23, 25, 26, 27, 32, 34, 35, 36, 37, 38, 39)
29+
30+
31+
def __init__(self,
32+
pin_id_led = ON_BOARD_LED_PIN_NO,
33+
on_board_led_high_is_on = ON_BOARD_LED_HIGH_IS_ON,
34+
pin_id_reset = PIN_ID_FOR_LORA_RESET,
35+
blink_on_start = (2, 0.5, 0.5)):
36+
37+
super().__init__(pin_id_led,
38+
on_board_led_high_is_on,
39+
pin_id_reset,
40+
blink_on_start)
41+
42+
43+
def prepare_pin(self, pin_id, in_out = Pin.OUT):
44+
if pin_id is not None:
45+
pin = Pin(pin_id, in_out)
46+
new_pin = Controller.Mock()
47+
new_pin.pin_id = pin_id
48+
new_pin.value = pin.value
49+
50+
if in_out == Pin.OUT:
51+
new_pin.low = lambda : pin.value(0)
52+
new_pin.high = lambda : pin.value(1)
53+
else:
54+
new_pin.irq = pin.irq
55+
56+
return new_pin
57+
58+
59+
def prepare_irq_pin(self, pin_id):
60+
pin = self.prepare_pin(pin_id, Pin.IN)
61+
if pin:
62+
pin.set_handler_for_irq_on_rising_edge = lambda handler: pin.irq(handler = handler, trigger = Pin.IRQ_RISING)
63+
pin.detach_irq = lambda : pin.irq(handler = None, trigger = 0)
64+
return pin
65+
66+
67+
def get_spi(self):
68+
spi = None
69+
70+
try:
71+
spi = SPI(baudrate = 10000000, polarity = 0, phase = 0, bits = 8, firstbit = SPI.MSB,
72+
sck = Pin(self.PIN_ID_SCK, Pin.OUT, Pin.PULL_DOWN),
73+
mosi = Pin(self.PIN_ID_MOSI, Pin.OUT, Pin.PULL_UP),
74+
miso = Pin(self.PIN_ID_MISO, Pin.IN, Pin.PULL_UP))
75+
#spi.init()
76+
77+
except Exception as e:
78+
print(e)
79+
if spi:
80+
spi.deinit()
81+
spi = None
82+
reset() # in case SPI is already in use, need to reset.
83+
84+
return spi
85+
86+
87+
def prepare_spi(self, spi):
88+
89+
if spi:
90+
new_spi = Controller.Mock()
91+
92+
def transfer(pin_ss, address, value = 0x00):
93+
response = bytearray(1)
94+
95+
pin_ss.low()
96+
97+
spi.write(bytes([address]))
98+
spi.write_readinto(bytes([value]), response)
99+
100+
pin_ss.high()
101+
102+
return response
103+
104+
new_spi.transfer = transfer
105+
new_spi.close = spi.deinit
106+
return new_spi
107+
108+
109+
def __exit__(self):
110+
self.spi.close()

0 commit comments

Comments
 (0)