{"id":13801902,"url":"https://github.com/martynwheeler/u-lora","last_synced_at":"2025-05-13T12:32:06.207Z","repository":{"id":54673973,"uuid":"333871883","full_name":"martynwheeler/u-lora","owner":"martynwheeler","description":"raspi-lora for micropython","archived":false,"fork":false,"pushed_at":"2023-10-05T19:16:37.000Z","size":128,"stargazers_count":67,"open_issues_count":14,"forks_count":10,"subscribers_count":9,"default_branch":"main","last_synced_at":"2024-08-04T00:06:43.859Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/martynwheeler.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2021-01-28T19:13:56.000Z","updated_at":"2024-06-29T23:08:55.000Z","dependencies_parsed_at":"2024-01-29T19:30:20.178Z","dependency_job_id":"8732556c-b9c9-4b1a-aa44-be182d1c58fc","html_url":"https://github.com/martynwheeler/u-lora","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martynwheeler%2Fu-lora","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martynwheeler%2Fu-lora/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martynwheeler%2Fu-lora/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martynwheeler%2Fu-lora/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/martynwheeler","download_url":"https://codeload.github.com/martynwheeler/u-lora/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225217889,"owners_count":17439712,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T00:01:29.717Z","updated_at":"2024-11-18T17:30:30.668Z","avatar_url":"https://github.com/martynwheeler.png","language":"Python","funding_links":[],"categories":["Libraries"],"sub_categories":["Communications"],"readme":"# u-lora\n\nThis is a port of raspi-lora (https://pypi.org/project/raspi-lora/) for micropython.  I have tested on raspberry pi pico, esp8266, and esp32.  It allows your microcontroller to use an RFM95 radio to communicate.\n\n## Wiring\n\nThe pinout for the RFM95 module can be found on page 10 of the documentation (https://cdn.sparkfun.com/assets/learn_tutorials/8/0/4/RFM95_96_97_98W.pdf).  The pin numbers below are for the RFM95 - look at your microcontroller docs for the pins to connect to them.\n\nPower (the RFM95 module requires 3.3V from your microcontroller):  \n+ connect 3.3V to pin 13  \n+ connect GND to pin 1, 8, or 10 on the RFM95 module\n\nFor SPI communication:  \n+ MISO to pin 2 (MISO)  \n+ MOSI to pin 3 (MOSI)  \n+ SCK to pin 4 (SCK)  \n+ CS to pin 5 (NSS)  \n    \nOther pins:  \n+ Use a GPIO output to pin 6 (RESET) for resetting the RFM95  \n+ Use a GPIO input to pin 14 (D) to trigger that a message has been received  \n\n## Configuration\n**INITIALIZATION**\n```\nLoRa(spi_channel, interrupt, this_address, cs_pin, reset_pin=None, freq=868, tx_power=14,\n    modem_config=ModemConfig.Bw125Cr45Sf128, acks=False, crypto=None)\n```\n\n**spi_channel** SPI channel, check SPIConfig for preconfigured names, e.g. SPIConfig.rp2_0 for RPi pico channel 0   \n**interrupt** GPIO pin to use for the interrupt  \n**this_address** The address number (0-254) your device will use when sending and receiving packets.  \n**cs_pin** chip select pin from microcontroller  \n**reset_pin** : the GPIO used to reset the RFM9x if connected  \n**freq** Frequency used by your LoRa radio. Defaults to 868Mhz  \n**tx_power** Transmission power level from 5 to 23. Keep this as low as possible. Defaults to 14  \n**modem_config** Modem configuration. See RadioHead docs. Default to Bw125Cr45Sf128.  \n**receive_all** Receive messages regardless of the destination address  \n**acks** If True, send an acknowledgment packet when a message is received and wait for an acknowledgment when transmitting a message. This is equivalent to using RadioHead's RHReliableDatagram  \n**crypto** An instance of PyCryptodome Cipher.AES (not tested) - should be able to use ucrypto  \n\n### SPICONFIG\nPreconfigured SPI bus pins for tested devices, just add into the class for other devices\n```\nclass SPIConfig():\n    # spi pin defs for various boards (channel, sck, mosi, miso)\n    rp2_0 = (0, 6, 7, 4)\n    rp2_1 = (1, 10, 11, 8)\n    esp8286_1 = (1, 14, 13, 12)\n    esp32_1 = (1, 14, 13, 12)\n    esp32_2 = (2, 18, 23, 19)\n```\n\n### ModemConfig\nPreconfigured modem settings taken from Radiohead docs, I will try and add the ability to fine tune these in future.\n```\n    Bw125Cr45Sf128 = (0x72, 0x74, 0x04) #\u003c Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium range\n    Bw500Cr45Sf128 = (0x92, 0x74, 0x04) #\u003c Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Fast+short range\n    Bw31_25Cr48Sf512 = (0x48, 0x94, 0x04) #\u003c Bw = 31.25 kHz, Cr = 4/8, Sf = 512chips/symbol, CRC on. Slow+long range\n    Bw125Cr48Sf4096 = (0x78, 0xc4, 0x0c) #/\u003c Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, low data rate, CRC on. Slow+long range\n    Bw125Cr45Sf2048 = (0x72, 0xb4, 0x04) #\u003c Bw = 125 kHz, Cr = 4/5, Sf = 2048chips/symbol, CRC on. Slow+long range\n```\n\n## Examples\nThere are two examples to test sending and receiving data in the examples folder\n\n### Server mode:\n\nCopy the file server.py to your main.py and copy it across together with the library ulora.py to your microcontroller\n\n```\nfrom time import sleep\nfrom ulora import LoRa, ModemConfig, SPIConfig\n\n# This is our callback function that runs when a message is received\ndef on_recv(payload):\n    print(\"From:\", payload.header_from)\n    print(\"Received:\", payload.message)\n    print(\"RSSI: {}; SNR: {}\".format(payload.rssi, payload.snr))\n\n# Lora Parameters\nRFM95_RST = 27\nRFM95_SPIBUS = SPIConfig.rp2_0\nRFM95_CS = 5\nRFM95_INT = 28\nRF95_FREQ = 868.0\nRF95_POW = 20\nCLIENT_ADDRESS = 1\nSERVER_ADDRESS = 2\n\n# initialise radio\nlora = LoRa(RFM95_SPIBUS, RFM95_INT, SERVER_ADDRESS, RFM95_CS, \n            reset_pin=RFM95_RST, freq=RF95_FREQ, tx_power=RF95_POW, acks=True)\n\n# set callback\nlora.on_recv = on_recv\n\n# set to listen continuously\nlora.set_mode_rx()\n\n# loop and wait for data\nwhile True:\n    sleep(0.1)\n```\n\n### Client mode:\nCopy the file server.py to your main.py and copy it across together with the library ulora.py to your microcontroller\n\n```\nfrom time import sleep\nfrom ulora import LoRa, ModemConfig, SPIConfig\n\n# Lora Parameters\nRFM95_RST = 27\nRFM95_SPIBUS = SPIConfig.rp2_0\nRFM95_CS = 5\nRFM95_INT = 28\nRF95_FREQ = 868.0\nRF95_POW = 20\nCLIENT_ADDRESS = 1\nSERVER_ADDRESS = 2\n\n# initialise radio\nlora = LoRa(RFM95_SPIBUS, RFM95_INT, CLIENT_ADDRESS, RFM95_CS,\n            reset_pin=RFM95_RST, freq=RF95_FREQ, tx_power=RF95_POW, acks=True)\n\n\n# loop and send data\nwhile True:\n    lora.send_to_wait(\"This is a test message\", SERVER_ADDRESS)\n    print(\"sent\")\n    sleep(10)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartynwheeler%2Fu-lora","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmartynwheeler%2Fu-lora","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartynwheeler%2Fu-lora/lists"}