Storm Detector Modules: Dancing In The Rain

Earlier, we had covered setting up an AS3935 lightning detector module. This detector picks up radio emissions, then analyzes them to determine if they are a lightning strike or some other radio source. After collecting some data, it outputs the estimated distance to the incoming storm front.

But that only gets you halfway there. The device detects many non-lightning events, and the bare circuit board is lacking in pizzazz. Today I fix that by digging into the detector’s datasheet, and taking a quick trip to the dollar store buy a suitable housing. The result? A plastic plant that dances when it’s going to rain!

In the last article, I had covered detecting events from the device and then reading back the type of event detected from the device memory. However, we had received a whole lot of type ‘4’ (0100) events output to the terminal, indicating the detection of a lot of non-lightning events. These are called ‘disturbers’ and are radio signals that the chip detects but does not consider lighting. By default it raises the interrupt pin high for these and transmits them anyway.

Our first step will be to filter these out so that we have one less thing to worry about. We could just ignore them, but that’s inelegant – it would be better if there was no data sent at all for these as we’re not interested in them at this time. Thankfully, the datasheet for the AS3935 (PDF) describes a way to do exactly this: bit 5 of memory register 0x03 (MASK_DIST) controls whether the chip transmits disturber events. We can do that by setting that memory address to 0x20 (decimal 32, binary 00100000) before polling the interrupt pin:

pin   = 8
light = 2
spi.setup(1, spi.MASTER, spi.CPOL_LOW, spi.CPHA_LOW, 8, 256);
gpio.mode(pin, gpio.OUTPUT)
gpio.mode(light, gpio.INPUT)

function reason()
	gpio.write(pin, gpio.HIGH)
	gpio.write(pin, gpio.LOW)
	spi.send(1, 0x43)
	read = spi.recv(1, 8)
	gpio.write(pin, gpio.HIGH)
	gpio.write(pin, gpio.LOW)
	gpio.write(pin, gpio.HIGH)

spi.send(1, 0x03)
spi.send(1, 0x20)

tmr.alarm(1, 100, 1, function() poll(0) end)

function poll()
	x =
	if x == 1 then 

When we reset the device, we no longer see any disturber events. Now we see nothing unless I touch the antenna, at which point we read decimal 33 (binary 100001). The MSB (most significant bit) is just the MASK_DIST register that we wrote to, so we can just subtract 32 from whatever result we get, resulting the in the interrupt code. Having done that, the device will output 1 if the interrupt reason is an excessive noise level, and 8 if it is a lightning event.

Getting Wet

This is where something a little embarrassing happened. I was sitting in a café at this stage, showing the device to a friend, and it started recording lightning events. It’s dry season in Vietnam right now and it was a clear day, so I explained I had a few bugs to iron out, then got on my motorbike and took the highway home. I proceeded to get caught in the first storm of the year, it was too violent to drive, and spent half an hour hiding under a small bush laughing at myself. Success!?

Returning to the device, we will ignore high noise level events. For a commercial device you would want to let the user know that the noise level is too high, but that’s not interesting to us right now. What would be fun to know is how far away a storm is. The chip needs to collect a little data to be able to estimate stormfront distance, so we’re going to tell the chip not to alert us unless it detects a minimum of lightning strikes within 15 minutes. Bits 4 and 5 of memory register 0x02 control that feature according to the following table:

Source: AS3935 datasheet

The default value of the entire 8-bit memory register is 11000010, which we will change to 11010010 (0xD2). This sets a minimum of 5 detected lightning strikes per minute before the chip will report lightning. After the 5th strike, it will report every lightning strike by raising the interrupt pin high:

An unusual method of horticulture.

Once it detects 5 lightning strikes, we’ll want the device to output the distance to the storm as it approaches. To do that, we just read register 0x07 and clear bits 6 and 7 in the result. While I’ve only ever seen those bits set to 0, they are reserved by the device and we are not interested in their state. To finish up, we check the event types and distances produced and make the output a little more human-readable. Our final(ish) code is here.

This works and is fine, but it’s not fun enough yet. You know those little plastic toys that dance when a small solar panel is exposed to sunlight? Well, it turns out that the 3.3v output from a NodeMCU is a very effective surrogate to their amorphous silicon solar panel. A quick pulse from one of the output pins converts a device that dances when exposed to sunlight, to one that dances in the rain.

The only modification needed to the code was to raise a pin high for a short while on lightning detection events, connected to the solar panel positive output (NodeMCU ground to the negative output):

gpio.write(quiver, gpio.HIGH)
tmr.alarm(2, 4777, 1, function() dequiver(0) end)

I considered a few models of toy for this part. Monkeys and chickens both sound good with the prefix ‘thunder’. Finally, I settled on a plastic plant because there’s something somehow nightmarish about a plant that quivers in anticipation of rain.

My frivolous use of parts aside, these detectors would be a great addition to many projects like an automatically deploying lightning rod, or a lamp that graphically displays the current weather.

18 thoughts on “Storm Detector Modules: Dancing In The Rain

  1. Can it tell direction? Would there be an easy way to maybe build a yagi antenna (lets see 500KHz is about 600meters, hmmm, not very portable). Or maybe 4 modules with shielding between?

    1. Might be able to tell direction with one antenna, though easier to do with more. Google “ferrite loopstick antenna” images for more ideas also for more directional types if I understand correctly. I assume has directionality especially if you have a reflector on one side of the loop and can rotate like a rotating radar… a “Ferrite Sleeve Antenna” like lately I see DXerGary on youtube demonstrating though not so much for the XLF, ULF or VLF range as much though that range is more for thunder I’m thinking. is handy also for information and kits. That is the site that got me started looking into high magnetic permeability materials other than ferrite.

  2. Yes this would also work if you also used magnetic Hall or MR sensors at one end of the ferrite rods.
    Incidentally someone totally needs to build one of these modules into a prop PKE meter already.

  3. Polling the interrupt pin … Wouldn’t it be better to connect it to the interrupt pin on the microcontroller, that’s what it’s intended for?
    That as3935 is around for quite some time, but I hesitate to buy it as it’s quite expensive. All in all looks like a pretty interesting chip if all you need is warning that storm is approaching. Then you can check Blitzortung to see where the storm is and where it’s heading.

    1. I just felt that this article is incomplete without reference to Blitzortung… You were faster, though :-)

      I wonder if this device would work as a part of the Blitzortung network…

      1. Probably not. BO uses very precise timing from multiple stations to determine lightning positions. Featured chip uses internal signal processing and provides data over SPI interface. Usable for warnings but I think it’s too slow for precisely locating lightnings.

    2. It would have been better to use the interrupt pin… as an interrupt. However using gpio.trig() always failed without error message when I tried it.

      My guess is that it wasn’t enabled at compile time for the firmware (I used the excellent but I’m not sure.

    1. I was originally going to get a Thor action figure, put it on a nice wood altar, and add a “Thor displeased” indicator to the base with some LEDs :)

      I didn’t though, mainly because it seemed a terrible waste of artfully carved wood. I’m remarkably incompetent at making anything actually look good!

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.