Please help de-Arduinofy my lightning detector

I wanted to use the Mega for some reason. This program didn’t work, so I moved it to the Uno.
But now I want to use the Mega again. I fixed a handful of things, but there’s one last error.
It’s flagging the declaration: AS3935 AS3935(SPItransfer, SS, 2);
It says AS3935 is not a type name.

This is the code.

  LightningDetector.pde - AS3935 Franklin Lightning Sensor™ IC by AMS library demo code
  Copyright (c) 2012 Raivis Rengelis (raivis [at] 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
  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 <Arduino.h>
#include <SPI.h>
#include <AS3935.h>
#include "Adafruit_GFX.h"
#include "Fonts/FreeMono12pt7b.h"
#include "Fonts/FreeMono9pt7b.h"
#include <Adafruit_SSD1306.h>
VDD             3.3V - Max32, 5V - Mega 2560
GND             GND
MOSI            51
MISO            50
SCLK            52
IRQ             2
SI              GND
CS              53

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

byte SPItransfer(byte sendByte);
Adafruit_SSD1306 display(128, 64, &Wire, 8);
AS3935 AS3935(SPItransfer, SS, 2);

void printAS3935Registers();
void AS3935Irq();
volatile int AS3935IrqTriggered;

void setup()
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.print("Lightning Detector");
  delay(5000); // Pause for 2 seconds

  // Clear the buffer

  // first begin, then set parameters
  // NB! chip uses 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
  // and chip is MSB first
  // reset all internal register values to defaults
bool calibrateOsc();
void setNoiseLevel(uint8_t _floor);
if (!AS3935.calibrate())
  Serial.println("Tuning out of range, check your wiring, your sensor and make sure physics laws have not changed!");

// since this is demo code, we just go on minding our own business and ignore the fact that someone divided by zero

// first let's turn on disturber indication and print some register values from AS3935
// tell AS3935 we are indoors, for outdoors use setOutdoors() function
// turn on indication of distrubers, once you have AS3935 all tuned, you can turn those off with disableDisturbers()
AS3935IrqTriggered = 0;
// 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
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()
  display.setCursor(1, 20);
  display.println("Lightning Monitor ");

  // here we go into loop checking if interrupt has been triggered, which kind of defeats
  // the whole purpose of interrupts, but in real life you could put your chip to sleep
  // and lower power consumption or do other nifty things
  if (AS3935IrqTriggered)
    // reset the flag
    AS3935IrqTriggered = 0;
    // first step is to find out what caused interrupt
    // as soon as we read interrupt cause register, irq pin goes low
    int 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 & 0b0001)
      Serial.println("Noise level too high, try adjusting noise floor");
    display.println("Noise level too high, try adjusting noise floor");
    if (irqSource & 0b0100)
      Serial.println("Disturbance detected");
    display.println("Disturbance detected");
    if (irqSource & 0b1000)
      // need to find how far that lightning stroke, function returns approximate distance in kilometers,
      // where value 1 represents storm in detector's near victinity, and 63 - very distant, out of range stroke
      // everything in between is just distance in kilometers
      int strokeDistance = AS3935.lightningDistanceKm();
      if (strokeDistance == 1)
        Serial.println("Storm overhead, watch out!");
      display.println("Storm overhead, watch out!");
      if (strokeDistance == 63)
        Serial.println("Out of range lightning detected.");
      display.println("Out of range lightning detected.");
      if (strokeDistance < 63 && strokeDistance > 1)
        Serial.print("Lightning detected ");
        display.print("Lightning detected ");
        Serial.print(strokeDistance, DEC);
        display.print(strokeDistance, DEC);
        Serial.println(" kilometers away.");
        display.println(" kilometers away.");

void printAS3935Registers()
  int noiseFloor = AS3935.getNoiseFloor();
  int spikeRejection = AS3935.getSpikeRejection();
  int watchdogThreshold = AS3935.getWatchdogThreshold();
  Serial.print("Noise floor is: ");
  Serial.println(noiseFloor, DEC);
  Serial.print("Spike rejection is: ");
  Serial.println(spikeRejection, DEC);
  Serial.print("Watchdog threshold is: ");
  Serial.println(watchdogThreshold, DEC);
  Serial.print("Noise floor is: ");
  display.println(noiseFloor, DEC);
  display.print("Spike rejection is: ");
  display.println(spikeRejection, DEC);
  display.print("Watchdog threshold is: ");
  display.println(watchdogThreshold, DEC);

// 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()
  AS3935IrqTriggered = 1;

Is that an actual build error? The code looks fine to me.

What happens when you press Build / full error?

I get one “problem”:
variable “AS3935” is not a type name

But the other window shows this:

Compiling .pio\build\megaatmega2560\libe1e\Adafruit BusIO@src-1c59a2908cd7e8f991f92381d560d371\Adafruit_I2CDevice.cpp.o
.pio\libdeps\megaatmega2560\ArduinoOTA\src\ArduinoOTA.cpp:4:10: fatal error: functional: No such file or directory
 #include <functional>
compilation terminated.
*** [.pio\build\megaatmega2560\lib298\ArduinoOTA\ArduinoOTA.cpp.o] Error 1

There is no BusIO, and there is no OTA.


So since AS3935 is already a typename, you maybe can’t use it as a variable name. Try something like

    AS3935 myAS3935(SPItransfer, SS, 2);

and change all references to the object in the code below.

I’m not sure why PIO thinks it has to include OTA…


  1. Deleting the .pio folder of the project and building again
  2. Adding lib_ignore = ArduinoOTA to the platformio.ini to exclude it from the build.