Hello forum,
I've put together a weather station that measures a whole list of variables, and I'm having a hard time getting my AS3935 lightning sensor (CJMCU) to work within an interrupt. I'm using a MEGA and I use both pins 2 and 3. Pin 2 for the lightning detector and 3 for my rain guage. The rain guage works like a charm, making use of simple high / low state of the pin, dictated by the reed valve on the rain guage.
The lightning sensor however is proving a bit more tricky. This sensor lets you use either I2C or SPI - I couldn't get it to work within the interrupt when using I2C, I soon realised that I2C doesn't do well inside an ISR. Now I'm trying with SPI and having the same results, no joy.
As soon as I move the code that needs to execute with a detected strike to the loop it works great, but when I attach an interrupt to pin 2 and execute the code that way, nothing happens. I guess SPI doesn't like to run in ISR either, so what are my options?
The loop is jam packed with uploading data to my webserver through a SIM900 module, reading the other sensors, checking time from an RTC, so leaving the code for the lightning detector in the loop will not suffice, seeing that lightning happens without prior warning and if you miss one you may miss the only one. And I would like to record them all!
Here's the code that works, when left in loop. The code for I2C and SPI is identical, apart from initialising the sensor and setting an address for I2C.
void loop()
{
if(digitalRead(LIGHTNINGINTERRUPT) == HIGH)
{
intVal = lightning.readInterruptReg();
if(intVal == NOISE_INT){
Serial.println("Noise.");
}
else if(intVal == DISTURBER_INT){
Serial.println("Disturber.");
}
else if(intVal == LIGHTNING_INT)
{
Serial.println("Lightning Strike Detected!");
byte distance = lightning.distanceToStorm();
Serial.print("Approximately: ");
Serial.print(distance);
Serial.println("km away!");
long lightEnergy = lightning.lightningEnergy();
Serial.print("Lightning Energy: ");
Serial.println(lightEnergy);
}
}
}
And this is how I call the same code using an interrupt, commenting out all Serial printing of course. The transfer between variables between noInterrupts() and interrupts() is to save the values so I can upload them with the SIM900.
void Setup()
{
attachInterrupt(digitalPinToInterrupt(LIGHTNINGINTERRUPT), showLightingInterrupt, RISING);
}
void showLightingInterrupt()
{
intVal = lightning.readInterruptReg();
// Serial.println(intVal);
// if(intVal == NOISE_INT)
// Serial.println("Noise.");
// else if(intVal == DISTURBER_INT)
// Serial.println("Disturber.");
// else
if(intVal == LIGHTNING_INT)
{
// Serial.println("Lightning Strike Detected!");
lightningVal++;
distance = lightning.distanceToStorm();
// Serial.print("Approximately: ");
// Serial.print(distance);
// Serial.println("km away");
noInterrupts(); // COPY VOLATILE VALUES TO VARIABLES FOR REST OF SKETCH
intValOut = intVal;
lightningValOut = lightningVal;
distanceOut = distance;
TXlightningNow = true;
interrupts();
long lightEnergy = lightning.lightningEnergy();
// Serial.print("Lightning Energy: ");
// Serial.println(lightEnergy);
}
}