Sunday, February 28, 2016

Arduino WiFi Weather Web Server Prototype

Building on previous work, the Arduino WiFi 101 Shield will now be configured to broadcast weather information, using a slow but effective temperature/humidity sensor, the DHT-22.

Connecting the device was accomplished with a slightly modified set of procedures from the original example found on AdaFruit. Most notably the use of 3.3V vs 5V to support the different levels on the Arduino Zero.  Note that a 10K pull-up resistor is also used on pin 2.




After compiling and downloading the sketch below, the temperature/humidity was successfully obtained and published/visible on the network via Chrome.



The source code used to implement the WiFi Weather Web Server is seen below.

 #include <SPI.h>  
 #include <WiFi101.h>  
 #include "DHT.h"  
   
 char ssid[] = "mynetwork";     // your network SSID (name)   
 char pass[] = "mypassword"; // your network password  
 int status = WL_IDLE_STATUS;  // the Wifi radio's status  
 WiFiServer server(80);  
   
 #define DHTPIN 2      // what digital pin we're connected to  
 #define DHTTYPE DHT22   // DHT 22 (AM2302), AM2321, RHT03  
 DHT dht(DHTPIN, DHTTYPE); // Initialize DHT sensor.  
   
 void setup()   
 {  
  // initialize serial:  
  Serial.begin(9600);  
  while (!Serial)  
  {  
   ; // wait for serial port to connect. Needed for native USB port only  
  }  
   
  dht.begin();  
    
  if (WiFi.status() == WL_NO_SHIELD)  
  {  
   Serial.println("WiFi shield not present");  
   // don't continue:  
   while (true);  
  }   
   
  // attempt to connect to Wifi network:  
  while ( status != WL_CONNECTED)  
  {  
   // attempt to connect using WPA2 encryption:  
   Serial.println("");  
   Serial.println("Attempting to connect to WPA2 network...");  
   status = WiFi.begin(ssid, pass);  
   
   if (status != WL_CONNECTED)  
   {   
    // if you're not connected, stop here:  
    Serial.println("Network unavailable, trying again in 10 seconds...");  
    // wait 10 seconds for connection:  
    delay(10000);  
   }  
  }  
    
  server.begin();  
   
  Serial.println("Connected to network");  
  printWifiStatus();  
 }  
   
 void loop()  
 {  
  // listen for incoming clients  
  WiFiClient client = server.available();  
  if (client)  
  {  
   Serial.println("new client...");  
   
   // Wait a few seconds between measurements.  
   delay(2000);  
     
   // Reading temperature or humidity takes about 250 milliseconds!  
   // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)  
   float h = dht.readHumidity();  
   // Read temperature as Celsius (the default)  
   float t = dht.readTemperature();  
   // Read temperature as Fahrenheit (isFahrenheit = true)  
   float f = dht.readTemperature(true);  
   
   // Check if any reads failed and exit early (to try again).  
   if (isnan(h) || isnan(t) || isnan(f)) {  
    Serial.println("Failed to read from DHT sensor!");  
    f = 0;  
    h = 0;  
    t = 0;  
   }    
   
   // Compute heat index in Fahrenheit (the default)  
   float hif = dht.computeHeatIndex(f, h);  
   // Compute heat index in Celsius (isFahreheit = false)  
   float hic = dht.computeHeatIndex(t, h, false);  
    
   // an http request ends with a blank line  
   boolean currentLineIsBlank = true;  
   while (client.connected())  
   {  
    if (client.available())  
    {  
     char c = client.read();  
     Serial.write(c);  
     // if you've gotten to the end of the line (received a newline  
     // character) and the line is blank, the http request has ended,  
     // so you can send a reply  
     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: close"); // the connection will be closed after completion of the response  
      //client.println("Refresh: 5"); // refresh the page automatically every 5 sec  
      client.println();  
      client.println("<!DOCTYPE HTML>");  
      client.println("<html>");  
      client.println("<head><title>Arduino Web Server</title></head>");  
      client.println("<body>");  
        
      client.print("Humidity is ");  
      client.print(h);  
      client.println("<br />");  
   
      client.print("Temperature is ");  
      client.print(t);  
      client.println(" (C) <br />");       
        
      client.print("Temperature is ");  
      client.print(f);  
      client.println(" (F) <br />");       
   
      client.print("Heat Index is ");  
      client.print(hic);  
      client.println(" (C) <br />");       
   
      client.print("Heat Index is ");  
      client.print(hif);  
      client.println(" (F) <br />");       
   
      client.println("</body>");  
      client.println("</html>");  
      break;  
     }  
       
     if (c == '\n')  
     {  
      // you're starting a new line  
      currentLineIsBlank = true;  
     }  
     else if (c != '\r')  
     {  
      // you've gotten a character on the current line  
      currentLineIsBlank = false;  
     }  
    }  
   }  
   // give the web browser time to receive the data  
   delay(1);  
   
   // close the connection:  
   client.stop();  
   Serial.println("client disonnected...");  
  }  
 }  
   
 void printWifiStatus()   
 {  
  // print the SSID of the network you're attached to:  
  Serial.print("SSID: ");  
  Serial.println(WiFi.SSID());  
   
  // print your WiFi shield's IP address:  
  IPAddress ip = WiFi.localIP();  
  Serial.print("IP Address: ");  
  Serial.println(ip);  
   
  // print your gateway address:  
  IPAddress gateway = WiFi.gatewayIP();  
  Serial.print("Gateway: ");  
  Serial.println(gateway);  
    
  // print the received signal strength:  
  long rssi = WiFi.RSSI();  
  Serial.print("signal strength (RSSI):");  
  Serial.print(rssi);  
  Serial.println(" dBm");  
 }  
   

Saturday, February 27, 2016

Arduino WiFi Shield 101 Web Server Basics

Without much fuss, the earlier code example was modified per Arduino instructions for a WiFi Web Server.   No additional code libraries were needed, and the application worked without issue.  Here is a snapshot of the page being served by the Arduino after opening the IP address in Chrome.


The code is documented below:

 #include <SPI.h>  
 #include <WiFi101.h>  
   
 char ssid[] = "mynetwork";   // your network SSID (name)   
 char pass[] = "mypassword!";  // your network password  
 int status = WL_IDLE_STATUS;   // the Wifi radio's status  
 WiFiServer server(80);  

 void setup()   
 {  
  // initialize serial:  
  Serial.begin(9600);  
  while (!Serial)  
  {  
   ; // wait for serial port to connect. Needed for native USB port only  
  }  
   
  if (WiFi.status() == WL_NO_SHIELD)  
  {  
   Serial.println("WiFi shield not present");  
   // don't continue:  
   while (true);  
  }   
   
  // attempt to connect to Wifi network:  
  while ( status != WL_CONNECTED)  
  {  
   // attempt to connect using WPA2 encryption:  
   Serial.println("");  
   Serial.println("Attempting to connect to WPA2 network...");  
   status = WiFi.begin(ssid, pass);  
   
   if (status != WL_CONNECTED)  
   {   
    // if you're not connected, stop here:  
    Serial.println("Network unavailable, trying again in 10 seconds...");  
    // wait 10 seconds for connection:  
    delay(10000);  
   }  
  }  
    
  server.begin();  
   
  Serial.println("Connected to network");  
  printWifiStatus();  
 }  
   
 void loop()  
 {  
  // listen for incoming clients  
  WiFiClient client = server.available();  
  if (client)  
  {  
   Serial.println("new client...");  
   // an http request ends with a blank line  
   boolean currentLineIsBlank = true;  
   while (client.connected())  
   {  
    if (client.available())  
    {  
     char c = client.read();  
     Serial.write(c);  
     // if you've gotten to the end of the line (received a newline  
     // character) and the line is blank, the http request has ended,  
     // so you can send a reply  
     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: close"); // the connection will be closed after completion of the response  
      client.println("Refresh: 5"); // refresh the page automatically every 5 sec  
      client.println();  
      client.println("<!DOCTYPE HTML>");  
      client.println("<html>");  
      client.println("<head><title>Arduino Web Server</title></head>");  
      client.println("<body>");  
      // output the value of each analog input pin  
      for (int analogChannel = 0; analogChannel < 6; analogChannel++)  
      {  
       int sensorReading = analogRead(analogChannel);  
       client.print("analog input channel ");  
       client.print(analogChannel);  
       client.print(" is ");  
       client.print(sensorReading);  
       client.println("<br />");  
      }  
      client.println("</body>");  
      client.println("</html>");  
      break;  
     }  
       
     if (c == '\n')  
     {  
      // you're starting a new line  
      currentLineIsBlank = true;  
     }  
     else if (c != '\r')  
     {  
      // you've gotten a character on the current line  
      currentLineIsBlank = false;  
     }  
    }  
   }  
   // give the web browser time to receive the data  
   delay(1);  
   
   // close the connection:  
   client.stop();  
   Serial.println("client disonnected...");  
  }  
 }  
   
 void printWifiStatus()   
 {  
  // print the SSID of the network you're attached to:  
  Serial.print("SSID: ");  
  Serial.println(WiFi.SSID());  
   
  // print your WiFi shield's IP address:  
  IPAddress ip = WiFi.localIP();  
  Serial.print("IP Address: ");  
  Serial.println(ip);  
   
  // print your gateway address:  
  IPAddress gateway = WiFi.gatewayIP();  
  Serial.print("Gateway: ");  
  Serial.println(gateway);  
    
  // print the received signal strength:  
  long rssi = WiFi.RSSI();  
  Serial.print("signal strength (RSSI):");  
  Serial.print(rssi);  
  Serial.println(" dBm");  
 }  
   

The data itself is not very interesting (as it is just pulling values from floating pins), however that will be remedied in the next post.

Saturday, February 20, 2016

Getting Started with the Arduino WiFi Shield 101

After verifying the Arduino Zero was functional (previous blog entry), the WiFi Shield 101 was connected (via stacking headers) and tested out.  Again, there is not too much to be added to the basic documentation on the Arduino site, this just documents the links for later:

Arduino WiFi Shield 101
Arduino WiFi Shield 101 Getting Started
Arduino WiFi 101 Software Library


The shield requires a software library, which is first downloaded via the Library Manager (Sketch | Include Library | Manage Libraries...):


After installing the library, the sample code for Scan for available networks was compiled/uploaded and successfully listed my local network.  I then combined a few sample code snippets into the following, and was able to connect to the local network with WPA2:

 #include <SPI.h>  
 #include <WiFi101.h>  
   
 char ssid[] = "mynetwork";   // your network SSID (name)   
 char pass[] = "mypassword";  // your network password  
 int status = WL_IDLE_STATUS;   // the Wifi radio's status  
   
 void setup()   
 {  
  // initialize serial:  
  Serial.begin(9600);  
   
  if (WiFi.status() == WL_NO_SHIELD)  
  {  
   Serial.println("WiFi shield not present");  
   // don't continue:  
   while (true);  
  }  
    
  // attempt to connect using WPA2 encryption:  
  Serial.println("");  
  Serial.println("Attempting to connect to WPA network...");  
  status = WiFi.begin(ssid, pass);  
   
  if (status != WL_CONNECTED)  
  {   
   // if you're not connected, stop here:  
   Serial.println("Couldn't get a wifi connection");  
   while(true);  
  }   
  else  
  {  
   // if you are connected, print out info about the connection:  
   Serial.println("Connected to network");  
   printWifiStatus();  
  }  
 }  
   
 void loop()  
 {  
  // do nothing  
 }  
   
 void printWifiStatus()   
 {  
  // print the SSID of the network you're attached to:  
  Serial.print("SSID: ");  
  Serial.println(WiFi.SSID());  
   
  // print your WiFi shield's IP address:  
  IPAddress ip = WiFi.localIP();  
  Serial.print("IP Address: ");  
  Serial.println(ip);  
   
  // print your gateway address:  
  IPAddress gateway = WiFi.gatewayIP();  
  Serial.print("Gateway: ");  
  Serial.println(gateway);  
    
  // print the received signal strength:  
  long rssi = WiFi.RSSI();  
  Serial.print("signal strength (RSSI):");  
  Serial.print(rssi);  
  Serial.println(" dBm");  
 }  
   

The sketch worked as designed, and the Arduino was visible on my routers list of connected devices.  Unfortunately I can find no way to set the device name for the WiFi shield, but that is a minor complaint when so much functionality worked "out of the box".


Next up will be to work with the onboard real-time clock (RTC), set the RTC automatically via an NTP call, and perform some basics to serve a webpage on the local network.



Thursday, February 18, 2016

Getting Started with the Arduino Zero

There is not too much to be added to the documentation on the Arduino site, this just documents the links for later:

Getting Started with the Arduino Zero

First install the latest software, which as of February 2016 is the following:


Make sure to perform the step of installing the SAMD core like this, then select the appropriate Board and Serial Port from the Tools menu.  As an initial test, the Blink application was installed and observed to be functioning normally.



Next step will be to connect up the WiFi 101 board...