in my opinion, with my little experience as a beginner, a point to start 
from could be the specific library of DFrobot_as3935 together with the two 
py files that work only as a terminal with raspberry and adapt them to work 
with weewx

I attach the py files

-- 
You received this message because you are subscribed to the Google Groups 
"weewx-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/weewx-user/4a4fa815-84b8-4083-933a-3bee137654b7%40googlegroups.com.
import time
import smbus

class DFRobot_AS3935:
    def __init__(self, address, bus = 1):
        self.address = address
        self.i2cbus = smbus.SMBus(bus)

    def writeByte(self, register, value):
        try:
            self.i2cbus.write_byte_data(self.address, register, value)
            return 1
        except:
            return 0

    def readData(self, register):
        self.register = self.i2cbus.read_i2c_block_data(self.address, register)

    def manualCal(self, capacitance, location, disturber):
        self.powerUp()
        if location == 1:
            self.setIndoors()
        else:
            self.setOutdoors()

        if disturber == 0:
            self.disturberDis()
        else:
            self.disturberEn()

        self.setIrqOutputSource(0)
        time.sleep(0.5)
        self.setTuningCaps(capacitance)

    def setTuningCaps(self, capVal):
        #Assume only numbers divisible by 8 (because that's all the chip supports)
        if capVal > 120: #cap_value out of range, assume highest capacitance
            self.singRegWrite(0x08, 0x0F, 0x0F) #set capacitance bits to maximum
        else:
            self.singRegWrite(0x08, 0x0F, capVal >> 3) #set capacitance bits

        self.singRegRead(0x08)
        #print('capacitance set to 8x%d'%(self.register[0] & 0x0F))

    def powerUp(self):
        #register 0x00, PWD bit: 0 (clears PWD)
        self.singRegWrite(0x00, 0x01, 0x00)
        self.calRCO() #run RCO cal cmd
        self.singRegWrite(0x08, 0x20, 0x20) #set DISP_SRCO to 1
        time.sleep(0.002)
        self.singRegWrite(0x08, 0x20, 0x00) #set DISP_SRCO to 0

    def powerDown(self):
        #register 0x00, PWD bit: 0 (sets PWD)
        self.singRegWrite(0x00, 0x01, 0x01)

    def calRCO(self):
        self.writeByte(0x3D, 0x96)
        time.sleep(0.002)

    def setIndoors(self):
        self.singRegWrite(0x00, 0x3E, 0x24)
        print("set to indoors model")

    def setOutdoors(self):
        self.singRegWrite(0x00, 0x3E, 0x1C)
        print("set to outdoors model")

    def disturberDis(self):
        #register 0x03, PWD bit: 5 (sets MASK_DIST)
        self.singRegWrite(0x03, 0x20, 0x20)
        print("disenable disturber detection")

    def disturberEn(self):
        #register 0x03, PWD bit: 5 (sets MASK_DIST)
        self.singRegWrite(0x03, 0x20, 0x00)
        print("enable disturber detection")

    def singRegWrite(self, regAdd, dataMask, regData):
        #start by reading original register data (only modifying what we need to)
        self.singRegRead(regAdd)
        #calculate new register data... 'delete' old targeted data, replace with new data
        #note: 'dataMask' must be bits targeted for replacement
        #add'l note: this function does NOT shift values into the proper place... they need to be there already
        newRegData = (self.register[0] & ~dataMask)|(regData & dataMask)
        #finally, write the data to the register
        self.writeByte(regAdd, newRegData)
        #print('wrt: %02x'%newRegData)
        self.singRegRead(regAdd)
        #print('Act: %02x'%self.register[0])

    def singRegRead(self,regAdd):
        self.readData(regAdd)

    def getInterruptSrc(self):
        #definition of interrupt data on table 18 of datasheet
        #for this function:
        #0 = unknown src, 1 = lightning detected, 2 = disturber, 3 = Noise level too high
        time.sleep(0.03) #wait 3ms before reading (min 2ms per pg 22 of datasheet)
        self.singRegRead(0x03) #read register, get rid of non-interrupt data
        intSrc = self.register[0]&0x0F
        if intSrc == 0x08:
            return 1 #lightning caused interrupt
        elif intSrc == 0x04:
            return 2 #disturber detected
        elif intSrc == 0x01:
            return 3 #Noise level too high
        else:
            return 0 #interrupt result not expected

    def reset(self):
        err = self.writeByte(0x3C, 0x96)
        time.sleep(0.002) #wait 2ms to complete
        return err

    def setLcoFdiv(self,fdiv):
        self.singRegWrite(0x03, 0xC0, (fdiv & 0x03) << 6)

    def setIrqOutputSource(self, irqSelect):
        #set interrupt source - what to display on IRQ pin
        #reg 0x08, bits 5 (TRCO), 6 (SRCO), 7 (LCO)
        #only one should be set at once, I think
        #0 = NONE, 1 = TRCO, 2 = SRCO, 3 = LCO
        if irqSelect == 1:
            self.singRegWrite(0x08, 0xE0, 0x20) #set only TRCO bit
        elif irqSelect == 2:
            self.singRegWrite(0x08, 0xE0, 0x40) #set only SRCO bit
        elif irqSelect == 3:
            self.singRegWrite(0x08, 0xE0, 0x80) #set only SRCO bit
        else:
            self.singRegWrite(0x08, 0xE0, 0x00) #clear IRQ pin display bits

    def getLightningDistKm(self):
        self.singRegRead(0x07) #read register, get rid of non-distance data
        return self.register[0]&0x3F

    def getStrikeEnergyRaw(self):
        self.singRegRead(0x06) #MMSB, shift 8  bits left, make room for MSB
        nrgyRaw = (self.register[0]&0x1F) << 8
        self.singRegRead(0x05) #read MSB
        nrgyRaw |= self.register[0]
        nrgyRaw <<= 8 #shift 8 bits left, make room for LSB
        self.singRegRead(0x04) #read LSB, add to others
        nrgyRaw |= self.register[0]
        
        return nrgyRaw/16777

    def setMinStrikes(self, minStrk):
        #This function sets min strikes to the closest available number, rounding to the floor,
        #where necessary, then returns the physical value that was set. Options are 1, 5, 9 or 16 strikes.
        if minStrk < 5:
            self.singRegWrite(0x02, 0x30, 0x00)
            return 1
        elif minStrk < 9:
            self.singRegWrite(0x02, 0x30, 0x10)
            return 5
        elif minStrk < 16:
            self.singRegWrite(0x02, 0x30, 0x20)
            return 9
        else:
            self.singRegWrite(0x02, 0x30, 0x30)
            return 16

    def clearStatistics(self):
        #clear is accomplished by toggling CL_STAT bit 'high-low-high' (then set low to move on)
        self.singRegWrite(0x02, 0x40, 0x40) #high
        self.singRegWrite(0x02, 0x40, 0x00) #low
        self.singRegWrite(0x02, 0x40, 0x40) #high

    def getNoiseFloorLv1(self):
        #NF settings addres 0x01, bits 6:4
        #default setting of 010 at startup (datasheet, table 9)
        self.singRegRead(0x01) #read register 0x01
        return (self.register[0] & 0x70) >> 4 #should return value from 0-7, see table 16 for info

    def setNoiseFloorLv1(self, nfSel):
        #NF settings addres 0x01, bits 6:4
        #default setting of 010 at startup (datasheet, table 9)
        if nfSel <= 7: #nfSel within expected range
            self.singRegWrite(0x01, 0x70, (nfSel & 0x07) << 4)
        else:       #out of range, set to default (power-up value 010)
            self.singRegWrite(0x01, 0x70, 0x20)
        
    def getWatchdogThreshold(self):
        #This function is used to read WDTH. It is used to increase robustness to disturbers,
        #though will make detection less efficient (see page 19, Fig 20 of datasheet)
        #WDTH register: add 0x01, bits 3:0
        #default value of 0010
        #values should only be between 0x00 and 0x0F (0 and 7)
        self.singRegRead(0x01)
        return self.register[0] & 0x0F

    def setWatchdogThreshold(self, wdth):
        #This function is used to modify WDTH. It is used to increase robustness to disturbers,
        #though will make detection less efficient (see page 19, Fig 20 of datasheet)
        #WDTH register: add 0x01, bits 3:0
        #default value of 0010
        #values should only be between 0x00 and 0x0F (0 and 7)
        self.singRegWrite(0x01, 0x0F, wdth & 0x0F)

    def getSpikeRejection(self):
        #This function is used to read SREJ (spike rejection). Similar to the Watchdog threshold,
        #it is used to make the system more robust to disturbers, though will make general detection
        #less efficient (see page 20-21, especially Fig 21 of datasheet)
        #SREJ register: add 0x02, bits 3:0
        #default value of 0010
        #values should only be between 0x00 and 0x0F (0 and 7)
        self.singRegRead(0x02)
        return self.register[0] & 0x0F

    def setSpikeRejection(self, srej):
        #This function is used to modify SREJ (spike rejection). Similar to the Watchdog threshold,
        #it is used to make the system more robust to disturbers, though will make general detection
        #less efficient (see page 20-21, especially Fig 21 of datasheet)
        #WDTH register: add 0x02, bits 3:0
        #default value of 0010
        #values should only be between 0x00 and 0x0F (0 and 7)
        self.singRegWrite(0x02, 0x0F, srej & 0x0F)
        
    def printAllRegs(self):
        self.singRegRead(0x00)
        print("Reg 0x00: %02x"%self.register[0])
        self.singRegRead(0x01)
        print("Reg 0x01: %02x"%self.register[0])
        self.singRegRead(0x02)
        print("Reg 0x02: %02x"%self.register[0])
        self.singRegRead(0x03)
        print("Reg 0x03: %02x"%self.register[0])
        self.singRegRead(0x04)
        print("Reg 0x04: %02x"%self.register[0])
        self.singRegRead(0x05)
        print("Reg 0x05: %02x"%self.register[0])
        self.singRegRead(0x06)
        print("Reg 0x06: %02x"%self.register[0])
        self.singRegRead(0x07)
        print("Reg 0x07: %02x"%self.register[0])
        self.singRegRead(0x08)
        print("Reg 0x08: %02x"%self.register[0])



# file DFRobot_AS3935_detailed.py
#
# SEN0290 Lightning Sensor
# This sensor can detect lightning and display the distance and intensity of the lightning within 40 km
# It can be set as indoor or outdoor mode.
# The module has three I2C, these addresses are:
# AS3935_ADD1  0x01   A0 = 1  A1 = 0
# AS3935_ADD2  0x02   A0 = 0  A1 = 1
# AS3935_ADD3  0x03   A0 = 1  A1 = 1
#
#
# Copyright    [DFRobot](http://www.dfrobot.com), 2018
# Copyright    GNU Lesser General Public License
#
# version  V1.0
# date  2018-11-28

import sys
sys.path.append('../')
import time
from DFRobot_AS3935_Lib import DFRobot_AS3935
import RPi.GPIO as GPIO
from datetime import datetime

#I2C address
AS3935_I2C_ADDR1 = 0X01
AS3935_I2C_ADDR2 = 0X02
AS3935_I2C_ADDR3 = 0X03

#Antenna tuning capcitance (must be integer multiple of 8, 8 - 120 pf)
AS3935_CAPACITANCE = 96
IRQ_PIN = 7

GPIO.setmode(GPIO.BOARD)

sensor = DFRobot_AS3935(AS3935_I2C_ADDR3, bus = 1)
if (sensor.reset()):
    print("init sensor sucess.")
else:
    print("init sensor fail")
    while True:
        pass
#Configure sensor
sensor.powerUp()

#set indoors or outdoors models
sensor.setIndoors()
#sensor.setOutdoors()

#disturber detection
sensor.disturberEn()
#sensor.disturberDis()

sensor.setIrqOutputSource(0)
time.sleep(0.5)
#set capacitance
sensor.setTuningCaps(AS3935_CAPACITANCE)

# Connect the IRQ and GND pin to the oscilloscope.
# uncomment the following sentences to fine tune the antenna for better performance.
# This will dispaly the antenna's resonance frequency/16 on IRQ pin (The resonance frequency will be divided by 16 on this pin)
# Tuning AS3935_CAPACITANCE to make the frequency within 500/16 kHz plus 3.5% to 500/16 kHz minus 3.5%
#
# sensor.setLcoFdiv(0)
# sensor.setIrqOutputSource(3)

#Set the noise level,use a default value greater than 7
sensor.setNoiseFloorLv1(2)
#noiseLv = sensor.getNoiseFloorLv1()

#used to modify WDTH,alues should only be between 0x00 and 0x0F (0 and 7)
sensor.setWatchdogThreshold(2)
#wtdgThreshold = sensor.getWatchdogThreshold()

#used to modify SREJ (spike rejection),values should only be between 0x00 and 0x0F (0 and 7)
sensor.setSpikeRejection(2)
#spikeRejection = sensor.getSpikeRejection()

#view all register data
#sensor.printAllRegs()

def callback_handle(channel):
    global sensor
    time.sleep(0.005)
    intSrc = sensor.getInterruptSrc()
    if intSrc == 1:
        lightningDistKm = sensor.getLightningDistKm()
        print('Lightning occurs!')
        print('Distance: %dkm'%lightningDistKm)

        lightningEnergyVal = sensor.getStrikeEnergyRaw()
        print('Intensity: %d '%lightningEnergyVal)
    elif intSrc == 2:
        print('Disturber discovered!')
    elif intSrc == 3:
        print('Noise level too high!')
    else:
        pass
#Set to input mode
GPIO.setup(IRQ_PIN, GPIO.IN)
#Set the interrupt pin, the interrupt function, rising along the trigger
GPIO.add_event_detect(IRQ_PIN, GPIO.RISING, callback = callback_handle)
print("start lightning detect.")

while True:
    time.sleep(1.0)


Reply via email to