Zeiterfassungsgerät mit PureBox und Nextion Display

PureBox als Daten Server für eine Zeiterfassung

Zeiterfassungsgeräte oder Zeiterfassungsterminals mit einer offenen SQL Datenbank als API sind schwer zu finden oder meistens gar nicht käuflich zu erwerben. Aus vielen vergangenen Blogberichten auf dieser Seite ist bekannt, daß die PureBox ein vielseitiger Edge Computer im industriellen Standard ist. Er unterliegt allen notwendigen Industrie Schutzart Prüfungen. Weiterhin hat dieses Gerät jede nur erdenkliche Industrie 4.0 Schnittstelle.

Die Purebox ist weit von dem entfernt, was ein Rasperry Pi leisten kann – womit viele Leser dieses Gerät vielleicht vergleichen würden. Die PureBox hat festgelegte Aufgaben, für die sie Masken und Web-Oberflächen intern hat, die genau auf die Aufgabe zugeschnitten sind. Dennoch gibt es Möglichkeiten, das Gerät nach den eigenen Bedürfnissen umzubauen oder zu modifizieren. In diesem Bericht wird angerissen, wie man aus der PureBox eine Zeiterfassung mit einem RFID Trigger bauen kann. Von Haus aus besitzt die verwendete Version (PureBox3 50518) keine I/O`s. Deshalb wurde ein NEXTION Display NX3224T024 – Generic 2.4″ TFT von ITEAD ausgewählt, um dem User eine Rückmeldung nach einer Aktion zu geben. Der Vorteil des NEXTION Displays ist, dass es via TTL TX/RX kommunizieren kann. Die PureBox besitzt auch eine TTL RX/TX Schnittstelle on Board.

Beim Anschließen der Bauteile an die interne PureBox Schnittstelle ist darauf zu achten, dass die Schnittstelle außerhalb des Gehäuses geführt wird, da sonst alle Schutzprüfungen der PureBox vom Hersteller verfallen und die Garantie erlischt. Weiterhin verträgt die on Board Schnittstelle nur max 40mA Strom. Deswegen ist in dieser Variante des Zeiterfassungsgerätes oder Zeiterfassungsterminals das NEXTION Display auf nur 10% gedimmt. Somit hat das Display eine Stromaufnahme von nur 31mA in Summe. Ungetestet ist allerdings das Ausschalten der „Touch Funktion“ da nur die RX Leitung für das Display benutzt wurde.

dim = 10

Das RFID Modul RDM6300

Als RFID-Trigger Einheit dient das RFID Modul RDM6300. Dieses Modul kommuniziert ebenfalls über eine TTL-Schnittstelle. Es wird mit 3 Kabeln angeschlossen: Vin 5v , GND, und TX. Sobald sich ein RFID-Tag nähert, sendet das Modul über TTL die Nummer des Tags oder über die Karte an ein Endgerät. Hier muss darauf geachtet werden, dass es zwei Versionen (Stand 10.12.2018) gibt. Version 1 benutzt einen 5v Pegel bei der Signal-Übertragung und Version 2 3v. Die PureBox verträgt allerdings nur einen Pegel von 3v. Bei der Verwendung von RDM6300 V1 muß man einen Spannungsteiler verwenden. Dieser Spannungsteiler ist jedoch schon auf der Verbkinderplatine vorhanden und muß bei V2 lediglich überbrückt werden.

RDM6300 V1 u V2 für die Zeiterfassung
-RDM6300 V1 und V2

intelligent ideas bietet hier eine Verbinder-Platine, mit der man beide RDM6300 Versionen an der PureBox Schnittstelle verwenden kann. Bei Version 2 des RDM6300 muss bei R1 auf der Platine dann ein NULL Widerstand aufgelötet werden. Hier ein Bild der Platine.

Verbinder Platine RDM6300
Verbinder Platine für RDM6300 RFID Modul und PureBox
Verbinder Platine mit RDM6300 V2
Verbinder Platine mit RDM6300 V2 und NULL Widerstand

Hier der PHP Code um mit der Platine zu kommunizieren und Werte zu bekommen. In der PureBox wird das Script als Chron Job angelegt und z.B. alle 10 Sekunden neu gestartet. Dann bleibt der serielle Kanal 10sec. geöffnet und wartet einen Empfang von Werten.

$TIMEOUT = 10; // the pureBox is opening the serial listener for 10 sec.
	$fd = dio_open( '/dev/ttyS1', O_RDWR | O_NONBLOCK );
	dio_tcsetattr( $fd, array(
	  'baud'       => 9600,
	  'bits'       => 8,
	  'stop'       => 1,
	  'parity'     => 0,
	  'flow_control' => 0,
	  'is_canonical' => 0
	) );

	$request = '';
	$merker = '';
	$time_start = time();
	while($time_start + $TIMEOUT > time()) { 
		$merker = dio_read( $fd,1 );
		usleep( 10 );
		if ($merker === chr(2)) {
			while(strpos($request, chr(3)) === false){
				$request .= dio_read( $fd,1 ); //read one ASCII charakter from device and append
			}
			$request = substr($request, 0, -1);
			flush ();
			dio_close( $fd );
			break;
		}		
	}

Das LCD NEXTION Display

Das Display von Nextion muß vor dem Verwenden über eine Software eingerichtet werden. Das Einrichten läuft über einen wysiwyg Editor und kann auf der Homepage des Herstellers heruntergeladen werden. Sehr einfach zieht man sich Steuerelemente in das Display, die dann serielle Befehle empfangen können. Um z.B. in eine Testbox einen String von einem Gerät zu senden, sendet man über TTL den String < t0.txt=“Hallo Welt“ >. Um in ein Nummernfeld zu schreiben sendet man < n0.val=2 >. Mehr muß man nicht machen. Die einzelnen Steuerelemente können noch gescriptet werden. Im Fall der Zeiterfassung zeigt das Display eine Uhr damit der Benutzer sieht, wann er sich ein- oder ausloggt. Diese Uhr ist keine RTC Echtzeituhr, sondern fingiert. Man hat in der NEXTION IDE zum Programmieren des Displays ein Timer Steuerelement. Dieser Timer ist ungenau, jedoch gibt er dem Benutzer auf dem Display den Eindruck, als wenn es eine RTC ist. In Wirklichkeit läuft der Nextion Timer in seinem eigenen, annähernd Sekunden-Takt und alle 10 Sekunden wird die Server Zeit an die Stunden- Minuten- und Sekunden Textbox gesendet. Das bewirkt, dass man eine Echtzeit-Uhr im Display hat. Der folgende Code wird in der IDE in dem Timer Event geschrieben.

if(n2.val==59)
{
  n2.val=0
  n1.val++
}
n2.val++
if(n1.val==60)
{
  n1.val=0
  n0.val++
}
if(n0.val==24)
{
  n0.val=0
}

n0 = Steuerelement für die Stunden, n1 = Steuerelement für die Minuten , n2 = Steuerelement für die Sekunden. Der Code um die aktuelle Serverzeit alle 10 Sekunden an das Display zu senden wird im Chron Job gelegte PHP Datei der PureBox in PHP geschrieben. und sieht wie folgt aus.

	$jetzt_h = date("H");
	$jetzt_min = date("i");
	$jetzt_sec = date("s");
	//Die arktuelle Uhrzeit in n0,n1,n2
	dio_write( $fd, 'n0.val='.$jetzt_h.'' ); //Write value to the Nextion Display
	dio_write($fd,"\xff");  // write 0xff to /dev/ttyS1
	dio_write($fd,"\xff"); 
	dio_write($fd,"\xff"); 
	flush ();
	dio_write( $fd, 'n1.val='.$jetzt_min.'' ); //Write value to the Nextion Display
	dio_write($fd,"\xff");  // write 0xff to /dev/ttyS1
	dio_write($fd,"\xff"); 
	dio_write($fd,"\xff"); 
	flush ();	
	dio_write( $fd, 'n2.val='.$jetzt_sec.'' ); //Write value to the Nextion Display
	dio_write($fd,"\xff");  // write 0xff to /dev/ttyS1
	dio_write($fd,"\xff"); 
	dio_write($fd,"\xff"); 
	flush ();
NEXTION IDE Screenshot
NEXTION IDE Screenshot Uhr mit Timer ohne RTC programmieren

Der Code des Projekts

Hier nun der komplette Code des Projekts um aus einer PureBox , RDM6300 und dem NEXTION Display eine Zeiterfassung zu erstellen. Ohne monatliche Gebühren zu bezahlen kann man hier einen Zeiterfassungsterminal mit SQL Anbindung bekommen.

function InsertInto($num,$InOrOUT)
	{
		$servername = "localhost";
		$username = "admin";
		$password = "ii2018";
		$dbname = "userdb";
		$conn = new mysqli($servername, $username, $password, $dbname);
		$sql = "INSERT INTO ZeitStempel (number,InOrOut)VALUES ('".$num."','".$InOrOUT."')";
		$conn->query($sql);
		$conn->close();
	}
function select($number)
	{
		$servername = "localhost";
		$username = "admin";
		$password = "ii2018";
		$dbname = "userdb";
		$conn = new mysqli($servername, $username, $password, $dbname);
		$sql = "SELECT ZeitStempel.number, member.Name,ZeitStempel.InOrOut FROM ZeitStempel INNER JOIN member ON ZeitStempel.number = member.number WHERE ZeitStempel.NUMBER = '".$number."' ORDER BY timedate DESC LIMIT 1";
		$result = $conn->query($sql);

		if ($result->num_rows > 0) {
			// output data of each row
			while($row = $result->fetch_assoc()) {
				$InOrOut = $row["InOrOut"];
				$UserName = $row["Name"];
				//echo "number: " . $row["number"]. " - InOrOut: " . $row["InOrOut"]. "
"; } } else { echo "0 results"; } $conn->close(); return array($InOrOut, $UserName); } // Melde alle PHP Fehler error_reporting(-1); $TIMEOUT = 50; //the pureBox is opening the serial listener for 50 sec. $fd = dio_open( '/dev/ttyS1', O_RDWR | O_NONBLOCK ); dio_tcsetattr( $fd, array( 'baud' => 9600, 'bits' => 8, 'stop' => 1, 'parity' => 0, 'flow_control' => 0, 'is_canonical' => 0 ) ); //Das Datum in die Text box t0 $heuteDatum = date("d.m.Y"); dio_write( $fd, 't0.txt="'.$heuteDatum.'"' ); //Write value to the Nextion Display dio_write($fd,"\xff"); // write 0xff to /dev/ttyS1 dio_write($fd,"\xff"); dio_write($fd,"\xff"); flush (); $jetzt_h = date("H"); $jetzt_min = date("i"); $jetzt_sec = date("s"); //Die arktuelle Uhrzeit in n0,n1,n2 dio_write( $fd, 'n0.val='.$jetzt_h.'' ); //Write value to the Nextion Display dio_write($fd,"\xff"); // write 0xff to /dev/ttyS1 dio_write($fd,"\xff"); dio_write($fd,"\xff"); flush (); dio_write( $fd, 'n1.val='.$jetzt_min.'' ); //Write value to the Nextion Display dio_write($fd,"\xff"); // write 0xff to /dev/ttyS1 dio_write($fd,"\xff"); dio_write($fd,"\xff"); flush (); dio_write( $fd, 'n2.val='.$jetzt_sec.'' ); //Write value to the Nextion Display dio_write($fd,"\xff"); // write 0xff to /dev/ttyS1 dio_write($fd,"\xff"); dio_write($fd,"\xff"); flush (); //Linie wird von Rot nach dunkel Grün dio_write( $fd, 't4.bco=1024' ); //Write value to the Nextion Display dio_write($fd,"\xff"); // write 0xff to /dev/ttyS1 dio_write($fd,"\xff"); dio_write($fd,"\xff"); flush (); $request = ''; $merker = ''; $time_start = time(); while($time_start + $TIMEOUT > time()) { $merker = dio_read( $fd,1 ); usleep( 10 ); if ($merker === chr(2)) { while(strpos($request, chr(3)) === false){ $request .= dio_read( $fd,1 ); //read one ASCII charakter from device and append } $request = substr($request, 0, -1);//subtrack one charakter from string because will be EOT char $InOrOUT = select($request)[0]; $UserName = select($request)[1]; if (!$UserName) { $UserName = $request; } if ($InOrOUT == 'In'){ $InOrOUT = 'Out'; }else{ $InOrOUT = 'In'; } dio_write( $fd, 't4.bco=33823' ); //Write value to the Nextion Display dio_write($fd,"\xff"); // write 0xff to /dev/ttyS1 dio_write($fd,"\xff"); dio_write($fd,"\xff"); flush (); dio_write( $fd, 't0.txt="'. $UserName .'"' ); //Write value to the Nextion Display dio_write($fd,"\xff"); // write 0xff to /dev/ttyS1 dio_write($fd,"\xff"); dio_write($fd,"\xff"); flush (); $JetztTime = date("d.m.y H:i"); dio_write( $fd, 't1.txt="'.$JetztTime.' '. $UserName .' is '.$InOrOUT.'"' ); //Write value to the Nextion Display dio_write($fd,"\xff"); // write 0xff to /dev/ttyS1 dio_write($fd,"\xff"); dio_write($fd,"\xff"); flush (); dio_close( $fd ); InsertInto($request,$InOrOUT); break; } }

ii intelligent ideas, Siehe dazu auch den Bericht über das Verbinden des NEXTION Displays mit der PureBox. (klick hier)

Hier ein Video über die Bauteile und Funktionsweise der Zeiterfassung
Tabellenaufbau des Zeiterfassungsterminals der SQL Datenbank
Tabellenaufbau des Zeiterfassungsterminals der SQL Datenbank