Zu diesem kleinen Projekt inspirierte mich eine Bastelarbeit im Internet. Die "Mystery-Box I." ist ein Behälter, indem kleine Überraschungen (z.B. für Kinder) platziert werden können, die jedoch nur mit einem speziellen Code zugänglich sind.
Die Mystery-Box öffnet eine Tür (hinter dieser z.B. eine kleine Überraschung versteckt ist) mit einem 4-stelligem Code, welcher mittels vier Tastern eingegeben wird. Stimmt die Reihenfolge der Eingabe, so geht die Tür der Mystery-Box auf. Ein beliebiger Druck auf einen Taster schließt die Tür wieder. Soll der Zugangscode geändert werden, so müssen seitlich gleichzeitig zwei kleine Magneten am Gehäuse platziert werden. Ein kurzes Aufleuchten der Code-LEDs zeigt an, das nun der neue Code eingegeben werden kann. Man muss nun in einer beliebigen Reihenfolge die Taster drücken. Sind alle Taster verwendet worden (entsprechende LED leuchtet), so ist der neue Code eingestellt.
Der Mikro-USB-Anschluss kann mit einem PC verbunden werden (voher das Gerät mit dem Hauptschalter von der Batterie trennen). Mit einer seriellen Konsole (z.B. PuTTY oder Arduino IDE) mit einer Übertragungsrate von 9600 Baud können Debug-Meldungen des Sketches empfangen werden und können der Fehlersuche dienen.
Der Aufbau an sich ist relative einfach, denn es müssen nur LEDs, Mikrotaster, Reed-Kontakte und ein Servo-Motor angeschlossen werden. Zusätzlich wird noch eine Stromversorgung mit einer aufladbaren Batterie benötigt.
#define PIN_LED_1 A0
#define PIN_LED_2 A1
#define PIN_LED_3 A2
#define PIN_LED_4 A3
#define PIN_BUTTON_1 4
#define PIN_BUTTON_2 5
#define PIN_BUTTON_3 6
#define PIN_BUTTON_4 7
#define PIN_LED_SUCCESS 9
#define PIN_SERVO 10
#define PIN_REED_1 11
#define PIN_REED_2 12
#include <Servo.h>
#include <EEPROM.h>
bool isDoorOpen, openDoor, buttonPressed[4];
byte buttons[4] = {PIN_BUTTON_1, PIN_BUTTON_2, PIN_BUTTON_3, PIN_BUTTON_4};
byte leds[4] = {PIN_LED_1, PIN_LED_2, PIN_LED_3, PIN_LED_4}, doorCode[4];
Servo servoMotor;
void setup()
{
Serial.begin(9600);
Serial.print("Init...");
pinMode(PIN_REED_1, INPUT_PULLUP);
pinMode(PIN_REED_2, INPUT_PULLUP);
pinMode(PIN_LED_SUCCESS, OUTPUT);
digitalWrite(PIN_LED_SUCCESS, LOW);
for (byte i = 0; i < sizeof(leds); i++) {
pinMode(leds[i], OUTPUT);
pinMode(buttons[i], INPUT_PULLUP);
buttonPressed[i] = false;
}
blinkLEDs();
servoMotor.attach(PIN_SERVO);
servoMotor.write(0);
isDoorOpen = false;
EEPROM.get(0, doorCode);
Serial.println("ok");
printDoorCode();
}
void loop()
{
checkCode();
if (digitalRead(PIN_REED_1) == HIGH && digitalRead(PIN_REED_2) == HIGH) {
resetCode();
}
checkDoor();
}
void checkCode()
{
static byte foundOffset = 0, pressOffset = 0, currentState;
openDoor = false;
for (byte i = 0; i < sizeof(buttons); i++) {
currentState = digitalRead(buttons[i]);
if (!buttonPressed[i] && currentState == LOW) {
digitalWrite(leds[i], HIGH);
buttonPressed[i] = true;
pressOffset++;
if (doorCode[foundOffset] == i) {
foundOffset++;
}
}
}
if (foundOffset >= 4) {
openDoor = true;
pressOffset = 0;
foundOffset = 0;
delay(200);
} else {
if (pressOffset >= 4) {
pressOffset = 0;
foundOffset = 0;
for (byte i = 0; i < sizeof(buttons); i++) {
delay(200);
buttonPressed[i] = false;
digitalWrite(leds[i], LOW);
}
}
}
}
void checkDoor()
{
if (!isDoorOpen) {
if (openDoor) {
digitalWrite(PIN_LED_SUCCESS, HIGH);
for (byte i = 0; i < sizeof(leds); i++) {
digitalWrite(leds[i], LOW);
}
delay(500);
servoMotor.write(90);
isDoorOpen = true;
delay(1000);
while (openDoor == true) {
for (byte i = 0; i < sizeof(buttons); i++) {
if (digitalRead(buttons[i]) == LOW) {
openDoor = false;
break;
}
}
}
}
} else {
if (!openDoor) {
digitalWrite(PIN_LED_SUCCESS, LOW);
for (byte i = 0; i < sizeof(leds); i++) {
buttonPressed[i] = false;
digitalWrite(leds[i], LOW);
}
servoMotor.write(0);
isDoorOpen = false;
delay(2000);
}
}
}
void resetCode()
{
servoMotor.write(90);
for (byte i = 0; i < sizeof(doorCode); i++) {
doorCode[i] = 255;
}
blinkLEDs();
openDoor = false;
isDoorOpen = false;
bool isExisting = false;
byte offset = 0;
do {
for (byte i = 0; i < sizeof(buttons); i++) {
isExisting = false;
if (digitalRead(buttons[i]) == LOW && doorCode[offset] == 255) {
for (byte j = 0; j < sizeof(doorCode); j++) {
if (doorCode[j] == i) {
isExisting = true;
}
}
if (!isExisting) {
digitalWrite(leds[i], HIGH);
doorCode[offset] = i;
offset++;
}
}
}
} while (offset < 4);
printDoorCode();
EEPROM.put(0, doorCode); // writing code to EEPROM
servoMotor.write(0);
blinkLEDs();
}
void blinkLEDs()
{
for (byte j = 0; j < 9; j++) {
for (byte i = 0; i < sizeof(leds); i++) {
digitalWrite(leds[i], j % 2);
delay(40);
}
}
}
void printDoorCode()
{
Serial.print("Code:");
for (byte i = 0; i < sizeof(doorCode); i++) {
Serial.print(" ");
Serial.print(doorCode[i]);
}
Serial.println("");
}
Zunächst habe ich einen Prototypen auf dem Breadboard aufgebaut und die obige Schaltung mit dem Sketch getestet.
- noch nicht vorhanden -
zurück