Hi everybody,

In this post I'm gonna share with you my new application that simple embedded server to control and measure somethings over the internet.

Nowadays as you know IoT is popular topic and may become more popular. Even there is a motto that "by 2020 50 billion devices will be connected to the internet" recently I saw it is changed as 37 billion. Why changed or who counts these devices I don't know. Actually I don't believe that. :) Because IoT is a just name, alias, motto etc. These applications, sytems, techniques already were have. Today with IoT these are highlighted. Anyway, it is good for us, because by IoT trend so many tools, kits and hardwares which releated IoT became cheaper and available.

Of course IoT pushed technology companies to develop products, kits, modules, hardwares for IoT applications, cheap as well. One of them is Tiva Connected launchpad. It is really has a wonderful price/performance rate. It is just $19.99, it has a so many features and also has an ethernet hardware. So by just using launchpad you can make internet applications over the ethernet. Anyway I'm not a saller for TI I just had it and I used it. Lets talk about application.

Step 1: Web Server Application

Picture of Web Server Application

As you know servers are big and expensive systems. These are serve us web sites, audios, videos, files etc. Comparing to web servers launchpad is really simple. With launchpad we can't serve so complex and functional web sites or files. We don't care that because we just want control electrical devices and measure some quantities over the internet.

In this context I made simple web site. You can see the screenshot of the site above.

As you see site is a very simple. It just has a few texts, buttons and geometric draws. Launchpad has a four LEDs and two push buttons for general purposes usage. On the web site I used buttons to control LEDs and filled circles to see LEDs and buttons situations. Also text elements are used to give information. You can see HTML and JavaScript codes of the site below.

<!DOCTYPE html>
<html>
<head>
<title>Erhan Web Page</title>
<script>
var led1, x1, led2, x2, led3, x3, led4, x4;
function GetSwitchState()
{
	nocache = led1 + led2 + led3 + led4 + "&nocache="+ Math.random() * 1000000;
	var request = new XMLHttpRequest();
	request.onreadystatechange = function() 
	{
		if (this.readyState == 4) 
		{
			if (this.status == 200) 
			{
				if (this.responseText != null)
				{
					if (this.responseText.indexOf("LED1ON") > -1)
					{
						document.getElementById("LED1").style.fill = "yellow";
					}
					else 
					{
						document.getElementById("LED1").style.fill = "black";
					}
				
					if (this.responseText.indexOf("LED2ON") > -1)
					{
						document.getElementById("LED2").style.fill = "yellow";
					}
					else 
					{
						document.getElementById("LED2").style.fill = "black";
					}
	
					if (this.responseText.indexOf("LED3ON") > -1)
					{
						document.getElementById("LED3").style.fill = "yellow";
					}
					else
					{
						document.getElementById("LED3").style.fill = "black";
					}
	
					if (this.responseText.indexOf("LED4ON") > -1)
					{
						document.getElementById("LED4").style.fill = "yellow";
					}
					else 
					{
						document.getElementById("LED4").style.fill = "black";
					}
	
					if (this.responseText.indexOf("S1:ON") > -1)
					{
						document.getElementById("SW1").style.fill = "red";
						document.getElementById("text1").innerHTML ="SW1:ON";
					}
					else
					{
						document.getElementById("SW1").style.fill = "white";
						document.getElementById("text1").innerHTML ="SW1:OFF";
					}
	
					if (this.responseText.indexOf("S2:ON") > -1)
					{
						document.getElementById("SW2").style.fill = "red";
						document.getElementById("text2").innerHTML ="SW2:ON";
					}
					else
					{
						document.getElementById("SW2").style.fill = "white";
						document.getElementById("text2").innerHTML ="SW2:OFF";
					}
				}
			}
		}
	}
	request.open("GET", "ajax_switch" + nocache, true);
	request.send(null);
	setTimeout('GetSwitchState()', 500);
}

function SetLEDStates(num)
{
	switch(num)
	{
		case 1:
			if(x1==1)
			{
				led1="&LED1ON";
				x1=0;
			}
			else
			{
				led1="&LED1OFF";
				x1=1;
			}
		break;
		
		case 2:
			if(x2==1)
			{
				led2="&LED2ON";
				x2=0;
			}
			else
			{
				led2="&LED2OFF";
				x2=1;
			}
		break;
			
		case 3:
			if(x3==1)
			{
				led3="&LED3ON";
				x3=0;
			}
			else
			{
				led3="&LED3OFF";
				x3=1;
			}
		break;
		
		case 4:
			if(x4==1)
			{
				led4="&LED4ON";
				x4=0;
			}
			else
			{
				led4="&LED4OFF";
				x4=1;
			}
		break;
		
		case 0: 
			led1="&LED1OFF";
			x1=1;
			led2="&LED2OFF";
			x2=1;
			led3="&LED3OFF";
			x3=1;
			led4="&LED4OFF";
			x4=1;
		break;
	}
}
</script>
</head>
<body onload="GetSwitchState();SetLEDStates(0);">
	<center>
		<h1>Erhan YILMAZ AJAX Test Application</h1>
		<div id="text1"></div>
		<svg width="40" height="40"><circle id="SW1" cx="20" cy="20" r="10"stroke="black" stroke-width="4" fill="white"/></svg>
		<div id="text2"></div>
		<svg width="40" height="40"><circle id="SW2" cx="20" cy="20" r="10"stroke="black" stroke-width="4" fill="white"/></svg>
		<p><button type="L1" onclick="SetLEDStates(1);">LED1</button>&nbsp;
		<button type="L2" onclick="SetLEDStates(2);">LED2</button>&nbsp;
		<button type="L3" onclick="SetLEDStates(3);">LED3</button>&nbsp;
		<button type="L4" onclick="SetLEDStates(4);">LED4</button>&nbsp;</p>
		<p><center>
			<svg width="50" height="50"><circle id="LED1" cx="20" cy="20" r="10"stroke="green" stroke-width="4" fill="black"/></svg>
			<svg width="50" height="50"><circle id="LED2" cx="20" cy="20" r="10"stroke="green" stroke-width="4" fill="black"/></svg>
			<svg width="50" height="50"><circle id="LED3" cx="20" cy="20" r="10"stroke="green" stroke-width="4" fill="black"/></svg>
			<svg width="50" height="50"><circle id="LED4" cx="20" cy="20" r="10"stroke="green" stroke-width="4" fill="black"/></svg>
		</center></p>
	</center></body>
</html>

As you see on the codes GetSwitchState function create XMLHttpRequest request and set himself to run periodically by setTimeout function. Time interval I chose 500ms for this application. If you want you can change the value. When page onload event once GetSwitchState function run and it is go on... This is the main operation of codes, and ajax technique. Thus you can use the web site without always refresh. Check out here to learn detailed info about ajax.

Step 2: Source Code of Application

At the embedded side I used energia platform to develop application codes. As you know or not "Energia is an open-source electronics prototyping platform started by Robert Wessels in January of 2012 with the goal to bring the Wiring and Arduino framework to the Texas Instruments MSP430 based LaunchPad." So it is arduino sketch based, easy to use and free platform. Energia almost completely compatible with arduino examples. In a short time you can switch your application from Arduino to TI Launchpads. You can check out heresupported kits, examples and more info.

Anyway, as i said, i wrote my codes energia. It is based by examples codes. You can easily understand and change whatever you want. You can see codes below.

/****************************************************************
 * Designer: Erhan YILMAZ					*
 * Application: Tiva Connected Launchpad Web Server Application	*
 * Date: 19-08-2015						*
 * Version: 1.0							*
 * Description:	Web server application with Tiva connected      *
 * launchpad. Codes writen on energia			    *
 * *************************************************************/

#define LED1 PN_1
#define LED2 PN_0
#define LED3 PF_4
#define LED4 PF_0

#include "Ethernet.h"
// Prototypes
void printEthernetData();
void GetSwitchState(EthernetClient);
void SetLEDStates(EthernetClient, String);

EthernetServer server(80);
int statusConfig = 0;


void setup() {
  Serial.begin(115200);    

  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
  pinMode(PUSH1, INPUT_PULLUP);
  pinMode(PUSH2, INPUT_PULLUP);

  Serial.println("Connecting to Ethernet....");  

  Ethernet.begin(0);
  // For static ip use below code
  /*
  IPAddress ip = IPAddress(10,2,7,158);
  IPAddress dns = IPAddress(10,2,7,200);
  IPAddress gw = IPAddress(10,2,7,254);
  IPAddress mask = IPAddress(255,255,0,0);
  Ethernet.begin(0, ip, dns, gw);
  */
  server.begin();
  printEthernetData();
}

EthernetClient client;
String HTTP_req;            // stores the HTTP request
void loop() 
{
  client = server.available();

  if (client)
  {                             // if you get a client,
    Serial.print("new client on port ");           // print a message out the serial port
    Serial.println(client.port());
    String currentLine = "";                // make a String to hold incoming data from the client
    boolean newConnection = true;     // flag for new connections
    unsigned long connectionActiveTimer;  // will hold the connection start time

    boolean currentLineIsBlank = true;
    while (client.connected())
    {       // loop while the client's connected
      if (newConnection)
      {                 // it's a new connection, so
        connectionActiveTimer = millis(); // log when the connection started
        newConnection = false;          // not a new connection anymore
      }
      if (!newConnection && connectionActiveTimer + 1000 < millis())
      { 
        // if this while loop is still active 1000ms after a web client connected, something is wrong
        break;  // leave the while loop, something bad happened
      }


      if (client.available())
      {             // if there's bytes to read from the client,    
        char c = client.read();             // read a byte, then
        // This lockup is because the recv function is blocking.
        Serial.print(c);
        HTTP_req += c;  // save the HTTP request 1 char at a time
        // last line of client request is blank and ends with \n
        // respond to client only after last line received
        if (c == '\n' && currentLineIsBlank)
        {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: keep-alive");
          client.println();
          // AJAX request for switch state
          if (HTTP_req.indexOf("ajax_switch") > -1)
          {
            // read switch state and send appropriate paragraph text
            GetSwitchState(client);
            SetLEDStates(client, HTTP_req);

          }
          else 
          {  // HTTP request for web page
            // send web page - contains JavaScript with AJAX calls
            client.println("<!DOCTYPE html>");
            client.println("<html>");
            client.println("<head>");
            client.println("<title>Erhan Web Page</title>");
            client.println("<script>");
            client.println("var led1, x1, led2, x2, led3, x3, led4, x4;");
            client.println("function GetSwitchState() {");
            client.println("nocache = led1 + led2 + led3 + led4 + \"&nocache=\"\+ Math.random() * 1000000;");
            client.println("var request = new XMLHttpRequest();");
            client.println("request.onreadystatechange = function() {");
            client.println("if (this.readyState == 4) {");
            client.println("if (this.status == 200) {");
            client.println("if (this.responseText != null) {");            
            client.println("if (this.responseText.indexOf(\"LED1ON\") > -1){document.getElementById(\"LED1\").style.fill = \"yellow\";}");
            client.println("else {document.getElementById(\"LED1\").style.fill = \"black\";}");
            client.println("if (this.responseText.indexOf(\"LED2ON\") > -1){document.getElementById(\"LED2\").style.fill = \"yellow\";}");
            client.println("else {document.getElementById(\"LED2\").style.fill = \"black\";}");
            client.println("if (this.responseText.indexOf(\"LED3ON\") > -1){document.getElementById(\"LED3\").style.fill = \"yellow\";}");
            client.println("else {document.getElementById(\"LED3\").style.fill = \"black\";}");
            client.println("if (this.responseText.indexOf(\"LED4ON\") > -1){document.getElementById(\"LED4\").style.fill = \"yellow\";}");
            client.println("else {document.getElementById(\"LED4\").style.fill = \"black\";}");
            client.println("if (this.responseText.indexOf(\"S1:ON\") > -1){document.getElementById(\"SW1\").style.fill = \"red\";document.getElementById(\"text1\")\.innerHTML =\"SW1:ON\";}");
            client.println("else {document.getElementById(\"SW1\").style.fill = \"white\"; document.getElementById(\"text1\")\.innerHTML =\"SW1:OFF\";}");
            client.println("if (this.responseText.indexOf(\"S2:ON\") > -1){document.getElementById(\"SW2\").style.fill = \"red\"; document.getElementById(\"text2\")\.innerHTML =\"SW2:ON\";}");
            client.println("else {document.getElementById(\"SW2\").style.fill = \"white\"; document.getElementById(\"text2\")\.innerHTML =\"SW2:OFF\";}");
            client.println("}}}}");
            client.println("request.open(\"GET\", \"ajax_switch\" + nocache, true);");
            client.println("request.send(null);");
            client.println("setTimeout('GetSwitchState()', 500);");
            client.println("}");
            client.println("function SetLEDStates(num){");
            client.println("switch(num){");
            client.println("case 1: if(x1==1){led1=\"&LED1ON\";x1=0;}else{led1=\"&LED1OFF\";x1=1;}break;");
            client.println("case 2: if(x2==1){led2=\"&LED2ON\";x2=0;}else{led2=\"&LED2OFF\";x2=1;}break;");
            client.println("case 3: if(x3==1){led3=\"&LED3ON\";x3=0;}else{led3=\"&LED3OFF\";x3=1;}break;");
            client.println("case 4: if(x4==1){led4=\"&LED4ON\";x4=0;}else{led4=\"&LED4OFF\";x4=1;}break;");
            client.println("case 0: led1=\"&LED1OFF\";x1=1; led2=\"&LED2OFF\";x2=1; led3=\"&LED3OFF\";x3=1; led4=\"&LED4OFF\";x4=1;break;");
            client.println("}}");
            client.println("</script>");
            client.println("</head>");
            client.println("<body onload=\"GetSwitchState();SetLEDStates(0);\"><center>");
            client.println("<h1>Erhan YILMAZ AJAX Test Application</h1>");
            client.println("<div id=\"text1\"></div>");
            client.println("<svg width=\"40\" height=\"40\"><circle id=\"SW1\" cx=\"20\" cy=\"20\" r=\"10\"stroke=\"black\" stroke-width=\"4\" fill=\"white\"/></svg>");
            client.println("<div id=\"text2\"></div>");
            client.println("<svg width=\"40\" height=\"40\"><circle id=\"SW2\" cx=\"20\" cy=\"20\" r=\"10\"stroke=\"black\" stroke-width=\"4\" fill=\"white\"/></svg>");
            client.println("<p><button type=\"L1\" onclick=\"SetLEDStates(1);\">LED1</button>&nbsp;");
            client.println("<button type=\"L2\" onclick=\"SetLEDStates(2);\">LED2</button>&nbsp;");
            client.println("<button type=\"L3\" onclick=\"SetLEDStates(3);\">LED3</button>&nbsp;");
            client.println("<button type=\"L4\" onclick=\"SetLEDStates(4);\">LED4</button>&nbsp;</p>");
            client.println("<p><center>");
            client.println("<svg width=\"50\" height=\"50\"><circle id=\"LED1\" cx=\"20\" cy=\"20\" r=\"10\"stroke=\"green\" stroke-width=\"4\" fill=\"black\"/></svg>");
            client.println("<svg width=\"50\" height=\"50\"><circle id=\"LED2\" cx=\"20\" cy=\"20\" r=\"10\"stroke=\"green\" stroke-width=\"4\" fill=\"black\"/></svg>");
            client.println("<svg width=\"50\" height=\"50\"><circle id=\"LED3\" cx=\"20\" cy=\"20\" r=\"10\"stroke=\"green\" stroke-width=\"4\" fill=\"black\"/></svg>");
            client.println("<svg width=\"50\" height=\"50\"><circle id=\"LED4\" cx=\"20\" cy=\"20\" r=\"10\"stroke=\"green\" stroke-width=\"4\" fill=\"black\"/></svg>");
            client.println("</center></p>");
            client.println("</center></body>");
            client.println("</html>");
          }
          // display received HTTP request on serial port
          Serial.print(HTTP_req);
          HTTP_req = "";            // finished with request, empty string
          break;
        }
        // every line of text received from the client ends with \r\n
        if (c == '\n')
        {
          // last character on line of received text
          // starting new line with next character read
          currentLineIsBlank = true;
        } 
        else if (c != '\r')
        {
          // a text character was received from client
          currentLineIsBlank = false;
        }
      }
    }
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
}

// send the state of the switch to the web browser
void GetSwitchState(EthernetClient cl)
{ 
  char x=0;

  if (!digitalRead(PUSH1)) x+=1;
  if (!digitalRead(PUSH2)) x+=2;	
  
  switch(x)
  {
  case 0:
    cl.println("S1:OFF S2:OFF");
  break;

  case 1:
    cl.println("S1:ON S2:OFF");
  break;

  case 2:
    cl.println("S1:OFF S2:ON");
  break;

  default:
    cl.println("S1:ON S2:ON");
  break;
  }
}

void SetLEDStates(EthernetClient cl, String HTTP_req)
{

  if (HTTP_req.indexOf("LED1ON") > -1)
  {
    digitalWrite(LED1, HIGH); 
    cl.println("LED1ON");
  }
  else
  {
    digitalWrite(LED1, LOW); 
    cl.println("LED1OFF");
  }

  if (HTTP_req.indexOf("LED2ON") > -1)
  {
    digitalWrite(LED2, HIGH); 
    cl.println("LED2ON");
  }
  else
  {
    digitalWrite(LED2, LOW); 
    cl.println("LED2OFF");
  }

  if (HTTP_req.indexOf("LED3ON") > -1)
  {
    digitalWrite(LED3, HIGH); 
    cl.println("LED3ON");
  }
  else
  {
    digitalWrite(LED3, LOW); 
    cl.println("LED3OFF");
  }

  if (HTTP_req.indexOf("LED4ON") > -1)
  {
    digitalWrite(LED4, HIGH); 
    cl.println("LED4ON");
  }
  else
  {
    digitalWrite(LED4, LOW); 
    cl.println("LED4OFF");
  }
}


void serialEvent() {
  while (Serial.available()) 
  {
    // get the new byte:
    char inChar = (char)Serial.read(); 
  } 
}

void printEthernetData()
{
  // print your IP address:
  Serial.println();
  Serial.println("IP Address Information:");  
  IPAddress ip = Ethernet.localIP();
  Serial.print("IP Address:\t");
  Serial.println(ip);

  // print your MAC address:

  IPAddress subnet = Ethernet.subnetMask();
  Serial.print("NetMask:\t");
  Serial.println(subnet);

  // print your gateway address:
  IPAddress gateway = Ethernet.gatewayIP();
  Serial.print("Gateway:\t");
  Serial.println(gateway);

  // print your gateway address:
  IPAddress dns = Ethernet.dnsServerIP();
  Serial.print("DNS:\t\t");
  Serial.println(dns);

}

Step 3: Running of The Application and Results

Picture of Running of The Application and Results

webserver_running.jpg

As result as, after load energia codes to launchpad, power it and connect to network. Than that's it! It will work.

When you open energia serial terminal you can see text data come from launchpad. Tiva Connected Launchpad's default serial port is uart0. So when you use function such Serial.print (it is also same as arduino) it prints data from uart0 to energia serial terminal.

As you see on the terminal screenshot after connecting launchpad takes automatically ip and relevant info from your network provider such as router, gateway. Then you type this ip to the your web browser's address bar and press enter you can load web site from launchpad.

You can see running of the application below picture. For example when you press SW1 button on the Launchpad The text SW1 on the site goes on and releated circle color fill as red. Again when you press LED buttons on the site releated LED states changes on the launchpad etc.

Also you can use static ip by changing initial code. But you should have enough experience about your network. If you can't take ip it doesn't work. I prefer that on the evaluation phase use taking ip as automatically.

Enclosed you can get related files about application. I hope it helps you on your projects. See you on next post inshaAllah. Have fun!