ich möchte ein Zahlenschloss bauen. Die Eingabe der Zahlen soll über Taster erfolgen.
Die Taster sin üner 1 Analog Pin angeschlossen. Mein Problem ist das beim betätigen einer Taste gleich
alle Zahlen des Schloss gefüllt werden. Der Analoge Input schick zuviele Werte auf einmal.
Wie könnte ich das Problem lösen?
Sollte ich die Taster lieber an Digitalen Pins anschließen? (habe leider nur ein Arduino Uno mit 13 Pins)
Stelle Deinen Sketch hier ins Forum, damit Ihn alle sehen können. Das kannst Du auch noch nachträglich machen.
Ich hab den sketch nur mal schnell überflogen. Ich denke es fehlt eine Flankenerkennung. Nun ist das bei einem Analogwert nicht so ganz einfach. Eine q&d Lösung ein delay(200) nach den Einlesen des Analogwertes. Allerdings darfst Dann den Taster nicht länger als 200 ms gedrückt lassen.
Eigendlich müsste man wenn der Wert >100 ist ein Flag setzen , taster ist gedrückt worden. Wenn das auf H ist wird ein erneutes Einlesen gesperrt. Mit dem Flag wird dann millis() abgefragt und nach 200ms das Flag zurück gesetzt.
#include "pitches.h"
int notes[] = {262, 294, 330, 349, 392, 440, 494};
int roteLED = 12; //Die rote LED ist an Pin 12 angeschlossen
int grueneLED = 13; //Die grüne LED wird an Pin 13 angeschlossen
int P1 = 1; int P2 = 2; int P3 = 3; int P4 = 4; // Hier werden die vier Zeichen des Passwortes eingegeben Hier: "1234"
int C1, C2, C3, C4; // Unter C1 bis C4 werden im Loop die vier eingegebenen Zeichen gespeichert
int z1 = 0, z2, z3, z4; // Diese Variablen werden verwendet um für die einzelnen Zahlencodes die EIngabe freizuschalten. Damit wird im Sketch verhindert, dass eine einzene Codeziffer einer falschen Position zugeordnet wird.
int Prufen = 0;
int Taster;
int Analogwert = 0;
#define Taster1 1
#define Taster2 2
#define Taster3 3
#define Taster4 4
#define Taster5 5
#define Taster6 6
#define KeinTaster 0
int Tasterabfrage()
{
Analogwert = analogRead(A0); // Auslesen des Tastermoduls am Analogen Pin A0.
Serial.println(Analogwert); //Diese Zeile sorgt dafür, dass der ausgelesene Analogwert im seriellen Monitor angezeigt wird. Das kann sinnvoll sein, wenn das Tastenmodul mit einer anderen Spannung als 5V versorgt wird, da sich daraus andere analoge Messwerte ergeben würden. Ansonsten kann diese Zeile weggelassen werden.
if (Analogwert < 300) return KeinTaster; // Solange kein Taster gedrückt wurde, liegt der analoge Wert liegt bei 1023
if (Analogwert >= 1000 & Analogwert <= 1008) return Taster1;
if (Analogwert >= 990 & Analogwert <= 1000) return Taster2;
if (Analogwert >= 960 && Analogwert <= 985) return Taster3;
if (Analogwert >= 900 && Analogwert <= 945) return Taster4;
if (Analogwert >= 480 && Analogwert <= 520) return Taster5;
if (Analogwert >= 1010 && Analogwert <= 1023) return Taster6;
return KeinTaster; // Ausgabe wenn kein Taster gedrückt wurde.
}
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(Prufen, INPUT);
pinMode(roteLED, OUTPUT);
pinMode(grueneLED, OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
Anfang: // Dies ist eine Markierung, zu der per "goto-"Befehl gesprungen werden kann.
Taster = Tasterabfrage();
if (Taster)
{
if (digitalRead(Prufen) == LOW)
{
if (C1 == P1 && C2 == P2 && C3 == P3 && C4 == P4) //wird gepüft, ob die eingaben Codezeichen (C1 bis C4) mit den Zeichen des Passwortes (P1 bis P4) übereinstimmen. Falls der eingegebene Code richtig ist...
{
Serial.println ("Code korrekt, Schloss offen");
digitalWrite(roteLED, LOW); //..die rote LED nicht leuchten..
digitalWrite(grueneLED, HIGH); //..die grüne LED leuchten..
}
else // ist das nicht der Fall, bleibt das Schloss gesperrt
{
Serial.println ("Code falsch, Schloss gesperrt");
digitalWrite(roteLED, HIGH); // Die rote LED leuchtet
digitalWrite(grueneLED, LOW); // Die grüne LED is aus
delay(3000);
z1 = 0; z2 = 1; z3 = 1; z4 = 1; // Der Zugang für die erste Zeicheneingabe wird wieder freigeschaltet
goto Anfang; //An dieser Stelle springt der Sketch zur Eingabe der Taste zurück, damit das Zeichen "#" nicht im folgenden Abschlitt als Codeeingabe gewertet wird.
}
}
// Ab hier werden die vier Code-positionen unter den Variablen C1 bis C4 abgespeichert. Damit die eingegebenen Zeichen auch an der richtigen Position des Passwortes gespeichert werden, wird mit den Variablen z1 bis z4 der Zugang zu den einzelnen Positinen freigegeben oder gesperrt.
if (z1 == 0) // Wenn das erste Zeichen noch nicht gespeichert wurde...
{
C1 = Taster; //Unter der Variablen "C1" wird nun die aktuell gedrückte Taste gespeichert
Serial.print("Die Taste "); //Teile uns am Serial Monitor die gedrückte Taste mit
Serial.print(C1);
Serial.println(" wurde gedrueckt");
z1 = 1; z2 = 0; z3 = 1; z4 = 1; // Zugang zur zweiten Zeicheneingabe freischalten
goto Anfang;
}
if (z2 == 0) // Wenn das zweite Zeichen noch nicht gespeichert wurde...
{
C2 = Taster; //Unter der Variablen "C2" wird nun die aktuell gedrückte Taste gespeichert
Serial.print("Die Taste "); //Teile uns am Serial Monitor die gedrückte Taste mit
Serial.print(C2);
Serial.println(" wurde gedrueckt");
z1 = 1; z2 = 1; z3 = 0; z4 = 1; // Zugang zur dritten Zeicheneingabe freischalten
goto Anfang;
}
if (z3 == 0) // Wenn das dritte Zeichen noch nicht gespeichert wurde...
{
C3 = Taster; //Unter der Variablen "C3" wird nun die aktuell gedrückte Taste gespeichert
Serial.print("Die Taste "); //Teile uns am Serial Monitor die gedrückte Taste mit
Serial.print(C3);
Serial.println(" wurde gedrueckt");
z1 = 1; z2 = 1; z3 = 1; z4 = 0; // Zugang zur vierten Zeicheneingabe freischalten
goto Anfang;
}
if (z4 == 0) // Wenn das vierte Zeichen noch nicht gespeichert wurde...
{
C4 = Taster; //Unter der Variablen "C4" wird nun die aktuell gedrückte Taste gespeichert
Serial.print("Die Taste "); //Teile uns am Serial Monitor die gedrückte Taste mit
Serial.print(C4);
Serial.println(" wurde gedrueckt");
z1 = 1; z2 = 1; z3 = 1; z4 = 1; // Zugang zur weiteren Zeicheneingabe sperren
}
}
}
if (Analogwert < 300) return KeinTaster; // Solange kein Taster gedrückt wurde, liegt der analoge Wert liegt bei 1023
if (Analogwert >= 1000 & Analogwert <= 1008) return Taster1;
if (Analogwert >= 990 & Analogwert <= 1000) return Taster2;
if (Analogwert >= 960 && Analogwert <= 985) return Taster3;
if (Analogwert >= 900 && Analogwert <= 945) return Taster4;
if (Analogwert >= 480 && Analogwert <= 520) return Taster5;
if (Analogwert >= 1010 && Analogwert <= 1023) return Taster6;
return KeinTaster; // Ausgabe wenn kein Taster gedrückt wurde.
Du scheinst 6 Taster zu haben.
Du verwendest nur einen kleinen Bereich des Analogwertes. Du hast 5 Taster innerhalb 10% des Analogbereiches (zwischen 1023 und 900).
Verwende ein R2R Netzwerk für eine bessere Aufteilung.
Du mußt wie gesagt eine Flankenerkennung programmieren. Du kannst Auch schuen ob die Taste wieder losgelassen wurde bevr ein neuer Tastendruck gültig ist.
Ich habe meine Schaltung nach so einem R2R Netzwerk aufgebaut. Alle Taster werden über 1 Pin ausgelesen,
und haben unterschiedliche Widerstände.
Kann mir bitte jemand Informationen für die Flankenprogrammierung geben?
Bzw. wie von Uwe beschrieben, die Erkennung ob die Taste bereits losgelassen wurde?
äh.
Was ich übersehen hatte: Beim R2R Netzwerk braucht es Wechsler und keine normalen Schließer. Taster sind meist nur Schließer. Sie schließen den Kontakt bei Betätigung.
Grüße Uwe
christian_der_bastler:
Ich habe meine Schaltung nach so einem R2R Netzwerk aufgebaut. Alle Taster werden über 1 Pin ausgelesen,
und haben unterschiedliche Widerstände.
Nein; laut Grenzwerte mit dem Du die Tasterbetätigung erkennen willst ist das kein R2R Netzwerk. R2R Netzwerke haben die Eigenschaft, daß die Werte immer die Hälfte des vorherigen sind und somit mit den Binären Zahlendarstellung übereinstimmt.
Moin,
allein in dem Stück Code sehe ich 2 Dinge:
In der ersten Zeile prüfst Du <300 und meinst kein Taster - Im Kommentar sprichst Du von 1023
Gleichzeitig prüfst Du für Taster 6 auf <=1023. Das passt nicht zusammen.
In Zeile 2 prüfst Du auf >= 1000 -> daraus wird Taster1
In Zeile 3 prüfst Du auf <= 1000 -> daraus wird Taster2
Benutzt Du ein Tastenpad oder hast es auf einem Steckbrett zusammengestellt?
Kannst Du mal einen Plan ggfls. Bild einstellen - nicht irgendwohin auf irgendwelche Bilderserver verlinken.
christian_der_bastler:
Ich würde auch gern das nachfolgende Schema verwenden, jedoch weiß ich nicht wie ich die Taster
als Matrix verkabele und auslese.
So eine Keypad-Matrix ist an sich recht einfach aufgebaut.
..und mithilfe der Keypad-Library auch sehr komfortabel anzupassen und zu bedienen. Diese erkennt sogar, ob eine Taste gedrückt, gehalten oder losgelassen wurde.
Du müsstest lediglich für 6 Taster die Matrix als 2x3 aufbauen und das im Sketch am Anfang definieren. Gegenüber der Analog-Taster-Lösung kostet dich das "nur" 5 Pins..
ich habe die Variant mit der Keypad-Matrix gewählt.
Dies funktioniert sehr gut. Ich möchte nun mehrere Passwörter nacheinander abrufen.
Sobald das erste Passwort korrekt ist soll die Variable Song geändert werden und das nächste Passwort muss eingegeben werden. Leider komm es zu einem Fehler sobald ich die Abfrage nach dem 2. Passwort mache.
Kann mir bitte jemand helfen?
#include <Keypad.h> //Keypad und Servo Library wird eingebunden
#include <Servo.h>
#include "pitches.h"
int notes[] = {262, 294, 330, 349, 392, 440, 494};
Servo servoblau; //Servo wird ab jetzt mit „servoblau“ angesprochen
char* password = "123455"; //Das Passwort "Alle meine Entchen"
char* password2 = "54321"; //Das Passwort wird festgelegt. In diesem Beispiel„123“
int position = 0;
const byte ROWS = 2; //Hier wird angegeben wie viele Zeilen und Spalten das
const byte COLS = 4; //Tastenfeld besitzt
char keys[ROWS][COLS] = { //Die Ziffern und Zeichen des Tastenfelds werden angegeben
{'#', '0', '*', '1'},
{'2', '3', '4', '5'},
};
byte rowPins[ROWS] = {A0, A1}; //Die Verbindung mit dem Arduino wird
byte colPins[COLS] = {2, 3, 4, 5}; //festgelegt
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
int roteLED = 12; //Die rote LED ist an Pin 12 angeschlossen
int grueneLED = 13; //Die grüne LED wird an Pin 13 angeschlossen
int Song = 0;
void setup()
{
pinMode(roteLED, OUTPUT); //Die LEDs werden als Ausgang festgelegt
pinMode(grueneLED, OUTPUT);
servoblau.attach(11); //Der Servo ist an Pin 11 angeschlossen
setLocked(true);
}
void loop()
{
char key = keypad.getKey();
Serial.println(key);
if (key == '1') {
tone(8, notes[0]); // C
}
else if (key == '2') {
tone(8, notes[1]); // D
}
else if (key == '3') {
tone(8, notes[2]); // E
}
else if (key == '4') {
tone(8, notes[3]); // F
}
else if (key == '5') {
tone(8, notes[4]); // G
}
else if (key <= 1) { // if no switch is pressed, do not play tone
noTone(8);
}
//Alle meine Entchen
if (Song == 1)
{
if (key == '*' || key == '#') //wenn das Schloss entsperrt ist kann es mit der Taste „*“ oder „#“ wieder gesperrt werden
{
position = 0;
setLocked(true); //Schloss sperren wenn * oder # gedrückt wurde
}
if (key == password[position])
Song = 2;
{
position ++;
}
if (position == 6) //Diese Zeile gibt die Länge des Passwortes an. In unserem Fall 3 Stellen.
{
setLocked(false);
}
delay(100);
}
//Song 2
if (Song == 2)
{
if (key == '*' || key == '#') //wenn das Schloss entsperrt ist kann es mit der Taste „*“ oder „#“ wieder gesperrt werden
{
position = 0;
setLocked(true); //Schloss sperren wenn * oder # gedrückt wurde
}
if (key == password2[position])
Song = 2;
{
position ++;
}
if (position == 5) //Diese Zeile gibt die Länge des Passwortes an. In unserem Fall 3 Stellen.
{
setLocked(false);
}
delay(100);
}
void setLocked(int locked;)
{
if (locked) // Wenn das Schloss gesperrt ist soll..
{
digitalWrite(roteLED, HIGH); //..die rote LED leuchten..
digitalWrite(grueneLED, LOW); //..die grüner LED nicht leuchten..
//servoblau.write(90); //und der Servo soll 0 Grad ansteuern.
}
else //wenn das Schloss entsperrt ist soll..
{
digitalWrite(roteLED, LOW); //..die rote LED nicht leuchten..
digitalWrite(grueneLED, HIGH); //..die grüne LED leuchten..
//servoblau.write(0); //..und der Servo 90 Grad ansteuern.
}
}
}
Peter-CAD-HST:
Akkoladen kannte ich auch noch nicht notier
YMMD
Ich fand "geschweifte Klammer" immer so einen unprofessionellen Ausdruck. Deswegen hab ich mich mal schlau gegoogelt... Bisher hab ich im Akkoladen auch immer nur meine aufladbaren Batterien gekauft...
Anyway... ein sehr schönes Tutorial, das den Umgang mit Keypad-Matrix, Passwort-Überprüfung, LCD-Screen & Aktuator (Relais statt servo) zum Thema hat. Zwar englisch, aber gut erklärt..
Geppi, du bist der einzige den ich kenne, der "curly braces" mit "Akkolade" übersetzt.
Ich weiß, dass die Namen "Klammeraffe" und "Lattenkreuz" inzwischen veraltet sind. (@ und #, falls jemand verwirrt ist)
Aber 0x7D ist immer noch eine "geschweifte Klammer rechts" Völlig professionell.