AS3935 & SPI

Hello,

This is the several components within my project.

Arduino UNO SMD3
Arduino UNO Click Shield
Thunder click device AS3935 on slot 2 (CS/D9 & D3/INT)
IDE 1.6.5
Adafruit SD DATALOGGER (CS D10)

I’m trying to build a Thunder Lightning detector with recording.
I would like some help to gather the both SPI’s components: AS3935 & SD_card.

There is clearly a conflict between the two components.
THE AS3935 used SPI-mode1 and the data sheet declare an Active Low Cheap select. Obviously when CS is HIGH more than one device can communicate on MISO…

I tried to switch the both CS of SD-Card and AS3935 to organise the recording on interrupt but… without success…

I added the sketch but without SD-card management because I think I’m a real bad coder…

Thanks in advance.

#include <SPI.h>
#include <AS3935.h>
void printAS3935Registers();
byte SPItransfer(byte sendByte);
void AS3935Irq();
volatile int AS3935IrqTriggered;
#define IRQpin 3 // Interrupt1
#define CSpin 9
AS3935 AS3935(SPItransfer,CSpin,IRQpin);

void setup() //------------------------------------------------------------------------------------------------------------------------
{
  Serial.begin(9600);
  SPI.begin(); SPI.setDataMode(SPI_MODE1); SPI.setClockDivider(SPI_CLOCK_DIV16); SPI.setBitOrder(MSBFIRST);
  AS3935.reset(); 
  outputCalibrationValues(); recalibrate(); 
  AS3935.setIndoors();
  AS3935.setNoiseFloor(1);
  AS3935.setSpikeRejection(2);
  AS3935.setWatchdogThreshold(2); 
  outputCalibrationValues(); recalibrate();
  //AS3935.disableDisturbers();
  printAS3935Registers();
  AS3935IrqTriggered = 0;
  attachInterrupt(1,AS3935Irq,RISING);
}

void loop() //------------------------------------------------------------------------------------------------------------------------
{
  if(AS3935IrqTriggered)
  {
    AS3935IrqTriggered = 0;
    int irqSource = AS3935.interruptSource();
    if (irqSource & 0b0001) {Serial.println("Noise level too high, try adjusting noise floor");}     
    if (irqSource & 0b0100) {Serial.println("Disturber detected");}    
    if (irqSource & 0b1000)
    {
      int strokeDistance = AS3935.lightningDistanceKm();
      if (strokeDistance == 1) {Serial.println("Storm overhead, watch out!");}    
      if (strokeDistance == 63) {Serial.println("Out of range lightning detected.");}  
      if (strokeDistance < 63 && strokeDistance > 1) {Serial.print("Lightning detected "); Serial.print(strokeDistance,DEC); Serial.println(" km away."); }   
    }
  }
}

//------------------------------------------------------------------------------------------------------------------------
byte SPItransfer(byte sendByte) { return SPI.transfer(sendByte);}

//------------------------------------------------------------------------------------------------------------------------
void AS3935Irq() { AS3935IrqTriggered = 1;}

AS3935_example_Rebuild.ino (2.01 KB)

PrintRegister.ino (541 Bytes)

OutputCalibrationValues.ino (419 Bytes)

Recalibrate.ino (185 Bytes)

I tried to write the complet sketch.
So I provide my test in attachment…
This seem working with SD_card, but it’s not possible now to monitoring informations on serial monitor…
Each Serial commands doesn’t work…

#include <SPI.h>
#include <AS3935.h>
#include <SD.h>
void printAS3935Registers();
byte SPItransfer(byte sendByte);
void AS3935Irq();
volatile int AS3935IrqTriggered;
#define IRQpin 3 // Interrupt1
#define CS_AS3935 9
#define CS_SDCard 10
#include <Wire.h>
#define DS1307_I2C_ADDRESS 0x68
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
String File_record = "AS3935_E";
AS3935 AS3935(SPItransfer,CS_AS3935,IRQpin);

void setup() //------------------------------------------------------------------------------------------------------------------------
{
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
  if (!SD.begin(CS_SDCard)) {Serial.println("Card failed, or not present");return;}
  Serial.println("card initialized.");
  
  SPI.begin(); SPI.setDataMode(SPI_MODE1); SPI.setClockDivider(SPI_CLOCK_DIV16); SPI.setBitOrder(MSBFIRST);
  AS3935.reset(); 
  outputCalibrationValues(); recalibrate(); 
  AS3935.setIndoors(); AS3935.setNoiseFloor(2); AS3935.setSpikeRejection(2); AS3935.setWatchdogThreshold(2); 
  outputCalibrationValues(); recalibrate();
  printAS3935Registers();
  AS3935IrqTriggered = 0;
  attachInterrupt(1,AS3935Irq,RISING);
  Wire.begin();
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0x07);
  Wire.write(0x10);
  Wire.endTransmission();
  pinMode(CS_AS3935,OUTPUT);digitalWrite(CS_SDCard,LOW);
  pinMode(CS_SDCard,OUTPUT);digitalWrite(CS_SDCard,HIGH);
}

void loop() //------------------------------------------------------------------------------------------------------------------------
{
  if(AS3935IrqTriggered)
  {
    getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
    AS3935IrqTriggered = 0;
    int irqSource = AS3935.interruptSource();
    
    if (irqSource & 0b0001) {Serial.print(hour); Serial.print(":");Serial.print(minute);Serial.print(":");Serial.print(second);Serial.print("  ");Serial.println("Noise level too high, try adjusting noise floor");     
        digitalWrite(CS_AS3935,HIGH);digitalWrite(CS_SDCard,LOW);delay(10);
        File dataFile = SD.open(File_record, FILE_WRITE); 
        if (dataFile) {dataFile.print(hour);dataFile.print(":");dataFile.print(minute);dataFile.print(":");dataFile.print(second);dataFile.print(" ; ");
                       dataFile.print(dayOfMonth);dataFile.print("/");dataFile.print(month);dataFile.print("/");dataFile.print(year);dataFile.print(" ; ");
                       dataFile.println("Noise level too high, try adjusting noise floor");dataFile.close();}  
        digitalWrite(CS_SDCard,HIGH);digitalWrite(CS_AS3935,LOW);}
        
    if (irqSource & 0b0100) {Serial.print(hour); Serial.print(":");Serial.print(minute);Serial.print(":");Serial.print(second);Serial.print("  ");Serial.println("Disturber detected");
        digitalWrite(CS_AS3935,HIGH);digitalWrite(CS_SDCard,LOW);delay(10);
        File dataFile = SD.open(File_record, FILE_WRITE); 
        if (dataFile) {dataFile.print(hour);dataFile.print(":");dataFile.print(minute);dataFile.print(":");dataFile.print(second);dataFile.print(" ; ");
                       dataFile.print(dayOfMonth);dataFile.print("/");dataFile.print(month);dataFile.print("/");dataFile.print(year);dataFile.print(" ; ");
                       dataFile.println("Disturber detected");dataFile.close();}  
        digitalWrite(CS_SDCard,HIGH);digitalWrite(CS_AS3935,LOW);}
       
    if (irqSource & 0b1000)
    {
      int strokeDistance = AS3935.lightningDistanceKm();
      if (strokeDistance == 1) {Serial.print(hour); Serial.print(":");Serial.print(minute);Serial.print(":");Serial.print(second);Serial.print("  ");Serial.println("Storm overhead, watch out!");}    
      if (strokeDistance == 63) {Serial.print(hour); Serial.print(":");Serial.print(minute);Serial.print(":");Serial.print(second);Serial.print("  ");Serial.println("Out of range lightning detected.");}  
      if (strokeDistance < 63 && strokeDistance > 1) {Serial.print(hour); Serial.print(":");Serial.print(minute);Serial.print(":");Serial.print(second);Serial.print("  ");Serial.print("Lightning detected "); Serial.print(strokeDistance,DEC); Serial.println(" km away."); }   
        digitalWrite(CS_AS3935,HIGH);digitalWrite(CS_SDCard,LOW);delay(10);
        File dataFile = SD.open(File_record, FILE_WRITE); 
        if (dataFile) {dataFile.print(hour);dataFile.print(":");dataFile.print(minute);dataFile.print(":");dataFile.print(second);dataFile.print(" ; ");
                       dataFile.print(dayOfMonth);dataFile.print("/");dataFile.print(month);dataFile.print("/");dataFile.print(year);dataFile.print(" ; ");
                       dataFile.print(strokeDistance);dataFile.println("km");dataFile.close();}  
        digitalWrite(CS_SDCard,HIGH);digitalWrite(CS_AS3935,LOW);}
  }
}

//------------------------------------------------------------------------------------------------------------------------
byte SPItransfer(byte sendByte) { return SPI.transfer(sendByte);}

//------------------------------------------------------------------------------------------------------------------------
void AS3935Irq() { AS3935IrqTriggered = 1;}

CS can be active high or low, please consult the data sheets. When the AS3935 constructor accepts a CS pin, I'd assume that it handles the CS itself. Otherwise select a device before you transmit data, and deselect it afterwards, leaving all other CS in deselected state.