{"id":1847,"date":"2020-04-27T07:18:01","date_gmt":"2020-04-27T07:18:01","guid":{"rendered":"https:\/\/www.sabulo.com\/sb\/?p=1847"},"modified":"2020-04-27T07:18:04","modified_gmt":"2020-04-27T07:18:04","slug":"using-the-udp-protocol-with-an-esp32-and-android-studio-part-3","status":"publish","type":"post","link":"https:\/\/www.sabulo.com\/sb\/esp32-development-board\/using-the-udp-protocol-with-an-esp32-and-android-studio-part-3\/","title":{"rendered":"Using the UDP protocol with an ESP32 and Android Studio, Part 3"},"content":{"rendered":"\n<p>In the previous episodes of this trilogy, I showed you the <a rel=\"noreferrer noopener\" href=\"https:\/\/www.sabulo.com\/sb\/esp32-development-board\/using-the-udp-protocol-with-an-esp32-and-android-studio-part-1\/\" target=\"_blank\">general idea of using UDP <\/a>(User Datagram Protocol) to send messages from an Android phone app to any device that is able to receive them, such as an ESP32. The second instalment showed you <a rel=\"noreferrer noopener\" href=\"https:\/\/www.sabulo.com\/sb\/esp32-development-board\/using-the-udp-protocol-with-an-esp32-and-android-studio-part-1\/\" target=\"_blank\">how to set up the ESP32 so that you can confirm its ability to receive data<\/a>, and today it is time to fire up Android Studio and create a custom app to run your device remotely.<\/p>\n\n\n\n<p><a rel=\"noreferrer noopener\" href=\"https:\/\/developer.android.com\/studio\/install\" target=\"_blank\">Android Studio <\/a>is a heavyweight development environment, and when you install it and set it up, I guarantee it will intimidate you. It has so many menu options, windows, moving parts, gizmos and whatchamacallits, that at first glance it will look insurmountable. It would be very nice if block programming via <a rel=\"noreferrer noopener\" href=\"http:\/\/www.thunkable.com\" target=\"_blank\">Thunkable <\/a>or the <a rel=\"noreferrer noopener\" href=\"https:\/\/appinventor.mit.edu\/\" target=\"_blank\">MIT App Inventor<\/a> could provide us with  UDP protocol support, but as of now, such features are not available. There are other environments such as <a rel=\"noreferrer noopener\" href=\"http:\/\/phonegap.com\/\" target=\"_blank\">PhoneGap \/ Cordova<\/a>, but I couldn&#8217;t see the benefit for using them in my project. Android Studio gives it all, so I decided to bite the bullet.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1388\" height=\"998\" src=\"https:\/\/i1.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio01-1.png?fit=825%2C593&amp;ssl=1\" alt=\"\" class=\"wp-image-1850\" srcset=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio01-1.png?w=1388&amp;ssl=1 1388w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio01-1.png?resize=300%2C216&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio01-1.png?resize=1024%2C736&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio01-1.png?resize=768%2C552&amp;ssl=1 768w\" sizes=\"auto, (max-width: 825px) 100vw, 825px\" \/><figcaption>Starting up Android Studio with a new project<\/figcaption><\/figure><\/div>\n\n\n\n<p>What I did with Android Studio then was to install it, run updates as instructed, and decide to use <a rel=\"noreferrer noopener\" href=\"https:\/\/kotlinlang.org\/\" target=\"_blank\">Kotlin <\/a>instead of Java. Kotlin is a slightly simplified version of Java and it is somewhat easier to understand. It is selected for any project at the project creation time, as seen here.<\/p>\n\n\n\n<p>I won&#8217;t walk you through the Android Studio 101 phase I then took, because it is easier for you to learn the absolute basics from people who actually know what they are doing. Here&#8217;s a few good videos I used.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a rel=\"noreferrer noopener\" href=\"https:\/\/www.youtube.com\/watch?v=yHg9cdKrATQ\" target=\"_blank\">Kotlin for Dummies 1<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/developer.android.com\/kotlin\/get-started\" target=\"_blank\">Get started with Kotlin<\/a><\/li><li>And this video course, <a rel=\"noreferrer noopener\" href=\"https:\/\/www.raywenderlich.com\/4936497-your-first-kotlin-android-app\" target=\"_blank\">Your First Kotlin App<\/a><\/li><\/ul>\n\n\n\n<p>So, using these, I got relatively familiar with creating an app, setting up the emulator to test the app, and using two screens with one for the main program and one for the settings, before embarking on the quest for using UDP. Getting even data read from edit boxes was somewhat quirky in my mind, but that&#8217;s just me because I am from an HTML, C, Python and even Pascal background. Then again, if I can learn this, anyone can.<\/p>\n\n\n\n<p>You will need to understand how Android apps are built using XML files for layout and Java or Kotlin files for functionality, so do watch some ofthe videos listed above. When you install my app project, you will be able to find the relevant files, <strong>MainActivity.kt, Settings.kt, activity_main.xml, and activity_settings.xml<\/strong>.<\/p>\n\n\n\n<p>The only other file I had to edit is called <strong>AndroidManifest.xml<\/strong>, and in that one, you must insert these clauses for the system to have permission to use the Internet:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>&lt;uses-permission android:name=\"android.permission.INTERNET\" \/<\/code>>\n\n<code>&lt;uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" \/><\/code><\/pre>\n\n\n\n<p>But these are already inserted in the project you can go and collect from GitHub. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Getting the project from GitHub<\/h2>\n\n\n\n<p>Before you can use your own phone in developer mode, ie. move APK files to it and install your own app, <a href=\"https:\/\/www.howtogeek.com\/129728\/how-to-access-the-developer-options-menu-and-enable-usb-debugging-on-android-4.2\/\" target=\"_blank\" rel=\"noreferrer noopener\">you need to go into Developer Mode.<\/a><\/p>\n\n\n\n<p>I have uploaded the whole shebang of this project to my account on GitHub. GitHub is a wonderful system for delivering open source projects to users and maintaining the latest version online. I have a user account at  <a href=\"https:\/\/github.com\/HeikkiHietala\">https:\/\/github.com\/HeikkiHietala<\/a> and you can see many other projects besides this one. <\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1560\" height=\"899\" src=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio02.png?fit=825%2C475&amp;ssl=1\" alt=\"\" class=\"wp-image-1851\" srcset=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio02.png?w=1560&amp;ssl=1 1560w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio02.png?resize=300%2C173&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio02.png?resize=1024%2C590&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio02.png?resize=768%2C443&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio02.png?resize=1536%2C885&amp;ssl=1 1536w\" sizes=\"auto, (max-width: 825px) 100vw, 825px\" \/><figcaption>The esp-udp-android-app project repository<\/figcaption><\/figure><\/div>\n\n\n\n<p>The way it now works is this.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Go to the <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/HeikkiHietala\/esp32-udp-android-app\" target=\"_blank\">project repository on GitHub<\/a><\/li><li>use the Clone Project button to Download ZIP<\/li><li>unpack the project to the AndroidStudioProjects folder, usually found at <strong>c:\\Users\\&lt;your-username>\\AndroidStudioProjects<\/strong><\/li><li>go to Android Studio<\/li><li>see the new project in the Open Project list<\/li><li>As a bonus you get both of the ESP32 C language files, ready to be edited in the Arduino IDE. They are the two INO files in the root folder of the project, so you may want to move them to your Arduino folder before editing.<\/li><\/ul>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"426\" height=\"484\" src=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio03.png?resize=426%2C484&#038;ssl=1\" alt=\"\" class=\"wp-image-1852\" srcset=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio03.png?w=426&amp;ssl=1 426w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio03.png?resize=264%2C300&amp;ssl=1 264w\" sizes=\"auto, (max-width: 426px) 100vw, 426px\" \/><figcaption>The list of available projects in my Android Studio<\/figcaption><\/figure><\/div>\n\n\n\n<p>So, you should see the project listed along whatever other projects you may have. Open it and you get to this view, or something similar in any case.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1335\" height=\"836\" src=\"https:\/\/i2.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio04-1.png?fit=825%2C516&amp;ssl=1\" alt=\"\" class=\"wp-image-1854\" srcset=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio04-1.png?w=1335&amp;ssl=1 1335w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio04-1.png?resize=300%2C188&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio04-1.png?resize=1024%2C641&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio04-1.png?resize=768%2C481&amp;ssl=1 768w\" sizes=\"auto, (max-width: 825px) 100vw, 825px\" \/><figcaption>Project as opened in Android Studio<\/figcaption><\/figure><\/div>\n\n\n\n<p>The juicy bits are well hidden in the bowels of the project. I won&#8217;t even try to claim to understand how Android Studio uses all these files, it&#8217;s just that the files to modify are located in these folders:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1335\" height=\"836\" src=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio05.png?fit=825%2C516&amp;ssl=1\" alt=\"\" class=\"wp-image-1855\" srcset=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio05.png?w=1335&amp;ssl=1 1335w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio05.png?resize=300%2C188&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio05.png?resize=1024%2C641&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio05.png?resize=768%2C481&amp;ssl=1 768w\" sizes=\"auto, (max-width: 825px) 100vw, 825px\" \/><figcaption>The files you need to edit if this setup isn&#8217;t to your liking<\/figcaption><\/figure><\/div>\n\n\n\n<p>This setup gives you two screens in the application. They are the Main Activity and the Settings. Main Activity is the screen that collects your button pushes and constructs the string to be sent to the ESP32. Since your WLAN or shared mobile hotspot will give you a different IP, you need to use the Settings screen to edit that data. The port is set in the Arduino code, so  if you don&#8217;t edit that data, it&#8217;s 1234 &#8211; all that matters is that the same port is on both the app and the ESP32. <\/p>\n\n\n\n<p>Before you compile your app, it is possible to set the default values in the app data, but more on that in just a moment.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The layout of the project in Android Studio<\/h2>\n\n\n\n<p>In the Android operating system, all user interface elements are stored in XML format, and in XML files. All code is in Java files, or, in this case, Kotlin files, with a filename extension of .kt. All items of user interface that you have in the XML file have parts in code that correspond, and you can operate your app via this interplay. Here is the user interface as created by the XML files in this project, with the speed text and increase buttons indicated.<\/p>\n\n\n\n<div class=\"wp-block-image is-style-default\"><figure class=\"aligncenter size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"407\" height=\"846\" src=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio06.png?resize=407%2C846&#038;ssl=1\" alt=\"\" class=\"wp-image-1863\" srcset=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio06.png?w=407&amp;ssl=1 407w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio06.png?resize=144%2C300&amp;ssl=1 144w\" sizes=\"auto, (max-width: 407px) 100vw, 407px\" \/><figcaption>User interface<\/figcaption><\/figure><\/div>\n\n\n\n<p>This is how the Increase button looks like in XML:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&lt;<strong>Button\n android:id=\"@+id\/btnIncrease\"\n android:layout_width=\"160dp\"\n android:layout_height=\"wrap_content\"\n android:layout_marginStart=\"108dp\"\n android:layout_marginTop=\"30dp\"\n android:background=\"#4CAF50\"\n android:onClick=\"increaseSpeed\"\n android:text=\"INCREASE\"\n android:textColor=\"#FFFFFF\"\n android:textSize=\"30sp\"\n android:textStyle=\"bold\"\n app:layout_constraintStart_toStartOf=\"parent\"\n app:layout_constraintTop_toBottomOf=\"@+id\/txtSpeed\" <\/strong>\/&gt;<\/pre>\n\n\n\n<p>So, this button has an id, <strong>btnIncrease<\/strong>, its width is <strong>160 dp<\/strong> (density independent pixel &#8211; some sort of witchcraft item), its margins etc. are given in relevant units, and when it is clicked, it calls for a button listener called <strong>increaseSpeed<\/strong>. XML is a very handy language for such things as layouts, because you can read it directly.<\/p>\n\n\n\n<p>The listener, then, is in Kotlin:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">btnIncrease.setOnClickListener <strong>{\n<\/strong>mySpeed += 1\nif<strong> <\/strong>(mySpeed > 10) mySpeed = 10\n<strong>val <\/strong>SpeedtoShowTv = this.findViewById&lt;TextView>(R.id.txtSpeed)\nSpeedtoShowTv.text = mySpeed.toString()\nmyUDP = mySpeed.toString() + <strong>\",\" <\/strong>+ myDirection.toString()\nsendUDP(myUDP)\n<strong>}<\/strong><\/pre>\n\n\n\n<p>When the button is pressed, it goes to this piece of code. As this is the increase speed button, it adds one to <strong>mySpeed<\/strong>, and if it is going past 10 as a result, it is forced to be 10. It then updates the <strong>SpeedtoShowTv.text<\/strong> to show the new value in the display. And then it takes the two values, <strong>mySpeed <\/strong>and <strong>myDirection<\/strong>, makes them into string, adds a comma in between, and then goes to the function <strong>sendUDP <\/strong>to pass it to the ESP32. <\/p>\n\n\n\n<p>This is just about all you need to know about the user interface, since it&#8217;s all rather self-explanatory. If you need to add or remove buttons, just go into the relevant XML file. It looks like this, if you select the Design view:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1097\" height=\"613\" src=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio07-1.png?fit=825%2C461&amp;ssl=1\" alt=\"\" class=\"wp-image-1867\" srcset=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio07-1.png?w=1097&amp;ssl=1 1097w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio07-1.png?resize=300%2C168&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio07-1.png?resize=1024%2C572&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/uploads\/2020\/04\/androidstudio07-1.png?resize=768%2C429&amp;ssl=1 768w\" sizes=\"auto, (max-width: 825px) 100vw, 825px\" \/><figcaption>Studio in design mode<\/figcaption><\/figure>\n\n\n\n<p>You can use the three buttons in the top right corner to select either XML view, split code\/design view, or Design view. It pays to practice a little with a tutorial, before attempting to do extensive surgery on this sample project of mine.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The sendUDP function<\/h3>\n\n\n\n<p>The actual beef of this little application is the <strong>sendUDP<\/strong> function. I do not claim any ownership of this function, I found it on the Internet and adapted it to suit my needs. The biggest issue seemed to revolve around the data type of the message. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">fun sendUDP(messageStr: String) {\n\/\/ this function sends the UDP message as String\n\/\/ Hack Prevent crash (sending should be done using an async task)\nval policy = StrictMode.ThreadPolicy.Builder().permitAll().build()\nStrictMode.setThreadPolicy(policy)\ntry {\n\/\/Open a port to send the package\nval socket = DatagramSocket()\nsocket.broadcast = true\n\/\/get the message from function parameters and make it into a byte array\nval sendData = messageStr.toByteArray()\n\/\/craft the packet with the parameters\nval sendPacket = DatagramPacket(sendData, sendData.size, InetAddress.getByName(mySettings.RemoteHost), mySettings.RemotePort)\nsocket.send(sendPacket)\n} catch (e: IOException) {\n\/\/ Log.e(FragmentActivity.TAG, \"IOException: \" + e.message)\n}\n}<\/pre>\n\n\n\n<p>So, the message to be sent is passed to the function as an argument <strong>messageStr<\/strong>. At this point it is of the data type String. The Hack Prevention clause is just something that needs to be done for this to work. The structure <strong>try<\/strong> is a neat procedure that tries to send the message, and if it doesn&#8217;t pass properly, it will add the message to an error log at the end of the function with the <strong>catch clause<\/strong>. <\/p>\n\n\n\n<p>The  datagram system uses sockets, which are small interfaces into the data traffic. Therefore there is the socket, which has the methods <strong>broadcast<\/strong> and <strong>send. <\/strong>The message needs to be converted once more from <strong>string <\/strong>to <strong>byteArray<\/strong> for the sending to work, probably due to the particular type of voodoo that is happening here. If it isn&#8217;t converted, your app will crash and burn, and you will see the reason for it in the error log of Android Studio. I suggest that you don&#8217;t try to edit this function, but if you want to pass a different message, create it elsewhere and then pass it to the sendUDP as a string.  <\/p>\n\n\n\n<p>It may well be that you have a different message to pass to the UDP receiver. If that is the case, you can easily edit the structures I have here, add more or take out some of the buttons and functionalities this system has. If you look at the button listeners, it&#8217;s easy to figure out hwow they work, and you can craft your own. The global variables <strong>RemoteHost<\/strong> and <strong>RemotePort<\/strong> were best done this way, but you may want to have different values from these. The basic values I have here are related to my particular wlan setup, so these you need to edit anyway.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">public class SoftOptions {\nvar RemoteHost: String = \"192.168.10.61\"\nvar RemotePort: Int = 1234\n\nconstructor()\ninit{}\n}\n\n\/\/create a variable of this type:\n<strong>val <\/strong><em>mySettings <\/em>= SoftOptions()<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Summing it up so far<\/h3>\n\n\n\n<p>This project has now provided you with the tools necessary to open UDP communication between any ESP32 and this application. My needs dictated that my message should be a string of the type <strong>&lt;integer>, &lt;integer><\/strong>, but it is totally possible for you to make your own app send something completely different. <\/p>\n\n\n\n<p>The main issues I had with creating this app were related to my inexperience in using text boxes for displaying and reading data, and converting the data between data types.  I was quite prepared to drop the whole project when I was getting more error messages than I had lines of code, but tenacity saved the day.<\/p>\n\n\n\n<p>Setting up an Android phone emulator in Android Studio is something you need to figure out using the other tutorials I listed in the beginning, and that applies to how to set up your own phone to use as the runtime environment. <\/p>\n\n\n\n<p>The next instalment (this seems to be running into four parts even if it is a trilogy) will discuss how to build the actual system where the ESP32 governs a servo and a motor based on the strings passed to it. <\/p>\n<div class=\"pvc_clear\"><\/div><p id=\"pvc_stats_1847\" class=\"pvc_stats all  \" data-element-id=\"1847\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/i0.wp.com\/www.sabulo.com\/sb\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif?resize=16%2C16&#038;ssl=1\" border=0 \/><\/p><div class=\"pvc_clear\"><\/div>","protected":false},"excerpt":{"rendered":"<p>In the previous episodes of this trilogy, I showed you the general idea of using UDP (User Datagram Protocol) to &hellip; <a href=\"https:\/\/www.sabulo.com\/sb\/esp32-development-board\/using-the-udp-protocol-with-an-esp32-and-android-studio-part-3\/\" class=\"more-link\">More <span class=\"screen-reader-text\">Using the UDP protocol with an ESP32 and Android Studio, Part 3<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_1847\" class=\"pvc_stats all  \" data-element-id=\"1847\" style=\"\"><i class=\"pvc-stats-icon medium\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/www.sabulo.com\/sb\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p>\n<div class=\"pvc_clear\"><\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[87,64,86,85],"tags":[],"class_list":["post-1847","post","type-post","status-publish","format-standard","hentry","category-android-app-development","category-esp32-development-board","category-heltec-oled","category-udp-protocol"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p6vhqE-tN","_links":{"self":[{"href":"https:\/\/www.sabulo.com\/sb\/wp-json\/wp\/v2\/posts\/1847","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.sabulo.com\/sb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sabulo.com\/sb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sabulo.com\/sb\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sabulo.com\/sb\/wp-json\/wp\/v2\/comments?post=1847"}],"version-history":[{"count":18,"href":"https:\/\/www.sabulo.com\/sb\/wp-json\/wp\/v2\/posts\/1847\/revisions"}],"predecessor-version":[{"id":1875,"href":"https:\/\/www.sabulo.com\/sb\/wp-json\/wp\/v2\/posts\/1847\/revisions\/1875"}],"wp:attachment":[{"href":"https:\/\/www.sabulo.com\/sb\/wp-json\/wp\/v2\/media?parent=1847"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sabulo.com\/sb\/wp-json\/wp\/v2\/categories?post=1847"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sabulo.com\/sb\/wp-json\/wp\/v2\/tags?post=1847"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}