{"id":1146,"date":"2022-08-14T07:45:30","date_gmt":"2022-08-14T07:45:30","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=1146"},"modified":"2022-08-14T07:48:32","modified_gmt":"2022-08-14T07:48:32","slug":"nec-protocol-decoding-with-stm32-part-3-decoding-algorithm","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=1146","title":{"rendered":"NEC Protocol Decoding with STM32 Part 3: Decoding algorithm"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"535\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-07-at-9.29.12-AM-535x1024.png\" alt=\"\" class=\"wp-image-1139\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-07-at-9.29.12-AM-535x1024.png 535w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-07-at-9.29.12-AM-157x300.png 157w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-07-at-9.29.12-AM-768x1469.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-07-at-9.29.12-AM-803x1536.png 803w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-07-at-9.29.12-AM-750x1435.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-07-at-9.29.12-AM-400x765.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-07-at-9.29.12-AM-250x478.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-07-at-9.29.12-AM.png 806w\" sizes=\"(max-width: 535px) 100vw, 535px\" \/><\/figure><\/div>\n\n\n\n<p>In the previous guide (<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=1141\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=1141\" target=\"_blank\">here<\/a>), we saw how to configure the required peripherals. In this guide we shall see how to develop the algorithm required to decode the data.<\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Decoding algorithm.<\/li><li>Code.<\/li><li>Demo<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">8. Decoding Algorithm:<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"184\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-10-at-7.37.11-AM-1024x184.png\" alt=\"\" class=\"wp-image-1147\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-10-at-7.37.11-AM-1024x184.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-10-at-7.37.11-AM-300x54.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-10-at-7.37.11-AM-768x138.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-10-at-7.37.11-AM-1536x276.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-10-at-7.37.11-AM-2048x367.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-10-at-7.37.11-AM-1150x206.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-10-at-7.37.11-AM-750x135.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-10-at-7.37.11-AM-400x72.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/Screen-Shot-2022-08-10-at-7.37.11-AM-250x45.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>In general, the protocol has the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Leader code<\/li><li>First address<\/li><li>Second address<\/li><li>First command<\/li><li>Second command<\/li><\/ul>\n\n\n\n<p>In Leader code, there is AGC pulse which is 9.4 milliseconds, hence we can detect this as following once the external interrupt is generated:<\/p>\n\n\n\n<p>We start of by declare a variable to store the pulse length and read the current timer value (which should be zero) as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">uint16_t len = 0;\nlen = read_nec_timer();   <\/pre><\/div>\n\n\n\n<p>Then switch the decode state:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Start of AGC pulse<\/li><li>End of AGC pulse<\/li><\/ul>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">switch (decoding_state)\n\t  {\n\t  case AGC_START:\n\t    start_nec_timer();                          \/\/ Start 9 ms pulse measurement\n\t    decoding_state = AGC_END;                   \/\/ Begin decoding\n\t    return;\n\n\t  case AGC_END:\n\t    reset_nec_timer();                          \/\/ Reset timer\n\t    if ((len &gt; MIN_9_MS) &amp;&amp; (len &lt; MAX_9_MS))   \/\/ ... 9 ms AGC\n\t    {\n\t      decoding_state = SHORT_PAUSE;             \/\/ then begin a 4,5 ms..\n\t      return;                                   \/\/ ..pulse measurement\n\t    }\n\t    break;<\/pre><\/div>\n\n\n\n<p>Then move the to long pause which is about 4.5 milliseconds<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\t  case SHORT_PAUSE:\n\t    reset_nec_timer();                          \/\/ Reset timer\n\t    if ((len &gt; MIN_4_5_MS) &amp;&amp; (len &lt; MAX_4_5_MS))\n\t    {\n\t      decoding_state = NEC_ADDR_COMM;           \/\/ Begin system adress decode\n\t      return;\n\t    }\n\t    break;<\/pre><\/div>\n\n\n\n<p>Then first address:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">case NEC_ADDR_COMM:\n\t    if ((len &gt; MIN_560_US) &amp;&amp; (len &lt; MAX_560_US) &amp;&amp;\n\t       (bitn == MAX_BITS) &amp;&amp;\n\t       ((system &amp; inv_system) == 0) &amp;&amp;\n\t       ((command &amp; inv_command) == 0))\n\t    {\n\t      decoding_state = LONG_PAUSE_1;            \/\/ Begin a long pause measurement\n\t      reset_nec_timer();                        \/\/ Reset timer\n\t      bitn = DECODE_IS_OK;\n\t      return;\n\t    }\n\t    else\n\t    {\n\t      decoding_state = NEC_BITS_DEC;\n\t      return;\n\t    }\n\t    break;<\/pre><\/div>\n\n\n\n<p>Decoding the actual data:<\/p>\n\n\n\n<p>If the pulse length is about 2.25 milliseconds, then data is 1.<\/p>\n\n\n\n<p>If the pulse is about 1.25, then the data is 0.<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\t  case NEC_BITS_DEC:                            \/\/ Bits receiving\n\t    reset_nec_timer();                          \/\/ Reset timer\n\t    decoding_state = NEC_ADDR_COMM;\n\t    bitn++;\n\n\t    if ((len &gt; MIN_2_25_MS) &amp;&amp; (len &lt; MAX_2_25_MS))\n\t    {\n\t      one_is_received();                        \/\/ Received bit is &quot;1&quot;\n\t      return;\n\t    }\n\t    else if ((len &gt; MIN_1_125_MS) &amp;&amp; (len &lt; MAX_1_125_MS))\n\t    {\n\t      zero_is_received();                       \/\/ Received bit is &quot;0&quot;\n\t      return;\n\t    }\n\t    break;<\/pre><\/div>\n\n\n\n<p>For adding zero and 1:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\nvoid one_is_received(void)\n{\n  if (bitn &lt; START_OF_COM)\n  {\n    if (bitn &lt; START_OF_INV_SYS)     \/\/ Receive system address bits\n    {\n      system = ((system &gt;&gt; 1) | 0x80);\n    }\n    else\n    {\n      inv_system = ((inv_system &gt;&gt; 1) | 0x80);\n    }\n  }\n  else\n  {\n    if (bitn &lt; START_OF_INV_COM)     \/\/ Receive command bits\n    {\n      command = ((command &gt;&gt; 1) | 0x80);\n    }\n    else\n    {\n      inv_command = ((inv_command &gt;&gt; 1) | 0x80);\n    }\n  }\n}\n\n\n\/* This functon stores the received &quot;zero&quot; bits\n *\n *\/\nvoid zero_is_received(void)\n{\n  if (bitn &lt; START_OF_COM)\n  {\n    if (bitn &lt; START_OF_INV_SYS)   \/\/ Receive system address bits\n    {\n      system = ((system &gt;&gt; 1) &amp; 0x7F);\n    }\n    else\n    {\n      inv_system = ((inv_system &gt;&gt; 1) &amp; 0x7F);\n    }\n  }\n  else\n  {\n    if (bitn &lt; START_OF_INV_COM)   \/\/ Receive command bits\n    {\n      command = ((command &gt;&gt; 1) &amp; 0x7F);\n    }\n    else\n    {\n      inv_command = ((inv_command &gt;&gt; 1) &amp; 0x7F);\n    }\n  }\n}\n\n<\/pre><\/div>\n\n\n\n<p>The rest of the algorithm (mostly identical to the first):<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">case NEC_ADDR_COMM:\n\t    if ((len &gt; MIN_560_US) &amp;&amp; (len &lt; MAX_560_US) &amp;&amp;\n\t       (bitn == MAX_BITS) &amp;&amp;\n\t       ((system &amp; inv_system) == 0) &amp;&amp;\n\t       ((command &amp; inv_command) == 0))\n\t    {\n\t      decoding_state = LONG_PAUSE_1;            \/\/ Begin a long pause measurement\n\t      reset_nec_timer();                        \/\/ Reset timer\n\t      bitn = DECODE_IS_OK;\n\t      return;\n\t    }\n\t    else\n\t    {\n\t      decoding_state = NEC_BITS_DEC;\n\t      return;\n\t    }\n\t    break;\n\n\t  case NEC_BITS_DEC:                            \/\/ Bits receiving\n\t    reset_nec_timer();                          \/\/ Reset timer\n\t    decoding_state = NEC_ADDR_COMM;\n\t    bitn++;\n\n\t    if ((len &gt; MIN_2_25_MS) &amp;&amp; (len &lt; MAX_2_25_MS))\n\t    {\n\t      one_is_received();                        \/\/ Received bit is &quot;1&quot;\n\t      return;\n\t    }\n\t    else if ((len &gt; MIN_1_125_MS) &amp;&amp; (len &lt; MAX_1_125_MS))\n\t    {\n\t      zero_is_received();                       \/\/ Received bit is &quot;0&quot;\n\t      return;\n\t    }\n\t    break;\n\n\t  case LONG_PAUSE_1:\n\t    reset_nec_timer();                          \/\/ Reset timer\n\t    if ((len &gt; MIN_40_MS) &amp;&amp; (len &lt; MAX_40_MS)) \/\/ P\n\t    {                                           \/\/ A\n\t      decoding_state = REPEAT_AGC;              \/\/ U\n\t      return;                                   \/\/ S\n\t    }                                           \/\/ E\n\t    break;\n\n\t  case REPEAT_AGC:\n\t    reset_nec_timer();                          \/\/ Reset timer\n\t    if ((len &gt; MIN_9_MS) &amp;&amp; (len &lt; MAX_9_MS))\n\t    {                                           \/\/ R\n\t      decoding_state = REPEAT_SPACE;            \/\/ E\n\t      return;                                   \/\/ P\n\t    }                                           \/\/ E\n\t    break;                                      \/\/ A\n\t                                                \/\/ T\n\t  case REPEAT_SPACE:\n\t    reset_nec_timer();                          \/\/ Reset timer\n\t    if ((len &gt; MIN_2_25_MS) &amp;&amp; (len &lt; MAX_2_25_MS))\n\t    {                                           \/\/ C\n\t      decoding_state = REPEAT_BURST;            \/\/ O\n\t      return;                                   \/\/ D\n\t    }                                           \/\/ E\n\t    break;\n\n\t  case REPEAT_BURST:\n\t    reset_nec_timer();                          \/\/ Reset timer\n\t    if ((len &gt; MIN_560_US) &amp;&amp; (len &lt; MAX_560_US))\n\t    {                                           \/\/ R\n\t      decoding_state = LONG_PAUSE_2;            \/\/ E\n\t      rep_code++;                               \/\/ P\n\t      return;                                   \/\/ E\n\t    }                                           \/\/ A\n\t    break;                                      \/\/ T\n\t                                                \/\/ .\n\t  case LONG_PAUSE_2:                            \/\/ .\n\t    reset_nec_timer();                          \/\/ Reset timer\n\t    if ((len &gt; MIN_98_MS) &amp;&amp; (len &lt; MAX_98_MS))\n\t    {                                           \/\/ C\n\t      decoding_state = REPEAT_AGC;              \/\/ O\n\t      return;                                   \/\/ D\n\t    }                                           \/\/ E\n\t    break;\n\n\t  default:\n\t    reset_nec_timer();                          \/\/ Reset timer\n\t    decoding_state = FAULT;                     \/\/ Indicate an error\n\t    dec_ready = 0;\n\t    break;\n\t  }\n<\/pre><\/div>\n\n\n\n<p>For NEC timer start and reset:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\n\nvoid reset_nec_timer(void)\n{\n\tTIM2-&gt;CNT=0;\n\tTIM2-&gt;EGR|=TIM_EGR_UG;\n}\n\nuint16_t read_nec_timer(void)\n{\n  return TIM2-&gt;CNT; \/\/ Get the pulse len\n}\n\nvoid start_nec_timer(void)\n{\n  TIM2-&gt;CR1|=TIM_CR1_CEN;\n  TIM2-&gt;CNT=0;\n  TIM2-&gt;EGR|=TIM_EGR_UG;\n}\n\n\n\nvoid stop_nec_timer(void)\n{\n\tTIM2-&gt;CR1&amp;=~TIM_CR1_CEN;\n}<\/pre><\/div>\n\n\n\n<p>For reading the data from the main <\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">uint8_t decode_state()\n{\n\n\tif((bitn==DECODE_IS_OK)){return decode_success;}\n\telse {return decode_failed;}\n\treturn 0;\n}\n\nuint8_t get_system_state()\n{\n  return system;\n}\n\n\nuint8_t read_command()\n{\n\treturn decoded_data;\n\n}<\/pre><\/div>\n\n\n\n<p>Then inside the header file, we shall add the following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\n#define decode_success 1\n#define decode_failed  0\n\nuint8_t decode_state();\nuint8_t read_command();\nuint8_t get_system_state();\n\nenum decoding_state {\n\t\t\t\t\t\tAGC_START,\n\t\t\t\t\t\tAGC_END,\n\t\t\t\t\t\tSHORT_PAUSE,\n\t\t\t\t\t\tNEC_ADDR_COMM,\n\t\t\t\t\t\tNEC_BITS_DEC,\n\t\t\t\t\t\tLONG_PAUSE_1,\n\t\t\t\t\t\tREPEAT_AGC,\n\t\t\t\t\t\tREPEAT_SPACE,\n\t\t\t\t\t\tREPEAT_BURST,\n\t\t\t\t\t\tLONG_PAUSE_2,\n\t\t\t\t\t\tFAULT\n\t\t\t\t\t};\n\n#define         SYSTEM                     0\n#define         FAULT                      0xFF\n#define         MAX_BITS                   32\n#define         START_OF_INV_SYS           9\n#define         START_OF_COM               17\n#define         START_OF_INV_COM           25\n#define         DECODE_IS_OK               0x55<\/pre><\/div>\n\n\n\n<p>In the main function:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">extern void SysClockConfig(void);\n#include &quot;stm32f4xx.h&quot;\n#include &quot;delay.h&quot;\n#include &quot;math.h&quot;\n#include &quot;stdlib.h&quot;\n#include &quot;NEC.h&quot;\n#include &quot;stdio.h&quot;\n#include &quot;oled.h&quot;\n#include &quot;i2c.h&quot;\n\n\n\n\n\nint main(void)\n\t{\n\n\tSCB-&gt;CPACR |= ((3UL &lt;&lt; 10*2)|(3UL &lt;&lt; 11*2)); \/*Enable floating point unit*\/\n\tSysClockConfig();\n\tsystick_init_ms(64000000);\n\tNEC_Decoder_Init();\n\tSSD1306_Init();\n\tSSD1306_GotoXY(0,0);\n\tSSD1306_Puts(&quot;hello world&quot;,&amp;Font_11x18,1);\n\tSSD1306_UpdateScreen();\n\tdelay(2000);\n\tSSD1306_Clear();\n\n\twhile(1)\n\t\t{\n\t\t\tif(decode_state()==decode_success)\n\t\t\t\t{\n\t\t\t\t\tif(get_system_state()){\n\t\t\t\t\tuint8_t data=read_command();\n\t\t\t\t\tchar data_str[20];\n\t\t\t\t\tsprintf(data_str,&quot;Code=0x%x&quot;,data);\n\t\t\t\t\tSSD1306_Clear();\n\t\t\t\t\tSSD1306_GotoXY(0,0);\n\t\t\t\t\tSSD1306_Puts(data_str,&amp;Font_11x18,1);\n\t\t\t\t\tSSD1306_UpdateScreen();}\n\n\n\t\t\t\t}\n\n\n\t\t}\n\n\t}\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">9. Code:<\/h2>\n\n\n\n<p>You may download the entire source code from here:<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/IR_Remote_F407-2.zip\">IR_Remote_F407-2<\/a><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/08\/IR_Remote_F407-2.zip\" class=\"wp-block-file__button\" download>Download<\/a><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">10. Demo:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"NEC Protocol Decoding with STM32\" width=\"1170\" height=\"878\" src=\"https:\/\/www.youtube.com\/embed\/vltbcTD9rsg?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<p>Happy coding \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the previous guide (here), we saw how to configure the required peripherals. In this guide we shall see how to develop the algorithm required to decode the data. In this guide, we shall cover the following: Decoding algorithm. Code. Demo 8. Decoding Algorithm: In general, the protocol has the following: Leader code First address [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,2,19,11,7,12],"tags":[],"class_list":["post-1146","post","type-post","status-publish","format-standard","hentry","category-data-structures","category-embedded-systems","category-lcd","category-peripheral-drivers","category-state-machine","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1146"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1146"}],"version-history":[{"count":3,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1146\/revisions"}],"predecessor-version":[{"id":1151,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1146\/revisions\/1151"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1146"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1146"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1146"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}