DIY ZOE M8Q jamming indicator

How to use the anti-jamming and anti-spoofing functions of the GNSS ZOE M8Q (RAK12500)
GNSS ZOE M8Q features high precision GNSS, dual-frequency RF front-end, anti-jamming, anti-spoofing, and many more.
Built-in anti-jamming and anti-spoofing functions allow you to get rid of a very unpleasant feature of miniature GNSS receivers: after the external “jammer” has worked, the GNSS receiver still produces some coordinates, which, of course, are false.
If you are a developer of GNSS navigation for a homemade drone, then this behavior of the GNSS device can lead to a crash of your aircraft.
However, in GNSS u-blox ZOE M8Q it is possible to read the UBX-MON-HW message and receive data Noise level (hwStatus.noisePerMS), AGC monitor (hwStatus.agcCnt),
CW jamming indicator (hwStatus.jamInd).
It follows from this that it is possible to “block” the output of false location data in the case, for example, if AGC < 100 or CW > 60, as well as in any other combinations.
Thus, the GNSS receiver will stop outputting data if
the level of interference is too high or the AGC gain is too low (the radio receiving path is “clogged” with interference, “shut up”).
This reduces the CPU load because you can avoid reading coordinates from the GNSS device if there is too much interference (or reduce the reading frequency).
Enable that message UBX-MON-HW message for periodic output using CFG-MSG and you can watch the indicators change as you bring potential jamming sources into proximity.
Note that broadband jamming may not necessarily be indicated with the CW jamming metric. For non-CW jammers, monitor for changes in AGC value and C/N0 values as you introduce potential jamming sources.
The software part is implemented in the SparkFun_u-blox_GNSS_Arduino_Library library.
The code is not very complicated, I tried to adapt it for Wisblock API and FreeRTOS
Below are two functions that allow you to monitor interference.
The rest of the code can be found here

Also in the official library SparkFun there is a full-fledged example for Arduino, the file is called Example29_jamminginformation.ino

Sorry for my bad English and I hope my message will be useful for DIY developers.

/* Noise level as measured by the GPS core */
uint16_t noisePerMS;
/* AGC Monitor (counts SIGHI xor SIGLO, range 0 to 8191) */
uint16_t agcCnt;
/* CW jamming indicator, scaled (0 = no CW jamming, 255 = strong CW jamming) */
uint8_t jamInd;

/* Enable the jamming / interference monitor */
bool setup_jamming()
/* Create storage for the jamming configuration */
    UBX_CFG_ITFM_data_t jammingConfig;
/* Read the jamming configuration */
    if (myGNSS.getJammingConfiguration(&jammingConfig))
	  /* Check if the monitor is already enabled */
	  if (jammingConfig.config.bits.enable == 0)
		/* Enable the monitor */
		jammingConfig.config.bits.enable = 1;
		/* Set the jamming configuration */
		if (myGNSS.setJammingConfiguration(&jammingConfig))
		    MYLOG("GNSS", "Enable the jamming");
		    MYLOG("GNSS", "Error the jamming");
    return true;

void getHWstatus()
/* Create storage to hold the hardware status */
    UBX_MON_HW_data_t hwStatus;
/* Read the hardware status */
    if (myGNSS.getHWstatus(&hwStatus))
	  noisePerMS = hwStatus.noisePerMS;
	  agcCnt = hwStatus.agcCnt;
	  jamInd = hwStatus.jamInd;
	  /* Noise level, AGC monitor, CW indicator */
    MYLOG("GNSS", "HW status: NL[%d] AGC[%d] CW[%d]",
	  noisePerMS, agcCnt, jamInd);


1 Like

Thanks for sharing another interesting use case.

You should start a blog with all your nice sharings.