Pages: 1 [2] 3   Go Down
Author Topic: Probleme eines Anfängers :)  (Read 4040 times)
0 Members and 1 Guest are viewing this topic.
AREA COLOGNE
Offline Offline
Edison Member
*
Karma: 21
Posts: 1128
I am 1 of 10 who understands binary
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!
Logged

So ist das Leben:
Manchmal bis du das Denkmal, manchmal die Taube!

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 266
Posts: 21657
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 smiley-sweat ....
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

Logged

Germany
Offline Offline
Edison Member
*
Karma: 47
Posts: 2321
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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?  smiley-lol
Mein Vorredner hats ja schon als Beispiel gebracht.
Logged

Mein Arduino-Blog: http://www.sth77.de/ - letzte Einträge: Teensy 3.0 - Teensyduino unter Window 7 - Teensyduino unter Windows 8

Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

des stimmt ... hmm

ok ich gebe zu mein problem ist ich bin zu doof/unerfahren smiley-sad

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 ....


Code:
#include <LiquidCrystal.h>
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;
  }
}
Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 266
Posts: 21657
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok ich gebe zu mein problem ist ich bin zu doof/unerfahren smiley-sad

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

Quote from: 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 ....

Code:
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
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hallo uwe

danke für deine schnelle und ausführliche antwort ....

ich werde mal schauen ob ich da etwas lese stoff zu finde und mich dann mal dran versuchen smiley


so nu ist es spät hab mir einiges übers entprellen und vergleichen durchgelesen und hab mich jetzt glaube ich mal total verklammert wobei ich dachte das ich auf dem richtigen weg bin .....

Code:
#include <LiquidCrystal.h>
float tempC = 0;     // variable for holding Celcius temp (floating for decimal points precision)
float samples[8];    // array to hold 8 samples for Average temp calculation
int tempPin = 0;     // Temperatursensor LM35 an Analogpin 0
int i;
int ButtonDown = 8;       // Taster an Digitalpin 8
int backLight = 13;       // pin 13 schaltet die hintergrundbeleuchtung
int page;
int buttonVal = 0;        // wert des Tasters
int buttonValprell = 0;   // entprellt den Taster
int buttonstatus;

  // 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(){
   buttonVal = digitalRead(ButtonDown);  // Taster auslesen
   delay(10);  // 10 Millisekunden warten
   buttonValprell = digitalRead(ButtonDown);  // nochmal Taster auslesen
   if (buttonVal == buttonValprell)  // wenn gleich dann schwingt nichts mehr
 {
   if(buttenVal != buttonstatus)  // veränderung des Tasters abfragen
 {
    if (ButtonVal == 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 ind");
          break;
  }
}
« Last Edit: November 30, 2011, 05:14:10 pm by Ice-Man » Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 266
Posts: 21657
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Du mußt buttonstatus irgendwo, bei jedem Zustandswechsel den Status des buttonVal geben
Grüße Uwe
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

so nachdem ich meine tippfehler und verklammerungen entfernt habe läuft mein code wieder und er nimmt jeden einzelnen tastendruck wenn ich den taster gedrückt halte zählt er trozdem nur einen druck 1a :

 if (ButtonVal == HIGH)
    page = (page+1)%3; // Dreiseitiges Menue. '%' ('modulo') sorgt dafuer dass nach '2' wieder '0' kommt...
 }
{
 buttonstatus = buttonVal;    
}
  switch (page) {


ABER .....

in Case1  bleibt er trozdem noch wegen dem delay(1000); hängen

wenn ich es entferne flackert mein display wie hulle und die stelle nach dem komma ist nichtmehr erkennbar

wie bekomme ich es gelöst das er troz meinem wait von einer sekunde sauber durch die cases switcht ????
« Last Edit: December 01, 2011, 07:49:56 am by Ice-Man » Logged

NRW
Offline Offline
Sr. Member
****
Karma: 2
Posts: 372
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mach im case eine millis-Abfrage
if(currentMillis - previousMillis > interval) {
und in der IF schreibst du den Wert neu.
dadurch kannst du delay weg lassen, er aktualisiert dann immer nur wenn zb eine Sekunde um ist

Schau dir dazu mal blink without delay an
http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

okay also ....

ähm .... das klingt sehr gut nur irrgedwie will bei mir der funke net überspringen ...

bzw. ich verstehe das prinzip das program arbeitet weiterhin das ganze program ab und überprüft einfach nur ob es schon an der zeit ist meinen wert im case 1 neu auszugeben

nur ich hab noch ein dickes fragezeichen zur umsetzung ....

Code:
   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);
        }


das würde doch dann heißen das ich in meinem gesammten code niergendwo ein delay nutzen darf .... da ich noch eine rtc uhr mit einbinden will und andere kleinigkeiten müsste ich ja für jedes delay einen interval schreiben oder kann ich den mehrmals verwenden ohne ihn jedesmal neu zu schreiben????
« Last Edit: December 01, 2011, 09:11:20 am by Ice-Man » Logged

Munich/Germany
Offline Offline
God Member
*****
Karma: 11
Posts: 643
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Du brauchst Dir nicht mal die Zeit merken
Code:
   case 1:                  //zweite Seite
              if ((millis() % 1000) == 0){             
                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");
              }
        }
So aktualisiert sich das Display nur, wenn millis() einem vielfachen von 1000 entspricht, also 1x pro Sekunde.
Logged

_______
Manfred

Weinsberg, Germany
Offline Offline
God Member
*****
Karma: 3
Posts: 773
A Coder's Tale
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Nicht gut! Wenn er zu der entsprechenden Millisekunde nicht an der Stelle ist wird das Display nicht aktualisiert.

Würde mir auch einfach den letzten Wert merken (also die Sekunde) und wenn der aktuelle davon abweicht das Display refreshen und den neuen Wert merken.

Ungefähr was in der Richtung:
Code:
  int lastSecond;
...
  if (lastSecond != millis()/1000) {
    lastSecond = millis()/1000;
    ... // Update Display
  }
« Last Edit: December 01, 2011, 09:40:38 am by Joghurt » Logged

NRW
Offline Offline
Sr. Member
****
Karma: 2
Posts: 372
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Du kannst trotzdem weiterhin delays verwenden solltest es aber wo es geht vermeiden!
Du kannst hin gehen und deine Fühler ja abfragen lassen wenn du magst aber nur das Display im sekundentakt aktualisieren.
Du kannst eine oldmillis-Variable für alle Screens verwenden da ja immer nur einer angezeigt wird.
Wenn du aber die RTC auch darüber abfragen willst musst du eine neue Variable nehmen.

Du kannst, du kannst hihi

Code:
long previousMillis = 0;        // will store last time LED was updated
long interval = 1000;           // interval at which to blink (milliseconds)


Code:
unsigned long currentMillis = millis();

case 1:                  //zweite Seite
  if(currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;
              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);
        }

}
So werden wenn ich mich nicht irre jede Sekunde die temps ausgelesen und angezeigt.
Logged

Munich/Germany
Offline Offline
God Member
*****
Karma: 11
Posts: 643
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Nicht gut! Wenn er zu der entsprechenden Millisekunde nicht an der Stelle ist wird das Display nicht aktualisiert.
Ich hab mir schon gedacht, dass der Einwand kommt. Ich hab es extra aussen vor gelassen, weil ich wissen wollte, wer es als Erster bemängelt  smiley-twist

Ich würde den ganzen switch/case Block für die Anzeige in eine Funktion auslagern (nennen wir sie mal Ausgabe()).
für die sekündliche Anzeige erfolgt dann der Aufruf so:
Code:
  if ((millis() % 1000) == 0)
    Anzeige();
Und beim Seitenwechsel aufgrund eines Buttondrucks wird Anzeige() einfach zusätzlich aufgerufen.
Dass dabei unter Umständen die Anzeige zweimal kurz nacheinander aktualisiert wird ist ja egal.
Logged

_______
Manfred

Offline Offline
Newbie
*
Karma: 0
Posts: 22
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

nun hab ich das mit dem interval usw. richtig verstanden und kann es auch anwenden smiley ich hätte nicht gedacht das es für ein problem 10 verschiedene lösungswege gibt ... unglaublich

so alles in allem funktioniert nun das switch case und auc die saubere ausgabe meiner temperatur ginial

ihr seit der hammer .... smiley

bekomm ich eigendlich auch probleme wenn ich delay ausserhalb der switch case anweisung verwende???

und

kann ich meine prozesse auch ausserhalb der cases bearbeiten so das ich im case nur noch print befehle nutze?

Logged

Pages: 1 [2] 3   Go Up
Jump to: