Closed CBMalloch closed 6 years ago
I'll try to take a look at this later in the week. I now have some hardware to spy on the I2C communications so I'll use that to check that SoftWire
is sending the expected data. I never had much luck with the AS3935; my breakout board never generated an interrupt.
@CBMalloch Please can you attach that Arduino script instead of pasting it inline. I can't guarantee it will work with my hardware but it might be a useful starting point.
I've not been able to look at the hardware signals but I did see that the AS3935
library had not been updated to work with SoftWire
v2.0.0. I've updated AS3935
to use llWrite()
instead of write()
and I believe that v1.0.2 of AS3935
will fix the problem. Please let me know either way.
It looks like it works fine now. Thanks!
Great - thanks for letting me know so that I can close this issue.
Recompiled a slightly-modified, but working, program which used AS3935 and SoftWire to speak to an AS3935 in a MOD-1016 card. Wouldn't work. Backed out of changes. Still won't work. Tried demo. Wouldn't work. Hardware not changed. Signal analyzer sees writes to 0x06 (AS3935 address is 0x03, so this is right) and 0x07, reads 0x24 always. It looks like SoftWire llwrite function buffers bytes to be sent, but nobody seems to call endTransmissionInner, which looks like it would be the thing to actually transmit what's in the buffer! Here's the sequence I see: SW: llWrite: 0x6 SW: llWrite: 0x6 SW: llWrite: 0x6 sPU=>sI1 SW: llWrite: 0x6 SW: llWrite: 0x6 SW: llWrite: 0x7 SW: llRead: got 0x24 SW: llWrite: 0x6 sI1=>sI2 SW: llWrite: 0x6 SW: llWrite: 0x7 SW: llRead: got 0x24 SW: llWrite: 0x6 SW: llWrite: 0x6 SW: llWrite: 0x7 SW: llRead: got 0x24 sI2=>sL SW: llWrite: 0x6 SW: llWrite: 0x7 SW: llRead: got 0x24 SW: llWrite: 0x6 SW: llWrite: 0x6 SW: llWrite: 0x7 SW: llRead: got 0x24 Problem - noise floor was set to 0 but didn't set ==> 2
Did this get broken with the update to SoftWire? Or am I missing something else?
Here's my Arduino code:
define PROGNAME "MOD-1016_AS3935_lightning_sensor.ino"
define VERSION "0.3.4"
define VERDATE "2018-08-04"
/* Side notes: that program uses SoftWire, which initializes pin 14 (A0) for SDA and pin 17 (A3) for SCL.
Many "Something else happened!" events
Two kinds of calls - process and getTriggered. What events lead to each? getTriggered returns the value of _triggered process turns _triggered off if state is WaitR Does calling getInterruptFlags and getState clear these? No. When should they be called? Add a real-time clock to this setup, then hard-wire it; move it to an ESP so can query a timeserver?
v0.3.0 removed dumping registers unless VERBOSE or actual lightning detected
*/
include
include
include
ifdef JTD
include
endif
//**** //****
define VERBOSE 4
const unsigned long BAUDRATE = 115200; const int tabColumn = 40;
//**** //****
/* hardware incl GPIO *****/
/* connections: A0 SDA for sensor (yellow) A3 SCL for sensor (white)
*/
const int piSensor = 2; // IRQ pin from sensor const int intSensor = 0; // Arduino pin 2 is INT0; pin 3 (not used here) is INT1 const int pdThrobber = 13;
const uint8_t i2cAddr = 0x03; const byte antennaTuningValue = 0x02;
/*** Global Vars **/
int distanceEstimate = 0; uint8_t count = 0; bool ledState = true;
AS3935 as3935;
AsyncDelay throbberTimeout, textThrobberTimeout;
char states [ ] [ 6 ] = { "Off", "PwrUp", "Init1", "Init2", "Listn", "WaitR", "Cal" };
/** Function Prototypes ***/
void ISR_lightning_sensor (void); void displayRegs ();
/**/
void setup () {
const int dly = 5;
ifdef JTD
endif
Serial.begin ( BAUDRATE ); while ( !Serial && millis() < 2000 );
// sda, scl, address, tunCap, indoor, timestamp as3935.initialise ( 14, 17, i2cAddr, antennaTuningValue, true, NULL ); // no delays necessary - internal to as3935 code // delay ( dly );
// as3935.reset(); // delay ( dly ); // as3935.clearStats(); // delay ( dly );
as3935.start(); // start implicitly calls calibrate // delay ( dly );
// wait until it's in Listen state while ( as3935.getState() != AS3935::stateListening ) as3935.process(); // process steps through initilization states
// delay ( dly );
if ( ! as3935.setNoiseFloor ( 0 ) ) { Serial.println ( "Failed to set noise floor!" ); while ( 1 ); } delay ( dly );
if ( 1 ) { uint8_t val = 0xff; if ( ! as3935.readRegister ( AS3935::regNoiseFloor , val ) ) { Serial.println ( "Failed to read noise floor register!" ); while ( 1 ); } val = ( val >> 4 ) & 0x07; if ( val != 0 ) { Serial.print ( "Problem - noise floor was set to 0 but didn't set ==> " ); Serial.println ( val ); } while ( 1 ); }
// as3935.calibrate(); // delay ( 20 ); // set bit 5 of interrupt mask register to ignore disturbance events as3935.setRegisterBit ( 0x03, 5, 1 ); delay ( 20 );
// set threshold number of strikes within 1 minute // 0x00 -> 1; 0x01 -> 5; 0x02 -> 9; 0x03 -> 16 in bits 5-4 of register 2 as3935.setRegisterBit ( 0x02, 5, 0 ); delay ( 20 ); as3935.setRegisterBit ( 0x02, 4, 1 ); delay ( 20 ); // as3935.setMinimumLightnings ( 1 );
pinMode ( pdThrobber, OUTPUT ); digitalWrite ( pdThrobber, ledState );
pinMode ( piSensor, INPUT ); attachInterrupt ( intSensor, ISR_lightning_sensor, RISING ); throbberTimeout.start ( 1000, AsyncDelay::MILLIS );
if ( VERBOSE >= 2 ) { textThrobberTimeout.start ( 10UL 60UL 1000UL, AsyncDelay::MILLIS ); }
if VERBOSE >= 2
endif
}
void loop () {
int interruptFlags = -1; int distanceEstimate = -1; static int oldState = -1;
/ AS3935 software state stateOff = 0, statePoweringUp = 1, // first 2ms wait after power applied stateInitialising1 = 2, stateInitialising2 = 3, stateListening = 4, stateWaitingForResult = 5, stateCalibrate = 6, / int state = as3935.getState(); if ( state != oldState ) { for ( int i = 0; i < tabColumn; i++ ) Serial.print ( " " ); Serial.print ( "===> new state: " ); Serial.println ( states [ as3935.getState() ] ); oldState = state; }
if ( as3935.process() ) { interruptFlags = as3935.getInterruptFlags(); distanceEstimate = as3935.getDistance();
}
if (as3935.getBusError()) Serial.println ( "\nBus error!" );
if ( as3935.getTriggered() ) {
}
if (throbberTimeout.isExpired()) { ledState = ! ledState; digitalWrite ( pdThrobber, ledState );
}
if ( VERBOSE >= 2 ) { if (textThrobberTimeout.isExpired()) { Serial.println ( "Still alive..." ); textThrobberTimeout.start ( 10UL 60UL 1000UL, AsyncDelay::MILLIS ); } }
}
/**/ /* lightning sensor ***/ /**/
void ISR_lightning_sensor (void) { as3935.interruptHandler(); }
void displayRegs () {
static bool firstTimeP = true;
Serial.print ( "\nAS3936 Registers as of " ); Serial.print ( millis() ); Serial.println ( " ms" ); /* AS3935 registers 0x00 5-1 AFE_GB 0 PWD AFE Gain Boost (norm 0x12 = 18) Power-down (norm 0) 0x01 6-4 NF_LEV 3-0 WDTH Noise Floor Level (norm 0) Watchdog threshold (norm 2) 0x02 6 CL_STAT 5-4 MIN_NUM_LIGH 3-0 SREJ Reg is usually 0xc2 (using a reserved bit!) Clear statistics (norm 1) Minimum number of lightning (norm 0) Spike rejection (norm 2) 0x03 7-6 LCO_FDIV 5 MASK_DIST 3-0 INT Frequency division ratio for antenna tuning (norm 0) Mask Disturber (norm 0) Interrupt (norm 0)
*/
uint8_t val;
as3935.readRegister ( 0 , val ); Serial.print ( " AFE gain boost ( 0x12 ): " ); Serial.println ( ( val >> 1 ) & 0x1f, HEX ); Serial.print ( " Power-down ( 0 ): " ); Serial.println ( ( val >> 0 ) & 0x01, HEX );
as3935.readRegister ( 1 , val ); Serial.print ( " Noise Floor Level ( 0 ): " ); Serial.println ( ( val >> 4 ) & 0x03, HEX ); Serial.print ( " Watchdog threshold ( 2 ): " ); Serial.println ( ( val >> 0 ) & 0x0f, HEX );
as3935.readRegister ( 2 , val ); Serial.print ( " Clear statistics ( 1 ): " ); Serial.println ( ( val >> 6 ) & 0x01, HEX ); int num = ( ( val >> 4 ) & 0x03 ); int nums [] = { 1, 5, 9, 16 }; Serial.print ( " Minimum reportable strikes/min ( 0 ): " ); Serial.print ( num ); Serial.print ( " => " ); Serial.println ( nums [ num ] ); Serial.print ( " Spike rejection ( 2 ): " ); Serial.println ( ( val >> 0 ) & 0x0f, HEX );
as3935.readRegister ( 3 , val ); Serial.print ( " Frequency division ratio for antenna tuning ( 0 ): " ); Serial.println ( ( val >> 6 ) & 0x02, HEX ); Serial.print ( " Mask Disturber ( 0 ): " ); Serial.println ( ( val >> 5 ) & 0x01, HEX ); Serial.print ( " Interrupt ( 0 ): " ); Serial.println ( ( val >> 0 ) & 0x0f, HEX );
if ( ! firstTimeP ) {
}
/ // no referent! Serial.print("EIFR: "); Serial.print ( EIFR < 0x10 ? "0x0" : "0x" ); Serial.println(EIFR, HEX); / Serial.flush();
firstTimeP = false;
}