AMS, Franklin Lightning Sensor "AS3935" Library

Franklin Lightning Sensor

雷(落雷)センサー AS3935 用のライブラリです。

Sample

I2C接続

for LPC1114

main.cpp

#include "mbed.h"
#include "AS3935.h"

Serial pc(USBTX, USBRX);
DigitalOut led1(LED1);

AS3935 as(dp5, dp27, dp26); // sda, scl, irq
//I2C i2c(dp5, dp27);
//AS3935 as(i2c, dp26); // i2c, irq

void lightning () {
    int energy, distance;
    as.read(energy, distance);
    pc.printf("Lightning energy=%d distance=%d\r\n", energy, distance);
}

int main() {
    pc.baud(115200);
    pc.printf("*** AS3935\r\n");
    as.init();
    as.attach(&lightning);
    for (;;) {
        led1 = ! led1;
        wait(0.2);
    }
}

AS3935.cpp

Committer:
okini3939
Date:
2015-04-13
Revision:
0:5a6d7a605d26

File content as of revision 0:5a6d7a605d26:

/*
 * 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;
    }
}