3 Tasten: Einen Wert einstellen und im EEPROM ablegen

Um einen Kalibrationswert oder ähnliches einzustellen und im EEPROM abzulegen kann man 3 Tasten nehmen.

Die erste Taste unterbricht das Programm per Interrupt und geht in das Menu.

Die zwei anderen Tasten verändern den Wert. Eine Taste für kleiner und die andere für größer.

Danach verlässt die Interrupt Taste das Menu wieder und der Wert wird im EEPROM abgelegt.

Hier ein Beispielprogramm.

Die Interrupt Taste liegt an D2 mit internem pull up Widerstand und gegen Masse. Ich verwende hier den Arduino Nano, ein Arduino Uno geht aber genau so. > Die Beschreibung

  pinMode(2, INPUT);       // Pin 2 ist INT0
  digitalWrite(2, HIGH);   // interner Pull up Widerstand auf 5V
  attachInterrupt(0, interruptRoutine, LOW);

Die beiden hoch / runter Tasten liegen an A0 und A1, wie hier beschrieben.

  pinMode(A0,INPUT);          // Taste 0 hoch  
  digitalWrite(A0,HIGH);      // interner pullup Widerstand
  pinMode(A1,INPUT);          // Taste 1 runter
  digitalWrite(A1,HIGH);

Die Interrupt Routine schaltet den Wert cal um zwischen 0 und 1. Der CAL Modus (cal=1) wird mit der LED13 angezeigt.

void interruptRoutine() {
  if((millis() - alteZeit) > entprellZeit) { 
    // innerhalb der entprellZeit nichts machen
    digitalWrite(LED, !digitalRead(LED)); // LED umschalten
    alteZeit = millis(); // letzte Schaltzeit merken 
    cal = !cal; // Einstellmodus wechseln   
  }
}

Die eepromReadInt() und eepromWriteInt() Routinen werden aus diesem Artikel verwendet.

Eine zusätzliche LED an Pin6 mit Vorwiderstand wird über PWM in der Helligkeit geregelt zwischen 0 und 250 in 25er Schritten. Wenn der CAL Modus verlassen wird, soll der Wert im EEPROM abgelegt werden.

  if(cal==1) { 
    if(readButton(0)) hell+=25; // heller
    if(readButton(1)) hell-=25; // dunkler
    if(hell > 250) hell=250;    // die obere Grenze
    if(hell < 0) hell=0;        // die untere Grenze
    speichern=1; // Wert verändert, bei verlassen der cal > speichern
  }
  if(speichern==1) {            // Wert soll gespeichert werden
    eepromWriteInt(caladr, hell);
    speichern=0;                // Wert wurde gespeichert
  }

Beim Programmstart wird der letzte Wert aus dem EEPROM gelesen und verwendet. Beim allerersten Programmstart sollte die Zeile kommentiert werden, damit erst einmal ein Wert abgelegt werden kann.

hell=eepromReadInt(caladr); // Startwert aus dem EEPROM lesen

Und hier nun das komplette Programm

// Tasten zum Einstellen eines Wertes, der im EEPROM abgelegt wird
//
// Matthias Busse Version 1.0 vom 28.10.2014

#include < EEPROM.h>
int LED=13, lampe=6, hell=130, caladr=1, speichern=0;
volatile unsigned long alteZeit=0, entprellZeit=20, cal=0;

void setup() {
  Serial.begin(38400);
  pinMode(LED, OUTPUT);    // LED Pin
  pinMode(2, INPUT);       // Pin 2 ist INT0
  digitalWrite(2, HIGH);   // interner Pull up Widerstand auf 5V
  attachInterrupt(0, interruptRoutine, LOW);
  // Pin 2 (INT 0) geht auf LOW (0V) dann interruptRoutine aufrufen
  pinMode(A0,INPUT);          // Taste 0 hoch  
  digitalWrite(A0,HIGH);      // interner pullup Widerstand
  pinMode(A1,INPUT);          // Taste 1 runter
  digitalWrite(A1,HIGH);
  hell=eepromReadInt(caladr); // Startwert aus dem EEPROM lesen
}

void loop() {
  if(cal==1) { 
    if(readButton(0)) hell+=25; // heller
    if(readButton(1)) hell-=25; // dunkler
    if(hell > 250) hell=250;    // die obere Grenze
    if(hell < 0) hell=0;        // die untere Grenze
    speichern=1; // Wert verändert, bei verlassen der cal > speichern
  }
  if(speichern==1) {            // Wert soll gespeichert werden
    eepromWriteInt(caladr, hell);
    speichern=0;                // Wert wurde gespeichert
  }
  analogWrite(lampe, hell);
  Serial.println(hell);
  delay(100); 
}

int readButton(int pin) {     // Taste einlesen
  if(analogRead(pin) < 500) { // Analog Eingang abfragen
    delay(entprellZeit);            
    if(analogRead(pin) < 500)
      return 1;               // war gedrückt
  }
  return 0;                   // war nicht gedrückt
}

void interruptRoutine() {
  if((millis() - alteZeit) > entprellZeit) { 
    // innerhalb der entprellZeit nichts machen
    digitalWrite(LED, !digitalRead(LED)); // LED umschalten
    alteZeit = millis(); // letzte Schaltzeit merken 
    cal = !cal; // Einstellmodus wechseln   
  }
}

int eepromReadInt(int adr) {  
// Integer aus dem EEPROM lesen
byte low, high;
  low=EEPROM.read(adr);
  high=EEPROM.read(adr+1);
  return low + ((high << 8)&0xFF00);
} //eepromReadInt

void eepromWriteInt(int adr, int wert) {
// Integer in das EEPROM schreiben
byte low, high;
  low=wert&0xFF;
  high=(wert >> 8)&0xFF;
  EEPROM.write(adr, low); // dauert 3,3ms
  EEPROM.write(adr+1, high);
  return;
} //eepromWriteInt

Die Hardware

Arduino Uno oder Nano
Taste 1 an D2 und Masse
Taste 2 an A0 und Masse
Taste 3 an A1 und Masse
D6 an einen Vorwiderstand und über die LED an Masse

Interrupt Cal Menue

Die Berechnung des Vorwiderstandes
R = (5V – LED Spannungsabfall) / LED Strom

Ein Beispiel bei 1,4V Spannungsabfall von 5V und mit 20mA LED Strom
R = 3,6V / 0,02A = 180 Ohm

Ein Tip

Die beiden Tasten können im Programm weiter verwendet werden, wenn sie bei cal==0 abgefragt werden.

von Matthias Busse

11 Gedanken zu „3 Tasten: Einen Wert einstellen und im EEPROM ablegen

  1. Max Katzberg

    Hallo Matthias Busse
    Leider lässt sich der Sketch mit den 3 Tasten und speichern
    im EEPROM nicht kompilieren ?
    Viele Grüsse Max Katzberg

    Antworten
  2. Max Katzberg

    Ich habe noch eine Frage
    kann ich dieses Programm oder andere kleine z.B. in einen Attiny 85 laden ?
    Viele Grüsse Max aus Moers

    Antworten
    1. admin Beitragsautor

      Das habe ich nie ausprobiert und kann nicht sagen ob es da eine Möglichkeit gibt. Ist auch noch zu Überprüfen ob das dann alles kompatibel ist.
      Matthias

      Antworten
      1. Uwe

        Mit einigen kleineren Änderungen kannst Du das Programm im ATtiny45 und 85 betreiben:
        #include

        int LED=1, LED2=0, hell=130, caladr=1, speichern=0;
        //LED1(grün) ist Kontrolle, dass Programmierung eingeschaltet ist
        //LED2 (rot), diese wird programmiert
        volatile unsigned long alteZeit=0, entprellZeit=20, cal=0;

        void setup() {
        pinMode(LED, OUTPUT); // LED Pin
        pinMode(2, INPUT); // Pin 2 ist INT0
        digitalWrite(2, HIGH); // interner Pull up Widerstand auf 5V
        attachInterrupt(0, interruptRoutine, LOW);
        // Pin 2 (INT 0) geht auf LOW (0V) dann interruptRoutine aufrufen
        pinMode(3,INPUT); // Taste 0 hoch
        digitalWrite(3,HIGH); // interner pullup Widerstand
        pinMode(4,INPUT); // Taste 1 runter
        digitalWrite(4,HIGH);
        hell=eepromReadInt(caladr); // Startwert aus dem EEPROM lesen
        }

        void loop() {
        if(cal==1) {
        if(readButton(2)) hell+=25; // heller, PB3
        if(readButton(3)) hell-=25; // dunkler, PB4
        if(hell > 255) hell=255; // die obere Grenze
        if(hell speichern
        }
        if(speichern==1) { // Wert soll gespeichert werden
        eepromWriteInt(caladr, hell);
        speichern=0; // Wert wurde gespeichert
        }
        analogWrite(LED2, hell);
        delay(100);
        }

        int readButton(int pin) { // Taste einlesen
        if(analogRead(pin) < 500) { // Analog Eingang abfragen
        delay(entprellZeit);
        if(analogRead(pin) entprellZeit) {
        // innerhalb der entprellZeit nichts machen
        digitalWrite(LED, !digitalRead(LED)); // LED umschalten
        alteZeit = millis(); // letzte Schaltzeit merken
        cal = !cal; // Einstellmodus wechseln
        }
        }

        int eepromReadInt(int adr) {
        // Integer aus dem EEPROM lesen
        byte low, high;
        low=EEPROM.read(adr);
        high=EEPROM.read(adr+1);
        return low + ((high <> 8)&0xFF;
        EEPROM.write(adr, low); // dauert 3,3ms
        EEPROM.write(adr+1, high);
        return;
        } //eepromWriteInt

        Antworten
  3. Martin

    Hallo mal eine allgemeine frage ist es möglich eine drei stellige zahl die ich über Serial eingebe auch also solche im EEPROM zu speichern bei mir speichert es da immer nur die letzte zahl ab

    Hier mein Testcode

    #include void setup() { int t = EEPROM.read(0); Serial.begin(9600); while (!Serial){} Serial.println("EEPROM Test"); Serial.print("Wert im EEPROM :"); Serial.println(t); } void loop() { if(Serial.available() > 0) { int wert = (Serial.read()- '0'); Serial.print(wert); EEPROM.write(0,wert); } }

    Antworten
  4. Fritze Friemel

    Hallo,
    ich habe heute auf der Suche nach einer ähnlichen Lösung diese Version entdeckt. Funktioniert auch gut.
    Leider aber nur an der Kombination A0/A1, die anderen analogen Pins reagieren nicht. Sind aber in Ordnung, wie ich mit anderen Sensoren feststellen kann.
    Hat jemand eine Idee, woran das liegen könnte? Eingesetzt wird ein UNO-R3-Clone (Elegoo).
    Danke im voraus!

    Antworten
  5. Bernhard

    Mit dem Beispiel dürfte man sich recht schnell das EEPROM totschreiben. Besser ist es, nur nach Verlassen des Cal-Modus den Schreibvorgang auszulösen:
    if (cal==1) {
    ….
    speichern=1; // Wert verändert, bei verlassen der cal > speichern
    }
    if (speichern==1 && cal==0) {
    // erst nach Beendigung des CAL-Modus 1x ins EEPROM schreiben
    }

    Alternativ mit while (cal==1), dann sieht man aber die Veränderung bei der LED nicht mehr (oder fügt analogWrite noch in die while-Schleife hinzu).

    Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.