User Manual¶
Product description¶
The product is a RFID scanner used for time registration. It is meant to be a way for employees to check in- and out.
Step-by-step guide¶
An introduction to your product, start by giving context about the assignment and what you have worked on, your idea’s, …, like a summary in a research paper.
Introduction¶
Welcome to the product manual of the Time Registration blueprint. This blueprint is part of a course I took at the HvA. The idea is that through the use of sensors make a device that employees can use to check in and out. With the data you receive you build a database where you can show the check in/out times on a neat little website. Below this paragraph you will see an image of the product. The design is meant to look like a company building.
Check in and out system
Step 1 Arduino & Docker¶
- Download Arduino IDE for your specific device and follow the instructions on the website.
-
After installing Arduino, you will need to install these libraries: MFRC522 and ArduinoJson.
-
Then we have to download the docker to run the back-end on. My course gave me the docker files, they can be found here: https://gitlab.fdmci.hva.nl/IoT/individual-project/code/individual-project-docker
-
After downloading the files open your terminal, enter the following command:
docker -v
The result should be a docker version.
In the command line navigate to the place you downloaded the docker documents. Do this by typing the following line in the terminal:
cd “
“
Then start the docker program by typing this line in the terminal:
docker-compose up
Open up the docker, you should now see 5 files. Well done! :D
Tip: Test if it works by opening chrome and typing localhost.
Step 2 Solderen¶
The next step for preperation is to solder our Wemos D1 Mini and LED.
Wemos For the Wemos there is a handy tutorial that you can follow that explains the steps and shows you how to do it Soldering the headers on a Wemos D1 Mini
LED For the LED display you can follow this video from the Tech Vegan. How to Solder 16x2 LCD Display Properly\
Step 3 Avengers, assemble your breadboard¶
This is the wiring diagram with all three of the sensors connected.
I would advice to seperate the colours for different power supply types. I used orange for 5v and red for 3v3. It is to prevent confusion and cause magical black smoke to appear.
Step 4 The code and how to use it¶
Wifi¶
Setting up the wifi for your WeMos is an important step. Without it, setting up an online dashboard is gonna be a bit tougher.
First thing you need are the correct clients:
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
After that, enter this in the void setup:
Serial.begin(115200); // Initialize serial communications
WiFi.begin("SSID", "Password"); //SSID and password
Serial.print("starting setup");
// Keep in while-loop while the device is not connected to your accesspoint.
while (WiFi.status() != WL_CONNECTED) {
Serial.println("Waiting for connection status=" + String(WiFi.status()));
delay(1000); // Waiting on connection...
}
Serial.println("Connected! status=" + String(WiFi.status())); // tells you the connection status, 3 is connected.
And this is what you put in the void loop:
WiFiClient client;
HTTPClient httpClient;
httpClient.begin(client, "http://koffiepunthva.nl/api");
int httpCode = httpClient.GET();
if(httpCode == HTTP_CODE_OK) { // HTTP_CODE_OK == 200
String payload = httpClient.getString();
Serial.println(payload);
} else {
Serial.println("Unable to connect :(");
}
delay(5000);
And after setting up yout wifi, you can continue to work on the rest of your sensors.
LCD¶
For the LCD 16x2 I used the following code:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup()
{
// initialize the LCD
lcd.begin();
// Turn on the blacklight and print a message.
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Hello, world!");
Serial.begin(115200);
Serial.println("test");
}
void loop()
{
// Do nothing here...
}
RFID¶
//RFID scanner
#include <MFRC522.h>
#include <ArduinoJson.h>
// define
#define RST_PIN D0 // RST-PIN for RC522 - RFID - SPI - Modul GPIO15
#define SS_PIN D8 // SDA-PIN for RC522 - RFID - SPI - Modul GPIO2
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
void setup() {
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522
}
// Helper routine to dump a byte array as hex values to Serial
void dump_byte_array(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
}
String get_byte_array (byte *buffer, byte bufferSize) {
String UID = "";
for (byte i = 0; i < bufferSize; i++) {
buffer[i] < 0x10 ? " 0" : " ";
char myHex[10] = "";
ltoa(buffer[i], myHex, 16); //convert to c string base 16
UID += String(myHex);
UID += " ";
}
UID.toUpperCase();
return UID;
}
void loop() {
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent()) {
delay(50);
return;
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) {
delay(50);
return;
}
// Show some details of the PICC (that is: the tag/card)
Serial.print("Card UID:");
Serial.println(get_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size));
Serial.println();
delay(1000);
}
LDR¶
This is the code for de LDR that I am using.
#define LDRpin A0 // pin where we connected the LDR and the resistor
int LDRValue = 0; // result of reading the analog pin
void setup() {
Serial.begin(9600); // sets serial port for communication
}
void loop() {
LDRValue = analogRead(LDRpin); // read the value from the LDR
Serial.println(LDRValue); // print the value to the serial port
delay(1500); // wait a little, this was originally 100, but I put it to 1500 so my serial monitor would not be overloaded with small data.
}
Front end¶
Now we have reached the part where we can show our data on the website. This is the output of the data so it is important it is easy to read for the public. The front-end consists of three documents, HTML, CSS and JavaScript.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Blueprint dashboard</title>
<script src="/static/js/app.js" defer></script>
</head>
<body class="dash">
<header>
<section>
<h1>Dashboard Time Registration</h1>
</section>
</header>
<section id="table">
<table>
<thead>
<tr>
<td>Naam</td>
<td>Card id</td>
<td>Tijd</td>
</tr>
</thead>
<tbody></tbody>
</table>
</section>
</body>
</html>
/* All */
*,
*::after,
*::before {
box-sizing: border-box;
}
* {
margin: 0;
padding: 0;
}
html {
width: 100%;
height: 100vh;
}
body {
font-family: 'Open sans', sans-serif;
height: 100vh;
}
/* Index*/
body section#dashboard-button {
position: fixed;
top: 60%;
left: 40%;
}
body section#dashboard-button button {
background-color: #6970db;
/* purple */
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
border-radius: 10px;
}
/* Dashboard */
body.dash header{
position: sticky; /* zo blijft hij op zn plek tijdens het scrollen*/
width: 100%; /* lekker de volle breedte*/
top: 0;
background-color: white;
height: 100px;
}
body.dash header section {
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
body.dash header section h1 {
color: #6970db;
padding: 10px 5px;
}
body.dash section#table{
display: flex;
justify-content: center;
}
.dash td {
border: 1px solid #ddd;
padding: 8px;
}
.dash thead{
padding-top: 12px;
padding-bottom: 12px;
text-align: left;
background-color: #04AA6D;
color: white;
}
// Inez, Open source, goal is to fetch the data, respond in json, made a table and display the table in html code.
const table = document.querySelector('table')
function fetchData(){
return fetch('http://localhost/getdb.php')
.then((response) => response.json())
}
async function tableCreate(){
let html = '';
const data = await fetchData();
console.log(data);
data.forEach(registratie => {
html += `
<tr>
<td>${registratie.naam}</td>
<td>${registratie.card_id}</td>
<td>${registratie.datum}</td>
</tr>
`;
});
table.innerHTML = html;
}
// window.addEventListener()
tableCreate();
I am by no means a Css wizard, but I managed to create a simple and clean looking table.
PHPadmin¶
If you want a database to save your data you will need to set one up. You will need a servername, username, password and dbname. I used the one that my school provided for me.
The first thing I did was design my database in mySQLWorkbench. It looks like this. If you are following this project I would advice to do the same as I did. It is important to have a link between your databases so if you want to connect them you can.
Overview of the database design
After importing it in phpmyadmin it should look like this.
Overview of how the tables will be and function
API Documentation¶
The API is made through your own data and names. In the PHPadmin you fill in the data in the graph like shown and then if you use the servername, username and dbname you can use the data anywhere.
Back end/PHP¶
The back-end of the website is where the magic happens. There are three-ish pages that make up the back-end of the website. Two are php pages that handle the data, the other one is the javascript (that you saw in front-end) and that connect the php data to the html. You can see javascript as the bridge between the two files.
The first file is insert.php.
Insert.php
<?php
// Inez, Open source, goal is to get data to and from phpmyadmin.
$servername = "mariadb";
$username = "root";
$password = "7YKyE8R2AhKzswfN";
$dbname = "iot";
$cardUID = $_GET["cardUID"];
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "INSERT INTO Registratie(card_id,datum) VALUES ('" . $cardUID . "', NOW())";
if ($conn->query($sql) === TRUE) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
echo "Hello! $cardUID is here";
It starts off by making a connection to myphpadmin. After that, it inserts the data to the card_id and datum columns in the database that I have in phpmydamin. Instead of using the arduino to give me the time I used the “Now” so the webbrowser gives me the time and it is less code in my arduino.
You can test if the connection works by filling in:
http://localhost/insert.php?cardUID=8D20FFG08A2S05A
(or one of your own card id’s)
The second part of the php code is getting the data from phpmyadmin and getting it back to php.
//getting data from php and putting it in html
$db= $conn;
$tableName="Registratie";
$columns= ['datum', 'card_id'];
$fetchData = fetch_data($db, $tableName, $columns);
function fetch_data($db, $tableName, $columns){
if(empty($db)){
$msg= "Database connection error";
}elseif (empty($columns) || !is_array($columns)) {
$msg="columns Name must be defined in an indexed array";
}elseif(empty($tableName)){
$msg= "Table Name is empty";}
};
$conn->close();
?>
getdb.php
This document is going to get the data from phpmyadmin and print it in the console so that the javascript can put it into html.
<?php
// Inez, Open source, goal is to put all data from phpmyadmin in to an array and print it in the console.
$servername = "mariadb";
$username = "root";
$password = "7YKyE8R2AhKzswfN";
$dbname = "iot";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT * FROM `Registratie` INNER JOIN `Gebruiker`ON Registratie.card_id = Gebruiker.card_id ";
$result = $conn->query($sql);
$data[] = array();
//$datum[] = array();
//$card_id[] = array();z
$counter = 0;
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
//echo $row["datum"] . " " . $row["card_id"];
// $data[] = $row;
// $card_id[] = $row["card_id"];
// $datum[] = $row["datum"];
$data[$counter]["datum"] = $row["datum"];
$data[$counter]["card_id"] = $row["card_id"];
$data[$counter]["naam"] = $row["naam"];
$counter++;
}
} else {
echo "0 results";
}
$conn->close();
print_r(json_encode($data));
?>
Step 5 Bob the builder, buildt your case¶
Making the box¶
So before we can even start to make the box we have to think what we want it to look like. So I used makerscase.com and Adobe Illustrator to make a cut out drawing of my box.
These are the specifics: (all outside dimensions) - Width: 120.12mm - Height: 126mm - Depth: 92,07mm
- Material thickness: 3mm (but is personal choice)
- Closed box
- Number of bends: 4
- Bend radius: 35mm
- Finger size: highest possible
- Cut line width: 0.25mm
This drawing has boxes for the sensors and the LCD 16x2 screen.
The material I used was a fibre wood plank around 4mm in thickness. I wanted a sturdy box as it is supposed to be outside and should be able to withstand some weather or a lot of use inside the office.
Cut the box¶
I used the laser cutter at the Makers Lab at the TTH. I used a 4mm fibre wood plank. The printing took about 20 minutes, at 75% speed of cutting and 80% on scanning. The program I used had pre-set settings and I used those. Do remember, if you have more than 35mm bend radius, it might take longer, all those bends have to be individually cut.
Taking everything into account (setting up, framing it right, weighing down the wood and preparing everything) it took me about an hour and a half.
In the program I used the pre-set setting for my type of wood.
Finish the box¶
First prototype design
Due to not having a lot of time this is my first prototype, ~~without the room for the sensors.~~
Extra¶
There were some things that I was not able to fix.
Failure
The first thing was that I could not get a wifi manager to work, or let the wifi work at school. Not even with a hot spot from my phone. It would only work from home with my own wifi.
Failure
The second thing that did not want to work was the data sending from my wemos to the back-end. This is probably a combination of wifi and the firewall.
Though not everything went according to plan, I did put my energy to good use. What I was good at I put more work in, for example the UI and the physical design part.