Skip to content

Instantly share code, notes, and snippets.

@ksasao
Last active June 28, 2020 15:31
Show Gist options
  • Select an option

  • Save ksasao/77c789d05ae424ed6bfcb6c3e02b9564 to your computer and use it in GitHub Desktop.

Select an option

Save ksasao/77c789d05ae424ed6bfcb6c3e02b9564 to your computer and use it in GitHub Desktop.
M5Atom向け秋月雷センサーモジュール読み取りコード。ESP32系であればピン配置とわずかな修正で動くと思います。https://twitter.com/ksasao/status/1277181564036583424 を参照。
// Lightning detector for M5Atom
// AS3935 – Franklin Lightning Sensor IC
// 2020/06/28 @ksasao
// see https://twitter.com/ksasao/status/1277181564036583424
// Apache License 2.0
#include <M5Atom.h>
// M5Atom
#define IRQ_PIN 33 // ESP32 GPIO pin for IRQ
#define SDA_PIN 25
#define SCL_PIN 21
// Pin assignment for AS3935 module
// http://akizukidenshi.com/catalog/g/gK-08685/
//------------------
// M5Atom Module
//------------------
// 3V3 VDD
// G GND
// 33 IRQ
// 21 SCL
// 25 SDA
//------------------
// AS3935 Settings
#define AS3935_ADRS 0x00
#define AFE_GB 0x12 // Analog front end gain boost (0x12->Indoor, 0x0E->Outdoor) 0x00 to 0x1F
#define NF_LEV 0x02 // Noise floor level 0x00 to 0x07
#define WDTH 0x02 // Watchdog threshold 0x00 to 0x0F
#define MIN_NUM_LIGH 0x00 // Minimum number of lightning (0->1, 1->5, 2->9, 3->16)
#define SREJ 0x02 // Spike rejection 0x00 to 0x0f
// Register for AS3935
byte reg0,reg1,reg2,reg3,reg4,reg5,reg6,reg7,reg8,reg3A,reg3B,reg3C,reg3D,regDUMMY;
unsigned long energy;
unsigned int distance;
// LCO Calibration
// Frequency Measurement on digital input
// https://esp32.com/viewtopic.php?t=6533
volatile uint64_t StartValue; // First interrupt value
volatile uint64_t PeriodCount; // period in counts of 0.000001 of a second
float Freq; // frequency
hw_timer_t * timer = NULL; // pointer to a variable of type hw_timer_t
portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
void IRAM_ATTR handleInterrupt()
{
portENTER_CRITICAL_ISR(&mux);
uint64_t TempVal= timerRead(timer); // value of timer at interrupt
PeriodCount= TempVal - StartValue; // period count between rising edges in 0.000001 of a second
StartValue = TempVal; // puts latest reading as start for next calculation
portEXIT_CRITICAL_ISR(&mux);
}
float getFreq(){
portENTER_CRITICAL(&mux);
Freq =1000000.00/PeriodCount; // PeriodCount in 0.000001 of a second
portEXIT_CRITICAL(&mux);
//Serial.println((int)PeriodCount);
return Freq;
}
void lcoCalibration(void)
{
int minValue = 100 * 1000;
int cap = 0;
attachInterrupt(digitalPinToInterrupt(IRQ_PIN), handleInterrupt, FALLING);
int prescaler = 8;
timer = timerBegin(0, 80 / prescaler, true);
timerStart(timer);
// Find most suitable capacitance for 500kHz
for ( byte b = 0; b < 0x10 ; b++)
{
writeByte(0x08,(0x80 | b));
delay(50);
float freq = getFreq() * 128 * prescaler; // reg03: Frequency division ratio = 1/128
float diff = abs(freq - 500 * 1000); // 500kHz
if(diff < minValue){
minValue = diff;
cap = b;
}
Serial.print("CAP = ");
Serial.print(b);
Serial.print(" freq = ");
Serial.println((int)freq);
delay(300);
}
timerStop(timer);
Serial.print("CAP_RESULT=");
Serial.print(cap);
Serial.print(" ");
Serial.print(cap * 8);
Serial.println("pF");
writeByte(0x08,(0x80 | cap));
delay(100);
writeByte(0x08,cap);
delay(3000);
}
void readRegisters(void)
{
Wire.beginTransmission(AS3935_ADRS);
Wire.write(0);
Wire.endTransmission(false);
Wire.requestFrom(AS3935_ADRS,9);
reg0 = Wire.read();
reg1 = Wire.read();
reg2 = Wire.read();
reg3 = Wire.read();
reg4 = Wire.read();
reg5 = Wire.read();
reg6 = Wire.read();
reg7 = Wire.read();
reg8 = Wire.read();
Wire.beginTransmission(AS3935_ADRS);
Wire.write(0x3A);
Wire.endTransmission(false);
Wire.requestFrom(AS3935_ADRS,4);
reg3A = Wire.read();
reg3B = Wire.read();
reg3C = Wire.read();
reg3D = Wire.read();
}
void writeByte(byte reg, byte data)
{
Wire.beginTransmission(AS3935_ADRS);
Wire.write(reg);
Wire.write(data);
Wire.endTransmission();
delay(50);
}
byte readByte(byte reg)
{
byte data = 0;
Wire.beginTransmission(AS3935_ADRS);
Wire.write(reg);
Wire.endTransmission(false);
Wire.requestFrom(AS3935_ADRS,1);
data = Wire.read();
return data;
}
void initializeAS3935(void)
{
writeByte(0x3C,0x96);
writeByte(0x3D,0x96);
writeByte(0x00,(AFE_GB << 1));
writeByte(0x01,((NF_LEV << 4) | WDTH));
writeByte(0x02,(0xC0 | (MIN_NUM_LIGH << 4) | SREJ));
writeByte(0x03,0xC0); // Frequency division ratio = 1/128
lcoCalibration();
}
// Interrupt
void INT_DETECTS(void)
{
byte reg3buffer;
delay(4);
readRegisters();
reg3buffer = reg3 & 0x0F;
if (reg3buffer == 0x01) INT_NH();
if (reg3buffer == 0x04) INT_D();
if (reg3buffer == 0x08) INT_L();
}
void INT_NH(void) //noise level too high
{
Serial.println("Noise Level Too High ");
}
void INT_D(void) //disturber detected
{
Serial.println("Disturber Detected");
}
void INT_L(void) //lightning interrupt
{
energy = (((reg6 & 0x0F) * 65536)+ (reg5 * 256)+ (reg4)) & 0x0FFFFF;
distance = (reg7);
Serial.println(energy);
Serial.print(distance);
Serial.println(" km");
delay(1300);
}
void setup() {
M5.begin(true, false, true);
Serial.println();
Wire.begin(SDA_PIN, SCL_PIN);
pinMode(IRQ_PIN, INPUT);
initializeAS3935();
}
void loop() {
if (digitalRead(IRQ_PIN)== HIGH) INT_DETECTS();
M5.update();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment