Bu sefer diğerlerinden farklı olarak amatör telsiz harici bir proje ile karşınızdayım.
Aşağıdaki projeyi bir çok farklı kodu bir araya getirerek yaptım aslında.
Bir yerden rüzgar hızı hesaplayan bir kod bulup kendi cihazıma göre modifiye ettim.
Orjinal kodta sadece seri porttan data okumak varken hem LCD hem Web arayüzüne bu sonuçları koydum.
Kesmedi bir de ısı sensörü ilave ettim.
O da kesmedi bir tane de rüzgar gülü ekledim.
1 adet Anemometre (rüzgar hız ölçer) bendeki dönüş başına belirli bir pulse üretiyor. Kodtaki kısım bu pulse a karşılık dönüş hızını km cinsinden hesaplıyor.
1 adet rüzgar gülü. Rüzgarın esişine göre içindeki potansiyometre ile 0-5V arası çıkış veriyor. Bu sayede de yön bilgisi okunuyor
1 adet Texas Instruments 18b20 ısı sensörü.
Burada çizimde göstermediğim bir ethernet shield ta var. Onu bağladıktan sonra pin dizilimlerine tekrar bakabilirsiniz.
Arduino Uno da SDA/SCL yani I2C pinleri A4 ve A5 te takılı olduğundan bağlantılar oraya yapıldı. Başka arduino modüllerinde ona göre bir düzenleme yapmak gerekebilir.
//*****************Arduino anemometer sketch******************************
#include <Wire.h> // Library for I2C communication
#include <SPI.h>
#include <Ethernet.h>
#include <OneWire.h>
#include <DallasTemperature.h>
EthernetServer server(80);
//onewire port
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
#include <LiquidCrystal_I2C.h> // Library for LCD
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 20, 4);
static byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
static byte ip[] = { 192, 168, 1, 33 }; //IP Address for Arduino Ethernet Shield
static byte gateway[] = { 192, 168, 1, 1 };
static byte subnet[] = { 255, 255, 255, 0 };
int VaneValue;// raw analog value from wind vane
int Direction;// translated 0 - 360 direction
int CalDirection;// converted value with offset applied
int CompassDir;//Compass
int LastValue;
#define Offset 0;
const byte interruptPin = 3; //anemomter input to digital pin
volatile unsigned long sTime = 0; //stores start time for wind speed calculation
unsigned long dataTimer = 0; //used to track how often to communicate data
volatile float pulseTime = 0; //stores time between one anemomter relay closing and the next
volatile float culPulseTime = 0; //stores cumulative pulsetimes for averaging
volatile bool start = true; //tracks when a new anemometer measurement starts
volatile unsigned int avgWindCount = 0; //stores anemometer relay counts for doing average wind speed
float aSetting = 60.0; //wind speed setting to signal alarm
void setup() {
//winddir
LastValue = 1;
//onewire start
sensors.begin();
// Initiate the LCD: OGUZ
lcd.init();
lcd.backlight();
pinMode(13, OUTPUT); //setup LED pin to signal high wind alarm condition
pinMode(interruptPin, INPUT_PULLUP); //set interrupt pin to input pullup
attachInterrupt(interruptPin, anemometerISR, RISING); //setup interrupt on anemometer input pin, interrupt will occur whenever falling edge is detected
dataTimer = millis(); //reset loop timer
Ethernet.begin(mac, ip, gateway, subnet);
server.begin();
Serial.println(Ethernet.localIP());
delay(1000);
}
void loop() {
//winddir
VaneValue = analogRead(A0);
Direction = map(VaneValue, 0, 1023, 0, 360);
CalDirection = Direction + Offset;
if(CalDirection > 360)
CalDirection = CalDirection - 360;
if(CalDirection < 0)
CalDirection = CalDirection + 360;
// Only update the display if change greater than 2 degrees.
if(abs(CalDirection - LastValue) > 5)
{
Serial.print(VaneValue); Serial.print("\t\t");
Serial.print(CalDirection); Serial.print("\t\t");
getHeading(CalDirection);
LastValue = CalDirection;
}
//winddir-end
unsigned long rTime = millis();
if((rTime - sTime) > 2500) pulseTime = 0; //if the wind speed has dropped below 1MPH than set it to zero
if((rTime - dataTimer) > 3000){ //See if it is time to transmit
detachInterrupt(interruptPin); //shut off wind speed measurement interrupt until done communication
float aWSpeed = getAvgWindSpeed(culPulseTime,avgWindCount); //calculate average wind speed
if(aWSpeed >= aSetting) digitalWrite(13, HIGH); // high speed wind detected so turn the LED on
else digitalWrite(13, LOW); //no alarm so ensure LED is off
culPulseTime = 0; //reset cumulative pulse counter
avgWindCount = 0; //reset average wind count
float aFreq = 0; //set to zero initially
if(pulseTime > 0.0) aFreq = getAnemometerFreq(pulseTime); //calculate frequency in Hz of anemometer, only if pulsetime is non-zero
float wSpeedMPH = getWindMPH(aFreq); //calculate wind speed in MPH
//OGUZ
//web
// listen for incoming clients
EthernetClient client = server.available();
if (client) {
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.print("Wind Speed ");
client.print(wSpeedMPH);
client.print(" km/h");
client.print(" Average ");
client.print(aWSpeed);
client.print(" Temp ");
client.print(sensors.getTempCByIndex(0));
client.print(" Direction ");
client.print(CalDirection);
client.print(" ");
client.println("<br />");
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
}
//web-end
sensors.requestTemperatures();
lcd.setCursor(0, 0); // Set the cursor on the first column and first row.
lcd.print("Wnd");
lcd.setCursor(6, 0);
lcd.print("Tmp");
lcd.setCursor(12, 0);
lcd.print("Dir");
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print(aWSpeed,1);
lcd.setCursor(6, 1);
lcd.print(sensors.getTempCByIndex(0),1);
lcd.setCursor(12, 1);
lcd.print(CalDirection,1);
//OGUZ
Serial.begin(57600); //start serial monitor to communicate wind data
Serial.println();
Serial.println("...................................");
Serial.print("Dönüs Hz ");
Serial.println(aFreq);
Serial.print("Temperature is: ");
Serial.println(sensors.getTempCByIndex(0));
Serial.print("Anlık Ruzgar Hizi (Km) ");
Serial.println(wSpeedMPH);
Serial.print("Ortalama Ruzgar Hizi(Km) ");
Serial.println(aWSpeed);
Serial.print("Ruzgar Yonu ");
Serial.println(CalDirection);
Serial.end(); //serial uses interrupts
start = true; //reset start variable in case we missed wind data
attachInterrupt(digitalPinToInterrupt(interruptPin), anemometerISR, RISING); //turn interrupt back on
dataTimer = millis(); //reset loop timer
}
}
//using time between anemometer pulses calculate frequency of anemometer
float getAnemometerFreq(float pTime) { return (1/pTime); }
//Use anemometer frequency to calculate wind speed in MPH
float getWindMPH(float freq) { return (freq*0.36); }
//uses wind MPH value to calculate KPH
float getWindKPH(float wMPH) { return (wMPH*1.61); }
//Calculates average wind speed over given time period
float getAvgWindSpeed(float cPulse,int per) {
if(per) return getWindMPH(getAnemometerFreq((float)(cPulse/per)));
else return 0; //average wind speed is zero and we can't divide by zero
}
//This is the interrupt service routine (ISR) for the anemometer input pin
//it is called whenever a falling edge is detected
void anemometerISR() {
unsigned long cTime = millis(); //get current time
if(!start) { // calculate time between pulses
// test = cTime - sTime;
pulseTime = (float)(cTime - sTime)/1000;
culPulseTime += pulseTime; //add up pulse time measurements for averaging
avgWindCount++; //calculating average wind speed
}
sTime = cTime; //store current time for next pulse time calculation
start = false; //we have our starting point for a wind speed measurement
}
//winddir
void getHeading(int direction) {
if(direction < 22)
CompassDir = "N" ;
else if (direction < 67)
CompassDir = "NE" ;
else if (direction < 112)
CompassDir = "E" ;
else if (direction < 157)
CompassDir = "SE" ;
else if (direction < 212)
CompassDir = "S" ;
else if (direction < 247)
CompassDir = "SW" ;
else if (direction < 292)
CompassDir = "W" ;
else if (direction < 337)
CompassDir = "NW" ;
else
CompassDir = "N" ;
}