Blitzdetektor

Als Gewitterwarner oder zur Detektion und Zählung von Blitzen, bietet sich der AS3935 Franklin Lightning Sensor von ams an bzw. die fertig verwendbare Erweiterungsplatine von Tautic Electronics Llc. Der Blitzdetektor/Blitzsensor erkennt bei Gewittern das RF-Signal das von Blitzen zwischen Wolken und von Wolken zur Erde erzeugt wird und ermittelt anhand eines internen Algorithmus die Entfernung des Blitzes bis zu einer Distanz von 40 km. Störungen durch andere elektronische Geräte wie Motoren oder Mikrowellenherde oder auch PCs in direkter Umgebung, werden weitgehend erkannt und unterdrückt.

Die kleine Blitzdetektor-Platine von Tautic enthält diesen AS3935-Chip und kann leicht an einen Raspberry Pi oder Arduino über die SPI oder I2C-Schnittstelle angeschlossen und die Werte ausgelesen werden.

AS3935-Lightning-Sensor
Blitzdetektor: AS3935-Lightning-Sensor von Tautic Electronics LLC zu Blitzerkennung

Blockschaltbild des AS3935 Blitzsensors:

AS3935-Blitzsensor-Schaltbild
AS3935-Blitzsensor-Schaltbild (Quelle: Datenblatt ams AS3935 Lightning Sensor von ams Inc)

Der Blitz-Detektor kann über die SPI oder I2C Schnittstelle angesprochen werden, wobei der SI-Pin zur Umschaltung verwendet wird. Optional können auf der Platinen-Rückseite zwei Pullup-Widerstände eingelötet werden, wenn diese benötigt werden.

Technische Daten

Sensor-Chip ams AS3935 Frankling Lightning Sensor
Antenne Integrierte selbst-anpassende Antenne
Frequenz 500 kHz
Hersteller Tautic Electronics LLC (www.tautic.com)
Anschluss SPI oder I2C
Reichweite 1, 5, 6, 8, 10, 12, 14, 17, 20, 24, 27, 31, 40 km
Spannungsversorgung 2,4 V – 5,5 V (DC)
Stromverbrauch 1 μA bis 350 μA
Temperaturbereich -40° bis 85°C

Anschluss an Raspberry Pi

Der Blitzsensor kann über SPI oder I2C angesprochen werden, je nachdem ob der SI Pin auf Hi (VDD) oder Lo (GND) gesetzt wird. Um die Erweiterungsplatine über I2C anzusprechen wird der SI Pin mit Pin 1 (3,3 V) verbunden.

AS3935  VDD GND MOSI MISO SCLK IRQ SI CS
Raspberry Pi 3,3V
(Pin 1)
GND
(Pin 9)
SDA/GPIO2
(Pin 2)
 – SCL/GPIO3
(Pin 5)
GPIO17
(Pin 11)
3,3V
(Pin 1)

Installation des Blitzdetektors

Falls noch nicht durchgeführt, muss der Raspberry Pi zuerst für die Verwendung des I2C Protokolls vorbereitet werden. Dafür sind die Bibliotheken python-smbus und i2c-tools installiert und die Kernel-Module i2c-bcm2708 und i2c-dev akiviert werden.

sudo apt-get install python-smbus
sudo apt-get install i2c-tools
# Kernel Module laden
sudo modprobe i2c-bcm2708
sudo modprobe i2c-dev
sudo nano /etc/modules
# Kernel Module für automatisches Laden eintragen:
i2c-bcm2708
i2c-dev

# I2C Ports auflisten lassen sudo i2cdetect -y 1 # Treiber für AS3935 installieren sudo pip install RPi_AS3935

Test-Script um den AS3935 am RPi auszulesen (benötigt from RPi_AS3935 import RPi_AS3935)

#!/usr/bin/env python
from RPi_AS3935 import RPi_AS3935

import RPi.GPIO as GPIO
import time
from datetime import datetime

GPIO.setmode(GPIO.BCM)

# 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)
sensor = RPi_AS3935(address=0x00, bus=1)
#sensor.reset()
sensor.set_indoors(True)
sensor.set_noise_floor(0)
sensor.calibrate(tun_cap=0x0F)
sensor.set_disp_lco(False)

def handle_interrupt(channel):
 time.sleep(0.004)
 global sensor
 reason = sensor.get_interrupt()
 if reason == 0x01:
 noise = sensor.raise_noise_floor()
 print "Noise level too high - adjusting to level %s" % noise
 elif reason == 0x04:
 print "Disturber detected - masking"
 sensor.set_mask_disturber(True)
 elif reason == 0x08:
 now = datetime.now().strftime('%H:%M:%S - %Y/%m/%d')
 distance = sensor.get_distance()
 print ("lightning detected, distance: %s km at %s" % (str(distance), now))
 print ""

pin = 17

GPIO.setup(pin, GPIO.IN)
GPIO.add_event_detect(pin, GPIO.RISING, callback=handle_interrupt)

print "Waiting for lightning - or at least something that looks like it"
counter = 0
while True:
 #s = sensor.get_min_strikes()
 noise = sensor.get_noise_floor()
 print "noise floor: %s" % (noise)
 # try to decrease the noise floor
 if counter > 10:
 #noise = sensor.lower_noise_floor()
 #sensor.calibrate(tun_cap=0x0F)
 #print "Noise floor reduced to: %s" % noise
 counter = 0

 counter = counter + 1
 time.sleep(5.0)
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from RPi_AS3935 import RPi_AS3935

import RPi.GPIO as GPIO
import time
import logging
import requests
import xively
import datetime

# ---------------------------------------------------------------
# Lightning-Detector
# Detect lightnings using AS3935 lighting detection
# development board from Tautic.com
# Author: Roland Ortner (2015)
# ---------------------------------------------------------------

# gpio address (default: 0x00), bus (default: 1) and pin (default: 17) of the lightning sensor
GPIO_ADDRESS = 0x00
GPIO_BUS = 1
GPIO_PIN = 17

# interval between readings in seconds (default: 1 sec)
INTERVAL = 2

# interval to check noise and reduce floor (default: 120sec)
NOISECHECK_INTERVAL = 60

# normal minimal noise level 
NOISECHECK_LEVEL = 2

# xively.com data feed configuration
XIVELY_API_KEY = 'iPM6CaQHsJcnJea7BMnCQsohBLuChVsr7Wx0WmkXpcXbg7NT'
XIVELY_FEED_ID = '115042809'
XIVELY_FEED_NAME = 'Lightnings'

# logfile path and filename
LOG_FILE = '/home/pi/lightning-detector/lightning-detector.log'


# handle interrupt of AS3935 lightning detector
def handle_interrupt(channel):
  time.sleep(0.004)
  global sensor
  reason = sensor.get_interrupt()

  if reason == 0x00:
    pass
  elif reason == 0x01:
    noise = sensor.raise_noise_floor()
    logger.warn("noise level too high - adjusting to level %s" % str(noise))
    #update_feed(noise) # testing

  elif reason == 0x04:
    logger.warn("disturber detected")
    sensor.set_mask_disturber(True)

  elif reason == 0x08:
    distance = sensor.get_distance()
    logger.info("lightning detected, distance is " + str(distance) + "km")        
    update_feed(distance)
  else:
    logger.debug("interrupt: %s" % str(reason));


# get or create new xively datastream
def get_datastream(feed, feedname):
  try:
    datastream = feed.datastreams.get(feedname)
    return datastream
  except:
    datastream = feed.datastreams.create(feedname, tags=feedname)
    return datastream


# update data feed at xively.com
def update_feed(distance):
  now = datetime.datetime.utcnow()
  datastream.at = now
  datastream.current_value = distance
  try:
    datastream.update()
    logger.info("uploaded data to xively: %s km" % distance)
  except requests.HTTPError as e:
    logger.error("HTTPError({0}): {1}".format(e.errno, e.strerror))


# MAIN

# init logger
logger = logging.getLogger('app')
handler = logging.FileHandler(LOG_FILE)
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)

# get xively feed and datastream
api = xively.XivelyAPIClient(XIVELY_API_KEY)
feed = api.feeds.get(XIVELY_FEED_ID)
datastream = get_datastream(feed, XIVELY_FEED_NAME)
datastream.max_value = None
datastream.min_value = None

# init gpio port
GPIO.setmode(GPIO.BCM)

# init AS3935 lightning detector development board
sensor = RPi_AS3935(address=GPIO_ADDRESS, bus=GPIO_BUS)

# reset sensor registers
sensor.reset()

# set gain level for indoor usage
sensor.set_indoors(False)

# set primary noise floor to 0
sensor.set_noise_floor(0)

# calibrate the lightning sensor
sensor.calibrate(tun_cap=0x0F)

# disable output of resonant frequency
sensor.set_disp_lco(False)

# add intrrupt handler for AS3935
GPIO.setup(GPIO_PIN, GPIO.IN)
GPIO.add_event_detect(GPIO_PIN, GPIO.RISING, callback=handle_interrupt)
logger.info("init of lighting-detector at %s on pin %s done." % (GPIO_ADDRESS, GPIO_PIN))

timelast = time.time()
time_raised = 0
while True:
  noise = sensor.get_noise_floor()
  # logger.info("noise floor: %s" % noise)
  elapsed = int(time.time() - timelast)
  elapsed_raised = int(time.time() - time_raised)
  # try to lower the noise floor
  if elapsed >= NOISECHECK_INTERVAL and noise > NOISECHECK_LEVEL:
    noise = sensor.lower_noise_floor()
    logger.info("lower noise floor to: %s" % str(noise))
    timelast = time.time()

  time.sleep(INTERVAL)

Quellen

  • https://github.com/pcfens/RaspberryPi-AS3935
  • http://www.lightningmaps.org/blitzortung/america/index.php?bo_page=statistics&bo_show=station&bo_station_id=41&lang=de&bo_page=statistics&bo_show=station&bo_station_id=41&lang=de
  • http://www.blitzortung.org/Webpages/index.php?lang=de
  • http://www.lightningmaps.org/realtime?lang=de
  • http://mobile.aldis.at/informationen/blitzortung.htm
  • http://www.elektroniknet.de/automation/sensorik/artikel/103286/1/
  • https://www.tindie.com/products/TAUTIC/as3935-lightning-sensor-board/
  • http://www.rs-online.com/designspark/electronics/blog/detecting-lightning-with-an-arduino
  • http://www.tautic.com/Category:AS3935_Lightning_Sensor_Dev_Board
  • http://coffeewithrobots.com/detecting-lightning-with-a-raspberry-pi/
  • http://www.rs-online.com/designspark/electronics/blog/detecting-lightning-with-an-arduino
  • https://www.raspberrypi.org/forums/viewtopic.php?f=44&t=54884