There are many ways to communicate between two devices. One of that is the efficient, simple and cheap way: Web Service. Web Service is a software system designed for support communication over a network. To communicate between Arduino and host computer, we can apply Web Service which uses Arduino Ethernet Shield. The example from http://arduino.cc/en/Main/ArduinoEthernetShield describe how to call web server over HTTP protocol. We are able to apply to the call to a web service provider by sending a SOAP message.
This article shows how to call the web service provider with Arduino and ethernet shield.
Server-side install web service provider, developed with Java language and deploy on apache tomcat and client-side is an Arduino with Ethernet Shield installed.
“GET” is a method of request “/search?q=arduino” is URI which is a path on server to call,
“HTTP/1.1” is protocol/version.
“Host” tell server what host is request to and
“Connection:” tell the server state of the connection.
And the last “client.println();” is telling server for the end of the message.
The “GET” method tells the web server this is a request for some information. There are several methods which you can find an information here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
Then, if the server and the request path are available, we will receive some message with starting by “HTTP/1.1 200 OK”.
So, if we need to send web server some data, we can use “POST” method look like:
“Content-length” tell the server how many characters that client send to. In this case is length of word “q=arduino%20web%20service” which is 20. The server reads request data and count to “20” character and terminate the request. Then, if “Content-length” is not equal to the data character length the server will lose data or connection is timed out because server waiting until data is full of length.
“client.println();” after “client.println("Content-type: text/html");” is telling the server to start to receive an input data. And the last “client.println();” is telling server for the end of the message.
An Envelope element that identifies the XML document as a SOAP message. A Header element that contains header information. A Body element that contains call and response information. And a Fault element containing errors and status information.
The "SOAPAction" is from the WSDL file of the web service provider under path "/wsdl:definitions/ wsdl:binding/wsdlsoap:operation/soapaction". Below is an example of WSDLfile.
An example below creates an XML in the SOAP format with converting the analog value of pin A0 to String parameters of soap message.
Then use EthernetClient write command to call to the web service provider and wait for a response.
In the loop, starting to read an analog value from pin 0 and count. Then call the callService() function by passing String of analog value and count and waiting for 2 second.
So I created a simple web service project with Java to receive a request and responds some information back to client. The web service provider receives two parameters from Arduino and print out to the console, and then combine into a JSON string before return it back.
This article shows how to call the web service provider with Arduino and ethernet shield.
Server-side install web service provider, developed with Java language and deploy on apache tomcat and client-side is an Arduino with Ethernet Shield installed.
Arduino and Ethernet Shield
From WebClient in Arduino Example, demonstrate how to call web server by using an ethernet shield. Like use telnet command call to server with puting some instruction command within the request.client.println("GET /search?q=arduino%20web%20service HTTP/1.1"); client.println("Host: www.google.com"); client.println("Connection: close"); client.println();
“HTTP/1.1” is protocol/version.
“Host” tell server what host is request to and
“Connection:” tell the server state of the connection.
And the last “client.println();” is telling server for the end of the message.
The “GET” method tells the web server this is a request for some information. There are several methods which you can find an information here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
Then, if the server and the request path are available, we will receive some message with starting by “HTTP/1.1 200 OK”.
So, if we need to send web server some data, we can use “POST” method look like:
client.println("POST /search HTTP/1.1"); client.println("Host: www.google.com"); client.println("Connection: close"); client.println("Content-length: 20"); client.println("Content-type: text/html"); client.println(); client.println("q=arduino%20web%20service"); client.println();
“Content-length” tell the server how many characters that client send to. In this case is length of word “q=arduino%20web%20service” which is 20. The server reads request data and count to “20” character and terminate the request. Then, if “Content-length” is not equal to the data character length the server will lose data or connection is timed out because server waiting until data is full of length.
“client.println();” after “client.println("Content-type: text/html");” is telling the server to start to receive an input data. And the last “client.println();” is telling server for the end of the message.
SOAP Message Over HTTP
An information about SOAP are here: http://www.w3schools.com/soap/ . SOAP is a protocol for accessing a Web Service. SOAP Message is an ordinary XML document containing the elements Envelope, Header, Body and Fault.<?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Header> ... </soap:Header> <soap:Body> ... <soap:Fault> ... </soap:Fault> </soap:Body> </soap:Envelope>
Why SOAP Message?
SOAP Message without the hassle of communicating across platform or programming language. We have just sent the xml message in the correct SOAP format to the Web Service endpoint which disregard about what OS of a server or development language of provider.How to call Web Service with SOAP Message?
Sending soap message to the web service server is the same as request data from web server. However, we use "POST" method to send the soap message to the server. The following is a send message:POST /SimpleService/services/DataLoggerService HTTP/1.1 Host:192.168.1.176 Content-Type: text/xml; charset=utf-8 Content-Length: 253 Connection: close SOAPAction: "" <soapenv:envelope xmlns:ns1="http://test" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:header><soapenv:body><ns1:log><arg0>167</arg0><arg1> 3</arg1></ns1:log></soapenv:body></soapenv:header>
The "SOAPAction" is from the WSDL file of the web service provider under path "/wsdl:definitions/ wsdl:binding/wsdlsoap:operation/soapaction". Below is an example of WSDLfile.
<wsdl:definitions xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://test" xmlns:intf="http://test" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://test"> <!-- WSDL created by Apache Axis version: 1.4 Built on Apr 22, 2006 (06:55:48 PDT) --> <wsdl:message name="logRequest"> <wsdl:part name="temp" type="xsd:string"></wsdl:part> <wsdl:part name="time" type="xsd:string"></wsdl:part> </wsdl:message> <wsdl:message name="logResponse"> <wsdl:part name="logReturn" type="xsd:string"></wsdl:part> </wsdl:message> <wsdl:portType name="DataLoggerService"> <wsdl:operation name="log" parameterOrder="temp time"> <wsdl:input message="impl:logRequest" name="logRequest"></wsdl:input> <wsdl:output message="impl:logResponse" name="logResponse"></wsdl:output> </wsdl:operation> </wsdl:portType> <wsdl:binding name="DataLoggerServiceSoapBinding" type="impl:DataLoggerService"> <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="log"> <wsdlsoap:operation soapAction=""/> <wsdl:input name="logRequest"> <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://test" use="encoded"/> </wsdl:input> <wsdl:output name="logResponse"> <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://test" use="encoded"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="DataLoggerServiceService"> <wsdl:port binding="impl:DataLoggerServiceSoapBinding" name="DataLoggerService"> <wsdlsoap:address location="http://localhost:8080//SimpleService/services/DataLoggerService"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
Arduino Web Service Client
An example below creates an XML in the SOAP format with converting the analog value of pin A0 to String parameters of soap message.
Then use EthernetClient write command to call to the web service provider and wait for a response.
#include <Ethernet.h> #include <EthernetClient.h> #include <SPI.h> #define ETH_SS_PIN 10 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; String path = "/SimpleService/services/DataLoggerService"; int count = 0; EthernetClient client; void setup() { pinMode(ETH_SS_PIN, OUTPUT); digitalWrite(ETH_SS_PIN, LOW); Serial.begin(9600); while (!Serial) { ; } Serial.println("Start ethernet"); Ethernet.begin(mac, ip, _dns); delay(1000); } String callService(String arg1, String arg2) { String soapMsg1 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns1=\"http://test\"><soapenv:Header/><soapenv:Body><ns1:log>"; String a = "<arg0>" + arg1 + "</arg0><arg1>" + arg2 + "</arg1>"; String soapMsg2 = "</ns1:log></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 loop() { int value = analogRead(0); count += 1; Serial.println("calling service ......"); String result = callService(String(value), String(count)); Serial.println("result:" + result); Serial.println("waiting for 2 sec ....."); delay(2000); }
In the loop, starting to read an analog value from pin 0 and count. Then call the callService() function by passing String of analog value and count and waiting for 2 second.
Web Service Provider
The advantages of using a soap message is not depends on platform or technology.So I created a simple web service project with Java to receive a request and responds some information back to client. The web service provider receives two parameters from Arduino and print out to the console, and then combine into a JSON string before return it back.
public class DataLoggerService { public String log(String temp,String time){ String result = "{Temp:"+temp+",Time:"+time+"}"; System.out.println(result); return result; } }
Download
- Arduino: Create on Arduino 1.1 and testing with Arduino Uno + Arduino Ethernet Shield (W5100)
- Web Service Provider: Develop by Java 7, Eclipse, Deploy on Apache tomcat 7
Comments
Post a Comment