add raspberry

pull/2/head
ouki-wang 6 years ago
parent 33f486acb4
commit 8337515fb9
  1. 211
      RaspberryPi/Python/DFRobot_AS3935_Lib.py
  2. 82
      RaspberryPi/Python/README.md
  3. 82
      RaspberryPi/Python/example/DFRobot_AS3935.py

@ -0,0 +1,211 @@
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):
self.i2cbus.write_byte_data(self.address, register, value)
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)
def setOutdoors(self):
self.singRegWrite(0x00, 0x3E, 0x1C)
def disturberDis(self):
#register 0x03, PWD bit: 5 (sets MASK_DIST)
self.singRegWrite(0x03, 0x20, 0x20)
def disturberEn(self):
#register 0x03, PWD bit: 5 (sets MASK_DIST)
self.singRegWrite(0x03, 0x20, 0x00)
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):
self.writeByte(0x3C, 0x96)
time.sleep(0.002) #wait 2ms to complete
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 0001
#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 0001
#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)

@ -0,0 +1,82 @@
## DFRobot_AS3935_Lib.py Library for Raspberry pi
---------------------------------------------------------
This is the sample code for Gravity:Lightning Sensor, SKU: SEN0292.
## Table of Contents
* [Installation](#installation)
* [Methods](#methods)
<snippet>
<content>
## Installation
The Lightning Sensor should work with AS3935
(https://github.com/DFRobot/DFRobot_AS3935/tree/master/RaspberryPi/Python)
Run the program:
```cpp
$> python DFRobot_AS3935.py
```
## Methods
```C++
/*
* @brief Init The Lightning Sensor
*
* @param address I2C address(1~3)
* bus I2C bus
*/
DFRobot_AS3935(address, bus);
/*
* @brief Sensor reset
*/
def reset(self);
/*
* @brief Configure sensor
*
* @param capacitance Antenna tuning capcitance (must be integer multiple of 8, 8 - 120 pf)
* location Indoor/outdoor mode selection
* disturber Enable/disable disturber detection
*/
def manualCal(self, capacitance, location, disturber);
/*
* @brief Get mid-range type
*
* @return 0 Unknown src
* 1 Lightning detected
* 2 Disturber
* 3 Noise level too high
*/
def getInterruptSrc(self);
/*
* @brief get lightning distance
*
* @return unit kilometer
*/
def getLightningDistKm(self);
/*
* @brief get lightning energy intensity
*
* @return lightning energy intensity(0-1000)
*/
def getStrikeEnergyRaw(self);
```
## Credits
Written by DFRobot_JH, 2018. (Welcome to our [website](https://www.dfrobot.com/))

@ -0,0 +1,82 @@
# file DFRobot_AS3935_lightning_sensor.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 = High A1 = Low
# AS3935_ADD3 0x03 A0 = High A1 = High
# AS3935_ADD2 0x02 A0 = Low A1 = High
#
#
# Copyright [DFRobot](http://www.dfrobot.com), 2018
# Copyright GNU Lesser General Public License
#
# version V0.1
# date 2018-11-13
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 = 37
#Indoor/outdoor mode selection
AS3935_INDOORS = 0
AS3935_OUTDOORS = 1
AS3935_MODE = AS3935_INDOORS
#Enable/disable disturber detection
AS3935_DIST_DIS = 0
AS3935_DIST_EN = 1
AS3935_DIST = AS3935_DIST_EN
GPIO.setmode(GPIO.BOARD)
sensor = DFRobot_AS3935(AS3935_I2C_ADDR3, bus = 1)
sensor.reset()
#Configure sensor
sensor.manualCal(AS3935_CAPACITANCE, AS3935_MODE, AS3935_DIST)
# 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 ± 3.5%
#
# sensor.setLcoFdiv(0)
# sensor.setIrqOutputSource(3)
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)
while True:
time.sleep(1.0)
Loading…
Cancel
Save