AMS, Franklin Lightning Sensor "AS3935" Library
/*
* AMS, Franklin Lightning Sensor "AS3935" Library
* Copyright (c) 2015 Hiroshi Suga
* Released under the MIT License: http://mbed.org/license/mit
*/
// http://ams.com/eng/Products/Lightning-Sensor/Franklin-Lightning-Sensor/AS3935
#include "AS3935.h"
//#define DBG(...) printf("" __VA_ARGS__)
#define DBG(...)
#define AS3935_ADDR 0x00
AS3935::AS3935 (I2C &i2c, PinName irq) : _i2c(i2c), _irq(irq) {
_irq.mode(PullUp);
_mode = 0;
_type = 0;
}
AS3935::AS3935 (PinName sda, PinName scl, PinName irq) : _i2c(sda, scl), _irq(irq) {
_irq.mode(PullUp);
_mode = 0;
_type = 0;
}
void AS3935::init () {
char cmd[2];
cmd[0] = 0x3c;
cmd[1] = 0x96; // PRESET_DEFAULT
_i2c.write(AS3935_ADDR, cmd, 2);
cmd[0] = 0x3d;
cmd[1] = 0x96; // CALIB_RCO
_i2c.write(AS3935_ADDR, cmd, 2);
cmd[0] = 0x00;
cmd[1] = (0x12<<1); // AFE_GB=12(Indoor)
_i2c.write(AS3935_ADDR, cmd, 2);
cmd[0] = 0x01;
cmd[1] = (0x02<<4)|(0x02<<0); // NF_LEV, WDTH
_i2c.write(AS3935_ADDR, cmd, 2);
cmd[0] = 0x03;
cmd[1] = 0x00; // LCO_FDIV = 1/16
_i2c.write(AS3935_ADDR, cmd, 2);
calib_lco();
_irq.fall(this, &AS3935::isr_lightning);
}
// Antenna Tuning (500kHz)
void AS3935::calib_lco () {
int i, n, m = 10000, r = 0;
char cmd[2];
Timer t;
_mode = 0;
_irq.fall(this, &AS3935::isr_freq);
for (i = 0; i < 0x10; i ++) {
cmd[0] = 0x08;
cmd[1] = 0x80 | i;
_i2c.write(AS3935_ADDR, cmd, 2);
wait_ms(10);
t.reset();
t.start();
_freq = 0;
_mode = 1;
while (t.read_ms() < 100);
_mode = 0;
n = abs(_freq - 3125);
if (m > n) {
r = i;
} else {
break;
}
m = n;
}
_irq.fall(NULL);
t.stop();
cmd[0] = 0x08;
cmd[1] = r;
_i2c.write(AS3935_ADDR, cmd, 2);
DBG("- init %d %d\r\n", r, _freq * 16 * 10);
}
void AS3935::read (int &energy, int &distance) {
char cmd[4];
cmd[0] = 0x04;
_i2c.write(AS3935_ADDR, cmd, 1, true);
_i2c.read(AS3935_ADDR, cmd, 4);
energy = ((cmd[2] & 0x1f) << 16) | (cmd[1] << 8) | cmd[0];
distance = cmd[3] & 0x3f;
}
void AS3935::isr_freq () {
if (_mode == 1) {
_freq ++;
}
}
void AS3935::isr_lightning () {
char cmd[2];
cmd[0] = 0x03;
_i2c.write(AS3935_ADDR, cmd, 1, true);
_i2c.read(AS3935_ADDR, cmd, 1);
DBG("- irq %02x\r\n", cmd[0]);
_type = cmd[0] & 0x0f;
switch (_type) {
case 0x01: // Noise level too high
break;
case 0x04: // Disturber detected
break;
case 0x08: // Lightning interrupt
_func.call();
break;
}
}