#include <SoftwareSerial.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
#define RE 8 //max485-CTRL I suppose RE and DE could be tied to one pin?
#define DE 7 //max485-CTRL
const byte anemometer[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B};
byte values[9];
SoftwareSerial mod(2, 3); //Pin 2 = RO = max485-TX-M-RX ; Pin 3 = DI = max485-RX-M-TX
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
mod.begin(4800); //The sensor communicates at a baudrate of 4800
pinMode(RE, OUTPUT);
pinMode(DE, OUTPUT);
lcd.setCursor(2, 0);
lcd.print("Wind Speed");
lcd.setCursor(2, 1);
lcd.print("Measurement");
delay(3000);
lcd.clear(); // Clear the initial message
lcd.setCursor(0, 0); // Labels are now set up here
lcd.print("Speed:");
lcd.setCursor(0, 1);
lcd.print("Dir:");
}
void loop() {
// Transmit the request to the sensor
digitalWrite(DE, HIGH);
digitalWrite(RE, HIGH);
delay(10);
mod.write(anemometer, sizeof(anemometer));
digitalWrite(DE, LOW);
digitalWrite(RE, LOW);
delay(10);
// Wait until we have the expected number of bytes or timeout
unsigned long startTime = millis();
while (mod.available() < 9 && millis() - startTime < 1000) {
delay(1);
}
if (mod.available() >= 9) {
// Read the response
byte index = 0;
while (mod.available() && index < 9) {
values[index] = mod.read();
Serial.print(values[index], HEX);
Serial.print(" ");
index++;
}
Serial.println();
// Parse the Wind Speed value
//Windspeed is +/- 0.2m/s per datasheet
//shift the bits of values[3] 8 pos to the left.
//For example, if values[3] was 0x0A (decimal 10), values[3] << 8 becomes 0x0A00 (decimal 2560)
//After the left shift, values[3] has its bits in the upper 8 bits of a 16-bit space.
//values[3] = 0x05 (decimal 5)
//values[4] = 0x2A (decimal 42)
//values[3] << 8 = 0x0500 (decimal 1280)
//The OR operation then places the bits of values[4] into the lower 8 bits.
//0x0500 | 0x2A = 0x052A (decimal 1322)
int Wind_Speed_Int = int(values[3] << 8 | values[4]);
float Wind_Speed_m_s = Wind_Speed_Int / 100.0; //Windspeed from sensor is 100 times the actual value
float Wind_Speed_kph = Wind_Speed_m_s * 3.6; // Conversion to km/h
//float Wind_Speed_kph = Wind_Speed_m_s * 2.23694; // Conversion to Mph
//float Wind_Speed_kph = Wind_Speed_m_s * 1.94384; // Conversion to Knots
Serial.print("Wind Speed: ");
Serial.print(Wind_Speed_kph);
Serial.println(" km/h");
// Parse the Wind Direction value
// Wind direction is +/- 3 degrees per datasheet
//shift the bits of values[5] 8 pos to the left.
//For example, if values[5] was 0x0A (decimal 10), values[5] << 8 becomes 0x0A00 (decimal 2560)
//After the left shift, values[5] has its bits in the upper 8 bits of a 16-bit space.
//The OR operation then places the bits of values[6] into the lower 8 bits.
int Wind_Direction = int(values[5] << 8 | values[6]);
Serial.print("Wind Direction: ");
Serial.print(Wind_Direction);
Serial.println(" degrees");
char speedStr[10]; // For formatting speed
dtostrf(Wind_Speed_kph, 1, 1, speedStr); // Format to 1 decimal place
char dirStr[10]; // For formatting direction
dtostrf(Wind_Direction, 1, 0, dirStr); // Format to 0 decimal places
lcd.setCursor(6, 0); // Position after "Speed:"
lcd.print(speedStr); // Print the formatted speed string
lcd.print(" kph"); // Add units
lcd.setCursor(5, 1); // Position after "Dir:"
lcd.print(dirStr); // Print the formatted direction string
lcd.print(" deg."); // Add units
delay(1000);
} else {
Serial.println("Sensor timeout or incomplete frame");
lcd.setCursor(0,0);
lcd.print("Sensor Error");
delay(1000);
lcd.clear();
}
}