Good day Blynk Community
I am having troubling figuring out why my wind sensor measurements become erratic every time i interface the particle photon microcontroller with the Blynk application (on the android os) via a JDY08 BLE module. The program runs perfectly when Blynk is not connected. Here is the code below:
#include <BlynkSimpleSerialBLE.h>
#include <CE_BME280.h>
#define Addr 0x76 //BME280 address 118
char auth[] = "AUTH TOKKEN HIDDEN";
void BlynkComms(void);
void DisplayOnSerialMonitor();
void GetBME280SensorData(void); //Get BME280 Sensor data
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
CE_BME280 bme; // I2C
void WindsensorSetup(void); //Function to initialse the windsensor
void Revolution(void); //Interrupt function ISR
void WindDirection(void); //To get wind direction data
void Windsensor(void); //Function to get windsensor data
int WindspeedPin=D3; //Digital Read pin to detect revolutions of wind speed 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
int AnalogPin1=A1; //Analog read pin for Wind Direction
int AnalogPin6=A6; //Analog pin used as an output to the wind sensor detection circuit
int AnalogPin4=A4; //Analog pin used as an input to the microcontroller from the wind sensor detection circuit
float AnalogValue=0; //Voltage of the potentiometer from the wind direction sensor
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");
String WindsensorState(""); //Store the connection status of the windsensor
byte WindsensorConnected=0; //Variable used to control the execution of the WindsensorSetup function
Timer timer(SampleTime, WindSpeed); //Use of timers to calculate Windspeed, every 5 seconds. It has more precise timing than milli
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
Blynk.begin(Serial1, auth);
pinMode(WindspeedPin,INPUT_PULLDOWN);
pinMode(AnalogPin6, OUTPUT); //Set analog pin A6 as Output
pinMode(AnalogPin4, INPUT_PULLDOWN); //Set analog pin A4 as Input with a weak internal pull down resistor
Serial.println("BME280 and Windsensor Blynk detection test");
delay(3000);
}
void loop() {
GetBME280SensorData();
Windsensor();
BlynkComms();
DisplayOnSerialMonitor();
}
void WindsensorSetup(){
timer.start(); //Initialize Timer interrupt
attachInterrupt(WindspeedPin, Revolution, FALLING); //When the reed switch closes, ISR triggered on the FALLING edge only
WindsensorConnected=1;
}
void Revolution(){
//Hardware solves debounce issue
RevCount=RevCount+1;
}
void WindSpeed(){
Speed=(3.621015*RevCount)/(SampleTime/1000); //Speed in km/hr. Formula adpated 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 GetBME280SensorData(){
if(!bme.begin(Addr)){
Serial.println("\nBME280 sensor not connected");
BME280SensorState="Disconnected";
Serial.println(BME280SensorState);
BME280SensorConnected=0;
Temperature = 0;
Humidity = 0;
Pressure = 0;
Dewpoint = 0;
}
else if(bme.begin(Addr)){
if(BME280SensorConnected==0){
Serial.println("BME280 sensor is connected and setup is complete"); //Remove
BME280SensorState="Connected";
BME280SensorConnected=1;
}
Temperature = bme.readTemperature();
Humidity = bme.readHumidity();
Pressure = (bme.readPressure()/100); //To convert to hPa
Dewpoint = Temperature - ((100 - Humidity)/5);
}
}
void Windsensor(){
digitalWrite(AnalogPin6, HIGH);
if(digitalRead(AnalogPin4) == HIGH){ //To detect if the windsensor is connected to the weather station
if (WindsensorConnected == 0){ //Setup windsensor only the first time after it is detected
WindsensorSetup();
WindsensorState="Connected";
Serial.println("Windsensor is connected and setup is complete"); //REMOVE AFTER TESTING
//delay(1000); //REMOVE AFTER TESTING
}
if(Speed==0){ //if there is a wind speed measurement than look for the wind direction
Direction="None";
}
else
WindDirection(); //Call wind direction function
}
else if(digitalRead(AnalogPin4) == LOW){ //If the sensor is not connected disable the timer and interrupt once
timer.stop();
timer.reset();
detachInterrupt(WindspeedPin);
WindsensorConnected=0;
WindsensorState="Disconnected";
Serial.println("Windsensor is not connected");
RevCount=0;
Speed=0;
Direction="None";
}
digitalWrite(AnalogPin6, LOW);
}
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(V8, BME280SensorState);
Blynk.virtualWrite(V9, BME280SensorState);
Blynk.virtualWrite(V10, BME280SensorState);
Blynk.virtualWrite(V11, BME280SensorState);
Blynk.virtualWrite(V12, WindsensorState);
Blynk.virtualWrite(V13, WindsensorState);
}
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.println("");
Serial.printlnf("\nRev Count: %d", RevCount);
Serial.print("Wind direction: ");
Serial.print(Direction);
Serial.printlnf("\nAnalog voltage: %fV", AnalogValue);
Serial.printlnf("Windspeed %f km/h\n", Speed);
}
Strangely the code i wrote here, an earlier version which includes most of the same functions as the above but not all, runs perfectly fine. Here is it below:
#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("");
}
I cannot identify what is disrupting my timer interrupt for the wind speed measurement every time i establish communication with the Blynk application. I am hoping someone might be able to shed some light on the matter.