Mein Arduino Programm für einen Tresor funktioniert nicht?
Ich muss für die Schule einen Tresor mit einem 3x4Keypad , einem Servo und einem Lcd Display programmieren. Dafür habe ich einen Arduino UNO. Das Programm funktioniert aber nicht so wie ich es will.
Wenn ich eine Taste drücke, die nicht # oder * ist soll sie auf dem Display angezeigt werden und auf der Variable inputPasswort gespeichert werden. Diese sollen aber nicht immer in der ersten Spalte stehen, sondern sollen nebeneinander in einer Zeile angezeigt werden. Wenn ich # drücke soll der Arduino prüfen ob das eingegebene Passwort richtig ist. Wenn das der Fall ist, soll sich der Servo öffnen und das Display “Passwort richtig” anzeigen. Wenn nicht soll der Servo geschlossen bleiben und das Display soll “Passwort falsch” anzeigen. Wenn * gedrückt wird soll das Programm alle bisher eingegebenen Zahlen von der Variable inputPasswort löschen.
Das Display zeigt die Zahlen aber nur kurz und immer an verschiedenen Stellen an. Der Arduino erkennt auch nicht wenn das Passwort richtig ist. Kann mir bitte jemand helfen?
So sieht mein Programm bisher aus:
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <Servo.h>
#include <Keypad.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
int cursorPosition = 0; // Variable für die Position des Cursors
Servo IHateThis; // Servo heißt jetzt "IHateThis"
const int ROW_NUM = 4; // Anzahl der Tastenfeld Reihen
const int COLUMN_NUM = 3; // Anzahl der Tastenfeld Zeilen
byte pin_rows[ROW_NUM] = { 9, 8, 7, 6 }; //die Pins für die Reihen des Tastenfelds
byte pin_column[COLUMN_NUM] = { 5, 4, 3 }; //die Pins für die Zeilen des Tastenfelds
char keys[ROW_NUM][COLUMN_NUM] = {
{ '1', '2', '3' },
{ '4', '5', '6' },
{ '7', '8', '9' },
{ '*', '0', '#' }
};
Keypad keypad = Keypad(makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM);
char Passwort[5] = { '0', '1', '2', '3', '#' }; //Array mit Länge des Passworts (4 + #) und dem Passwort selbst (0123)
String inputPasswort; // Variable um die eingegebenen Tasten abzuspeichern
void setup() {
inputPasswort.reserve(4);
lcd.init();
lcd.clear();
lcd.backlight(); //Das Display soll beleuchtet sein
IHateThis.attach(12); //Servo ist an Pin 12 angeschlossen
IHateThis.write(140); //Servo ist anfangs in der Position 140 (Tresor ist zu)
}
void loop() {
char Taste = keypad.getKey(); //Variable "Taste" ist hier definiert
if (Taste != '*' && Taste != '#') {
lcd.setCursor(cursorPosition, 0); // Cursor position at position 0 of the first row of the LCD.
lcd.print(Taste); //Wenn eine Taste außer * und # gedrückt wird, wird diese auf dem Display angezeigt
cursorPosition = cursorPosition + 1;
}
if (Taste == '#') { //Nachdem # gedrückt wurde, wird überprüft ob das eingegebene Passwort dem tatsächlichen Passwort entspricht
if (inputPasswort == Passwort) { //Wenn das eingegebene Passwort dem tatsächlichen Passwort entspricht, wird für 3 Sekunden "Passwort richtig" angezeigt. Danach wird der inhalt der Variable inputPasswort gelöscht, der Servo geöffnet, die Variable cursorPosition auf 0 zurückgesetzt und das Display geleert.
lcd.setCursor(0, 0);
lcd.print("Passwort richtig");
delay(3000);
inputPasswort = "";
lcd.clear();
cursorPosition = 0;
lcd.setCursor(cursorPosition, 0);
IHateThis.write(30);
}
if (inputPasswort != Passwort) { //Wenn das eingegebene Passwort nicht dem eingegebenen Passwort entspricht, wird "Passwort falsch" für 3 Sekunden angezeigt, und danach die reset schleife ausgeführt
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Passwort falsch");
delay(3000);
reset();
}
}
if (Taste == '*') { //Wenn * gedrückt wird, wird die reset Schleife ausgeführt
reset();
}
}
void reset() {
inputPasswort = ""; //Alles was auf der Variable inputPasswort gespeichert war, wird gelöscht
lcd.clear(); //Display wird geleert
cursorPosition = 0; //Die Variable cursorPosition wird auf 0 gesetzt
IHateThis.write(140); //Der Servo wird geschlossen
}
The inputPassword-Variable isn’t changed by you. You have to attach the entered character.
Incidentally, I don’t see why you represent input and password with different data types. Either you use for both char-Arrays or for both String– Objects.
Principle would it be advisable to revise the code:
(1) Orient yourself to the common C/C++ name conventions: Variable names always start with a small letter. Also choose a language (German or English, no mix) and name your variables appropriately so that their purpose is immediately apparent when reading the code. You make it difficult for you (and readers) to keep an overview of the code.
2) Currently, in your code, you always assume that multiple cases could be met at the same time, but this is not possible. When the user presses #, button only the value ‘#’, not at the same time ‘*’. If the password is correct, then there is no need to check the opposite.
Use if-else if-elseto avoid unnecessary tests.
3) There are some double instructions in your code.
The reset– I’d change the function. Then it can be used in several cases.
Functions are not loops. Your related comments are therefore incorrect.
Grinds are structures that can repeat their fuselage as often as possible, depending on how long their loop condition applies. In Arduino for, do-while and and to this category.
The output of the test can also be outsourced:
Thank you for your help. I hope I did what you meant, but it didn’t change the problem.
Here is the changed program:
#include
#include
#include
#include
LiquidCrystal_I2C lcd(0x27, 16, 2);
int cursorPosition = 0; // Variable for the position of the cursor
Servo iHateThis; // Servo is now called “iHateThis”
const int ROW_NUM = 4; // Number of keypad rows
const int COLUMN_NUM = 3; // Number of keypad lines
byte pin_rows[ROW_NUM] = { 9, 8, 7, 6}; //the pins for the rows of the keypad
byte pin_column[COLUMN_NUM] = { 5, 4, 3}; //the pins for the rows of the keypad
char keys[ROW_NUM][COLUMN_NUM] = {
{‘1’, ‘2’, ‘3’},
‘4’, ‘5’, ‘6’,
‘7’, ‘8’, ‘9’,
‘*’, ‘0’, ‘#’
};
keypad keypad = keypad(makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM);
char password[5] = { ‘0’, ‘1’, ‘2’, ‘3’, ‘#’ }; //Array with length of password (4 + #) and password itself (0123)
String inputPassword; // Variable to save the entered keys
void setup() {
inputPassword.reserve(4);
lcd.init();
lcd.clear();
lcd.backlight(); //The display should be illuminated
iHateThis.attach(12); //Servo is connected to Pin 12
iHateThis.write(140); //Servo is initially in position 140 (Tresor is too)
}
void loop()
char key = keypad.getKey(); //Variable “key” is defined here
if (key != ‘*’ && key != ‘#’) {
lcd.setCursor(cursorPosition, 0); // Cursor position at position 0 of the first row of the LCD.
lcd.print(key); //If a button is pressed except * and #, it will be displayed on the display
cursorPosition = cursorPosition + 1;
inputPassword += key;
}
else if (key == ‘#’) { //After the # has been pressed, it is checked whether the password entered corresponds to the actual password
if (inputPassword == password) { // If the entered password corresponds to the actual password, “password correct” is displayed for 3 seconds. The content of the inputPassword variable is then deleted, the servo is opened, the cursorPosition variable is reset to 0 and the display is emptied.
printResult(“password correct”);
reset();
iHateThis.write(30);
}
else { //If the entered password does not correspond to the entered password, “password wrong” will be displayed for 3 seconds, and then the reset loop executed
printResult(“password wrong”);
reset();
iHateThis.write(140);
}
}
else { //If * is pressed, the reset function will be executed
reset();
}
}
void reset() {
inputPassword = “; //Everything stored on the inputPassword variable is deleted
lcd.clear(); //Display is emptied
cursorPosition = 0; //The cursorPosition variable is set to 0
lcd.setCursor(cursorPosition, 0);
}
void printResult(char* message) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(message);
delay(3000);
}
The comparison will fail for two reasons.
On the one hand, before the comparison, you do not catch the rhomb at the end of inputPassword (otherwise, you could password of course also simply leave).
On the other hand, you compare two different data types (inputPasswordis a String and password is a char-Array. I think that should also lead to a compiler error.
Either you decide for only one data type on both variables or you perform a conversion.
Example char[]-Comparation:
Example String-Comparation:
Example char[]-String-Comparation: