[gelöst] int hochstellen(mini, maxi);

Hallo,
um mein Programm etwas zu kürzen, möchte ich folgendes in einer int zusammenfassen:

int hochY(int mini, int maxi){
   int var=0;
   if(analogRead(Y_pin)>800){
   var++;  
   if(var>maxi){
    var=mini; }
   delay(100);
   lcd.clear();
   return var; }}

Eine Variable soll, wenn der Joystick bewegt wird, geändert werden, und wenn sie einen maximalen Wert erreicht hat, den Minimalwert einnehmen, sodass ich immer z.B. zwischen 1,2,3,1,2,3,1,2,3 wechseln kann.
Das Ganze soll mit mehren, verschiedenen Variablen funktionieren, d.h. dass ich den Bildschirm wechseln kann
( ort=hochY(1,3); ), aber auch die Zeit einstellen ( minute=hochX(0,59); ). Doch wie kann ich den Wert einer Variable “importieren”, dass “var” nicht 0, sondern “minute” entspricht?

Hier noch ein Teil des Gesamte Programms, falls es hilft. Das Meiste musste ich rauskürzen, weil die Nachricht zu lang war :frowning:

#include"Wire.h"
#define DS3231_I2C_ADDRESS 0x68
#include<DHT.h>
#define DHTPIN 2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
#include<LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);

const int SW_pin = 12; 
const int X_pin  = A0; 
const int Y_pin  = A1; 

int xAchse=0;   
int yAchse=0;

int cnt=0;
int cnt2=0;
int cnt3=0;
int cntA=0;
int ort=1;
int menu=1;   
int taster=0;    
int NN3=1;   

int h=0;
int m=0;
int s=0;
int dy=0;
int mon=0;
int yr=0;

int hw=0;
int mw=0;
int sw=0;
int tRun=0;

int Alarm=0;
  
float a=7.5;
float b=237.3; 
float c=6.1078;

void setup() {
 Serial.begin(9600);
 dht.begin();
 lcd.init();
 Wire.begin();
 lcd.clear();
 lcd.backlight();
 pinMode(22,OUTPUT);
 pinMode(SW_pin, INPUT_PULLUP);
  }

  
byte decToBcd(byte val){
  return((val/10*16)+(val%10));
  }

byte bcdToDec(byte val){
  return((val/16*10)+(val%16));
  }

void zweistellig(int Zweistellig, int Spalte, int Zeile){
  if (Zweistellig<10){
  lcd.setCursor(Spalte, Zeile);
  lcd.print("0");
  lcd.setCursor(Spalte+1,Zeile);
  }
  else{
  lcd.setCursor(Spalte,Zeile); 
  }
  lcd.print(Zweistellig);
}

void zweistelligA(int Zweistellig, int Spalte, int Zeile){
  zweistellig(Zweistellig, Spalte, Zeile);
  lcd.setCursor(Spalte+2,Zeile);
  lcd.print(":");
}

void zweistelligB(int Zweistellig, int Spalte, int Zeile){
  zweistellig(Zweistellig, Spalte, Zeile);
  lcd.setCursor(Spalte+2,Zeile);
  lcd.print(".");
}

void setDS3231time(byte second, byte minute,byte hour,byte dayOfWeek, byte dayOfMonth,byte month,byte year){
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0);
  Wire.write(decToBcd(second));
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));
  Wire.write(decToBcd(dayOfWeek));
  Wire.write(decToBcd(dayOfMonth));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.endTransmission();
}

void readDS3231time(byte *second, byte *minute,byte *hour,byte *dayOfWeek, byte *dayOfMonth,byte *month,byte *year){
   Wire.beginTransmission(DS3231_I2C_ADDRESS);
   Wire.write(0);
   Wire.endTransmission();
   Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
   *second = bcdToDec(Wire.read() & 0x7f);
   *minute = bcdToDec(Wire.read());
   *hour = bcdToDec(Wire.read() & 0x3f);
   *dayOfWeek = bcdToDec(Wire.read());
   *dayOfMonth = bcdToDec(Wire.read());
   *month = bcdToDec(Wire.read());
   *year = bcdToDec(Wire.read());
}

void displayTime(){
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  int Stunde=hour;
  int Minute=minute;
  int Sekunde=second;
  int Monat=month;
  int Tag=dayOfMonth;
  int Jahr=year;
  lcd.setCursor(0,0);
  lcd.print("------");
  zweistelligA(hour,6,0); 
  zweistelligA(minute,9,0);
  zweistellig(second,12,0);
  lcd.print(" ");
  lcd.setCursor(14,0);
  lcd.print("------");
  zweistelligB(dayOfMonth,10,1);
  zweistelligB(month,13,1);
  lcd.print("20");
  zweistellig(year,18,1);

  if(tRun==1){
    lcd.setCursor(0,3);
    lcd.print("Wecken um");
    zweistelligA(hw,10,3);
    zweistelligA(mw,13,3);
    zweistellig(sw,16,3);

  if(hw==Stunde&&mw==Minute&&sw==Sekunde&&tRun==1) {
    digitalWrite(22,HIGH);
    Alarm=1;
    tRun=0;
    cntA=0;
    lcd.setCursor(0,3);
    lcd.print("                    ");  }}}

void blinken(int namevar, int nameval, int cntvar, int cnttime, const char *text, int col, int line){
  lcd.setCursor(col,line);
  if(namevar==nameval&&cntvar%cnttime<cnttime/2){
      lcd.print("  "); }
    else{
      lcd.print(text); }}

int hochY(int mini, int maxi){
   int var=0;
   if(analogRead(Y_pin)>800){
   var++;  
   if(var>maxi){
    var=mini; }
    return var;
    delay(100);
    lcd.clear(); }}

void loop() {
cnt++;
xAchse=analogRead(X_pin);
yAchse=analogRead(Y_pin);

if(taster==0) {  

  ort=hochY(1, 3);
 
   if(yAchse<200){
  ort--;
  if(ort<1){  
  ort=3; } 
  lcd.clear();
  delay(100); }      

 if(ort==3){

  if(xAchse>800){
  menu++;
  if(menu>2){
  menu=1; }
  lcd.clear();
  delay(100);}
    
   if(xAchse<200){
  menu--;
  if (menu<1){
  menu=2; }
  lcd.clear();
  delay(100); }}}                                   //..................................

if(digitalRead(SW_pin)==LOW&&ort==3){                         //Taster Wert ändern
  if (taster==1){
  taster=0; }
  else{
  taster=1; }
  delay(100); 
  lcd.clear(); }

switch (ort){
    
  case 1:
   displayTime();
   menu=1;
  break;

  case 2:
   menu=1;
   if(cnt%5==0){
   lcd.setCursor(0,0);
   lcd.print("Temperatur    "+String(dht.readTemperature())+"C");
   lcd.setCursor(0,1);
   lcd.print("Feuchtigkeit  "+String(dht.readHumidity())+"%");
   lcd.setCursor(0,3);
   float DD=dht.readHumidity()/100*(c*pow(10,((a*dht.readTemperature())/(b+dht.readTemperature()))));
   float v=log10(DD/6.1078);
   float TD=b*v/(a-v);
   lcd.print("Taupunkt: "+String(TD)+"\337C"); }
  break;

  case 3:
   if(taster==0) {
   NN3=1;
   lcd.setCursor(0,0);
   lcd.print("Einstellungen");
   lcd.setCursor(0,1);
  
   switch (menu){
    case 1:
     lcd.print("Zeit anpassen");
    break;
    
    case 2: 
     lcd.print("Weckzeit setzen");
    break;
    }}
  break; }

delay(70);
}

jonas_xd:
Doch wie kann ich den Wert einer Variable "importieren", dass "var" nicht 0, sondern "minute" entspricht?

Bin mir nicht sicher, ob ich Deine Frage richtig verstehe, aber ich versuche mal eine Antwort: Du übergibst zusätzlich die Variable an die Funktion.

int hochY(int mini, int maxi, int var) {
  if (analogRead(Y_pin) > 800) {
    var++;
    if (var > maxi) {
      var = mini;
    }
    return var;
    delay(100);
    lcd.clear();
  }
}

...

ort = hochY(1, 3, ort);

...

minute = hochX(0, 59, minute);

...

Das delay (100); sollte wohl vor das return, damit die Hochzähl-Geschwindigkeit kontrollierbar ist.

Auch lcd.clear(); wird wohl nie erreicht :frowning:

jonas_xd:
Eine Variable soll, wenn der Joystick bewegt wird, geändert werden,

Das macht Dein Code nicht.
Der Fehler ist, das var seinen Inhalt verliert, wenn Du die Funktion verlässt.
Wenn das behoben ist, würde Dein Code unabhängig davon ob der Joy bewegt wurde hochzählen, solange Du eine bestimmte Position überfahren hast.
Mal als Denkanstoß:

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
}
void loop()
{
  static int last = 0;
  int jetzt = hochY(2, 6);
  if (last != jetzt)
  {
    Serial.println(jetzt);
    last = jetzt;
  }
}
int hochY(const int mini, const int maxi) // Da die nicht verändert werden, wirds const.
{
  const int Y_pin = A0;
  static int var = 0;
  if (var<mini) var=mini;
  static bool over = false;
  int obererPunkt = 800;
  int untererPunkt = 600;

  if (analogRead(Y_pin) > obererPunkt)
  {
    var++;
    over = true;
    if (var > maxi) {
      var = mini;
    }
    if (analogRead(Y_pin) < untererPunkt) {
      over = false;
    }
  }
  return var;
}

my_xy_projekt:
Das macht Dein Code nicht.

doch, macht er.

my_xy_projekt:
Der Fehler ist, das var seinen Inhalt verliert, wenn Du die Funktion verlässt.

Das ist auch so gewollt, dass var seinen Wert verliert, da er nicht mehr benötigt wird nachdem dieser mit return zurückgegeben wurde.

static int var = 0;

hilft hier nicht, da die Funktion nicht nur für eine Variable verwendet werden soll.

gruß lorenz

corvus_:
doch, macht er.Das ist auch so gewollt, dass var seinen Wert verliert, da er nicht mehr benötigt wird nachdem dieser mit return zurückgegeben wurde.

Dann wird var NIE größer als 1
Der Rückgabewert ist also nur 0 oder 1.

static int var = 0;

hilft hier nicht, da die Funktion nicht nur für eine Variable verwendet werden soll.

Dann muss das auch so kommuniziert werden.
Hat der TO nicht.
Er hat nur geschrieben, das er diesen Aufbau für mehrere Variablen will - Das eine Mehrfachverwendung der Funktion vorgesehen ist nicht.

Dann mit Übergabe:

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
}
void loop()
{
  static int last = 0;
  int jetzt = hochY(2, 6, last);
  if (last != jetzt)
  {
    Serial.println(jetzt);
    last = jetzt;
  }
}
int hochY(const int mini, const int maxi, int wert)
{
  const int Y_pin = A0;
  if (wert<mini) wert=mini;
  static bool over = false;
  int obererPunkt = 800;
  int untererPunkt = 600;

  if (analogRead(Y_pin) > obererPunkt)
  {
    wert++;
    over = true;
    if (wert > maxi) {
      wert = mini;
    }
    if (analogRead(Y_pin) < untererPunkt) {
      over = false;
    }
  }
  return wert;
}

Eine Möglichkeit wäre noch var als Referenz zu übergeben. Dann Wird var direkt geändert.

int hochY(int &var, const int mini, const int maxi) { //mit const ist es der bessere Stil 
  if (analogRead(Y_pin) > 800) {
    if (++var > maxi) var = mini; //ist kürzer
    delay(100); // Ohne Änderung würde ich auf delay verzichten
    lcd.clear(); //das gleiche gilt für lcd.clear()
  }
  return var; //zwar nicht mehr notwendig, aber evtl. nice to have 
}

Das ermöglicht dann den direkten Aufruf ohne Zuweisungsoperator z.B.:

hochY(ort,1, 3);
hochY(minute,0,59);

gruß lorenz

corvus_:
Eine Möglichkeit wäre noch var als Referenz zu übergeben. Dann Wird var direkt geändert.

int hochY(int &var, const int mini, const int maxi) { //mit const ist es der bessere Stil 

if (analogRead(Y_pin) > 800) {
    if (++var > maxi) var = mini; //ist kürzer

[code]hochY(ort,1, 3);
[/quote]
Auch schick.
Es findet keine Überprüfung stattfindet, wenn var < mini übergeben wird.
Die Zeile sollte mit rein, wenn der Rückgabewert mindestens mini erwartet wird.

my_xy_projekt:
Dann wird var NIE größer als 1
Der Rückgabewert ist also nur 0 oder 1.

Das war seine Frage.

my_xy_projekt:
Dann muss das auch so kommuniziert werden.
Hat der TO nicht.
Er hat nur geschrieben, das er diesen Aufbau für mehrere Variablen will - Das eine Mehrfachverwendung der Funktion vorgesehen ist nicht.

Doch hat er:

jonas_xd:
Das Ganze soll mit mehren, verschiedenen Variablen funktionieren, d.h. dass ich den Bildschirm wechseln kann
( ort=hochY(1,3); ), aber auch die Zeit einstellen ( minute=hochX(0,59); ).

In seinen genannten Beispielen hat er für minute und ort die selbe Funktion aufgerufen.
Weiterhin ergibt es keinen Sinn var zu verwenden. Wenn man genausogut eine globale variable direkt nutzen könnte. Von der fehlenden Sinhaftigkeit der Implementierung einer eigenen Funktion für jede Variable (die aber alle das gleiche tun) ganz zu schweigen.
gruß lorenz

corvus_:
In seinen genannten Beispielen hat er für minute und ort die selbe Funktion aufgerufen.

Nein!

( ort=hochY(1,3); ), aber auch die Zeit einstellen ( minute=hochX(0,59); ).

Sonst wär ich nicht auf die Idee gekommen das zwischenzuspeichern.

my_xy_projekt:
Es findet keine Überprüfung stattfindet, wenn var < mini übergeben wird.
Die Zeile sollte mit rein, wenn der Rückgabewert mindestens mini erwartet wird.

Guter Hinweis, danke!

my_xy_projekt:
Nein!

( ort=hochY(1,3); ), aber auch die Zeit einstellen ( minute=hochX(0,59); ).

Sonst wär ich nicht auf die Idee gekommen das zwischenzuspeichern.

Mein Fehler, sorry! Danke fürs hervorheben!

Gut, dann muss bei der Funktion auch noch der PIN übergeben werden, damit man die ansonsten gleiche Funktion nicht mehrfach implementieren muss.

gruß lorenz
und sorry nochmal :slight_smile:

wartet bitte mal kurz

corvus_:
Gut, dann muss bei der Funktion auch noch der PIN übergeben werden, damit man die ansonsten gleiche Funktion nicht mehrfach implementieren muss.

Nö. Warum?
Das was der TO hier machen will, ist den Joy als Taster verwenden.
Taster oben auf, Taster unten ab.
Darum auch mein Kniff darauf zu bauen, das die Stellung wieder zurück kommt, um dann den nächsten Zähler auszulösen, wenn Wert wieder überstiegen.

uns sorry nochmal :slight_smile:

schon gut...

@jonas_xd ... jau

@my_xy_projekt
Ja, war mein Fehler, ich möchte schon z.B. minute, Stunde, Tag etc. mit hochY umschalten.

@corvus
die Variable wird immer wieder auf 0 gesetzt

War jetzt nur die Antwort auf die neuesten Sachen, komm nämlich nicht nach mit Antorten, weil ich nur alle 5 min posten kann

my_xy_projekt:
Nö. Warum?
Das was der TO hier machen will, ist den Joy als Taster verwenden.
Taster oben auf, Taster unten ab.
Darum auch mein Kniff darauf zu bauen, das die Stellung wieder zurück kommt, um dann den nächsten Zähler auszulösen, wenn Wert wieder überstiegen.

Wenn dann aber noch eine Weitere Funktion zum dekrementieren des Zählers eingebaut werden soll funktioniert das ganze mit static nicht mehr, da diese mit static dann einen eigenen Zähler hätte mit einem anderen Wert.

gruß lorenz

my_xy_projekt:

Mein Code hat nen Klammerproblem.
Ich bin eine Ebene zutief fürs reseten der Statusvariablen.
Richtig in der Variante mit eigener Zählung:

  if (analogRead(Y_pin) > obererPunkt)
  {
    var++;
    over = true;
    if (var > maxi)
    {
      var = mini;
    }
  }
  if (analogRead(Y_pin) < untererPunkt) 
  {
    over = false;
  }
  return var;
}

Sorry…

Funktioniert aber leider nur einmal...

jonas_xd:
Ja, war mein Fehler, ich möchte schon z.B. minute, Stunde, Tag etc. mit hochY umschalten.

Also so:

int minute;
void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
}

void loop()
{
  static int lastminute = 0;
  minute = joy(0, 59, minute);
  if (lastminute != minute)
  {
    Serial.println(minute);
    lastminute = minute;
  }
}

int joy(const int mini, const int maxi, int wert)
{
  const int Y_pinhoch = A0;
  static bool over = false;
  int obererPunkt = 800;
  int untererPunkt = 600;

// Es wird bei jeder Bewegung eins gezählt und darauf gwartet das der Hebel wieder zurück kommt
if ((analogRead(Y_pinhoch) > obererPunkt) && (over==false))
  {
    wert++;
    over = true;
  }
  if (wert < mini) wert = maxi;
  if (wert > maxi) wert = mini;
  if (analogRead(Y_pinhoch) < untererPunkt)
  {
    over = false;
  }
  return wert;
}

Variante 2 zählt solange hoch wie der Hebel gehalten wird:

int minute;
void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
}

void loop()
{
  static int lastminute = 0;
  minute = joy(0, 59, minute);
  if (lastminute != minute)
  {
    Serial.println(minute);
    lastminute = minute;
  }
}

int joy(const int mini, const int maxi, int wert)
{
  const int Y_pinhoch = A0;
  static unsigned long lastmillis;
  int obererPunkt = 800;
  int untererPunkt = 600;

  // Wenn bei jeder Bewegung gezählt werden soll:
  if ((analogRead(Y_pinhoch) > obererPunkt) && (millis() - lastmillis > 100))
  {
    wert++;
    lastmillis = millis();
  }
  if (wert < mini) wert = maxi;
  if (wert > maxi) wert = mini;
  return wert;
}

Gegenfrage:
Benutzt der Joy nur einen Analogpin für die Werterfassung oder für jede Richtung einen eigenen?

X-Achse an A0, y-Achse an A1