🏠 FabLab Startseite | Nutzungsbedingungen | Impressum | Wiki

Nodemcu + mysql + rfid + relai


#1

Hi Leute,

Ich hab ein kleines Problem und hoffe in diesem Forum endlich auf eine Antwort zu stoßen. Und zwar:
Ich möchte das es am Ende so funktioniert das ich einen Nodemcu esp8266 habe und an diesen ist ein rfid Leser und ein Relai angeschlossen. Der nodemcu ist dann mit meinem lokalen Server verbunden und sobald ich einen chip(rfid Chip, Karte, sonstiges) an den rfid Leser halte, soll dieser per php Script an meiner MySQL Datenbank abfragen, ob der Wert „Allow“ bei der passenden Chip-id auf 1 oder 0 steht(der Wert Allow steht dafür ob das Relai angemacht werden darf oder nicht). Und je nach dem ob der Wert auf 1 oder 0 steht geht das relai an oder aus (1=an, 0=aus). ich will es dann noch so regeln dass das relai eine bestimmte Zeit lang an bleibt und dann von selber wieder ausgeht. Der Wert mit der 1 und der 0 über den ich gerade geschrieben habe soll allerdings nicht den Wert des Relais beschreiben sondern wie oft man das Relai noch an machen darf. Also z.b. So:
0 = Relai geht nicht an
1 = Relai geht an ( wert = -1)
2 = Relai geht an ( wert = -1)
usw…
Auf jedenfalls kenne ich mich schon gut mit php und MySQL aus allerdings nicht so mit der arduino ide und dem nodemcu und appelliere deswegen an alle guten Techniker in diesem Forum die mir netterweise helfen können. Mein Wissen geht auch deshalb nicht so weit weil ich erst 13 bin. Ich bin für jede Hilfe dankbar. :wink:
Insofern

Vielen Dank schon mal im Voraus

Max


#2

Hi @nichtwitzig228,

wenn du dich mit php und mysql schon gut auskennst, hast du das Meiste ja schon zusammen :wink:
Also was du neben dem esp8266 noch brauchst, ist ein Server, auf dem die MySQL-Datenbank und das PHP-Skript läuft. Dafür kannst du beispielsweise einen Raspberry Pi verwenden, zusammen mit apache als Webserver.

Als nächstes würdest du eine Datenbank anlegen, die eine Tabelle enthält mit einer Spalte für die RFID`s und einer Spalte für die Dauer (oder allow, je nachdem wie du es jetzt machen möchtest). Dein PHP-Skript baut dann eine Verbindung zu der angelegten Datenbank auf.

Da dein ESP dem PHP-Skript mitteilen muss, welcher RFID-Tag gelesen wurde, musst du Parameter mithilfe der $_GET oder $_POST Variablen einlesen. Die eingelesenen Daten verwendest du dann für deine MySQL-Anfrage. Die gelesene Dauer / das allow-Flag gibst du dann per “echo”-Befehl an den Client zurück.

Im letzten Schritt musst du nur noch den ESP Programmieren. Hierfür brauchst du einmal Arduino Studio, das bekommst du auf der Website von Arduino. Du kannst auch den Webeditor verwenden, davon würde ich aber abraten.
Dann verbindest du deinen ESP über USB mit deinem PC und schaust ob Arduino Studio ihn erkennt. Das siehst du, wenn du in Arduino Studio im Menü unter “Werkzeuge” den Unterpunkt “Port” anklickst. Dort müsste nach dem Anschließen ein neuer Eintrag auftauchen. Den kannst du dann auch gleich auswählen.

Der Port gibt an, über welche USB-Schnittstelle der Code auf den ESP geladen werden soll.
Anschließend musst du im Arduino Studio noch die Unterstützung für dein NodeMCU-Board aktivieren, wie das geht steht beispielsweise hier unter Punkt 2 beschrieben.

Danach kannst du anfangen den ESP zu programmieren. Hier sind zwei Schritte wichtig, Aufbauen der WLAN-Verbindung und Abrufen der Daten über HTTP.

Den Aufbau der WLAN-Verbindung findest du z.B. hier erklärt.
Um dann die Daten von deinem PHP-Skript abzurufen musst du einen GET- oder einen POST-Request durchführen, das ist abhängig von der Art der Variable die du in deinem PHP-Skript verwendet hast. Für einen GET-Request kannst du hier den Beispielcode sehen.

Ich hoffe das gibt dir einen groben Überblick darüber, was du alles brauchst. Wenn du noch Fragen hast, oder für einen Teil des Problems einen Beispielcode brauchst, schreib einfach nochmal.

Viel Erfolg beim basteln :wink:
Ian


Smarte Klingel mit ESP8266/ESP32
#3

Also erstens viiieelen dank.
Das ganze hilft mir echt weiter. Das is bisher das beste Forum auf dem ich die Frage gestellt habe und außerdem auch noch auf deutsch! Also wie gesagt nochmal vielen Dank aber bei einer Sache brauch ich noch Hilfe. Und zwar: ich kenn mich mit $_POST Aus aber nich so mit der GET Variante es wäre für mich schöner das ganze mit $_POST Zu machen. Hätest du da vlt ein Beispiel. Und nochmal vielen Dank!
Schon mal wieder Vielen vielen Dank im Voraus. Ach ja und außerdem hast du es echt schön erklärt aber ich glaub ich brauch das genauer also nur den teil mit dem nodemcu programmieren. Weil ich z.b. Nicht weis wie ich dann per php-Script ein relai an und aus machen kann oder z.b. Sagen kann, das wenn der Wert auf 1 is und die Karte wird drüber gezogen dann von dem Wert -1 abgezogen wird und das Relais angehen soll. Außerdem soll das ganze System so funktioniert das später wenn die Karte oder der Chip über den RFID Karten Leser gezogen wird, Das ganze System beziehungsweise der Nodemcu Dann in einer MySQL Datenbank prüft ob die ID des Chips oder der Karte einen bestimmten Wert hat wenn ja soll dann das Relais angehen

Lg

Max


#4

Kein Problem, dafür ist das Forum ja da :wink:

Ich habe zur Sicherheit deine Handynummer mal aus deinem Post entfernt, du solltest die nicht öffentlich im Internet zur Verfügung stellen.
Außerdem ist dieses Forum dazu da, das alle, die ähnliche Probleme wie du haben, die Lösung hier finden können. Es wäre also kontraproduktiv, wenn wir uns jetzt privat weiter unterhalten würden :slight_smile:

Zuerst zum PHP-Teil:
POST und GET unterscheiden sich in der Programmierung eigentlich gar nicht. Der einzige unterschied liegt darin, wie die Parameter an den Server übertragen werden.
Bei einer POST-Anfrage werden die Parameter innerhalb des Anfragekörpers übertragen. Bei einer GET-Anfrage werden die Parameter stattdessen in der URL übertragen. Ein Beispiel dafür:

Die GET-Anfrage auf die Adresse http://localhost:8000/index.php?suchtext=abc&sortierung=0 würde die Datei http://localhost:8000/index.php aufrufen und ihr die Parameter “suchtext” und “sortierung” mit den Werten “abc” und “0” übergeben.
Auf diese Werte greifst du dann wie gewohnt mit $_GET[“suchtext”] oder $_GET[“sortierung”] zu.
Die Namen für die Parameter kannst du natürlich selbst wählen.

In der URL wird die Adresse (also http://localhost:8000/index.php) von der Parameterliste mit einem “?” getrennt, alle darauffolgenden Parameter werden mit “&” voneinander getrennt.

Und zum esp8266:
Hier ist es tatsächlich einfacher den Aufruf per GET zu machen, weil du einfach nur die aufgerufene Adresse anpasst.

Egal wofür du dich entscheidest, anschließend kannst du mit der Antwort arbeiten. Ich weiß nicht wie gut du dich mit Datentypen auskennst, aber in Computerprogrammen musst du um mit Zahlen zu rechnen auch einen Datentyp verwenden der das unterstützt. Du bekommst aber über die Netzwerkanfrage nur einen String zurück. Also würde ich als nächstes den String in einen int (also ganzzahlige Nummern) umwandeln.

Als Beispiel:

string rfid = "123";//hier koenntest du das Einlesen vom RFID-Tag stattdessen verwenden.
http.begin("http://localhost:8000/index.php?rfid="+rfid);
int httpCode = http.GET();                                                                  //Anfrage absenden
 
if (httpCode > 0) { //Der Return-Code gibt an ob die Anfrage erfolgreich ist.
 
   String payload = http.getString();   //Hier kannst du den Antworttext auslesen
   Serial.println(payload);                     //Ausgabe über die Serielle Verbindung 
      //(einsehbar im Arduino Studio unter Werkzeuge > Serieller Monitor)
 
   int value = payload.toInt(); // Umwandlung in einen int mit dem gerechnet werden kann
} 
http.end();   //Verbindung schließen

Achtung, das ist kein vollständiger Code!

Damit könntest du den RFID-Tag per GET an den Server übertragen.
Wenn du wirklich lieber POST verwenden möchtest, kannst du dir das hier nochmal anschauen.

Liebe Grüße,
Ian


#5

Noch eine kurze Verständnisfrage, soll der Wert in der Datenbank geändert werden? Also wenn ich die RFID-Karte drüberziehe und in der Datenbank steht eine 4, soll dann danach eine 3 drin stehen? Wenn ja musst du das in deiner PHP-Datei mit bedenken


#6

Ja sollte es. Wahrscheinlich wäre es für mich leichter wenn du willst kannst du vlt einen ganzen Beispiel Code machen. Du musst nicht wäre aber schön! Weil ich versteh das immer noch nicht so ganz :grin:


#7

Ach ja und ich finde es echt toll von dir das du mir hilfst. Ist heutzutage nicht selbstverständlich :wink: danke!


#8

Wie gesagt, überhaupt kein Problem

Ich bin gerade unterwegs, ich mache heute Abend oder morgen früh was fertig


#9

Also danke, danke und nochmals vielen dank.
Ich finde es echt schön das du dir Zeit nimmst und weis das zu schätzen. Falls du mal irgendeinen gefallen hast den ich dir tun kann lass es mich wissen. :grin:


#10

So, hier jetzt mal der Beispielcode:
PHP-Datei, z.B. index.php, liegt in /var/www/html/ auf dem Raspberry pi

<?php
  //Prüfen ob ein rfid-Tag übergeben wurde
  if (isset($_GET['rfid'])) {
    //Datenbankverbindung aufbauen
    $mysqli = new mysqli("localhost", "meinuser", "meinpasswort", "datenbankname");

    //SQL-Query zum Abfragen des rfid-tags
    //prepare bereitet ein Statement vor, das Fragezeichen wird hinterher durch einen Wert ersetzt
    if ($stmt = $mysqli -> prepare("SELECT allow FROM tabellenname WHERE rfid=?")) {
      $stmt -> bind_param("s", $_GET['rfid']);
      $stmt -> execute();
      $stmt -> bind_result($allow);
      if ($stmt -> fetch()) {
        echo $allow;
      } else {
        //Hier kannst du den Fall abfangen, dass kein Eintrag zu dem RFID-Tag passt
      }
    } else {
      //Ein Fehler in deiner SQL-Abfrage ist aufgetreten, gebe den Fehler aus
      echo $mysqli -> error;
    }
  }
?>

Das wäre jetzt die PHP-Datei, ich verwende hier sogenannte prepared-statements, das bedeutet die Anfrage wird vorher generiert, ohne von Nutzern gegebene Daten (z.B. die RFID-Nummer) einzubauen. Diese werden erst anschließend übertragen. Der Vorteil ist, dass diese Methode immun gegen SQL-Injection ist.


#11

Den Arduino-Code müsste ich jetzt improvisieren, aber falls du den auch noch brauchst melde dich gerne


#12

Also erstmal schon wieder(ich weis es wird langsam langweilig) vielen vielen dank. und ja ich bräuchte noch den Arduino Code wenn es dir nichts ausmacht. wahrscheinlich laste ich dich damit für heute oder sonst wann voll aus, aber trotzdem erstmal danke für alles und ja es wäre wirklich wirklich nett wenn du mit einen Arduino Code schreiben könntest. am besten auch einen der dann funktioniert aber da zweifle ich nicht dran.

vielen dank im voraus(schon wieder)

max


#13

Also dass der ganze Code funktioniert kann ich dir nicht garantieren. Ich habe hier leider keinen ESP rumliegen. Du kannst dich aber mit Fehlermeldungen melden wenn du hängst, dann schaue ich mal.

Bei dem Arduinocode habe ich geschaut dass alles kompiliert, mehr kann ich jetzt gerade nicht prüfen.
Denk daran, du musst vorher Board und Library installieren wie oben beschrieben!

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

//Was hier drin steht wird nur einmal direkt nach dem Start des Controllers ausgeführt.
//Hier steht also nur die Initialisierung drin
void setup() {
  //Verbindet sich mit dem Computer um Text zur Konsole schicken zu können
  //Die Konsole findest du unter Werkzeuge > Serieller Monitor
  //Diese Konsole funktioniert nur über direkte USB-Verbindung, 
  //betreibst du den ESP über Batterie klappt das natürlich nicht
  Serial.begin(9600);

  //TODO: Hier musst du den richtigen Pin einsetzen. Das hängt davon ab, an welchem Digitalpin du dein Relay anschließt
  //Diese Zeile definiert, dass du über Pin 13 gerne Signale ausgeben möchtest.
  //Gibst du ein HIGH auf pin 13, liegt an diesem pin positive Spannung an, bei LOW 0V
  pinMode(13, OUTPUT);

  //TODO: Netzwerkdaten von dir eingeben
  WiFi.begin("netzwerkname", "netzwerkpasswort");
}

//Was hier drin steht wird wiederholt ausgeführt. 
//Sobald diese Funktion durchgelaufen ist, wird sie einfach von vorn ausgeführt.
void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    //Der Controller versucht sich solange zu verbinden, bis die Verbindung erfolgreich aufgebaut wurde
    while(WiFi.status() != WL_CONNECTED) {
      //0.5 Sekunden warten um den Router nicht zu überfordern
      delay(500);
      //Serial.print schreibt ein Zeichen an die Konsole des Computers
      //Auf der Konsole sollten jetzt Punkte auftauchen, bis die Verbindung erfolgreich aufgebaut wurde
      Serial.print(".");
    }
    //Schreibt einen Zeilenumbruch auf den Computer
    Serial.println();


    //Gibt die IP-Adresse innerhalb deines Netzwerks auf dem Computer aus
    Serial.print("Verbunden, IP-Adresse ist: ");
    Serial.println(WiFi.localIP());
  }

  //Der Teil hängt von deiner RFID-Library ab. 
  //Du kannst dafür vermutlich den Beispielcode des Herstellers verwenden um RFIDs einzulesen
  //TODO:Mit Code zum Lesen der RFID-Tags ersezen!
  String rfid="abc";

  //Initialisiert die Verbindung zu einem Webserver.
  //In diesem Beispiel also zu deinem Raspberry pi oder anderem Webserver
  HTTPClient http;
  //TODO: Hier musst du localhost durch die IP-Adresse des Raspberry pis ersetzen
  http.begin("http://localhost/index.php?rfid="+rfid);
  int httpCode = http.GET();

  Serial.print("HTTP Statuscode: ");
  Serial.println(httpCode);

  //Hier wird jetzt die Antwort des Servers gelesen. 
  //Alles, was der Server während der Laufzeit ausgibt sollte in der Variable allow landen.
  String allow = http.getString();
  Serial.println("Server antwortete mit: ");
  Serial.println(allow);
  //Da du mit der zurückgegebenen Zahl vermutlich noch rechnen musst, musst du sie zu einem int machen
  int allowNumber = allow.toInt();

  //TODO: Hier irgendwas mit allowNumber und einem Ausgangspin machen
  //Dieser Beispielcode schaltet das Relay an pin 13 für 1 Sekunde an.
  digitalWrite(13, HIGH);
  delay(1000);
  digitalWrite(13, LOW);
}

Ich habe im PHP-Code jetzt noch nicht geschrieben, wie die Zahl runtergezählt wird. Im Arduino-Code muss auch noch das ein oder andere angepasst werden. Ich empfehle dir erstmal selbst anzuschauen ob du das hinbekommst, viel muss nicht gemacht werden.
Wenn du nicht weiterkommst helfe ich dir gerne, aber nur durch selbst probieren lernst du es :wink:

Wenn du in der Nähe von Lübeck wohnst kannst du auch gerne mal bei uns im FabLab vorbei kommen, dann können wir uns dein Projekt auch mal zusammen anschauen

Liebe Grüße,
Ian


#14

Sieht soweit ganz gut aus.
Ich würde allerdings die While-Schleife in die Loop legen, damit bei einem Verbindungsabbruch die Verbindung wieder aufgebaut wird. :wink:


#15

Danke für den Hinweis, ich habe den Code entsprechend angepasst :+1:


#16

Was genau ist mit „irgendwas mit allownumber und irgendeinem Ausgangs Pin machen“ gemeint?


#17

Naja, das hängt ja von deinem Anwendungsfall ab, also im Prinzip musst du den Code

digitalWrite(13, HIGH);
delay(1000);
digitalWrite(13, LOW);

durch deinen eigenen Ersetzen.


#18

Wie kann ich sagen das z.b. Beim Wert eins bei der Spalte allow dann das relai 10 Sekunden angeht und bei dem Wert 2 dann 20 Sekunden usw.


#19

Cool wusste gar nicht das das Forum eine live Funktion hat :smiley:


#20

Also der Wert aus der Spalte allow wird ja mit dem obigen Code in die Variable allow im Arduino übertragen.
Anschließend wird allow zu einem Zahlenwert umgewandelt, der in allowNumber gespeichert wird.
Jetzt kannst du ganz normal mit allowNumber rechnen.
Mit
Serial.println(allowNumber * 10);
würdest du also zum Beispiel das 10-Fache von allow auf die Konsole ausgeben.

Wie du das Relay für 1 Sekunde anschaltest siehst du ja auch schon im Code oben, du übergibst dabei der delay-Methode die Zeit, wie lange das Relay geschaltet werden soll.
Die Übergabe erfolgt dabei in Millisekunden, das heißt wenn du 1000 übergibst wartet das Programm 1 Sekunde, bei 2000 2 Sekunden usw.

Jetzt solltest du versuchen mit diesen Hinweisen den Code selbst zusammenzubasteln :wink:

Was meinst du mit live?