Weather station - E38S6G5-600B-G24N as weather vane

Hello all. My first arduino forum post so please go easy on the hate.

I am building a weather station and have come to the last component which is my weather vane. I've tried various AI codes from google but cannot seem to achieve what I want....a positive integer between 0-359 to represent where the wind is blowing from.

My current function code is:

void updateEncoder2() {
  static int oldState = 0;
  int sig1 = digitalRead(encoderPin_1);
  int sig2 = digitalRead(encoderPin_2);
  int thisState = sig1 | (sig2 << 1);

  const int8_t KNOBDIR[] = {0, 22.5, 45, 67.5, 90, 112.5, 135, 157.5, 180, 202.5, 225, 247.5, 270, 292.5, 315, 337.5};
  encoderPosition += KNOBDIR[thisState | (oldState << 2)];
  if(encoderPosition > 360) {
    encoderPosition = encoderPosition - 360;
  }
  if(encoderPosition < 0) {
    encoderPosition = encoderPosition + 360;
  }
  else {
    oldState = thisState;
  }
}

this makes my encoder read data but nothing near what I need. This was AI generated based upon my query. If my full code is needed to understand my complexity...please ask. I could use some help trimming "fat" as well...but my focus is getting this to work to finalize my project.

Thanks in advance
LT

How to attract attention: "You are hateful, now answer my question."

Attention level: ACHIEVED!

Is that because humans refuse to be called hateful on your introduction?

You mean, "The AI's code is... Now fix it."

Maybe try this:

  1. Use your knowledge (not machine generated, AI garbage) to create reasonable code.
  2. Do your best to correct any errors found by the compiler.
  3. Do your best to correct non-syntax errors that make your program not perform as desired.
  4. Ask for help to analyze and render working code, like: you should post your complete sketch because you do not show how some variables are initialized or receive values.

Is that too hateful?

Would you consider addressing your second sentence?

You missed a comma after your insincere, "Thanks," and a fullstop after "advance."

Also, too hateful?

This is exactly why I stray away from forums...such fragile egos and people ripe for confrontation. I called this from the beginning and asked for the hate to be minimalized because I knew i'd get trolled like this. As for punctuation...your problem. I cannot strive for the perfection you exhibit. Point 1 in your reply: if I knew how to write code properly, I wouldn't have to ask AI...derr. Point 2: I did, in fact, correct many errors found and waited until now to ask for help. Point 3: answered in point 2. Point 4: what a concept!!! Asking for help!!! who knew? As for your AI code comment...that's MY code. I modified it to fix MY needs. How dare I ask for help...right? Now that I wasted time replying...don't help. Simple. Just keep scrolling and troll someone who truly deserves it. I am legitimately asking for human help as AI has failed. I knew, before hand, that I would get hate...so I asked to keep it to a minimum. Shoe fits, run with it.

Now...how did your reply further anything along? It didn't. I am still clueless as to why I am not achieving the results I desire. Before I forget my manners, thank you for your reply and reminding me why I do everything for myself until I exhaust every avenue I can find.

you would get a better response if you placed the part number for your encoder in the body of a post rather than the heading , its a tedious process to google info in bedded into the heading. or better still a link to the data sheet
and
post a compliable sketch instead of a useless snippet.
and
state what Arduino or whatever you are using'

so far what you have provided is nowhere near adequate

Here is the website of a seller of the E38S6G5-600B-G24N rotary encoder.
That site has a link to the E38S6G5-600B-G24N datasheet.

Photoelectric Incremental Rotary Encoder.pdf (309.5 KB)

Your encoder generates 600 pulses per revolution.

You need to count the pulses from a reference position, and then multiply by 360/600 (= 0.6) to get a number between 0 and 359.

You will need to reset the count to zero after a count of 600, and will need to be able to deal with counting negative values up to -600.

Your code has an array with 16 elements:

const int8_t KNOBDIR[] = {0, 22.5, 45, 67.5, 90, 112.5, 135, 157.5, 180, 202.5, 225, 247.5, 270, 292.5, 315, 337.5};

The elements are of datatype int8_t.
Are the elements integers?
What is the maximum value an int8_t can store?

Good morning John.

The array...or list...does have decimals. I had realized this when I was trying to fall asleep last night (when the mind reminds you of all the items your forgot or never thought of). My bad. What I understand of this line of code is:

" Based on the code snippet int8_t KNOBDIR[] = { };, here's a breakdown of what it means in C/C++:

  • int8_t: This is a data type that represents an 8-bit signed integer. It can store values ranging from -128 to 127. This specific type, defined in the stdint.h header, ensures portability and consistent behavior across different platforms and compilers because it has a fixed size of 8 bits.
  • KNOBDIR: This is the name given to the array being declared.
  • [] = { };: This part declares an array and initializes it with an empty initializer list."

That is a direct copy/paste from the AI I used to understand this line better. How it ties in, I'm unsure. After running my code several times, I don't find it even matching any of the numbers in the array/list...even the integer numbers.

const int8_t KNOBDIR[] = { 0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0 }; // Example from a rotary encoder library

This is the initial line of code AI gave me. I made this line mine by inserting the 16 points of the compass values (360 / 16 = 22.5). That was my logic there.

Int8_t stores 8 bits of information and can hold from -128 to 127 range of values. I have 16 pieces of information...my assumption is that I am in the clear as I have never worked with this before.

I did open up the links you provided and outside of technical data, found nothing to further me along in my quest.

const int8_t KNOBDIR[] = {0, 23, 45, 68, 90, 113, 135, 158, 180, 203, 225, 248, 270, 293, 315, 338};

I've changed my line to reflect integers per your suggestion

#include <DS3231.h>
#include <ArduinoJson.h>
#include <DFRobot_VEML6075.h>
#include <Adafruit_BMP085.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Arduino.h>
#include <time.h>

#define DHTTYPE DHT22
Adafruit_BMP085 bmp;
#define VEML6075_ADDR 0x10
#define DEBOUNCE_TIME 80
#define CALC_INTERVAL 1000
#define ENCODER_A 2

DFRobot_VEML6075_IIC VEML6075(&Wire, VEML6075_ADDR);
DS3231 myRTC;

const int encoderPin_1 = 3;
const int encoderPin_2 = 4;
const int t_pin = 22;
const int h_pin = 24;
const int l_pin = A1;
const int rain_pin = 25;


OneWire oneWire(t_pin);
DallasTemperature sensors(&oneWire);
DHT dht(h_pin, DHTTYPE);

float p = 0;
float press = 0;
float temp_f = 0;
float rainfall = 0;
float trigger = 0;
float rpm = 0;
int dir = 0;

volatile long encoderTicks = 0;
volatile long encoderPosition = 0;

unsigned long startTime, elapsedTime;
unsigned long lastTime = 0;

long lastTicks = 0;

void setup() {
Serial.println("setup initialized");
Serial.begin(9600);
pinMode(rain_pin, INPUT);
pinMode(t_pin, INPUT);
pinMode(ENCODER_A, INPUT_PULLUP);
pinMode(encoderPin_1, INPUT_PULLUP);
pinMode(encoderPin_2, INPUT_PULLUP);

attachInterrupt(digitalPinToInterrupt(ENCODER_A), updateEncoder, CHANGE);
attachInterrupt(digitalPinToInterrupt(encoderPin_1), updateEncoder2, CHANGE);
attachInterrupt(digitalPinToInterrupt(encoderPin_2), updateEncoder2, CHANGE);

sensors.begin();
dht.begin();

if (!bmp.begin()) {
  Serial.println("Could not find the BMP180 sensor...");
  while (1) {}
}

while (!Serial);
while (!VEML6075.begin()) {
  Serial.println("UV sensor failed to start");
  delay(8000);
}
  
Serial.println("All sensors initialized.");
Wire.begin();
//rtc.setTime(22, 21, 0);

startTime = millis();
}

void loop() {
  int cMin = myRTC.getMinute();
  if(cMin == 00) {
    connect();
  }
  else if(cMin == 10) {
      connect();
    }
  else if(cMin == 20) {
      connect();
    }
  else if(cMin == 30) {
      connect();
    }
  else if(cMin == 40) {
      connect();
    }
  else if(cMin == 50) {
      connect();
    } 
  /*float temp_f = getTemperature();
  Serial.print("Temperature = ");
  Serial.print(temp_f);
  Serial.println("F");
  float h = getHumidity();
  Serial.print("Humidity = ");
  Serial.print(h);
  Serial.println("%");
  float press = getBarometer();
  Serial.print("Barometric Pressure = ");
  Serial.print(press);
  Serial.println(" inHg");
  float li = getLight();
  Serial.print("Light Intensity = ");
  Serial.println(li);
  //float rainfall = getRain();
  //Serial.print("Total rainfall = ");
  //Serial.println(rainfall);
  float uva, uvb, uvIndex, power;
  getUV(uva, uvb, uvIndex, power);
  Serial.print("UVA = ");
  Serial.println(uva);
  Serial.print("UVB = ");
  Serial.println(uvb); 
  Serial.print("UV Index = "); 
  Serial.println(uvIndex);
  Serial.print("Solar Power = ");
  Serial.print(power);
  Serial.println(" kW/m2");*/
  //float ws = getWind();
  /*Serial.print("Wind speed = ");
  Serial.print(ws);
  Serial.println(" mph");*/
  int dir = getDir();/*
  Serial.print("Wind direction = ");
  Serial.print(dir);
  Serial.println(" degrees");*/
  //delay(500);
}

void connect() {
  float temp_f = getTemperature();
  Serial.print("Temperature = ");
  Serial.print(temp_f);
  Serial.println("F");
  float h = getHumidity();
  Serial.print("Humidity = ");
  Serial.print(h);
  Serial.println("%");
  float press = getBarometer();
  Serial.print("Barometric Pressure = ");
  Serial.print(press);
  Serial.println(" inHg");
  float li = getLight();
  Serial.print("Light Intensity = ");
  Serial.println(li);
  //float rainfall = getRain();
  //Serial.print("Total rainfall = ");
  //Serial.println(rainfall);
  float uva, uvb, uvIndex, power;
  getUV(uva, uvb, uvIndex, power);
  Serial.print("UVA = ");
  Serial.println(uva);
  Serial.print("UVB = ");
  Serial.println(uvb); 
  Serial.print("UV Index = "); 
  Serial.println(uvIndex);
  Serial.print("Solar Power = ");
  Serial.print(power);
  Serial.println(" kW/m2");
  float ws = getWind();
  Serial.print("Wind speed = ");
  Serial.print(ws);
  Serial.println(" mph");
  int dir = getDir();
  Serial.print("Wind direction = ");
  Serial.print(dir);
  Serial.println(" degrees");
  //delay(60000); //delay 1 min

  // Create JSON object
  StaticJsonDocument<256> doc;
  doc["temp"] = temp_f;
  doc["humid"] = h;
  doc["bar"] = press;
  doc["rain"] = rainfall;
  doc["uva"] = uva;
  doc["uvb"] = uvb;
  doc["uvi"] = uvIndex;
  doc["power"] = power;
  doc["intensity"] = li;
  doc["wind"] = ws;
  doc["anny"] = dir;

  // Serialize and send JSON
  String output;
  serializeJson(doc, output);
  //Serial.println(output);
}

float getTemperature() {
  //Serial.println("temp");
  sensors.requestTemperatures();
  temp_f = sensors.getTempFByIndex(0);
  return temp_f;
}

float getHumidity() {
  float h = dht.readHumidity();
  return isnan(h) ? 0.0 : h;
}

float getBarometer() {
  p = bmp.readPressure();
  press = (p / 3.2567) / 1000;  //change the decimal to match your current conditions - smaller this divsor, the larger your pressure reading will become
  return press;
}

float getLight() {
  return analogRead(l_pin);
}

float getRain() {
  static volatile unsigned int trigger = 0;
  static volatile unsigned long lastMicros = 0;
  int state = digitalRead(rain_pin);

  if (state == LOW && (long)(micros() - lastMicros) >= DEBOUNCE_TIME) {
    trigger += 1;
    lastMicros = micros();
  }
  return (trigger * 3.75) / 17; // measured at 1.875mL average per tip, translates to .0738 inches of rain
}

void getUV(float &uva, float &uvb, float &uvIndex, float &power) {
  uva = VEML6075.getUva();
  uvb = VEML6075.getUvb();
  uvIndex = VEML6075.getUvi(uva, uvb);
  power = (104 * uvIndex - 18.365) / 1000;
}

float getWind() {
  unsigned long currentTime = millis();
  if(currentTime - lastTime >= 100) {
    long currentTicks = encoderTicks;
    long ticksSinceLast = currentTicks - lastTicks;
    float rpm = (float)ticksSinceLast / (currentTime - lastTime) * 1000 / 600.0;
    float ws = 1.95 * rpm;
    Serial.print("wind speed= ");
    Serial.println(ws);
    lastTime = currentTime;
    lastTicks = currentTicks;
  }
  delay(10000);
}

int getDir() {
  int dir = (encoderPosition / 2400) * 360;
  Serial.print("Wind direction is ");
  Serial.println(dir);
  delay(1000);
}

void updateEncoder() {
  int a = digitalRead(ENCODER_A);
  encoderTicks++;
}

void updateEncoder2() {
  static int oldState = 0;
  int sig1 = digitalRead(encoderPin_1);
  int sig2 = digitalRead(encoderPin_2);
  int thisState = sig1 | (sig2 << 1);

  const int8_t KNOBDIR[] = {0, 23, 45, 68, 90, 113, 135, 158, 180, 203, 225, 248, 270, 293, 315, 338};
  encoderPosition += KNOBDIR[thisState | (oldState << 2)];
  if(encoderPosition > 360) {
    encoderPosition = encoderPosition - 360;
  }
  if(encoderPosition < 0) {
    encoderPosition = encoderPosition + 360;
  }
  else {
    oldState = thisState;
  }
}

This is my entire code snippet...to remove the comment about my code provided being "useless"

Again, I welcome CONTRUCTIVE help in streamlining my code. I do not work with arduinos enough to become as good as many of the trolls on here. I hope this provides more insight into what my end game is. I'd like a weather vane to report a value of 0 to 359...representing which angle the wind is blowing from.

I should note that a mass of my code is commented out. Once I get this portion working the way I like, those lines will be uncommented as they serve to make the whole thing function, send data to a raspberry pi for data logging. Parts are housed in various 3d printed housings and the encoders will be protected by 3d printed caps which allow for freedom of movement but make water saturation very very difficult.

When I manually move the vane...current code in use...

sig1 fluctuates between 0 and 1
sig2 fluctuates between 0 and 1
thisState fluctuates between 0 and 3
encoderPosition fluctuates between 0 and 359 (either direction of movement...clockwise/counter clockwise). seems that this is the solution but it is not. so I changed my code to reflect 600 counts instead of 360 (lines 285 onward). I also added within the else statement that encoderProsition will equal 0...to reset it after every "reading"...I think that's the right term I want to use? Sample maybe?

that is the output I am currently getting. Should I just

I made changes and am getting closer to my goal.

int getDir() {
  int dir = (encoderPosition * 0.6);
  if(dir < 0) {
    dir = dir + 360;
  }
  if (dir > 360) {
    dir = dir - 360;
  }
  else {    
    Serial.print("Wind direction is ");
    Serial.println(dir);
    delay(1000);
  }
}

void updateEncoder() {
  int a = digitalRead(ENCODER_A);
  encoderTicks++;
}

void updateEncoder2() {
  static int oldState = 0;
  int sig1 = digitalRead(encoderPin_1);
  int sig2 = digitalRead(encoderPin_2);
  int thisState = sig1 | (sig2 << 1);

  const int8_t KNOBDIR[] = {0, 23, 45, 68, 90, 113, 135, 158, 180, 203, 225, 248, 270, 293, 315, 338};
  encoderPosition += KNOBDIR[thisState | (oldState << 2)];
  if(encoderPosition > 600) {
    encoderPosition = encoderPosition - 600;
  }
  if(encoderPosition < -600) {
    encoderPosition = encoderPosition + 600;
  }
  else {
    //encoderPosition = 0;  //only produces 0's for result...taken out
    oldState = thisState;
  }
}

this is now producing values between 0 and 359...however...not accurate. If I manually start at 0, which is magnetic north, and rotate the vane 90 degrees counter clockwise, I should get a reading of 270...cardinal point West. I don't. I just get a reading of 271, 198, then settling on 167. It should remain on the 271, not drop. Would this be where I need to 0 out the encoder?

Fixed that for you.

If I am at a public swimming pool, and one person makes it known they are "having a nice poo" in the swimming pool, I am not one to swim around their ignorance. I am one to address the issue directly, so as to let others not have to deal with the ignorance, and have a nice swim. You will probably not start interactions with "all you haters listen up now!"

Is that too hateful?

For reference...

I agree. You modified AI code. When you know how to use it, it is a tool. Asking humans to clean up the waste product of an "AI" generator is not kind. Do your best to make your code work. We all need a hand some days. Some of my best thinking is in the lav.

Here's an even better hint at writing your own... "seed" your conscious thoughts with parts of your problem just before bed. "Fold" that issue a little while still conscious. You may find that your subconscious solves your problem before you doze off because your subconscious does not put up barriers (does not say, "that can't be the problem"), and it's better than a day at the swimming pool.

You are welcome.

I have found a solution to my weather vane issue and it has been running all day without complications.

The current cope of my code is to follow. For those who won't be using a data logger (pi), you can omit the void connect() and remove any calls to it.

/*Much of this code came from various Google searches and AI assistance. I merely modified it for my use
Limited help came from the Arduino Forums and I am grateful for what constructive help I did receive
This is a custom weather station, many parts engineered of my own design while others were provided from www.thingiverse.com and modified for my purpose
*/
#include <DS3231.h>
#include <ArduinoJson.h>
#include <DFRobot_VEML6075.h>
#include <Adafruit_BMP085.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Arduino.h>
#include <time.h>

#define DHTTYPE DHT22
Adafruit_BMP085 bmp;
#define VEML6075_ADDR 0x10
#define DEBOUNCE_TIME 80
#define ENCODER_A 2
#define encoderPin_1 3
#define encoderPin_2 4

DFRobot_VEML6075_IIC VEML6075(&Wire, VEML6075_ADDR);
DS3231 myRTC;

const int t_pin = 22;
const int h_pin = 24;
const int l_pin = A1;
const int rain_pin = 25;

OneWire oneWire(t_pin);
DallasTemperature sensors(&oneWire);
DHT dht(h_pin, DHTTYPE);

float temp_f = 0;
float h = 0;
float p = 0;
float press = 0;
float rainfall = 0;
float trigger = 0;
float rpm = 0;
float ws = 0;

static int dir = 0; 

volatile long encoderTicks = 0;
volatile long encoderPosition = 0;
volatile long eP = 0;
volatile int pulseCount = 0;
volatile int lastAState = 0;

unsigned long lastTime = 0;

long lastTicks = 0;

void setup() {
Serial.println("setup initialized");
Serial.begin(9600);
pinMode(rain_pin, INPUT);
pinMode(t_pin, INPUT);
pinMode(ENCODER_A, INPUT_PULLUP);
pinMode(encoderPin_1, INPUT_PULLUP);
pinMode(encoderPin_2, INPUT_PULLUP);

attachInterrupt(digitalPinToInterrupt(ENCODER_A), updateEncoder, CHANGE);
attachInterrupt(digitalPinToInterrupt(encoderPin_1), readEncoder, CHANGE);

sensors.begin();
dht.begin();

if (!bmp.begin()) {
  Serial.println("Could not find the BMP180 sensor...");
  while (1) {}
}

while (!Serial);
while (!VEML6075.begin()) {
  Serial.println("UV sensor failed to start");
  delay(8000);
}
  
Serial.println("All sensors initialized.");
Wire.begin();
//rtc.setTime(22, 21, 0);
}

void loop() {
  int cMin = myRTC.getMinute();
  if(cMin == 00) {
    connect();
  }
  else if(cMin == 10) {
      connect();
    }
  else if(cMin == 20) {
      connect();
    }
  else if(cMin == 30) {
      connect();
    }
  else if(cMin == 40) {
      connect();
    }
  else if(cMin == 50) {
      connect();
    } 
  float temp_f = getTemperature();
  Serial.print("Temperature = ");
  Serial.print(temp_f);
  Serial.println("F");
  float h = getHumidity();
  Serial.print("Humidity = ");
  Serial.print(h);
  Serial.println("%");
  float press = getBarometer();
  Serial.print("Barometric Pressure = ");
  Serial.print(press);
  Serial.println(" inHg");
  float li = getLight();
  Serial.print("Light Intensity = ");
  Serial.println(li);
  //float rainfall = getRain();
  //Serial.print("Total rainfall = ");
  //Serial.println(rainfall);
  float uva, uvb, uvIndex, power;
  getUV(uva, uvb, uvIndex, power);
  Serial.print("UVA = ");
  Serial.println(uva);
  Serial.print("UVB = ");
  Serial.println(uvb); 
  Serial.print("UV Index = "); 
  Serial.println(uvIndex);
  Serial.print("Solar Power = ");
  Serial.print(power);
  Serial.println(" kW/m2");
  float ws = getWind();
  Serial.print("Wind speed = ");
  Serial.print(ws);
  Serial.println(" mph");
  int dir = readEncoder();
  Serial.print("Wind direction = ");
  Serial.print(dir);
  Serial.println(" degrees");

  delay(10000);
}

void connect() {
  float temp_f = getTemperature();
  float h = getHumidity();
  float press = getBarometer();
  float li = getLight();
  //float rainfall = getRain();
  //Serial.print("Total rainfall = ");
  //Serial.println(rainfall);
  float uva, uvb, uvIndex, power;
  getUV(uva, uvb, uvIndex, power);
  float ws = getWind();
  readEncoder();

  // Create JSON object
  StaticJsonDocument<256> doc;
  doc["temp"] = temp_f;
  doc["humid"] = h;
  doc["bar"] = press;
  doc["rain"] = rainfall;
  doc["uva"] = uva;
  doc["uvb"] = uvb;
  doc["uvi"] = uvIndex;
  doc["power"] = power;
  doc["intensity"] = li;
  doc["wind"] = ws;
  doc["anny"] = dir;

  // Serialize and send JSON
  String output;
  serializeJson(doc, output);
  //Serial.println(output);
  delay(60000); //delay 1 min
}

float getTemperature() {
  //Serial.println("temp");
  sensors.requestTemperatures();
  temp_f = sensors.getTempFByIndex(0);
  return temp_f;
}

float getHumidity() {
  float h = dht.readHumidity();
  return isnan(h) ? 0.0 : h;
}

float getBarometer() {
  p = bmp.readPressure();
  press = (p / 3.2567) / 1000;  //change the decimal to match your current conditions - smaller this divsor, the larger your pressure reading will become
  return press;
}

float getLight() {
  return analogRead(l_pin);
}

float getRain() {
  static volatile unsigned int trigger = 0;
  static volatile unsigned long lastMicros = 0;
  int state = digitalRead(rain_pin);

  if (state == LOW && (long)(micros() - lastMicros) >= DEBOUNCE_TIME) {
    trigger += 1;
    lastMicros = micros();
  }
  return (trigger * 3.75) ; // measured at 1.875mL average per tip, 17 mL per cubic inch - translates to .0738 inches of rain
}

void getUV(float &uva, float &uvb, float &uvIndex, float &power) {
  uva = VEML6075.getUva();
  uvb = VEML6075.getUvb();
  uvIndex = VEML6075.getUvi(uva, uvb);
  power = (104 * uvIndex - 18.365) / 1000;
}

float getWind() {
  unsigned long currentTime = millis();
  if(currentTime - lastTime >= 100) {
    long currentTicks = encoderTicks;
    long ticksSinceLast = currentTicks - lastTicks;
    float rpm = (float)ticksSinceLast / (currentTime - lastTime) * 1000 / 600.0;
    float ws = 1.95 * rpm;  // converts rotational velocity to linear velocity - circle speed to straight speed - rpms to mph :)
    lastTime = currentTime;
    lastTicks = currentTicks;
    return ws;
  }
}

void updateEncoder() {
  int a = digitalRead(ENCODER_A);
  encoderTicks++;
  return encoderTicks;
}

int readEncoder() {
  int aState = digitalRead(encoderPin_1);
  int bState = digitalRead(encoderPin_2);

  if (aState != lastAState) {
    if (bState != aState) {
      pulseCount++;
    }
    else {
      pulseCount--;
    }
  }
  int dir = (pulseCount / 600.0000) * 360; //converts pulses to degrees
  if (dir <= -0.1) {  // keeps the reading between 0 and 359 degrees
    dir = dir + 360;
  }
  if (dir >= 360) { // keeps the reading between 0 and 359 degrees
    dir = dir - 360;
  }
  delay(100);
  //Serial.println(dir);
  lastAState = aState;
}

Thank you for your patience and thank you John for your feedback. Hope this helps someone in the future who is looking to build an arduino powered weather station :blush: