@ScruffR @peekay123
Good day Particle Community
I am having some challenges measuring wind speed accurately. Im using a Davis anemometer which is essentially a reed switch closed by a magnet (for wind speed) and a potentiometer (Wind direction). I have used a debounce circuit like the one attached.
When i run the following code, the interrupt i used seems to run perfectly both with and without Blynk communication
//Davis Anamometer Windspeed
int DigitalPin1=D3; //pin used to read pulses for windspeed
void WindSpeed(void); //Timer interrupt
void Revolution(void); //Interrupt function ISR
float SampleTime=5000; //Sample time in milliseconds
float Speed; //Wind speed
volatile int RevCount=0; //Since the main program and ISR are sharing this variable
Timer timer(SampleTime, WindSpeed);//Use of timers to calculate Windspeed more precise timing than milli and it is behaves like an interrupt
void setup() {
Serial.begin(9600);
timer.start();
pinMode(DigitalPin1,INPUT_PULLDOWN);
attachInterrupt(DigitalPin1, Revolution, FALLING); //When the reed switch closes, ISR triggered on the Falling edge only removing false reading
Serial.println("Windspeed test");
delay(2000);
}
void loop() {
Serial.printlnf("");
Serial.printlnf("RevCount= %d", RevCount);
//Blynk.virtualWrite(V5, Direction); //Replace serial code with blynk but put here in loop Function
delay(300);
}
void Revolution(){
//Hardware solves debounce issue
RevCount=RevCount+1;
}
void WindSpeed(){
Serial.printlnf("WindSpeed every %d milliseconds", millis());
Speed=(3.621015*RevCount)/(SampleTime/1000); //Speed in km/hr. Fromula adpated from technical manual check Bookmarks Davis says 1600 rev/hr ---> 1 mile/hour
Serial.printlnf("Wind speed %f km/hr", Speed);
Serial.printlnf("RevCount %d", RevCount);
RevCount=0;
timer.reset(); //RESET THE TIMER TO RESTART THE COUNT FROM ZERO TILL IT REACHES 5
}
However when i combine the operation of the wind speed, wind direction and a few other sensors than my interrupts seems to occur more than in should, which is indicative of the arbitrary rev count that shows up on the serial monitor, i.e the rev count will be 7 and suddenly jump to 92. With the Blynk communication code commented out or not i still get false measurements. Here is the code for the added sensors.
#include <CE_BME280.h>
#include <BlynkSimpleSerialBLE.h>
#include<Wire.h> //Is preinstalled on the particle IDE https://community.particle.io/t/porting-from-arduino-to-particle-io-simplified-hopefully/20072
//#include<Particle.h> //Does not seem to be required. Only required if arduino program requires arduino.h or application.h https://community.particle.io/t/porting-from-arduino-to-particle-io-simplified-hopefully/20072
#define SEALEVELPRESSURE_HPA (1013.25)
#define Addr 0x76 //BME280 address 118
#define Addr1 0x39 //TSL2561 address 57
#define Addr2 0x4A //Max4409 addres 74
//char auth[] = "AUTH TOKKEN 1"; //For Bluetooth Classic
char auth[] = "AUTH TOKKEN 2"; //Bluetooth BLE
void WindsensorSetup(void); //Function to initialse the windsensor
void TSL2561LuxSensorSetup(void); //TSL2561 Sensor Setup
void Max44009LuxSensorSetup(void); //Max44009 Sensor data
void GetBME280SensorData(void); //Get BME280 Sensor data
void GetTSL2561SensorData(void); //Get TSL2561 Sensor data
void GetMax44009SensorData(void); //Get Max44009 Sensor data
void Revolution(void); //Interrupt function ISR
void WindDirection(void); //To get wind direction data
void BlynkComms(void); //To send weather data to the Blynk application
void DisplayOnSerialMonitor(void);
float Temperature;
float Pressure;
float pressure1 = 991;
float pressure2 = 991;
float Humidity;
float Altitude;
float Dewpoint;
byte BME280SensorConnected=0;
String BME280SensorState; //To store the connection status of the sensor
int WindspeedPin=D3; //Digital Read pin to detect revolutions of wind speed sensor
int AnalogPin1=A1; //Analog read pin for Wind Direction
float AnalogValue=0; //Voltage of the potentiometer from the wind direction sensor
float SampleTime=5000; //Sample time in milliseconds
float Speed=0; //Wind speed in in Km/hr
volatile int RevCount=0; //Since the main program and ISR are sharing this variable
byte WindsensorConnected=0; //Variable used to control the execution of the WindsensorSetup function
String WindsensorState; //Store the connection status of the windsensor
String Direction;
String North("North");
String NorthEast("North East");
String East("East");
String SouthEast("South East");
String South("South");
String SouthWest("South West");
String West("West");
String NorthWest("North West");
byte LuxSensorResponse; //Stores the response from the sensor to test connection of sensor to the weather station
double ch0; //IR + visible light
double ch1; //IR light
double LightIntensity; //Visible light
CE_BME280 bme; // I2C
Timer timer(SampleTime, WindSpeed);
void setup() {
Serial.begin(9600);
//Serial1.begin(9600); //Baudrate compatible with Bluetooth Classic
Serial1.begin(9600); //Baudrate 115200 is the default but can be changed using AT+BOUD4
Blynk.begin(Serial1, auth); //Initilaise communication with Blynk application via bluetooth
timer.start(); //Initialize Timer interrupt
pinMode(WindspeedPin,INPUT_PULLDOWN);
attachInterrupt(WindspeedPin, Revolution, FALLING); //When the reed switch closes, ISR triggered on the FALLING edge only
//A hardware debounce circuit is applied to prevent reed switch chatter
//BME280 DETECTION
if(!bme.begin(Addr)){
Serial.println("BME280 Error");
}
else
Serial.println("BME280 interfaced with BLYNK test");
delay(1000);
//TSL2561 DETECTION
TSL2561LuxSensorSetup(); //Set up of the Lux Sensor
if(LuxSensorResponse == 0){ //Detect lux sensor is connected to the weather station
Serial.println("Lux sensor Interfaced with BLYNK test");
}
else
Serial.println("TSL2561 Lux sensor Error");
delay(1000);
//WIND SENSOR INITIALIZATION WILL GO HERE
Serial.println("Windspeed and Wind direction Interfaced with BLYNK test\n");
delay(1000);
}
void loop() {
GetBME280SensorData();
//_____________________________________________________________________________________________________________________________+
if(Speed==0){ //if there is a wind speed measurement than look for the wind direction
Direction="None";
}
else
WindDirection(); //Call wind direction function
//______________________________________________________________________________________________________________________________+
//______________________________________________________________________________________________________________________________-
GetTSL2561SensorData(); //Call light sensor function
//______________________________________________________________________________________________________________________________-
BlynkComms();
DisplayOnSerialMonitor(); //For testing purposes only
}
void TSL2561LuxSensorSetup(){
// Initialise I2C communication as MASTER
Wire.begin();
Wire.beginTransmission(Addr1);
LuxSensorResponse = Wire.endTransmission(); //Detect if Lux sensor is connected to weather Station
// Starts I2C communication
Wire.beginTransmission(Addr1);
// Select control register
Wire.write(0x00 | 0x80);
// Power ON mode
Wire.write(0x03);
// Stop I2C Transmission
Wire.endTransmission();
// Starts I2C communication
Wire.beginTransmission(Addr1);
// Select timing register
Wire.write(0x01 | 0x80);
// Nominal integration time = 402ms
Wire.write(0x02);
// Stop I2C Transmission and the response from the sensor at the end of this transmission is stored in TSL2561SensorResponse
Wire.endTransmission();
}
void GetBME280SensorData(){
Temperature = bme.readTemperature();
Humidity = bme.readHumidity();
Pressure = (bme.readPressure()/100); //To convert to hPa
Dewpoint = Temperature - ((100 - Humidity)/5);
}
void Revolution(){
//Hardware solves debounce issue
RevCount=RevCount+1;
}
void WindSpeed(){
Speed=(3.621015*RevCount)/(SampleTime/1000); //Speed in km/hr. Formula adapted from technical manual check Bookmarks Davis says 1600 rev/hr ---> 1 mile/hour
RevCount=0;
timer.reset(); //RESET THE TIMER TO RESTART THE COUNT FROM ZERO
}
void WindDirection(){
int RawValue=0;
RawValue=analogRead(AnalogPin1);
AnalogValue=(3.3*RawValue)/4096;
if(AnalogValue>= 2.8875){
Direction=NorthWest;
}
else if(AnalogValue>= 2.475){
Direction=West;
}
else if(AnalogValue>= 2.0625){
Direction=SouthWest;
}
else if(AnalogValue>= 1.65){
Direction=South;
}
else if(AnalogValue>= 1.2375){
Direction=SouthEast;
}
else if(AnalogValue>= 0.825){
Direction=East;
}
else if(AnalogValue>=0.4125 ){
Direction=NorthEast;
}
else if(AnalogValue<0.4125 ){
Direction=North;
}
}
void GetTSL2561SensorData(){
unsigned int data[4];
for(int i = 0; i < 4; i++)
{
// Starts I2C communication
Wire.beginTransmission(Addr1);
// Select data register
Wire.write((140 + i));
// Stop I2C Transmission
Wire.endTransmission();
// Request 1 byte of data
Wire.requestFrom(Addr1, 1);
// Read 1 bytes of data
if(Wire.available() == 1)
{
data[i] = Wire.read();
}
delay(200);
}
// Convert the data
ch0 = ((data[1] & 0xFF) * 256) + (data[0] & 0xFF); //Full spectrum light (Visible + IR))
ch1 = ((data[3] & 0xFF) * 256) + (data[2] & 0xFF); //IR spectrum light
LightIntensity=ch0-ch1; //Visible light
}
void BlynkComms(){
Blynk.run();
Blynk.virtualWrite(V0, Temperature);
Blynk.virtualWrite(V1, Humidity);
Blynk.virtualWrite(V2, Pressure);
Blynk.virtualWrite(V4, Dewpoint);
Blynk.virtualWrite(V5, Direction);
Blynk.virtualWrite(V6, Speed);
Blynk.virtualWrite(V7, LightIntensity);
}
//DISPLAYS ALL MEASUREMENTS ONTO THE SERIAL MONITOR. COMMENT OUT/REMOVE AFTER TESTING PHASE COMPLETE
void DisplayOnSerialMonitor(){
Serial.print("Temperature ");
Serial.print(Temperature);
Serial.println(" C");
Serial.print("Humidity ");
Serial.print(Humidity);
Serial.println(" %");
Serial.print("Pressure ");
Serial.print(Pressure);
Serial.println(" hPa");
Serial.print("Dewpoint ");
Serial.print(Dewpoint);
Serial.println(" C");
Serial.printlnf("RevCount= %d", RevCount); //Count changed to RevCount
Serial.printlnf("Voltage8 %fV",AnalogValue);
Serial.printlnf("Wind speed %f km/hr", Speed);
Serial.print("Wind direction: ");
Serial.println(Direction);
Serial.printlnf("Full Spectrum(IR + Visible) : %f Lux", ch0 );
Serial.printlnf("Infrared Value : %f Lux", ch1);
Serial.printlnf("Visible Value : %f Lux", LightIntensity);
Serial.println("");
}
At first i thought there was an issue with the code implemented for Blynk communication but after commenting out Blynk and running the above weather station code i still have the arbitrary jumps in Revcount.
I cant identity which lines of code that could be causing this unwanted behavior. Could it be the mixture of GPIOs that i am using that could be causing the problem? Or is that there is too much happening in my program which is causing false interrupt measurements?
Here is the setup of the sensors that i have connected to my particle photon:
The BME280 sensor is connected via I2C onto pins D0 and D1
The TSL2561 lux sensor is connected via I2C onto pins D0 and D1
The Davis wind speed is connected to D3
The Davis wind direction is connected to A1
Bluetooth BLE Jdy-08 is connected to TX ad RX
Its also worth mentioning that i have used a seperate power supply to test power the sensors and used a common ground to the photon to make everything work.
Additionally i have also tested the wind speed sensor in isolation using both the external supply and photons supply using the two codes above and still i have the issue.
Please can someone advise.