#include <dht.h>
#include <Adafruit_BME280.h>
#include <Wire.h>
// DHT22 variables
dht DHT;
#define DHT22_PIN 3
float temp_DHT_1;
float RH_DHT_1;
// BME280 variables
Adafruit_BME280 bme;
float temp_BME;
float RH_BME;
float altimeter;
// wind direction variables
int vane;
int heading;
const int offset = 0;
int calHeading;
int headingBuff[16] = {};
int headingAvg;
// wind speed variables
#define AnemometerPin 4
volatile unsigned long Rotations; // cup rotation counter used in interrupt routine
volatile unsigned long ContactBounceTime; // Timer to avoid contact bounce in interrupt routine
float windSpeed_mph; // Wind speed in miles per hour
float windSpeed_kts; // Wind speed in knots
int S = 2250; // S = anemometer sample period in milliseconds (provided in anemometer data sheet)
int T = 3000; // T = arduino sample period in milliseconds
// Serial communication
#define txEnable 2
int address = 301;
char data[64] = {0};
int y100;
int y200;
int packet1 = 201;
int packet2 = 202;
int packet3 = 203;
int packet4 = 204;
int packet5 = 205;
int packet6 = 206;
int comRelease = 207;
float tempAvg;
float RHAvg;
// Misc global variables
int w;
int x;
void setup() {
Serial.begin(19200);
bme.begin(0x77);
pinMode(txEnable, OUTPUT);
pinMode(AnemometerPin, INPUT);
attachInterrupt(digitalPinToInterrupt(AnemometerPin), isr_rotation, FALLING);
w = 1;
}
void loop() {
// temperature, humidity, and barometric pressure
while(w == 1) {
int chk = DHT.read22(DHT22_PIN);
temp_DHT_1 = (DHT.temperature) * 9/5 + 32;
RH_DHT_1 = DHT.humidity;
temp_BME = bme.readTemperature() * 9/5 + 32;
RH_BME = bme.readHumidity();
altimeter = (bme.readPressure() / 3386.39);
tempAvg = ((temp_DHT_1 + temp_BME) / 2.0);
RHAvg = ((RH_DHT_1 + RH_BME) / 2.0);
delay(100);
x = 0;
w = 2;
}
// wind direction
while(w == 2) {
while(x < 16) {
for(x = 0; x < 16; x++) {
vane = analogRead(A0);
heading = map(vane, 0, 1023, 0, 360);
calHeading = heading + offset;
if(calHeading > 360) {
calHeading = calHeading - 360;
}
if(calHeading < 0) {
calHeading = calHeading + 360;
}
delay(250);
headingBuff[x] = calHeading;
}
}
headingAvg = ((
headingBuff[0] +
headingBuff[1] +
headingBuff[2] +
headingBuff[3] +
headingBuff[4] +
headingBuff[5] +
headingBuff[6] +
headingBuff[7] +
headingBuff[8] +
headingBuff[9] +
headingBuff[10] +
headingBuff[11] +
headingBuff[12] +
headingBuff[13] +
headingBuff[14] +
headingBuff[15]
) / 16);
delay(20);
w = 3;
}
// wind speed
while(w == 3) {
Rotations = 0; // Set Rotations count to 0 ready for calculations
sei(); // Enables interrupts
delay (T); // Wait T milliseconds to average
cli(); // Disable interrupts
// convert to mp/h using the formula V=P(S/T)
// where:
// V = velocity in mph
// P = number of pulses in the sample period
// S = anemometer sample period in milliseconds (provided in anemometer data sheet)
// T = arduino sample period in milliseconds
// V = P(2250/3000) ==> windSpeed_mph = Rotations * (S/T);
windSpeed_mph = Rotations * (S/T);
windSpeed_kts = windSpeed_mph / 1.151;
delay(20);
w = 4;
}
// serial communication
while(w == 4) {
byte n = Serial.available();
if (n != 0) {
byte m = Serial.readBytesUntil('\n', data, 64);
data[m] = '\0'; //null-byte
y100 = atoi(strtok(data, ","));
y200 = atoi(strtok(NULL, ","));
if(y100 == address) {
if(y200 == 0) {
}
if(y200 == packet1) {
delay(200);
digitalWrite(txEnable, HIGH);
Serial.print(address);
Serial.print(",");
Serial.print(packet1);
Serial.print(",");
Serial.print(tempAvg);
Serial.print(",");
Serial.print(RHAvg);
Serial.print(",");
Serial.println(0);
digitalWrite(txEnable, LOW);
delay(50);
y200 = 0;
}
if(y200 == packet2) {
delay(200);
digitalWrite(txEnable, HIGH);
Serial.print(address);
Serial.print(",");
Serial.print(packet2);
Serial.print(",");
Serial.print(0);
Serial.print(",");
Serial.print(0);
Serial.print(",");
Serial.println(0);
digitalWrite(txEnable, LOW);
delay(50);
y200 = 0;
}
if(y200 == packet3) {
delay(200);
digitalWrite(txEnable, HIGH);
Serial.print(address);
Serial.print(",");
Serial.print(packet3);
Serial.print(",");
Serial.print(altimeter);
Serial.print(",");
Serial.print(headingAvg);
Serial.print(",");
Serial.println(windSpeed_kts);
digitalWrite(txEnable, LOW);
delay(50);
y200 = 0;
}
if(y200 == packet4) {
delay(200);
digitalWrite(txEnable, HIGH);
Serial.print(address);
Serial.print(",");
Serial.print(packet4);
Serial.print(",");
Serial.print(0);
Serial.print(",");
Serial.print(0);
Serial.print(",");
Serial.println(0);
digitalWrite(txEnable, LOW);
delay(50);
y200 = 0;
}
if(y200 == packet5) {
delay(200);
digitalWrite(txEnable, HIGH);
Serial.print(address);
Serial.print(",");
Serial.println(comRelease);
digitalWrite(txEnable, LOW);
delay(50);
y200 = 0;
}
}
}
else {
delay(20);
w = 1;
}
}
}
// This is the function that the interrupt calls to increment the rotation count
void isr_rotation() {
if ((millis() - ContactBounceTime) > 15 ) { // debounce the switch contact.
Rotations++;
ContactBounceTime = millis();
}
}