Last active
June 28, 2020 15:31
-
-
Save ksasao/77c789d05ae424ed6bfcb6c3e02b9564 to your computer and use it in GitHub Desktop.
M5Atom向け秋月雷センサーモジュール読み取りコード。ESP32系であればピン配置とわずかな修正で動くと思います。https://twitter.com/ksasao/status/1277181564036583424 を参照。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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