Guten Abend,
eigentlich wollte ich ursprünglich ja anhand von Temperatur, Feuchte, ... verschiedene Dinge steuern. Irgendwie bin ich jetzt aber auf das Wetter gestoßen und möchte einen reinen Datenlogger mit dem Arduino bauen.
Der Datenlogger soll auf einer großen Wiese installiert werden und dort verschiedene Wetterparameter erfassen. Dazu noch den Pegel eines Bachs. Zu solch einer Wetterstation gehört ja auch ein gescheites Menü. Da ich vielleicht auch direkt an der Wetterstation etwas an den Einstellung ändern möchte (Messrate, ...) experimentiere ich damit, wie man mit dem Encoder Einstellungen ändern kann.
So sieht mein (zusammenkopierter) Sketch aus:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Encoder.h>
LiquidCrystal_I2C lcd (0x27, 20, 4);
Encoder myEnc (3, 5);
int menue, encoderPos, oldEncoderPos, ergebnis, value, oldEncoderPosMenue, first;
int measure = 41;
int averaging = 10;
int menues = 2;
int Cursor = -1;
long counter;
float humidity, aIN[5];
void setup () {
Serial.begin(9600);
rtc.begin(DateTime(__DATE__, __TIME__));
lcd.init();
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print(F("Wetter Datalogger"));
lcd.setCursor(0, 1);
lcd.print(F("Param: OK"));
lcd.setCursor(0, 2);
lcd.print(F("Starting"));
for (int i = 0; i < 6; i++){
delay(1000);
lcd.print(F("."));
}
lcd.clear();
// Pin-Modes
pinMode(4, INPUT);
pinMode(A0, INPUT);
}
void loop()
{
readMenuePos();
switch(menue){
case 0: if (editParam() == true){
if (Cursor == 0) measure = ergebnis * 10 + measure % 10;
if (Cursor == 1) if (ergebnis != 0) ergebnis = ergebnis - 1; measure = measure + ergebnis;
Cursor++;
counter = 0;
first = 0;
//oldEncoderPos = 0;
//Encoder myEnc (3, 5);
//encoderPos = 0;
ergebnis = 0;
}
lcd.setCursor(0, 0);
lcd.print(F("+ Logger V1.1"));
lcd.setCursor(0, 1);
lcd.print(F("Sprache: Deutsch"));
lcd.setCursor(0, 2);
lcd.print(F("Messrate: "));
// Normaler Modus
if (Cursor == -1){
emptyZero(measure);
lcd.print(F(" sek"));
lcd.setCursor(20, 3);
lcd.print(F("Mittelung: "));
lcd.print(averaging);
lcd.print(F(" min"));
}
// Messrate erste Stelle
if (Cursor == 0){
if (first == 0){
ergebnis = measure % 100;
ergebnis = ergebnis - (ergebnis % 10);
ergebnis = ergebnis / 10;
value = ergebnis;
first = 1;
} else {
ergebnis = editValue();
}
lcd.setCursor(10, 2);
if (counter == 0 || counter > 5){
lcd.write(255);
if (counter > 10){
counter = 0;
}
} else {
lcd.print(ergebnis);
}
Serial.print(F("Neuer Wert Pos 1: "));
Serial.println(ergebnis);
counter++;
lcd.print(measure % 10);
lcd.print(F(" sek"));
lcd.setCursor(20, 3);
lcd.print(F("Mittelung: "));
lcd.print(averaging);
lcd.print(F(" min"));
}
// Messrate zweite Stelle
if (Cursor == 1){
lcd.setCursor(10, 2);
ergebnis = measure % 100;
ergebnis = ergebnis - (ergebnis % 10);
ergebnis = ergebnis / 10;
lcd.print(ergebnis);
lcd.setCursor(11, 2);
if (first == 0){
ergebnis = measure % 10;
value = ergebnis;
first = 1;
} else {
ergebnis = editValue();
}
Serial.print(F("Neuer Wert Pos 2: "));
Serial.println(ergebnis);
if (counter == 0 || counter > 5){
lcd.write(255);
if (counter > 10){
counter = 0;
}
} else {
lcd.print(ergebnis);
}
counter++;
lcd.print(F(" sek"));
lcd.setCursor(20, 3);
lcd.print(F("Mittelung: "));
lcd.print(averaging);
lcd.print(F(" min"));
}
if (Cursor == 2) Cursor = -1;
break;
case 1: meassureRoutine();
lcd.setCursor(0, 0);
lcd.print(F("rel. Feuchte"));
lcd.setCursor(0, 1);
lcd.print(F("Sensor: Haarhygro"));
lcd.setCursor(0, 2);
if (editParam() != true){
lcd.print(F("Current: "));
lcd.print(humidity, 1);
lcd.print(F(" %"));
lcd.setCursor(20, 3);
lcd.print(F("Average: "));
lcd.print(humidity, 1);
lcd.print(F(" %"));
}
if (editParam() == true){
lcd.setCursor(0, 2);
lcd.print(F("Min: "));
lcd.print(humidity, 1);
lcd.print(F(" %"));
lcd.setCursor(20, 3);
lcd.print(F("Max: "));
lcd.print(humidity, 1);
}
break;
}
}
void meassureRoutine()
{
// Hier wird normalerweise gemessen
}
void readMenuePos()
{
if (Cursor == -1){
encoderPos = myEnc.read() / 6;
if (encoderPos < oldEncoderPosMenue){
menue++;
if (menue > menues - 1){
menue = 0;
}
lcd.clear();
oldEncoderPosMenue = encoderPos;
}
if (encoderPos > oldEncoderPosMenue){
menue--;
if (menue < 0){
menue = menues - 1;
}
lcd.clear();
oldEncoderPosMenue = encoderPos;
}
}
}
boolean editParam()
{
if (digitalRead(4) == 1){
delay(500);
if (digitalRead(4) == 1){
return true;
}
}
}
void emptyZero(int number){
if (number < 10){
lcd.print(F("0"));
}
lcd.print(number);
}
int editValue()
{
encoderPos = myEnc.read() / 4;
if (encoderPos < oldEncoderPos){
value++;
if (value > 9){
value = 0;
}
oldEncoderPos = encoderPos;
}
if (encoderPos > oldEncoderPos){
value--;
if (value < 0){
value = 9;
}
oldEncoderPos = encoderPos;
}
return value;
}
Das Switchen zwischen den einzelnen "Seiten" funktioniert ganz gut.
Das Einstellen von z.B. Messrate funktioniert nur mittelmäßig. Z.B. werden manchmal die eingestellten Zahlen nicht übernommen oder wenn man gar nicht am Encoder dreht sondern nur den "Einstell-Modus" aktiviert werden die ursprünglichen Zahlen um eins verringert oder erhöht.
Das gefällt mir so nicht!! :0
Wie macht man so eine Steuerung, in der man Werte ändern kann (mit einem Encoder), professionell? Bzw. wo sind Denkfehler in meiner Steuerung?
Wäre super wenn Ihr mir mit dem "großen" Projekt helfen könntet.
Gruß,
Jan