How to Trigger AS3935 Lightning Distance Sensor

Screenshot

After we set the Lightning Sensor (AS3935) up on a Raspberry Pi on the previous post, we at least want to understand how the sensor behaves when lightning is detected.

What Do We Want?

Ideally, we can trigger lightning with a specific distance so that we can measure the reliability of this sensor.

One of the Raspberry Pi forum member suggested me to read the article that his friend wrote below (you may need some translation).

Thunderstorm detector AS3935 and APRS Application Rhapsody of Sensor Series

In his article, he mentioned 3 different methods to simulate lightning:

  1. Lightning Emulator Module – Find This on eBay >>
  2. Kitchen Lighter
  3. Instantaneous Inductance Short Circuit

Which One to Try First?

Undoubtedly, the lightning simulator module is the best if you don’t mind spending money to simulate a lightning.
However, the kitchen lighter option is something that I can try today without spending money and wait for any product to arrive. Also, I didn’t want to try the short circuit option for now.

Kitchen Lighter

Kitchen Lighter

As his article suggested, the AS3935 sensor just detects kitchen lighter mostly as a noise, but sometimes it does detect as a lightning.

It was highly portable and convenient to test the sensor at a number of different locations.

Other Household Items

There are other household items that can trigger the sensor (at least registered as a noise).

Fluorescent light

Fluorescent Light

The fluorescent light triggered the sensor when it is switched on. However, it was also registered only as a noise.

Portable cooktop

Portable Cooktop

A portable cooktop ignition again was registered as a noise, and was no better than a kitchen lighter.
Therefore, I switch back to kitchen lighter after couple of trials.

kitchen oven

Kitchen Oven

I had an I/O error every time, and had to restart Raspberry Pi to retest.

I’m not exactly sure why this happens, but I’m guessing it is caused by the sensor sending multiple interruptions within a short time before the program can process the interruption.

Mysterious Success

Anyway, after experimenting with different locations in our house with different methods, I accidentally found that a kitchen lighter can simulate lightning when the sensor is placed on top of a running dishwasher…

Little thunderstorm in house

Dishwasher + Kitchen Lighter

I’m completely lost why that is.
It sounds even like a little joke trying to mimic thunderstorm by those combinations.

Fake lightning with a dishwasher and a kitchen lighter
Running dishwasher & Kitchen Lighter to mimic a little thunderstorm.

How To Test the Distance Estimation?

Without having a lightning emulator, I don’t think I can mimic a lightning with a specific distance. I need a real thunderstorm to come. how do you then know the sensor is telling us reasonably accurate distance?

Program to Test the Distance Detected

I wrote a little program to count down for a thunder when lightning is detected.
It is capable of registering multiple flashes of lightning and start countdown all the thunders expected in parallel from a number depending on the distance estimation of the light detected.
This way I should be able to match thunders with the countdown.

I’m now looking forward to the next thunderstorm for the real opportunity to test this lightning sensor.

Tempestatis procella magna voco… Tempestatis procella magna voco…

#!/usr/bin/env python

### Common Library
import RPi.GPIO as GPIO
import time
from datetime import datetime
import numpy as np
from random import randrange
from subprocess import Popen
thunder_arr = np.zeros([1, 100]) #01 02 03 04 05

### Preparing LCD screen
import I2C_LCD_driver
lcd = I2C_LCD_driver.lcd()
lcd.lcd_clear()
GPIO.setmode(GPIO.BCM)
lcd_timer = 0
process_char = '+'
#### BME280
import smbus2
import bme280
port = 1
address = 0x76
bus = smbus2.SMBus(port)
calibration_params = bme280.load_calibration_params(bus, address)

# Rev. 1 Raspberry Pis should leave bus set at 0, while rev. 2 Pis should set
# bus equal to 1. The address should be changed to match the address of the
# sensor. (Common implementations are in README.md)
### AS3935
from RPi_AS3935 import RPi_AS3935
pin = 5
GPIO.setup(pin, GPIO.IN)
sensor = RPi_AS3935.RPi_AS3935(address=0x03, bus=1)
sensor.set_indoors(False)
sensor.set_noise_floor(0)
sensor.calibrate(tun_cap=0x0F)

def handle_interrupt(channel, test=False):
	time.sleep(0.003)
	global sensor
	global lcd_timer
	global thunder_arr
	data = bme280.sample(bus, address, calibration_params)
	reason = sensor.get_interrupt()
	speed_of_sound = 331.3 + data.temperature * 0.606
	time_now = time.time()
	if reason == 0x01:
		print("Noise level too high - adjusting")
		lcd.lcd_display_string('Noise lvl high'.ljust(16), 1, 0)
		lcd.lcd_display_string('adjusting'.ljust(16), 2, 0)
		lcd_timer = 4
		sensor.raise_noise_floor()
	elif reason == 0x04:
		print("Disturber detected - masking")
		lcd.lcd_display_string('Disturber'.ljust(16), 1, 0)
		lcd.lcd_display_string('detected masking'.ljust(16), 2, 0)
		lcd_timer = 4
		sensor.set_mask_disturber(True)
	elif reason == 0x08:
		now = datetime.now().strftime('%H:%M:%S - %Y/%m/%d')
		distance = sensor.get_distance()
		if distance < 30:
			thunder_arr = np.append(thunder_arr, time_now + distance*1000/speed_of_sound)
			thunder_arr = np.sort(thunder_arr)
		#print("speed_of_sound " + str(speed_of_sound))
		print("We sensed lightning! " + "It was " + str(distance) + "km away. (%s)" % now)
		print("")
		lcd.lcd_display_string('Lightning '+str(distance)+'km!'.ljust(16), 1, 0)
		lcd_timer = 4
	elif test:
		now = datetime.now().strftime('%H:%M:%S - %Y/%m/%d')
		distance = randrange(1, 20)
		if distance < 20:
			thunder_arr = np.append(thunder_arr, time_now + distance*1000/speed_of_sound)
			thunder_arr = np.sort(thunder_arr)
			#print("speed_of_sound " + str(speed_of_sound))
			print("We sensed lightning! " + "It was " + str(distance) + "km away. (%s)" % now)
			print("")
			lcd.lcd_display_string('Lightning '+str(distance)+'km!'.ljust(16), 1, 0)
			lcd_timer = 4

### Loop Preparation
GPIO.add_event_detect(pin, GPIO.RISING, callback=handle_interrupt)

print("Waiting for lightning - or at least something that looks like it")

while True:
	time.sleep(0.3)
	time_now = time.time()
	lcd_countdown = ''
	
	if '+' == process_char:
		process_char = '*'
	else:
		process_char = '+'
        
	# For Testing Only
	#if 1 == randrange(30):
	#	handle_interrupt(pin,True)
	
	thunder_arr = thunder_arr[thunder_arr > time_now]
	if thunder_arr.size > 0:
		for x in np.nditer(thunder_arr[:5]):
			lcd_countdown += f"{int(x - time_now):02d} "
	
	if thunder_arr.size > 0:
		if 0 == lcd_timer:
			lcd.lcd_display_string('Thunder in...'.ljust(16), 1, 0)
		elif lcd_timer > 0:
			lcd_timer -= 1
		lcd.lcd_display_string(lcd_countdown.ljust(16), 2, 0)
	else:
		lcd.lcd_display_string('Watching Sky for'.ljust(16), 1, 0)
		lcd.lcd_display_string('Lightning...'+process_char.ljust(16), 2, 0)

What’s Next?

I’ll try to make other sensors working with Raspberry Pi.