Probleme eines Anfängers :)

Hallo zusammen,

habe mich grade erst hier angemeldet und habe auch erst vor wenigen wochen mit der Arduino begonnen zu arbeiten

vorher habe ich die AtMegas mit Bascom geärgert ;)

Da mir aber Bascom + Hardware zu teuer war und auch einige projekte in Bascom zu aufwändig wurden wollte ich mall so versuchen.

Nunja ich habe mir auch schon ein paar bücher zum thema besorgt und gelesen aber im moment stehe ich auf dem schlauch.

ich möchte gerne auf tastendruck unterschiedliche werte ausgegeben haben

beispiel: Uhrzeit - Temperatur - Wasserstand - usw

Jedesmal wenn der taster gedrückt wird soll er einen weiter springen.

meine idee war jetzt das ganze mit einem counter der jedesmal eins hochzählt und dann mit swich case ??

hier mal mein code ... ist net viel weil bin mir grade sehr unsicher . =(

#include 

int Button = 8;

int backLight = 13;    // pin 13 schaltet die hintergrundbeleuchtung

// Connections:
// rs (LCD pin 4) to Arduino pin 12
// rw (LCD pin 5) to Arduino pin 11
// enable (LCD pin 6) to Arduino pin 10
// LCD pin 15 to Arduino pin 13
// LCD pins d4, d5, d6, d7 to Arduino pins 5, 4, 3, 2
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);

void setup()
  {
    pinMode(ButtonDown, INPUT); 
    pinMode(backLight, OUTPUT);
    digitalWrite(ButtonDown, LOW);  
    digitalWrite(backLight, HIGH);  //LCD Licht an
    lcd.begin(16,2);              
    lcd.clear();                 
    lcd.setCursor(0,0);           
    lcd.print("Wetterstation");    
    lcd.setCursor(0,1);           
    lcd.print("Version 1.0");
  }

void loop()

Also ich arbeite bei "Displaymenüs" immer mit switchcase. In dem Switchcase hinterlegt du dann die einzelnen Seiten. Du kannst dann innerhalb der Siwtchcases dann deine Displayausgabe gestalten und außerhalb der Cases die Werte verarbeiten. Wie du deine Displayseiten umschaltest ist ja dann dir überlassen :-)

hmm das klingt schonmal sehr gut ...

hast du auch zufällig ein code schnipsel aus dem ich sowas ableiten kann??

...mal eben auf die schnelle.

Ice-Man: pinMode(ButtonDown, INPUT); digitalWrite(ButtonDown, LOW);

Du initialisierst ButtonDown als Input und schreibst dann ein LOW auf diesen Pin. Das geht nicht. Es gibt an jedem Pin nur einen internen Pullup, den man mit digitalWrite(ButtonDown, HIGH) aktivieren könnte. Einen Pulldown gibt es nicht und dementsprechend auch nicht die oben genutzte Aktivierung.

danke für den tip ... ABER ... das löst mein grundsätzliches problem noch net :(

ich weis nicht wie ich jetzt einen counter initialisiere und durch cases switch ....

sprich tastendruck

case1

tastendruck

case2

tastendruck

case3

tastendruck

zurück zu case 1

  int page;
...
  if (digitalRead(BUTTONPIN) == TRUE)
    page = (page+1)%3; // Dreiseitiges Menue. '%' ('modulo') sorgt dafuer dass nach '2' wieder '0' kommt...

  switch (page) {
    case 0:
      // erste Seite...
    break;
    case 1:
      // zweite Seite...
    break;
    case 2:
      // dritte Seite...
    break;
  }

Was in der Gegend.

also brauch ich garkeinen counter ??

Der counter ist in dem Fall "page".

Die Variable page ist doch der Zähler. Oder willst du auf etwas anderes hinaus?

[edit] Ja ja, zu langsam... ;)

Hier mal ein Schnipsel einer Uhr die die Zeit in klarem Text auf ein Diplay zeigt und entsprechenden Seiten zum Stellen der einzelenen Sachen (die RTC Funktionen habe ich nicht mitkopiert) Main Loop

void loop() {
  tempist=get_TEMP();                           // einlesen Temperatur Istwert
  T1Read=digitalRead(Taster1);                  // Taster 1
  T2Read=digitalRead(Taster2);                  // Taster 2
  ssIn=digitalRead(RTCPuls);
  digitalWrite(13,ssIn);
  if (T1Read==false&<1Read==true){  // Taster muss gedrückt sein und darf vorher nicht gedrückt sein
    LT1Read=false;                    // Hilfmerker zum einmal ausführen
    setmode=setmode++;                // Erhöhen des Setmode zum Stellen 1=Std 2=Minuten 3=Tag 4=Monat 5=Jahr 0=Normalbetrieb
    Buttonmillis=millis();
    kopieren=false;
    lcd.clear();
    if (setmode>=7){
      lcd.clear();
      setmode=0;
      run=true;
    }  
  }
  if (T1Read==true&<1Read==false){
    LT1Read=true;
  }
  if (T2Read==false&<2Read==true&&setmode>0){   // Taster muss gedrückt sein und darf vorher nicht gedrückt sein
    LT2Read=false;                                // Hilfmerker zum einmal ausführen
    Wert=Wert++;                                  // Erhöhen des Setmode 1=Std 2=Minuten 3=Tag 4=Monat 5=Jahr 0=Normalbetrieb
    Buttonmillis=millis();  
  }
  if (T2Read==true&<2Read==false){
    LT2Read=true;
  }
  if (millis()-Buttonmillis>=7500&&setmode>0){      // Rücksetzen nach 7,5 Sekunden
    setmode=0;
    run=true;  
  }
  if (ssIn==true&&lssIn==false){
    ++ss; 
    if (DR==true){
      DateRead(); 
      DR=false;
    }
    if (ss==60){
      ss=0;
      mm=mm+1;
    }
    if (mm>=60){                                    //=> dann hier weiter (zählen) der Sekunden/Minuten/Stunden
      mm=0;
      hh=hh++;
      oncehh=false;
    }
    if (hh>=24){
      hh=0;
      DR=true;
    }
    lssIn=true; 
  }
  if (ssIn==false&&lssIn==true){
    lssIn=false;
  }

  switch (setmode){
  case 0:
    lcd.setCursor(0,0);
    lcd.print("ES IST "); // Bis Position 6,0
    lcd.setCursor(7,0);
    if (mm!=lmm || run==true){
      hh=HourRead();                                // RTC Funktion lesen der aktuellen zeit Stunden
      mm=MinuteRead();                              // RTC Funktion lesen der aktuellen zeit Minuten
      ss=SecondRead();                              // RTC Funktion lesen der aktuellen zeit Sekunden  
     check=true;
      lcd.clear();
      lcd.setCursor(7,0);
      MinutetoText(mm);
      HourtoText(hh);
      //  DatetoText
      lcd.setCursor(0,1);
      lcd.print("AM ");
      WeekdaytoText(WTag);
      printDate2();
      lmm=mm;
      run=false;
    }
    printTemp(31,0,tempist);
    break;
  case 1:
    if (kopieren==false){                                    // Einmaliges Kopieren des Istwertes in den Encoderarbeitswert nach aufruf dieses Setmodes
      Wert=hh;                                               // Schreiben des Istwertes in den Arbeitswert
      kopieren=true;                                         // Merker setzten zum einmaligen ausführen
    }
    if(hh!=Wert){                                         // Wenn der Stundewert über den Encoder verändert wurde 
      if (Wert>=24){                                      // Abfang überlauf nach oben größer 23 Uhr
        Wert=0;
      }
      hh=Wert;                                            // Schreiben des Arbeitswertes in den neuen Istwert
      RTC_Set_Time();                                     // Schreiben der neuern Werte in die RTC
    }
    lcd.setCursor(0,0);
    lcd.print("STELLEN STUNDEN                         ");
    break;
  case 2:
    if (kopieren==false){                                    // Einmaliges Kopieren ders Istwertes in den Encoderarbeitswert nach aufruf dieses Setmodes
      Wert=mm;                                            // Schreiben des Istwertes in den Arbeitswert
      kopieren=true;                                         // Merker setzten zum einmaligen ausführen
    }
    if(mm!=Wert){                                         // Wenn der Stundewert über den Encoder verändert wurde 
      if (Wert>=60){                                      // Abfang überlauf nach oben größer 23 Uhr
        Wert=0;
      }
    }
    mm=Wert;                                            // Schreiben des Arbeitswertes in den neuen Istwert
    RTC_Set_Time();
    lcd.setCursor(0,0);
    lcd.print("STELLEN MINUTEN                        ");
    break;
  case 3:
    if (kopieren==false){                                    // Einmaliges Kopieren ders Istwertes in den Encoderarbeitswert nach aufruf dieses Setmodes
      Wert=Tag;                                            // Schreiben des Istwertes in den Arbeitswert
      kopieren=true;                                         // Merker setzten zum einmaligen ausführen
    }
    if(Tag!=Wert){                                         // Wenn der Stundewert über den Encoder verändert wurde 
      if (Wert>31){                                      // Abfang überlauf nach oben größer 23 Uhr
        Wert=1;
      }
    }
    Tag=Wert;           
    RTC_Set_Date();    
    lcd.setCursor(0,0);
    lcd.print("STELLEN TAG                            ");
    break;
  case 4:
    if (kopieren==false){                                    // Einmaliges Kopieren ders Istwertes in den Encoderarbeitswert nach aufruf dieses Setmodes
      Wert=Monat;                                            // Schreiben des Istwertes in den Arbeitswert
      kopieren=true;                                         // Merker setzten zum einmaligen ausführen
    }
    if(Monat!=Wert){                                         // Wenn der Stundewert über den Encoder verändert wurde 
      if (Wert>12){                                      // Abfang überlauf nach oben größer 23 Uhr
        Wert=1;
      }
    }
    Monat=Wert;
    RTC_Set_Date();
    lcd.setCursor(0,0);
    lcd.print("STELLEN MONAT                          ");
    break;
  case 5:
    if (kopieren==false){                                    // Einmaliges Kopieren ders Istwertes in den Encoderarbeitswert nach aufruf dieses Setmodes
      Wert=Jahr;                                            // Schreiben des Istwertes in den Arbeitswert
      kopieren=true;                                         // Merker setzten zum einmaligen ausführen
    }
    if(Jahr!=Wert){                                         // Wenn der Stundewert über den Encoder verändert wurde 
      if (Wert>2019){                                      // Abfang überlauf nach oben größer 23 Uhr
        Wert=2011;
      }

    }
    Jahr=Wert;
    RTC_Set_Date();
    lcd.setCursor(0,0);
    lcd.print("STELLEN JAHR                           ");
    break;  
  case 6:
    if (kopieren==false){                                    // Einmaliges Kopieren ders Istwertes in den Encoderarbeitswert nach aufruf dieses Setmodes
      Wert=WTag;                                            // Schreiben des Istwertes in den Arbeitswert
      kopieren=true;                                         // Merker setzten zum einmaligen ausführen
    }
    if(WTag!=Wert){                                         // Wenn der Stundewert über den Encoder verändert wurde 
      lcd.clear();
      if (Wert>7){                                        // Abfang überlauf nach oben größer 23 Uhr
        Wert=1;
      }
    }
    WTag=Wert;
    RTC_Set_Date();
    lcd.setCursor(0,0);
    lcd.print("STELLEN WOCHENTAG  ");
    lcd.print(Name[Pointer]);
    lcd.print(" NOCH ");
    lcd.print(RestTage);
    lcd.print(" TAGE ");
    break;  

  }
  if (setmode>=1){
    printTime(0,1);
    printDate(9,1);
    WeekdaytoText(WTag);
  }
  if (test==true){

  }
  checkBday();
}

Die Funktionen dazu

[code]
void MinutetoText(int m){
  if (m >=5&&m<10){
    lcd.print(MinArray[2]);    // fuenf
    lcd.print(MinArray[1]);    // nach
  }
  if (m >=10&&m<15){
    lcd.print(MinArray[3]);    // zehn
    lcd.print(MinArray[1]);    // nach
  }
  if (m >=15&&m<20){
    lcd.print(MinArray[4]);    // viertel
    lcd.print(MinArray[1]);    // nach
  }
  if (m >=20&&m<25){
    lcd.print(MinArray[5]);    // zwanzig
    lcd.print(MinArray[1]);    // nach
  }
  if (m >=25&&m<30){
    lcd.print(MinArray[2]);    // fuenf
    lcd.print(MinArray[0]);    // vor
    lcd.print(MinArray[6]);    // halb
  }
  if (m >=30&&m<35){
    lcd.print(MinArray[6]);    // halb
  }
  if (m >=35&&m<40){
    lcd.print(MinArray[2]);    // fuenf
    lcd.print(MinArray[1]);    // nach
    lcd.print(MinArray[6]);    // halb
  }
  if (m >=40&&m<45){
    lcd.print(MinArray[5]);    // zwanzig
    lcd.print(MinArray[0]);    // vor
  }
  if (m >=45&&m<50){
    lcd.print(MinArray[4]);    // viertel
    lcd.print(MinArray[0]);    // vor
  }
  if (m >=50&&m<55){
    lcd.print(MinArray[3]);    // zehn
    lcd.print(MinArray[0]);    // nach
  }
  if (m >=55&&m<=59){
    lcd.print(MinArray[2]);    // fuenf
    lcd.print(MinArray[0]);    // vor
  }
}

void HourtoText(int h){
  if (h>12){
    h=h-12;
  }
  if (h==0){
    h=h+12;
  }
  if (mm>=25){
    if (h==12){
      lcd.print(StdArray[0]);
    }
    else
      lcd.print(StdArray[h]);
  }
  else{
    lcd.print(StdArray[h-1]);
  }
  if (mm<5){
    lcd.print(" UHR");
  }  
}

void WeekdaytoText(int d){
  lcd.print(TagArray[d-1]);
  if(setmode==0){
    lcd.print(" DEN ");
  }
}

void printDate2(){
  if (Tag<10){
    lcd.print("0");
  }
  lcd.print(Tag);
  lcd.print(".");
  if(Monat<10){
    lcd.print("0");
  }
  lcd.print(Monat);
  lcd.print(".");
  lcd.print(Jahr);
  lcd.print(" ");
}

void printTime(int x,int y){
  lcd.setCursor(x, y);
  if (hh<10){
    lcd.print("0");
  }
  lcd.print(hh);
  lcd.print(":");
  if(mm<10){
    lcd.print("0");
  }
  lcd.print(mm);
  lcd.print(":");
  if (ss<10){
    lcd.print("0");
  }
  lcd.print(ss);
}

void printDate(int x,int y){
  lcd.setCursor(x, y);
  if (Tag<10){
    lcd.print("0");
  }
  lcd.print(Tag);
  lcd.print(".");
  if(Monat<10){
    lcd.print("0");
  }
  lcd.print(Monat);
  lcd.print(".");
  lcd.print(Jahr);
  lcd.print(" ");
}

void printTemp(int x,int y, int z){
  int First; 
  int Last;
  lcd.setCursor(x,y);
  Last=z%10;
  First=(z-Last)/10;
  lcd.print(First);
  lcd.print(".");
  lcd.print(Last);
  lcd.print(" Grad");

}

int get_TEMP(){                               // Funktion Einlesen Lambda
  long TEMPY;
  long TEMPX;
  long TEMPact;
  long TEMPdis;
  TEMPact=analogRead(temp);                  // Einlesen des Lambdaistwertes
  TEMPX=TEMPact*10*0.2;                        // Filter neuer Lesewert mit 20% pro Zyklus
  TEMPY=TEMPlast*10*0.8;
  TEMPdis=(TEMPX+TEMPY)/10;
  TEMPlast=TEMPdis;
  return TEMPdis;
}


void checkBday(){
  for (int i=0;i<=4;i++){
    TempTag=Datum[i]%100;
    TempMon=(Datum[i]-TempTag)/100;  
    if ((TempMon-Monat)==0&&check==true){ 
      RestTage=TempTag-Tag;
      if (RestTage<=14&&RestTage>=1){
        Pointer=i;
        check=false;  
      }
    }
  }
}

[/code]

ich danke euch für eure hilfe ....

werde mich dann gleich mal an die arbeit machen und meinen erfolg dann die tage verkünden ausser es gibt noch fragen bzw. probleme dann hört ihr früher von mir :)

gruß

ice-man

Hallo, also der Code ist aber extrem lang um ein Uhrmodul zu stellen oder die Uhrzeit anzuzeigen. Anzeigen geht z.B. auch so (jede Sekunde einmal): Angezeigt wird Datum und Uhrzeit im Format: 29.11.11 20:12:12

RTC.get(UhrDaten,true);
 if(UhrMomentanzeit - UhrStartzeit > 1000){
  lcd.setCursor(0,0); 
  sprintf (puffer, "%02d.%02d.%02d", UhrDaten[4],UhrDaten[5],UhrDaten[6]);  // %02d sind Platzhalter: int mit zwei Ziffern und führender Null ausgeben
  lcd.print(puffer); lcd.print(" ");
  sprintf (puffer, "%02d:%02d:%02d", UhrDaten[2],UhrDaten[1],UhrDaten[0]);  
  lcd.print(puffer);

und stellen geht auch wesentlich einfacher. gruß Bernward

Lieber maverick Die Uhr schreibt alles in Buchstaben aus deswegen ist die Sache auch etwas komplizierter

also:
Es ist zwanzig vor sieben
am Dienstag den 29.11.2011

Und den Geburtag der hinterlegten zeigt diese auch an mit 14 Tage vorlauf .
Also nicht einfach so Zahlen anzeigen. Ausserdem sollte das Stellen dann auch komfortabel sein wenn man schon mal ein 40*2 Display hat
also oben in der Zeile steht was man gearde stellen kann und unten sieht man das.

eine wort uhr will ich mir auch gerne mal basteln aber da fehlt mir noch jede menge erfahrung :)

ich hab nochmal ne frage jetzt hab ich meine switch case anweisung und ich muss sagen es läuft :)

ABER :astonished:

wenn das program nachher mehr aufgaben hat z.b. ein rtc mudul dran hängt u.s.w. würde es ja "ewig" dauern bis das die schleife wieder an der tasten abfrage vorbei kommt

ich weis das ich mein problem mit debounce und nem interrupt in den griff bekomme ABER

das mit dem interrupt habe ich im bascom nichtmal richtig verstanden :sweat_smile: ....

hättet ihr da vielleicht noch ein paar zeilen code oder eine seite mit einem möglichst verständlichem tutorial ??

bin um jede hilfe dankbar

mfg Ice-Man

Ich glaube du unterschätz den Atemga in Sachen speed. Ich habe eine Nixiuhr mit einer 4 Schieberegister und eine Multiplex schaltung ingestam 11k Code und ich habe ein Zykluszeit von 1-1,2ms das heist die Loop wir 800-1000 pro Sekunde ausgeführt!

Ice-Man: ich weis das ich mein problem mit debounce und nem interrupt in den griff bekomme ABER das mit dem interrupt habe ich im bascom nichtmal richtig verstanden :sweat_smile: ....

Das mit dem Interrupt ist einfach. Bei einem Interrupt wird der abgearbeitet Kode unterbrochen und ein Interruptprogramm abgearbeitet. Nach Beendigung des Interruptprogramms wird das unterbrochene Programm an der unterbrochenen Stelle weiter abgearbeitet. Ein Interrupt kann von verschiedenen Ereignissen ausgelöst werden: Extern an Pins 2 und 3, durch Timer und Counter und anderes mehr. Es gibt einige Dinge zu beachten. http://arduino.cc/en/Reference/AttachInterrupt http://arduino.cc/en/Reference/Interrupts Grüße Uwe

Ich vertrete ja die Meinung, dass händische Eingaben in den seltensten Fällen einen Interrupt erfordern. Meist ist das dann einem schlechten Programmierstil geschuldet. Denkst du wirklich, du könntest einen Mikrocontroller, der mit 16 MHz getaktet ist mit einer RTC überfordern? XD Mein Vorredner hats ja schon als Beispiel gebracht.

des stimmt ... hmm

ok ich gebe zu mein problem ist ich bin zu doof/unerfahren :(

wenn ich jetzt in den cases switchen will bleibt er in case 1 bei der temperatur hängen und bekomme ihn dort nicht mehr wech .... dachte jetzt bint einer interrupt routine könne ich das problem lösen aber vllt kannst du mir einen anderen weg zeigen und mir ein paar tipps geben.

Am ende soll es eigendlich eine wetterstation ergeben die aus 2 atmegas besteht die via funk miteinander komunizieren sollen draussen werden temperatur, luftdruck, windgeschwindigkeit, windrichtung usw ermittelt und an die arduino drinnen gesendet die diese sachen erstmal auf einem 16x2lcd ausgeben soll und später auf nem glcd 128x64.

hier mal mein code bitte net lachen vermute mal das es im groben ganz großer bock mist ist aber es ist mein erstes projekt mit einem arduino ....

#include 
float tempC = 0;  // variable for holding Celcius temp (floating for decimal points precision)
float tempf = 0;  // variable for holding Fareghneit temp
int tempPin = 0;  // Declaring the Analog input to be 0 (A0) of Arduino board.
float samples[8]; // array to hold 8 samples for Average temp calculation
float maxi = 0,mini = 100; // max/min temperature variables with initial values. LM35 in simple setup only measures Temp above 0.
int i;
int ButtonDown = 8;
int backLight = 13;    // pin 13 schaltet die hintergrundbeleuchtung
int page;

  // Connections:
  // rs (LCD pin 4) to Arduino pin 12
  // rw (LCD pin 5) to Arduino pin 11
  // enable (LCD pin 6) to Arduino pin 10
  // LCD pin 15 to Arduino pin 13
  // LCD pins d4, d5, d6, d7 to Arduino pins 5, 4, 3, 2
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);

void setup()
  {
    pinMode(ButtonDown, INPUT); 
    pinMode(backLight, OUTPUT);
    digitalWrite(ButtonDown, LOW);  
    digitalWrite(backLight, HIGH);  //LCD Licht an
    lcd.begin(16,2);              
    lcd.clear();                 
    lcd.setCursor(0,0);           
    lcd.print("Wetterstation");    
    lcd.setCursor(0,1);           
    lcd.print("Version 1.0");
    delay(2000);                  //Wartet 2 Sekunden
    lcd.clear(); 
  }

void loop(){

  if (digitalRead(ButtonDown) == HIGH)
    page = (page+1)%3; // Dreiseitiges Menue. '%' ('modulo') sorgt dafuer dass nach '2' wieder '0' kommt...

  switch (page) {
    case 0:                    // erste Seite
              lcd.setCursor(0,0);           
              lcd.print("Case0");    
              lcd.setCursor(0,1);           
              lcd.print("Zeit Datum");
          break;
    case 1:                  //zweite Seite
              
              for(i = 0;i<=7;i++){ // gets 8 samples of temperature
              samples[i] = ( 4.4 * analogRead(tempPin) * 100.0) / 1024.0;
              lcd.clear();           
              lcd.setCursor(0, 0); // set LCD cursor position
              lcd.print("Innen: "); // print to LCD
              lcd.setCursor(12, 0); 
              lcd.print(samples[i]);  // print current Temp sample to LCD
              lcd.setCursor(0,1);           
              lcd.print("Aussen:");
              lcd.setCursor(12, 1);
              lcd.print("N/A");
              delay(1000);
            
          
        }
          break;
    case 2:                // dritte Seite
              lcd.setCursor(0,0);           
              lcd.print("Case2");    
              lcd.setCursor(0,1);           
              lcd.print("Luft Wind");
          break;
  }
}

Ice-Man: ok ich gebe zu mein problem ist ich bin zu doof/unerfahren :(

Das "doof" gefällt mir nicht. Bin für "unerfahren".

Ice-Man: wenn ich jetzt in den cases switchen will bleibt er in case 1 bei der temperatur hängen und bekomme ihn dort nicht mehr wech ....

 if (digitalRead(ButtonDown) == HIGH)

Wiederholt sich solange Du den Taster drückst. Da Du ein langes Delay in der Temperaturausgabe hast arbeitest Du die verschiedenen case durch bis Du in der Temperaturausgabe hängen bleibst

Gib mal die Variable "page" über die Seriele Schnittstelle an das Terminal im IDE aus. Da wirst Du es sehen.

Wenn Du willst daß bei jedem Tastendruck die Zahl um 1 erhöt wird dann brauchst Du eine andere Programmierlogik. Du mußt zuerst kontrollieren ob eine Taste gedrückt ist und dann ob sie losgelassen wurde um dann zu wissen daß die Variable zu erhöhen ist oder nicht. Außerdem mußt Du den Taster entprellen.

Viele Grüße Uwe