Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Lightning activated shutter trigger
/*******************************************************************
____ __ ____ ___ ____ ____ __ __ _ ____ __
( __)( ) ( __)/ __)(_ _)( _ \ / \ ( ( \(__ ) / _\
) _) / (_/\ ) _)( (__ )( ) /( O )/ / / _/ / \
(____)\____/(____)\___) (__) (__\_) \__/ \_)__)(____)\_/\_/
Project name: Lightning activated shutter trigger using Thunder click
Project page: https://electronza.com/lightning-activated-shutter-trigger-using-thunder-click/
Description:
********************************************************************/
/*
lightning_trigger.pde - AS3935 Franklin Lightning Sensor™ IC by AMS library demo code
Code by http://microcontroller-projects.com / Teodor Costachioiu (blog [at] microcontroller-projects [dot] com)
This Arduino sketch requires the AS3935 library from https://github.com/raivisr/AS3935-Arduino-Library
Based on the original library and code by:
LightningDetector.pde - AS3935 Franklin Lightning Sensor™ IC by AMS library demo code
Copyright (c) 2012 Raivis Rengelis (raivis [at] rrkb.lv). All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <SPI.h>
#include <AS3935.h>
// some parameters
// if there is too much noise you may wish to increase that (at the expense of sensitivity)
#define noise_lvl 2
// this control for how long the trigger is closed
#define trig_delay 250 // 250 msec
// post trigger delay; needed with long exposure times
// so no more trigger pulses are appled during the exposure
#define post_trig 5000 // 5 seconds
volatile int irqSource; // needed for interrupt management
volatile int strokeDistance; //distance to the lightning
//values for minimum and maximum distance to trigger the shutter
//if the storm is too close you'd better stop taking pictures and take shelter
//good values in km are 1(storm overhead), 6, 8, 10, 12, 14, 17, 20,
//24, 27, 31, 34, 37, 40 and 63 (out of distance)
#define min_dist 6
#define max_dist 20
// Function prototype that provides SPI transfer and is passed to
// AS3935 to be used from within library, it is defined later in main sketch.
// That is up to user to deal with specific implementation of SPI
// Note that AS3935 library requires this function to have exactly this signature
// and it can not be member function of any C++ class, which happens
// to be almost any Arduino library
// Please make sure your implementation of choice does not deal with CS pin,
// library takes care about it on it's own
byte SPItransfer(byte sendByte);
// Iterrupt handler for AS3935 irqs
// and flag variable that indicates interrupt has been triggered
// Variables that get changed in interrupt routines need to be declared volatile
// otherwise compiler can optimize them away, assuming they never get changed
void AS3935Irq();
// First parameter - SPI transfer function, second - Arduino pin used for CS
// and finally third argument - Arduino pin used for IRQ
// It is good idea to chose pin that has interrupts attached, that way one can use
// attachInterrupt in sketch to detect interrupt
// Library internally polls this pin when doing calibration, so being an interrupt pin
// is not a requirement
AS3935 AS3935(SPItransfer,10,2); //change to AS3935(SPITransfer,9,3) if using slot #2
void setup()
{
// first begin, then set parameters
// pin settings for relays
pinMode(5, OUTPUT); // relay 1
pinMode(9, OUTPUT); // relay 2
// now we set the thunder click
SPI.begin();
// NB! chip uses SPI MODE1
SPI.setDataMode(SPI_MODE1);
// NB! max SPI clock speed that chip supports is 2MHz,
// but never use 500kHz, because that will cause interference
// to lightning detection circuit
SPI.setClockDivider(SPI_CLOCK_DIV16);
// and chip is MSB first
SPI.setBitOrder(MSBFIRST);
// reset all internal register values to defaults
AS3935.reset();
delay(10);
AS3935.setOutdoors();
AS3935.registerWrite(AS3935_NF_LEV,noise_lvl);
// and run calibration
// if lightning detector can not tune tank circuit to required tolerance,
// calibration function will return false
if(!AS3935.calibrate())
// Since I have no serial output, I can only signal this by turning on the relay #2 on the relay shield
digitalWrite(9, HIGH);
while(1); // stop here
AS3935.disableDisturbers();
// Using interrupts means you do not have to check for pin being set continiously, chip does that for you and
// notifies your code
// demo is written and tested on ChipKit MAX32, irq pin is connected to max32 pin 2, that corresponds to interrupt 1
// look up what pins can be used as interrupts on your specific board and how pins map to int numbers
// ChipKit Max32 - irq connected to pin 2, or Arduino with irq connected to pin 3
// Uncomment the next line if using slot #2 of the Arduino mikroBUS adapter
// attachInterrupt(1,AS3935Irq,RISING);
// uncomment line below and comment out line above for Arduino Mega 2560, irq still connected to pin 2
attachInterrupt(0,AS3935Irq,RISING);
}
void loop()
{
// I prefer to move this code inside the interrupt routine itself
// Here I do nothing
delay(100);
}
// this is implementation of SPI transfer that gets passed to AS3935
// you can (hopefully) wrap any SPI implementation in this
byte SPItransfer(byte sendByte)
{
return SPI.transfer(sendByte);
}
// this is irq handler for AS3935 interrupts, has to return void and take no arguments
// always make code in interrupt handlers fast and short
void AS3935Irq()
{
// Here is the interesting part
// first I disable the AS3935 interrupt, so all interrupts that occur during the exposure time are ignored
detachInterrupt(0);
// now I determine what caused the interrupt
irqSource = AS3935.interruptSource();
// returned value is bitmap field, bit 0 - noise level too high, bit 2 - disturber detected, and finally bit 3 - lightning!
if (irqSource & 0b1000) // Lightning!!
{
strokeDistance = AS3935.lightningDistanceKm();
if (strokeDistance <= min_dist){
// storm too close, trigger relay #2 and stop everything
digitalWrite(9, HIGH);
while(1); // stop here
}
else if (strokeDistance <= max_dist) { // safe to take pictures.
digitalWrite(5, HIGH);
delay(trig_delay);
digitalWrite(5, LOW);
delay(post_trig);
}
}
// reattach interrupt
attachInterrupt(0,AS3935Irq,RISING);
// if another interrupt occured during the exposure time, the INT pin will remain high
// until we read register REG0x03[3:0}
// so I just perform a read of this register to clear any interrupts
irqSource = AS3935.interruptSource();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment