From the previous article, now we apply to the real world application. The time attendance machine which uses RFID is a good example. This article demonstrate you to how to call web service provider from Arduino and how to plug the Ethernet shield, LCD shield and RFID module to Arduino together.
The RFID time attendance reads tag key and send tag number of computer for request employee name and then display employee name and time on the LCD. After computer receive tag number, program find employee ID and record employee tag them to excel and then send the employee name back to the client.
In this article, the process of communication is web service by soap message. The computer server contains Microsoft excel file contain employee data. When the server receives a tag number, the web service program finds the employee name from excel file and write tag time to excel file while send back employee name.RFID Module
The Radio Frequency Identification (RFID) Reader Module is a RFID transponder tags reader. RFID Module use for application that need identify system such as access control, inventory tracking, user identification, payment systems and etc.
The example and library of RFID-RC522 Funduino is available here : https://github.com/miguelbalboa/rfid. RFID-RC522 communication with arduino via SPI, but we can change the chip select pin by software. So that, we can connect by parallel with arduino ethernet shield together without conflict. The arduino ethernet shield use SPI pins and PIN10 for chip select so the RFID module chip select will be moved to the other pin.
Arduino Ethernet Shield
The last Article, Call web service with Arduino using SOAP message over HTTP we use arduino ethernet shield to connect to ethernet for call web service provider, now we use the same environment for web service.
LCD Key Shield
The LCD key shield use for display a employee name and tag time after connecting to web service provider.
The LCD key shield use pin 4, 5, 6, 7, 8, 9 and 10 of the Arduino that conflict with the Ethernet shield on pin 10. Pin 10 of the Ethernet shield uses for the chip select and LCD key shield use for blacklight. So, we have to disconnect pin 10 of LCD shield.
The LCD key shield use pin 4, 5, 6, 7, 8, 9 and 10 of the Arduino that conflict with the Ethernet shield on pin 10. Pin 10 of the Ethernet shield uses for the chip select and LCD key shield use for blacklight. So, we have to disconnect pin 10 of LCD shield.
So, Connect everything together
For the RFID reader module connect pins by flowing:
The arduino ethernet shield and RFID reader module use the same pin of SPI, so we will need to disable one to use the other. I define RF_SS_PIN to A1 for disable/enable RFID module and ETH_SS_PIN ethernet shield chip select on pin 10 by default so that we have to set pinMode() to output. In the loop() call readCard() to read RFID tag until rfid.isCard() is true. When rfid.isCard() is true program construct string of tag key from a tag serial number array then call web service provider with send the key string to request employee name from server. Before call web service we need to disable RFID by set RF_SS_PIN to HIGH and endable by set ETH_SS_PIN to LOW. Then after receive employee name from web service provider we need disable ethernet shield and enable RFID Module as previously.
The employee service has one configuration file: config.properties contain path that point to excel file.
- MOSI: Pin 11 / ICSP-4
- MISO: Pin 12 / ICSP-1
- SCK: Pin 13 / ISCP-3
- SS: Pin A1 (Configurable)
- RST: Pin A0 (Configurable)
#include <Ethernet.h> #include <EthernetClient.h> #include <SPI.h> #include "RFID.h" #include <LiquidCrystal.h> #define RF_SS_PIN A1 #define ETH_SS_PIN 10 #define RF_RST_PIN A0 #define btnRIGHT 0 #define btnUP 1 #define btnDOWN 2 #define btnLEFT 3 #define btnSELECT 4 #define btnNONE 5 LiquidCrystal lcd(8, 9, 4, 5, 6, 7); RFID rfid(RF_SS_PIN, RF_RST_PIN); int serNum0; int serNum1; int serNum2; int serNum3; int serNum4; int lcd_key = 0; int adc_key_in = 0; byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192, 168, 1, 177); IPAddress _dns(192, 168, 1, 176); char host[] = "192.168.1.176"; uint16_t port = 8080; //http://localhost:8080/EmployeeService/services/EmployeeRegisterService String path = "/EmployeeService/services/EmployeeRegisterService"; EthernetClient client; int read_LCD_buttons() { adc_key_in = analogRead(0); if (adc_key_in > 1000) return btnNONE; // For V1.0 comment the other threshold and use the one below: if (adc_key_in < 50) return btnRIGHT; if (adc_key_in < 195) return btnUP; if (adc_key_in < 380) return btnDOWN; if (adc_key_in < 555) return btnLEFT; if (adc_key_in < 790) return btnSELECT; return btnNONE; } void readCard() { if (rfid.isCard()) { //Serial.println(" card"); if (rfid.readCardSerial()) { if (rfid.serNum[0] != serNum0 && rfid.serNum[1] != serNum1 && rfid.serNum[2] != serNum2 && rfid.serNum[3] != serNum3 && rfid.serNum[4] != serNum4) { Serial.println(" "); Serial.println("Card found"); serNum0 = rfid.serNum[0]; serNum1 = rfid.serNum[1]; serNum2 = rfid.serNum[2]; serNum3 = rfid.serNum[3]; serNum4 = rfid.serNum[4]; String args = String(serNum0) + String(serNum1) + String(serNum2) + String(serNum3) + String(serNum4); digitalWrite(RF_SS_PIN, HIGH); digitalWrite(ETH_SS_PIN, LOW); Serial.println("calling service ......"); String result = callService(args); Serial.println("result:" + result); digitalWrite(ETH_SS_PIN, HIGH); digitalWrite(RF_SS_PIN, LOW); String name = result.substring(0, result.indexOf(',')); String time = result.substring(result.indexOf(',') + 1); name = name.substring(result.indexOf(':') + 1); time = time.substring(result.indexOf(':') + 1); lcd.clear(); lcd.print(name+" "+time); delay(4000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Welcome"); } else { /* If we have the same ID, just write a dot. */ Serial.print("."); } } } // Serial.println(" halt"); rfid.halt(); } String callService(String args) { String soapMsg1 ="<?xml version=\"1.0\" encoding=\"UTF-8\"?><soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns1=\"http://webservice.ctrl\"><soapenv:Header/><soapenv:Body><ns1:service>"; String a = "<arg0>" + args + "</arg0>"; String soapMsg2 = "</ns1:service></soapenv:Body></soapenv:Envelope>"; Serial.print("connect to :"); Serial.print(host); Serial.print(":"); Serial.println(port); if (client.connect(host, port)) { Serial.println("connected."); Serial.println("POST " + path + " HTTP/1.1"); Serial.print("Host:"); Serial.println(host); Serial.println("Content-Type: text/xml; charset=utf-8"); Serial.print("Content-Length: "); Serial.println(soapMsg1.length() + a.length() + soapMsg2.length()); Serial.println("Connection: keep-alive"); Serial.print("SOAPAction: \"http://"); Serial.print(host); Serial.print(":"); Serial.print(port); Serial.print(path); Serial.println("\""); Serial.println(""); Serial.print(soapMsg1); Serial.print(a); Serial.println(soapMsg2); Serial.println(""); client.println("POST " + path + " HTTP/1.1"); client.print("Host:"); client.println(host); client.println("Content-Type: text/xml; charset=utf-8"); client.print("Content-Length: "); client.println(soapMsg1.length() + a.length() + soapMsg2.length()); client.println("Connection: keep-alive"); client.print("SOAPAction: \"http://"); client.print(host); client.print(":"); client.print(port); client.print(path); client.println("\""); client.println(""); client.print(soapMsg1); client.print(a); client.println(soapMsg2); client.println(""); } else { Serial.println(); Serial.println("Fail to connect."); } String ret; while (true) { if (client.available()) { ret = client.readStringUntil('{'); ret = client.readStringUntil('}'); Serial.println(ret); Serial.println(); Serial.println("disconnecting."); client.stop(); break; } if (!client.connected()) { Serial.println(); Serial.println("disconnecting."); client.stop(); break; } } return ret; } void setup() { pinMode(RF_SS_PIN, OUTPUT); pinMode(RF_RST_PIN, OUTPUT); pinMode(ETH_SS_PIN, OUTPUT); Serial.begin(9600); while (!Serial) { ; } Serial.println("begin."); lcd.begin(16, 1); lcd.setCursor(0, 0); lcd.print("Welcome"); Ethernet.begin(mac, ip, _dns); SPI.begin(); delay(1000); rfid.init(); Serial.println("end setup"); } void loop() { readCard(); }
The arduino ethernet shield and RFID reader module use the same pin of SPI, so we will need to disable one to use the other. I define RF_SS_PIN to A1 for disable/enable RFID module and ETH_SS_PIN ethernet shield chip select on pin 10 by default so that we have to set pinMode() to output. In the loop() call readCard() to read RFID tag until rfid.isCard() is true. When rfid.isCard() is true program construct string of tag key from a tag serial number array then call web service provider with send the key string to request employee name from server. Before call web service we need to disable RFID by set RF_SS_PIN to HIGH and endable by set ETH_SS_PIN to LOW. Then after receive employee name from web service provider we need disable ethernet shield and enable RFID Module as previously.
Employee Service
The employee web service develop by java deploy on apache tomcat 7 as previous article. The employee service use apache poi library for read and write excel of employee file. A excel of employee file contains employee name , id , address and etc on sheet1 and store employee tag time on sheet2. When employee service receive tag string from arduino then program find employee name from excel sheet1 and then write tag time into the last row of sheet2. After write excel and close file, program send employee name back to arduino.#include <Ethernet.h> #include <EthernetClient.h> #include <SPI.h> #include "RFID.h" #include <LiquidCrystal.h> #define RF_SS_PIN A1 #define ETH_SS_PIN 10 #define RF_RST_PIN A0 #define btnRIGHT 0 #define btnUP 1 #define btnDOWN 2 #define btnLEFT 3 #define btnSELECT 4 #define btnNONE 5 LiquidCrystal lcd(8, 9, 4, 5, 6, 7); RFID rfid(RF_SS_PIN, RF_RST_PIN); int serNum0; int serNum1; int serNum2; int serNum3; int serNum4; int lcd_key = 0; int adc_key_in = 0; byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192, 168, 1, 177); IPAddress _dns(192, 168, 1, 176); char host[] = "192.168.1.176"; uint16_t port = 8080; //http://localhost:8080/EmployeeService/services/EmployeeRegisterService String path = "/EmployeeService/services/EmployeeRegisterService"; EthernetClient client; int read_LCD_buttons() { adc_key_in = analogRead(0); if (adc_key_in > 1000) return btnNONE; // For V1.0 comment the other threshold and use the one below: if (adc_key_in < 50) return btnRIGHT; if (adc_key_in < 195) return btnUP; if (adc_key_in < 380) return btnDOWN; if (adc_key_in < 555) return btnLEFT; if (adc_key_in < 790) return btnSELECT; return btnNONE; } void readCard() { if (rfid.isCard()) { //Serial.println(" card"); if (rfid.readCardSerial()) { if (rfid.serNum[0] != serNum0 && rfid.serNum[1] != serNum1 && rfid.serNum[2] != serNum2 && rfid.serNum[3] != serNum3 && rfid.serNum[4] != serNum4) { Serial.println(" "); Serial.println("Card found"); serNum0 = rfid.serNum[0]; serNum1 = rfid.serNum[1]; serNum2 = rfid.serNum[2]; serNum3 = rfid.serNum[3]; serNum4 = rfid.serNum[4]; String args = String(serNum0) + String(serNum1) + String(serNum2) + String(serNum3) + String(serNum4); digitalWrite(RF_SS_PIN, HIGH); digitalWrite(ETH_SS_PIN, LOW); Serial.println("calling service ......"); String result = callService(args); Serial.println("result:" + result); digitalWrite(ETH_SS_PIN, HIGH); digitalWrite(RF_SS_PIN, LOW); String name = result.substring(0, result.indexOf(',')); String time = result.substring(result.indexOf(',') + 1); name = name.substring(result.indexOf(':') + 1); time = time.substring(result.indexOf(':') + 1); lcd.clear(); lcd.print(name+" "+time); delay(4000); lcd.clear(); lcd.setCursor(0, 0); lcd.print("Welcome"); } else { /* If we have the same ID, just write a dot. */ Serial.print("."); } } } // Serial.println(" halt"); rfid.halt(); } String callService(String args) { String soapMsg1 ="<?xml version=\"1.0\" encoding=\"UTF-8\"?><soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns1=\"http://webservice.ctrl\"><soapenv:Header/><soapenv:Body><ns1:service>"; String a = "<arg0>" + args + "</arg0>"; String soapMsg2 = "</ns1:service></soapenv:Body></soapenv:Envelope>"; Serial.print("connect to :"); Serial.print(host); Serial.print(":"); Serial.println(port); if (client.connect(host, port)) { Serial.println("connected."); Serial.println("POST " + path + " HTTP/1.1"); Serial.print("Host:"); Serial.println(host); Serial.println("Content-Type: text/xml; charset=utf-8"); Serial.print("Content-Length: "); Serial.println(soapMsg1.length() + a.length() + soapMsg2.length()); Serial.println("Connection: keep-alive"); Serial.print("SOAPAction: \"http://"); Serial.print(host); Serial.print(":"); Serial.print(port); Serial.print(path); Serial.println("\""); Serial.println(""); Serial.print(soapMsg1); Serial.print(a); Serial.println(soapMsg2); Serial.println(""); client.println("POST " + path + " HTTP/1.1"); client.print("Host:"); client.println(host); client.println("Content-Type: text/xml; charset=utf-8"); client.print("Content-Length: "); client.println(soapMsg1.length() + a.length() + soapMsg2.length()); client.println("Connection: keep-alive"); client.print("SOAPAction: \"http://"); client.print(host); client.print(":"); client.print(port); client.print(path); client.println("\""); client.println(""); client.print(soapMsg1); client.print(a); client.println(soapMsg2); client.println(""); } else { Serial.println(); Serial.println("Fail to connect."); } String ret; while (true) { if (client.available()) { ret = client.readStringUntil('{'); ret = client.readStringUntil('}'); Serial.println(ret); Serial.println(); Serial.println("disconnecting."); client.stop(); break; } if (!client.connected()) { Serial.println(); Serial.println("disconnecting."); client.stop(); break; } } return ret; } void setup() { pinMode(RF_SS_PIN, OUTPUT); pinMode(RF_RST_PIN, OUTPUT); pinMode(ETH_SS_PIN, OUTPUT); Serial.begin(9600); while (!Serial) { ; } Serial.println("begin."); lcd.begin(16, 1); lcd.setCursor(0, 0); lcd.print("Welcome"); Ethernet.begin(mac, ip, _dns); SPI.begin(); delay(1000); rfid.init(); Serial.println("end setup"); } void loop() { readCard(); }
The employee service has one configuration file: config.properties contain path that point to excel file.
config.employee.file=C:/Users/Default/Documents/employee.xls
Comments
Post a Comment