Guest User

Untitled

a guest
Sep 29th, 2023
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.75 KB | Source Code | 0 0
  1. # Send "Hello world!" over LoRa every second.
  2.  
  3. from aiolora import LoRa
  4. from machine import Pin, SPI
  5. import uasyncio as asyncio
  6.  
  7. # SPI pins
  8. SCK = 2
  9. MOSI = 3
  10. MISO = 4
  11. # This is the NSS pin on the SX1278
  12. CS = 5
  13. # IRQ pin = the DIO0 pin on the SX1278
  14. IRQ = 1
  15.  
  16. # SPIx_SCK = SCK
  17. # SPIx_TX = MOSI
  18. # SPIx_RX = MISO
  19.  
  20.  
  21. # Setup SPI
  22. spi = SPI(
  23. 0,
  24. baudrate=10000000,
  25. sck=Pin(SCK, Pin.OUT, Pin.PULL_DOWN),
  26. mosi=Pin(MOSI, Pin.OUT, Pin.PULL_UP),
  27. miso=Pin(MISO, Pin.IN, Pin.PULL_UP),
  28. )
  29. spi.init()
  30.  
  31. # Setup LoRa
  32. lora = LoRa(
  33. spi,
  34. cs=Pin(CS, Pin.OUT),
  35. irq=Pin(IRQ, Pin.IN),
  36. )
  37.  
  38. async def main():
  39. while True:
  40. await lora.send('Hello world!')
  41. await asyncio.sleep(1)
  42.  
  43. # Setup asyncio loop and start task
  44. loop = asyncio.get_event_loop()
  45. loop.create_task(main())
  46. loop.run_forever()
  47.  
  48.  
  49. This below is the aiolora library on the raspberry pi.
  50.  
  51. from machine import Pin
  52. import uasyncio as asyncio
  53.  
  54. TX_BASE_ADDR = 0x00
  55. RX_BASE_ADDR = 0x00
  56.  
  57. PA_BOOST = 0x80
  58. PA_OUTPUT_RFO_PIN = 0
  59. PA_OUTPUT_PA_BOOST_PIN = 1
  60.  
  61. REG_FIFO = 0x00
  62. REG_OP_MODE = 0x01
  63. REG_FRF_MSB = 0x06
  64. REG_FRF_MID = 0x07
  65. REG_FRF_LSB = 0x08
  66. REG_PA_CONFIG = 0x09
  67. REG_LNA = 0x0c
  68. REG_FIFO_ADDR_PTR = 0x0d
  69. REG_FIFO_TX_BASE_ADDR = 0x0e
  70. REG_FIFO_RX_BASE_ADDR = 0x0f
  71. REG_FIFO_RX_CURRENT_ADDR = 0x10
  72. REG_IRQ_FLAGS = 0x12
  73. REG_RX_NB_BYTES = 0x13
  74. REG_PKT_RSSI_VALUE = 0x1a
  75. REG_PKT_SNR_VALUE = 0x1b
  76. REG_MODEM_CONFIG_1 = 0x1d
  77. REG_MODEM_CONFIG_2 = 0x1e
  78. REG_PREAMBLE_MSB = 0x20
  79. REG_PREAMBLE_LSB = 0x21
  80. REG_PAYLOAD_LENGTH = 0x22
  81. REG_MODEM_CONFIG_3 = 0x26
  82. REG_DETECTION_OPTIMIZE = 0x31
  83. REG_DETECTION_THRESHOLD = 0x37
  84. REG_SYNC_WORD = 0x39
  85. REG_DIO_MAPPING_1 = 0x40
  86. REG_VERSION = 0x42
  87.  
  88. MODE_LORA = 0x80
  89. MODE_SLEEP = 0x00
  90. MODE_STDBY = 0x01
  91. MODE_TX = 0x03
  92. MODE_RX_CONTINUOUS = 0x05
  93.  
  94. IRQ_RX_DONE_MASK = 0x40
  95. IRQ_TX_DONE_MASK = 0x08
  96. IRQ_PAYLOAD_CRC_ERROR_MASK = 0x20
  97.  
  98. MAX_PKT_LENGTH = 255
  99.  
  100.  
  101. class LoRa:
  102.  
  103. def __init__(self, spi, **kw):
  104. self.spi = spi
  105. self.cs = kw['cs']
  106. self.irq = kw['irq']
  107. self._data = None
  108. self._recv_lock = asyncio.Lock()
  109. self._recv_event = asyncio.ThreadSafeFlag()
  110. self._send_lock = asyncio.Lock()
  111. self._send_event = asyncio.ThreadSafeFlag()
  112. if self._read(REG_VERSION) != 0x12:
  113. register_version = self._read(REG_VERSION)
  114. print(f"Register version: {register_version}")
  115.  
  116. raise Exception('Invalid version or bad SPI connection')
  117. self._write(REG_OP_MODE, MODE_LORA | MODE_SLEEP)
  118. self.set_frequency(kw.get('frequency', 443.0))
  119. self.set_bandwidth(kw.get('bandwidth', 250000))
  120. self.set_spreading_factor(kw.get('spreading_factor', 10))
  121. self.set_coding_rate(kw.get('coding_rate', 8))
  122. self.set_preamble_length(kw.get('preamble_length', 4))
  123. self.set_crc(kw.get('crc', False))
  124. # set LNA boost
  125. self._write(REG_LNA, self._read(REG_LNA) | 0x03)
  126. # set AGC
  127. self._write(REG_MODEM_CONFIG_3, 0x04)
  128. self.set_tx_power(kw.get('tx_power', 24))
  129. self.set_sync_word(kw.get('sync_word', 0x12))
  130. self._write(REG_FIFO_TX_BASE_ADDR, TX_BASE_ADDR)
  131. self._write(REG_FIFO_RX_BASE_ADDR, RX_BASE_ADDR)
  132. self.irq.irq(handler=self._irq, trigger=Pin.IRQ_RISING)
  133. self._write(REG_DIO_MAPPING_1, 0x00)
  134. self._write(REG_OP_MODE, MODE_LORA | MODE_RX_CONTINUOUS)
  135.  
  136. async def send(self, x):
  137. if isinstance(x, str):
  138. x = x.encode()
  139. async with self._send_lock:
  140. self._write(REG_OP_MODE, MODE_LORA | MODE_STDBY)
  141. self._write(REG_DIO_MAPPING_1, 0x40)
  142. self._write(REG_FIFO_ADDR_PTR, TX_BASE_ADDR)
  143. n = len(x)
  144. m = MAX_PKT_LENGTH - TX_BASE_ADDR
  145. if n > m:
  146. raise ValueError('Max payload length is ' + str(m))
  147. for i in range(n):
  148. self._write(REG_FIFO, x[i])
  149. self._write(REG_PAYLOAD_LENGTH, n)
  150. self._write(REG_OP_MODE, MODE_LORA | MODE_TX)
  151. await self._send_event.wait()
  152.  
  153. async def recv(self):
  154. async with self._recv_lock:
  155. await self._recv_event.wait()
  156. return self._data
  157.  
  158. def get_rssi(self):
  159. rssi = self._read(REG_PKT_RSSI_VALUE)
  160. if self._frequency >= 779.0:
  161. return rssi - 157
  162. return rssi - 164
  163.  
  164. def get_snr(self):
  165. return self._read(REG_PKT_SNR_VALUE) * 0.25
  166.  
  167. def set_tx_power(self, level, pin=PA_OUTPUT_PA_BOOST_PIN):
  168. if pin == PA_OUTPUT_RFO_PIN:
  169. level = min(max(level, 0), 14)
  170. self._write(REG_PA_CONFIG, 0x70 | level)
  171. else:
  172. level = min(max(level, 2), 17)
  173. self._write(REG_PA_CONFIG, PA_BOOST | (level - 2))
  174.  
  175. def set_frequency(self, frequency):
  176. self._frequency = frequency
  177. hz = frequency * 1000000.0
  178. x = round(hz / 61.03515625)
  179. self._write(REG_FRF_MSB, (x >> 16) & 0xff)
  180. self._write(REG_FRF_MID, (x >> 8) & 0xff)
  181. self._write(REG_FRF_LSB, x & 0xff)
  182.  
  183. def set_spreading_factor(self, sf):
  184. if sf < 6 or sf > 12:
  185. raise ValueError('Spreading factor must be between 6-12')
  186. self._write(REG_DETECTION_OPTIMIZE, 0xc5 if sf == 6 else 0xc3)
  187. self._write(REG_DETECTION_THRESHOLD, 0x0c if sf == 6 else 0x0a)
  188. reg2 = self._read(REG_MODEM_CONFIG_2)
  189. self._write(REG_MODEM_CONFIG_2, (reg2 & 0x0f) | ((sf << 4) & 0xf0))
  190.  
  191. def set_bandwidth(self, bw):
  192. bws = (7800, 10400, 15600, 20800, 31250, 41700, 62500, 125000, 250000)
  193. i = 9
  194. for j in range(len(bws)):
  195. if bw <= bws[j]:
  196. i = j
  197. break
  198. x = self._read(REG_MODEM_CONFIG_1) & 0x0f
  199. self._write(REG_MODEM_CONFIG_1, x | (i << 4))
  200.  
  201. def set_coding_rate(self, denom):
  202. denom = min(max(denom, 5), 8)
  203. cr = denom - 4
  204. reg1 = self._read(REG_MODEM_CONFIG_1)
  205. self._write(REG_MODEM_CONFIG_1, (reg1 & 0xf1) | (cr << 1))
  206.  
  207. def set_preamble_length(self, n):
  208. self._write(REG_PREAMBLE_MSB, (n >> 8) & 0xff)
  209. self._write(REG_PREAMBLE_LSB, (n >> 0) & 0xff)
  210.  
  211. def set_crc(self, crc=False):
  212. modem_config_2 = self._read(REG_MODEM_CONFIG_2)
  213. if crc:
  214. config = modem_config_2 | 0x04
  215. else:
  216. config = modem_config_2 & 0xfb
  217. self._write(REG_MODEM_CONFIG_2, config)
  218.  
  219. def set_sync_word(self, sw):
  220. self._write(REG_SYNC_WORD, sw)
  221.  
  222. def _get_irq_flags(self):
  223. f = self._read(REG_IRQ_FLAGS)
  224. self._write(REG_IRQ_FLAGS, f)
  225. return f
  226.  
  227. def _irq(self, event_source):
  228. f = self._get_irq_flags()
  229. if f & IRQ_TX_DONE_MASK:
  230. self._write(REG_DIO_MAPPING_1, 0x00)
  231. self._write(REG_OP_MODE, MODE_LORA | MODE_RX_CONTINUOUS)
  232. self._send_event.set()
  233. if f & IRQ_RX_DONE_MASK:
  234. if f & IRQ_PAYLOAD_CRC_ERROR_MASK == 0:
  235. addr = self._read(REG_FIFO_RX_CURRENT_ADDR)
  236. self._write(REG_FIFO_ADDR_PTR, addr)
  237. n = self._read(REG_RX_NB_BYTES)
  238. payload = bytearray(n)
  239. for i in range(n):
  240. payload[i] = self._read(REG_FIFO)
  241. self._data = bytes(payload)
  242. self._recv_event.set()
  243.  
  244. def _transfer(self, addr, x=0x00):
  245. resp = bytearray(1)
  246. self.cs.value(0)
  247. self.spi.write(bytes([addr]))
  248. self.spi.write_readinto(bytes([x]), resp)
  249. self.cs.value(1)
  250. return resp
  251.  
  252. def _read(self, addr):
  253. x = self._transfer(addr & 0x7f)
  254. return int.from_bytes(x, 'big')
  255.  
  256. def _write(self, addr, x):
  257. self._transfer(addr | 0x80, x)
  258.  
Advertisement
Add Comment
Please, Sign In to add comment