lee737
April 11, 2021, 8:23am
1
I'm using an interrupt in a Nano IOT 33 to watch for low going pulses (3V to gnd) from a lightning detector board. Pulses are 120ms long (see scope screen pics). The lightning board runs from AA batteries (3V), and the boards have grounds connected.
The ISR simply sets a variable to 1, then a main loop function counts the pulse, and sets the variable back to zero.
The interrupt, when set for 'FALLING', often - at least 80% of the time, detects two pulses, 120ms apart, presumably the rising edge as well.
If set to 'CHANGE', as expected it always picks up the two edges.
Set to 'RISING', it only ever detects the one, which is what I'm using now, does seem a bit counter intuitive though!
The image shows the scope display for a pulse (entire pulse, and rising edge) that was reported as two pulses,120ms apart.
I initially just relied on a loop function to pick up the pulse ( if (digitalRead(x)==0) { etc } ) which also worked, but as this sketch is often taking connections for a wifiserver, it was missing pulses quite a bit on testing, hence I switched to using an interrupt.
It's working using the rising edge, but I was wondering if there was a reason why FALLING wasn't working as expected.....
Thanks for any insights anyone can offer.....
6v6gt
April 11, 2021, 8:52am
2
Are you using pull-up/pull-down resistors ?
Anyway, show your code and a schematic.
lee737
April 11, 2021, 9:11am
3
full code....
#include <SPI.h>
#include <WiFiNINA.h>
#define SECRET_SSID "myssid"
#define SECRET_PASS "mlitramdknkbpuxxrsyqvlur" // not mine, but 24char random, have a guess!
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
int keyIndex = 0;
byte avCount=0;
float totalRSSI=0;
float avRSSI;
float avBatteryVoltage;
float batteryVoltage;
float totalBatteryVoltage;
const byte LED=13;
const byte lightning=2; // interrupt pin to lightning detector board
volatile byte jolt=0;
unsigned long boltCount=0;
unsigned int pastHour=0;
int pulses5min[144];
int discon=0;
long rssi;
bool wifiBegun=false;
WiFiServer server(2000);
unsigned long timer=0;
unsigned long timer5min=0;
unsigned long heartBeatTimer=0;
unsigned long pulsePeriod;
unsigned long pulseTimeStamp=0;
void setup() {
pinMode(LED,OUTPUT);
pinMode(lightning,INPUT);
digitalWrite(LED,HIGH);
attachInterrupt(digitalPinToInterrupt(lightning),lightningDetected,RISING);
Serial.begin(9600);
delay(1000);
digitalWrite(LED,LOW);
// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true) {
digitalWrite(LED,HIGH);
delay(1000);
digitalWrite(LED,LOW);
delay(500);
}
}
}
void loop() {
if (wifiBegun==false) {
digitalWrite(LED,HIGH);
server.begin();
WiFi.begin(ssid, pass);
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
delay(2000);
digitalWrite(LED,LOW);
if (WiFi.status() == WL_CONNECTED) {
wifiBegun = true;
} else {
WiFi.end();
}
} else if (wifiBegun && WiFi.status() != WL_CONNECTED) {
delay(5000);
Serial.print("CONNECTION FAILED");
WiFi.end();
wifiBegun = false;
discon=discon+1;
}
if (millis()-heartBeatTimer>5000){ // heartbeat timer
heartBeat();
heartBeatTimer=millis();
}
if (jolt==1){ //count pulses detected by interrupt routine
//delay(50);
pulsePeriod=millis()-pulseTimeStamp;
pulseTimeStamp=millis();
boltCount=boltCount+jolt;
pulses5min[0]=pulses5min[0]+jolt;
jolt=0;
}
if (millis()-timer5min>300000) { // store readings in array ev 5min
for (int a=0;a<143;a++){
pulses5min[143-a]=pulses5min[142-a]; // rotate array values
}
pulses5min[0]=0;
timer5min=millis();
}
if (millis()-timer>30000) { // show status ev 30s
Serial.println(WiFi.status());
timer=millis();
printWifiStatus();
batteryVoltage=(analogRead(A0)*3.3/1024);
totalBatteryVoltage=totalBatteryVoltage+batteryVoltage;
totalRSSI=totalRSSI+pow(10,(float(rssi))/10); // calc av signal strength
avCount=avCount+1;
if (avCount==10) {
avRSSI=10*log10(totalRSSI/avCount);
avBatteryVoltage=totalBatteryVoltage/avCount;
avCount=0;
totalRSSI=0;
totalBatteryVoltage=0;
}
}
WiFiClient client = server.available(); // listen for incoming clients
if (client) {
Serial.println("new client");
boolean currentLineIsBlank = true; // an HTTP request ends with a blank line
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the HTTP request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard HTTP response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println("Refresh: 5"); // refresh the page automatically every 5 sec
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.print("Arduino nano IOT 33 Lightning detector testing");
client.println("
");
client.print("
");
client.print("Detector impulses (total)- ");
client.print(boltCount);
client.println("
");
client.print("Detector impulses (past hour)- ");
pastHour=0;
for (int f=0;f<12;f++){
pastHour=pastHour+pulses5min[f];
}
client.print(pastHour);
client.println("
");
client.print("Detector impulses (past5min)- ");
client.print(pulses5min[0]);
client.println("
");
client.print("Time since last pulse - ");
client.print((float(millis()-pulseTimeStamp))/60000,1);
client.print(" min");
client.println("
");
client.print("Time between previous two pulses - ");
client.print(float(pulsePeriod)/60000,1);
client.print(" min");
client.println("
");
client.println("
");
client.print("Pulses past 5min groups (recent first)");
client.println("
");
for (int a=0;a<133;a=a+12){
for (int b=0;b<12;b++){
client.print(pulses5min[a+b]);
client.print(" ");
}
client.println("
");
}
client.println("
");
client.print("pin A0 - ");
client.print(analogRead(A0));
client.println("
");
client.print("Battery voltage - ");
client.print(avBatteryVoltage,2);
client.print(" V");
client.println("
");
client.print("Signal strength: ");
client.print(rssi);
client.print(" dBm");
client.println("
");
client.print("Average signal strength: ");
client.print(avRSSI,1);
client.print(" dBm");
client.println("
");
client.print("Disconnections - ");
client.print(discon);
client.println("
");
client.println("</html>");
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
} else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
Serial.println("client disconnected");
}
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
void lightningDetected(){
jolt=1;
}
void heartBeat(){
digitalWrite(LED,HIGH);
delay(50);
digitalWrite(LED,LOW);
delay(50);
}
lee737
April 11, 2021, 9:25am
4
I haven't added any pullups, as the lightning detector already has one (10k), pulling the line to 3V. There is a also a connection to Arduino A0, to sense the battery voltage, added to diagram.
I haven't reproduced the entire lightning detector circuit, but take a look at Charles Wenzels web site if you want to see the full circuit, I figured this end of it was the relevant bit.
It's the first circuit on this page - New Lightning Detector for the Beginner
Relevant code snippets....
const byte lightning=2; // interrupt pin to lightning detector board
volatile byte jolt=0;
void setup()
{
pinMode(lightning,INPUT);
digitalWrite(LED,HIGH);
attachInterrupt(digitalPinToInterrupt(lightning),lightningDetected,RISING);
}
void loop()
{
if (jolt==1){ //count pulses detected by interrupt routine
//delay(50);
pulsePeriod=millis()-pulseTimeStamp;
pulseTimeStamp=millis();
boltCount=boltCount+jolt;
pulses5min[0]=pulses5min[0]+jolt;
jolt=0;
}
}
void lightningDetected(){
jolt=1;
}
6v6gt
April 11, 2021, 11:36am
5
I'm afraid I don't know the Nano IOT 33 well enough to see if you've done something wrong like use the incorrect pin for an external interrupt.
However, on the face of it, it looks like it should work and FALLING is normally the one to use in the case where there is a pullup resistor.
You can "solve" it in software by adding a debounce to lightningDetected(), something like:
void lightningDetected(){
static uint32_t lastStrikeAtMs = 0 ; // initialised once only
if ( millis() - lastStrikeAtMs > 300 ) { // 300mS debounce
jolt=1;
lastStrikeAtMs = millis() ;
}
}
or possibly try CHANGE instead of FALLING, as you have, but do a digitalRead() in the ISR to see which state the pin is in.
system
Closed
August 9, 2021, 11:37am
6
This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.