// Anzahl Spalten des Display (20)
#define LCD_WIDTH 20
// Anzahl Zeilen des Display (4)
#define LCD_HEIGHT 4
// Pin für Reed-Kontakt, Digital-2 für Interrupt 0
#define REEDPIN 2
// Hardware-Interrupt für den Reed-Pin
#define REEDINTERRUPT 0
// Umfang in mm wurde im Windkanal mit dem Volkswindmesser ermittelt als Referenz
#define RADUMFANG 2200
// LED Balken
#define led05 11 // LED connected to digital pin 11
#define led10 10 // LED connected to digital pin 10
#define led15 9 // LED connected to digital pin 9
#define led20 8 // LED connected to digital pin 8
#define led25 7 // LED connected to digital pin 7
#define led30 6 // LED connected to digital pin 6
#define ledalarm 13 // LED ALARM
#define resetmaxpin 4 // reset max Pin (button)
#define resetalarmpin 5 // reset Alarm Pin (button)
#include <Wire.h>
#include <LiquidCrystal_I2C.h> //NewLiquidCrystal - https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads/
LiquidCrystal_I2C lcd(0x27,20,4); // (LCD2004) Set the LCD I2C address
//LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Addr, En, Rw, Rs, d4, d5, d6, d7, backlighpin, polarity
void setup()
{
lcd.init(); // initialize the lcd
//lcd.begin(20,4);
lcd.clear();
lcd.backlight();
lcd.begin(LCD_WIDTH, LCD_HEIGHT); // initialize the lcd
lcd.setCursor ( 0, 0 ); // erste Zeile mit Alarm
lcd.print ("Res 1Max 2Alarm A:");
lcd.setCursor ( 0, 1 ); // zweite Zeile
lcd.print (" Andre s Anemometer ");
//Switch on the backlight
//pinMode ( BACKLIGHT_PIN, OUTPUT );
//digitalWrite ( BACKLIGHT_PIN, HIGH );
pinMode(REEDPIN, INPUT_PULLUP); // Reedkontakt direkt und ohne Widerstand angeschlossen
attachInterrupt(REEDINTERRUPT, reedISR, FALLING);
Serial.begin(115200);
pinMode(led05, OUTPUT);
pinMode(led10, OUTPUT);
pinMode(led15, OUTPUT);
pinMode(led20, OUTPUT);
pinMode(led25, OUTPUT);
pinMode(led30, OUTPUT);
pinMode(resetmaxpin, INPUT_PULLUP); // Resetmax Taster direkt und ohne Widerstand angeschlossen (gegen ground)
pinMode(resetalarmpin, INPUT_PULLUP); // Resetalarm Taster direkt und ohne Widerstand angeschlossen (gegen ground)
}
float ms2; //globale Variable Speed in m/s
float msmax = 0; //Maximalwert
unsigned long umin; // U/min
int alarm; // Alarmgrenze in m/s (meter/sekunde)
volatile byte reedCountSum;
volatile long reedMillisSum;
unsigned long lastReedMillis;
void reedISR()
{
if (millis()-lastReedMillis>=5) // 25ms entspricht max. 40 Umdrehungen pro Sekunde (bei Volkswindmesser reichen 2ms Entprellzeit aus)
{
reedCountSum++; // eine Radumdrehung zählen
reedMillisSum+=millis()-lastReedMillis; // Zeit addieren
lastReedMillis=millis(); // Zeit merken
}
}
unsigned long gesamtUmdrehungen = 0; //4545300;
void tachoAnzeige()
{
byte umdrehungen;
unsigned long zeit;
float kph, kilometer, ms;
char buffer[10];
noInterrupts(); // Interrupts sperren
umdrehungen=reedCountSum;// Zählvariable umkopieren
reedCountSum=0; // Zählvariable auf 0 zurücksetzen
zeit=reedMillisSum; // Zeitzähler umkopieren
reedMillisSum=0; // Zeitzähler auf 0 zurücksetzen
interrupts(); // Interrupts wieder zulassen
gesamtUmdrehungen+= umdrehungen; // Aufsummieren aller Radumdrehungen
kilometer=(float)gesamtUmdrehungen*(float)RADUMFANG/1000000.0; // Kilometerzähler
if (umdrehungen>0){
kph=float(RADUMFANG)*(float)umdrehungen/(float)zeit*3.6;
ms=float(RADUMFANG)*(float)umdrehungen/(float)zeit;
umin=umdrehungen*60000/zeit; }
else {
kph=0.0; //Null setzen wenn keine Umdrehung gefunden wurde
umin = 0; } //Null setzen wenn keine Umdrehung gefunden wurde
// ms = kph/3.6; //aus km/h mach m/s - kmh/3.6
ms2 = ms; //variable ms in ms2 global kopieren
//LCD Ausgabe -- Kilometerzähler hier deaktiviert
//lcd.setCursor(0, 2);
//dtostrf(kilometer,8,3,buffer);
//lcd.print(buffer);
//Serial.println(buffer);
//lcd.print(" km MAX:");
//dtostrf(msmax,4,1,buffer);
//lcd.print(buffer);
// Serial.println(buffer);
//LCD Ausgabe -- U/min und Maximalwert
lcd.setCursor(0, 2);
sprintf(buffer,"%4i U/min ",umin); // mit Nullen - sprintf(buffer,"%04i U/min ",umin); 4-Stellen Lagerichtig :-).
lcd.print(buffer);
dtostrf(msmax,5,2,buffer); // Insgesamt 5 Stellen 12.45 (Dezimalpunkt ist auch eine Stelle)
lcd.print(buffer);
lcd.print(" Mkm");
//LCD Ausgabe -- km/h
lcd.setCursor(0, 3);
dtostrf(kph,5,1,buffer);
lcd.print(buffer);
// Serial.println(buffer);
lcd.setCursor(5, 3);
lcd.print(" km/h ");
//LCD Ausgabe -- m/s
dtostrf(ms,5,2,buffer);
lcd.print(buffer);
// Serial.println(buffer);
lcd.setCursor(16, 3);
lcd.print(" m/s");
//maximalwert speichern
//Km/h anzeigen
if (ms2*3.6 > msmax) {
msmax = ms2*3.6; }
// Serial.println(msmax);
//umin 0 setzen wenn ms2 0 ist.
// if (ms2 == 0.0) {
// umin = 0; }
//Serial.println(gesamtUmdrehungen);
//LED Balken Ansteuerung
if (kph >= 5) {
digitalWrite(led05, HIGH); }
else {
digitalWrite(led05, LOW); }
if (kph >= 10) {
digitalWrite(led10, HIGH); }
else {
digitalWrite(led10, LOW); }
if (kph >= 15) {
digitalWrite(led15, HIGH); }
else {
digitalWrite(led15, LOW); }
if (kph >= 20) {
digitalWrite(led20, HIGH); }
else {
digitalWrite(led20, LOW); }
if (kph >= 25) {
digitalWrite(led25, HIGH); }
else {
digitalWrite(led25, LOW); }
if (kph >= 30) {
digitalWrite(led30, HIGH); }
else {
digitalWrite(led30, LOW); }
}
unsigned long interval; // update LCD/LED interval (milliseconds)
unsigned long previousMillis = 0;
unsigned long intervalalarm = 200; // update Alarm Anzeige interval (milliseconds)
unsigned long previousMillisalarm = 0;
unsigned long currentMillis;
int potpin = 0; // analog pin used to connect the potentiometer
int val; // variable to read the value from the analog pin
void loop()
{
//Auswerteintervall nach Drehzahl anpassen
if (ms2 < 1) {
interval = 4000; }
if (ms2 >= 1 && ms2 < 2) {
interval = 2100; }
if (ms2 >= 2 && ms2 < 3) {
interval = 1100; }
if (ms2 >= 3 && ms2 < 4) {
interval = 800; }
if (ms2 >= 4 && ms2 < 6 ) {
interval = 600; }
if (ms2 > 6) {
interval = 400; }
// Anzeige wird nach dem eingestellten inteval aktualisiert
currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
tachoAnzeige();
previousMillis = currentMillis;
}
// Alaramzeige wird nach dem eingestellten interval aktualisiert
if (currentMillis - previousMillisalarm >= intervalalarm)
{
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
alarm = map(val, 0, 1023, 0, 30); // scalieren der Potistellung (0-30m/s)
lcd.setCursor(18, 0);
if(alarm < 10) lcd.print("0"); // ein leerzeichen oder auch Zahl Nullf(zahl <10) print(" "); // ein leerzeichen oder auch Zahl Null
lcd.print(alarm);
//Alarm LED einschalten wenn Wind > Alarmwert
if (ms2 > alarm) {
digitalWrite(ledalarm, HIGH);
lcd.setCursor(0, 1);
lcd.print("**** A L A R M !****"); }
previousMillisalarm = currentMillis;
}
// Alarm LED zurücksetzen wenn Wind >5ms oder resetbutton gedrückt wird
// if (ms2 < 2 && digitalRead(ledalarm) == HIGH || digitalRead(resetmaxpin) == LOW)
if (digitalRead(resetalarmpin) == LOW) {
digitalWrite(ledalarm, LOW);
lcd.setCursor(0, 1);
lcd.print (" Andre s Anemometer ");
}
//Unterdrückung der ersten 10 Umdrehungen oder reset Button gedrückt zum resetten der Maximalwertes
if (gesamtUmdrehungen < 10 || digitalRead(resetmaxpin) == LOW ) {
msmax = 0; }
//gesamtUmdrehungen resetten bevor Display überlauf
if (gesamtUmdrehungen > 4545430) {
gesamtUmdrehungen = 0; }
}
//char buffer[7];
//sprintf(buffer,"%4imA",zahl);
//print buffer;
//mit Nullen
//char buffer[7];
//sprintf(buffer,"%04imA",zahl);
//print buffer;