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
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
Hallo Matthias Busse
Leider lässt sich der Sketch mit den 3 Tasten und speichern
im EEPROM nicht kompilieren ?
Viele Grüsse Max Katzberg
Hallo Max,
nimm mal in der Zeile
#include < EEPROM.h>
das Leerzeichen zwischen < und EEPROM weg, dann funktioniert es. Matthias Busse
Danke Danke so einfach ist das man muss es nur wissen
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
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
Hi
ich muss mich doch noch bedanken für die schnelle Antwort.
Vieleicht probiere ich das mal aus mit dem Attiny
Grüsse Max
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
in der 1. Zeile fehlt das
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); } }
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!
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).