//-------------------------------------------------------------Libraries*einbinden-----------------------------------------------------------
//LED*LIBRARIES
#include*<
Wire.h>
#include*<Adafruit_MCP23017.h>
#include*<Adafruit_RGBLCDShield.h>
//Data*Logger*Libraries
#include*<
SD.h>
#include*<
Wire.h>
#include*
"RTClib.h"
//Sonstige*Libraries
#include*<
EEPROM.h>
// EEPROM Byte Speicherung Library
//---------------------------------------------------------------Definition*LCD---------------------------------------------------------------
//*Das*LCD*Shield*verwendet*standardmäßig*die*Analogausgänge*4*und*5*des*Arduino*für*die*Datenübermittlung
Adafruit_RGBLCDShield*lcd*=*Adafruit_RGBLCDShield();***
//Bennunung des LCD Shields in "lcd"
#define*OFF*0x0****************************************
//#define Definiert die Farben des LCD
#define*RED*0x1
#define*YELLOW*0x3
#define*GREEN*0x2
#define*TEAL*0x6
#define*BLUE*0x4
#define*VIOLET*0x5
#define*WHITE*0x7
//---------------------------------------------------Definition*Data*Logger-------------------------------------------------------------------
const int chipSelect = 10;
File dataFile;
long zeitAnfang = 0;
long zeitEnde = 0;
long drehzahlZwischenspeicher = 0;
boolean timerMittelwert = 0;
int zaehlerIst = 0;
RTC_DS1307*rtc;
//-------------------------------------------------------------Implementierung*der*Zähler*&*Variablen------------------------------------------
int lcd_count = 0;
// Implementierung der Zähler für die LCD Menüsteuerung
int color_count = 0;
int horizontal_count = 0;
int vertical_count = 0;
int avg1_count = 0;
//Anzahl Messwerte im Puffer für die Drehzahl der Windkraftanlage
int avg2_count = 0;
//Anzahl Messwerte im Puffer für die Drehzahl der Windgeschwindigkeitsanzeige
const int AVG1 = 4;
// Einstellung der Glättungsvariablen über mindestens 4 Messwerte
//---------------------------------------------------Definition*DREHZAHLSENSOR*(Eingangspin*2)--------------------------------------------
//*Definition*der*Drehzahlsensorvariablen
volatile*
unsigned long dauer=0;
// microsekunden seit dem letzten Interrupt
volatile*
unsigned long last=0;
// Zählerwert beim letzten Interrup
volatile*
unsigned long average_rpm=1;
long drehzahl;
// Definition der Variablen "Drehzahl"
int durchmesser_windrad = 2200;
long umfangsgeschwindigkeit;
long interruptDauer = 0;
long interruptStop = 0;
char buf[17];
// RPM (Umdrehungen) Pufferstring für sprintf
char buf3[17];
// Umfangsgeschwindigkeit
const int EingangDrehzahlmesser = 2;
// Pin 2 ist Eingang für Drehzahlschalter (Reed Kontakt)
int drehzahlMittelwert;
//Mittelwerte Drehzahlsensor für Datalogger
//--------------------------------------------------Definition*WINDGESCHWINDIGKEITSENSOR*(Eingangspin*A1)**---------------------------------
//Definition*der*Windgeschwindigkeitsvariablen
volatile*
unsigned long dauer1=0;
volatile*
unsigned long last1=0;
long drehzahl1;
long windgeschwindigkeit;
// Definition der Variablen "Windgeschwindigkeit"
long interrupt1Dauer = 0;
long interrupt1Stop = 0;
char buf1[17];
// Windgeschwindigkeit Pufferstring für sprintf
const int EingangWindgeschwindigkeit = 3;
// Pin 3 ist Eingang für Reed Kontakt des Anemometers
int windgeschwindigkeitMittelwert;
//Erstellung der Mittelwerte für die Windgeschwindigkeit
//--------------------------------------------------Definition*Windrichtungssensor*--------------------------------------------------------
#define*EingangPotentiometer*(A0)*
String windrichtung;
int Richtung;
int KorrRichtung = 0;
//Korrekturwert für Richtungswert (-360 bis +360) für die Kalibrierung der Windfahne
int WertPotentiometer = 0;
//Zwischenspeicher der Werte des Poti
String buf2;
//Ausgabewert der Windgrichtung
const int CalPin = 8;
//Definition Kalibrierungsknopf
byte DirCorrB1 = 0;
//Korrekturwerte bei der Kalibrierung
byte DirCorrB2 = 0;
//-------------------------------------------------------------------SETUP------------------------------------------------------------------
void setup() {
// Setup des Gesamtsystems initialisieren
**
Serial.
begin(9600);
**
//LCD initialisieren---------------------------------
**
// Ausgänge für das LCD debuggen - Gibt die Übertragungsgeschwindigkeit des LCD Shield und des Arduino in [bit/s] an
**lcd.
begin(16, 2);
// Setup des LCD in Anzahl der Zeichen und Anzahl der Reihen:
**lcd.
print(
"STARTE...");
// Standard Überschrift "Drehzahlmesser" ausgeben
**lcd.
setCursor(0, 1);
**lcd.
print(
"Halten f. KAL");
**lcd.
setCursor(15, 1);
**lcd.
print(
"5");
**
delay(1000);
**lcd.
setCursor(15, 1);
**lcd.
print(
"4");
**
delay(1000);
**lcd.
setCursor(15, 1);
**lcd.
print(
"3");
**
delay(1000);
**lcd.
setCursor(15, 1);
**lcd.
print(
"2");
**
delay(1000);
**lcd.
setCursor(15, 1);
**lcd.
print(
"1");
**
delay(1000);
**lcd.
clear();
**
//DataLogger initialisieren--------------------------
#ifdef*AVR
**
Wire.
begin();
#else
**Wire1.
begin();
// Initialisierung des Dataloggers
#endif
**rtc.
begin();
**
Serial.
println(
"Datum,Uhrtzeit,RPM [1/min],Umfangsgeschw.[m/s],Windgeschw.[m/s],Windrichtung");
**dataFile.
println(
"Datum,Uhrtzeit,RPM [1/min],Umfangsgeschw.[m/s],Windgeschw.[m/s],Windrichtung");
**zeitAnfang*=*
millis();
**
//Drehzahlsensor-------------------------------------
**
pinMode(EingangDrehzahlmesser,
INPUT);
// Definition EingangDrehzahlmesser (pin 2) als Eingangspin
**
digitalWrite(EingangDrehzahlmesser,
HIGH);
// Arduinointernen Pullup-Widerstand einschalten (20kOhm), somit wird kein Hardwarewiderstand benötigt
**
attachInterrupt(0, readmicros ,
RISING );
// Interrupt 0 (pin2 auf ArduinoUno) auf Routine "readmicros" (Zeit zwischen Umdrehungen) reagiert auf steigende Flanken an Pin 2
**
//Windgeschwindigkeit
**
pinMode(EingangWindgeschwindigkeit,
INPUT);
// Definition EingangDrehzahlmesser (pin 3) als Eingangspin
**
digitalWrite(EingangWindgeschwindigkeit,
HIGH);
// Arduinointernen Pullup-Widerstand einschalten (20kOhm), somit wird kein Hardwarewiderstand benötigt
**
attachInterrupt(1, readmicros1 ,
RISING );
// Interrupt 1 (pin3 auf ArduinoUno) für den Windgeschwindigkeitssensor
**
//Windrichtung
**
pinMode(CalPin,
INPUT);
// Kalibrierung, wenn der Kalibrierungsknopf gedrückt ist
**
digitalWrite(CalPin,
HIGH);
**
delay(1000);
**
if ((
digitalRead(CalPin) ==
LOW)){
****calibrate*();
**}
**
else lcd.
print(
"1.Drehzahlmesser");
**DirCorrB1*=*
EEPROM.
read(1);
// Wenn keine Kalibrierung gestartet wird, Werte aus Zwischenspeicher übernehmen
**DirCorrB2*=*
EEPROM.
read(2);
**KorrRichtung*=*(DirCorrB1)*+*(DirCorrB2);*
}
//-------------------------------------*Hauptprogramm------------------------------------------------------------------------------------
void loop() {
// Hauptprogramm als Schleife
**
//Drehzahl---------------------------------------------------------------
**
if ( dauer == 0 || (((interruptDauer =
millis()) - interruptStop) > 20000)){
//Drehzahl startet bei Null und springt bei Fehlen von Signalen nach 20s auf Null zurück
****drehzahl*=*0;
****umfangsgeschwindigkeit*=*0;
****avg1_count*=*0;
**}
**
else {
****drehzahl*=*myround*(60000000*/*average_rpm);*****************************************
// Drehzahl ausrechnen
****umfangsgeschwindigkeit*=*((drehzahl**3.14159265359**durchmesser_windrad)/60000);*****
//Aus Drehzahl Umfangsgeschwindigkeit ausrechnen
**}
**
//Windgeschwindigkeit----------------------------------------------------
**
if ( dauer1 == 0 || (((interrupt1Dauer =
millis()) - interrupt1Stop) > 20000)){
// Bei Start des Programmes und bei Stillstand (20s) auf Wert Null setzen
****windgeschwindigkeit*=*0;
**}
**
else {
****drehzahl1*=*60000000*/*dauer1;********************************************************
// Drehzahl ausrechnen
****windgeschwindigkeit*=*((((drehzahl1**3.14159265359**0.13)*/*60)**3)**3.6);************
//Aus Drehzahl Umfangsgeschwindigkeit ---> Windgeschwindigkeit = Vu*3
**}
*
**
//Anzeige der Puffervariablen----------------------
**sprintf(buf,*
"RPM %4lu ", drehzahl);
// Drehzahl als 4stellig formatierte Zahl in den Puffer schreiben
**sprintf(buf3,*
"%2lu m/s", umfangsgeschwindigkeit);
// Geschwindigkeit als 2stellig formatierte Zahl in den Puffer schreiben
**sprintf(buf1,*
"%2lu km/h", windgeschwindigkeit);
// Geschwindigkeit als 2stellig formatierte Zahl in den Puffer schreiben
**buf2*=*(windrichtung);**********************************
//Windrichtung als Himmelsrichtung ausgeben
**
//Daten der zweiten Reihe anzeigen-----------------
**lcd.
setCursor(0, 1);
// cursor an den Anfang der 2. Zeile (fängt mit 0 an)
**
if ((horizontal_count == 0) && (vertical_count == 0)){
****lcd.
print(buf);
// Puffer (RPM) ausgeben
**}
**
if ((horizontal_count == 0) && (vertical_count == 1)){
****lcd.
print(buf3);
// Puffer3 (Umfangsgeschwindigkeit) ausgeben
**}
**
if (horizontal_count == 1){
****lcd.
print(buf1);
// Puffer1 (Windgeschwindigkeit) ausgeben
**}
**
if (horizontal_count == 2){
****lcd.
print(buf2);
// Puffer2 (Windrichtung) ausgeben
**}
**
//DataLogger------------------------------------------------------------
**
//Mittelwert Drehzahlsensor
**
if (timerMittelwert == 0){
//Ist der Timer auf "0", springt das Programm in Mittelwert berechnen.
****MittelwertBerechnen();*
**}
**
//Schreiben des Datums und Uhrzeit alle 5 Sekunden-------------------------
**
if (timerMittelwert == 1){
//Wurde der Timer des Mittelwertes von Mittelwert Berechnen von 0 auf 1 gesetztz, wird eine Datenreihe auf die SD Karte geschrieben
****DateTime*now*=*rtc.now();
****
Serial.
print(now.year(),
DEC);
****
Serial.
print(
'/');
****
Serial.
print(now.month(),
DEC);
****
Serial.
print(
'/');
****
Serial.
print(now.day(),
DEC);
****
Serial.
print(
',');
****
Serial.
print(now.hour(),
DEC);
****
Serial.
print(
':');
****
Serial.
print(now.minute(),
DEC);
****
Serial.
print(
':');
****
Serial.
print(now.second(),
DEC);
****
Serial.
print(
',');
****dataFile.
print(now.year(),
DEC);
****dataFile.
print(
'/');
****dataFile.
print(now.month(),
DEC);
****dataFile.
print(
'/');
****dataFile.
print(now.day(),
DEC);
****dataFile.
print(
',');
****dataFile.
print(now.hour(),
DEC);
****dataFile.
print(
':');
****dataFile.
print(now.minute(),
DEC);
****dataFile.
print(
':');
****dataFile.
print(now.second(),
DEC);
****dataFile.
print(
',');
****
Serial.
println(drehzahlMittelwert);
****dataFile.
println(drehzahlMittelwert);
****
Serial.
print(
',');
****dataFile.
print(
',');
****
Serial.
print(windgeschwindigkeitMittelwert);
****dataFile.
print(windgeschwindigkeitMittelwert);
****dataFile.
flush();
****timerMittelwert*=*0;
****zeitAnfang*=*
millis();
**}
}
//-------------------------------------INTERRUPT*1*für*Drehzahlmesser*(Pin*2)---------------------------------------
void readmicros() {
// Interrupt-Routine 1
**
detachInterrupt(1);
// Interrupt 2 ausschalten
**
detachInterrupt(0);
// Interrupt 1 ausschalten
**
int avgmax;
**
unsigned long us =
micros();
// Microsekundenzähler auslesen
**
if (last == 0) {
// erster Messwert
****last*=*us;******************************
// merken und nicht weiter bearbeiten
**}****
**
else {
****
if ( us < last ) {
// Zählerüberlauf
******dauer*=*4294967295*-*last*+*us;*********
// erzeugt einen Fehler von 1µS - vernachlässigbar
****}
****
else {
******dauer*=*us*-*last;**********************
// Differenz zum letzten Durchlauf berechnen
****}
****
if (dauer > 5000) {
// ignorieren wenn <= 5ms (Kontaktpreller)
******average_rpm*=*dauer*+*average_rpm***avg1_count++;********
// Wert in buffer und mit Faktor avgcnt glätten
******average_rpm*/=*avg1_count;*******************************
// und zurückrechnen
******avgmax*=*1000000*/*dauer;********************************
// dynamische Größe des Integrationspuffers
******
if (avgmax < AVG1) avgmax = AVG1;
// Trägheit mindestens 1 Sekunde
******
if (avg1_count >= avgmax) avg1_count--;
******last*=*us;**********************************************
// und wieder den letzten Wert merken
****}
**}
**interruptStop*=*
millis();
**
attachInterrupt(0, readmicros,
RISING );
// Interrupt 1 wieder einschalten.
**
attachInterrupt(1, readmicros1,
RISING );
// Interrupt 2 wieder einschalten.
}
//-------------------------------------INTERRUPT*2*für*Windgeschwindigkeitssensor*(Pin*3)---------------------------------------
void readmicros1() {
// Interrupt-Routine 2
**
detachInterrupt(0);
// Interrupt 1 ausschalten während Interrupt 2 läuft
**
detachInterrupt(1);
// Interrupt 2 ausschalten während er läuft
**
unsigned long t =
micros();
// Microsekundenzähler auslesen
**
unsigned long dt = t - last1;
// Differenz zum letzten Durchlauf berechnen
**
if (dt > 100000) {
// ignorieren wenn <= 100ms (Kontaktpreller)
****dauer1*=*dt;**********************************
// Wert in dauer übernehmen
****last1*=*t;************************************
// und wieder den letzten Wert merken
**}
**interrupt1Stop*=*
millis();
**
attachInterrupt(1, readmicros1,
RISING );
// Interrupt wieder einschalten.
**
attachInterrupt(0, readmicros,
RISING );
// Interrupt wieder einschalten.
}
//-------------------Gewichtete*Rundung*für*Drehzahlmesser*einstellen--------------------------------
unsigned long myround(
unsigned long value) {
// Gewichtete Rundung für den Drehzahlsensor erstelleb
**
int rto;
**
if (value > 3000) {
// Rundungswert bestimmen
****rto*=*100;****
**}
**
else if (value > 1500) {
****rto*=*50;
**}
**
else if (value > 500) {
****rto*=*10;
**}
**
else if (value > 100) {
****rto*=*5;
**}
**
else {
****
return (value);
**}
**
return (_myround(value, rto));
}
unsigned long _myround(
unsigned long value,
int roundto) {
**value*+=*(roundto*>>*1);**************************************
// Halben roundto Wert addieren
**value*/=*roundto;*********************************************
// Integer division
**value**=*roundto;*********************************************
// Integer multiplikation
**
return (value);
}
//Kalibrierung*der*Windrichtung------------------------------------------------------------------------
void calibrate () {
//Routine wird aufgerufen, wenn der Kalibrierungsknopf beim Start des Systemes gedrückt wird
**lcd.
clear();
**lcd.
setCursor(0, 1);
**lcd.
print(
"Kalibriert... ");
**
delay (1000);
//Eine Sekunde warten
**WertPotentiometer*=*
analogRead(EingangPotentiometer);
//Wert des Poti auslesen
**KorrRichtung*=*
map(WertPotentiometer, 0, 1023, 359, 0);
//Korrekturwert ins Array schreiben
**lcd.
setCursor(0, 1);
**lcd.
print(
"KAL Wert = ");
//Korrekturwert ausgeben
**lcd.
print(KorrRichtung,
DEC);
**lcd.
print(
" ");
**
delay (2000);
//2 Sekunden warten
**
//Korrekturwerte in beide Richtungen speichern
**DirCorrB1*=*KorrRichtung*/*255;
**
if (DirCorrB1 == 1){
****DirCorrB1*=*255;**
****DirCorrB2*=*KorrRichtung*-*255*;
**}
**
else {
****DirCorrB1*=*KorrRichtung;**
****DirCorrB2*=*0;
**}***
**
EEPROM.
write (1, DirCorrB1);
//Und in den EEPROM Speicher schreiben
**
EEPROM.
write (2, DirCorrB2);
**lcd.
clear();
**lcd.
setCursor(0, 1);
**lcd.
print(
"KAL OK!");
**
delay(1000);
**lcd.
clear();
//Kalibierung abgeschlossen. System startet mit neuer Kalibierung neu...
**lcd.
print(
"Kalibrierung OK");
**lcd.
setCursor(0, 1);
**lcd.
print(
"Neustart... ");
**
delay (2000);
**lcd.
clear();
**
setup ();
}*
//Mittelwerte*berechnen-----------------------------------
void MittelwertBerechnen(){
//Mittelwerte der Drehzahl und Windgeschwindigkeit erstellen und alle 5 min auf die SD schreiben
****
if (((zeitEnde =
millis()) - zeitAnfang) < 5000){
//Wärend die Gesamtzeit von 5 min wird alle 300ms ein Wert genommen.
****zaehlerIst*++;******************************************************
//Die Anzahl der Werte wird zwecks Mittelwertbestimmung fortgeschrieben.
****drehzahlZwischenspeicher*=*drehzahlZwischenspeicher*+*drehzahl;
****drehzahlMittelwert*=*0;
****timerMittelwert*=*0;
****
delay(300);
**}
**
if (((zeitEnde =
millis()) - zeitAnfang) >= 5000){
//Ist die Gesamtzeit erreicht, wird der Mittelwert berechnet und die Zähler wieder genullt
****drehzahlMittelwert*=*(drehzahlZwischenspeicher*/*zaehlerIst);
****zaehlerIst*=*0;
****drehzahlZwischenspeicher*=*0;
****timerMittelwert*=*1;
**}
}
Lesezeichen