Rusty_Gunn

Arduino Every Web Server with favicon

Nov 26th, 2022 (edited)
433
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.20 KB | None | 0 0
  1. //////////////////////////////////////////////////////////////////////////////////////////
  2. //Hello World on an Arduino Every with a Robotdyn Nano V3 Ethernet Shield - W5500 (V2)  //
  3. //                                                                                      //
  4. //Arduino Every: https://store-usa.arduino.cc/products/arduino-nano-every               //
  5. //Ethernet Shield: https://www.aliexpress.com/item/32966745493.html                     //
  6. //////////////////////////////////////////////////////////////////////////////////////////
  7.  
  8.  
  9. //////////////////////////////////////////////////////////////////////////////////////////
  10. // Initialize                                                                           //
  11. //////////////////////////////////////////////////////////////////////////////////////////
  12.  
  13. //Ethernet Varirable Setup
  14. //install ethernet2 library from https://www.arduino.cc/reference/en/libraries/ethernet2/
  15. //or by using the library manager within the arduino IDE
  16. //ethernet code based on web server sample that comes with the library
  17. #include <SPI.h>
  18. #include <Ethernet2.h>
  19.  
  20. byte mac[] = { 0x74, 0x69, 0x69, 0x2D, 0x33, 0x36 }; // ethernet mac address - must be unique on your network
  21. //set ip, gateway, and subnet to match your network, you will use the ip to access the server
  22. IPAddress ip(192, 168, 0, 46);
  23. IPAddress gateway(192, 168, 0, 1);
  24. IPAddress subnet(255, 255, 255, 0);
  25.  
  26. EthernetServer server(80); //set HTTP server port
  27. String readString; //var for url requested, this allows us to serve different pages based on the url
  28.  
  29. //To create a favicon, first create a 16x16 png file, then convert to base64 then to 8 bit signed hex
  30. //http://www.xiconeditor.com/   -> create and or edit ico file
  31. //https://www.aconvert.com/image/ico-to-png/  -> convert ico to png
  32. //https://www.base64-image.de/    -> png to base64
  33. //https://cryptii.com/   -> hex encode
  34. //      text -> decode 64 -> encode 8 bit hexidecimal signed -> text    -> signed 8 bit for ethercard library
  35. //http://tomeko.net/online_tools/base64.php?lang=en    -> base64 to unsigned hex with 0x prefix for ethernet2 library
  36. //for this example I have created a arduino green house/home icon
  37. //code was originally inspired by this forum post: https://jeelabs.org/forum/node/1042.html
  38. const char favicon[] = {
  39.   -0x77, 0x50, 0x4e, 0x47, 0x0d, 0xa, 0x1a, 0xa, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
  40.   0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x2, 0x3, 0x00, 0x00, 0x00, 0x62, -0x63, 0x17,
  41.   -0x0e, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, -0x4f, -0x71, 0x0b, -0x04, 0x61,
  42.   0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x00, 0x00, 0x7a, 0x26, 0x00, 0x00, -0x80,
  43.   -0x7c, 0x00, 0x00, -0x06, 0x00, 0x00, 0x00, -0x80, -0x18, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, -0x16,
  44.   0x60, 0x00, 0x00, 0x3a, -0x68, 0x00, 0x00, 0x17, 0x70, -0x64, -0x46, 0x51, 0x3c, 0x00, 0x00, 0x00,
  45.   0x09, 0x50, 0x4c, 0x54, 0x45, 0x00, 0x00, 0x00, 0x00, -0x6a, -0x64, -0x01, -0x01, -0x01, 0x2a, 0x0d,
  46.   0x43, 0x7e, 0x00, 0x00, 0x00, 0x01, 0x74, 0x52, 0x4e, 0x53, 0x00, 0x40, -0x1a, -0x28, 0x66, 0x00,
  47.   0x00, 0x00, 0x01, 0x62, 0x4b, 0x47, 0x44, 0x02, 0x66, 0x0b, 0x7c, 0x64, 0x00, 0x00, 0x00, 0x07,
  48.   0x74, 0x49, 0x4d, 0x45, 0x07, -0x1e, 0x06, 0x10, 0x09, 0x13, 0x0d, 0x58, -0x72, -0x4c, -0x4a, 0x00,
  49.   0x00, 0x00, 0x34, 0x49, 0x44, 0x41, 0x54, 0x08, -0x29, 0x63, 0x60, 0x0c, 0x0d, 0x75, 0x60, 0x10,
  50.   0x0d, 0x0d, 0x0d, -0x7f, 0x10, -0x5f, 0x61, 0x53, -0x7f, 0x44, -0x2c, -0x2e, 0x50, -0x7a, -0x30, -0x54,
  51.   -0x6b, 0x40, 0x62, -0x2b, -0x56, 0x50, -0x7a, -0x50, 0x55, -0x55, -0x5a, 0x42, 0x58, 0x50, 0x22, 0x0a,
  52.   -0x67, 0x40, -0x18, 0x05, 0x19, 0x05, 0x00, -0x35, -0x6e, 0x18, 0x60, 0x40, 0x44, 0x39, -0x49, 0x00,
  53.   0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61,
  54.   0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x38, 0x2d, 0x30, 0x36, 0x2d, 0x31, 0x36, 0x54, 0x30, 0x39,
  55.   0x3a, 0x31, 0x39, 0x3a, 0x31, 0x33, 0x2d, 0x30, 0x37, 0x3a, 0x30, 0x30, -0x7a, 0x13, -0x11, 0x3e,
  56.   0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64,
  57.   0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x38, 0x2d, 0x30, 0x36, 0x2d, 0x31, 0x36, 0x54, 0x30,
  58.   0x39, 0x3a, 0x31, 0x39, 0x3a, 0x31, 0x33, 0x2d, 0x30, 0x37, 0x3a, 0x30, 0x30, -0x9, 0x4e, 0x57,
  59.   -0x7e, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, -0x52, 0x42, 0x60, -0x7e
  60. };
  61.  
  62. //////////////////////////////////////////////////////////////////////////////////////////
  63. // Start Functions                                                                      //
  64. //////////////////////////////////////////////////////////////////////////////////////////
  65.  
  66. //return how long the arduino/server has been running
  67. //original code from Arduino forum
  68. //https://forum.arduino.cc/t/function-uptime/70600
  69. char *uptime(unsigned long milli)
  70. {
  71.   static char _return[25];
  72.   unsigned long secs = milli / 1000, mins = secs / 60;
  73.   unsigned int hours = mins / 60, days = hours / 24;
  74.   milli -= secs * 1000;
  75.   secs -= mins * 60;
  76.   mins -= hours * 60;
  77.   hours -= days * 24;
  78.   sprintf(_return, "%d days %2.2d:%2.2d:%2.2d.%3.3d", (byte)days, (byte)hours, (byte)mins, (byte)secs, (int)milli);
  79.   return _return;
  80. }
  81.  
  82. //////////////////////////////////////////////////////////////////////////////////////////
  83. // Start Setup                                                                          //
  84. //////////////////////////////////////////////////////////////////////////////////////////
  85.  
  86. void setup () {
  87.   Serial.begin(9600);
  88.   Serial.println("Setup Start.");
  89.  
  90.   // start the Ethernet connection and the server:
  91.   Ethernet.begin(mac, ip);
  92.   server.begin();
  93.   Serial.print("server is at ");
  94.   Serial.println(Ethernet.localIP());
  95.  
  96.   Serial.println("Setup Complete.");
  97.   Serial.println("");
  98. }
  99.  
  100. //////////////////////////////////////////////////////////////////////////////////////////
  101. // Start Main Loop                                                                      //
  102. //////////////////////////////////////////////////////////////////////////////////////////
  103.  
  104. void loop() {
  105.  
  106.   // listen for incoming clients
  107.   EthernetClient client = server.available();
  108.   if (client) {
  109.     Serial.println("");
  110.     Serial.println("new client");
  111.     boolean currentLineIsBlank = true;
  112.     boolean endofFirstLine = false;
  113.     readString = "";
  114.     while (client.connected()) {
  115.       if (client.available()) {
  116.         char c = client.read();
  117.  
  118.         //first time encounter a line return say true
  119.         if (c == '\n' && endofFirstLine == false) endofFirstLine = true;
  120.  
  121.         //Serial.print(c); //print what server receives to serial monitor
  122.  
  123.         //read char by char HTTP request, limit to checking the first 30 and stop after first line
  124.         if ((readString.length() < 30) && (endofFirstLine == false)) {
  125.           //store characters to string
  126.           readString += c;
  127.         }
  128.  
  129.         // if you've gotten to the end of the line (received a newline
  130.         // character) and the line is blank, the http request has ended
  131.         // so you can send a reply
  132.         if (c == '\n' && currentLineIsBlank) {
  133.          
  134.           //serve a text version of Hello World and server uptime
  135.           if (readString.indexOf("/text") > 0) {
  136.             Serial.println(F("Text Hello World Sent"));
  137.             // send a standard http response header
  138.             client.println("HTTP/1.1 200 OK");
  139.             client.println("Content-Type: text/plain");
  140.             client.println("Pragma: no-cache");
  141.             client.println("Connection: close");  // the connection will be closed after completion of the response
  142.             client.println();
  143.             client.println("Hello World!");
  144.             client.print("Server uptime: "); client.print(uptime(millis()));
  145.             break;
  146.           }
  147.  
  148.          //server a html version of Hello World and the server update
  149.          if (readString.indexOf("/html") > 0) {
  150.             Serial.println(F("HTML Hello World Sent"));
  151.             // send a standard http response header
  152.             client.println("HTTP/1.1 200 OK");
  153.             client.println("Content-Type: text/html");
  154.             client.println("Pragma: no-cache");
  155.             client.println("Connection: close");  // the connection will be closed after completion of the response
  156.             client.println();
  157.             client.println("<!DOCTYPE HTML>");
  158.             client.println("<html><body>");
  159.             client.println("<h1>Hello World!</h1>");
  160.             client.print("<br>Server uptime: "); client.println(uptime(millis()));
  161.             client.println("</body></html>");
  162.             break;
  163.           }
  164.  
  165.         //serve the favicon
  166.          if (readString.indexOf("favicon") > 0) {
  167.             Serial.println(F("favicon Served"));
  168.             client.println("HTTP/1.1 200 OK");
  169.             client.println("Content-Type: image/png");
  170.             client.println("Pragma: no-cache");
  171.             client.println("Connection: close");  // the connection will be closed after completion of the response
  172.             client.println();
  173.             for (int i = 0; i < sizeof(favicon); i++) {
  174.               client.write(favicon[i]);
  175.             }
  176.             break;
  177.           }
  178.  
  179.  
  180.           //all other inquiries get 404
  181.           else {
  182.             Serial.println(F("404 Served"));
  183.             client.println("HTTP/1.1 200 OK");
  184.             client.println("Content-Type: text/plain");
  185.             client.println("Pragma: no-cache");
  186.             client.println("Connection: close");  // the connection will be closed after completion of the response
  187.             client.println();
  188.             client.println("404 Error");
  189.             break;
  190.           }
  191.         }
  192.         if (c == '\n') {
  193.           // you're starting a new line
  194.           currentLineIsBlank = true;
  195.         }
  196.         else if (c != '\r') {
  197.           // you've gotten a character on the current line
  198.           currentLineIsBlank = false;
  199.         }
  200.       }
  201.     }
  202.     // give the web browser time to receive the data
  203.     delay(1);
  204.     // close the connection
  205.     client.stop();
  206.     Serial.println("client disconnected");
  207.     Serial.print (F("Uptime: ")); Serial.print (uptime(millis())); Serial.print(F(" readString: ")); Serial.println(readString);
  208.   }
  209.  
  210.   delay(100);
  211. }
  212.  
Add Comment
Please, Sign In to add comment