{"id":1601,"date":"2017-01-08T20:15:37","date_gmt":"2017-01-08T20:15:37","guid":{"rendered":"http:\/\/blog.paranoidprofessor.com\/?p=1601"},"modified":"2017-01-08T20:15:37","modified_gmt":"2017-01-08T20:15:37","slug":"evolution-of-led-lighting-software-solution","status":"publish","type":"post","link":"https:\/\/blog.paranoidprofessor.com\/index.php\/2017\/01\/08\/evolution-of-led-lighting-software-solution\/","title":{"rendered":"Evolution of LED Lighting &#8211; software solution"},"content":{"rendered":"<p>In my previous blog entry, <a href=\"http:\/\/blog.paranoidprofessor.com\/index.php\/2017\/01\/03\/evolution-of-led-lighting-hardware-and-tools\/\">Evolution of LED Lighting &#8211; hardware and tools<\/a>, I only managed to describe the tools and hardware as well as a first project to test the ability to upload new programs to the device.<\/p>\n<p>Some of the more interesting articles on the internet are about using the ESP8266 and setting it up as a web server. \u00a0It is a totally fascinating solution but the reason I don&#8217;t want a web browser is that I am planning on having more than one device in my network and I don&#8217;t want to bring up a web page for each one when I am controlling them. \u00a0I would rather have a separate server, perhaps a home dashboard, which will allow me to control the all devices.<\/p>\n<p>My devices won&#8217;t be heart pacemakers and won&#8217;t be internet facing so I am going to use the <a href=\"https:\/\/en.wikipedia.org\/wiki\/User_Datagram_Protocol\">UDP protocol<\/a>. \u00a0If for any reason a message gets lost, then I will simply send it again.\u00a0 If someone is already sniffing my network packets this is probably the least sensitive information that I have to steal.<\/p>\n<p>The standard Arduino libraries actually have some classes to support WiFi bundled with the IDE.\u00a0When I did my searching on the internet I found some Arduino examples that were using the WiFi, WiFiClient, and WiFiServer and that led me down the wrong path.<\/p>\n<p>Indeed part of my problem was that the ESP8266 environment also has these classes but either I had forgotten to initialize some object or there are other differences.<\/p>\n<p>One of the additional counter intuitive\u00a0situations is that to do UDP messages you don&#8217;t include the WiFIUdp code, but rather just include the ESP8266WiFi.h file instead.<\/p>\n<p>Once you look at the right kind of example it is actually trivial to connect to your device to the network using WiFi.<\/p>\n<h3>ESP8266\u00a0device<\/h3>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n#include &lt;ESP8266WiFi.h&gt;\r\n#include &lt;WiFiUDP.h&gt;\r\n\r\n\/\/ pins for this device\r\n#define ESP8266_LED1 16 \/\/ center\r\n#define ESP8266_LED2 2  \/\/ edge\r\n\r\n\/\/ wifi connection variables\r\nconst char* ssid = &quot;your-ssid&quot;;\r\nconst char* password = &quot;your-ssid-password&quot;;\r\nboolean wifiConnected = false;\r\n\r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n\/\/ UDP variables\r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\nWiFiUDP UDP;\r\nboolean udpConnected = false;\r\nchar packetBuffer[UDP_TX_PACKET_MAX_SIZE]; \/\/ buffer to hold incoming packet,\r\nchar ReplyBuffer[UDP_TX_PACKET_MAX_SIZE];  \/\/ a string to send back\r\nchar ack[] = &quot;acknowledged&quot;;               \/\/ my default response\r\n\r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\n\/\/ my IoT device info\r\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\r\nboolean debug = false;\r\nunsigned int localPort = 8192;\r\n\r\nvoid setup()\r\n{\r\n  \/\/ Initialise Serial connection\r\n  Serial.begin(74880);\r\n  Serial.println(&quot;begin serial&quot;);\r\n\r\n  \/\/ turn off both leds on board\r\n  pinMode(ESP8266_LED1, OUTPUT);\r\n  pinMode(ESP8266_LED2, OUTPUT);\r\n  digitalWrite(ESP8266_LED1, HIGH);\r\n  digitalWrite(ESP8266_LED2, HIGH);\r\n  delay(2000);\r\n\r\n  \/\/ Initialise wifi connection\r\n  wifiConnected = connectWifi();\r\n\r\n  \/\/ do UDP setup if wifi connection exists\r\n  if (wifiConnected)\r\n  {\r\n    udpConnected = connectUDP();\r\n    if (udpConnected)\r\n    {\r\n      \/\/ show we are connected\r\n      digitalWrite(ESP8266_LED1, LOW);\r\n    }\r\n  }\r\n}\r\n\r\nvoid loop()\r\n{\r\n  \/\/ check if the WiFi and UDP connections were successful\r\n  if (wifiConnected)\r\n  {\r\n    if (udpConnected)\r\n    {\r\n      \/\/ if there\u2019s data available, read a packet\r\n      int packetSize = UDP.parsePacket();\r\n      if (packetSize)\r\n      {\r\n        IPAddress remoteIP = UDP.remoteIP();\r\n        int remotePort = UDP.remotePort();\r\n\r\n        Serial.print(&quot;\\nReceived packet of size &quot;);\r\n        Serial.println(packetSize);\r\n        Serial.print(&quot;From &quot;);\r\n        Serial.print(remoteIP);\r\n        Serial.print(&quot;, port &quot;);\r\n        Serial.println(remotePort);\r\n\r\n        \/\/ read the packet into packetBufffer\r\n        UDP.read(packetBuffer, sizeof(packetBuffer));\r\n\r\n        \/\/ make a zero terminated character array\r\n        packetBuffer[packetSize] = 0;\r\n        Serial.println(&quot;Contents:&quot;);\r\n        Serial.println(packetBuffer);\r\n\r\n        \/\/ send a reply, to the IP address and port that sent us the packet we received\r\n        UDP.beginPacket(UDP.remoteIP(), UDP.remotePort());\r\n        UDP.write(ReplyBuffer);\r\n        UDP.endPacket();\r\n      }\r\n      delay(10);\r\n    }\r\n  }\r\n}\r\n\r\n\/\/ connect to UDP \u2013 returns true if successful or false if not\r\nboolean connectUDP()\r\n{\r\n  boolean state = false;\r\n\r\n  if (UDP.begin(localPort) == 1)\r\n  {\r\n    Serial.println(&quot;\\nUDP Connection successful\\nlocal port: &quot;);\r\n    Serial.println(localPort);\r\n    state = true;\r\n  }\r\n  else\r\n  {\r\n    Serial.println(&quot;\\nUDP Connection failed&quot;);\r\n  }\r\n\r\n  return state;\r\n}\r\n\r\n\/\/ connect to wifi \u2013 returns true if successful or false if not\r\nboolean connectWifi()\r\n{\r\n  boolean connected = true;\r\n  int idx = 0;\r\n  WiFi.begin(ssid, password);\r\n  Serial.println(&quot;\\nConnecting to WiFi&quot;);\r\n\r\n  \/\/ Wait for connection, up to 5 seconds\r\n  while (WiFi.status() != WL_CONNECTED)\r\n  {\r\n    delay(500);\r\n    Serial.print(&quot;.&quot;);\r\n    if (idx &gt; 10)\r\n    {\r\n      connected = false;\r\n      break;\r\n    }\r\n    idx++;\r\n  }\r\n  return connected;\r\n}\r\n<\/pre>\n<p>This code is great. \u00a0It actually allows me to get an IP address from my DHCP server and to start to listen for some UDP messages.<\/p>\n<p>Most of this example code is nothing special. \u00a0Of the 135 lines only about about a dozen are required to setup and do all of the networking.<\/p>\n<p><em><strong>function loop<\/strong><\/em><\/p>\n<p>Lines 64 determines that if a UDP packet exists line 78 reads the packet into our buffer.<\/p>\n<p>Lines 86 &#8211; 88 simply send back a response to the machine that sent us the packet.<\/p>\n<p><em><strong>function connectUDP<\/strong><\/em><\/p>\n<p>The only interesting line is 100. \u00a0This is setting up which port that we wish to monitor.<\/p>\n<p><em><strong>function connectWifi<\/strong><\/em><\/p>\n<p>Lines 119 and 123 perform the connection to our local WiFi network.<\/p>\n<p>It is really a tribute to the people who put together all of supporting code that make these small devices possible.<\/p>\n<h2>Testing<\/h2>\n<p>The advantage to the web server solution is that at this point you are done. \u00a0Simply point your browser at the device and start to click on buttons to control it. \u00a0I choose to send UDP packets to my device so now I need a special program on my personal computer that can send commands to the device.<\/p>\n<p>I am not a network programmer so I was happy to see that there are a number of different examples available\u00a0on the internet. \u00a0I will use the <a href=\"https:\/\/systembash.com\/a-simple-java-udp-server-and-udp-client\/\">Java UDP example<\/a> on laptop during testing but may ultimately end up using the <a href=\"https:\/\/www.abc.se\/~m6695\/udp.html\">C UDP example<\/a> from my home automation server.<\/p>\n<div id=\"code-link-1601\" class=\"sh-link code-link sh-hide\"><a href=\"#\" onclick=\"showhide_toggle('code', 1601, 'Display java client (158 More Words)', 'Hide code'); return false;\" aria-expanded=\"false\"><span id=\"code-toggle-1601\">Display java client (158 More Words)<\/span><\/a><\/div><div id=\"code-content-1601\" class=\"sh-content code-content sh-hide\" style=\"display: none;\">\n<h3>PC Client<\/h3>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nimport java.io.*;\r\nimport java.net.*;\r\n\r\nclass clientUdp\r\n{\r\n   static public int destPort = 8192;\r\n   static public String message = &quot;hello IoT&quot;;\r\n   static public String destIPAddr = &quot;192.168.178.46&quot;;\r\n   \r\n   public static void parseArgs(String args[])\r\n   {\r\n\tString cmd;\r\n\tString value;\r\n\tfor (int idx = 0; idx &lt; args.length; idx++)\r\n\t{\r\n\t\tvalue = &quot;&quot;;\r\n\t\tcmd = args[idx];\r\n\t\tif (idx+1 &lt; args.length)\r\n\t\t\tvalue = args[idx+1];\r\n\t\t   \r\n\t\tif (cmd.equals(&quot;message&quot;))\r\n\t\t{\r\n\t\t\t message = value;\r\n\t\t\tidx++;\r\n\t\t}\t   \r\n\t}\r\n   }\r\n   \r\n   public static void main(String args[]) throws Exception\r\n   {\r\n\tparseArgs(args);\r\n\t  \r\n\tSystem.out.println(&quot;dest port = &quot; + destPort);\r\n\tSystem.out.println(&quot;dest ip   = &quot; + destIPAddr);\r\n\tSystem.out.println(&quot;message   = '&quot; + message + &quot;'&quot;);\r\n\r\n\tDatagramSocket clientSocket = new DatagramSocket();\r\n\tInetAddress IPAddress = InetAddress.getByName(destIPAddr);\r\n\t  \r\n\tbyte[] sendData = new byte[1024];\r\n\tbyte[] receiveData = new byte[1024];\r\n\r\n\tsendData = message.getBytes();\r\n\tDatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, destPort);\r\n\tclientSocket.send(sendPacket);\t  \r\n\t  \r\n\tDatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);\r\n\tclientSocket.receive(receivePacket);\r\n\tclientSocket.close();\r\n\r\n\tString response = new String(receivePacket.getData());\r\n\tSystem.out.println(&quot;FROM SERVER: &quot; + response);\r\n   }\r\n}\r\n<\/pre>\n<p><\/div><br \/>\nEverything at this point looks pretty good. \u00a0I have a device that can connect to my network and I have a small client program that can send it messages. \u00a0I now have my very own starting point for any generic device that should be controlled via WiFi.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my previous blog entry, Evolution of LED Lighting &#8211; hardware and tools, I only managed to describe the tools and hardware as well as a first project to test the ability to upload new programs to the device. Some &hellip; <a href=\"https:\/\/blog.paranoidprofessor.com\/index.php\/2017\/01\/08\/evolution-of-led-lighting-software-solution\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[20,3],"tags":[84,80,36],"_links":{"self":[{"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/posts\/1601"}],"collection":[{"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/comments?post=1601"}],"version-history":[{"count":24,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/posts\/1601\/revisions"}],"predecessor-version":[{"id":1965,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/posts\/1601\/revisions\/1965"}],"wp:attachment":[{"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/media?parent=1601"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/categories?post=1601"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.paranoidprofessor.com\/index.php\/wp-json\/wp\/v2\/tags?post=1601"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}