Raspberry Pi Lightning Detector - v1 and v2

This is a current in-progress project. I’m using an ams AS3935 lightning detection sensor IC with a Raspberry Pi to detect lightning within approx 40km. To quote from the manufacturer about the AS3935…

AS3935 Franklin Lightning Sensorâ„¢ IC is a programmable fully integrated lightning sensor that detects the presence and approach of potentially hazardous lightning activity in the vicinity and provides an estimation on the distance to the head of the storm. The embedded lightning algorithm checks the incoming signal pattern to reject the potential man-made disturbers. The AS3935 can also provide information on the noise level and inform the external unit (e.g. microcontroller) in case of high noise conditions, with the noise floor generator and noise floor evaluation blocks.
[ul] [li]Lightning sensor warns of lightning storm activity within a radius of 40km[/li] [li]Distance estimation to the head of the storm down to 1km in 14 steps[/li] [li]Detects both cloud-to-ground and intra-cloud (cloud-to-cloud) flashes[/li] [li]Embedded man-made disturber rejection algorithm[/li] [li]Programmable detection levels enable threshold setting for optimal controls[/li] [li]SPI and I²C interface is used for control and register reading[/li] [li]Antenna Tuning to compensate variations of the external components[/li] [li]Supply voltage range: 2.4V to 5.5V[/li] [li]Power-down, listening, and active mode[/li] [li]Package: 16LD MLPQ (4x4mm)[/li] [/ul]

The project is currently using module parts, which means that in it’s simplest form it’s more or less plug-and-play. That does mean it’s probably more expensive too. However, if you have the skills you can build it from indivudual parts which is probably going to be cheaper.

Hardware

  • 1*Raspberry Pi - I’m using a 4GB Model 4B but I think this will also work on Model 3 devices with less RAM and possibly Model 2’s too. The GPIO interface on Model 1’s isn’t compatible though. Raspberry Pi’s are available from many sources and I’m treating it as a commodity device so I won’t discuss it too much within the project.
  • 1*Mikroe Pi 3 Click Shield - This is a Pi addon board designed to plug into the 40-pin GPIO connector on a Raspberry Pi. It provides two mikroBUS sockets which allow you to plug a wide variety of ‘click boards’ into the Pi. This is a simple way to add sensors onto a Pi, but be aware that Pi software isn’t available for all of the sensor boards so you may have to write your own/adapt other code. You can buy the Pi 3 Click Shield direct from Mikroe Pi 3 Click Shield in the US, and also some electronics suppliers in other countries, e.g. RS Components or Farnell in the UK. Note that whilst this is called a ‘Pi 3’ shield it is also compatible with the Pi 4 (and I think the Pi 2).
  • 1*Mikroe Thunder Click board - This is a mikroBUS module that plugs into the Pi 3 Click Shield. It has an AS3935 lightning detector chip and a MA5532 coil antenna built onto the module with supporting components. You can buy the Thunder Click direct from Mikroe Thunder Click in the US, and also some electronics suppliers in other countries, e.g. RS Components or Farnell in the UK.

Assembly

  1. Plug the Pi 3 Click Shield onto the 40-pin GPIO connector on the Pi. Follow the instructions for the Click Shield for how to do this. Note: Make sure your Pi is turned off when you do this!
  2. Plug the Thunder Click board into one of the sockets on the Click Shield. It will work in either socket. Mine is plugged into socket 2 because I have another module plugged into socket 1 (see another project to be documented later on). Ensure the the small GPIO/ADC switch on the Click Shield for the socket you choose is set to GPIO. This should be the default out of the box setting. Note: Make sure your Pi is turned off when you do this!
  3. Turn on your Pi. After the Pi has started to boot up you should see the green LED on the Thunder Click board light up.
  4. That’s it for assembly. The rest is down to software.

Software

As mentioned above, not all Click Boards have software available for them on the Raspberry Pi. This is true in the case of the Thunder Click board. There is some software available to use the AS3935 but much of this is for using the chip on its I2C interface but the Thunder Click is configured to use SPI (Serial Peripheral Interface) which meant that I had re-work some existing code to make it work.

There are a number of steps included in the software setup…

  1. Enable SPI on the Raspberry Pi. See https://www.raspberrypi-spy.co.uk/2014/08/enabling-the-spi-interface-on-the-raspberry-pi/
  2. I’m using Python 3 to access the AS3935. You also need to use ‘pip’. If you’re running Raspberry Pi OS (previously called Raspbian OS) then you should have both Python2, Python 3 and pip installed by default. If you’re using another OS or installed a version of the Raspberry Pi OS without Python 3/pip included please install them using the appropriate method for your OS.
  3. Install Python SpiDev. This is a small software module that can be used from Python to access SPI connected devices. At the Pi OS prompt use ‘pip3 install spidev’ to install this module.
  4. Create a directory “/home/pi/Sensors” for the other software. You can name the directory as you wish, but I’m using Sensors here so that I can refer to it consistently.
  5. Put a copy of the attached C source code (as3935_spidev_test.txt) into the Sensors directory and rename it to as3935_spidev_test.c
  6. Compile the C source code using 'gcc -o as3935_spidev_test as3935_spidev_test.c
    [li]Test the Thunder Click board by running the test program. The program defaults to the Thunder Click being plugged into socket 2 of the Pi 3 Click Shield. If your Thunder Click is also plugged into socket 2 run the program using ‘as3935_spidev_test -H 0x40,0,0,0,0,0,0,0,0,0’. If your Thunder Click is plugged into socket 1 of the Click Shield run the program using ‘as3935_spidev_test -H -D /dev/spidev0.0 0x40,0,0,0,0,0,0,0,0,0’. You should get two lines of output if things are working correctly which look something like this…

    40 00 00 00 00 00 00 00 00 00
    00 24 32 C2 20 00 00 00 3F 0F

    The numbers on the second line may vary a little depending on the current state of the AS3935. If you get an output like this then your installation is probably OK.[/li]

The next steps start to cover the Python software. This is still a work in progress for me. For now, I’ve included the some AS3935 library routines converted from I2C to SPI connection and a simple Python3 program to get some output and start monitoring for lightning.

  1. Download the attached file ‘RPi_AS3935_SPI.txt’ and put it in the Sensors directory. Rename the file to ‘RPi_AS3935_SPI.py’
  2. Download the attached file ‘thunder_interrupt.txt’ and put it in the Sensors directory. Rename the file to ‘thunder_interrupt.py’
    [li]If your Thunder Click is plugged into socket 1 of the Click Shield you must modify thunder_interrupt.py as follows. Edit the file, e.g. using ‘nano’, and find the line containing 'as3935 = RPi_AS3935(bus=0, address=1, mode=0b10, speed=400000)
    ’ (should be line 11) and change ‘address=1’ to ‘address=0’. Save the modified file. [/li]
    [li]In the Sensors directory run the thunder_interrupt.py script using ‘python3 thunder_interrupt.py’. You should see some output something like…

    Waiting for lightning - or at least something that looks like it
    Noise level too high - adjusting

    You may see no noise level entries, or multiple of them depending on how electrically noisy your location is.
    [/li]

thunder_interrupt.py configures the AS3935 for indoor use, sets the noise floor and calibrates the frequency of operation. These are unlikely to be optimal settings for all use. The code probably isn’t written well, or optimised, but it’s for demo purposes only to check that you can access the Thunder Click from Python.

After the setup, it adds an interrupt handler. Simply put, when the AS3935 wants to signal that something has happened, e.g. lightning is detected, or the noise level has changed, etc, it interrupts the Raspberry Pi (using GPIO 26) which causes the ‘handle_interrupt’ code to be executed. This code checks the AS3935 registers to find out what has been signalled and displays it on screen…then goes back to waiting for the next interrupt.

The next steps are to write more Python code to use the data, e.g. to output it to screen, send it to another program or create a web page containing the data (or anything else you can think of that would be a useful way to use the data). I’ve not done any more coding yet, but I’ll post what I do write when I’ve written it. If you understand Python then you can probably continue from this point to do your own thing.


as3935_spidev_test.txt (8.08 KB)

RPi_AS3935_SPI.txt (7.49 KB)

thunder_interrupt.txt (1.18 KB)

Always wanted to add lightning detector to site, this sounds ideal :smiley:

I would be interested if there was a SD card image, the old brain not up to it. :frowning:

An SD card image would be a lot of work because it would need to be kept up to date as well as needing a lot of bandwith for downloads. Once the project gets more settled, i.e. the software is in a better shape, it should be possible to create an installation script that will download/install all the bits that are required using a relatively simple command.

I’ve ordered the Mikroe Pi 3 Click Shield and the Mikroe Thunder Click boards
and I have a spare Raspberry Pi 3 Model B

I didn’t realize an image file takes such time and effort to do and maintain, so
going to have a go Chris.

The standard Pi OS image has the majority of the stuff that’s needed so I’d just be replicating that if I created an image. The other stuff isn’t too difficult and should be easy enough to walk you through if you get stuck.

Where’s the lightning when you want to test :roll: It’s been forecast 3 times in the last week but each time it’s been a no-show (visually and audibly so it’s not the detector not detecting).

At least that’s given me time to make progress on the software. I’m not ready to release a new version yet, because I’ve done a fairly major rewrite. I’ve changed from using the spidev library to pigpio. The spidev library just provides SPI functions and pigpio provides a whole load of GPIO functions, including SPI. The pigpio IRQ handling functions were what I needed to write the calibration routines for the antenna tuning capacitor. The next software release will have a calibration_run library routine which returns the best capacitor value to tune the antenna to 500kHz.

I’m also writing a small Python web server (using flask) to display the lightning data. This is just intended to run on the Pi for internal/home use because flask isn’t really production ready for the Internet. I’m also watching a thread about generating a lightning file for WD to ingest. When that’s come to a conclusion I’ll try to get my software to generate the same format of file.

I don’t know if Pi consolewd includes the lightning import routines though. It would be good if it did because then you could do everything on the Pi.

I don't know if Pi consolewd includes the lightning import routines though. It would be good if it did because then you could do everything on the Pi.
i could add that, so that the count etc can be outputted as custom tags etc?

So import nowcast.txt (?) like in Windows WD?

The web interface (modified and updated from another AS3935 project) needs more work but its basic functions are there now (see attached). In debug mode it shows simulated strikes, but it is connected to the AS3935 so if there was any real lightning it would update in real time. I need to tidy up non-functional bits of the donor code and add strike energy info to the display.


yes, nowcast import would work

The web server can now maintain a log of strikes which can be processed to generate a nowcast.txt file, e.g.

pi@IOT-DevPi:~/lightning_web $ cat nowcast.txt 5 strokes per minute 7 strokes in past 5 mins. (avg. 1.4/min.) 7 strokes in past 10 mins. (avg. 0.7/min.) 7 strokes in past 20 mins. (avg. 0.3/min.) 7 strokes in past 30 mins. (avg. 0.2/min.) 20 strokes in past 60 mins. (avg. 0.3/min.)

good oh

I think the lightning on the 25th was mostly over the Isle of Man
does this filter out noise from light switches and motors etc
can the nowcast.txt be exported to a windows 10 machine already running WD

It is nice to see there are more people using the AS3935 detectors. I don’t want to go off this topic but can we discuss the detector’s performance, siting, etc. here or in another topic?

As far as I know there hasn’t been any lightning in the vicinity since I had the board/software usable (it’s not running 24*7 yet). At least I’ve not heard any rumbles or flashes. I’m still working on the software so I’m not leaving it running until I’m sure it’s working properly although I’m probably at a point now where I could do that.

The AS3935 has algorithms built in to filter out non-lightning (disturbers) and to set the noise floor if you’re in an electrically noisy environment. You can get it to report disturbers and increases in the noise floor but they’re not classed as ‘strikes’.

The nowcast.txt file could be sent to another device but it would probably be easier to have the other device download it somehow. PCs don’t tend to have FTP servers running on them and setting up Samba to run securely isn’t trivial. I’ve not tried it but I think the easiest way might be for me to make nowcast.txt accessible through the mini-web browser and then WD should be able to download it using the ‘HTTP Download’ option. The nowcast.txt functionality is currently just a standalone program that I run on demand so I still need to add more automation to that part of the process.

By all means discuss it here. When the project is finished I’ll pull together all the bits of documentation, notes, scripts and software into a new post (maybe in another board) so that the details don’t get lost in discussions.

Sorry Chris, got a problem, all ok up to compile

gcc -o as3935_spidev_test as3935_spidev_test.c

I get this error

as3935_spidev_test.c:103:13: error: redefinition of ‘transfer’
static void transfer(int fd)
^~~~~~~~
as3935_spidev_test.c:95:13: note: previous definition of ‘transfer’ was here
static void transfer(int fd)
^~~~~~~~
pi@raspberrypi:~/Sensors $

Any ideas what I have done wrong

Phil

Hi Phil

That’s weird. It suggests that the C code has two functions called ‘transfer’ defined…one around line 95 and one around line 103. In my copy of the code, the transfer function is defined near line 95 and the function ‘print_usage’ is near line 103. Can you edit the code and check to see if it’s become corrupt with an extra copy of the transfer function included somehow?

I really need to write up the new way of setting things up. It uses pigpio in place of spidev so what you’re trying to compile isn’t actually needed in the long term.

I think version 2 setup is advanced enough to document and make available. I need to create a fresh boot image for my development Pi so that I can be sure I’m not making assumptions about what needs to be installed. I’ll do that, rebuild the AS3935 setup and check my documentation as I rebuild. Hopefully it will be available soon (maybe tomorrow).

I’ve also just received a Sparkfun AS3935 board to try as an alternative to the Mikroe Click boards. If it works OK, then if you’re happy doing a bit of soldering (7 wires) then it should work out at less than £25 to add this to your Pi compared to about £45 for the Mikroe solution.

Chris found it, extra copy of the transfer function
Will continue with set up tomorrow, TV time :smiley:

Just downloaded another copy, its the same

static void transfer(int fd)
{
    int ret;
    ret = ioctl(fd, SPI_IOC_MESSAGE(ntransfers), spi_xfrs);
    if (ret < 1)
        pabort("can't send spi message");
}

static void transfer(int fd)
{
    int ret;
    ret = ioctl(fd, SPI_IOC_MESSAGE(ntransfers), spi_xfrs);
    if (ret < 1)
        pabort("can't send spi message");
}

static void print_usage(const char *prog)
{
    printf("Usage: %s [-DsbdlnHOLC3] [data,..]\n", prog);
    puts("  -D --device   device to use (default /dev/spidev0.1)\n"
         "  -s --speed    max speed (Hz)\n"
         "  -d --delay    delay (usec)\n"
         "  -b --bpw      bits per word \n"
         "  -n --len      length\n"
         "  -l --loop     loopback\n"
         "  -H --cpha     clock phase\n"
         "  -O --cpol     clock polarity\n"
         "  -L --lsb      least significant bit first\n"
         "  -C --cs-high  chip select active high\n"
         "  -3 --3wire    SI/SO signals shared\n"
         "  -q --quiet    Don't output data send/received\n"
         "  data is a series of octets to send, separated by comma, or b# to switch to another bits per word\n"
    );
    exit(1);
}