LoPy LoRa general consumption/effiency (code and scope printscreen)
Hello, please sit down because I have a long post about LoRa:
-my main objective is to send some sensor data via LoRa from one LoPy to onother, then deepsleep.
-the code is simple and practical, but there where some strange details:
from network import LoRa import socket import time import binascii import pycom from pysense import Pysense import machine from SI7006A20 import SI7006A20 from LTR329ALS01 import LTR329ALS01 from MPL3115A2 import MPL3115A2,ALTITUDE,PRESSURE import json py = Pysense() si = SI7006A20(py) lt = LTR329ALS01(py) mp = MPL3115A2(py,mode=ALTITUDE) mpp = MPL3115A2(py,mode=PRESSURE) data1=mp.temperature() data2=mpp.pressure() data3=si.humidity() data4=lt.light() data = "%.0d %.0d %.0d %.0d" % (data1,data2,data3,data4) lora = LoRa(mode=LoRa.LORA) s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) lora.nvram_restore() s.setblocking(False) for x in range (3): s.setblocking(False) s.send(data) time.sleep(0.2) s.setblocking(True) s.send(data) time.sleep(0.2) s.setblocking(False) py.setup_sleep(1) py.go_to_sleep()
That is the current conspumtion, as you can see it wakes up, has a little delay, I send the same data 6 times and then deepsleep. The reason I send it 6 times is because it is not recieved verry well and I hope that from 6 times it will be recieved at least once. Besides that sometimes works ONLY when setblocking is FALSE and other times ONLY when it's TRUE (don't understand why).
The sollution is not verry practical, the 2 LoPy's where at 30cm distance and the transmision was poor. So I decided to see if is there a correspondance between message length and probability of reception.
I made a code when it sends first 10 characters, then 20, and then 40 (between them I have rgb lights just for reference), the code:
from network import LoRa import socket import time import pycom from pysense import Pysense pycom.heartbeat(False) py = Pysense() lora = LoRa(mode=LoRa.LORA, tx_power=18, sf=6 ,frequency=863000000) s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) s.setblocking(False) pycom.rgbled(0xffffff) time.sleep(0.5) pycom.heartbeat(False) s.send('1234567890') pycom.rgbled(0xffff00) time.sleep(0.1) pycom.heartbeat(False) s.send('12345678901234567890') pycom.rgbled(0x0000ff) time.sleep(0.1) pycom.heartbeat(False) s.send('1234567890123456789012345678901234567890') #and another one with 80 characters that doesn't fit in the screen pycom.rgbled(0x00ff00) time.sleep(0.2) py.setup_sleep(15) py.go_to_sleep()
With the following consumption:
With a little zoom on the transmission :
- This is verry dissapointing : the transmission length is the same wether I send 10, 20, 40 or 80 characters, why is that ?
- What are those spikes right before the transmission ?
- Why it takes 10,4 ms to send it ? When is used the function chrono.start() / chrono.read() / chrono.stop() it indicated only 70 us
- How can I improve the transmission efficiency (tx-power ? spread factor ? frequency ?)
Thanks for your pacience and hope for the best !
@iplooky Hard to say what's wrong. I made my first test with the lopy-lopy examples https://github.com/pycom/pycom-libraries/tree/master/examples/lopy-lopy, and they worked ok, as long as I started lopy-b first. No problem with a short distance.
I have also set up a LoPy as TTN gateway and a FiPy a TTN node, and walked away like 500m from the gateway. Still at rrsi of -100, being able to send and receive messages. I also receive messages at the gateway from nodes like 3 km away, estimated from the rssi level of -126 to -130. I'll try some larger (than 500m) distances later.
@robert-hh poor transmission means the following: if I want to send a short message (7characters) it is a slightly chance to recieve it from the first time ( but still I send it 6 times consecutively just to be shure ), 10,20,40 or 80 characters have a nearly to 0 chance to be recieved. (10 meters, SF=7/DR=5 , TX_power=20 )
lora = LoRa(mode=LoRa.LORA, tx_power=20 , sf=7 ,frequency=863000000) #europe 863MHz s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) s.setblocking(False)
should work just fine ?
In LoRa mode the socket.SO_DR socket options are ignored, those are meant for LoRaWAN mode.
For LoRa please set all these parameters at init time in your LoRa() call, for LoRaWAN set it via socket options.
@iplooky How is your antenna set-up? And what do you call a poor transmission?
@jmarcelino the reciever code should be the same in any case or do I need there to modify Lora's paramethers too?
I mean :
from network import LoRa import socket import time lora = LoRa(mode=LoRa.LORA, rx_iq=True ,frequency=863000000) s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) s.setblocking(False) print("start") while True: mesaj = s.recv(64) if(mesaj != b''): print(mesaj)
..should be a universal code OR should I try to modify there too ?(DR,SF,freq)
- from what i've understand DR and SF are complementary, if DR is 5 that means automatically that SF is 7 (and therefore I should not modify it because it's known already from DR) ?
- tx_power=20 should have also a rx_power=20 or just rx_iq=True ?
- putting the 2 lopy's at several meters and testing the code has the same bad results (poor transmission)
TX Power = 20dBm isn't legal in Europe for most channels (there are some exceptions), by law it should be 14dBm.
But yes it generally would greatly increase the signal (at the cost of higher power consumption).
@jmarcelino would tx_power = 20 (the maximum value) influence in any way ? (in comparison with the default value?)
I've read one of your old posts : https://forum.pycom.io/topic/1652/solved-lopy-max-transmit-power-20-dbm-at-869-mhz but being 7 month old I was wondering if updates/imporvements appeared.
It's not possible to have accurate DR to distances calculations. What you can know is what is the lowest SNR at which a signal can be decoded and that depends on the spreading factor:
Higher spreading factors mean lower data rates. So at SF7 (or DR5) you can decode up to SNR -7.5, at SF12 (DR0) you can go as low as -20 so effectively being able to pick up weaker signals.
However three problems:
At SF12 you can see transmission of 10 bytes takes 1483ms, this means that (considering Europe's) duty cycle restrictions of 1% mean you'll need to wait a very long time until you can transmit again on that channel: 131 seconds!
Also it means you have the radio full on for that time consuming more energy
Finally since the transmission takes so long you're also at higher risk of collision/interference from other transmitters operating on the same frequency.
@iplooky The slowest data rates (smallest DR number and largest SF) have in theory the longest coverage.
With devices in the same room, DR5 (SF7) should be more than enough. If you want to test long-distance, you'll probably go for DR0 (SF12). You can adjust the actual DR based on the received signal levels (RSSI and SNR).
@robert-hh If I did understand correct, I should lower the DR in order to increase the chance te recieve the message, in my case it is aprox. 20 characters long so DR=1 should work just fine
Is there a datasheet where I can see the correspondance SF - distance ?
@iplooky DR = Data Rate. The time needed to send a byte depends on the data rate setting. The default here is 5 alas DR5. = 5470 bit per second. At that data rate, even mesages with the shortest payload take about 20ms airtime. The join request/accept message ar on air for instance about 70 ms, the test messages from the example with 6 bytes payload take about 30 ms.
@robert-hh don't quite know what means DR and where to modify it
@jcaron I didn't disable the wi-fi, I will try it next time I have acces to the scope
@rcolistete ok, will try to increase the distance between the Lopy's
I don't quite know what paramethers to modify and how much to modify them, will try to measure the transmision time with chrono.start() and chrono.stop() when recieved the ackowledge signal (assuming the transmision is made 100% accurate)
You've said :
" the 2 LoPy's where at 30cm distance and the transmision was poor."
while LoRa has problems for low distances, depending on its configuration (SF, BW, tx_power), because it saturates the amplifier.
Solution is simple : put both LoPy separated by some meters.
Also, my experience with "setblocking(True)" isn't good*, so I suggest to avoid using it.
(*) : any send is a lot slower when "setblocking(True)" is chosen and Terminal is running.
Regarding the spikes, they do not seem to be related to transmission, as they are present during the whole active time of the LoPy. They seem to be every 100 ms, i.e. 10 Hz. As they start quite early, they're probably related to something started by the system. Have you disabled Wi-Fi on boot?
@iplooky You may also look into the picture here, https://forum.pycom.io/topic/2676/abp-mode-and-frame-counters/17
Where you can see the sensing of a OTAA Join request and response. The actual time on air is like 70 ms at DR5.
I don't have answers to all your questions, but in any case even at the fastest DR, the order of magnitude to send a frame is tens of milliseconds, definitely not micro-seconds (and if you get to the slowest data rates we're talking seconds). If you measure micro-seconds, you're most certainly non-blocking and measuring just the time to queue the frame internally.
In LoRaWAN mode there's a lot of overhead (preamble, header...) which may imply very little difference on the total transmission time for different data lengths. Not sure about raw LoRa, but you probably still have at least the preamble.
@iplooky At DR5, the transmission speed is 5470 bit/s or ~1.5 ms per byte. So whatever happens in 10ms, is not the sending of the message. You should also wait a few seconds between sending attempts.