#include <SPI.h>
#include <Wire.h>
#include <PN532.h>
#include <PN532_SPI.h>
#include <ESP8266WiFi.h>
#include <WiFiClientSecureAxTLS.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// If using the breakout with SPI, define the pins for SPI communication.
PN532_SPI pn532spi(SPI, 2);
PN532 nfc(pn532spi);
#define BUZZ_PIN D8
#define GATE_PIN D3
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const char* host = "script.google.com";
const int httpsPort = 443;
const char* fingerprint = "46 B2 C3 44 9C 59 09 8B 01 B6 F8 BD 4C FB 00 74 91 2F EF F6"; // for https
//***********Things to change*******************
const char* ssid = "*****************";
const char* password = "*************";
String GOOGLE_SCRIPT_ID = "AKfycbyNJyCjyqBRDul36nhpc1k1hpDuHxjzio2-VvbKyOxzv7fUBwgF99w2D6vFMcp7Np1d"; // Replace by your GAS service id
const String unitName = "Hafven_Makerspace"; // any name without spaces and special characters
//***********Things to change*******************
uint64_t openGateMillis = 0;
WiFiClientSecure client;
void setup() {
pinMode(GATE_PIN, OUTPUT);
digitalWrite(GATE_PIN, LOW);
Serial.begin(9600);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.println("Started");
Serial.print("Connecting");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("Hallo!");
nfc.begin();
uint32_t versiondata = nfc.getFirmwareVersion();
if (!versiondata) {
Serial.print("Didn't find PN53x board");
while (10)
; // halt
}
// Got ok data, print it out!
Serial.print("Gefundener Chip PN5");
Serial.println((versiondata >> 24) & 0xFF, HEX);
Serial.print("Firmware ver. ");
Serial.print((versiondata >> 16) & 0xFF, DEC);
Serial.print('.');
Serial.println((versiondata >> 8) & 0xFF, DEC);
// configure board to read RFID tags
nfc.setPassiveActivationRetries(0xFF); // for example
nfc.SAMConfig();
Serial.println("Warte auf eine Karte ...");
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
delay(2000);
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 10);
display.print("Karte bitte");
display.display();
}
void HandleDataFromGoogle(String data) {
int ind = data.indexOf(":");
String access = data.substring(0, ind);
int nextInd = data.indexOf(":", ind + 1);
String name = data.substring(ind + 1, nextInd);
String text = data.substring(nextInd + 1, data.length());
Serial.println(name);
if (access == "-1") {
Serial.print(" " + String("denied"));
} else if (access == "any") {
Serial.print(" " + String("go in"));
OpenGate();
} else if (access == "fridge") {
Serial.print(" " + String("take it"));
OpenGate();
}
}
void OpenGate() {
//openGateMillis = millis()+4000;
digitalWrite(GATE_PIN, HIGH);
}
void CloseGate() {
//openGateMillis = 0;
digitalWrite(GATE_PIN, LOW);
}
void loop() {
uint8_t success;
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
if (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength)) {
// Display some basic information about the card
Serial.println("Found an ISO14443A card");
Serial.print(" UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
Serial.print(" UID Value: ");
nfc.PrintHex(uid, uidLength);
Serial.println("");
String idcard = "";
for (uint8_t i=0; i < uidLength; i++)
{
idcard += (String)uid[i];
}
Serial.println("UID Hex_als_String: "+idcard);
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 10);
display.print(idcard);
display.display();
String data = sendData("id=" + unitName + "&uid=" + idcard,NULL);
HandleDataFromGoogle(data);
while (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength)) {}
}
else
{
CloseGate();
String data = sendData("id=" + unitName + "&uid="+"Ende", NULL);
while (!nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength)) {
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 10);
display.print("Karte bitte");
display.display();
}
}
}
String sendData(String params, char* domain) {
//google scripts requires two get requests
bool needRedir = false;
if (domain == NULL) {
domain = (char*)host;
needRedir = true;
params = "/macros/s/" + GOOGLE_SCRIPT_ID + "/exec?" + params;
}
Serial.println(*domain);
String result = "";
client.setInsecure();
Serial.print("connecting to ");
Serial.println(host);
if (!client.connect(host, httpsPort)) {
Serial.println("connection failed");
return "";
}
if (client.verify(fingerprint, domain)) {
}
Serial.print("requesting URL: ");
Serial.println(params);
client.print(String("GET ") + params + " HTTP/1.1\r\n" + "Host: " + domain + "\r\n" + "Connection: close\r\n\r\n");
Serial.println("request sent");
while (client.connected()) {
String line = client.readStringUntil('\n');
//Serial.println(line);
//delay(500);
if (needRedir) {
int ind = line.indexOf("/macros/echo?user");
if (ind > 0) {
Serial.println(line);
line = line.substring(ind);
ind = line.lastIndexOf("\r");
line = line.substring(0, ind);
Serial.println(line);
result = line;
}
}
if (line == "\r") {
Serial.println("headers received");
break;
}
}
while (client.available()) {
String line = client.readStringUntil('\n');
if (!needRedir)
if (line.length() > 5)
result = line;
// Serial.println(line);
}
if (needRedir)
return sendData(result, "script.googleusercontent.com");
else
return result;
}
Ich habe mal meinen kompletten code hier aufgezeigt. Eigentlich funktioniert er so, wie er soll. Eigentlich!!! Wenn eine Karte mit 4 bytes vor dem Reader liegt, wird die UID erkannt, übermittelt, geprüft, bei positiver Rückmeldung wird das Relais geschaltet und solange die Karte vor dem Reader ist, passiert nichts. Das soll auch so sein. Nehme ich die Karte weg, schaltet das Relais aus. Soweit alles gut. Mach ich das gleiche mit einer Karte mit 7 bytes, wird die uid korrekt erkannt, das Relais schaltet, allerdings hält der Loop nicht an. D.h. das relais wird immer wieder an und aus geschaltet. Warum also stopt der loop bei einer 4 bytes Karte und bei einer 7 bytes Karte nicht?