From 501ceebb00e991f2af43eaf7bd1cd9d1f75d6257 Mon Sep 17 00:00:00 2001 From: Philipp Wagner Date: Fri, 22 Mar 2024 21:48:20 +0100 Subject: [PATCH] added v4 --- v4/v4.ino | 612 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 612 insertions(+) create mode 100644 v4/v4.ino diff --git a/v4/v4.ino b/v4/v4.ino new file mode 100644 index 0000000..a1b5f7c --- /dev/null +++ b/v4/v4.ino @@ -0,0 +1,612 @@ +//© 2024 Philipp Wagner, Riccardo Henning. +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// NFC-Pin-Definitionen und -Objekt +#define PN532_SCK (91) +#define PN532_MOSI (90) +#define PN532_SS (4) +#define PN532_MISO (89) +Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS); + +//NFC-Request für Anlernen +bool request1 = false; + +USBHostMSD msd; +mbed::FATFileSystem usb("usb"); +mbed::DigitalOut otg(PB_8, 1); + +const int pinRedLED = 86; // Rot +const int pinGreenLED = 87; // Grün +const int pinBlueLED = 88; // Blau +const int pinStatusRedLED = 26; // ROT externe LED +const int pinStatusGreenLED = 24; // Grün externe LED +const int pinStatusYellowLED = 22; // Gelb externe LED + +//ISR +bool doorIsOpened = false; +volatile bool ButtonPressed = false; +volatile unsigned long lastPressTime = 0; + +// WiFI +WiFiServer server(80); + +// Keypad Initialisierung +const byte ROWS = 4; //vier Reihen +const byte COLS = 4; //vier Spalten +char hexaKeys[ROWS][COLS] = { + { '1', '2', '3', 'A' }, + { '4', '5', '6', 'B' }, + { '7', '8', '9', 'C' }, + { '*', '0', '#', 'D' } +}; +byte rowPins[ROWS] = { 32, 34, 36, 38 }; //verbinde mit den Reihen-Pinouts des Keypads +byte colPins[COLS] = { 40, 42, 44, 46 }; //verbinde mit den Spalten-Pinouts des Keypads + +//LCD Initialisierung +const int rs = 49, en = 51, d4 = 33, d5 = 35, d6 = 37, d7 = 39; +LiquidCrystal lcd(rs, en, d4, d5, d6, d7); +Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); + + +//Überprüfung +String inputString = ""; // Zum Speichern der Tasteneingaben +String correctString = ""; // Der zu überprüfende String + +//Ultraschall +int echo_pin = 7; +int trig_pin = 6; +bool isPackageSpace = true; +bool isPackageInside = false; +long distanceUltraSonic = 0; + +void setup() { + attachInterrupt(digitalPinToInterrupt(71), isrPin71, CHANGE); + Serial.begin(9600); + // Ultraschall Set + pinMode(trig_pin, OUTPUT); + pinMode(echo_pin, INPUT); + // LCD Beginnen + analogWrite(2, 50); // Kontrast LCD einstellen + lcd.begin(16, 2); + // LCD Startup Message und Copyright + lcd.print("Startup Brain V4"); + lcd.setCursor(0, 1); + lcd.print("c:Wagner|Henning"); + // EXTERNE STATUS LEDs + pinMode(pinStatusRedLED, OUTPUT); + pinMode(pinStatusGreenLED, OUTPUT); + pinMode(pinStatusYellowLED, OUTPUT); + digitalWrite(pinStatusRedLED, HIGH); + digitalWrite(pinStatusGreenLED, HIGH); + digitalWrite(pinStatusYellowLED, HIGH); + // NFC-Kram + nfc.begin(); + uint32_t versiondata = nfc.getFirmwareVersion(); + while (!versiondata) { + ledBlink(GPIOJ, 14); + lcd.clear(); + lcd.println("Error starting: "); + lcd.setCursor(0, 1); + lcd.println("NFC Module error"); + delay(500); + } + nfc.setPassiveActivationRetries(0x00); + //NFC-Anlern-Knopf --> BOOT0 auf Giga R1 Wifi + pinMode(PC_13, INPUT); + + //USB-A + pinMode(PA_15, OUTPUT); + digitalWrite(PA_15, HIGH); + // Kommunikationsleitungsen + pinMode(69, OUTPUT); + pinMode(71, INPUT); + + int randomSeedValue = analogRead(0); // RandomSeed value with some Noise... + randomSeed(randomSeedValue); + + while (!msd.connect()) { + delay(1000); + } + + int err = usb.mount(&msd); + if (err) { + Serial.println("Error mounting USB device"); + while (1) + ; + } + Serial.println("Mounting USB device... done"); + + //Onboard LED + pinMode(pinRedLED, OUTPUT); + pinMode(pinGreenLED, OUTPUT); + pinMode(pinBlueLED, OUTPUT); + digitalWrite(pinRedLED, LOW); + + char ssid[32] = ""; + char pass[32] = ""; + FILE *wifiFile = fopen("/usb/WiFi.txt", "r"); + if (wifiFile) { + fscanf(wifiFile, "%31s\n%31s", ssid, pass); + fclose(wifiFile); + } else { + strcpy(ssid, "SSID"); + strcpy(pass, "PASSWORD"); + FILE *newWifiFile = fopen("/usb/WiFi.txt", "w"); + if (newWifiFile) { + fprintf(newWifiFile, "%s\n%s", ssid, pass); + fclose(newWifiFile); + } + } + + int status = WL_IDLE_STATUS; + while (status != WL_CONNECTED) { + status = WiFi.begin(ssid, pass); + delay(10000); + } + server.begin(); + digitalWrite(pinGreenLED, LOW); + digitalWrite(pinRedLED, HIGH); + digitalWrite(pinBlueLED, HIGH); + + //externer LED-Status + statusYellow(); + + // Serielle Ausgabe der IP + Serial.println("Connected Succesfully!"); + IPAddress ip = WiFi.localIP(); + Serial.print("IP Address: "); + Serial.println(ip); + + // LCD Start des Programmes + lcd.clear(); + lcd.print("IP: "); + lcd.setCursor(0, 1); + lcd.print(ip); + delay(5000); // Warte 5 Sekunden + lcdWritePinInterface(); +} + + +void loop() { + // NFC-Anlern-Knopp + if (digitalRead(PC_13) == HIGH) { + Serial.println("Anlernen angefragt."); + lcd.clear(); + lcd.print("neuen NFC-TAG"); + lcd.setCursor(0, 1); + lcd.print("vorzeigen"); + request1 = true; // Setzen Sie request1 auf true, wenn der Button gedrückt wurde + } + // NFC-Tag lesen + uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; + uint8_t uidLength; + boolean success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength); + if (success) { + // UID in eine String-Repräsentation umwandeln + String uidString = ""; + for (uint8_t i = 0; i < uidLength; i++) { + uidString += String(uid[i], HEX); + } + // Überprüfen, ob der Button gedrückt wurde + if (request1) { + // UID in die Datei "NFC-UIDS.txt" schreiben + FILE *file = fopen("/usb/NFC-UIDS.txt", "a+"); + if (file) { + fprintf(file, "%s\n", uidString.c_str()); + fclose(file); + // LCD-Anzeige aktualisieren + lcd.clear(); + lcd.print("NFC-Tag"); + lcd.setCursor(0, 1); + lcd.print("gespeichert!"); + delay(1000); + lcdWritePinInterface(); + request1 = false; + } + } else { + // UID in der Datei "NFC-UIDS.txt" überprüfen + FILE *file = fopen("/usb/NFC-UIDS.txt", "r"); + boolean tagFound = false; // Variable hinzufügen, um zu überwachen, ob der Tag gefunden wurde + if (file) { + char line[32]; + while (fgets(line, sizeof(line), file)) { + String lineString = String(line); + lineString.trim(); + if (lineString.equalsIgnoreCase(uidString)) { // Verwende equalsIgnoreCase für eine nicht case-sensitive Überprüfung + Serial.println("NFC: Akzeptiert"); + //LED-Status + statusGreen(); + lcd.clear(); + lcd.print("NFC-TAG:"); + lcd.setCursor(0, 1); + lcd.print("akzeptiert!"); + delay(2000); + lcdWritePinInterface(); + //LED-Status + statusYellow(); + tagFound = true; // Tag gefunden + // Kommunikations-UPDATE + openDoor(); + break; + } + } + fclose(file); + if (!tagFound) { + Serial.println("NFC: Nicht akzeptiert"); // Wenn der Tag nicht gefunden wurde, zeige diese Nachricht + lcd.clear(); + statusRed(); + lcd.print("NFC-TAG:"); + lcd.setCursor(0, 1); + lcd.print("nicht akzeptiert!"); + delay(1000); + lcdWritePinInterface(); + statusYellow(); + } + } + } + } + + WiFiClient client = server.available(); + if (client) { + //Serial.println("Client start"); + lcd.clear(); + lcd.print("Webinterface!"); + lcd.setCursor(0, 1); + lcd.print("keine Eingabe..."); + boolean currentLineIsBlank = true; + String request = ""; + + while (client.connected()) { + if (client.available()) { + //Serial.println(request); + char c = client.read(); + if (c == '\n' && currentLineIsBlank) { + if (request.indexOf("/generie}rePIN ") != -1) { + String pin = generatePIN(); + // Schreibe die generierte PIN direkt in die Datei PINs.txt auf dem USB-Stick + FILE *pinFile = fopen("/usb/PINs.txt", "a+"); + if (pinFile) { + fprintf(pinFile, "%s\n", pin.c_str()); + fclose(pinFile); + } + client.println("HTTP/1.1 200 OK"); + client.println("Content-Type: text/html"); + client.println("Connection: close"); + client.println(); + client.println(""); + client.println(""); + client.println("Deine generierte PIN: " + pin); + client.println(""); + } else if (request.indexOf("/ ") != -1) { + // Senden Sie eine HTML-Seite zurück, die den Status dedistanceUltraSonic = r Tür anzeigt + client.println("HTTP/1.1 200 OK"); + client.println("Content-Type: text/html"); + client.println("Connection: close"); + client.println("Refresh: 5"); + client.println(); + client.println(""); + client.println(""); + client.println("Packstation"); + client.println("

Packstation (Selbstbau)

"); + client.println("

Codename: Brain (Version: 4)

"); + client.println("

Tuerstatus:

"); + if (doorIsOpened) { + client.println("

Die Tuer ist geoeffnet.

"); + } else { + client.println("

Die Tuer ist geschlossen.

"); + } + client.println("

Packetstatus

"); + if (isPackageInside) { + client.println("

In der Packstation liegen Packete

"); + } else { + client.println("

Kein Packet ist in der Packstation

"); + } + client.println("

Code-Generierung:

"); + client.println(" Zusteller-PIN generieren "); + client.println("
"); + client.println(" Besitzer-PIN generieren "); + client.println(""); + } else if (request.indexOf("/generieOWNERPIN ") != -1) { + String pin = generateOwnerPIN(); + FILE *pinFile = fopen("/usb/OWNER-PINs.txt", "a+"); + if (pinFile) { + fprintf(pinFile, "%s\n", pin.c_str()); + fclose(pinFile); + } + client.println("HTTP/1.1 200 OK"); + client.println("Content-Type: text/html"); + client.println("Connection: close"); + client.println(); + client.println(""); + client.println(""); + client.println("Deine generierte PIN: " + pin); + client.println(""); + } else { + client.println("HTTP/1.1 404 Not found"); + client.println("Content-Type: text/html"); + client.println("Connection: close"); + client.println(); + client.println(""); + client.println(""); + client.println("404 Not Found"); + client.println(""); + } + break; + } + + if (c == '\n') { + currentLineIsBlank = true; + } else if (c != '\r') { + currentLineIsBlank = false; + } + request += c; + } + } + client.stop(); + delay(100); + lcdWritePinInterface(); + //Serial.println("Client Stop"); + } + //Serial.println("Keypad 1"); + char customKey = customKeypad.getKey(); + //Serial.println("Keypad 2"); + if (customKey) { + if (customKey == '#') { + // Überprüfe, ob die eingegebene PIN in den korrekten PINs enthalten ist + bool pinAccepted = false; + FILE *pinFile = fopen("/usb/PINs.txt", "r"); + if (pinFile) { + char line[32]; + while (fgets(line, sizeof(line), pinFile)) { + String correctPin = String(line); + correctPin.trim(); + if (inputString == correctPin) { + if (isPackageSpace) { // Überprüfung ob denn noch genung Platz drinne ist.. + pinAccepted = true; + break; // Beende die Schleife, wenn eine korrekte PIN gefunden wurde + } + } + } + fclose(pinFile); + } + + if (!pinAccepted) { + // Überprüfe, ob die eingegebene PIN in den OWNER-PINs enthalten ist + pinFile = fopen("/usb/OWNER-PINs.txt", "r"); + if (pinFile) { + char line[32]; + while (fgets(line, sizeof(line), pinFile)) { + String correctPin = String(line); + correctPin.trim(); + if (inputString == correctPin) { + pinAccepted = true; + break; // Beende die Schleife, wenn eine korrekte PIN gefunden wurde + } + } + fclose(pinFile); + } + } + + if (pinAccepted) { + //LED-Status + Serial.println("PIN: akzeptiert"); + lcd.clear(); + lcd.print("PIN:"); + lcd.setCursor(0, 1); + lcd.print("akzeptiert!"); + delay(1000); + lcdWritePinInterface(); + // Kommunikations-UPDATE + openDoor(); + // Lösche die verwendete PIN aus der Datei PINs.txt + FILE *pinFile = fopen("/usb/PINs.txt", "r"); + FILE *tempFile = fopen("/usb/temp.txt", "w"); + if (pinFile && tempFile) { + char line[32]; + while (fgets(line, sizeof(line), pinFile)) { + String currentPin = String(line); + currentPin.trim(); + // Schreibe alle PINs außer der verwendeten PIN in die temporäre Datei + if (currentPin != inputString) { + fprintf(tempFile, "%s\n", currentPin.c_str()); + } + } + fclose(pinFile); + fclose(tempFile); + + // Lösche die ursprüngliche Datei und benenne die temporäre Datei um + remove("/usb/PINs.txt"); + rename("/usb/temp.txt", "/usb/PINs.txt"); + } + inputString = ""; // Setze den Eingabestring zurück + } else { + lcd.clear(); + statusRed(); + Serial.println("PIN: nicht akzeptiert!"); + lcd.print("PIN:"); + lcd.setCursor(0, 1); + lcd.print("nicht akzeptiert!"); + delay(1000); + lcdWritePinInterface(); + statusYellow(); + } + inputString = ""; // Setze den Eingabestring zurück + statusYellow(); + } else if (customKey == '*') { + // Setze den Eingabestring zurück + inputString = ""; + lcd.clear(); + lcd.print("Eingabe"); + lcd.setCursor(0, 1); + lcd.print("zurueckgesetzt"); + delay(1000); + lcdWritePinInterface(); + } else { + // Füge die gedrückte Taste zum Eingabestring hinzu + inputString += customKey; + lcd.print(customKey); + } + } + if (doorIsOpened) { + //andere LEDs aus. + digitalWrite2(GPIOJ, 12, false); + digitalWrite2(GPIOG, 12, false); + digitalWrite2(GPIOJ, 14, false); + lcd.clear(); + lcd.print("Tuer offen!"); + ledBlink(GPIOG, 12); // PIN 24 + lcdWritePinInterface(); + //Ausgangszustand + digitalWrite2(GPIOJ, 12, true); + digitalWrite2(GPIOG, 12, false); + digitalWrite2(GPIOJ, 14, false); + } + ultraSonicDistanceRead(); + delay(1); +} +String generatePIN() { + const char validCharacters[] = "ABCD0123456789"; + String pin = ""; + for (int i = 0; i < 6; i++) { + int index = random(0, sizeof(validCharacters) - 1); + pin += validCharacters[index]; + } + return pin; +} + +String generateOwnerPIN() { + const char validCharacters[] = "ABCD0123456789"; + String pin = ""; + for (int i = 0; i < 7; i++) { + int index = random(0, sizeof(validCharacters) - 1); + pin += validCharacters[index]; + } + return pin; +} + +void isrPin71() { + static unsigned long lastPressTime = 0; + // Nur den Druck verarbeiten, wenn seit dem letzten Druck mehr als 20 Millisekunden vergangen sind + if (millis() - lastPressTime >= 20) { + if (digitalRead(71) == 0) { + doorIsOpened = false; + } + if (digitalRead(71) == 1) { + doorIsOpened = true; + } + ButtonPressed = true; + lastPressTime = millis(); + } +} + +// UND JETZT, NACH 500 Stunden: ASSEMBLY!!!!!! +void ledBlink(GPIO_TypeDef *port, uint32_t pin) { + digitalWrite2(port, pin, true); + delayApproxOneSecond(); + digitalWrite2(port, pin, false); + delayApproxOneSecond(); +} + + +void digitalWrite2(GPIO_TypeDef *port, uint32_t pin, bool state) { + volatile uint32_t *bsrr = &(port->BSRR); + if (state) { + // Setzt den Pin + asm volatile( + "mov r0, %0\n\t" // Lade die Adresse des BSRR-Registers + "mov r1, #1\n\t" // Setze r1 auf 1 + "lsl r1, r1, %1\n\t" // Verschiebe 1 um die Anzahl der Bits, die durch pin angegeben sind + "str r1, [r0]\n\t" // Schreibe den Wert in BSRR, setzt den Pin + : // Keine Ausgaben + : "r"(bsrr), "r"(pin) + : "r0", "r1" // Verwendete Register + ); + } else { + // Löscht den Pin + asm volatile( + "mov r0, %0\n\t" // Lade die Adresse des BSRR-Registers + "mov r1, #1\n\t" // Setze r1 auf 1 + "lsl r1, r1, %1\n\t" // Verschiebe 1 um pin + 16 Positionen + "str r1, [r0]\n\t" // Schreibe den Wert in BSRR, löscht den Pin + : // Keine Ausgaben + : "r"(bsrr), "r"(pin + 16) + : "r0", "r1" // Verwendete Register + ); + } +} + + + +void delayApproxOneSecond() { + asm volatile( + "mov r0, %0 \n" // Lädt den Wert (480000000) in das Register r0 + "1: \n" // Beginn des Schleifenlabels + "subs r0, #1 \n" // Subtrahiert 1 von r0 und aktualisiert die Flags + "bne 1b \n" // Springt zurück zum Label 1, wenn r0 nicht 0 ist + : // keine Ausgaben + : "r"(480000000) // Der Wert, der in r0 geladen wird + : "r0" // Teilt dem Compiler mit, dass r0 verändert wird + ); +} + + +//ENDE ASSEMBLY +void lcdWritePinInterface() { + lcd.clear(); + lcd.print("PIN eingeben:"); + lcd.setCursor(0, 1); +} + +void openDoor() { + digitalWrite(69, HIGH); + delay(100); + digitalWrite(69, LOW); +} + +void statusGreen() { + digitalWrite(pinStatusGreenLED, HIGH); + digitalWrite(pinStatusRedLED, LOW); + digitalWrite(pinStatusYellowLED, LOW); +} + +void statusYellow() { + digitalWrite(pinStatusRedLED, LOW); + digitalWrite(pinStatusGreenLED, LOW); + digitalWrite(pinStatusYellowLED, HIGH); +} + +void statusRed() { + digitalWrite(pinStatusGreenLED, LOW); + digitalWrite(pinStatusRedLED, HIGH); + digitalWrite(pinStatusYellowLED, LOW); +} + +void ultraSonicDistanceRead() { + // UltraSchall + digitalWrite(trig_pin, LOW); // um Probleme mit potenziellen ECHOS zu vermeiden + delay(5); // um Probleme mit potenziellen ECHOS zu vermeiden + digitalWrite(trig_pin, HIGH); + delayMicroseconds(10); + digitalWrite(trig_pin, LOW); + + long echoTime = pulseIn(echo_pin, HIGH); + long distanceUltraSonic = (echoTime / 2) * 0.03432; + if (distanceUltraSonic > 30) { + isPackageSpace = true; + isPackageInside = false; + } else if (distanceUltraSonic < 7) { + isPackageSpace = false; + isPackageInside = true; + } else { + isPackageSpace = true; + isPackageInside = true; + } +} \ No newline at end of file