LoRa – does CAD work at weak signal levels ?

The SX127x data sheet defines CAD as;

When in CAD mode, the device will check a given channel to detect LoRa preamble signal

And;

Principle of Operation

The channel activity detection mode is designed to detect a LoRa preamble on the radio channel with the best possible power efficiency. Once in CAD mode, the SX1276/77/78/79 will perform a very quick scan of the band to detect a LoRa packet preamble.

There is little to suggest that CAD works on the body of the packet, which in practice is the major par of the transmit time. So whilst CAD is supposed to detect the pre-amble of a packet, does it detect a packet at other times ?

To test this the idea would be to transmit long packets (of several seconds) and have a receiver constantly running the CAD process. When each CAD period was finished the CAD detected flag would be read and a LED turned on or logic level set if the flag was active. Thus by observing the LED so that you could see for how long a packet was detected by CAD and how consistent the detect was.

The packets would be sent in sequence of descending powers (17dBm down to 2dBm) so it would be possible to see by observing the LED how well CAD performs as the signals got weaker. The link test software I use was changed to send packets that were close to 5 seconds long at SF12 and bandwidth 125khz.

The test transmitter was fitted with an SMA terminator on its antenna input, this should cut the actual transmitter power (and received distance) significantly.

I did an initial test with transmitter and receiver close. It’s clear that the CAD worked on the entire packet. In my test the LED on the transmitter (indicating a packet send in progress) closely followed the CAD detect on the receiver. There was one curious exception and it was consistent, approximately 360mS into the 5079mS packet there would be one CAD detect that failed. It was also noted later that this gap occurred with weak signals too.

With the principle of CAD working on the entire packet established I moved on to seeing if it also worked on weak packets.

The transmitter and receiver were loaded with my link test software and I adjusted the locations of both so that the packets stopped being received at around the 9dBm point.

Here is the link test software output;

Mode1 17dBm,11 16dBm,11 15dBm,11 14dBm,11 13dBm,10 12dBm,10 11dBm,11 10dBm,10 9dBm,8 8dBm,4 7dBm,5 6dBm,0 5dBm,1 4dBm,0 3dBm,0 2dBm,0

Mode1,CSV,11,11,11,11,10,10,11,10,8,4,5,0,1,0,0,0

You can see from the counts that packet reception starts to fail at around the 9dBm point and stops almost completely after 7dBm.

Once the test link had been characterised the receiver was loaded with the CAD detect test software. The positions of the transmitter and receiver were kept the same to ensure consistent link performance.

With the receiver LED being on when CAD succeeds, we can easily tell when a packet is being received. At the start of the descending power sequence (17dBm packet) there is an audio tone transmitted which can be heard on a UHF handheld. When the tone from the remote transmitter is heard you can now count the arriving packets by observing the CAD detect LED. By counting the packets you know which power is in use when the CAD starts to fail, indicated by the LED flickering.

The CAD process was consistent (apart form the gap @ 360mS mentioned above) and started breaking up at around 14 to 13dBm dBm so within about 4 or 5dBm of link failure, this is better performance than expected.

So in approximate terms CAD detect does appear to work on the entire packet, but is only consistent up to around half the distance that the weakest packets are detected.

In the CAD detect software used each CAD detect and print of information to console was taking approximately 62mS. I left the receiver running for 10 minutes to see if there were any false CADs. There were 119 false CADs in 10 minutes or about 1 every 5 seconds or about 1 : 80 CADs are false.

What of the gap in the CAD at the beginning of the packet?  This would appear to be at the time the preamble pattern ends and the packet data starts, so it’s possible CAD will see the preamble, or the packet, but not when both are mixed together.

 

More ESP32 adventures

I have shown in a previous post that it had been possible to cut the deep sleep current of a ESP32 module, with a LoRa device, FRAM and display down to the 8uA region by careful attention to pull up resistors and type of display.

I thought it would be useful to be able to include a Micro SD card into my projects. For the trackers it would be very handy to be able to log GPS data to an SD card. This could be useful if for some reason the LoRa radio link stopped working. For the same reason this would be a useful backup for remote sensor or data gathering applications.

The current taken by micro SD cards seems to vary greatly, the one I was using was consuming 200uA or more when inactive, which would make battery life poor.

I tried switching off the power to just the SD card, but that had the effect of dragging pins on the SPI bus low which increased the sleep current of the LoRa device.

A different approach was needed.

I built up an ESP32 board that used a MOSFET to turn off the VCC power rail to all the devices external to the ESP32, LoRa module, display, FRAM, BME280 sensor and micro SD card.

The picture shows the prototype in action, sleep current was measured at 11uA, and that includes a resistor network to measure the battery voltage and a charger IC to allow for solar battery charging.

This power switching approach also made the software side an easier, it was not necessary to take all the attached devices through a shutdown sequence.

Of course this does mean that all devices need to be re-initialised every time the ESP32 comes out of sleep mode but this is not a difficult issue to deal with.

Locator ESP32 FrontLocator ESP32 Rear

Measuring Low Currents

You may find you need to measure the current consumption of your latest cunning project.

If this current is in the mA range, say from 2mA up to 500mA or more then a standard multimeter will normally do the job. All you need to do it put the multimeter on a suitable current range in series with the power supply, as in the picture;

Measuring current ReducedOne issue that can affect the measurements is the voltage drop across the multimeter. The multimeter measures current by allowing the current to flow through a low value resistor and then measures the voltage drop across that resistor (normally called the shunt). The multimeter can then calculate the current in the resistor.

This voltage drop across the resistor\multimeter is the burden voltage of the multimeter and its consequence is that the project whose current consumption you are measuring is now lower than before.

A Fluke 87 for instance has a burden voltage of 1.8mV per mA on the mA range so if the current flow is 100mA, there is an 180mV voltage drop across the multimeter and the projects supply voltage is now 180mV lower.

What do you do if you want to measure the sleep current of a project which is likely in the tens of uA range? If you have the multimeter on the mA range there won’t be enough resolution to give a good indication of a current in the low uA range.

Also you probably cannot put the multimeter on the mA and then switch to uA as the switching can disconnect power from your project and cause a reset.

So what happens if you start with the multimeter on the uA range? The Fluke 87 has a burden voltage of 100uV per uA on this range so if the project is drawing 100mA when its not in sleep mode the burden voltage of the multimeter will be;

100,000 * 0.0001 = 10v !

Oh dear, with a 10V voltage drop across the multimeter your project is unlikely to run in at all.

Wire Short ReducedSo what to do ?

The answer is fairly straight forward. Start with the multimeter on the uA range and short across it with a bit of wire.

See picture, the multimeter connections are the red and black crocodile clips, the shorting wire is the yellow one.

Then when your project puts itself into low current mode, remove the wire. The burden voltage of 100uV per uA should not cause problems with most projects and you should be able to accurately measure currents down to 1 or 2 uA.

The project shown in the first picture has a sleep current 12.9uA, so the burden voltage is only 1.29mV, which is unlikely to cause a problem. My OWAN B35T (much cheaper than a Fluke !) has a burden voltage of 50uV per uA.

Rather than use a bit of wire to short out the multimeter, make up a switch unit that has power in and out connectors (see picture) with tags for the multimeter connections in the positive line. The switch shorts across the multimeter connections. Short out the multimeter with the switch put the multimeter on the uA range and when the project is in low current mode open the switch. Simple.

Switch Reduced

 

Switch in Use Reduced

ESP32 Shield – Adding a LoRa Device

I added the socket headers that allowed me to plug in a LoRa module. The sleep current went from around 8uA to 1.95mA, something definitely wrong. Checking the current consumption figures in the SX127x datasheet and registers it appeared that the LoRa device was in standby mode, despite the fact that the commands to put the LoRa device to sleep were being sent.

I eventually traced this issue to the RESET line on the LoRa device, when the ESP32 enters deep sleep mode it turns off the IO pins and it appeared that during this turn off it causes the LoRa device to reset. I removed the ESP32 IO pin (27) from the LoRa device and the LoRa device then went into sleep mode correctly. An alternative solution was to set pin 27 to an input prior to the ESP32 entering sleep mode. The LoRa device has an internal pull up on RESET so it would not be floating.

Although the ESP32, SSD1306, FRAM and LoRa device were now going into sleep mode, the current was still high, in the region of 290uA, I say ‘region of’ because it was varying.  I recall from the previous build of the shield that the LoRa device would still consume 300uA or so when in sleep mode, but with some of its inputs (SCK, MISO and NSS) floating, this should not be a surprise. So I added the pull ups in order;

Start 280uA.

MOSI 19uA

SCK 8uA

NSS 8uA

RESET 8uA

So it would appear that pull ups on MOSI and SCK are required, and it makes sense to leave the one on NSS to prevent any oddities if the select pin floats low.

Progress so far is that the shield with an ESP32, SSD1306 display, FRAM and SX127x LoRa device has a sleep current of 8uA, although it does vary downwards a bit, sometimes going as low as 7.2uA.

Testing the board with and without the SSD1306, I would conclude that the SSD1306 consumes 0.5uA in when in sleep mode.

Testing the board with and without the LoRa device, I would conclude that the LoRa device consumes, 0.1uA when in sleep mode.

The partially completed board is below, it can powered from battery or USB power.

ESP32 Shield with LoRa

Next: adding the SD card.

ESP32 Shield – a Low Power Journey.

This post is about the build of a very low sleep current ESP32 shield. This is my second version of the shield and incorporates improvements discovered the first build. The original shield seemed to be a surprise to the outside World, the power consumption was in the region of 8uA when complete with SSD1306 display, FRAM, TC75 temperature sensor and SX127x LoRa device.

This blog is a description of the build of version 2 of the shield stage by stage and the measured sleep current as more parts are added.

Sleep currents were measured with a multimeter. I built an adapter that goes inline with the battery with connections for the multimeter and a toggle switch. The switch allows the multimeter to be shorted. Thus with the switch shorting the multimeter there are  no burden voltage issues caused by the multimeter. When the ESP32 goes into deep sleep just flip the switch and read the current (in uA) from the multimeter. With the multimeter measuring a a sleep current of 8uA the voltage across the multimeter was only 0.8mV, which is less than would occur if I was using my uCurrent Gold on the 1mV per uA range.

I started the build by adding fitting the  MCP1700 3.3V regulator. The current consumed with nothing connected to the output of the regulator was 1.6uA, a good starting point.

I fitted the ESP32 and the components required to allow the ESP32 to be programmed via a plug in USB to serial adapter, see picture.

The test program was a version the Andreas Spiess used in the video on deep sleep of the ESP32, see the link below;

https://www.youtube.com/watch?v=r75MrWIVIw4&vl=en

I changed the program so that at  start the LED would flash and the ESP32 would go into deep sleep for 30 seconds, when the LED stopped flashing I knew to flip the switch shorting the meter and take the current reading. 

ESP32 just module

OK, so lets add a SSD1306 OLED. The Adafruit library has an option that in effect turns the display off; ssd1306_command(SSD1306_DISPLAYOFF);

The test program writes some text to the screen then flashed the LED and goes into a 30 second deep sleep, this is the result, 7.7uA;

ESP32_SSD1306

The ESP32 does have 8Kbytes of RTC RAM that will survive deep sleep, so this could be useful for keeping track of what a program is doing when going into and out of deep sleep, however this RAM will not survive reset or power down, so I prefer to add a FRAM to projects. These FRAMs are like EEPROM but they have a limited life, maybe 1,000,000 writes. FRAMs have a write endurance many times greater, up to 100,000,000,000,000 writes, so can be treated as RAM. I added a MB85RC16PNF 2Kbyte FRAM and measured the sleep current, it was only 0.1uA extra;

ESP32_SSD1306_FRAM

So 7.8uA for an ESP32, SSD1306 display and a 2Kbyte FRAM, looks promising.

Next:  Adding SPI devices.

Power measurements can be useful !

A previous blog post looked at how you can use a cheap (£20) power meter to make accurate measurments on the power output of LoRa radio devices.

I was following the guide and program for a creating a simple TTN node that Andreas Spiess presented in a video;

https://www.youtube.com/watch?v=duwUwXt-hs8

The program provided uses the LMIC library. The program works fine and the packets show up in the TTN device console.

I wanted to add some of my own diagnostics, so I borrowed some routines from my tracker software thats reads back the LoRa device registers after a packet send and displays the frequency, bandwidth, spreading factor, coding rate and power level the LoRa device was set to.

I had assumed the power level for a TTN node would be set to 14dBm/25mW due to legal restrictions, but the LoRa device was inmdicating it was s set to 16dBm/40mW .

I knew that my ‘calibrated’ 868mhz LoRa module was about 1dBm below the power it should be (see the previous blog post) so I hooked that module and the TTN node software to the power meter. The node program copde was set to send a SF12 packet at start up so there would be enough time for the power meter to display it.

The power meter displayed 15dBm, which is consistent to it actually being programmed for 16dBm as my diagnostic code had suggested. 

Now the appropriate register for power level is RegPaConfig and its set in radio.c of the LMIC library;

static void configPower () {
#ifdef CFG_sx1276_radio
// no boost used for now
s1_t pw = (s1_t)LMIC.txpow;
if(pw >= 17) {
pw = 15;
} else if(pw < 2) {
pw = 2;
}
// check board type for BOOST pin
writeReg(RegPaConfig, (u1_t)(0x80|(pw&0xf)));
writeReg(RegPaDac, readReg(RegPaDac)|0x4);

#elif CFG_sx1272_radio
// set PA config (2-17 dBm using PA_BOOST)
s1_t pw = (s1_t)LMIC.txpow;
if(pw > 17) {
pw = 17;
} else if(pw < 2) {
pw = 2;
}
writeReg(RegPaConfig, (u1_t)(0x80|(pw-2)));
#else
#error Missing CFG_sx1272_radio/CFG_sx1276_radio
#endif /* CFG_sx1272_radio */
}

I have CFG_sx1276_radio selected so the power level is set by this line of code;

writeReg(RegPaConfig, (u1_t)(0x80|(pw&0xf)));

Which writes the pw variable into the power setting register. If pw is 14 (for 14dBm?) the power level of the device is according to the datasheet;

Pout=17-(15-OutputPower). ‘OutputPower’ is what is written to bits 3-0 of RegPaConfig and if its 14 the actual power level selected appears to be;

Pout=17-(15-14) = 16dBm.

This is in line with my diagnostic print, which suggests the power level is being set to 16dBm when 14dbm is expected.

Is it possible the LMIC code should be;

writeReg(RegPaConfig, (u1_t)(0x80|(pw&0xf)-2));

Measuring Power

When your using or experimenting with radio devices there is often the need to measure power levels at radio frequencies. This can be the power output of a small radio module, 10mW at 433Mhz or the signal power seen by a receiver, –100dBm. The receiver power is often referred to as the RSSI.

Measuring RF power under 100mW, with accuracy, is not so easy as a lot of RF power meters of the type used by radio amateurs often have a minimum power input in the 1W region.

There are now available some low cost RF power meters, which have a wide frequency range of up to 8Ghz and measure power in dBm from –5dBm to –55dBm. One such is shown in the picture, it was purchased on eBay for around £20.

If these meters can measure only from –5dBm to –55dBm, and you want to measure the 2dBm output from a LoRa module you need to use an inline attenuator, 20dB or 30dB for example. With the power meter connected through the attenuator and the LoRa module set to transmit a 2dBm carrier,  if the power meter is accurate, then it ought to display –28dBm. See picture for the setup. The LoRa module is on a plug in Mikrobus module, so it can easily be moved between different controller boards.

 

And here lies a problem, how do you know your (cheap) power meter is accurate?

The simple way is to take the power meter somewhere and get it calibrated, but I decided it would be more useful to calibrate the transmitted power output of a LoRa module and then keep it as a reference. If I know that a specific LoRa module puts out 9.8dBm when set to 10dBm, I can be keept as a long term reference and as long as I take care when using it, always have an antenna connected for instance, then it ought to be stable for quite some time.

In the centre of Cardiff is Eagle labs;

https://labs.uk.barclays/locations/cardiff-en

It’s run by Barclays and Legal & General with RadioSpares providing equipment in the electronics lab. Part of this equipment is a spectrum analyser (RSSA PRO 3032X) and it’s got a  proven calibration history. So my plan was to book a session at Eagle labs and use their spectrum analyser  to ‘calibrate’ the power output of a 434Mhz and 868Mhz LoRa module.

I wrote a simple test program that for the 433Mhz and 868mHz modules that transmitted RF carrier for a couple of seconds at 17dBm, 10dBm and 2dBm, I used a 20dB attenuator between the LoRa module and the spectrum analyser.

I got these results for 434mhz;

LoRa device programmed power output       17dBm          10dBm               2dBm

Measured power 434mHz                            -4.6dBm        -11.3dBm          -18.6dbm

LoRa device actual power 434mHz              15.4dBm         8.7dBm            1.4dBm   

 

For the 868Mhz tests I have included the readings of the power meter with a total of 30dB of attenuator in line, these were the results;

LoRa device programmed power output       17dBm           10dBm               2dBm

Measured power 868mHz                            -4.1dBm         -10.3dBm          -18.5dbm

LoRa device actual power 868mhz               15.9dBm         9.7dBm             1.5dBm    

Power meter indication (30dB att)                -13.1dBm       -19.3dBm           -27.6dBm

Power Meter corrected  +29dBm                   15.9dBm        10.7dBm             2.6dBm  

 

The key point from the above measurements is that I know that my 868mHz module puts out 15.9dBm when set to 17dBm. 

With a 30dB attenuator in use the power meter indicates –13.1dBm. Now 30dBm (because of the attenuator) below an actual power of 15.9dBm is –14.1dBm, so with the power meter actually reading –13.1dBm, its reading 1dBm lower than it should be. The power meter has an offset you can set, so if I set the offset to 29dBm, then when the actual power is 15.9dBm, the power meter will read 15.9dBm due to the effect of the attenuators. 

I know that all sounds a bit long winded, but the end result is that I have a relatively cheap power meter (£20) that has been adjusted to give accurate results. Of course its entirely possible to calibrate the power meter directly, but since I now have a LoRa module that puts out a known amount of power I can keep it and use it to check this or other power meter or attenuators in the future. And then of course with enough attenuators in line, I can also use the calibrated LoRa modules to check the RSSI readings of various radio receivers.

Phantom Packets – Is this the reason ?

After consulting Semtech, the reason why these phantom packets are seen becomes clear.

This is my current understanding of the issue but testing is continuing …………….

The LoRa receiver will occasionally falsely see noise from the receiver itself as a packet preamble and header. Since its noise from the receiver this explains why the phantom packets are seen even in heavily screened receivers underground.

The header is protected with only a 6 bit CRC so there is a 1:64 chance that this noise will pass a valid header check.

When sending LoRa packets you have the option of using a payload CRC (16 bit) or not. If there is a payload CRC enabled a flag bit is set in the header. When receiving the packet the LoRa receiver tests for this payload CRC enabled flag and carries out the CRC check on the payload.

The trap you can fall into is in assuming that since your application only sends packets with CRC on the payload enabled, on packet receipt you only need to check the RegIrqFlags register PayloadCrcError bit. If its set there is a CRC error, if it clear then you assume your packet is valid. But it may not be.

When one of the phantom packets is received (which are just noise remember) there is a probability that the false header both passes the header CRC check and does not have the payload CRC enabled bit set. If this bit is not set in the header then the LoRa receiver does not carry out a payload CRC check and the CRC error flag is left clear.

There are some LoRa software libraries that on packet receipt appear to check the header for the payload CRC enabled flag and then check the payload PayloadCrcError flag as appropriate. This makes sense if your receiver software is designed to automatically cope with packets that use a payload CRC and those that do not.

So in summary to ensure that you do not read phantom packets as valid, you should consider;

1. Sending packets with the payload CRC enabled.

2. Checking the RegHopChannel register RxPayloadCrcOn bit, if its is clear, dump the packet, it could be a phantom.

3. If the RegHopChannel register RxPayloadCrcOn bit is set, check the RegIrqFlags register for the PayloadCrcError bit, if that is set dump the packet, it could be a phantom.

 

 

A LoRa mystery – Phantom packets but deeper

Despite the shielding of my LoRa receivers being able to resist 50mW at 5cm it was possible that there could be a Megawatt LoRa transmitter somewhere close that was the cause of the phantom LoRa packets I was seeing at 868Mhz bandwidth 500khz and spreading factor 7. It’s unlikely there would be such a powerful transmitter nearby that I did not know about, but it seemed a good idea to eliminate it as a possibility.

What I needed was a test area that was in a relatively remote, was underground and with no openings to the outside world. Fortunately up in the hills nearby is a disused railway tunnel, it’s at a height of 439m AGL, the tunnel is 600m long and curved so that in the middle there is no line of sight to the outside world. The tunnel is some 40m underground in the middle. There is a quiet road nearby with a few cars, the nearest building is 1km away. There are a few further buildings 3km away.

I went to the tunnel on a wet afternoon with my brother (Neil) to see if there would be any difference in the number of phantom packets received and their signal strengths in the middle of this tunnel. I used two receivers heavily screened as before and took the precaution of eliminating all possible EMI producing gadgets, phones off, cameras off, I even took the battery out of my car key fob.

With the two receivers on the floor I could still hear the beeps indicating phantom packets at the same rate as I had been getting in my workshop and local field.  Looking at the logs the receivers produced later it was clear that the signal strengths in the workshop were the same as I was seeing deep underground and a very long way from any LoRa transmitters.

 

Log

ReqIrqFlags 0x50
CRC and Header OK
SNR,-11dB,RSSI,-114dBm,Length,153
Packet data 9E,62,C8,7C,55,B2,6F,E1,40,8A,F8,D4,B1,99,0C,33,EA,E1,58, (packet data truncated)
Valid Packets 7  CRC Errors 2  Header Errors 0

Reported signal strength in all the tests, with an antenna on a tall mast, with small antenna on the bench, with an SMA terminator on the antenna socket on the bench, heavily screened on the bench and now with a heavily screened receiver deep underground were always the same, –112dBm to –114dBm and with SNRs of –11dB or –12dB. My assuimption would be that the source of the phantom packets was the receiver itself.

With  the microprocessor in use (ATMEGA328) being put to sleep this suggests the source of the phantom LoRa packets may be the LoRa device. If that is the case how can it be that the CRC is valid for about 70% of the phantom packets? My logging software was printing out the contents of the ReqIrqFlags register and that indicates a valid header (which has its own CRC) as well. 

What are the chances of the CRCs for header and payload being valid in a packet that’s some sort of random occurrence of noise?

 

A LoRa Mystery – Phantom Packets.

I had noticed  while testing LoRa links at 868Mhz with different receiver types that I was seeing a number of ‘phantom’ packets that I did not recognise. I initally thought these were just LoRa packets from the surrounding environment. 

The receiver I was using was listening on Bandwidth 500Khz and spreading factor 7, which is not the typical packet settings used by LoRa for Internet of things applications. I was using these settings as I needed a fast data rate and only a hundread meters or so of range. These phantom packets being quite short range I thought must be coming from somewhere nearby.

I used some LoRa SD card logging software I had written to check out the details of these phantom packets. I could leave the receiver running for long periods to see how many packets were received. I did fing a bug in the software which explained some odd RSSI and SNR values I had been seeing but I was still curious as to where the packets were coming from.

 

LoRa Receiver

 

With the receiver running on the bench with an antenna I was getting around 5 to 10 phantom packets per hour, these were a mixture of packets with valid CRC and those where the CRC check had failed. Packets varied in length from a few bytes up to 200+. The reported RSSI and SNR was always around –110dBm and –10dB respectively which suggested a single source of the packets. 

I put an SMA terminator in place of the antenna and was surprised to see that I got around the same results, 5 to 10 packets per hour and similar RSSI and SNR values.

As a check to see if these phantom packets were actually coming from the great wide world I put my reference 868Mhz antenna (1/4 wave vertical with radials) on top of the 8.5m mast attached to my workshop. I got the same results as I had when the receiver was sat on the bench with an SMA terminator on it. The assumption might be that the source of the phantom packets was therefore very local, interference from my PC or the lights perhaps ? That however would not explain why I origionally seen these packets in the middle of a large field.

For some of the LoRa link testing I had been doing recently I needed to cut the range of the LoRa transmitter (at spreading factor 12) to just 50m or so. Fitting an SMA terminator in place of the antenna was not enough. Even putting the receiver in a die-cast aluminium box was not enough. What did work very well was wrapping the transmitter in aluminium foil. That cut the reception range to 10m or so and it was easy to adjust the range out to 50m by using a pin to put small holes in the aluminium foil.

LoRa Test Transmitter

 

 

 

 

 

 

 

 

 

 

 Screened Transmitter

 

 

 

 

 

 

 

 

 

 

 

If the aluminium foil was so effective at preventing the RF getting out, it ought to be effective at preventing RF getting in. So I wrapped a LoRa receiver in foil and also put it in an   aluminium box. A LoRa transmitter sending packets at 17dBm (50mW) had to be within 5cm of the box for the receiver to pick up the packets, there was a buzzer on the receiver so I could tell when packets were received. So if real world packets were getting through all that shielding they had to be very powerful indeed.

Screened Receiver

With the receiver now wrapped in foil and consequently very well screened I was still receiving phantom packets and with the similar RSSI and SNR values as before. Perhaps the phantom packets were a result of electro magnetic interference (EMI) coming from the receiver itself, but if so how could the CRCs be valid ?

I modified my logger software to put the Arduino Pro Mini to sleep and have it wake up when a packet was received using an interrupt from the LoRa devices DIO0 pin. I even powered down the SD card. Thus the only active electronics running (and thus possibly generating EMI) was the LoRa device itself listening for a packet.

With only the LoRa device itself active and with it heavily screened from the outside world, still the phantom packets appeared.

These phantom packets do seem to be coming from the receiver itself; when I ran two identical receivers next to each other on the bench, each would receive phantom packets but not at the same time. If the source of the packets was external then you might expect at least some duplicate receptions.

This does not appear to be just an issue with the 500khz bandwidth setting, IO have also seen phantom packts when the 125khz bandwidth setting is used.

Maybe the LoRa receiver is fooled into starting packet reception by noise but then why does reception complete with a valid payload CRC and a valid header CRC as well?