Zitat:
//-------------------------------------------------------------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;
**}
}