<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.8.6">Jekyll</generator><link href="/feed.xml" rel="self" type="application/atom+xml" /><link href="/" rel="alternate" type="text/html" /><updated>2020-03-05T11:46:43+07:00</updated><id>/feed.xml</id><title type="html">tin.ng</title><subtitle>A development journal and personal blog.</subtitle><author><name>Tin Nguyen</name></author><entry><title type="html">Task Scheduler in Real-time Operating Systems (Part 1)</title><link href="/tutorial/task-scheduler-in-rtos-part-1" rel="alternate" type="text/html" title="Task Scheduler in Real-time Operating Systems (Part 1)" /><published>2019-05-19T00:00:00+07:00</published><updated>2019-05-19T00:00:00+07:00</updated><id>/tutorial/task%20scheduler%20in%20rtos%20part%201</id><content type="html" xml:base="/tutorial/task-scheduler-in-rtos-part-1">&lt;h1 id=&quot;overview&quot;&gt;Overview&lt;/h1&gt;

&lt;p&gt;This article is part 1 of an overview series specifically about the &lt;em&gt;Scheduler&lt;/em&gt; in a &lt;strong&gt;Real-time Operating System (RTOS)&lt;/strong&gt;. Examples of such systems can be found in almost anything from automotive application such as airbags, emergency breaks to avionics, and also infotainment, multi-media systems like video playback and QoS in web servers.&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;A real-time system is one in which the correctness of the system depends not only on the logical results of computation, but also on the time at which the results are generated.&lt;/p&gt;

  &lt;p&gt;This means that they both have to look at the output of the system and at the time at which the output was generated to determine whether an execution is successful.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;prerequisite&quot;&gt;Prerequisite&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;Assuming you have foundation knowledge about
    &lt;ul&gt;
      &lt;li&gt;&lt;em&gt;Programming&lt;/em&gt;, &lt;em&gt;Big-O Notation&lt;/em&gt;, &lt;em&gt;Algorithm&lt;/em&gt;, &lt;em&gt;Interrupt&lt;/em&gt; and &lt;em&gt;Computer Architecture&lt;/em&gt;&lt;/li&gt;
      &lt;li&gt;&lt;em&gt;Real-time Operating System (RTOS)&lt;/em&gt; knowledge would make it more comprehensive&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More about type of Real-time Systems coming later.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;(Optional) Schedule Simulation software &lt;a href=&quot;http://projects.laas.fr/simso/&quot;&gt;&lt;strong&gt;SimSo&lt;/strong&gt;&lt;/a&gt; which offer all Platform Compatibility (&lt;em&gt;Python-powered&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;understand-the-needs-for-scheduler&quot;&gt;Understand the needs for Scheduler&lt;/h1&gt;

&lt;p&gt;That said, in the heart of RTOS is the Scheduler and as the software complexity advances, the scheduling become more complex and thus expect extreme scheduling methods. For instance, there are only two &lt;strong&gt;Electronic Control Units (ECUs)&lt;/strong&gt; in luxury class cars in mid-80s to control most of the Engine, Exhaust, etc. and by the time this article was written, the BMW 7-series models have as many as &lt;em&gt;150 ECUs&lt;/em&gt;&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; and average at 80 ECUs in total.&lt;/p&gt;

&lt;p&gt;There are primarily two distinction of Real-time Systems, a missed deadline&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;In &lt;strong&gt;Hard Real-time&lt;/strong&gt;: is &lt;strong&gt;catastrophic&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;In &lt;em&gt;Soft Real-time&lt;/em&gt;: can lead to &lt;em&gt;significant loss&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One important concern in such a system like RTOS is the predictability of system behavior, meaning there should be no space for un-accountability, everything must be &lt;em&gt;accountable&lt;/em&gt; and &lt;em&gt;predictable&lt;/em&gt;. This is often achieved by either &lt;em&gt;static&lt;/em&gt; or &lt;em&gt;dynamic scheduling&lt;/em&gt; of Real-time tasks to meet their deadlines.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-05-19/rtos-taxonomy.png&quot; alt=&quot;Taxonomy of Real-time Systems Scheduling Scheme&quot; /&gt;
&lt;em&gt;Taxonomy of Real-time Systems Scheduling Scheme. Classified by &lt;strong&gt;system type&lt;/strong&gt; and &lt;strong&gt;scheduling mechanism&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;task-structure&quot;&gt;Task Structure&lt;/h2&gt;

&lt;p&gt;The Task Structure in RTOS includes the planning and the scheduling of workload on a processor and  guarantees that the workload timeline is never violated. That workload can be quantified into discrete pieces, i.e. &lt;strong&gt;a Task&lt;/strong&gt;. The functionality of a Task will be executed over and over again and thus differentiate between each iteration by an &lt;em&gt;instance of a task&lt;/em&gt;, a.k.a. &lt;strong&gt;a Job&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A periodic task, which will release a new job every time units, is usually defined by&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Period (P):&lt;/strong&gt; time interval between releases of jobs in a task
    &lt;ul&gt;
      &lt;li&gt;&lt;em&gt;Side Note:&lt;/em&gt; in reality, this interval is not necessarily constant with the presence of &lt;a href=&quot;#task-jitter&quot;&gt;jitter&lt;/a&gt; between task transition.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Execution time (&lt;script type=&quot;math/tex&quot;&gt;E_t&lt;/script&gt;):&lt;/strong&gt; how long the job is&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Deadline (D):&lt;/strong&gt; the deadline of a task&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-05-19/task-structure.png&quot; alt=&quot;Example of Task Structure&quot; /&gt;
&lt;em&gt;Example of Task &lt;script type=&quot;math/tex&quot;&gt;T_1&lt;/script&gt; with &lt;script type=&quot;math/tex&quot;&gt;P=3&lt;/script&gt; , &lt;script type=&quot;math/tex&quot;&gt;E_t=1s&lt;/script&gt; on x-axis of timeslice &lt;script type=&quot;math/tex&quot;&gt;t=1&lt;/script&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Since there is a latest time at which a task must be completed, all tasks must never violate its deadline. Although, a deadline can be defined as &lt;em&gt;absolute&lt;/em&gt; or &lt;em&gt;relative&lt;/em&gt; in &lt;em&gt;Hard Real-time&lt;/em&gt; or &lt;em&gt;Soft Real-time&lt;/em&gt; respectively.&lt;/p&gt;

&lt;p&gt;The longer the execution time, the more CPU resources are needed and if &lt;script type=&quot;math/tex&quot;&gt;E_t&lt;/script&gt; becomes too large, the CPU gets overloaded and it cannot handle all the tasks within the time limit.&lt;/p&gt;

&lt;h2 id=&quot;task-jitter&quot;&gt;Task Jitter&lt;/h2&gt;

&lt;p&gt;From the Task Structure, it is necessary to ensure the consistency between tasks and the amount of time it takes to complete current task and move on to the next task while not overloading the CPU. In reality, the transition is delayed due to various reasons: &lt;em&gt;current task not completely finished&lt;/em&gt;, &lt;em&gt;resource is not released&lt;/em&gt; and furthermore.&lt;/p&gt;

&lt;p&gt;The total amount of time for such delay is called &lt;em&gt;Task Jitter&lt;/em&gt;. Ideally, &lt;strong&gt;no jitter is desirable&lt;/strong&gt;, and Hard real-time scheduling ensures that with extremely precise scheduling, leaving no wasted time between task transition or &lt;a href=&quot;#data-inconsistency&quot;&gt;context switching&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; A &lt;em&gt;Hard Real-time&lt;/em&gt; OS has &lt;strong&gt;less jitter&lt;/strong&gt; than a &lt;em&gt;Soft Real-time OS&lt;/em&gt; in general.&lt;/p&gt;

&lt;p&gt;Example from this &lt;a href=&quot;https://stackoverflow.com/a/34077698&quot;&gt;SO discussion&lt;/a&gt; clearly demonstrate the scenario where Task Jitter is inevitable.&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;A task should be started after 10ms, but for whatever reason, it is started after 15ms. In our example the jitter is 5ms.&lt;/p&gt;

  &lt;p&gt;All tasks would use no more than 100ms per scheduled time, a task that requires and uses 150ms would cause significant scheduling jitter.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;data-inconsistency&quot;&gt;Data Inconsistency&lt;/h2&gt;

&lt;p&gt;When the scheduler switches the CPU from executing one task to execute another, the resource from the current running task is released for another task, usually higher priority, to take control and this process is called context switching.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;Context Switch&lt;/strong&gt; enables multiple tasks to share a single CPU by storing/restoring the state and context so that the execution can be preempted and resumed later &lt;em&gt;without interrupting current progress&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The context/shared memory require special attention since switching tasks will inevitably causing data inconsistency where any task could &lt;em&gt;alter the values&lt;/em&gt; or worse &lt;em&gt;completely corrupt it&lt;/em&gt;. This is partly solved by &lt;em&gt;creating a temporary lock on the resources&lt;/em&gt;, &lt;em&gt;buffer snapshot&lt;/em&gt; or other mechanisms such as &lt;strong&gt;Semaphore (Signaling)&lt;/strong&gt; or &lt;strong&gt;Mutual Exclusion (Locking)&lt;/strong&gt; to maintain the correct values between tasks.&lt;/p&gt;

&lt;h2 id=&quot;the-o1-task-scheduler-in-linux&quot;&gt;The O(1) Task Scheduler in Linux&lt;/h2&gt;

&lt;p&gt;Another reason for the needs of a Scheduler is efficiency when it comes to &lt;em&gt;task priority&lt;/em&gt;, what instruction should run first which would require more computing resources to calculate the order. This is what the O(1) Task Scheduler introduced in &lt;strong&gt;Linux 2.6&lt;/strong&gt; trying to solve.&lt;/p&gt;

&lt;p&gt;Essentially, there is a &lt;em&gt;First-In-First-Out&lt;/em&gt; (FIFO) &lt;strong&gt;Active Runqueues&lt;/strong&gt; and another FIFO &lt;strong&gt;Expired Runqueues&lt;/strong&gt;, each with their own tasks and their priorties. All tasks are scheduled based on priorities inside the Active Runqueue and ran based on a pre-defined &lt;strong&gt;timeslice&lt;/strong&gt;, and swap in the Tasks from Expired Runqueue once similar priorities from Active Runqueue is emptied.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The time it takes for the Linux Task Scheduler to find a task to execute depends not on the &lt;em&gt;number of active tasks&lt;/em&gt; but instead on the &lt;em&gt;number of priorities&lt;/em&gt; which is constant since there are only 140 priorities.&lt;/p&gt;

  &lt;p&gt;This makes the Linux 2.6 Task Scheduler an O(1) process because the time to schedule is both &lt;em&gt;fixed&lt;/em&gt; and &lt;em&gt;deterministic&lt;/em&gt; regardless of the number of active tasks.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Side note:&lt;/strong&gt; Linux 2.6 Task Scheduler also supports preemption, that is prioritize when a higher-priority task is ready to run and re-schedules the lower-priority task. It also offers Dynamic Task Prioritization at runtime in addition with the Static Task Prioritization defined at compile time.&lt;/p&gt;

&lt;h1 id=&quot;static-scheduling&quot;&gt;Static Scheduling&lt;/h1&gt;

&lt;p&gt;As mentioned, &lt;em&gt;predictability&lt;/em&gt; for an RTOS is an important characteristic and Static Scheduling provides just that, the ability to schedule, optimize for the tasks at runtime with very &lt;em&gt;low complexity&lt;/em&gt;. Although, this also means that every modification requires execution of the scheduling algorithm again.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-05-19/static-taxonomy.png&quot; alt=&quot;Taxonomy of Static Scheduling&quot; /&gt;
&lt;em&gt;Taxonomy of Static Scheduling binded with Priority Scheduling Scheme. Different methodologies include &lt;strong&gt;timeslice&lt;/strong&gt;, &lt;strong&gt;periodicity&lt;/strong&gt;, and &lt;strong&gt;priority&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For Static Scheduling, &lt;em&gt;all parameters of all the tasks are assumed knownn&lt;/em&gt; in which the Scheduler built a schedule based on this information. This characterstic makes it simplier to schedule by timeslice based on &lt;em&gt;task arrival pattern&lt;/em&gt; since there will be no change throughout the schedules.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Despite being fixed at runtime, Static Scheduling can be implemented in Search Tree where the tree level is Time Unit and the tree depth is Period in the schedule.&lt;/p&gt;

  &lt;p&gt;Another applications can be Process Control System where all sensory and actuator data range of all tasks are known before hand.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;clock-driven-scheduling&quot;&gt;Clock-Driven Scheduling&lt;/h2&gt;

&lt;p&gt;Clock-Driven Scheduling is a Static Scheduling mechanism that consist of the following characteristics:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Schedule is created off-line at compile time&lt;/li&gt;
  &lt;li&gt;Precedence is treated explicitly between tasks&lt;/li&gt;
  &lt;li&gt;Scheduler operates when timer expires, i.e. Timer interrupt&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Following is example of Clock-Driven Scheduling with a timeslice of Scheduling time &lt;script type=&quot;math/tex&quot;&gt;t=1s&lt;/script&gt; and three tasks &lt;script type=&quot;math/tex&quot;&gt;T_1&lt;/script&gt; , &lt;script type=&quot;math/tex&quot;&gt;T_2&lt;/script&gt; , &lt;script type=&quot;math/tex&quot;&gt;T_3&lt;/script&gt; scheduled at compile time.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Task (&lt;script type=&quot;math/tex&quot;&gt;T&lt;/script&gt;)&lt;/th&gt;
      &lt;th&gt;Period (&lt;script type=&quot;math/tex&quot;&gt;P&lt;/script&gt;)&lt;/th&gt;
      &lt;th&gt;Execution&lt;br /&gt;Time (&lt;script type=&quot;math/tex&quot;&gt;E_t&lt;/script&gt;)&lt;/th&gt;
      &lt;th&gt;Deadline (&lt;script type=&quot;math/tex&quot;&gt;D&lt;/script&gt;)&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;script type=&quot;math/tex&quot;&gt;T_1&lt;/script&gt;&lt;/td&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;3&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;script type=&quot;math/tex&quot;&gt;T_2&lt;/script&gt;&lt;/td&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;4&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;script type=&quot;math/tex&quot;&gt;T_3&lt;/script&gt;&lt;/td&gt;
      &lt;td&gt;10&lt;/td&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;10&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;em&gt;Table of Schedule for 3 Tasks with their Execution Time, Period and Deadline&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Before any scheduling, a concept of &lt;strong&gt;CPU Utilization is important&lt;/strong&gt; since tasks with fast period and long execution time will occupy a large amount of CPU resources.&lt;/p&gt;

&lt;p&gt;CPU Utilization is defined as the sum of all tasks’ Execution times &lt;script type=&quot;math/tex&quot;&gt;\sum E_i&lt;/script&gt; divided by their Periods &lt;script type=&quot;math/tex&quot;&gt;\sum P_i&lt;/script&gt;. &lt;strong&gt;If the sum is greater than 1, then the system is guaranteed not feasible&lt;/strong&gt;.&lt;/p&gt;

&lt;script type=&quot;math/tex; mode=display&quot;&gt;Utilization = \sum_{i=1}^{n}\frac{E_i}{P_i}&lt;/script&gt;

&lt;p&gt;For this example of 3 Tasks, &lt;script type=&quot;math/tex&quot;&gt;U = \frac{1}{3} + \frac{1}{4} + \frac{1}{5} = 0.78&lt;/script&gt;, and thus the system &lt;strong&gt;will not be unfeasible&lt;/strong&gt;. It does not mean the system is feasible yet, this point will be discussed in the schedule plot.&lt;/p&gt;

&lt;p&gt;On the following plot, the Scheduler generates and allocates Tasks with &lt;strong&gt;start-of-task&lt;/strong&gt; one direction arrow (&lt;script type=&quot;math/tex&quot;&gt;\uparrow&lt;/script&gt;) and &lt;strong&gt;end-of-task&lt;/strong&gt; small dot (.) at the end of Execution Time (filled range).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-05-19/clock-driven.png&quot; alt=&quot;Clock-Driven Scheduling of three tasks at one second timeslice&quot; /&gt;
&lt;em&gt;Task &lt;script type=&quot;math/tex&quot;&gt;T_1&lt;/script&gt;, &lt;script type=&quot;math/tex&quot;&gt;T_2&lt;/script&gt;, &lt;script type=&quot;math/tex&quot;&gt;T_3&lt;/script&gt; and Processor &lt;script type=&quot;math/tex&quot;&gt;P_0&lt;/script&gt; plotted on Scheduling time (&lt;script type=&quot;math/tex&quot;&gt;t&lt;/script&gt;) x-axis in 20 seconds. Plotted on &lt;a href=&quot;#prerequisite&quot;&gt;SimSo Simulation&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;On the first line of Task 1, the timer interrupts the system at time 0 and &lt;script type=&quot;math/tex&quot;&gt;T_1&lt;/script&gt; is selected. The job of &lt;script type=&quot;math/tex&quot;&gt;T_1&lt;/script&gt; is then executed through out its &lt;script type=&quot;math/tex&quot;&gt;E_{t1}&lt;/script&gt; and come to a stop at &lt;script type=&quot;math/tex&quot;&gt;t=1&lt;/script&gt; then the next task is up.
    &lt;ul&gt;
      &lt;li&gt;&lt;em&gt;Side Note:&lt;/em&gt; similarly the second and third lines of Task 2 and 3 respectively.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Since &lt;script type=&quot;math/tex&quot;&gt;T_3&lt;/script&gt; start-of-task is &lt;script type=&quot;math/tex&quot;&gt;t=1&lt;/script&gt;, it takes control next.
    &lt;ul&gt;
      &lt;li&gt;&lt;em&gt;Side Note:&lt;/em&gt; there is no concept of priority yet, the only determinants are which Task &lt;em&gt;available&lt;/em&gt; and &lt;em&gt;ready&lt;/em&gt;.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;At time &lt;script type=&quot;math/tex&quot;&gt;t=3&lt;/script&gt;, the Scheduler selects &lt;script type=&quot;math/tex&quot;&gt;T_1&lt;/script&gt; eventhough &lt;script type=&quot;math/tex&quot;&gt;T_2&lt;/script&gt; also starts at &lt;script type=&quot;math/tex&quot;&gt;t=3&lt;/script&gt;. That is because Task 3 Period is &lt;script type=&quot;math/tex&quot;&gt;P_3=4&lt;/script&gt; and thus not executed until the next timeslice &lt;script type=&quot;math/tex&quot;&gt;t=4&lt;/script&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
  &lt;p&gt;From the schedule plot, it seems all tasks executed &lt;em&gt;promptly&lt;/em&gt; and the schedule is &lt;em&gt;feasible&lt;/em&gt;. However, as mentioned on CPU Utilization, because of &lt;strong&gt;&lt;a href=&quot;#task-jitter&quot;&gt;task jitter&lt;/a&gt;&lt;/strong&gt; between transition or some jobs occur &lt;strong&gt;simultaneously&lt;/strong&gt;, the schedule will go wrong even if there are available CPU resources because the schedule is static.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;acknowledgement&quot;&gt;Acknowledgement&lt;/h1&gt;

&lt;p&gt;This series is heavily influenced by a &lt;a href=&quot;https://www.coursera.org/learn/real-time-systems/&quot;&gt;Coursera online course&lt;/a&gt; aiming for &lt;em&gt;Master’s student&lt;/em&gt; created by the &lt;strong&gt;EIT-Digital University&lt;/strong&gt; in &lt;em&gt;Turku&lt;/em&gt;, &lt;em&gt;Finland&lt;/em&gt; as part of the &lt;em&gt;on-campus course on Real-Time Systems&lt;/em&gt; as given in their Embedded Systems master curriculum.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;https://www.embitel.com/blog/embedded-blog/automotive-control-units-development-innovations-mechanical-to-electronics &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</content><author><name>Tin Nguyen</name></author><category term="O(1) Scheduler" /><category term="RTOS" /><category term="Static Scheduling" /><category term="Preemption" /><summary type="html">Define OS Scheduling based on different definition and mechanism, including discussion on methodologies such as Timeslice/Priority</summary></entry><entry><title type="html">MQTT protocol analysis for embedded systems and IoT applications</title><link href="/tutorial/mqtt-protocol-analysis-for-iot-application" rel="alternate" type="text/html" title="MQTT protocol analysis for embedded systems and IoT applications" /><published>2019-04-28T00:00:00+07:00</published><updated>2019-04-28T00:00:00+07:00</updated><id>/tutorial/MQTT%20protocol%20analysis%20for%20IoT%20application</id><content type="html" xml:base="/tutorial/mqtt-protocol-analysis-for-iot-application">&lt;h1 id=&quot;overview&quot;&gt;Overview&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;MQ Telemetry Transport&lt;/strong&gt; is a &lt;em&gt;Client – Server&lt;/em&gt; Publish/ Subscribe messaging transport protocol and was initially named after the &lt;strong&gt;MQ series&lt;/strong&gt; of IBM where the protocol was first developed for &lt;em&gt;proprietary embedded systems&lt;/em&gt; in the late 90’s.&lt;/p&gt;

&lt;p&gt;Nowadays, MQTT is considered as the &lt;strong&gt;protocol name&lt;/strong&gt;, as opposed to be an &lt;em&gt;acronym&lt;/em&gt; previously, and is the &lt;a href=&quot;https://www.iso.org/standard/69466.html&quot;&gt;de facto standard&lt;/a&gt; by OASIS and later ISO.&lt;/p&gt;

&lt;p&gt;Throughout the development of MQTT, &lt;strong&gt;ease of use&lt;/strong&gt; was always the key concern and thus the protocol are said to be &lt;em&gt;easy to implement&lt;/em&gt; on the &lt;em&gt;client side&lt;/em&gt; and excel at transferring data over the wire since it is &lt;em&gt;lightweight&lt;/em&gt;, &lt;em&gt;simple&lt;/em&gt;, and a widely adapted &lt;em&gt;open standard&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Ultimately, the &lt;strong&gt;goal&lt;/strong&gt; for this type of protocol is to ensure the communication channel in constrained environments, e.g. Machine to Machine (M2M) and Internet of Things (IoT) applications where a &lt;strong&gt;minimal code footprint&lt;/strong&gt; is desirable and a &lt;strong&gt;limited network bandwidth&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;prerequisite&quot;&gt;Prerequisite&lt;/h1&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;A MQTT Client (for Desktop), e.g. &lt;a href=&quot;https://mqttfx.jensd.de/index.php/download&quot;&gt;MQTT.fx&lt;/a&gt;, a cross-platform client (Windows, macOS, Linux) built under the Eclipse Paho Project. Another option is &lt;a href=&quot;https://mosquitto.org/download/&quot;&gt;Mosquito MQTT&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;(Optional) Setup Mathwork free account for &lt;a href=&quot;https://thingspeak.com&quot;&gt;ThingSpeak&lt;/a&gt; &amp;amp; &lt;a href=&quot;https://www.mathworks.com/products/matlab-online.html&quot;&gt;MATLAB Online&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
  &lt;p&gt;If you have already understand MQTT, well done ! Skip to the second part of the article for instruction on how to setup and observe MQTT in action or read more about how the packets transmitted over the TCP/IP protocol.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; From this point onwards, the term MQTT is referring to the &lt;strong&gt;MQTT Version 3.1.1&lt;/strong&gt; of the &lt;a href=&quot;http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.pdf&quot;&gt;OASIS standard&lt;/a&gt;. Official PDF can be downloaded &lt;a href=&quot;http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.pdf&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h1 id=&quot;understand-how-mqtt-works&quot;&gt;Understand how MQTT works&lt;/h1&gt;

&lt;p&gt;The Pub/ Sub pattern of MQTT provides a &lt;strong&gt;decoupling mechanism&lt;/strong&gt; between the &lt;em&gt;Client&lt;/em&gt; and &lt;em&gt;Server&lt;/em&gt; where the &lt;em&gt;Broker&lt;/em&gt; acting as a &lt;strong&gt;medium&lt;/strong&gt; between them (this can be extrapolated from the preview image).&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Space Decoupling: Publisher and Subscriber &lt;strong&gt;do not need to know each other&lt;/strong&gt;, i.e. no exchange of IP address and port.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Time Decoupling: Publisher and Subscriber &lt;strong&gt;do not need to run at the same time&lt;/strong&gt;, e.g. sensor update at specific interval and only retrieved to end-user when needed.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Synchronization Decoupling: Operations on both components &lt;strong&gt;do not need to be interrupted&lt;/strong&gt; during sending or receiving.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-fixed-header&quot;&gt;The Fixed Header&lt;/h2&gt;

&lt;p&gt;There are three different aspects of MQTT include &lt;strong&gt;basic concepts&lt;/strong&gt; (Publish/ Subscribe, Client/ Broker), &lt;strong&gt;basic functionalities&lt;/strong&gt; (Connect, Publish, Subscribe) of MQTT and &lt;strong&gt;basic features&lt;/strong&gt; such as &lt;em&gt;Quality of Service&lt;/em&gt;, &lt;em&gt;Retained Messages&lt;/em&gt;, &lt;em&gt;Persistent Session&lt;/em&gt;, &lt;em&gt;Last Will and Testament&lt;/em&gt;, &lt;em&gt;Keep Alive&lt;/em&gt; and more.&lt;/p&gt;

&lt;p&gt;Specifically, these &lt;strong&gt;functionalities&lt;/strong&gt; (&lt;em&gt;CONNECT&lt;/em&gt;, &lt;em&gt;PUBLISH&lt;/em&gt;, &lt;em&gt;SUBSCRIBE&lt;/em&gt;, &lt;em&gt;UNSUBSCRIBE&lt;/em&gt; and &lt;em&gt;DISCONNECT&lt;/em&gt;, etc.) are defined in a &lt;a href=&quot;http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718021&quot;&gt;MQTT Control Package Type&lt;/a&gt; and comprise the Fixed Header (bit 7 - bit 4), i.e. the protocol &lt;a href=&quot;http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Figure_2.2_-&quot;&gt;first header&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-04-28/fixed_header.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Fixed Header format&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In general, the protocol has &lt;a href=&quot;http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Figure_2.1_-&quot;&gt;three different headers&lt;/a&gt; vary by the package type.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-04-28/structure_header.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Structure of an MQTT Control Packet&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Side note:&lt;/strong&gt; &lt;a href=&quot;http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718021&quot;&gt;Full list&lt;/a&gt; of Control Packet Types.&lt;/p&gt;

&lt;h2 id=&quot;the-variable-header&quot;&gt;The Variable Header&lt;/h2&gt;

&lt;p&gt;A &lt;em&gt;Variable Header&lt;/em&gt; includes a 2 byte &lt;strong&gt;Packet Identifier&lt;/strong&gt; field  and resides between the &lt;em&gt;Fixed Header&lt;/em&gt; and the &lt;em&gt;Payload&lt;/em&gt;. Although, &lt;a href=&quot;http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc385349217&quot;&gt;not every&lt;/a&gt; Control Package requires the identifier field.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-04-28/variable_header.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;An example of Variable Header of the &lt;strong&gt;CONNECT&lt;/strong&gt; packet with Protocol Length, Protocol Name, Protocol Level, Connect Flag, and Keep Alive fields.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For the above example, every bits encoded in hexadecimal format, e.g. Keep Alive field of 60 seconds (&lt;script type=&quot;math/tex&quot;&gt;60_{DEC} = 3C_{HEX}&lt;/script&gt;).&lt;/p&gt;

&lt;h2 id=&quot;the-payload&quot;&gt;The Payload&lt;/h2&gt;

&lt;p&gt;A Payload is the final part of the packet and also optional depends on the Control Package type. In the case of the &lt;strong&gt;PUBLISH&lt;/strong&gt; packet this is optional and commonly named as the &lt;em&gt;Application Message&lt;/em&gt;, whereas it’s required in the &lt;strong&gt;SUBSCRIBE&lt;/strong&gt; package and contain &lt;em&gt;Topic Filter&lt;/em&gt;, &lt;em&gt;Quality of Service&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-04-28/payload_header.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;An example of Payload of the &lt;strong&gt;CONNECT&lt;/strong&gt; packet with *Client Identifier&lt;/em&gt; fields*&lt;/p&gt;

&lt;h2 id=&quot;quality-of-service&quot;&gt;Quality of Service&lt;/h2&gt;

&lt;p&gt;MQTT Protocol ensures high delivery guarantees with 3 levels of QoS serve to the constraint of embedded system communication in previous discussion.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;QoS 0&lt;/strong&gt;: Guarantees a &lt;strong&gt;best effort&lt;/strong&gt; delivery but not result.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-04-28/mqtt_publish_qos0.png&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Image courtesy of MATLAB &lt;a href=&quot;https://www.mathworks.com/help/thingspeak/mqtt-api.html?s_tid=CRUX_lftnav&quot;&gt;MQTT API&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;QoS 1&lt;/strong&gt;: Guarantees that a message will be &lt;strong&gt;delivered&lt;/strong&gt; at least once.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-04-28/mqtt_publish_qos1.png&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Image courtesy of MATLAB &lt;a href=&quot;https://www.mathworks.com/help/thingspeak/mqtt-api.html?s_tid=CRUX_lftnav&quot;&gt;MQTT API&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;QoS 2&lt;/strong&gt;: Guarantees that each message is &lt;strong&gt;received&lt;/strong&gt; only once by the counterpart&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-04-28/mqtt_publish_qos2.png&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Image courtesy of MATLAB &lt;a href=&quot;https://www.mathworks.com/help/thingspeak/mqtt-api.html?s_tid=CRUX_lftnav&quot;&gt;MQTT API&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Beside that, MQTT also provides other mechanism for quality control.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Last will&lt;/strong&gt; means in case of unexpected disconnection of a client all subscribed clients will get a message from a broker.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Testament and &lt;strong&gt;Retained message&lt;/strong&gt; means that a newly subscribed client will get an immediate status update.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;implement-mqtt-for-practical-uses&quot;&gt;Implement MQTT for practical uses&lt;/h1&gt;

&lt;p&gt;Now that you have an idea of MQTT, let’s examine it in action using &lt;strong&gt;MQTT.fx&lt;/strong&gt; to establish the connection and &lt;strong&gt;Wireshark&lt;/strong&gt; to capture the packet.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-04-28/fx_setting.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;In MQTT.fx Setting tab, select “MQTT Broker” under Profile section and fill in ThingSpeak Server info as above&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you have a MathWork ThingSpeak/MATLAB account, sign in under &lt;em&gt;User Credentials&lt;/em&gt; sub-menu (Refer to Prerequisite). Otherwise, leave at default.&lt;/p&gt;

&lt;p&gt;Under tab &lt;code class=&quot;highlighter-rouge&quot;&gt;Subscribe&lt;/code&gt;, use the below syntax to Subscribe any &lt;a href=&quot;https://thingspeak.com/channels/public&quot;&gt;Public channel&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;channels/&lt;span class=&quot;nt&quot;&gt;&amp;lt;channel&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;_ID&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;/subscribe/json
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once you receive the channel feed, it means that&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;The connection was requested &amp;amp; Server Acknowledged Request&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Subscription requested &amp;amp; Server Acknowledged Subscription&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Message Published from Server to MQTT.fx client&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This can be verified in Wireshark by select “Start Capturing Packet” icon in the Top bar and &lt;strong&gt;re-do every steps&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-04-28/wireshark_preview.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;MQTT packet captured while using MQTT.fx to the Broker on ThingSpeak server&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Side note:&lt;/strong&gt; Use “MQTT” (protocol) or “1883” (port) as the filter for better analysis.&lt;/p&gt;

&lt;p&gt;Under &lt;strong&gt;network layer&lt;/strong&gt; section, it can seen that MQTT indeed working on top of the &lt;em&gt;TCP/IP layer&lt;/em&gt;. Beside that, Wireshark provides deeper look into the protocol and exactly how the packet  was formed.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-04-28/wireshark_connect.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Analysis of MQTT CONNECT packet headers and flags setup&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This can breakdown into several headers as discussed, i.e. &lt;span style=&quot;color:blue&quot;&gt;Fixed Header &lt;/span&gt; with &lt;em&gt;Control Packet Type&lt;/em&gt;, &lt;span style=&quot;color:SlateBlue&quot;&gt;Variable Header&lt;/span&gt; with &lt;em&gt;Protocol Length/ Name&lt;/em&gt;, &lt;em&gt;Connect Flags&lt;/em&gt;, &lt;em&gt;Keep Alive&lt;/em&gt; fields and lastly the &lt;span style=&quot;color:orange&quot;&gt;Payload&lt;/span&gt; with &lt;em&gt;Client ID&lt;/em&gt; and &lt;em&gt;Authentication&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Also, these information can be interpreted in raw hexadecimal format too.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-04-28/wireshark_hex.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Same MQTT packet in raw HEX code with Headers &lt;strong&gt;highlighted&lt;/strong&gt; and Fields &lt;strong&gt;separated&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tips:&lt;/strong&gt; You can &lt;em&gt;hover&lt;/em&gt; over the HEX code in Wireshark to display the MQTT field that matches in the control bar at the bottom.&lt;/p&gt;

&lt;p&gt;By using any DEC-HEX decoder, these code will yield similar result as expected.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-04-28/excel_packet.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Analysis of the same &lt;strong&gt;CONNECT&lt;/strong&gt; packet in Microsoft Excel. Grab it &lt;a href=&quot;/assets/blogs/2019-04-28/mqtt_tutorial.xlsx&quot;&gt;here&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In Excel, the &lt;em&gt;built-in&lt;/em&gt; function &lt;code class=&quot;highlighter-rouge&quot;&gt;CODE()&lt;/code&gt; convert character to ASCII and &lt;code class=&quot;highlighter-rouge&quot;&gt;DEX2HEX()&lt;/code&gt; could seamlessly achieve the task and of course modify to analyze other MQTT packets.&lt;/p&gt;

&lt;h1 id=&quot;thingspeak--matlab-application&quot;&gt;ThingSpeak &amp;amp; MATLAB Application&lt;/h1&gt;

&lt;p&gt;The great thing about ThingSpeak &amp;amp; MATLAB combination is that it provides an &lt;em&gt;easy-to-implement&lt;/em&gt; approach &lt;em&gt;without any restriction&lt;/em&gt; of further improvement.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-04-28/thingspeak_esp.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;ThingSpeak panels provide basic data collection and visualization&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Many tools can be found under &lt;code class=&quot;highlighter-rouge&quot;&gt;Apps&lt;/code&gt; top menu on your ThingSpeak &lt;a href=&quot;https://thingspeak.com/account/profile&quot;&gt;profile&lt;/a&gt; with two &lt;a href=&quot;https://thingspeak.com/apps&quot;&gt;main categories&lt;/a&gt;: &lt;strong&gt;Analytics&lt;/strong&gt; and &lt;strong&gt;Actions&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;For instances, you could use ThingSpeak to &lt;strong&gt;capture the temperature&lt;/strong&gt; from sensor via MQTT, then import to MATLAB using script for &lt;strong&gt;Data Cleansing&lt;/strong&gt; or use a Widget &lt;strong&gt;ThingTweet&lt;/strong&gt; to inform public on sudden temperature changes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On the other hand, MATLAB also provides excellent &lt;a href=&quot;https://www.mathworks.com/matlabcentral/fileexchange/52244-thingspeak-support-toolbox&quot;&gt;MQTT Support Toolbox&lt;/a&gt; for both reading and writing data directly to the ThingSpeak database.&lt;/p&gt;

&lt;p&gt;Connect to &lt;a href=&quot;https://matlab.mathworks.com&quot;&gt;MATLAB Online&lt;/a&gt; and try it out !&lt;/p&gt;

&lt;div class=&quot;language-matlab highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;% thingSpeakRead(&amp;lt;channelID&amp;gt;, &amp;lt;Name&amp;gt;, &amp;lt;Value&amp;gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thingSpeakRead&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12397&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;% Or specific Fields with Output Format flag&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;thingSpeakRead&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12397&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Fields'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'NumPoints'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'OutputFormat'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'table'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;% Now try to write to your private channel&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;% NOTE: Example Key Value&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;% Update multiple fields at once &lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;thingSpeakWrite&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;channelID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'WriteKey'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;...&lt;/span&gt;
		&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;field1_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;field2_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;field3_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; 

&lt;span class=&quot;c1&quot;&gt;% Or automated process for batch authentication from multiple channels&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;thingSpeakAuthenticate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;channelID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Tips:&lt;/strong&gt; Use &lt;code class=&quot;highlighter-rouge&quot;&gt;help&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;doc&lt;/code&gt; prefix in MATLAB Console Window on instruction how to implement the commands and its parameters&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-04-28/thingspeak_bihistogram.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;An Example of Bi-Histogram from ThingSpeak data imported for a Transportation Tracking application.&lt;/em&gt;&lt;/p&gt;

&lt;h1 id=&quot;troubleshooting-extra&quot;&gt;Troubleshooting (Extra)&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;Authorization issues in MQTT.fx&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Make sure that you type in &lt;strong&gt;User-ID&lt;/strong&gt; and &lt;strong&gt;MQTT-API-key&lt;/strong&gt; for fields &amp;lt;User Name&amp;gt; and &amp;lt;Password&amp;gt; of &lt;em&gt;User Credentials&lt;/em&gt; Tab respectively.&lt;/p&gt;

&lt;p&gt;Both can be found under &lt;code class=&quot;highlighter-rouge&quot;&gt;Account&lt;/code&gt; &lt;script type=&quot;math/tex&quot;&gt;\rightarrow&lt;/script&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;My Profile&lt;/code&gt; on your ThingSpeak &lt;a href=&quot;https://thingspeak.com/account/profile&quot;&gt;profile&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Decimal-Hexadecimal Conversion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In case you could not access the &lt;a href=&quot;/assets/blogs/2019-04-28/mqtt_tutorial.xlsx&quot;&gt;Excel&lt;/a&gt; file for reading the content of a MQTT packet, try to use directly in &lt;a href=&quot;https://matlab.mathworks.com&quot;&gt;MATLAB Online&lt;/a&gt; with the &lt;a href=&quot;https://www.mathworks.com/help/matlab/ref/dec2hex.html&quot;&gt;Dec2Hex&lt;/a&gt; built-in function.&lt;/p&gt;

&lt;hr /&gt;</content><author><name>Tin Nguyen</name></author><category term="MQTT" /><category term="ThingSpeak" /><category term="MATLAB" /><category term="Machine-to-Machine" /><category term="Wireshark" /><summary type="html">Understand the lightweight MQTT communication protocol and practical implementation as well as advantages/trade-offs</summary></entry><entry><title type="html">Configure Graphical UI access to VMs on Google Compute Engine</title><link href="/tutorial/graphical-interface-virtual-machine" rel="alternate" type="text/html" title="Configure Graphical UI access to VMs on Google Compute Engine" /><published>2019-04-16T00:00:00+07:00</published><updated>2019-04-16T00:00:00+07:00</updated><id>/tutorial/Graphical%20interface%20virtual%20machine</id><content type="html" xml:base="/tutorial/graphical-interface-virtual-machine">&lt;h1 id=&quot;overview&quot;&gt;Overview&lt;/h1&gt;
&lt;p&gt;Google Compute Engine is an &lt;em&gt;Infrastructure as a Service&lt;/em&gt; (IaaS) component of the &lt;em&gt;Google Cloud Platform &lt;/em&gt;(GCP) and aiming to &lt;strong&gt;provide specific hardware&lt;/strong&gt; and &lt;strong&gt;utilize the cloud environment&lt;/strong&gt; for development as well as production.&lt;/p&gt;

&lt;p&gt;With Compute Engine, an instance could be generated with a couple of clicks with &lt;em&gt;“a custom Machine Types optimized for your specific needs”&lt;/em&gt;.  This is a great tool alongside with Docker, Kubernetes, etc. and is a game changer in the software industry and definitely a must-have tool.&lt;/p&gt;

&lt;h1 id=&quot;prerequisite&quot;&gt;Prerequisite&lt;/h1&gt;
&lt;blockquote&gt;
  &lt;p&gt;If you have &lt;a href=&quot;https://tin.ng/2019/03/05/how-to-setup-and-remotely-access-to-vm-instances-on-cloud/&quot;&gt;already created your own VM instance&lt;/a&gt;, well done ! This is the next part to setup a Graphical User Interface (GUI) for your virtual computer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;vm-setups&quot;&gt;VM setups&lt;/h1&gt;
&lt;p&gt;There are two essential components required in order for this to work includes a &lt;em&gt;desktop environment&lt;/em&gt; and the &lt;em&gt;Virtual Network Computing&lt;/em&gt; (VNC) tool.&lt;/p&gt;

&lt;p&gt;Both can be installed via the &lt;em&gt;Command Line Interface&lt;/em&gt; (CLI) from our previous SSH session (If you forgot, &lt;em&gt;don’t worry&lt;/em&gt; ! Refer to “&lt;a href=&quot;http://tin.ng/2019/03/05/how-to-setup-and-remotely-access-to-vm-instances-on-cloud/#2-ssh-into-your-vm-instance&quot;&gt;how to SSH into your vm instance&lt;/a&gt;”).&lt;/p&gt;
&lt;h2 id=&quot;install-desktop-environment&quot;&gt;Install Desktop Environment&lt;/h2&gt;
&lt;p&gt;A CLI is differentiated based on the type of OS image and commonly is a &lt;em&gt;Terminal&lt;/em&gt;, &lt;em&gt;Console&lt;/em&gt; or some specific application with &lt;em&gt;Shell&lt;/em&gt; (an interface) on it.&lt;/p&gt;

&lt;div class=&quot;language-slim highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nt&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;apt-get&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;update
&lt;span class=&quot;nt&quot;&gt;apt&lt;/span&gt;-get&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;install&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;xfce4
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;sudo&lt;/code&gt; &amp;lt;Admin Privilege&amp;gt; ;  &lt;code class=&quot;highlighter-rouge&quot;&gt;install&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;update&lt;/code&gt; &amp;lt;Command&amp;gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;apt-get&lt;/code&gt;: Package Manager, Others: &lt;code class=&quot;highlighter-rouge&quot;&gt;aptitude&lt;/code&gt;; &lt;code class=&quot;highlighter-rouge&quot;&gt;yum&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;xfce4&lt;/code&gt;: Desktop Environment, Others: &lt;code class=&quot;highlighter-rouge&quot;&gt;gnome&lt;/code&gt; ; &lt;code class=&quot;highlighter-rouge&quot;&gt;KDE&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;install-vnc-client&quot;&gt;Install VNC Client&lt;/h2&gt;
&lt;div class=&quot;language-slim highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nt&quot;&gt;apt&lt;/span&gt;-get&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;install&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;tightvncserver
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;tightvncserver&lt;/code&gt;: VNC Client, Others: &lt;code class=&quot;highlighter-rouge&quot;&gt;realvnc-vnc-server&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After successful installation, run command &lt;code class=&quot;highlighter-rouge&quot;&gt;tightvncserver&lt;/code&gt; to initialize the server and identify the &lt;code class=&quot;highlighter-rouge&quot;&gt;xstartup&lt;/code&gt; file in order to register installed desktop environment.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-04-16/desktop_env.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Register newly installed desktop environment in VNC server startup file.&lt;/em&gt;&lt;/p&gt;

&lt;div class=&quot;language-slim highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nt&quot;&gt;sudo&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;vim&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;/home/user-name/&lt;span class=&quot;nc&quot;&gt;.vnc&lt;/span&gt;/xstartup
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;vim&lt;/code&gt;: Text Editor, &lt;code class=&quot;highlighter-rouge&quot;&gt;:wq&lt;/code&gt; to Save &amp;amp; Quit. &lt;strong&gt;Trust me you will need it !&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hint:&lt;/strong&gt; The syntax is &lt;code class=&quot;highlighter-rouge&quot;&gt;start&amp;lt;desktop-environment&amp;gt;&lt;/code&gt;
and an ampersand &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;amp;&lt;/code&gt; to link with the rest of the script.&lt;/p&gt;

&lt;p&gt;Ultimately, follow the instruction to setup &lt;strong&gt;credential key&lt;/strong&gt;, this will be the &lt;strong&gt;access password&lt;/strong&gt; for the upcoming VNC session.&lt;/p&gt;

&lt;h1 id=&quot;network-connectivity&quot;&gt;Network Connectivity&lt;/h1&gt;
&lt;p&gt;After you have successfully installed all required components, test run the VNC server and its connectivity:&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;tightvncserver&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;nc&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;localhost&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5901&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-04-16/init_vnc.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Success initialization of the VNC Server. Port &amp;lt;5901&amp;gt; returns value meaning it is listening and &lt;code class=&quot;highlighter-rouge&quot;&gt;RFB&lt;/code&gt; indicates our server is up and running.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;nc&lt;/code&gt; net cat &amp;lt;Command&amp;gt;. More on the command &lt;em&gt;manual&lt;/em&gt; with &lt;code class=&quot;highlighter-rouge&quot;&gt;man nc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;5901&amp;gt;&lt;/code&gt;: Default VNC Connection Port (5800/5900), increment 1 for every new session (next, X:2 5902, X:3 5903, etc.)&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;RFB&lt;/code&gt;: Remote Frame Buffer, this means the port is &lt;em&gt;up&lt;/em&gt; and &lt;em&gt;listening&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Although the server is up, the port still need to be configured &lt;em&gt;forwarding&lt;/em&gt; to the Internet (out of the VM instance, on GCP) for remote access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Side note:&lt;/strong&gt; On your &lt;strong&gt;local&lt;/strong&gt; computer, you can try to test the connectivity to the instance (which will be unconnected since the VNC server port is not &lt;em&gt;forwarding&lt;/em&gt;). &lt;strong&gt;Hint:&lt;/strong&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;nc &amp;lt;global-ip&amp;gt; &amp;lt;port&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;configure-port-for-remote-access&quot;&gt;Configure port for remote access&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Before configure any settings&lt;/strong&gt;, &lt;em&gt;always backup&lt;/em&gt; or at least write down every step so that it’s easier for you to trace back later. Also, &lt;em&gt;turn off VNC server&lt;/em&gt; and close port &lt;code class=&quot;highlighter-rouge&quot;&gt;tightvncserver -kill: X&lt;/code&gt; with X essentially the number of your session.&lt;/p&gt;

&lt;p&gt;From the &lt;em&gt;Compute Engine&lt;/em&gt; page, go to your vm tab - click on more (at the right end) and select &lt;em&gt;view network details&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;From the Firewall Rules page, select &lt;em&gt;Create Firewall Rule&lt;/em&gt; on the top bar.&lt;/p&gt;

&lt;p&gt;Modify these fields:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Name: &lt;em&gt;default-vnc-server&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Description: &lt;em&gt;instance-name&lt;/em&gt; ; &lt;em&gt;vnc-server&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Source Filter: &lt;strong&gt;Select&lt;/strong&gt; IP Range&lt;/li&gt;
  &lt;li&gt;Source IP Range: &lt;strong&gt;Type&lt;/strong&gt; “0.0.0.0/0”, allow all incoming connection&lt;/li&gt;
  &lt;li&gt;Specified Protocol and Ports: &lt;strong&gt;Type&lt;/strong&gt; “tcp:5901”, specify for VNC&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then leave the rest as default (modify only when you are sure what it does) and &lt;strong&gt;hit create&lt;/strong&gt;. And &lt;em&gt;voila&lt;/em&gt; now everything is running and establishing a connection !&lt;/p&gt;

&lt;h2 id=&quot;establish-vnc-connection&quot;&gt;Establish VNC Connection&lt;/h2&gt;
&lt;p&gt;The only step left is to find your VM External (Global) IP Address and access into it from your &lt;strong&gt;local&lt;/strong&gt; computer.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;External IP from the Developer console&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-04-16/external_ip.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Retrieve External IP Address of your instance from &lt;strong&gt;Compute Engine&lt;/strong&gt; page on the Cloud console.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;External IP from 3rd party provider&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ifconfig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;me&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This method &lt;em&gt;contains security risk&lt;/em&gt; for obvious reason.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Once having the External IP&lt;/strong&gt; of your instance, access to it using any of the available VNC Viewer for your computer OS.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Built-in VNC viewer for macOS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every macOS computer contains a built-in VNC viewer and can be quickly activate via Finder shortcut &lt;code class=&quot;highlighter-rouge&quot;&gt;⌘ + K&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-04-16/vnc_native.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;VNC session using native tool &lt;strong&gt;Screen Sharing&lt;/strong&gt; on &lt;strong&gt;macOS 10.14.1&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hint:&lt;/strong&gt; The syntax is &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;protocol&amp;gt;://&amp;lt;global-ip&amp;gt;:&amp;lt;port&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Third-party VNC Viewer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-04-16/vnc_viewer.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;VNC session using &lt;strong&gt;Jump Desktop&lt;/strong&gt; on &lt;strong&gt;macOS 10.14.1&lt;/strong&gt;. Others: &lt;strong&gt;VNC Viewer&lt;/strong&gt; (RealVNC), &lt;strong&gt;Screen 4&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h1 id=&quot;troubleshooting-extra&quot;&gt;Troubleshooting (Extra)&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;Issue with Desktop Environment configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Re-check if the Default Session, i.e. which DE to start up, is correct in the Display Managers: lightdm, GDM&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Forgot VNC Server Password (tightvncserver)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;On vm instance&lt;/strong&gt;, type &lt;code class=&quot;highlighter-rouge&quot;&gt;vncpasswd&lt;/code&gt; into the CLI and follow instruction to reset the password.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;VNC Server port not forwarding&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Re-check the Firewall settings of your computer for issue such as SSH permission, SSH tunneling config.&lt;/p&gt;

&lt;p&gt;Also, from &lt;em&gt;Compute Engine&lt;/em&gt; page, &lt;em&gt;click&lt;/em&gt; on your VM and select &lt;em&gt;edit&lt;/em&gt;. In network tag, add the &lt;code class=&quot;highlighter-rouge&quot;&gt;default-vnc-server&lt;/code&gt; tag or the equivalent name that you &lt;a href=&quot;http://tin.ng/2019/04/16/configure-graphical-ui-access-to-vms-on-google-compute-engine/#configure-port-for-remote-access&quot;&gt;created before&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;</content><author><name>Tin Nguyen</name></author><category term="Compute Engine" /><category term="Virtual Network Computing" /><summary type="html">After setup and SSH into the VM, graphical interface can be installed and executed via terminal</summary></entry><entry><title type="html">Jekyll Category and Tag Taxonomies for custom Collection</title><link href="/tutorial/jekyll-category-tag-for-custom-collection" rel="alternate" type="text/html" title="Jekyll Category and Tag Taxonomies for custom Collection" /><published>2019-03-17T00:00:00+07:00</published><updated>2019-08-22T00:00:00+07:00</updated><id>/tutorial/jekyll%20category%20tag%20for%20custom%20collection</id><content type="html" xml:base="/tutorial/jekyll-category-tag-for-custom-collection">&lt;h1 id=&quot;update&quot;&gt;Update&lt;/h1&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;As of August &lt;script type=&quot;math/tex&quot;&gt;20^{th}&lt;/script&gt; 2019, Jekyll 4.0 release will support natively category and tag for custom collection&lt;/strong&gt;. This means the work-around is no longer necessary. However, this tutorial is left here in case anyone still need it. For instance, static-blog hosts support only older Jekyll version.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;overview&quot;&gt;Overview&lt;/h1&gt;

&lt;p&gt;The main purpose of this &lt;strong&gt;category / tag iterator&lt;/strong&gt; is to create an index page, or a taxonomy. Brief review about Collection will be mentioned, but at this point, you should be able to &lt;em&gt;build&lt;/em&gt;, &lt;em&gt;host&lt;/em&gt; your own site and understand basic functionality of &lt;em&gt;layout&lt;/em&gt;, &lt;em&gt;include&lt;/em&gt; and &lt;em&gt;post&lt;/em&gt; folders.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick View of the result&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;a href=&quot;/tags/&quot;&gt;Tag Archive&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;/categories/&quot;&gt;Category Archive&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An alternative would be using the Ruby plugin &lt;code class=&quot;highlighter-rouge&quot;&gt;jekyll-archives&lt;/code&gt;, although as mentioned earlier these additional / non-native plugin could be not supported depend on build on the server host.&lt;/p&gt;

&lt;h1 id=&quot;prerequisite&quot;&gt;Prerequisite&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;Define a custom Collection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In case you do not have a custom collection already, it can be quickly configured. In &lt;code class=&quot;highlighter-rouge&quot;&gt;_config.xml&lt;/code&gt;, a custom collection of &lt;code class=&quot;highlighter-rouge&quot;&gt;recipe&lt;/code&gt; is defined as below.&lt;/p&gt;
&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;ss&quot;&gt;collections:
  category: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recipe&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;output: &lt;/span&gt;&lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;

&lt;span class=&quot;ss&quot;&gt;defaults:
  &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;scope:
      path: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;type: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recipe&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;values:
      layout: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;single&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Usage in article YAML Front Matter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the configuration is defined, simply add it in your article. For example, this tutorial has the following tags defined in its Front Matter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; &lt;strong&gt;YAML Front Matter&lt;/strong&gt; is essentially everything inside the &lt;em&gt;divider (3-dashes)&lt;/em&gt; at the beginning of your article.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;o&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;ss&quot;&gt;categories: &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Tutorial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Productivity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;ss&quot;&gt;tags: &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Jekyll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Taxonomy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;---&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;category-tag-iterator&quot;&gt;Category Tag Iterator&lt;/h1&gt;

&lt;p&gt;It depends on your purpose to place the following code snippet in the correct place, bu typically this would be in file &lt;code class=&quot;highlighter-rouge&quot;&gt;_layout/categories.html&lt;/code&gt; if you want to create an Index / Taxonomy page.&lt;/p&gt;

&lt;h2 id=&quot;collect-all-data-from-collection&quot;&gt;Collect all data from collection&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;Assign variable &lt;code class=&quot;highlighter-rouge&quot;&gt;thisCollection&lt;/code&gt; for your custom collection data&lt;/li&gt;
  &lt;li&gt;Apply filter to keep only category
    &lt;ul&gt;
      &lt;li&gt;&lt;em&gt;group_by:&lt;/em&gt; Re-group field data by their &lt;code class=&quot;highlighter-rouge&quot;&gt;category&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;em&gt;join, split:&lt;/em&gt; Order field data into an array with &lt;code class=&quot;highlighter-rouge&quot;&gt;,&lt;/code&gt; delimeter&lt;/li&gt;
      &lt;li&gt;&lt;em&gt;map:&lt;/em&gt; Keep only data belongs to &lt;code class=&quot;highlighter-rouge&quot;&gt;site.categories&lt;/code&gt; i.e. our interested categories.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; The &lt;code class=&quot;highlighter-rouge&quot;&gt;|&lt;/code&gt; is the &lt;em&gt;pipe special character&lt;/em&gt; from &lt;strong&gt;Liquid&lt;/strong&gt; syntax.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;% assign &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;thisCollection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;portfolio&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%}	
{% assign allCats =  thisCollection | map: 'categories' | join: ','  | split: ','  | group_by: category %}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;array-for-unique-values&quot;&gt;Array for unique values&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;This stage is not necessary but recommended&lt;/strong&gt;, if you’re doing indexer, it is best to count duplicated values and later display that Category only once.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;% capture &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;category_array&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%}
  {% for eachCat in allCats %}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eachCat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;% endfor &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;% endcapture &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;iterate-all-categories&quot;&gt;Iterate all categories&lt;/h2&gt;

&lt;p&gt;Now it is essentially a nested &lt;code class=&quot;highlighter-rouge&quot;&gt;for-loop&lt;/code&gt; to match all of categories of the current article (&lt;code class=&quot;highlighter-rouge&quot;&gt;post.categories&lt;/code&gt;) with the one collected earlier from all articles of a collection.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;% for &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;eachCat&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allCats&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%}
  {% for post in thisCollection %}&lt;/span&gt;
    
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;% if &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;categories&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contains&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eachCat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%}

      {% assign thisCat = eachCat.name | append: '|' %}&lt;/span&gt;

      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;% if &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;category_array&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contains&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thisCat&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%}
        &amp;lt;!-- Apply your code here to display the category list --&amp;gt;
      {% endif %}&lt;/span&gt;

      &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;% assign &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;category_array&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;category_array&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;remove: &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;thisCat&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%}
    {% endif %}&lt;/span&gt;

  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;% endfor &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;% endfor &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;final-implementation-for-this-website&quot;&gt;&lt;a href=&quot;#overview&quot;&gt;Final implementation for this website&lt;/a&gt;.&lt;/h2&gt;

&lt;h1 id=&quot;troubleshooting-extra&quot;&gt;Troubleshooting (Extra)&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;Custom Plugin Jekyll Hook&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another approach is writing your own plugin with the Jekyll.Hook method inspired from this &lt;a href=&quot;https://stackoverflow.com/questions/49938010/jekyll-custom-collection-hook&quot;&gt;StackOverflow Discussion&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;</content><author><name>Tin Nguyen</name></author><category term="Jekyll" /><category term="Taxonomy" /><summary type="html">A work-around that provide Category and Tag iterator for custom Collections in Jekyll static blog</summary></entry><entry><title type="html">How to setup and remotely access to VM instances on Cloud</title><link href="/tutorial/remote-access-virtual-machine" rel="alternate" type="text/html" title="How to setup and remotely access to VM instances on Cloud" /><published>2019-03-05T00:00:00+07:00</published><updated>2019-03-05T00:00:00+07:00</updated><id>/tutorial/Remote%20access%20virtual%20machine</id><content type="html" xml:base="/tutorial/remote-access-virtual-machine">&lt;h1 id=&quot;overview&quot;&gt;Overview&lt;/h1&gt;
&lt;p&gt;Google Compute Engine is an &lt;em&gt;Infrastructure as a Service&lt;/em&gt; (IaaS) component of the &lt;em&gt;Google Cloud Platform &lt;/em&gt;(GCP) and aiming to &lt;strong&gt;provide specific hardware&lt;/strong&gt; and &lt;strong&gt;utilize the cloud environment&lt;/strong&gt; for development as well as production.&lt;/p&gt;

&lt;p&gt;With Compute Engine, an instance could be generated with a couple of clicks with &lt;em&gt;“a custom Machine Types optimized for your specific needs”&lt;/em&gt;.  This is a great tool alongside with Docker, Kubernetes, etc. and is a game changer in the software industry and definitely a must-have tool. Now, let’s create a Virtual Machine !!&lt;/p&gt;

&lt;h1 id=&quot;prerequisite&quot;&gt;Prerequisite&lt;/h1&gt;
&lt;p&gt;Follow the official documentations to setup your &lt;a href=&quot;https://support.google.com/accounts/answer/27441?hl=en&quot;&gt;Google account&lt;/a&gt; and create a &lt;a href=&quot;https://cloud.google.com/resource-manager/docs/creating-managing-projects&quot;&gt;Google Cloud Platform Project&lt;/a&gt; with &lt;a href=&quot;https://cloud.google.com/billing/docs/how-to/manage-billing-account&quot;&gt;Billing Enabled&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Google Free Tier&lt;/em&gt; introduces a &lt;strong&gt;12 months, $300 trial&lt;/strong&gt; &lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; for new user to learn the basics with several &lt;a href=&quot;https://cloud.google.com/free/docs/gcp-free-tier&quot;&gt;limitations&lt;/a&gt; which will not be an issue for our setup.&lt;/p&gt;

&lt;p&gt;Well ! To be &lt;em&gt;perfectly candid&lt;/em&gt;, it does &lt;strong&gt;depend&lt;/strong&gt; on how much resources you want for your computer, so make sure to verify it.&lt;/p&gt;

&lt;p&gt;For part 2 of this tutorial: “&lt;strong&gt;Gain access to your VM instance&lt;/strong&gt;”, make sure your computer have a version of Python installed, preferably Python 2.7, for the best compatibility with the Software Development Kit from GCP.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;If you have already created your own VM instance, well done ! Skip to the second part of the tutorial for instruction on how to gain access to the instance.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;configure-vm-step-by-step&quot;&gt;Configure VM step-by-step&lt;/h1&gt;
&lt;p&gt;There will be two main steps:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Create and enable a VM on GCP Server&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Install development tools for access using laptop’s terminal or simply access via web client&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;1-create-vm-instance-image-option&quot;&gt;1. Create VM Instance: Image Option&lt;/h2&gt;
&lt;p&gt;First, access the &lt;a href=&quot;https://console.cloud.google.com/&quot;&gt;Cloud Console&lt;/a&gt; of your GCP Project and proceed to the Navigation menu (top-left corner) to tab &lt;em&gt;Compute - Compute Engine&lt;/em&gt;. There will be a button to create the instance at the top bar.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-03-05/step1.png&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Four steps to navigate VM Instance Manager section. Hold to enlarge.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now, it is advised that you left the settings as default in case you do not know what it does. The main settings for your instance are 
&lt;span style=&quot;color:green&quot;&gt; &lt;b&gt; Name, Region, Specifications. &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;*&lt;strong&gt;Hint:&lt;/strong&gt; You can monitor how much is the 
&lt;span style=&quot;color:orange&quot;&gt; Operation Cost &lt;/span&gt;, both estimated in monthly and hourly*&lt;/p&gt;

&lt;p&gt;Also, once you got familiar with the process, do explore the 
&lt;span style=&quot;color:red&quot;&gt;&lt;b&gt; Instance Template &lt;/b&gt;&lt;/span&gt; 
section for a more robust process of generating virtual machines from pre-defined sets of template.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-03-05/step2.png&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Boot Disk allows you to choose a variety of Operating System from Windows to Linux and even specific application image of SQL server built upon.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Once hit create, half of our tutorial is done. The next part is to gain access into your VM instance.&lt;/p&gt;

&lt;h2 id=&quot;2-access-vm-instance-ssh&quot;&gt;2. Access VM instance: SSH&lt;/h2&gt;

&lt;h3 id=&quot;the-easy-way-web-client&quot;&gt;The Easy Way: Web Client&lt;/h3&gt;
&lt;p&gt;By now you have got the instance up and running, as in the same tab &lt;em&gt;Compute Engine - VM instances&lt;/em&gt;. In column &lt;strong&gt;Connect&lt;/strong&gt;, simply expand and chose the appropriate option to initiate a session with your instance.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-03-05/step3.png&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Enable Secure Shell connection using a browser window which result in a direct access to the command line of your instance.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you are looking for a way to gain access using your laptop terminal, keep scrolling to next part. Otherwise, that is the whole point of this tutorial, &lt;strong&gt;congratulation&lt;/strong&gt; !&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Hint:&lt;/strong&gt; You might want to have a quick look into the “&lt;/em&gt;View gcloud command&lt;em&gt;” tab&lt;/em&gt; for our next approach.&lt;/p&gt;

&lt;h3 id=&quot;the-not-so-easy-way-cli&quot;&gt;The Not-So-Easy Way: CLI&lt;/h3&gt;
&lt;p&gt;For those of you want a CLI-based developing environment, the official SDK powered by Python from GCP is definitely a fine choice. Refer to the Prerequisite section at the beginning for Python installation requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;em&gt; The following instruction is specifically for macOS, however, majority of other Operating Systems have either similar installation process or conveniently built directly from a package manager. Refer to the official documentation for your OS specific &lt;a href=&quot;https://cloud.google.com/sdk/docs/quickstarts&quot;&gt;Installation Guide&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;From that very page, download the &lt;a href=&quot;https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-241.0.0-darwin-x86_64.tar.gz&quot;&gt;package&lt;/a&gt; for macOS 64-bit (x86_64). Navigate to the downloaded location and extract the package. Ultimately, you can do this in terminal using the built-in &lt;code class=&quot;highlighter-rouge&quot;&gt;tar&lt;/code&gt; command. Then execute the install Shell script.&lt;/p&gt;

&lt;div class=&quot;language-slim highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nt&quot;&gt;tar&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-xvf&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;google-cloud-sdk-241&lt;span class=&quot;nc&quot;&gt;.0.0-darwin-x86_64.tar.gz&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;google&lt;/span&gt;-cloud-sdk/install&lt;span class=&quot;nc&quot;&gt;.sh&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;Side note:&lt;/em&gt; The option flags stand for e&lt;strong&gt;X&lt;/strong&gt;tract, &lt;strong&gt;V&lt;/strong&gt;erbose (optional), &lt;strong&gt;F&lt;/strong&gt;ilename&lt;/p&gt;

&lt;p&gt;After install successfully, execute the initialization command &lt;code class=&quot;highlighter-rouge&quot;&gt;gcloud init&lt;/code&gt; and follow the instruction to set up account and verify the connection credential keys.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-03-05/step4.png&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Re-initialize previous configuration, when you first initialize it will be different but will essentially defining these parameters&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You are almost there !!! Run the previous “View gcloud command” to establish SSH connection to the VM instance and you are all set. FYI, the command has the format of&lt;/p&gt;

&lt;div class=&quot;language-slim highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nt&quot;&gt;gcloud&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;compute&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;--project&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&quot;YOUR-PROJECT&quot;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;ssh&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;--zone&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&quot;YOUR-ZONE&quot;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&quot;YOUR-INSTANCE-NAME&quot;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-03-05/step5.png&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Successfully established SSH connection to my Debian VM instance. Now it’s your turn !!.&lt;/em&gt;&lt;/p&gt;

&lt;h1 id=&quot;troubleshooting-extra&quot;&gt;Troubleshooting (Extra)&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;“Command Not Found” for missing Shell Path&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-slim highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nt&quot;&gt;export&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;/usr/lib/google-cloud-sdk/bin:$PATH&quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is due to the current Shell not knowing the location of &lt;code class=&quot;highlighter-rouge&quot;&gt;gcloud&lt;/code&gt; and requires a re-open of Shell, i.e. Terminal.&lt;/p&gt;

&lt;p&gt;Relatively, looking into &lt;code class=&quot;highlighter-rouge&quot;&gt;.bashrc/.zshrc&lt;/code&gt;  for automatic loading shell command for &lt;code class=&quot;highlighter-rouge&quot;&gt;gcloud&lt;/code&gt; if the issue was not completely resolved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lost/Forgot Credential keys&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-slim highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nt&quot;&gt;rm&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-rf&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;/Users/YOUR-USER-NAME/&lt;span class=&quot;nc&quot;&gt;.config&lt;/span&gt;/gcloud/*&lt;span class=&quot;nc&quot;&gt;.db&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This attempts to delete the stored access_token and credentials local database. Run &lt;code class=&quot;highlighter-rouge&quot;&gt;gcloud init&lt;/code&gt; to re-initialize and set up for new credential keys.&lt;/p&gt;

&lt;hr /&gt;

&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;As of the written time &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</content><author><name>Tin Nguyen</name></author><category term="Compute Engine" /><category term="Virtual Network Computing" /><summary type="html">Quick setup guide for Virtual Machine with hardware resources from GCP Compute Engine and eliminates the needs for specialized hardware</summary></entry><entry><title type="html">Embedded Systems and Communication Protocols</title><link href="/tutorial/embedded-systems-and-communication" rel="alternate" type="text/html" title="Embedded Systems and Communication Protocols" /><published>2019-02-26T00:00:00+07:00</published><updated>2019-02-26T00:00:00+07:00</updated><id>/tutorial/Embedded%20Systems%20and%20Communication</id><content type="html" xml:base="/tutorial/embedded-systems-and-communication">&lt;h1 id=&quot;overview&quot;&gt;Overview&lt;/h1&gt;
&lt;p&gt;Embedded system is a system that has software embedded into the hardware and is dedicated  to a particular part of a computer application regarding one or many specific features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:  &lt;/strong&gt;Embedded systems are commonly referred as &lt;em&gt;microprocessor-based systems&lt;/em&gt; (MPU) or &lt;em&gt;microcontroller-based systems&lt;/em&gt; (MCU). More on this later.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-02-26/embedded_sf_hw.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Understanding connection between Hardware and Software Interfaces. Source: RMIT VNM– EEET2490 (2017)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So, what is with the &lt;a href=&quot;https://www.embedded.com/electronics-blogs/break-points/4441588/The-shape-of-the-MCU-market&quot;&gt;interests in embedded systems&lt;/a&gt;?&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;99% of newly manufactured microprocessors&lt;/strong&gt; were designed for Embedded Systems, whilst only 1% left for the rest of all desktop processors out in the market.&lt;/p&gt;

  &lt;p&gt;Over &lt;strong&gt;31 billion MCUs was sold&lt;/strong&gt; in 2015 and forecast to grow to almost 50 billion in 2019.&lt;/p&gt;

  &lt;p&gt;&lt;strong&gt;$10.46 billion&lt;/strong&gt;  in Embedded Software Market size valued in 2015 and is anticipated to grow at over 7% CAGR from 2016 to 2023.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;system-architectures&quot;&gt;System Architectures&lt;/h1&gt;
&lt;p&gt;Before discussing different types of system, it is important to understand that a system essentially consists of &lt;code class=&quot;highlighter-rouge&quot;&gt;data&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;instruction&lt;/code&gt; units which can loosely defined as human &lt;strong&gt;memory&lt;/strong&gt; and &lt;strong&gt;brain&lt;/strong&gt; respectively. From there, the idea is to access data, i.e. &lt;em&gt;knowledge&lt;/em&gt;, to analyze and make instruction.&lt;/p&gt;

&lt;p&gt;As previously mentioned, embedded systems are classified as &lt;em&gt;MPU&lt;/em&gt; and &lt;em&gt;MCU&lt;/em&gt; with primary differences which are important in design including &lt;em&gt;application perspective&lt;/em&gt;, &lt;em&gt;connectivity standpoints&lt;/em&gt;, &lt;em&gt;power consumption&lt;/em&gt; and whether it is &lt;em&gt;consumer&lt;/em&gt; electronic or &lt;em&gt;industrial&lt;/em&gt; automation. More on that, &lt;a href=&quot;http://ww1.microchip.com/downloads/en/DeviceDoc/MCU_vs_MPU_Article.pdf&quot;&gt;detailed analysis&lt;/a&gt; by Product Managers from Microchip - a microcontroller manufacturer.&lt;/p&gt;

&lt;p&gt;Beside that, their functionality are tabulated &lt;a href=&quot;https://electronicsforu.com/resources/difference-between-microprocessor-and-microcontroller&quot;&gt;as below&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-02-26/system_architecture_uC.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Microprocessor and Microcontroller specification and comparison. Source: ElectronicForum&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That being said, depends on the specific architecture, the &lt;strong&gt;medium&lt;/strong&gt; for such transmission can serve different purposes (data/code) as well as interface with the &lt;em&gt;CPU&lt;/em&gt;, &lt;em&gt;memory&lt;/em&gt; and &lt;em&gt;I/O&lt;/em&gt; units.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-02-26/system_architecture_medium.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Hardware components and transmission interfaces. Source: RMIT VNM– EEET2490 (2017)&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;harvard-and-von-neumann&quot;&gt;Harvard and Von Neumann&lt;/h2&gt;
&lt;p&gt;The system architectures are commonly categorized essentially based on the design of their transmission interface. That is, a Harvard architecture with &lt;em&gt;separate busses&lt;/em&gt; for data and instruction allowing &lt;strong&gt;simultaneous&lt;/strong&gt; transfers on both busses.  On the other hand, a Von Neumann with a &lt;em&gt;single bus&lt;/em&gt; used for both data transfers and instruction fetches hence must be &lt;strong&gt;scheduled&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-02-26/system_architecture_types.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Design Concept, Memory Allocation, Computing Speed and Purpose comparison between architectures.&lt;/em&gt;&lt;/p&gt;

&lt;h1 id=&quot;communication-protocol&quot;&gt;Communication Protocol&lt;/h1&gt;
&lt;p&gt;The aforementioned &lt;strong&gt;medium&lt;/strong&gt; typically a pre-defined sets of signal (voltage) leveling which referred as &lt;em&gt;protocol&lt;/em&gt; and is a way for electronic components to exchange information hence the &lt;em&gt;communication&lt;/em&gt; part.&lt;/p&gt;

&lt;p&gt;There are two typical types of Electronic Communication Protocols, classified as:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;em&gt;Inter System Protocol&lt;/em&gt;: Between (External) &lt;strong&gt;Interconnected&lt;/strong&gt; Different Devices. E.g: USB, RS232, UART/USART.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;em&gt;Intra System Protocol&lt;/em&gt;: Between (Internal) &lt;strong&gt;Intraconnected&lt;/strong&gt; Entities, Submodules. E.g: SPI, I2C, CAN.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; There is another classification (and will be discussed in another article): &lt;strong&gt;Serial&lt;/strong&gt; and &lt;strong&gt;Parallel&lt;/strong&gt; which can be inferred from their name, are transmitting the data &lt;em&gt;sequentially&lt;/em&gt; or &lt;em&gt;simultaneously&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Some of the protocols are commonly implemented in industrial automation include USB, RS485, CAN. Although, three fundamental serial communication protocols will be examined for the purpose of an introduction.&lt;/p&gt;

&lt;h2 id=&quot;uart&quot;&gt;UART&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-02-26/comm_protocol_uart.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Universal Asynchronous Receiver Transmitter (UART) Hardware Setup and Interface.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It is a &lt;strong&gt;2-wire&lt;/strong&gt;, &lt;strong&gt;full-duplex&lt;/strong&gt;,  &lt;strong&gt;asynchronous&lt;/strong&gt; and &lt;strong&gt;one-to-one&lt;/strong&gt; serial protocol. Meaning it requires &lt;em&gt;only&lt;/em&gt; 2 wires:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Rx: Receiver&lt;/li&gt;
  &lt;li&gt;Tx: Transmitter&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;to receive &lt;strong&gt;AND&lt;/strong&gt; transmit at the same time (&lt;em&gt;Duplex&lt;/em&gt;) while using their own CPU clocks, hence &lt;em&gt;asynchronous&lt;/em&gt; and is typically used in scenario with &lt;em&gt;two devices&lt;/em&gt; communicate to each other.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Commonly the &lt;em&gt;2-wire&lt;/em&gt; could be replaced with any general purpose input/output (GPIO) pin, a process supported by software library &lt;em&gt;emulating&lt;/em&gt; the similar process at the hardware level, i.e. voltage. &lt;strong&gt;Hint&lt;/strong&gt;: &lt;em&gt;&lt;a href=&quot;https://www.arduino.cc/en/Reference/SoftwareSerial&quot;&gt;Software Serial&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id=&quot;spi&quot;&gt;SPI&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-02-26/comm_protocol_spi.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Serial Peripheral Interface (SPI) Hardware Setup and Interface.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It is a &lt;strong&gt;4-wire&lt;/strong&gt;, &lt;strong&gt;full-duplex&lt;/strong&gt;,  &lt;strong&gt;synchronous&lt;/strong&gt; and &lt;strong&gt;one-to-(at least one)&lt;/strong&gt; serial protocol and follow the &lt;strong&gt;master-slave&lt;/strong&gt; interface scheme. Meaning it requires &lt;em&gt;at least&lt;/em&gt; 4 wires:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;SS: Slave Select (aka. CS: Chip Select)&lt;/li&gt;
  &lt;li&gt;SCLK: Serial Clock (aka. SCL)&lt;/li&gt;
  &lt;li&gt;MOSI: Master Output, Slave Input&lt;/li&gt;
  &lt;li&gt;MISO: Master Input, Slave Output&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;to receive &lt;strong&gt;AND&lt;/strong&gt; transmit at the same time similar to UART with a &lt;strong&gt;designated CPU clock&lt;/strong&gt; and a &lt;strong&gt;specific selected slave&lt;/strong&gt; all of which initiated by the &lt;em&gt;one-and-only &lt;/em&gt;master, hence synchronous and is usually implemented for scenario with &lt;em&gt;only one master&lt;/em&gt; broadcast data, not necessarily identical, to different destinations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The number of SPI-slaves is technically unlimited, however, realistically it is depend on the number of &lt;em&gt;Slave Select&lt;/em&gt; (SS) pins, i.e. usually from 2 to 4 pins, and &lt;em&gt;shift-register&lt;/em&gt; scheme for sequential interconnected slaves. More on that, &lt;a href=&quot;https://www.maximintegrated.com/en/app-notes/index.mvp/id/3947&quot;&gt;SPI Direct and Daisy linked chains explanation&lt;/a&gt; from Maxim Integrated (Advanced).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Side note:&lt;/strong&gt; SPI is a trademark of Motorola and later became the &lt;em&gt;standard&lt;/em&gt; but &lt;strong&gt;not to be confused with&lt;/strong&gt; Texas Instrument interpretation of SPI.&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;Definitely not when working with DSP application (E.g. TMS320C/OMAP-L series), it’s a painful memory.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;i2c&quot;&gt;I2C&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-02-26/comm_protocol_i2c.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Inter-Integrated Circuit (&lt;script type=&quot;math/tex&quot;&gt;I^2 C&lt;/script&gt;, I-squared-C ) Hardware Setup and Interface.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It is a &lt;strong&gt;2-wire&lt;/strong&gt;, &lt;strong&gt;half-duplex&lt;/strong&gt;,  &lt;strong&gt;synchronous&lt;/strong&gt; and &lt;strong&gt;(at least one)-to-(at least one)&lt;/strong&gt; serial protocol and also follow the &lt;strong&gt;master-slave&lt;/strong&gt; interface scheme similar to SPI. Meaning it requires &lt;em&gt;only&lt;/em&gt; 2 wires:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;SDA: Serial Data&lt;/li&gt;
  &lt;li&gt;SCL: Serial Clock&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;to receive &lt;strong&gt;OR&lt;/strong&gt; transmit sequentially, i.e. scheduled (half-duplex) different than UART or SPI. In spite of that, the beauty of I2C comes from both the world of UART and SPI with &lt;em&gt;only two wire&lt;/em&gt;, &lt;em&gt;multiple slaves&lt;/em&gt;, &lt;em&gt;synchronous&lt;/em&gt; and especially &lt;strong&gt;multiple masters&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: On a single bus (1 byte - 8 bits), I2C theoretically supports &lt;strong&gt;&lt;script type=&quot;math/tex&quot;&gt;2^7 = 127&lt;/script&gt;&lt;/strong&gt; different addresses (slaves) which is a huge advantage over SPI with the &lt;em&gt;Slave Select limitation&lt;/em&gt; dilemma. Realistically, the address of each slave is usually pre-defined under hardware level and &lt;em&gt;conflict is inevitable&lt;/em&gt;, i.e. much less than 127 addresses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Side note:&lt;/strong&gt; SPI is &lt;em&gt;proprietary product&lt;/em&gt; of Phillips and as such &lt;a href=&quot;http://ww1.microchip.com/downloads/en/DeviceDoc/90003181A.pdf&quot;&gt;Two-Wire Interface&lt;/a&gt; (TWI) is another variation of it which introduced by Atmel as more of an &lt;strong&gt;open standard&lt;/strong&gt; and is &lt;em&gt;almost identical&lt;/em&gt; in term of interface and protocol.&lt;/p&gt;

&lt;h2 id=&quot;advantages--trade-offs&quot;&gt;Advantages / Trade-offs&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-02-26/advantage_tradeoff.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Summary and comparison between Serial protocols. More on &lt;a href=&quot;http://www.rfwireless-world.com/Terminology/UART-vs-SPI-vs-I2C.html&quot;&gt;details&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;hr /&gt;</content><author><name>Tin Nguyen</name></author><category term="Serial" /><category term="UART" /><category term="SPI" /><category term="I2C" /><category term="Harvard" /><category term="Von Neumann" /><summary type="html">An introduction to computer architecture and embedded system serial communication protocols with different classifications such as intra/inter system, serial/parallel, data bus, pipeline</summary></entry><entry><title type="html">How to setup and burn the Bootloader to any Arduino board</title><link href="/tutorial/burn-bootloader-to-arduino-board" rel="alternate" type="text/html" title="How to setup and burn the Bootloader to any Arduino board" /><published>2019-02-02T00:00:00+07:00</published><updated>2019-02-02T00:00:00+07:00</updated><id>/tutorial/Burn%20Bootloader%20to%20Arduino%20board</id><content type="html" xml:base="/tutorial/burn-bootloader-to-arduino-board">&lt;h1 id=&quot;overview&quot;&gt;Overview&lt;/h1&gt;
&lt;p&gt;The idea of using Arduino and how it &lt;strong&gt;accelerates&lt;/strong&gt; the process of &lt;em&gt;programming&lt;/em&gt; and &lt;em&gt;uploading&lt;/em&gt; code to the board was explained in the &lt;a href=&quot;https://tin.ng/2019/01/18/Define-Compiling-workflow-for-Arduino-sketch-with-Makefile/&quot;&gt;Makefile tutorial&lt;/a&gt;, &lt;em&gt;check it out&lt;/em&gt; if you have a &lt;em&gt;vague&lt;/em&gt; idea of what is the ultimate goal here.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;concept&lt;/strong&gt; of Bootloader is similar to the BIOS of a computer if you have ever heard of. The &lt;em&gt;Basic Input/Output System&lt;/em&gt; (BIOS) on your computer &lt;em&gt;typically&lt;/em&gt; waits for a user input at startup (the &lt;strong&gt;ubiquitous&lt;/strong&gt; “&lt;em&gt;Press F1 to continue, Del to enter SETUP&lt;/em&gt;” screen) and  provide options to modify Boot settings, i.e. CPU clock, peripherals, etc. and then proceed to load the Operating System (OS), e.g. &lt;em&gt;Floating flag&lt;/em&gt; of Windows or &lt;em&gt;an apple&lt;/em&gt; in macOS.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-02-02/overview_bootloading.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;The bootloader program is written in the bootloader section, and the application program is written in the application section. Source: &lt;a href=&quot;https://www.electronicwings.com/arduino/basics-to-developing-bootloader-for-arduino&quot;&gt;ElectronicWings&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here, in the &lt;strong&gt;embedded system&lt;/strong&gt;, Bootloader is an initial piece of code (usually &lt;a href=&quot;https://www.arduino.cc/en/Tutorial/ArduinoISP&quot;&gt;512 bytes&lt;/a&gt;) which runs whenever a microcontroller is powered up or resets. It also looks for external inputs, i.e. &lt;em&gt;uploading new program&lt;/em&gt;. Similarly, in case of no input, it executes the program that was uploaded previously.&lt;/p&gt;

&lt;h1 id=&quot;prerequisite&quot;&gt;Prerequisite&lt;/h1&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Arduino IDE: &lt;strong&gt;Only the IDE is enough&lt;/strong&gt;, if you want to know other toolchains, look into previous &lt;a href=&quot;https://tin.ng/2019/01/18/Define-Compiling-workflow-for-Arduino-sketch-with-Makefile/#toolchain-installation&quot;&gt;instruction&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Two (2) Arduino boards: One as the &lt;strong&gt;target&lt;/strong&gt; board and one as the &lt;strong&gt;programmer&lt;/strong&gt; board&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;USB-AVR-ISP (Optional): Advance, Bootload without the need for another programmer board&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;understanding-bootloader&quot;&gt;Understanding Bootloader&lt;/h1&gt;

&lt;p&gt;Arduino board implements &lt;strong&gt;AVR microcontrollers&lt;/strong&gt; which has &lt;em&gt;program memory&lt;/em&gt; and &lt;em&gt;bootload memory&lt;/em&gt; sections. They are used to &lt;strong&gt;simplify&lt;/strong&gt; the process of &lt;em&gt;uploading&lt;/em&gt; programs to the microcontrollers as well as &lt;em&gt;initializing&lt;/em&gt; IO devices before they begin the main application program, e.g. Initialize Analog-to-Digital-Conversion (ADC) pins.&lt;/p&gt;

&lt;p&gt;Essentially, the bootloader is a &lt;em&gt;.hex&lt;/em&gt; code and it initially &lt;strong&gt;watching&lt;/strong&gt; &lt;em&gt;dedicated pins&lt;/em&gt; for a new program to be uploaded, then using simple &lt;em&gt;serial communication&lt;/em&gt; (in case of Arduino Uno, UART. &lt;a href=&quot;https://tin.ng/2019/02/26/embedded-systems-and-communication-protocols/#uart&quot;&gt;More about the protocol&lt;/a&gt;) to &lt;strong&gt;download&lt;/strong&gt; the program and &lt;strong&gt;write&lt;/strong&gt; it into the application flash memory.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-02-02/bootload_memory.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Arduino Uno (ATmega328p) Memory Map. Source: &lt;a href=&quot;https://www.arduino.cc/en/Tutorial/ArduinoISP&quot;&gt;Arduino.cc&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Luckily, Arduino provides you a &lt;em&gt;built-in&lt;/em&gt; written Bootloader program within the IDE serving for this exact purpose at “&lt;strong&gt;File&lt;/strong&gt; &lt;script type=&quot;math/tex&quot;&gt;\rightarrow&lt;/script&gt; &lt;strong&gt;Examples&lt;/strong&gt; &lt;script type=&quot;math/tex&quot;&gt;\rightarrow&lt;/script&gt; &lt;strong&gt;ArduinoISP&lt;/strong&gt;”.&lt;/p&gt;

&lt;h1 id=&quot;bootloading-any-board&quot;&gt;Bootloading any board&lt;/h1&gt;
&lt;p&gt;Now with the Bootloader program ready, the rest is to &lt;em&gt;physically setup&lt;/em&gt; a way for the &lt;strong&gt;programmer&lt;/strong&gt; board and &lt;strong&gt;target&lt;/strong&gt; board to communicate.&lt;/p&gt;

&lt;h2 id=&quot;circuit-examination&quot;&gt;Circuit Examination&lt;/h2&gt;

&lt;p&gt;The setup utilizes Serial Peripheral Interface, a &lt;em&gt;synchronous four-wire&lt;/em&gt; communication protocol with &lt;strong&gt;master-slave&lt;/strong&gt; scheme, i.e. the programmer-target board. &lt;a href=&quot;https://tin.ng/2019/02/26/embedded-systems-and-communication-protocols/#spi&quot;&gt;More about SPI protocol here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Beside power pins, peripheral pins such as ADC, GPIO on any Arduino board, another set of pins called In Circuit Serial Programming (ICSP) header. These will give direct (serial) access to the main microcontroller on the board and will be the entry point.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-02-02/uno_icsp.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;From top left: *Master In Slave Out&lt;/em&gt;, &lt;em&gt;+VCC Positive Supply&lt;/em&gt;, &lt;em&gt;Serial Clock&lt;/em&gt;, &lt;em&gt;Master Out Slave In&lt;/em&gt;, &lt;em&gt;Reset&lt;/em&gt; and *Ground**&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Side note&lt;/strong&gt;: Read more about the &lt;a href=&quot;https://tin.ng/2019/01/18/Define-Compiling-workflow-for-Arduino-sketch-with-Makefile/#hardware-level&quot;&gt;functionality of ATMega16u2&lt;/a&gt; on Arduino Uno.&lt;/p&gt;

&lt;p&gt;Not only that, for some boards such as the ubiquitous &lt;em&gt;Arduino Uno&lt;/em&gt; or &lt;em&gt;Mega&lt;/em&gt;, they contains &lt;strong&gt;another set&lt;/strong&gt; of &lt;em&gt;SPI&lt;/em&gt; pins beside the &lt;em&gt;ICSP&lt;/em&gt; header and are&lt;strong&gt; completely functional &lt;/strong&gt;which can also be utilized for Bootloading.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-02-02/pin_map.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;It is important to notice that some only contain either and not both sets of pin, wire your board accordingly to either Digital pins scheme or ICSP header.&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;hardware-setup&quot;&gt;Hardware Setup&lt;/h2&gt;

&lt;p&gt;No matter how the &lt;em&gt;Digital pins&lt;/em&gt; or &lt;em&gt;ICSP headers&lt;/em&gt; were connected, the idea &lt;em&gt;remains the same&lt;/em&gt;. That is, connect pins in &lt;strong&gt;SPI&lt;/strong&gt; scheme from the &lt;em&gt;Programmer&lt;/em&gt; board to that of the &lt;em&gt;Target&lt;/em&gt; board in order &lt;strong&gt;to upload Bootloader on the microcontroller of the Programmer board to the one on the Target board&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is also important to remember that, the &lt;strong&gt;power&lt;/strong&gt; comes from the &lt;em&gt;Programmer&lt;/em&gt; board which can originated from your &lt;em&gt;USB port&lt;/em&gt; or an &lt;em&gt;external supply&lt;/em&gt; and then will be shared with the &lt;em&gt;Target&lt;/em&gt; board.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-02-02/procedure_bootload.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Bootloader procedure pin map using Digital Pin (applicable for Uno, Mega) Refer to the Pin Map in previous section. Schematic: Fritzing on macOS.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: In case of using a &lt;strong&gt;Programmer&lt;/strong&gt; board of &lt;em&gt;Arduino Mega&lt;/em&gt;, a 10 to &lt;script type=&quot;math/tex&quot;&gt;100 \mu F&lt;/script&gt; &lt;strong&gt;electrolytic&lt;/strong&gt; capacitor must be placed (&lt;em&gt;positive, long leg&lt;/em&gt;) between the Reset and (&lt;em&gt;negative, short leg&lt;/em&gt;) Ground pins.&lt;/p&gt;

&lt;details&gt;
&lt;summary&gt;
	&lt;code&gt;&lt;i&gt;SELF CHECK&lt;/i&gt;&lt;/code&gt;
&lt;/summary&gt;
&lt;p&gt;
&lt;h3&gt;Arduino Mega as the &lt;b&gt;Programmer&lt;/b&gt; board&lt;/h3&gt;
&lt;img src=&quot;/assets/blogs/2019-02-02/mega_icsp.jpg&quot; /&gt;
This is to diminish the &lt;i&gt;unwanted reset&lt;/i&gt; signal sent every time the Programmer attempts to establish connection with the Target in Bootload mode.
&lt;br /&gt;
&lt;h3&gt;(Extra) ICSP Header Setup&lt;/h3&gt;
&lt;img src=&quot;/assets/blogs/2019-02-02/setup_icsp.jpg&quot; /&gt;
&lt;/p&gt;
&lt;/details&gt;

&lt;h1 id=&quot;bootloading-procedure&quot;&gt;Bootloading Procedure&lt;/h1&gt;

&lt;p&gt;Now that everything is clear, the procedure first took place with &lt;strong&gt;ONLY&lt;/strong&gt; the &lt;em&gt;Programmer&lt;/em&gt; &lt;strong&gt;WITHOUT&lt;/strong&gt; &lt;em&gt;any connection&lt;/em&gt; to the &lt;em&gt;Target&lt;/em&gt; board.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;: From Arduino IDE, &lt;strong&gt;Open&lt;/strong&gt; the previously mentioned &lt;em&gt;Bootloader firmware&lt;/em&gt; in the Arduino IDE in “&lt;strong&gt;File&lt;/strong&gt; &lt;script type=&quot;math/tex&quot;&gt;\rightarrow&lt;/script&gt; &lt;strong&gt;Examples&lt;/strong&gt; &lt;script type=&quot;math/tex&quot;&gt;\rightarrow&lt;/script&gt; &lt;strong&gt;ArduinoISP&lt;/strong&gt;”.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;: &lt;strong&gt;Select&lt;/strong&gt; the model of &lt;em&gt;Programmer&lt;/em&gt; board in “&lt;strong&gt;Tool&lt;/strong&gt; &lt;script type=&quot;math/tex&quot;&gt;\rightarrow&lt;/script&gt; &lt;strong&gt;Board&lt;/strong&gt;” (E.g. Arduino Mega) menu and the Serial Port in “&lt;strong&gt;Tool&lt;/strong&gt; &lt;script type=&quot;math/tex&quot;&gt;\rightarrow&lt;/script&gt; &lt;strong&gt;Port&lt;/strong&gt;” (E.g. &lt;em&gt;/dev/cu.usbserial1410&lt;/em&gt;) menu.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Side note&lt;/strong&gt;: Connected device port on macOS can &lt;strong&gt;also&lt;/strong&gt; be identified using &lt;strong&gt;list&lt;/strong&gt; command directly in Terminal, either &lt;code class=&quot;highlighter-rouge&quot;&gt;ls /dev/cu.*&lt;/code&gt; or less common &lt;code class=&quot;highlighter-rouge&quot;&gt;ls /dev/tty.*&lt;/code&gt; command.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Step 3&lt;/strong&gt;: Select &lt;strong&gt;Upload&lt;/strong&gt; button in the IDE and proceed to load the ArduinoISP sketch to your &lt;em&gt;Programmer&lt;/em&gt; board.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-02-02/procedure_mega.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Successfully upload Bootloader Firmware onto the Programmer’s microcontroller.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now&lt;/strong&gt;, the Bootloader is &lt;em&gt;currently&lt;/em&gt; on the microcontroller of your &lt;em&gt;Programmer&lt;/em&gt; board and is &lt;strong&gt;ready&lt;/strong&gt; to be burned onto the &lt;em&gt;Target&lt;/em&gt; board.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Step 4&lt;/strong&gt;: &lt;strong&gt;Wiring&lt;/strong&gt; the Target Board to the Programmer as in previous Hardware Setup, either ICSP header or SPI Digital Pins.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Side note&lt;/strong&gt;: Also remember the capacitor for Arduino Mega which was explained previously.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Step 5&lt;/strong&gt;: Back to the IDE, &lt;strong&gt;Select&lt;/strong&gt; the model of &lt;em&gt;Target&lt;/em&gt; board in “&lt;strong&gt;Tool&lt;/strong&gt; &lt;script type=&quot;math/tex&quot;&gt;\rightarrow&lt;/script&gt; &lt;strong&gt;Board&lt;/strong&gt;” (E.g. Arduino Uno) menu and the Programming Mode as &lt;strong&gt;Arduino as ISP&lt;/strong&gt; in “&lt;strong&gt;Tool&lt;/strong&gt; &lt;script type=&quot;math/tex&quot;&gt;\rightarrow&lt;/script&gt; &lt;strong&gt;Programmer&lt;/strong&gt;” (&lt;em&gt;Originally AVRISP mkII&lt;/em&gt;).&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Step 6&lt;/strong&gt;: Lastly, &lt;strong&gt;select&lt;/strong&gt; the Burn Bootloader command, i.e. “&lt;strong&gt;Tool&lt;/strong&gt; &lt;script type=&quot;math/tex&quot;&gt;\rightarrow&lt;/script&gt; &lt;strong&gt;Burn Bootloader&lt;/strong&gt;”.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-02-02/procedure_done.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Successfully bootloaded a &lt;strong&gt;Target&lt;/strong&gt; Arduino Uno (ATmega328p) using a &lt;strong&gt;Programmer&lt;/strong&gt; Arduino Mega (ATmega2560).&lt;/em&gt;&lt;/p&gt;

&lt;h1 id=&quot;troubleshooting-extra&quot;&gt;Troubleshooting (Extra)&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;“avrdude: Yikes! Invalid device signature.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is usually due to mismatch in hardware interface as well as software configuration and is an indication of selected wrong &lt;em&gt;Target&lt;/em&gt; board. There are some issues need to be taken into consideration:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Board Selection&lt;/strong&gt;: Re-trace any &lt;a href=&quot;http://tin.ng/2019/02/02/How-to-setup-and-burn-the-Bootloader-to-any-Arduino-board/#bootloading-procedure&quot;&gt;step to select&lt;/a&gt; the correct &lt;em&gt;board&lt;/em&gt; model, &lt;em&gt;microcontroller&lt;/em&gt; variant (some have different architecture and signature)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Schematic Setup&lt;/strong&gt;: Re-trace &lt;a href=&quot;http://tin.ng/2019/02/02/How-to-setup-and-burn-the-Bootloader-to-any-Arduino-board/#hardware-setup&quot;&gt;the setup&lt;/a&gt; for &lt;em&gt;SPI protocol&lt;/em&gt; and/or the ICSP header pin map (if used)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Metallic Contact&lt;/strong&gt;: Avoid any contact with the &lt;em&gt;spikes&lt;/em&gt; on the back of the board. &lt;span class=&quot;spoiler&quot;&gt;&lt;b&gt;Trust me, I learned that the hard way !&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;</content><author><name>Tin Nguyen</name></author><category term="Bootloader" /><category term="AVRisp" /><category term="Arduino IDE" /><category term="AVR" /><category term="GCC" /><summary type="html">Overview The idea of using Arduino and how it accelerates the process of programming and uploading code to the board was explained in the Makefile tutorial, check it out if you have a vague idea of what is the ultimate goal here.</summary></entry><entry><title type="html">Define Compiling workflow for Arduino sketch with Makefile</title><link href="/tutorial/compiling-arduino-with-makefile" rel="alternate" type="text/html" title="Define Compiling workflow for Arduino sketch with Makefile" /><published>2019-01-18T00:00:00+07:00</published><updated>2019-01-18T00:00:00+07:00</updated><id>/tutorial/Compiling%20Arduino%20with%20Makefile</id><content type="html" xml:base="/tutorial/compiling-arduino-with-makefile">&lt;h1 id=&quot;overview&quot;&gt;Overview&lt;/h1&gt;

&lt;p&gt;This method is a wonderful &lt;strong&gt;bridge&lt;/strong&gt; between &lt;em&gt;beginner&lt;/em&gt; and &lt;em&gt;intermediate&lt;/em&gt; in a sense from automated script from Arduino IDE to &lt;strong&gt;define your very own flags&lt;/strong&gt; to feed the compiler. That is, before you just “need to” (or to be &lt;em&gt;perfectly candid&lt;/em&gt; “only-able-to”) hit compile button.&lt;/p&gt;

&lt;p&gt;After this, you will be able to comprehend a concept of Makefile and further working with Makefile in raw &lt;strong&gt;.c&lt;/strong&gt; and &lt;strong&gt;.cpp&lt;/strong&gt; format and even with other compiler, e.g. GNU C++ Compiler (GCC).&lt;/p&gt;

&lt;p&gt;That being said, this approach utilizes &lt;strong&gt;pre-defined routine&lt;/strong&gt; from Arduino IDE itself such as &lt;em&gt;board variant&lt;/em&gt;, &lt;em&gt;microcontroller architecture&lt;/em&gt; to &lt;em&gt;monitor port&lt;/em&gt; on your computer and furthermore.&lt;/p&gt;

&lt;h1 id=&quot;prerequisite&quot;&gt;Prerequisite&lt;/h1&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;An application running Shell (Command Line Interpreter) typically &lt;strong&gt;Terminal&lt;/strong&gt; on macOS.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;A &lt;strong&gt;Package Manager&lt;/strong&gt;, typically &lt;code class=&quot;highlighter-rouge&quot;&gt;homebrew&lt;/code&gt; (macOS) or &lt;code class=&quot;highlighter-rouge&quot;&gt;apt-get&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;yum&lt;/code&gt; on a variety of Linux distros.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;A &lt;strong&gt;C Compiler&lt;/strong&gt;, specifically OSX-GCC Compiler if you are on macOS which will be installed along with the Xcode application.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;A &lt;strong&gt;Python&lt;/strong&gt; interpreter and Python-specific &lt;em&gt;Package Manager&lt;/em&gt;: &lt;strong&gt;pip&lt;/strong&gt; for Python 2.7 or pip3 for Python 3.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Don’t worry if you are missing any of those !! A comprised instruction can be found&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;
	&lt;code&gt;&lt;i&gt;INSTRUCTION HERE&lt;/i&gt;&lt;/code&gt;
&lt;/summary&gt;
&lt;p&gt;
&lt;b&gt;Install homebrew package manager&lt;/b&gt;
Copy and Paste this command into your Terminal to install homebrew.


&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;/usr/bin/ruby &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;curl &lt;span class=&quot;nt&quot;&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/Homebrew/install/master/install&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;


Once installed, update the &lt;b&gt;symlink&lt;/b&gt; of homebrew directory in &lt;i&gt;.bash_profile&lt;/i&gt;
 

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;vim ~/.bash_profile
&lt;span class=&quot;c&quot;&gt;# Place this line into the profile&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/usr/local/bin:/usr/local/sbin:&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;


&lt;code&gt;:wq&lt;/code&gt; to Save &amp;amp; Quit; &lt;b&gt;Trust me you will need it&lt;/b&gt;. Restart Terminal for changes effect.

&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Install OSX-GCC Compiler&lt;/b&gt;
Still in Terminal, verify if you have XCode and its Command Line Tools yet.

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;/usr/bin/xcodebuild &lt;span class=&quot;nt&quot;&gt;-version&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;


If not, then proceed to install the Command Line Tools (necessary) or the entire application (optional)

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;xcode-select &lt;span class=&quot;nt&quot;&gt;--install&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;


Once installed, the compiler can be verified using command

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;whereis gcc
~ /usr/bin/gcc&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;



&lt;br /&gt;&lt;b&gt;Install Python Interpreter&lt;/b&gt;
Some of the toolchains have &lt;b&gt;reported discrepancies&lt;/b&gt; with Python &amp;gt; 3.5 . For the sake of this tutorial, Python 2.7 will be installed instead.

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;brew &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;python@2&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;


 
Similarly, update the &lt;code&gt;python@2&lt;/code&gt; keg directory

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;vim ~/.bash_profile
&lt;span class=&quot;c&quot;&gt;# Place this line into the profile&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/usr/local/opt/python@2/bin:&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;/p&gt;
&lt;/details&gt;

&lt;h1 id=&quot;toolchain-installation&quot;&gt;Toolchain Installation&lt;/h1&gt;
&lt;p&gt;In case you are an &lt;em&gt;intrinsic&lt;/em&gt; newbie, definitely check out the Prerequisite instruction above. Once having all the application and dependencies, the main toolchains are required to setup.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Arduino IDE &amp;amp; AVR-G++ Compiler&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Download the latest version of Arduino IDE from &lt;a href=&quot;https://www.arduino.cc/en/Main/Software&quot;&gt;arduino.cc&lt;/a&gt; which includes the AVR-G++ Compiler. Drag &amp;amp; Drop the &lt;em&gt;Arduino IDE&lt;/em&gt; into &lt;em&gt;Application&lt;/em&gt; folder (&lt;strong&gt;important&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;Once installed, the compiler can be verified by using command&lt;/p&gt;
&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;/Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/avr-g++ &lt;span class=&quot;nt&quot;&gt;--version&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The output should indicates &lt;em&gt;compiler version&lt;/em&gt; and flag &lt;code class=&quot;highlighter-rouge&quot;&gt;-v&lt;/code&gt; can be used to find more about it, e.g. &lt;em&gt;configuration&lt;/em&gt;, &lt;em&gt;target&lt;/em&gt;, &lt;em&gt;thread mode&lt;/em&gt; and etc.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Makefile workflow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(&lt;strong&gt;Recommended&lt;/strong&gt;) Using &lt;code class=&quot;highlighter-rouge&quot;&gt;homebrew&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;apt-get&lt;/code&gt; to install directly with command&lt;/p&gt;
&lt;div class=&quot;language-slim highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nt&quot;&gt;brew&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;update
&lt;span class=&quot;nt&quot;&gt;brew&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;tap&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;sudar/arduino-mk
&lt;span class=&quot;nt&quot;&gt;brew&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;install&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;arduino-mk
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Side note&lt;/strong&gt;: As of the time writing this article, the &lt;code class=&quot;highlighter-rouge&quot;&gt;arduino-mk&lt;/code&gt; package has already been in the default &lt;em&gt;homebrew 2.1.2&lt;/em&gt; inventory and does not need to tap anymore.&lt;/p&gt;

&lt;p&gt;Another way is if you are familiar with GitHub, clone the directory &lt;a href=&quot;https://github.com/sudar/Arduino-Makefile&quot;&gt;sudar/Arduino-Makefile&lt;/a&gt; and extract the .ZIP into &lt;code class=&quot;highlighter-rouge&quot;&gt;/usr/bin/Cellar&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;PySerial tool&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Arduino IDE provides avrdude to work with uploading code to the board and by using Pyserial program, this process can be further automated.&lt;/p&gt;

&lt;p&gt;(&lt;strong&gt;Recommended&lt;/strong&gt;) Install using the &lt;strong&gt;pip&lt;/strong&gt;, Package Manager for Python &lt;em&gt;2.7&lt;/em&gt; package with the command.&lt;/p&gt;

&lt;div class=&quot;language-slim highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nt&quot;&gt;pip&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;install&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;pyserial
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Another way is to install it &lt;em&gt;as a package&lt;/em&gt; with &lt;code class=&quot;highlighter-rouge&quot;&gt;apt-get install python-serial&lt;/code&gt;.&lt;/p&gt;

&lt;h1 id=&quot;understanding-arduino&quot;&gt;Understanding Arduino&lt;/h1&gt;

&lt;p&gt;Now that &lt;em&gt;every dependencies&lt;/em&gt; are satisfied, let’s take a look into how components on Arduino board and &lt;em&gt;controller peripherals&lt;/em&gt; operated as well as &lt;em&gt;compiler directive&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id=&quot;hardware-level&quot;&gt;Hardware Level&lt;/h2&gt;
&lt;p&gt;At Hardware Level, an Arduino Board, e.g. &lt;em&gt;Uno&lt;/em&gt;, &lt;em&gt;Leonardo&lt;/em&gt;, &lt;em&gt;Mega&lt;/em&gt;, etc.; typically contains a &lt;strong&gt;main AVR microcontroller&lt;/strong&gt; (&lt;em&gt;ATmega328p&lt;/em&gt;, &lt;em&gt;ATmega32u4&lt;/em&gt;, &lt;em&gt;ATmega2560&lt;/em&gt; respectively) from &lt;strong&gt;Atmel&lt;/strong&gt; and &lt;em&gt;hence the controller names&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Beside that, a common microcontroller &lt;em&gt;ATmega16u2&lt;/em&gt; is usually in charge of convert between the computer’s &lt;strong&gt;USB port&lt;/strong&gt; and the main controller’s &lt;strong&gt;serial port&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-01-18/hardware_uno.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Arduino Uno and Hardware Interface between computer to the microcontroller.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This bridge is &lt;strong&gt;essential&lt;/strong&gt; for &lt;em&gt;uploading code&lt;/em&gt; from the computer to the main controller’s memory and &lt;em&gt;communicating with it&lt;/em&gt; via serial protocol &lt;a href=&quot;https://tin.ng/2019/02/26/embedded-systems-and-communication-protocols/&quot;&gt;as discussed in the embedded system article&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;software-level&quot;&gt;Software Level&lt;/h2&gt;
&lt;p&gt;At Software Level, Arduino IDE provides a &lt;strong&gt;medium&lt;/strong&gt; between the user and the AVR-G++ compiler. That is, it completes  &lt;em&gt;function pre-define&lt;/em&gt;, &lt;em&gt;header&lt;/em&gt;, &lt;em&gt;library linking&lt;/em&gt; and ultimately export machine-understandable directive, usually in &lt;em&gt;.hex&lt;/em&gt; format.&lt;/p&gt;

&lt;p&gt;The nature of an Arduino sketch is nothing else but C, C++ code and parameter directive as well as other “&lt;em&gt;under the hood&lt;/em&gt;” declaration, for instance look at the way CPU clock speed defined below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hint&lt;/strong&gt;: AVR-C &lt;em&gt;expected&lt;/em&gt; param defined in the script whereas Arduino &lt;em&gt;stored&lt;/em&gt; a default clock speed in a file and automated that for you (unless modified, of course).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-01-18/software_blink.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Typical AVR C script and Arduino sketch depict the same behavior, blinking LEDs every 1 second&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: A &lt;strong&gt;misconception&lt;/strong&gt; should be cleared is that the Arduino &lt;em&gt;programming language&lt;/em&gt; &lt;strong&gt;is essentially&lt;/strong&gt; the C (and C++) code compiled and &lt;strong&gt;not a different language&lt;/strong&gt;.&lt;/p&gt;

&lt;h1 id=&quot;makefile-flags&quot;&gt;Makefile Flags&lt;/h1&gt;

&lt;p&gt;In the Makefile, some usual parameters are defined for the &lt;em&gt;board&lt;/em&gt;, &lt;em&gt;port&lt;/em&gt;, user Library and one important line to include the directive &lt;code class=&quot;highlighter-rouge&quot;&gt;Arduino.mk&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hint&lt;/strong&gt;: The full list of &lt;em&gt;Arduino boards&lt;/em&gt;, &lt;em&gt;AVR microcontroller&lt;/em&gt; can be found inside the &lt;code class=&quot;highlighter-rouge&quot;&gt;Arduino.app&lt;/code&gt; or simply &lt;code class=&quot;highlighter-rouge&quot;&gt;make show_boards&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;make show_submenu&lt;/code&gt; respectively.&lt;/p&gt;

&lt;div class=&quot;language-makefile highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nv&quot;&gt;BOARD_TAG&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; mega
&lt;span class=&quot;nv&quot;&gt;BOARD_SUB&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; atmega2560

&lt;span class=&quot;nv&quot;&gt;ARDUINO_LIBS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; SoftwareSerial

&lt;span class=&quot;nv&quot;&gt;MONITOR_PORT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; /dev/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.usbserial&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;MONITOR_BAUDRATE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 115200

&lt;span class=&quot;k&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt; ../../Arduino.mk&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Typical Makefile script for Arduino Mega board*&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Full list of &lt;code class=&quot;highlighter-rouge&quot;&gt;make&lt;/code&gt; commands can be found in the &lt;strong&gt;arduino-mk-vars.md&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Side note&lt;/strong&gt;: On macOS, the &lt;code class=&quot;highlighter-rouge&quot;&gt;MONITOR_PORT&lt;/code&gt; is either tty/cu and modem/serial depend on the OS version.&lt;/p&gt;

&lt;h1 id=&quot;routine-usage&quot;&gt;Routine Usage&lt;/h1&gt;

&lt;p&gt;The usage is quite straight forward with a few commands and a &lt;code class=&quot;highlighter-rouge&quot;&gt;Makefile&lt;/code&gt; in the &lt;strong&gt;same directory &lt;/strong&gt;as the Arduino sketch &lt;code class=&quot;highlighter-rouge&quot;&gt;.ino&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;These commands are pretty &lt;em&gt;self-explanatory&lt;/em&gt; using a prefix &lt;code class=&quot;highlighter-rouge&quot;&gt;make&lt;/code&gt; with flags:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-01-18/make.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Output of Compile-Only command &lt;code class=&quot;highlighter-rouge&quot;&gt;make&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-01-18/make_upload.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Output of Compile-and-Upload command &lt;code class=&quot;highlighter-rouge&quot;&gt;make upload&lt;/code&gt; using PySerial to trigger reset.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2019-01-18/make_monitor.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Establish serial connection command &lt;code class=&quot;highlighter-rouge&quot;&gt;make monitor&lt;/code&gt; using native app &lt;code class=&quot;highlighter-rouge&quot;&gt;screen&lt;/code&gt; on &lt;strong&gt;macOS 10.14.1&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h1 id=&quot;advance-to-avr-development&quot;&gt;Advance to AVR Development&lt;/h1&gt;

&lt;p&gt;If you are feeling confident enough, explores these new aspects:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Compiling plain AVR C programs&lt;/strong&gt;: Also look up Atmel Studio for an IDE with troubleshooting.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Program using Arduino as ISP&lt;/strong&gt;:  Bootload firmware form one to another board (More on upcoming article).&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Generate assembly and symbol files&lt;/strong&gt;: Understand more of file linking and how compiler works.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;troubleshooting-extra&quot;&gt;Troubleshooting (Extra)&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;“Command Not Found” for missing Shell Path&lt;/strong&gt;
In case of homebrew or Python commands not found, try to refresh it&lt;/p&gt;

&lt;div class=&quot;language-makefile highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/usr/local/bin:/usr/local/sbin:&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;”&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;/.bashprofile&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Or better yet, look into &lt;code class=&quot;highlighter-rouge&quot;&gt;~/.bashrc&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Python 3 and Python 2 compatibility&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Python &amp;gt; 3.5 is &lt;strong&gt;NOT&lt;/strong&gt; backwards compatible and thus some of the dependencies might be &lt;em&gt;newer&lt;/em&gt; than wanted. One solution is to &lt;code class=&quot;highlighter-rouge&quot;&gt;switch&lt;/code&gt; using &lt;strong&gt;homebrew&lt;/strong&gt;.&lt;/p&gt;

&lt;div class=&quot;language-makefile highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;err&quot;&gt;brew&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;python&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;2.7.x&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Also, make sure to use the correct commands in execution, i.e. &lt;code class=&quot;highlighter-rouge&quot;&gt;pip&lt;/code&gt;/&lt;code class=&quot;highlighter-rouge&quot;&gt;pip2&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;python&lt;/code&gt;/&lt;code class=&quot;highlighter-rouge&quot;&gt;python2&lt;/code&gt;.&lt;/p&gt;

&lt;hr /&gt;</content><author><name>Tin Nguyen</name></author><category term="Makefile" /><category term="GCC" /><category term="Arduino IDE" /><category term="AVR" /><category term="Python" /><summary type="html">Getting start with a robust pre-compile routine of Makefile parameters and flags for Arduino board using AVR GCC compiler in the command line and brief mention about serial communication between Arduino boards</summary></entry><entry><title type="html">Quick Service to copy code format and reserve syntax highlight</title><link href="/tutorial/macos-service-copy-code-format" rel="alternate" type="text/html" title="Quick Service to copy code format and reserve syntax highlight" /><published>2018-12-23T00:00:00+07:00</published><updated>2018-12-23T00:00:00+07:00</updated><id>/tutorial/macos%20service%20copy%20code%20format</id><content type="html" xml:base="/tutorial/macos-service-copy-code-format">&lt;h1 id=&quot;overview&quot;&gt;Overview&lt;/h1&gt;

&lt;p&gt;This short tutorial aims to simplify the process of &lt;strong&gt;reserve the syntax highlight&lt;/strong&gt; property of any code blocks and paste them into other application such as &lt;em&gt;Microsoft Word&lt;/em&gt;, &lt;em&gt;Keynote&lt;/em&gt;, etc. conveniently with &lt;strong&gt;System Service routines&lt;/strong&gt; and couple of clicks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; [2019-06-12] Visit &lt;a href=&quot;https://github.com/tinng81/CopyHighlightService&quot;&gt;this repo&lt;/a&gt; to get the available Service workflow or type&lt;/p&gt;

&lt;div class=&quot;language-slim highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nt&quot;&gt;svn&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;checkout&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;https://github&lt;span class=&quot;nc&quot;&gt;.com&lt;/span&gt;/tinng81/CopyHighlightService&lt;span class=&quot;nc&quot;&gt;.git&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;in your Terminal app to directly download it.&lt;/p&gt;

&lt;h1 id=&quot;prerequisite&quot;&gt;Prerequisite&lt;/h1&gt;

&lt;p&gt;1.  Install Python-powered Syntax Highlighter &lt;em&gt;Pygments&lt;/em&gt; via Terminal app&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;# Python 2.7
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pip&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pygments&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Python 3.x
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pip3&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pygments&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;pip/ pip3&lt;/code&gt;: Python Package Managers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Side note:&lt;/strong&gt; &lt;em&gt;Python 2.7&lt;/em&gt; end of life is on January &lt;script type=&quot;math/tex&quot;&gt;1^{st}&lt;/script&gt;, 2020 and &lt;em&gt;Python 3.x&lt;/em&gt; is &lt;strong&gt;backward-incompatible&lt;/strong&gt;, i.e. you cannot keep using obsolete modules. It is highly recommended to install &lt;em&gt;Python 3.x&lt;/em&gt; instead.&lt;/p&gt;

&lt;p&gt;2. (Optional) In case you don’t have Python installed yet. Download Python 3 Latest Release &lt;a href=&quot;https://www.python.org/downloads/mac-osx/&quot;&gt;here&lt;/a&gt;. Or follow the below script to install via command line.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;#! /bin/bash&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# One-liner install homebrew using default Ruby shipped with your macOS Version&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;mkdir &lt;/span&gt;homebrew &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; curl &lt;span class=&quot;nt&quot;&gt;-L&lt;/span&gt; https://github.com/Homebrew/brew/tarball/master | &lt;span class=&quot;nb&quot;&gt;tar &lt;/span&gt;xz &lt;span class=&quot;nt&quot;&gt;--strip&lt;/span&gt; 1 &lt;span class=&quot;nt&quot;&gt;-C&lt;/span&gt; homebrew

&lt;span class=&quot;c&quot;&gt;# Then update the default PATH to use homebrew with your Shell&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Or other config file, E.g. '.bashrc'&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; ~/.zshrc &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;export PATH=&quot;&lt;/span&gt;/usr/local/bin:/usr/local/sbin:&lt;span class=&quot;nv&quot;&gt;$PATH&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.zshrc &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; ~/.zshrc

&lt;span class=&quot;c&quot;&gt;# Verify successful installation&lt;/span&gt;
brew &lt;span class=&quot;nt&quot;&gt;--version&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Install Python via Brew&lt;/span&gt;
brew &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;python

&lt;span class=&quot;c&quot;&gt;# Or specify a version&lt;/span&gt;
brew &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;python@2

&lt;span class=&quot;c&quot;&gt;# Lastly, install the Syntax Highlighter as in step 1&lt;/span&gt;
pip3 &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;pygments
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Side note:&lt;/strong&gt; Have a look into &lt;a href=&quot;/tutorial/compiling-arduino-with-makefile&quot;&gt;similar tutorials&lt;/a&gt; for Python installation and settings.&lt;/p&gt;

&lt;h1 id=&quot;about-pygments&quot;&gt;About Pygments&lt;/h1&gt;

&lt;blockquote&gt;
  &lt;p&gt;Python is an intepreted, high-level and without a doubt, the most common general-purpose programming language as of 2018.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And Pygments is simply a syntax highlighter suitable for &lt;em&gt;code hosting&lt;/em&gt;, &lt;em&gt;forums&lt;/em&gt;, &lt;em&gt;wikis&lt;/em&gt; or other applications that need to &lt;strong&gt;prettify source code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;From the Terminal, use command &lt;code class=&quot;highlighter-rouge&quot;&gt;pygmentize&lt;/code&gt; to initiate and provide &lt;em&gt;input flags&lt;/em&gt; to process your code block. If you have experience with Python, head to the next section on how to use Pygment in Python Environment.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;touch&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;py&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'print(&quot;Success&quot;) # Just a comment'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;py&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;pygmentize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;O&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;friendly&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;full&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;o&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;py&lt;/span&gt; 

&lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;html&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;touch&lt;/code&gt;: Create a file named &lt;em&gt;test.py&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;echo&lt;/code&gt;: Insert ‘{string}’ of text to designated file &amp;gt; {output}. This would also create file (if not exist) when invoked&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;open&lt;/code&gt;: Open input file&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pygment flags explanation. Type &lt;code class=&quot;highlighter-rouge&quot;&gt;pygmentize --help&lt;/code&gt; for a detailed manual.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-f&lt;/code&gt;: Format flag&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-O&lt;/code&gt;: Option flags, comma separated values&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-o&lt;/code&gt;: Output file (&lt;em&gt;stdout&lt;/em&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Lastly, the &lt;em&gt;test.py&lt;/em&gt; file was given as input (&lt;em&gt;stdin&lt;/em&gt;) for the command.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2018-12-23/array.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Grab another example &lt;a href=&quot;/assets/blogs/2018-12-23/array.py&quot;&gt;array.py&lt;/a&gt; and try it yourself.&lt;/em&gt;&lt;/p&gt;

&lt;h1 id=&quot;automate-with-services&quot;&gt;Automate with Services&lt;/h1&gt;

&lt;p&gt;Now that you have an initial idea of how &lt;em&gt;Pygments&lt;/em&gt; works, let’s try to automate copy code format with &lt;em&gt;a couple of clicks&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2018-12-23/services.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Services provide convenient routines visibly on a right click. Screen captured on &lt;strong&gt;macOS Mojave 10.14&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Essentially, &lt;em&gt;Services&lt;/em&gt; are &lt;em&gt;pre-defined routines&lt;/em&gt; that aim to automate tasks using &lt;strong&gt;AppleScript&lt;/strong&gt;. Open &lt;em&gt;Automator&lt;/em&gt; app via &lt;em&gt;Spotlight&lt;/em&gt; using  &lt;code class=&quot;highlighter-rouge&quot;&gt;⌘-Space Bar&lt;/code&gt; keystroke.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2018-12-23/step1.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Step 1 – Select Quick Action workflow&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Simply put, the flow is to &lt;em&gt;Copy the selected text&lt;/em&gt; (Step 1) &lt;script type=&quot;math/tex&quot;&gt;\rightarrow&lt;/script&gt; Prompt for highlighting language (Step 2) &lt;script type=&quot;math/tex&quot;&gt;\rightarrow&lt;/script&gt; Set variable value (Step 3) &lt;script type=&quot;math/tex&quot;&gt;\rightarrow&lt;/script&gt; Run command to&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2018-12-23/step2.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Step 2 – Select Input as Text. On the left panel, search &amp;amp; drag &lt;code class=&quot;highlighter-rouge&quot;&gt;Copy to Clipboard&lt;/code&gt; action&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The transition between Step 2 and 3. The &lt;em&gt;Input(1) and Copy(2)&lt;/em&gt; actions are inter-connected (Above, middle), whereas the &lt;em&gt;Copy(2) and Ask for Text (3)&lt;/em&gt; actions below are not connected.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2018-12-23/step3.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Step 3 – Similarly, search &amp;amp; drag &lt;code class=&quot;highlighter-rouge&quot;&gt;Set Value of Variable&lt;/code&gt; action, then select New Variable. This will serve as input for the final command&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Ultimately, the whole workflow should look similar to this.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/blogs/2018-12-23/step4.jpg&quot; alt=&quot;&quot; /&gt;
&lt;em&gt;Step 4 – Finally, Add a &lt;code class=&quot;highlighter-rouge&quot;&gt;Run Shell Script&lt;/code&gt; action, select your Shell and make sure it _Pass input_ &lt;code class=&quot;highlighter-rouge&quot;&gt;as arguments&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;pbpaste&lt;/code&gt; &amp;amp; &lt;code class=&quot;highlighter-rouge&quot;&gt;pbcopy&lt;/code&gt;: Command lines to provide text from Clipboard and add text to Clipboard. This setup serves our purpose of copy code blocks and later able to paste a &lt;em&gt;highlighted version&lt;/em&gt; of it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;New Pygments flags are added as well as the full path in order to ensure all cases.&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-g&lt;/code&gt;: Automatically detect Lexer from the content, i.e. the programming language.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;-l&lt;/code&gt;: Manually input Lexer, i.e. the user-input in Step 3&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The &lt;code class=&quot;highlighter-rouge&quot;&gt;-f&lt;/code&gt; formatter flag now utilizes rtf (Rich Text Format) instead.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;LC_CTYPE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;UTF-8&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; 
pbpaste | /usr/local/bin/pygmentize &lt;span class=&quot;nt&quot;&gt;-g&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-O&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;colorful &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; rtf &lt;span class=&quot;nt&quot;&gt;-l&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt; | pbcopy
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The command here has been revised and is a little bit different than the ‘raw’ one from previous section. Most importantly, the &lt;em&gt;export&lt;/em&gt; command ensures that the copied text is in &lt;strong&gt;UTF-8&lt;/strong&gt; encode in order for this to work.&lt;/p&gt;

&lt;h1 id=&quot;command-line-variant&quot;&gt;Command Line variant&lt;/h1&gt;

&lt;p&gt;As a bonus, if you’re more comfortable working with CLI, there is a quick function for you. Usage is simply as passing any file into your CLI, for instance &lt;code class=&quot;highlighter-rouge&quot;&gt;highlight array.py&lt;/code&gt; from the previous example.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'function highlight() {/usr/local/bin/pygmentize -g -O style=colorful -f rtf $1 | pbcopy}'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.zshrc
&lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt; ~/.zshrc
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Again replace the config file based on your Shell, the default is usually bashrc*&lt;/p&gt;

&lt;p&gt;⚠️ &lt;strong&gt;Important:&lt;/strong&gt; Use of &lt;code class=&quot;highlighter-rouge&quot;&gt;echo&lt;/code&gt; command with &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;gt;&amp;gt;&lt;/code&gt; will append to file. &lt;strong&gt;Do not&lt;/strong&gt; use &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;gt;&lt;/code&gt;, this will replace all your text.&lt;span class=&quot;spoiler&quot;&gt; I learned that the hard way !&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;The result will be copy onto your &lt;em&gt;Clipboard&lt;/em&gt; and is ready to paste in any other application that support &lt;em&gt;RTF&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Side note:&lt;/strong&gt; With the &lt;code class=&quot;highlighter-rouge&quot;&gt;-g&lt;/code&gt; flag enabled and file extension, there is no need to provide a &lt;em&gt;Lexer&lt;/em&gt; as Pygments will automatically detect the language and highlight accordingly.&lt;/p&gt;

&lt;h1 id=&quot;explore-highlight-style&quot;&gt;Explore highlight style&lt;/h1&gt;

&lt;p&gt;To find more about available &lt;em&gt;color scheme&lt;/em&gt;, simply type &lt;code class=&quot;highlighter-rouge&quot;&gt;python3&lt;/code&gt; to access Python Environment or use &lt;em&gt;Python3 IDLE&lt;/em&gt; if you use a Graphical UI application and the following code&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pygments.styles&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_all_styles&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;styles&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_all_styles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;styles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;troubleshooting-extra&quot;&gt;Troubleshooting (Extra)&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;Command not found with brew and/or python&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Make sure that you have installed successfully, try &lt;code class=&quot;highlighter-rouge&quot;&gt;source ~/.zshrc&lt;/code&gt; to refresh your Shell config file or simply &lt;em&gt;open a new window&lt;/em&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Command not found with Pygments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is usually due to inproper installation of multiple Python version on your machine.
Run&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;brew doctor &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; brew prune
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;to eliminate any empty keg and un-link unused dependencies.&lt;/p&gt;

&lt;p&gt;Also, install Pygments with Python &lt;code class=&quot;highlighter-rouge&quot;&gt;pip&lt;/code&gt; and &lt;strong&gt;NOT&lt;/strong&gt; to be confuse with brew.&lt;/p&gt;

&lt;hr /&gt;</content><author><name>Tin Nguyen</name></author><category term="Syntax Highlight" /><category term="OS X Services" /><category term="Python" /><category term="Pygment" /><summary type="html">An enhanced robust routine to copy-paste code block via macOS System Services, but the core is using the ubiquitous Python and its syntax highlighter Pygment</summary></entry><entry><title type="html">Study Matlab Script</title><link href="/tutorial/template-matlab-script" rel="alternate" type="text/html" title="Study Matlab Script" /><published>2018-05-02T00:00:00+07:00</published><updated>2018-05-02T00:00:00+07:00</updated><id>/tutorial/template%20matlab%20script</id><content type="html" xml:base="/tutorial/template-matlab-script">&lt;script src=&quot;/assets/js/mermaid.min.js&quot;&gt;&lt;/script&gt;

&lt;link rel=&quot;stylesheet&quot; href=&quot;/assets/css/mermaid.forest.css&quot; /&gt;

&lt;script&gt;mermaid.initialize({startOnLoad:true});&lt;/script&gt;

&lt;!-- Get Content for This Post and Split at Pound Signs to Find Headers --&gt;

&lt;!-- Encapsulate in Capture to Handle the Whitespace and Allow Commenting --&gt;

&lt;!-- Make the Graph --&gt;
&lt;h1&gt; Workflow Overview &lt;/h1&gt;

&lt;!-- Strip HTML and Seperate at Line Breaks --&gt;

&lt;!-- Strip Each Line of Whitespace and Only Keep Lines Longer than 3 --&gt;
&lt;div class=&quot;mermaid&quot; id=&quot;mermaidworkflow&quot; style=&quot;margin-left:100px&quot;&gt;

graph TB









node1(Load Variables From Workspace)



click node1 &quot;#1&quot;













node1(Load Variables From Workspace) --&amp;gt; node2(Obtain 2-Point Statistics)



click node2 &quot;#2&quot;













node2(Obtain 2-Point Statistics) --&amp;gt; node3(PCA)



click node3 &quot;#3&quot;













node3(PCA) --&amp;gt; node4(Function Estimation)



click node4 &quot;#4&quot;

&lt;/div&gt;

&lt;!--
This HTML was auto-generated from MATLAB code.
To make changes, update the MATLAB code and republish this document.
--&gt;

&lt;p&gt;&lt;br /&gt;Obtain the direct to Project-Pages publish function &lt;a href=&quot;https://github.com/ahmetcecen/MATLAB-PublishtoProjectPages&quot;&gt;here.&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h2&gt;Load Variables From Workspace&lt;a name=&quot;1&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Loading the microstructures and the effective property.&lt;/p&gt;

&lt;div class=&quot;language-matlab highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;
&lt;span class=&quot;nb&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GDL200Volumes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mat&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MPL290Volumes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mat&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;load&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EffectiveProperty290MPL200GDLinThatOrder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mat&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2&gt;Obtain 2-Point Statistics&lt;a name=&quot;2&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;language-matlab highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;
&lt;span class=&quot;n&quot;&gt;GG&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;zeros&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;490&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;49&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;290&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;current&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MPL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;GGcurrent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TwoPointMaster&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'full'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'auto'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;GG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,:)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GGcurrent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(:)/&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;numel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;PP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GGcurrent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)/&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;numel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;current&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GDL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;GGcurrent&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TwoPointMaster&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'full'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'auto'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;GG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;290&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,:)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GGcurrent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(:)/&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;numel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;PP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;290&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GGcurrent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)/&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;numel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2&gt;PCA&lt;a name=&quot;3&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Via SVD: 

&lt;img src=&quot;data:image/png;base64,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&quot; /&gt;


&lt;/p&gt;

&lt;div class=&quot;language-matlab highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PC1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Var1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Basis1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PCAConstruct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;scatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PC1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(:,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PC1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(:,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ones&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;290&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ones&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)],&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'filled'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;colormap&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;jet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;data:image/png;base64,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&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Function Estimation&lt;a name=&quot;4&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Using Multivariate Polynomial Regression&lt;/p&gt;

&lt;div class=&quot;language-matlab highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;
&lt;span class=&quot;n&quot;&gt;reg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MultiPolyRegress&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PC1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(:,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'figure'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-matlab highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;
&lt;span class=&quot;n&quot;&gt;reg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 

           &lt;span class=&quot;n&quot;&gt;FitParameters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'-----------------'&lt;/span&gt;
             &lt;span class=&quot;n&quot;&gt;PowerMatrix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x2&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;Scores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;490&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x10&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;PolynomialExpression&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x2&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Coefficients&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;yhat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;490&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
               &lt;span class=&quot;n&quot;&gt;Residuals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;490&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;double&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
           &lt;span class=&quot;n&quot;&gt;GoodnessOfFit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'-----------------'&lt;/span&gt;
                 &lt;span class=&quot;n&quot;&gt;RSquare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.9572&lt;/span&gt;
                     &lt;span class=&quot;n&quot;&gt;MAE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0571&lt;/span&gt;
                  &lt;span class=&quot;n&quot;&gt;MAESTD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0561&lt;/span&gt;
           &lt;span class=&quot;n&quot;&gt;Normalization&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'1-to-1 (Default)'&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;LOOCVGoodnessOfFit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'-----------------'&lt;/span&gt;
               &lt;span class=&quot;n&quot;&gt;CVRSquare&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.9556&lt;/span&gt;
                   &lt;span class=&quot;n&quot;&gt;CVMAE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0583&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;CVMAESTD&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0570&lt;/span&gt;
         &lt;span class=&quot;n&quot;&gt;CVNormalization&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'1-to-1 (Default)'&lt;/span&gt;


&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;img src=&quot;data:image/png;base64,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&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;&lt;a href=&quot;http://www.mathworks.com/products/matlab/&quot; style=&quot;font-size: 0.7em&quot;&gt;Published with MATLAB® R2014b&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;</content><author><name>Tin Nguyen</name></author><category term="Markdown" /><category term="MATLAB" /><summary type="html">Matlab Script Template, display MATLAB function plot workflow in HTML with reserved parameters and interactive</summary></entry></feed>