Newer
Older
m5stickcplus / _build / html / week1.html
@Motoki Miura Motoki Miura on 19 Mar 2021 236 KB bt serial


<!DOCTYPE html>
<html class="writer-html4" lang="ja" >
<head>
  <meta charset="utf-8" />
  
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  
  <title>1週目 &mdash; IoT Programming  ドキュメント</title>
  

  
  <link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
  <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="_static/copybutton.css" type="text/css" />

  
  

  
  

  

  
  <!--[if lt IE 9]>
    <script src="_static/js/html5shiv.min.js"></script>
  <![endif]-->
  
    
      <script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
        <script type="text/javascript" src="_static/jquery.js"></script>
        <script type="text/javascript" src="_static/underscore.js"></script>
        <script type="text/javascript" src="_static/doctools.js"></script>
        <script type="text/javascript" src="_static/language_data.js"></script>
        <script type="text/javascript" src="_static/clipboard.min.js"></script>
        <script type="text/javascript" src="_static/copybutton.js"></script>
        <script type="text/javascript" src="_static/translations.js"></script>
    
    <script type="text/javascript" src="_static/js/theme.js"></script>

    
    <link rel="index" title="索引" href="genindex.html" />
    <link rel="search" title="検索" href="search.html" />
    <link rel="next" title="2週目" href="week2.html" />
    <link rel="prev" title="事前準備" href="pre.html" /> 
</head>

<body class="wy-body-for-nav">

   
  <div class="wy-grid-for-nav">
    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search" >
          

          
            <a href="index.html" class="icon icon-home"> IoT Programming
          

          
          </a>

          
            
            
          

          
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>

          
        </div>

        
        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
          
            
            
              
            
            
              <p class="caption"><span class="caption-text">Contents:</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="intro.html">実験の目的</a></li>
<li class="toctree-l1"><a class="reference internal" href="intro.html#id2">実験のすすめかた</a></li>
<li class="toctree-l1"><a class="reference internal" href="intro.html#url">参考URL</a></li>
<li class="toctree-l1"><a class="reference internal" href="pre.html">事前準備</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">1週目</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#id2">電源の切り方・入れ方</a></li>
<li class="toctree-l2"><a class="reference internal" href="#id3">プログラムの書き込み方</a></li>
<li class="toctree-l2"><a class="reference internal" href="#id4">コードを書くときのヒントと注意</a></li>
<li class="toctree-l2"><a class="reference internal" href="#serial">Serial通信</a></li>
<li class="toctree-l2"><a class="reference internal" href="#lcd">本体の液晶ディスプレイ(LCD)</a></li>
<li class="toctree-l2"><a class="reference internal" href="#id5">本体のボタン</a></li>
<li class="toctree-l2"><a class="reference internal" href="#id7">文字列の扱い、16進数や10進数の変換</a></li>
<li class="toctree-l2"><a class="reference internal" href="#beep">ブザー(Beep)</a></li>
<li class="toctree-l2"><a class="reference internal" href="#led">内蔵LED(赤・赤外)</a></li>
<li class="toctree-l2"><a class="reference internal" href="#id9">外部のLED等を接続</a></li>
<li class="toctree-l2"><a class="reference internal" href="#pwm-pulse-width-modulation">PWM (Pulse Width Modulation)</a></li>
<li class="toctree-l2"><a class="reference internal" href="#id10">サーボモータ(サーボハット利用)</a></li>
<li class="toctree-l2"><a class="reference internal" href="#adc">アナログセンサを接続 (ADC)</a></li>
<li class="toctree-l2"><a class="reference internal" href="#id13">加速度センサ</a></li>
<li class="toctree-l2"><a class="reference internal" href="#infrared">赤外(InfraRed)リモコン</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#id14">信号の読み取り</a></li>
<li class="toctree-l3"><a class="reference internal" href="#id15">信号の送信</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#tft-esprite">スプライト表示(TFT_eSprite クラス)</a></li>
<li class="toctree-l2"><a class="reference internal" href="#wifi">Wifi 接続</a></li>
<li class="toctree-l2"><a class="reference internal" href="#ntp-network-time-protocol">NTPサーバ (Network Time Protocol) と時刻の取得</a></li>
<li class="toctree-l2"><a class="reference internal" href="#webclient">WebClient</a></li>
<li class="toctree-l2"><a class="reference internal" href="#google-spreadsheet">Google Spreadsheet にデータを送信する</a></li>
<li class="toctree-l2"><a class="reference internal" href="#webserver">WebServer</a></li>
<li class="toctree-l2"><a class="reference internal" href="#mqtt">MQTT</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#mqtt-publish">MQTT Publish</a></li>
<li class="toctree-l3"><a class="reference internal" href="#mqtt-subscribe">MQTT Subscribe</a></li>
<li class="toctree-l3"><a class="reference internal" href="#id17">トピック名とワイルドカード</a></li>
<li class="toctree-l3"><a class="reference internal" href="#mosquitto">mosquitto コマンド例</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#bluetooth-serial-protocol-profile-spp">Bluetooth Serial Protocol Profile (SPP)</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#mac">(1) スレーブ用デバイスのMACアドレスを調べる</a></li>
<li class="toctree-l3"><a class="reference internal" href="#id19">(2) マスタ用デバイスにサンプルを書き込む</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#bluetooth-low-energy">Bluetooth Low Energy</a></li>
<li class="toctree-l2"><a class="reference internal" href="#preference">Preference</a></li>
<li class="toctree-l2"><a class="reference internal" href="#id20">電力制御</a></li>
<li class="toctree-l2"><a class="reference internal" href="#id21">その他</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="week2.html">2週目</a></li>
</ul>

            
          
        </div>
        
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" aria-label="top navigation">
        
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="index.html">IoT Programming</a>
        
      </nav>


      <div class="wy-nav-content">
        
        <div class="rst-content">
        
          

















<div role="navigation" aria-label="breadcrumbs navigation">

  <ul class="wy-breadcrumbs">
    
      <li><a href="index.html" class="icon icon-home"></a> &raquo;</li>
        
      <li>1週目</li>
    
    
      <li class="wy-breadcrumbs-aside">
        
          
            <a href="_sources/week1.rst.txt" rel="nofollow"> View page source</a>
          
        
      </li>
    
  </ul>

  
  <hr/>
</div>
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
            
  <div class="section" id="id1">
<h1>1週目<a class="headerlink" href="#id1" title="このヘッドラインへのパーマリンク">¶</a></h1>
<div class="admonition note">
<p class="first admonition-title">注釈</p>
<p class="last">以下の項目について、全員がすべてを試す必要はありません。役割分担をして、確認と理解をすすめてください。</p>
</div>
<div class="section" id="id2">
<h2>電源の切り方・入れ方<a class="headerlink" href="#id2" title="このヘッドラインへのパーマリンク">¶</a></h2>
<ul class="simple">
<li>電源を入れるには、電源ボタンを、2秒間長押しします。</li>
<li>電源を切るには、電源ボタン(M5と書かれたAボタンの左側面)を、6秒間長押しします。その際、プログラムによっては再スタートしたように見える場合がありますが、気にせずに長押し継続してください。</li>
<li>動画をみる→ <a class="reference external" href="https://youtu.be/Lo1jZbAeT8Y">https://youtu.be/Lo1jZbAeT8Y</a></li>
<li><a class="reference external" href="https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/M5StickC_Guide_Japanese.pdf">M5StickCガイド</a> の、4ページ目、ハードウェアの概要も参考になります。</li>
</ul>
</div>
<div class="section" id="id3">
<h2>プログラムの書き込み方<a class="headerlink" href="#id3" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p><a class="reference internal" href="pre.html#writetom5"><span class="std std-ref">プログラムの書き込み</span></a> を参照してください。</p>
</div>
<div class="section" id="id4">
<h2>コードを書くときのヒントと注意<a class="headerlink" href="#id4" title="このヘッドラインへのパーマリンク">¶</a></h2>
<ul class="simple">
<li>以下のソースコード例は、右上のボタンを押すと、クリップボードに簡単にコピーできます。</li>
<li>ソースコードのインデントは、CTRL+T (Macの場合はCommand+T)キーで、自動整形できます。</li>
<li><code class="docutils literal notranslate"><span class="pre">#include</span> <span class="pre">&lt;M5StickC.h&gt;</span></code>  は、M5StickC用のコードです。 <strong>M5StickCPlus</strong> では、<code class="docutils literal notranslate"><span class="pre">#include</span> <span class="pre">&lt;M5StickCPlus.h&gt;</span></code> に変更しないと、表示がおかしくなることがあります。</li>
<li>大文字と小文字は厳密に区別されます。</li>
<li>画面をつかうプログラムを書き込んだあと、画面を使わないプログラムを書き込むと、前のプログラムの画面が残ることがあります。</li>
<li>スケッチブック(プログラムを構成する、複数のソースコードを含むファイル、他のIDEではプロジェクトと呼ぶ場合もある)をコピーしたいときは、内包するフォルダごとコピーしてください。その際、フォルダ名と、メインのソースコードファイル名(拡張子以外の部分)は、一致している必要があります。</li>
</ul>
</div>
<div class="section" id="serial">
<h2>Serial通信<a class="headerlink" href="#serial" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p><a class="reference internal" href="#serial01"><span class="std std-numref">リスト 1</span></a> は、シリアルモニタへ文字列を出力するシンプルな例です。グローバル変数 num を 0 に設定したうえで、setup()関数が1回実行されます。その後、loop()関数が繰り返し実行されます。
プログラムの出力をみるには、Arduino IDEで「シリアルモニタ」をひらいてください。コードエディタ右上の虫眼鏡アイコンボタンをおします。
Serialクラスには、print()関数、println()関数、 printf()関数があります。Serial通信を用いると、デバイス側の変数の値や状況を、PC側で確認するプログラムを書くことができます。</p>
<div class="literal-block-wrapper docutils container" id="serial01">
<div class="code-block-caption"><span class="caption-number">リスト 1 </span><span class="caption-text">src/serial01.ino</span><a class="headerlink" href="#serial01" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1
2
3
4
5
6
7
8
9</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kr">int</span> <span class="n">num</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="hll"><span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
</span>  <span class="nf">Serial</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="mi">115200</span><span class="p">);</span> <span class="c1">// 通信速度をbpsで設定</span>
<span class="p">}</span>
<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;%d </span><span class="se">\n</span><span class="s">&quot;</span> <span class="p">,</span> <span class="n">num</span><span class="p">);</span>
  <span class="n">num</span><span class="o">++</span><span class="p">;</span>
  <span class="nf">delay</span><span class="p">(</span><span class="mi">500</span><span class="p">);</span> <span class="c1">// 500ミリ秒待つ</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
<p>シリアルモニタは、デバイスからの出力を確認するだけではなく、デバイスに文字を送信することもできます。<a class="reference internal" href="#serial02"><span class="std std-numref">リスト 2</span></a> は、シリアルモニタを介して、PCからデバイスに文字を送信する例です。シリアルモニタ上部のテキストエリアから 0 を送信すると、カウンタ num をリセットします。10〜14行目で、PCから送信された文字を、1文字ずつ <code class="docutils literal notranslate"><span class="pre">Serial.read()</span></code> で読み取って、配列 <code class="docutils literal notranslate"><span class="pre">buf</span></code> に格納しています。PCから複数の文字を1回で送信すると、 <code class="docutils literal notranslate"><span class="pre">Serial.available()</span></code> は連続して 1 (=true) を返しますので、1回に送信された文字をすべて <code class="docutils literal notranslate"><span class="pre">buf</span></code> に格納することができます。ちなみに、シリアルモニタで送信された文字列の最後は、改行コード(10)が付与されます。</p>
<div class="literal-block-wrapper docutils container" id="serial02">
<div class="code-block-caption"><span class="caption-number">リスト 2 </span><span class="caption-text">src/serial02.ino</span><a class="headerlink" href="#serial02" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kr">int</span> <span class="n">num</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kr">char</span> <span class="n">buf</span><span class="p">[</span><span class="mi">100</span><span class="p">];</span>

<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="mi">115200</span><span class="p">);</span> <span class="c1">// 通信速度をbpsで設定</span>
<span class="p">}</span>

<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
  <span class="kr">int</span> <span class="n">pos</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="hll">  <span class="k">while</span> <span class="p">(</span><span class="nf">Serial</span><span class="p">.</span><span class="nf">available</span><span class="p">())</span> <span class="p">{</span> <span class="c1">//PCから送信された文字があるあいだ、くりかえす</span>
</span><span class="hll">    <span class="kr">char</span> <span class="n">c</span> <span class="o">=</span> <span class="nf">Serial</span><span class="p">.</span><span class="nf">read</span><span class="p">();</span> <span class="c1">// 1バイト読み取る</span>
</span><span class="hll">    <span class="n">buf</span><span class="p">[</span><span class="n">pos</span><span class="p">]</span> <span class="o">=</span> <span class="n">c</span><span class="p">;</span>           <span class="c1">// 配列buf に格納</span>
</span><span class="hll">    <span class="n">pos</span><span class="o">++</span><span class="p">;</span>    <span class="c1">// 格納位置をひとつ右へ</span>
</span><span class="hll">  <span class="p">}</span>
</span>  <span class="k">if</span> <span class="p">(</span><span class="n">pos</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">buf</span><span class="p">[</span><span class="n">pos</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">// さいごに Null (文字列の終端)を追加(これを忘れるとどうなる?)</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;&gt; from pc: &quot;</span><span class="p">);</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span> <span class="n">buf</span> <span class="p">);</span> <span class="c1">// 格納しておいた文字列を表示</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">buf</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="sc">&#39;0&#39;</span> <span class="o">&amp;&amp;</span> <span class="n">pos</span> <span class="o">==</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// buf={ 48(=&#39;0&#39;), 10(=改行) } のとき</span>
      <span class="n">num</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>  <span class="c1">// num を 0 にする</span>
      <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span> <span class="s">&quot;Reset num&quot;</span> <span class="p">);</span>
    <span class="p">}</span>
    <span class="nf">delay</span><span class="p">(</span><span class="mi">2000</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="nf">Serial</span><span class="p">.</span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;%d </span><span class="se">\n</span><span class="s">&quot;</span> <span class="p">,</span> <span class="n">num</span> <span class="p">);</span>
  <span class="n">num</span><span class="o">++</span><span class="p">;</span>
  <span class="nf">delay</span><span class="p">(</span><span class="mi">500</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
<div class="admonition note">
<p class="first admonition-title">注釈</p>
<p class="last">16行目の処理を忘れると、どうなるでしょうか? また、buf が溢れると、なにが起きるでしょうか?プログラムを書くときは、常に例外的な事象がおきる可能性を考えておきましょう。ただし、全ての例外的な事象に対処するのは困難な場合が多いです。</p>
</div>
</div>
<div class="section" id="lcd">
<h2>本体の液晶ディスプレイ(LCD)<a class="headerlink" href="#lcd" title="このヘッドラインへのパーマリンク">¶</a></h2>
<ul class="simple">
<li>M5StickCのDisplay周り解析 &lt;<a class="reference external" href="https://lang-ship.com/blog/work/m5stickc-display">https://lang-ship.com/blog/work/m5stickc-display</a>&gt; が詳しいです。</li>
<li><a class="reference internal" href="#lcd01"><span class="std std-numref">リスト 3</span></a> のサンプルでは、外側から内側に向かって、10ピクセルずつ余白を残しながら、色を変えて塗りつぶしています。その後、8,16,26ピクセルフォント(それぞれ1,2,4番)をsetCursor()関数で指定して、print()関数で文字列を描画しています。</li>
<li>M5StickCPlusの機能である液晶ディスプレイ(LCD)を使用するため、 <code class="docutils literal notranslate"><span class="pre">#include</span> <span class="pre">&lt;M5StickCPlus.h&gt;</span></code> を指定し、<code class="docutils literal notranslate"><span class="pre">M5.begin()</span></code> を呼び出しています。</li>
</ul>
<div class="literal-block-wrapper docutils container" id="lcd01">
<div class="code-block-caption"><span class="caption-number">リスト 3 </span><span class="caption-text">src/lcd01.ino</span><a class="headerlink" href="#lcd01" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">&lt;M5StickCPlus.h&gt;</span><span class="cp"></span>

<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">M5</span><span class="p">.</span><span class="nf">begin</span><span class="p">();</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">setRotation</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillRect</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">240</span><span class="p">,</span> <span class="mi">135</span><span class="p">,</span> <span class="n">RED</span><span class="p">);</span> 
  <span class="c1">//M5StickCPlusの画面サイズは、240 x 135</span>

  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillRect</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">220</span><span class="p">,</span> <span class="mi">115</span><span class="p">,</span> <span class="n">ORANGE</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillRect</span><span class="p">(</span><span class="mi">20</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">200</span><span class="p">,</span> <span class="mi">95</span><span class="p">,</span> <span class="n">YELLOW</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillRect</span><span class="p">(</span><span class="mi">30</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="mi">180</span><span class="p">,</span> <span class="mi">75</span><span class="p">,</span> <span class="n">GREENYELLOW</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillRect</span><span class="p">(</span><span class="mi">40</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">160</span><span class="p">,</span> <span class="mi">55</span><span class="p">,</span> <span class="n">CYAN</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillRect</span><span class="p">(</span><span class="mi">50</span><span class="p">,</span> <span class="mi">50</span><span class="p">,</span> <span class="mi">140</span><span class="p">,</span> <span class="mi">35</span><span class="p">,</span> <span class="n">BLUE</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillRect</span><span class="p">(</span><span class="mi">60</span><span class="p">,</span> <span class="mi">60</span><span class="p">,</span> <span class="mi">120</span><span class="p">,</span> <span class="mi">15</span><span class="p">,</span> <span class="n">MAGENTA</span><span class="p">);</span>

  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">setTextFont</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// 8pixel ASCII font</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setTextSize</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="c1">// Magnify (x1-7)</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">setTextColor</span><span class="p">(</span><span class="n">WHITE</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setCursor</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">1</span><span class="p">);</span> <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;RED&quot;</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">setTextColor</span><span class="p">(</span><span class="n">BLACK</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setCursor</span><span class="p">(</span><span class="mi">20</span><span class="p">,</span><span class="mi">11</span><span class="p">);</span> <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;ORANGE&quot;</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setCursor</span><span class="p">(</span><span class="mi">30</span><span class="p">,</span><span class="mi">21</span><span class="p">);</span> <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;YELLOW&quot;</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setCursor</span><span class="p">(</span><span class="mi">40</span><span class="p">,</span><span class="mi">31</span><span class="p">);</span> <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;GREENYELLOW&quot;</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setCursor</span><span class="p">(</span><span class="mi">50</span><span class="p">,</span><span class="mi">41</span><span class="p">);</span> <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;CYAN&quot;</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">setTextColor</span><span class="p">(</span><span class="n">WHITE</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setCursor</span><span class="p">(</span><span class="mi">60</span><span class="p">,</span><span class="mi">51</span><span class="p">);</span> <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;BLUE&quot;</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setCursor</span><span class="p">(</span><span class="mi">70</span><span class="p">,</span><span class="mi">60</span><span class="p">,</span><span class="mi">2</span><span class="p">);</span> <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;MAGENTA (2)&quot;</span><span class="p">);</span>
  <span class="c1">// setCursorの第3引数は、TextFont番号</span>

  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">setTextColor</span><span class="p">(</span><span class="n">BLACK</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setCursor</span><span class="p">(</span><span class="mi">30</span><span class="p">,</span><span class="mi">90</span><span class="p">,</span><span class="mi">4</span><span class="p">);</span> <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;26pixel ASCII (4)&quot;</span><span class="p">);</span>
<span class="p">}</span>

<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
<p>画面の向きは、setRotation() 関数で、設定します。0〜3までの整数で、指定します。</p>
<div class="figure">
<a class="reference internal image-reference" href="_images/setRotation.gif"><img alt="_images/setRotation.gif" src="_images/setRotation.gif" style="width: 400.0px; height: 400.0px;" /></a>
</div>
<div class="admonition note">
<p class="first admonition-title">注釈</p>
<p class="last">フォントの種類を設定するときは、setTextFont() や、setCursor()の第3引数をつかいます。setTextSize()は、指定したフォントを何倍に引き伸ばして表示するか?なので、基本は1を指定することが多いです。倍率を増やすと、ギザギザが目立ちます。</p>
</div>
</div>
<div class="section" id="id5">
<h2>本体のボタン<a class="headerlink" href="#id5" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>本体には、3つのボタンがあります。
(参考:<a class="reference external" href="https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/M5StickC_Guide_Japanese.pdf">M5StickCガイド</a> の、4ページ目、ハードウェアの概要)</p>
<p><a class="reference internal" href="#button01"><span class="std std-numref">リスト 4</span></a> に、ボタンをおしたらシリアルモニタに表示する例を示します。ボタンも、M5StickC/CPlusの機能なので、 <code class="docutils literal notranslate"><span class="pre">#include</span> <span class="pre">&lt;M5StickCPlus.h&gt;</span></code> を指定し、<code class="docutils literal notranslate"><span class="pre">M5.begin()</span></code> を呼び出しておく必要があります。また、ボタンの状態を読み出して、ボタンオブジェクト(BtnA,BtnB)に設定するために、 <code class="docutils literal notranslate"><span class="pre">M5.update()</span></code> を、ループのなかに入れておく必要があります( <a class="reference external" href="https://github.com/m5stack/M5StickC-Plus/blob/master/src/M5StickCPlus.cpp">update()の定義</a> )。長押しと普通押しを区別したい場合は、ifで確認する順番(長押しを先に判定する)が重要です。</p>
<div class="literal-block-wrapper docutils container" id="button01">
<div class="code-block-caption"><span class="caption-number">リスト 4 </span><span class="caption-text">src/button01.ino</span><a class="headerlink" href="#button01" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">&lt;M5StickCPlus.h&gt;</span><span class="cp"></span>

<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">M5</span><span class="p">.</span><span class="nf">begin</span><span class="p">();</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">setRotation</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
<span class="p">}</span>

<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">update</span><span class="p">();</span> <span class="c1">// 各ボタンの状態を(読み取って)更新する:ボタンを判定するときは必須。</span>

  <span class="k">if</span> <span class="p">(</span><span class="n">M5</span><span class="p">.</span><span class="n">BtnA</span><span class="p">.</span><span class="n">wasReleasefor</span><span class="p">(</span><span class="mi">1000</span><span class="p">)</span> <span class="p">)</span> <span class="p">{</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;[A] was Pressed longer than 1s&quot;</span><span class="p">);</span>
  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">M5</span><span class="p">.</span><span class="n">BtnA</span><span class="p">.</span><span class="n">wasReleased</span><span class="p">())</span> <span class="p">{</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;[A] was Pressed&quot;</span><span class="p">);</span>
  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">M5</span><span class="p">.</span><span class="n">BtnB</span><span class="p">.</span><span class="n">wasReleasefor</span><span class="p">(</span><span class="mi">1000</span><span class="p">)</span> <span class="p">)</span> <span class="p">{</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;[B] was Pressed longer than 1s&quot;</span><span class="p">);</span>
  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">M5</span><span class="p">.</span><span class="n">BtnB</span><span class="p">.</span><span class="n">wasReleased</span><span class="p">())</span> <span class="p">{</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;[B] was Pressed&quot;</span><span class="p">);</span>
  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">M5</span><span class="p">.</span><span class="n">Axp</span><span class="p">.</span><span class="n">GetBtnPress</span><span class="p">()</span> <span class="o">==</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;[Power] was Pressed&quot;</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="nf">delay</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
<div class="admonition note">
<p class="first admonition-title">注釈</p>
<p class="last"><a class="reference external" href="https://lang-ship.com/reference/unofficial/M5StickC/Class/Button">非公式リファレンスの「ボタン管理(Button)」</a> も参考になります。</p>
</div>
</div>
<div class="section" id="id7">
<h2>文字列の扱い、16進数や10進数の変換<a class="headerlink" href="#id7" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p><a class="reference internal" href="#str01"><span class="std std-numref">リスト 5</span></a> に、文字列から整数に変換したり、16進数表現の文字列を10進数に変換する例を示します。
Stringクラスを用いると、char配列 / byte配列 / 小文字変換や、空白改行の削除(ただし文字列の前後のみ)、部分文字列の取得などができます。
元のデータが保持されるメソッドと、破壊されるメソッドがあることに注意しましょう。
M5系デバイスのLCDでは、色を16ビット値(赤5bit/緑6bit/青5bit)で表現しています。 <code class="docutils literal notranslate"><span class="pre">M5.Lcd.color565()</span></code> という関数もありますが、ここではビット演算の理解を深めるため、関数を定義しています。
C言語のポインタや、シフト演算などを理解していると、このような処理を円滑に記述できるようになります。</p>
<div class="literal-block-wrapper docutils container" id="str01">
<div class="code-block-caption"><span class="caption-number">リスト 5 </span><span class="caption-text">src/str01.ino</span><a class="headerlink" href="#str01" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">&lt;M5StickCPlus.h&gt;</span><span class="cp"></span>

<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="mi">115200</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="nf">begin</span><span class="p">();</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">setRotation</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;整数 または 6文字の16進数(RRGGBB)を入力してください。&quot;</span><span class="p">);</span>
<span class="p">}</span>

<span class="kr">String</span> <span class="n">str</span> <span class="o">=</span> <span class="s">&quot;&quot;</span><span class="p">;</span> <span class="c1">// String: 可変長の文字列クラス</span>
<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
  <span class="kr">char</span> <span class="n">buf</span><span class="p">[</span><span class="mi">100</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>
  <span class="kr">int</span> <span class="n">pos</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
  <span class="k">while</span> <span class="p">(</span><span class="nf">Serial</span><span class="p">.</span><span class="nf">available</span><span class="p">())</span> <span class="p">{</span> <span class="c1">//PCから送信された文字があるあいだ、くりかえす</span>
    <span class="kr">char</span> <span class="n">c</span> <span class="o">=</span> <span class="nf">Serial</span><span class="p">.</span><span class="nf">read</span><span class="p">();</span> <span class="c1">// 1バイト読み取る</span>
    <span class="n">buf</span><span class="p">[</span><span class="n">pos</span><span class="p">]</span> <span class="o">=</span> <span class="n">c</span><span class="p">;</span>           <span class="c1">// 配列buf に格納</span>
    <span class="n">pos</span><span class="o">++</span><span class="p">;</span>    <span class="c1">// 格納位置をひとつ右へ</span>
  <span class="p">}</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">pos</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">buf</span><span class="p">[</span><span class="n">pos</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="kr">String</span> <span class="n">sbuf</span> <span class="o">=</span> <span class="n">buf</span><span class="p">;</span>
    <span class="n">sbuf</span><span class="p">.</span><span class="n">trim</span><span class="p">();</span> <span class="c1">//文字列の前と後の空白と改行を取り除く(破壊的メソッド)</span>
    <span class="n">str</span><span class="p">.</span><span class="n">concat</span><span class="p">(</span><span class="n">sbuf</span><span class="p">);</span> <span class="c1">// 文字列の連結 (意味としては、str = str + sbuf)</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="n">str</span><span class="p">);</span>
    <span class="k">if</span> <span class="p">(</span><span class="nf">isDigit</span><span class="p">(</span><span class="n">sbuf</span><span class="p">))</span> <span class="p">{</span>
      <span class="kr">int</span> <span class="n">num</span> <span class="o">=</span> <span class="n">sbuf</span><span class="p">.</span><span class="n">toInt</span><span class="p">();</span>
      <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span> <span class="n">num</span> <span class="o">*</span> <span class="n">num</span> <span class="p">);</span>
    <span class="p">}</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">sbuf</span><span class="p">.</span><span class="n">length</span><span class="p">()</span> <span class="o">==</span> <span class="mi">6</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// RRGGBBとして、LCD画面の背景を塗りつぶす</span>
      <span class="n">sbuf</span><span class="p">.</span><span class="n">toLowerCase</span><span class="p">();</span>
      <span class="kr">uint8_t</span> <span class="n">r</span> <span class="o">=</span> <span class="n">hexToDec</span><span class="p">(</span> <span class="n">sbuf</span><span class="p">.</span><span class="n">substring</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span> <span class="p">);</span>
      <span class="kr">uint8_t</span> <span class="n">g</span> <span class="o">=</span> <span class="n">hexToDec</span><span class="p">(</span> <span class="n">sbuf</span><span class="p">.</span><span class="n">substring</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">)</span> <span class="p">);</span>
      <span class="kr">uint8_t</span> <span class="n">b</span> <span class="o">=</span> <span class="n">hexToDec</span><span class="p">(</span> <span class="n">sbuf</span><span class="p">.</span><span class="n">substring</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">)</span> <span class="p">);</span>
      <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillScreen</span><span class="p">(</span> <span class="n">getColorUInt16</span><span class="p">(</span> <span class="n">r</span> <span class="p">,</span> <span class="n">g</span> <span class="p">,</span> <span class="n">b</span> <span class="p">)</span> <span class="p">);</span>
      <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setCursor</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">70</span><span class="p">,</span> <span class="mi">4</span><span class="p">);</span>
      <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">printf</span><span class="p">(</span><span class="s">&quot; %02x %02x %02x </span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">g</span><span class="p">,</span> <span class="n">b</span><span class="p">);</span>
      <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">printf</span><span class="p">(</span><span class="s">&quot; %d %d %d &quot;</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">g</span><span class="p">,</span> <span class="n">b</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">}</span>
  <span class="nf">delay</span><span class="p">(</span><span class="mi">50</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">//全ての文字が0〜9なら、1(true)を返す</span>
<span class="kr">bool</span> <span class="nf">isDigit</span><span class="p">(</span><span class="kr">String</span> <span class="n">s</span><span class="p">)</span> <span class="p">{</span>
  <span class="kr">bool</span> <span class="n">isAllDigit</span> <span class="o">=</span> <span class="kr">true</span><span class="p">;</span>
  <span class="kr">const</span> <span class="kr">char</span> <span class="o">*</span><span class="n">p</span> <span class="o">=</span> <span class="n">s</span><span class="p">.</span><span class="n">c_str</span><span class="p">();</span> <span class="c1">// String.c_str() は、NULLで終端されたchar配列の先頭アドレスを返す</span>
  <span class="k">while</span> <span class="p">(</span> <span class="o">*</span><span class="n">p</span> <span class="o">!=</span> <span class="mi">0</span> <span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">*</span><span class="n">p</span> <span class="o">&lt;</span> <span class="sc">&#39;0&#39;</span> <span class="o">||</span> <span class="sc">&#39;9&#39;</span> <span class="o">&lt;</span> <span class="o">*</span><span class="n">p</span><span class="p">)</span> <span class="n">isAllDigit</span> <span class="o">=</span> <span class="kr">false</span><span class="p">;</span>
    <span class="n">p</span><span class="o">++</span><span class="p">;</span>
  <span class="p">}</span>
  <span class="k">return</span> <span class="n">isAllDigit</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// M5 用の、16ビットカラー値に変換 引用:https://qiita.com/nnn112358/items/ea6b5e81623ba690343c</span>
<span class="kr">uint16_t</span> <span class="nf">getColorUInt16</span><span class="p">(</span><span class="kr">uint8_t</span> <span class="n">red</span><span class="p">,</span> <span class="kr">uint8_t</span> <span class="n">green</span><span class="p">,</span> <span class="kr">uint8_t</span> <span class="n">blue</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="p">((</span><span class="n">red</span> <span class="o">&gt;&gt;</span> <span class="mi">3</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="mi">11</span><span class="p">)</span> <span class="o">|</span> <span class="p">((</span><span class="n">green</span> <span class="o">&gt;&gt;</span> <span class="mi">2</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="mi">5</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="n">blue</span> <span class="o">&gt;&gt;</span> <span class="mi">3</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">// 引数hex が16進表記の文字列だと仮定して、10進の値を返す</span>
<span class="kr">uint8_t</span> <span class="nf">hexToDec</span><span class="p">(</span><span class="kr">String</span> <span class="n">hex</span><span class="p">)</span> <span class="p">{</span>
  <span class="kr">int</span> <span class="n">dec</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
  <span class="kr">int</span> <span class="n">tmp</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
  <span class="k">for</span> <span class="p">(</span><span class="kr">int</span> <span class="n">p</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">p</span> <span class="o">&lt;</span> <span class="n">hex</span><span class="p">.</span><span class="n">length</span><span class="p">();</span> <span class="n">p</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">tmp</span> <span class="o">=</span> <span class="kr">int</span><span class="p">(</span><span class="n">hex</span><span class="p">.</span><span class="n">charAt</span><span class="p">(</span><span class="n">p</span><span class="p">));</span>
    <span class="k">if</span> <span class="p">(</span> <span class="sc">&#39;0&#39;</span> <span class="o">&lt;=</span> <span class="n">tmp</span> <span class="o">&amp;&amp;</span> <span class="n">tmp</span> <span class="o">&lt;=</span> <span class="sc">&#39;9&#39;</span> <span class="p">)</span> <span class="n">tmp</span> <span class="o">=</span> <span class="n">tmp</span> <span class="o">-</span> <span class="sc">&#39;0&#39;</span><span class="p">;</span>
    <span class="k">if</span> <span class="p">(</span> <span class="sc">&#39;a&#39;</span> <span class="o">&lt;=</span> <span class="n">tmp</span> <span class="o">&amp;&amp;</span> <span class="n">tmp</span> <span class="o">&lt;=</span> <span class="sc">&#39;f&#39;</span> <span class="p">)</span> <span class="n">tmp</span> <span class="o">=</span> <span class="n">tmp</span> <span class="o">-</span> <span class="sc">&#39;a&#39;</span> <span class="o">+</span> <span class="mi">10</span><span class="p">;</span>
    <span class="k">if</span> <span class="p">(</span> <span class="sc">&#39;A&#39;</span> <span class="o">&lt;=</span> <span class="n">tmp</span> <span class="o">&amp;&amp;</span> <span class="n">tmp</span> <span class="o">&lt;=</span> <span class="sc">&#39;F&#39;</span> <span class="p">)</span> <span class="n">tmp</span> <span class="o">=</span> <span class="n">tmp</span> <span class="o">-</span> <span class="sc">&#39;A&#39;</span> <span class="o">+</span> <span class="mi">10</span><span class="p">;</span>
    <span class="n">tmp</span> <span class="o">=</span> <span class="nf">constrain</span><span class="p">(</span><span class="n">tmp</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">15</span><span class="p">);</span> <span class="c1">//例外処理</span>
    <span class="n">dec</span> <span class="o">=</span> <span class="p">(</span><span class="n">dec</span> <span class="o">*</span> <span class="mi">16</span><span class="p">)</span> <span class="o">+</span> <span class="n">tmp</span><span class="p">;</span>
  <span class="p">}</span>
  <span class="k">return</span> <span class="n">dec</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
<div class="admonition note">
<p class="first admonition-title">注釈</p>
<p class="last"><a class="reference external" href="https://nobita-rx7.hatenablog.com/entry/28248811">変数の型一覧</a> uint16_t は unsigned int 16bit type の略です。 <br /> 参考:<a class="reference external" href="https://qiita.com/nnn112358/items/ea6b5e81623ba690343c">M5StackのLCDディスプレイの色をRGBで指定する。</a></p>
</div>
</div>
<div class="section" id="beep">
<h2>ブザー(Beep)<a class="headerlink" href="#beep" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p><a class="reference internal" href="#sound01"><span class="std std-numref">リスト 6</span></a> は、内蔵Beepを鳴らすサンプルです。音の周波数は、最初の1オクターブ (f[0]〜f[6]) のみを配列宣言時に指定し、残りの3オクターブはsetup()内で、倍数を計算して配列に設定しています。</p>
<p><code class="docutils literal notranslate"><span class="pre">setBeep()</span></code> と <code class="docutils literal notranslate"><span class="pre">beep()</span></code> を使うと、同じビープ音を使い回すときは記述が短くて便利ですが、通常は <code class="docutils literal notranslate"><span class="pre">tone()</span></code> のほうが簡潔です。
どちらの記法でも、命令実行のあと、音の停止を待たずに、すぐに次の処理に移行します(ノンブロッキング)。
継続ミリ秒数(ms)は、 <code class="docutils literal notranslate"><span class="pre">M5.Beep.update()</span></code> が周期的に呼び出せるときに指定し、それ以外は省略するとよいでしょう。(結局、 <code class="docutils literal notranslate"><span class="pre">delay()</span></code> と <code class="docutils literal notranslate"><span class="pre">mute()</span></code> が必要になるため)</p>
<div class="literal-block-wrapper docutils container" id="sound01">
<div class="code-block-caption"><span class="caption-number">リスト 6 </span><span class="caption-text">src/sound01.ino</span><a class="headerlink" href="#sound01" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">&lt;M5StickCPlus.h&gt;</span><span class="cp"></span>

<span class="kr">int</span> <span class="n">f</span><span class="p">[</span><span class="mi">28</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="mi">262</span><span class="p">,</span> <span class="mi">294</span><span class="p">,</span> <span class="mi">330</span><span class="p">,</span> <span class="mi">349</span><span class="p">,</span> <span class="mi">392</span><span class="p">,</span> <span class="mi">440</span><span class="p">,</span> <span class="mi">494</span> <span class="p">};</span> <span class="c1">// 配列のサイズは4オクターブ分</span>
<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="mi">115200</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="nf">begin</span><span class="p">();</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">setRotation</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
  <span class="k">for</span> <span class="p">(</span><span class="kr">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">7</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">f</span><span class="p">[</span><span class="n">i</span> <span class="o">+</span> <span class="mi">7</span><span class="p">]</span>  <span class="o">=</span> <span class="n">f</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">*</span> <span class="mi">2</span><span class="p">;</span>
    <span class="n">f</span><span class="p">[</span><span class="n">i</span> <span class="o">+</span> <span class="mi">14</span><span class="p">]</span> <span class="o">=</span> <span class="n">f</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">*</span> <span class="mi">4</span><span class="p">;</span>
    <span class="n">f</span><span class="p">[</span><span class="n">i</span> <span class="o">+</span> <span class="mi">21</span><span class="p">]</span> <span class="o">=</span> <span class="n">f</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">*</span> <span class="mi">8</span><span class="p">;</span>
  <span class="p">}</span>
  <span class="c1">// setBeep( Hz, ms) でビープ音を設定して、beep()で鳴らす。</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Beep</span><span class="p">.</span><span class="n">setBeep</span><span class="p">(</span><span class="mi">523</span><span class="p">,</span> <span class="mi">500</span><span class="p">);</span>  <span class="n">M5</span><span class="p">.</span><span class="n">Beep</span><span class="p">.</span><span class="nf">beep</span><span class="p">();</span>  <span class="nf">delay</span><span class="p">(</span><span class="mi">500</span><span class="p">);</span>
  <span class="c1">// tone( Hz, ms ) で鳴らす方法</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Beep</span><span class="p">.</span><span class="nf">tone</span><span class="p">(</span><span class="mi">1046</span><span class="p">,</span> <span class="mi">500</span><span class="p">);</span>  <span class="nf">delay</span><span class="p">(</span><span class="mi">500</span><span class="p">);</span>
  <span class="c1">// msを省略し、tone( Hz ) で鳴らす(結局、delayが必要になるので)</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Beep</span><span class="p">.</span><span class="nf">tone</span><span class="p">(</span><span class="mi">2092</span><span class="p">);</span>  <span class="nf">delay</span><span class="p">(</span><span class="mi">500</span><span class="p">);</span>
  <span class="c1">// ここはmsを指定するとよい (loopのM5.Beep.updateが停めてくれるので、delayを省略できる)</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Beep</span><span class="p">.</span><span class="nf">tone</span><span class="p">(</span><span class="mi">2092</span> <span class="o">*</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1000</span><span class="p">);</span>
<span class="p">}</span>

<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Beep</span><span class="p">.</span><span class="n">update</span><span class="p">();</span> <span class="c1">//tone()やsetBeep()で指定した時間を過ぎていたら音を止める。</span>
  <span class="c1">//                  M5.Beep.mute() とすると、すぐに停止する。</span>

  <span class="k">while</span> <span class="p">(</span><span class="nf">Serial</span><span class="p">.</span><span class="nf">available</span><span class="p">())</span> <span class="p">{</span>
    <span class="kr">char</span> <span class="n">c</span> <span class="o">=</span> <span class="nf">Serial</span><span class="p">.</span><span class="nf">read</span><span class="p">();</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">c</span> <span class="o">&lt;</span> <span class="sc">&#39;c&#39;</span> <span class="o">||</span> <span class="sc">&#39;z&#39;</span> <span class="o">&lt;</span> <span class="n">c</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span> <span class="c1">// c〜zの文字以外なら、以降のwhile内処理をスキップ</span>
    <span class="n">M5</span><span class="p">.</span><span class="n">Beep</span><span class="p">.</span><span class="nf">tone</span><span class="p">(</span> <span class="n">f</span><span class="p">[</span><span class="n">c</span> <span class="o">-</span> <span class="sc">&#39;c&#39;</span><span class="p">]</span> <span class="p">,</span> <span class="mi">1000</span><span class="p">);</span> <span class="c1">// 1秒鳴らす</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span> <span class="n">f</span><span class="p">[</span><span class="n">c</span> <span class="o">-</span> <span class="sc">&#39;c&#39;</span><span class="p">]</span> <span class="p">);</span>
  <span class="p">}</span>
  <span class="nf">delay</span><span class="p">(</span><span class="mi">50</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
<div class="section" id="led">
<h2>内蔵LED(赤・赤外)<a class="headerlink" href="#led" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>M5StickCPlusには、2つのLEDランプが内蔵されています。GPIO(General Purpose I/O)10 には、赤色LED、GPIO9 には、赤外LEDが接続されています。
場所は、USBケーブルを挿す面の反対側の面にある、小さな穴2つの内側です。</p>
<p><a class="reference internal" href="#led01"><span class="std std-numref">リスト 7</span></a> は、赤色LEDを点滅させるシンプルなプログラムです。</p>
<div class="literal-block-wrapper docutils container" id="led01">
<div class="code-block-caption"><span class="caption-number">リスト 7 </span><span class="caption-text">src/led01.ino</span><a class="headerlink" href="#led01" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kr">int</span> <span class="n">PIN</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span> <span class="c1">// 赤色LED G10</span>
<span class="c1">//int PIN = 9; // Ir LED (カメラには映りますが、肉眼では見えません) G9</span>
<span class="c1">// その他、G0 (0) , G25 (25), G26 (26) がつかえます。</span>
<span class="c1">// https://lang-ship.com/blog/work/m5stickc-io/</span>

<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="nf">pinMode</span><span class="p">(</span><span class="n">PIN</span><span class="p">,</span> <span class="kr">OUTPUT</span><span class="p">);</span> <span class="c1">// PINのモード設定</span>
<span class="p">}</span>

<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
  <span class="nf">digitalWrite</span><span class="p">(</span><span class="n">PIN</span><span class="p">,</span> <span class="kr">HIGH</span><span class="p">);</span> <span class="c1">// HIGH = 1</span>
  <span class="nf">delay</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span>
  <span class="nf">digitalWrite</span><span class="p">(</span><span class="n">PIN</span><span class="p">,</span> <span class="kr">LOW</span><span class="p">);</span> <span class="c1">// LOW = 0</span>
  <span class="nf">delay</span><span class="p">(</span><span class="mi">500</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
<div class="section" id="id9">
<h2>外部のLED等を接続<a class="headerlink" href="#id9" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>外部のLED等は、 G0, G25, G26 に接続します。(GROVE端子のG32, G33も利用できます。)
サンプルプログラムは、<a class="reference internal" href="#led01"><span class="std std-numref">リスト 7</span></a> と同様です。PIN 番号を、0 / 25 / 26 に変更してください。</p>
<p>ブレッドボードに、抵抗とLEDを直列に接続します。
LEDの長い足のほうに、G0 (or G25 or G26) をジャンパワイヤで接続し、反対側(短い足)のほうを、GND (グランド)に接続します。
ポートを「HIGH」にすると、3.3Vの電圧がかかります。</p>
<div class="figure">
<a class="reference internal image-reference" href="_images/SimpleLED_m5s.png"><img alt="_images/SimpleLED_m5s.png" src="_images/SimpleLED_m5s.png" style="width: 291.59999999999997px; height: 606.6px;" /></a>
</div>
<div class="admonition warning">
<p class="first admonition-title">警告</p>
<p class="last">LEDのみで回路を構成しないよう注意!一般に、LEDは抵抗をつないで使用しないと、故障したり、最悪の場合破裂したりして危険です。ただし、抵抗入りLEDであれば問題ありません。</p>
</div>
</div>
<div class="section" id="pwm-pulse-width-modulation">
<h2>PWM (Pulse Width Modulation)<a class="headerlink" href="#pwm-pulse-width-modulation" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>パルス幅変調とは、信号の周期Tに対する、パルスの幅を変化させる方法です。
直流モータの速度制御や、サーボモータの制御、LEDの明度調整などに使われます。</p>
<p><a class="reference internal" href="#pwm01"><span class="std std-numref">リスト 8</span></a> は、赤色LEDを点滅させるシンプルなプログラムです。 <code class="docutils literal notranslate"><span class="pre">ledcSetup(チャンネル,</span> <span class="pre">周波数,</span> <span class="pre">分解能)</span></code> で、PWMチャンネル(0〜3)に対する周波数と分解能設定をし、 <code class="docutils literal notranslate"><span class="pre">lecAttachPin(ピン番号,</span> <span class="pre">チャンネル)</span></code> で、PWMチャンネルを適用する出力ピンを選択します。そのあと、 <code class="docutils literal notranslate"><span class="pre">ledcWrite(チャンネル,</span> <span class="pre">値)</span></code> で、分解能で設定したビットで表現できる最大値+1以下の値を指定することで、デューティー比を設定します。<a class="reference internal" href="#pwm01"><span class="std std-numref">リスト 8</span></a> の場合、分解能で8bitを指定したので、0〜256 の値が、デューティー比 0〜1 のパルス生成に対応します。</p>
<div class="literal-block-wrapper docutils container" id="pwm01">
<div class="code-block-caption"><span class="caption-number">リスト 8 </span><span class="caption-text">src/pwm01.ino</span><a class="headerlink" href="#pwm01" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kr">int</span> <span class="n">PIN</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span> <span class="c1">// 内蔵LED</span>
<span class="kr">int</span> <span class="n">PWM_CH</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// 0~3で指定する。0にすると高音が鳴って耳障り?</span>

<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="nf">pinMode</span><span class="p">(</span><span class="n">PIN</span><span class="p">,</span> <span class="kr">OUTPUT</span><span class="p">);</span> <span class="c1">// PINのモード設定</span>
<span class="hll">  <span class="n">ledcSetup</span><span class="p">(</span><span class="n">PWM_CH</span><span class="p">,</span> <span class="mi">90</span><span class="p">,</span> <span class="mi">8</span><span class="p">);</span> <span class="c1">// CH, 周波数(Hz) 【小さくするとどうなる?】, 分解能(bit)</span>
</span><span class="hll">  <span class="n">ledcAttachPin</span><span class="p">(</span><span class="n">PIN</span><span class="p">,</span> <span class="n">PWM_CH</span><span class="p">);</span>
</span>  <span class="c1">// https://lang-ship.com/reference/unofficial/M5StickC/Peripherals/LED_Control/</span>
<span class="p">}</span>

<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
  <span class="kr">int</span> <span class="n">i</span><span class="p">;</span>

  <span class="k">for</span> <span class="p">(</span><span class="kr">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span> <span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="mi">256</span> <span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="hll">    <span class="n">ledcWrite</span><span class="p">(</span><span class="n">PWM_CH</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span>
</span>    <span class="nf">delay</span><span class="p">(</span> <span class="mi">5</span> <span class="p">);</span>
  <span class="p">}</span>
  <span class="k">for</span> <span class="p">(</span><span class="kr">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">256</span> <span class="p">;</span> <span class="n">i</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="p">;</span> <span class="n">i</span><span class="o">--</span><span class="p">)</span> <span class="p">{</span>
<span class="hll">    <span class="n">ledcWrite</span><span class="p">(</span><span class="n">PWM_CH</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span>
</span>    <span class="nf">delay</span><span class="p">(</span> <span class="mi">5</span> <span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
<div class="admonition note">
<p class="first admonition-title">注釈</p>
<p class="last">ソースコードのコメントにも書いていますが、周波数を小さくする(20〜30程度)と、どうなるでしょうか?ぜひやってみてください。</p>
</div>
</div>
<div class="section" id="id10">
<h2>サーボモータ(サーボハット利用)<a class="headerlink" href="#id10" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p><a class="reference internal" href="#servohat01"><span class="std std-numref">リスト 9</span></a> は、<a class="reference external" href="https://www.switch-science.com/catalog/6076">サーボハット</a> のサーボモータを動かすサンプルです。サーボモータの制御はPWMですので、基本的に、上のPWMとやっていることは同じです。おまけとして、LEDも点灯させました。<code class="docutils literal notranslate"><span class="pre">map関数</span></code> は、Arduinoで使える関数で、範囲に対応する値を変換するときに使います。ここでは、サーボ制御で用いる5〜33の値を、LED制御の値0〜256に変換しています。</p>
<div class="literal-block-wrapper docutils container" id="servohat01">
<div class="code-block-caption"><span class="caption-number">リスト 9 </span><span class="caption-text">src/servohat01.ino</span><a class="headerlink" href="#servohat01" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="cp">#define MLOW 5</span>
<span class="cp">#define MHIGH 33</span>

<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">ledcSetup</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">50</span><span class="p">,</span> <span class="mi">8</span><span class="p">);</span> <span class="c1">//サーボハット CH1</span>
  <span class="n">ledcAttachPin</span><span class="p">(</span><span class="mi">26</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>

  <span class="nf">pinMode</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="kr">OUTPUT</span><span class="p">);</span>
  <span class="n">ledcSetup</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="mi">8</span><span class="p">);</span><span class="c1">//LED CH2</span>
  <span class="n">ledcAttachPin</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>
<span class="p">}</span>

<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">for</span> <span class="p">(</span><span class="kr">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">MLOW</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;=</span> <span class="n">MHIGH</span><span class="p">;</span> <span class="n">i</span> <span class="o">=</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">ledcWrite</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span>
    <span class="kr">int</span> <span class="n">v</span> <span class="o">=</span> <span class="nf">map</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">MLOW</span><span class="p">,</span> <span class="n">MHIGH</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">256</span><span class="p">);</span> <span class="c1">// 範囲5〜33に対するiの値を、範囲0〜256に変換</span>
    <span class="n">ledcWrite</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">v</span><span class="p">);</span>
    <span class="nf">delay</span><span class="p">(</span><span class="mi">50</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="nf">delay</span><span class="p">(</span><span class="mi">300</span><span class="p">);</span>
  <span class="k">for</span> <span class="p">(</span><span class="kr">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">MHIGH</span><span class="p">;</span> <span class="n">i</span> <span class="o">&gt;=</span> <span class="n">MLOW</span><span class="p">;</span> <span class="n">i</span> <span class="o">=</span> <span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">ledcWrite</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span>
    <span class="kr">int</span> <span class="n">v</span> <span class="o">=</span> <span class="nf">map</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">MLOW</span><span class="p">,</span> <span class="n">MHIGH</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">256</span><span class="p">);</span>
    <span class="n">ledcWrite</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">v</span><span class="p">);</span>
    <span class="nf">delay</span><span class="p">(</span><span class="mi">20</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="nf">delay</span><span class="p">(</span><span class="mi">300</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
<div class="section" id="adc">
<h2>アナログセンサを接続 (ADC)<a class="headerlink" href="#adc" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>ADCは、Analog to Digital Converter の意味です。
<code class="docutils literal notranslate"><span class="pre">analogRead(PIN)</span></code> は、PIN番ピンの電圧(0~3.3V)を、0〜4095 の値で返します。一般に、抵抗値が変化するタイプのセンサは、この方法をつかって、読み取ることができます。</p>
<div class="admonition warning">
<p class="first admonition-title">警告</p>
<p class="last"><a class="reference external" href="https://lang-ship.com/reference/unofficial/M5StickC/Peripherals/ADC">ADC</a> にかいてあるように、G26, G32, G33, G36のみ使えます。G26は、無線利用時には使えません。</p>
</div>
<p><a class="reference internal" href="#cds01"><span class="std std-numref">リスト 10</span></a> はCdSセル(照度センサ) の値を読み取るサンプルです。</p>
<div class="literal-block-wrapper docutils container" id="cds01">
<div class="code-block-caption"><span class="caption-number">リスト 10 </span><span class="caption-text">src/cds01.ino</span><a class="headerlink" href="#cds01" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kr">int</span> <span class="n">PIN</span> <span class="o">=</span> <span class="mi">26</span><span class="p">;</span>

<span class="c1">// +--- 15kΩ抵抗 --+-- CdSセル --+</span>
<span class="c1">// |              |             |</span>
<span class="c1">// GND           G26           3V3</span>
<span class="c1">// https://www.storange.jp/2012/03/arduinocds.html</span>

<span class="c1">// 注意点: https://lang-ship.com/reference/unofficial/M5StickC/Peripherals/ADC/</span>

<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="mi">115200</span><span class="p">);</span>
  <span class="nf">pinMode</span><span class="p">(</span><span class="n">PIN</span><span class="p">,</span> <span class="n">ANALOG</span><span class="p">);</span> <span class="c1">// PINのモード設定</span>
  <span class="c1">// https://lang-ship.com/blog/work/m5stickc-io/</span>
<span class="p">}</span>

<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;%04d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="nf">analogRead</span><span class="p">(</span><span class="n">PIN</span><span class="p">)</span> <span class="p">);</span> <span class="c1">// 暗 0 〜 4095 明</span>
  <span class="nf">delay</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
<p>圧力センサや、曲げセンサも、同様の方法で利用することができます。</p>
</div>
<div class="section" id="id13">
<h2>加速度センサ<a class="headerlink" href="#id13" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p><a class="reference internal" href="#accgyro01"><span class="std std-numref">リスト 11</span></a> は、内蔵されている加速度センサ(MPU6886) の値を表示するサンプルです。ちなみに、IMUとは、Inertial Measurement Unit: 慣性計測装置 の略です。
「ツール」→「シリアルプロッタ」をひらくと、値をグラフでみることができます。
ジャイロセンサの値も取得可能です。</p>
<div class="literal-block-wrapper docutils container" id="accgyro01">
<div class="code-block-caption"><span class="caption-number">リスト 11 </span><span class="caption-text">src/accgyro.ino</span><a class="headerlink" href="#accgyro01" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1">// 参考にしたサイト: https://qiita.com/kitazaki/items/1ce671532270cd44fabf</span>

<span class="cp">#include</span> <span class="cpf">&lt;M5StickCPlus.h&gt;</span><span class="cp"></span>

<span class="kr">float</span> <span class="n">gyroX</span><span class="p">,</span> <span class="n">gyroY</span><span class="p">,</span> <span class="n">gyroZ</span><span class="p">;</span>  <span class="c1">// ジャイロデータ </span>
<span class="kr">float</span> <span class="n">ax</span><span class="p">,</span> <span class="n">ay</span><span class="p">,</span> <span class="n">az</span><span class="p">;</span>  <span class="c1">// 加速度データ</span>

<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">M5</span><span class="p">.</span><span class="nf">begin</span><span class="p">();</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">setRotation</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">IMU</span><span class="p">.</span><span class="n">Init</span><span class="p">();</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="mi">115200</span><span class="p">);</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;&quot;</span><span class="p">);</span>
<span class="p">}</span>
<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">IMU</span><span class="p">.</span><span class="n">getGyroData</span><span class="p">(</span><span class="o">&amp;</span><span class="n">gyroX</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">gyroY</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">gyroZ</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">IMU</span><span class="p">.</span><span class="n">getAccelData</span><span class="p">(</span><span class="o">&amp;</span><span class="n">ax</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">ay</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">az</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setCursor</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">2</span><span class="p">);</span>

  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;aX :%7.2f  </span><span class="se">\n</span><span class="s">aY :%7.2f  </span><span class="se">\n</span><span class="s">aZ :%7.2f mg  </span><span class="se">\n\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">ax</span> <span class="p">,</span> <span class="n">ay</span> <span class="p">,</span> <span class="n">az</span> <span class="p">);</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;%7.2f , %7.2f , %7.2f </span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">ax</span> <span class="p">,</span> <span class="n">ay</span> <span class="p">,</span> <span class="n">az</span><span class="p">);</span> <span class="c1">//シリアルプロッタ用の出力</span>

  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;gX :%7.2f  </span><span class="se">\n</span><span class="s">gY :%7.2f  </span><span class="se">\n</span><span class="s">gZ :%7.2f mg  &quot;</span><span class="p">,</span> <span class="n">gyroX</span> <span class="o">*</span> <span class="n">M5</span><span class="p">.</span><span class="n">IMU</span><span class="p">.</span><span class="n">gRes</span><span class="p">,</span> <span class="n">gyroY</span> <span class="o">*</span> <span class="n">M5</span><span class="p">.</span><span class="n">IMU</span><span class="p">.</span><span class="n">gRes</span><span class="p">,</span> <span class="n">gyroZ</span> <span class="o">*</span> <span class="n">M5</span><span class="p">.</span><span class="n">IMU</span><span class="p">.</span><span class="n">gRes</span><span class="p">);</span>
  <span class="c1">// Serial.printf(&quot;%7.2f,%7.2f,%7.2f,&quot;, gyroX * M5.IMU.gRes, gyroY * M5.IMU.gRes, gyroZ * M5.IMU.gRes);</span>

  <span class="nf">delay</span><span class="p">(</span><span class="mi">50</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
<div class="section" id="infrared">
<h2>赤外(InfraRed)リモコン<a class="headerlink" href="#infrared" title="このヘッドラインへのパーマリンク">¶</a></h2>
<div class="section" id="id14">
<h3>信号の読み取り<a class="headerlink" href="#id14" title="このヘッドラインへのパーマリンク">¶</a></h3>
<p>赤外線リモコン受信モジュールが必要です。ここでは、<a class="reference external" href="https://akizukidenshi.com/catalog/g/gI-06487">GP1UXC41QS</a> を前提に、話をすすめます。</p>
<p>また、準備として、ライブラリマネージャにて、IRremoteESP8266 をインストールします。ちなみに、テストしたバージョンは2.7.15でした。</p>
<div class="admonition note">
<p class="first admonition-title">注釈</p>
<p class="last">ライブラリマネージャは、「スケッチ」→「ライブラリをインクルード」→「ライブラリを管理…」で、ひらきます。</p>
</div>
<p>ファイルメニュー → スケッチ例 → IRremoteESP8266 → IRrecvDumpV2 を選択します。</p>
<p>ブレッドボードに、以下の図のように配線します。Pとかいてある面が、受光器が出っ張っている面だとおもってください。47Ωの抵抗を、5Vとの間に入れます。
赤外線リモコン受信モジュールに接続したピンを <code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">uint16_t</span> <span class="pre">kRecvPin</span> <span class="pre">=</span> <span class="pre">36;</span></code> として設定します。
受光器にリモコンを向けて、ボタンを押すと、シリアルモニタに情報が表示されます。ここでは、Protocol : NEC , Code 0x2FD48B7 (32 Bits) と表示されたとします。この数値(uint32_t)を覚えておきます。</p>
<div class="figure">
<a class="reference internal image-reference" href="_images/ir_sensor_47owm.png"><img alt="_images/ir_sensor_47owm.png" src="_images/ir_sensor_47owm.png" style="width: 291.59999999999997px; height: 590.4px;" /></a>
</div>
</div>
<div class="section" id="id15">
<h3>信号の送信<a class="headerlink" href="#id15" title="このヘッドラインへのパーマリンク">¶</a></h3>
<p>内蔵の赤外LEDを用いて、信号を送信する例を <a class="reference internal" href="#irsend01"><span class="std std-numref">リスト 12</span></a> に示します。
内蔵の赤外LED光はあまり強くないため、50cm程度まで近づかないと反応しない場合があります。
単体の赤外LEDを接続して用いると、距離を伸ばすことができます。</p>
<p>なお、NECフォーマットではない赤外線リモコンの通信フォーマットについては、 <a class="reference external" href="http://elm-chan.org/docs/ir_format.html">赤外線リモコンの通信フォーマット</a> や、スケッチ例を参考にしてください。</p>
<div class="literal-block-wrapper docutils container" id="irsend01">
<div class="code-block-caption"><span class="caption-number">リスト 12 </span><span class="caption-text">src/irsend01.ino</span><a class="headerlink" href="#irsend01" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">&lt;IRremoteESP8266.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;IRsend.h&gt;</span><span class="cp"></span>

<span class="kr">uint16_t</span> <span class="n">kIrLed</span> <span class="o">=</span> <span class="mi">9</span><span class="p">;</span> <span class="c1">// 内蔵IrLED</span>
<span class="n">IRsend</span> <span class="nf">irsend</span><span class="p">(</span><span class="n">kIrLed</span><span class="p">);</span>

<span class="kr">uint32_t</span> <span class="n">code</span> <span class="o">=</span> <span class="mh">0x2FD48B7</span><span class="p">;</span> <span class="c1">// Toshiba TV Power</span>
<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">irsend</span><span class="p">.</span><span class="nf">begin</span><span class="p">();</span>
<span class="p">}</span>

<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">irsend</span><span class="p">.</span><span class="n">sendNEC</span><span class="p">(</span> <span class="n">code</span> <span class="p">,</span> <span class="mi">32</span><span class="p">);</span>
  <span class="nf">delay</span><span class="p">(</span><span class="mi">5000</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
</div>
<div class="section" id="tft-esprite">
<h2>スプライト表示(TFT_eSprite クラス)<a class="headerlink" href="#tft-esprite" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>M5.Lcd ではじまる画面描画命令は、表示されている画面に対して、直接描画するため、画面のちらつきが生じることがあります。
TFT_eSprite クラスを用いると、画面に表示されていない仮想画面(オフスクリーン)を作成して、そこに対して描画を行っておき、さいごにまとめて仮想画面の内容をメインの画面(Lcd)に描画することができます。
これにより、画面のちらつきが抑制できます(ダブルバッファリング)。
ちらつき防止のほかに、なめらかに画面スクロールする目的で、実画面よりも大きい仮想画面を作成しておき、その一部の領域のみを実画面に描画するといった用途にも使われます。</p>
<p>TFT_eSprite クラスは、Lcdクラスとほぼ同様の描画関数を備えています。<a class="reference internal" href="#sprite01"><span class="std std-numref">リスト 13</span></a> は、スプライトの効果あり/なしを確認できるサンプルプログラムです。</p>
<div class="literal-block-wrapper docutils container" id="sprite01">
<div class="code-block-caption"><span class="caption-number">リスト 13 </span><span class="caption-text">src/sprite01.ino</span><a class="headerlink" href="#sprite01" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">&lt;M5StickCPlus.h&gt;</span><span class="cp"></span>

<span class="kr">int</span> <span class="n">USE_SPRITE</span> <span class="o">=</span> <span class="mi">0</span> <span class="p">;</span> <span class="c1">//スプライトを使用するとき1</span>

<span class="n">TFT_eSprite</span> <span class="n">spu</span> <span class="o">=</span> <span class="n">TFT_eSprite</span><span class="p">(</span><span class="o">&amp;</span><span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">);</span> <span class="c1">// Sprite object</span>

<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">M5</span><span class="p">.</span><span class="nf">begin</span><span class="p">();</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">setRotation</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>

  <span class="n">spu</span><span class="p">.</span><span class="n">setColorDepth</span><span class="p">(</span><span class="mi">8</span><span class="p">);</span>
  <span class="n">spu</span><span class="p">.</span><span class="n">createSprite</span><span class="p">(</span><span class="mi">240</span><span class="p">,</span> <span class="mi">135</span><span class="p">);</span>

  <span class="nf">randomSeed</span><span class="p">(</span><span class="nf">analogRead</span><span class="p">(</span><span class="mi">0</span><span class="p">));</span>
<span class="p">}</span>

<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
  <span class="kr">int</span> <span class="n">r</span> <span class="o">=</span> <span class="nf">random</span><span class="p">(</span><span class="mi">100000</span><span class="p">);</span>
  <span class="k">if</span> <span class="p">(</span> <span class="n">USE_SPRITE</span> <span class="p">)</span> <span class="p">{</span>
    <span class="n">spu</span><span class="p">.</span><span class="n">fillSprite</span><span class="p">(</span> <span class="n">CYAN</span> <span class="p">);</span>
    <span class="n">spu</span><span class="p">.</span><span class="nf">setCursor</span><span class="p">(</span><span class="mi">30</span><span class="p">,</span> <span class="mi">34</span><span class="p">,</span> <span class="mi">4</span><span class="p">);</span>  <span class="n">spu</span><span class="p">.</span><span class="nf">setTextSize</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>
    <span class="n">spu</span><span class="p">.</span><span class="n">setTextColor</span><span class="p">(</span> <span class="n">WHITE</span><span class="p">,</span> <span class="n">BLUE</span> <span class="p">);</span>
    <span class="n">spu</span><span class="p">.</span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;  %d  </span><span class="se">\n</span><span class="s"> Sprite &quot;</span><span class="p">,</span> <span class="n">r</span> <span class="p">);</span>
    <span class="n">spu</span><span class="p">.</span><span class="n">pushSprite</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillScreen</span><span class="p">(</span> <span class="n">CYAN</span> <span class="p">);</span>
    <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setCursor</span><span class="p">(</span><span class="mi">30</span><span class="p">,</span> <span class="mi">34</span><span class="p">,</span> <span class="mi">4</span><span class="p">);</span>  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setTextSize</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>
    <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">setTextColor</span><span class="p">(</span> <span class="n">WHITE</span><span class="p">,</span> <span class="n">BLUE</span> <span class="p">);</span>
    <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;  %d  </span><span class="se">\n</span><span class="s"> LCD &quot;</span><span class="p">,</span> <span class="n">r</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="n">M5</span><span class="p">.</span><span class="n">update</span><span class="p">();</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">M5</span><span class="p">.</span><span class="n">BtnA</span><span class="p">.</span><span class="n">wasReleased</span><span class="p">())</span> <span class="p">{</span>
    <span class="n">USE_SPRITE</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">-</span> <span class="n">USE_SPRITE</span> <span class="p">;</span> <span class="c1">// スプライト使用の切り替え(1なら0、0なら1)</span>
    <span class="n">M5</span><span class="p">.</span><span class="n">Beep</span><span class="p">.</span><span class="nf">tone</span><span class="p">(</span><span class="mi">1000</span> <span class="o">+</span> <span class="mi">1000</span> <span class="o">*</span> <span class="n">USE_SPRITE</span><span class="p">,</span> <span class="mi">500</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Beep</span><span class="p">.</span><span class="n">update</span><span class="p">();</span>
  <span class="nf">delay</span><span class="p">(</span><span class="mi">100</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
<div class="section" id="wifi">
<h2>Wifi 接続<a class="headerlink" href="#wifi" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p><a class="reference internal" href="#wifi01"><span class="std std-numref">リスト 14</span></a> は、Wifi接続のサンプルです。<code class="docutils literal notranslate"><span class="pre">ssid</span></code> と <code class="docutils literal notranslate"><span class="pre">password</span></code> には、環境にあわせたものを入力してください。接続すると、m5デバイスのIPアドレスを画面に表示します。本当にWifi接続できたかどうかを、PCのターミナルからpingを打つなどして、確認してみましょう。(Windowsの場合、コマンドプロンプトをひらき、ping のあとに、半角スペースと、確認したいIPアドレスを入れます)</p>
<div class="literal-block-wrapper docutils container" id="wifi01">
<div class="code-block-caption"><span class="caption-number">リスト 14 </span><span class="caption-text">src/wifi01.ino</span><a class="headerlink" href="#wifi01" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">&lt;M5StickCPlus.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;WiFi.h&gt;</span><span class="cp"></span>

<span class="hll"><span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">ssid</span> <span class="o">=</span> <span class="s">&quot;**********&quot;</span><span class="p">;</span>
</span><span class="hll"><span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">password</span> <span class="o">=</span> <span class="s">&quot;**********&quot;</span><span class="p">;</span>
</span>
<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">M5</span><span class="p">.</span><span class="nf">begin</span><span class="p">();</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">setRotation</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillScreen</span><span class="p">(</span><span class="n">ORANGE</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setCursor</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">50</span><span class="p">,</span> <span class="mi">4</span><span class="p">);</span>

<span class="hll">  <span class="nf">WiFi</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="n">ssid</span><span class="p">,</span> <span class="n">password</span><span class="p">);</span> <span class="c1">// 接続開始</span>
</span><span class="hll">  <span class="k">while</span> <span class="p">(</span><span class="nf">WiFi</span><span class="p">.</span><span class="n">status</span><span class="p">()</span> <span class="o">!=</span> <span class="n">WL_CONNECTED</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 接続中...</span>
</span><span class="hll">    <span class="n">M5</span><span class="p">.</span><span class="n">Beep</span><span class="p">.</span><span class="nf">tone</span><span class="p">(</span><span class="mi">2000</span><span class="p">);</span>  <span class="nf">delay</span><span class="p">(</span><span class="mi">200</span><span class="p">);</span>
</span><span class="hll">    <span class="n">M5</span><span class="p">.</span><span class="n">Beep</span><span class="p">.</span><span class="n">mute</span><span class="p">();</span>  <span class="nf">delay</span><span class="p">(</span><span class="mi">300</span><span class="p">);</span>
</span><span class="hll">    <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;.&quot;</span><span class="p">);</span>
</span><span class="hll">  <span class="p">}</span>
</span>  <span class="c1">// 接続完了!!</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Beep</span><span class="p">.</span><span class="nf">tone</span><span class="p">(</span><span class="mi">4000</span><span class="p">);</span> 
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillScreen</span><span class="p">(</span><span class="n">GREEN</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setCursor</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">4</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">setTextColor</span><span class="p">(</span><span class="n">BLACK</span><span class="p">,</span> <span class="n">GREEN</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;  Wifi Connected!</span><span class="se">\n</span><span class="s">  &quot;</span><span class="p">);</span>
  <span class="kr">String</span> <span class="n">gotip</span> <span class="o">=</span> <span class="nf">WiFi</span><span class="p">.</span><span class="nf">localIP</span><span class="p">().</span><span class="n">toString</span><span class="p">();</span> <span class="c1">// m5デバイスのIPアドレス</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="n">gotip</span><span class="p">);</span>
  <span class="nf">delay</span><span class="p">(</span><span class="mi">1500</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Beep</span><span class="p">.</span><span class="n">mute</span><span class="p">();</span>
<span class="p">}</span>

<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
<p>Wifi接続するだけでは、あまり意味がないので、Telnetサーバを起動する例を <a class="reference internal" href="#telnet01"><span class="std std-numref">リスト 15</span></a> に示します。
シリアルモニタを開いて、IPアドレスを確認したら、ターミナル(コマンドプロンプト)で、<code class="docutils literal notranslate"><span class="pre">telnet</span> <span class="pre">IPaddr</span></code> と入力して、接続します。
telnet から文字を入力すると、シリアルモニタに表示されます。
逆に、シリアルモニタから文字を入力すると、Telnet接続しているターミナルに、文字が表示されます。
<code class="docutils literal notranslate"><span class="pre">WiFiServer</span> <span class="pre">server(23)</span></code> で、23番ポートで待ち受けるサーバを、作成しています。
ちなみに、<code class="docutils literal notranslate"><span class="pre">WiFiMulti</span></code> は、複数のアクセスポイントに対して、Wifi接続を試みることができる機能(クラス)です。ただし、最終的に繋がるのは1つのアクセスポイントになります。</p>
<div class="admonition note">
<p class="first admonition-title">注釈</p>
<p class="last">Telnet接続を切断するときは、まずControlキーをおしながら <code class="docutils literal notranslate"><span class="pre">]</span></code> をおしてください。プロンプトが <code class="docutils literal notranslate"><span class="pre">telnet&gt;</span></code> と表示されますので、<code class="docutils literal notranslate"><span class="pre">quit</span></code> と打ち込むと終了します。 <code class="docutils literal notranslate"><span class="pre">Escape</span> <span class="pre">character</span> <span class="pre">is</span> <span class="pre">'^]'.</span></code> の <code class="docutils literal notranslate"><span class="pre">^</span></code> は、Controlキーのことです。</p>
</div>
<div class="literal-block-wrapper docutils container" id="telnet01">
<div class="code-block-caption"><span class="caption-number">リスト 15 </span><span class="caption-text">src/telnet01.ino</span><a class="headerlink" href="#telnet01" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1">// オリジナルのWifiTelnetToSerial を、改変しました。</span>
<span class="cm">/*</span>
<span class="cm">  WiFiTelnetToSerial - Example Transparent UART to Telnet Server for ESP32</span>

<span class="cm">  Copyright (c) 2017 Hristo Gochkov. All rights reserved.</span>
<span class="cm">  This file is part of the ESP32 WiFi library for Arduino environment.</span>

<span class="cm">  This library is free software; you can redistribute it and/or</span>
<span class="cm">  modify it under the terms of the GNU Lesser General Public</span>
<span class="cm">  License as published by the Free Software Foundation; either</span>
<span class="cm">  version 2.1 of the License, or (at your option) any later version.</span>

<span class="cm">  This library is distributed in the hope that it will be useful,</span>
<span class="cm">  but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<span class="cm">  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU</span>
<span class="cm">  Lesser General Public License for more details.</span>

<span class="cm">  You should have received a copy of the GNU Lesser General Public</span>
<span class="cm">  License along with this library; if not, write to the Free Software</span>
<span class="cm">  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA</span>
<span class="cm">*/</span>
<span class="cp">#include</span> <span class="cpf">&lt;WiFi.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;WiFiMulti.h&gt;</span><span class="cp"></span>

<span class="n">WiFiMulti</span> <span class="n">wifiMulti</span><span class="p">;</span>

<span class="c1">//how many clients should be able to telnet to this ESP32</span>
<span class="cp">#define MAX_SRV_CLIENTS 3</span>
<span class="hll"><span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">ssid</span> <span class="o">=</span> <span class="s">&quot;**********&quot;</span><span class="p">;</span>
</span><span class="hll"><span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">password</span> <span class="o">=</span> <span class="s">&quot;**********&quot;</span><span class="p">;</span>
</span>
<span class="hll"><span class="nf">WiFiServer</span> <span class="nf">server</span><span class="p">(</span><span class="mi">23</span><span class="p">);</span>
</span><span class="nf">WiFiClient</span> <span class="n">serverClients</span><span class="p">[</span><span class="n">MAX_SRV_CLIENTS</span><span class="p">];</span>

<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="mi">115200</span><span class="p">);</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">Connecting&quot;</span><span class="p">);</span>

  <span class="n">wifiMulti</span><span class="p">.</span><span class="n">addAP</span><span class="p">(</span><span class="n">ssid</span><span class="p">,</span> <span class="n">password</span><span class="p">);</span>
  <span class="c1">//  wifiMulti.addAP(&quot;ssid_from_AP_2&quot;, &quot;your_password_for_AP_2&quot;);</span>
  <span class="c1">//  wifiMulti.addAP(&quot;ssid_from_AP_3&quot;, &quot;your_password_for_AP_3&quot;);</span>

  <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;Connecting Wifi &quot;</span><span class="p">);</span>
  <span class="k">for</span> <span class="p">(</span><span class="kr">int</span> <span class="n">loops</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span> <span class="n">loops</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">;</span> <span class="n">loops</span><span class="o">--</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">wifiMulti</span><span class="p">.</span><span class="nf">run</span><span class="p">()</span> <span class="o">==</span> <span class="n">WL_CONNECTED</span><span class="p">)</span> <span class="p">{</span>
      <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;&quot;</span><span class="p">);</span>
      <span class="nf">Serial</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;WiFi connected &quot;</span><span class="p">);</span>
      <span class="nf">Serial</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;IP address: &quot;</span><span class="p">);</span>
      <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="nf">WiFi</span><span class="p">.</span><span class="nf">localIP</span><span class="p">());</span>
      <span class="k">break</span><span class="p">;</span>
    <span class="p">}</span>
    <span class="k">else</span> <span class="p">{</span>
      <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="n">loops</span><span class="p">);</span>
      <span class="nf">delay</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">}</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">wifiMulti</span><span class="p">.</span><span class="nf">run</span><span class="p">()</span> <span class="o">!=</span> <span class="n">WL_CONNECTED</span><span class="p">)</span> <span class="p">{</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;WiFi connect failed&quot;</span><span class="p">);</span>
    <span class="nf">delay</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span>
    <span class="n">ESP</span><span class="p">.</span><span class="n">restart</span><span class="p">();</span>
  <span class="p">}</span>

  <span class="c1">//start UART and the server</span>
  <span class="c1">//  Serial2.begin(9600);</span>
  <span class="n">server</span><span class="p">.</span><span class="nf">begin</span><span class="p">();</span>
  <span class="n">server</span><span class="p">.</span><span class="n">setNoDelay</span><span class="p">(</span><span class="kr">true</span><span class="p">);</span>

  <span class="nf">Serial</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;Ready! Use &#39;telnet &quot;</span><span class="p">);</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="nf">WiFi</span><span class="p">.</span><span class="nf">localIP</span><span class="p">());</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot; 23&#39; to connect&quot;</span><span class="p">);</span>
<span class="p">}</span>

<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
  <span class="kr">uint8_t</span> <span class="n">i</span><span class="p">;</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">wifiMulti</span><span class="p">.</span><span class="nf">run</span><span class="p">()</span> <span class="o">==</span> <span class="n">WL_CONNECTED</span><span class="p">)</span> <span class="p">{</span>
    <span class="c1">//check if there are any new clients</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">server</span><span class="p">.</span><span class="n">hasClient</span><span class="p">())</span> <span class="p">{</span>
      <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">MAX_SRV_CLIENTS</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">//find free/disconnected spot</span>
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">serverClients</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">||</span> <span class="o">!</span><span class="n">serverClients</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">connected</span><span class="p">())</span> <span class="p">{</span>
          <span class="k">if</span> <span class="p">(</span><span class="n">serverClients</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="n">serverClients</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">stop</span><span class="p">();</span>
          <span class="n">serverClients</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">server</span><span class="p">.</span><span class="nf">available</span><span class="p">();</span>
          <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">serverClients</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;available broken&quot;</span><span class="p">);</span>
          <span class="nf">Serial</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;New client: &quot;</span><span class="p">);</span>
          <span class="nf">Serial</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="n">i</span><span class="p">);</span> <span class="nf">Serial</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="sc">&#39; &#39;</span><span class="p">);</span>
          <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="n">serverClients</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">remoteIP</span><span class="p">());</span>
          <span class="k">break</span><span class="p">;</span>
        <span class="p">}</span>
      <span class="p">}</span>
      <span class="k">if</span> <span class="p">(</span><span class="n">i</span> <span class="o">&gt;=</span> <span class="n">MAX_SRV_CLIENTS</span><span class="p">)</span> <span class="p">{</span>
        <span class="c1">//no free/disconnected spot so reject</span>
        <span class="n">server</span><span class="p">.</span><span class="nf">available</span><span class="p">().</span><span class="nf">stop</span><span class="p">();</span>
      <span class="p">}</span>
    <span class="p">}</span>
    <span class="c1">//check clients for data</span>
    <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">MAX_SRV_CLIENTS</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
      <span class="k">if</span> <span class="p">(</span><span class="n">serverClients</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="n">serverClients</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">connected</span><span class="p">())</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">serverClients</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">available</span><span class="p">())</span> <span class="p">{</span>
          <span class="c1">//get data from the telnet client and push it to the UART</span>
          <span class="k">while</span> <span class="p">(</span><span class="n">serverClients</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">available</span><span class="p">())</span> <span class="nf">Serial</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="n">serverClients</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">read</span><span class="p">());</span>
        <span class="p">}</span>
      <span class="p">}</span>
      <span class="k">else</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">serverClients</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="p">{</span>
          <span class="n">serverClients</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">stop</span><span class="p">();</span>
        <span class="p">}</span>
      <span class="p">}</span>
    <span class="p">}</span>
    <span class="c1">//check ==UART== =&gt; Serial for data</span>
    <span class="k">if</span> <span class="p">(</span><span class="nf">Serial</span><span class="p">.</span><span class="nf">available</span><span class="p">())</span> <span class="p">{</span>
      <span class="kt">size_t</span> <span class="n">len</span> <span class="o">=</span> <span class="nf">Serial</span><span class="p">.</span><span class="nf">available</span><span class="p">();</span>
      <span class="kr">uint8_t</span> <span class="n">sbuf</span><span class="p">[</span><span class="n">len</span><span class="p">];</span>
      <span class="nf">Serial</span><span class="p">.</span><span class="nf">readBytes</span><span class="p">(</span><span class="n">sbuf</span><span class="p">,</span> <span class="n">len</span><span class="p">);</span>
      <span class="c1">//push UART data to all connected telnet clients</span>
      <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">MAX_SRV_CLIENTS</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">serverClients</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="n">serverClients</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">connected</span><span class="p">())</span> <span class="p">{</span>
          <span class="n">serverClients</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">write</span><span class="p">(</span><span class="n">sbuf</span><span class="p">,</span> <span class="n">len</span><span class="p">);</span>
          <span class="nf">delay</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
        <span class="p">}</span>
      <span class="p">}</span>
    <span class="p">}</span>
  <span class="p">}</span>
  <span class="k">else</span> <span class="p">{</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;WiFi not connected!&quot;</span><span class="p">);</span>
    <span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">MAX_SRV_CLIENTS</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
      <span class="k">if</span> <span class="p">(</span><span class="n">serverClients</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="n">serverClients</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="nf">stop</span><span class="p">();</span>
    <span class="p">}</span>
    <span class="nf">delay</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
<div class="section" id="ntp-network-time-protocol">
<h2>NTPサーバ (Network Time Protocol) と時刻の取得<a class="headerlink" href="#ntp-network-time-protocol" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>M5StickCPlusには、システム時間(localTime)と、RTC(リアルタイムクロック:時計の機能を備えたICのこと)の2種類の時計があります。システム時間は、システムリセット(再起動)のたびに、時刻もリセットされますが、後者のRTCはリセットされません。</p>
<p><a class="reference internal" href="#ntp01"><span class="std std-numref">リスト 16</span></a> に、NTPサーバを使ってシステム時間の修正をしたのち、システム時間を1秒ごとに取得して、シリアルモニタに表示する例を示します。こちらは、M5のライブラリは不要です。configTime()でNTPサーバを設定しておくと、1時間に1回、NTPサーバに接続して、時刻修正します。</p>
<div class="literal-block-wrapper docutils container" id="ntp01">
<div class="code-block-caption"><span class="caption-number">リスト 16 </span><span class="caption-text">src/ntp01.ino</span><a class="headerlink" href="#ntp01" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">&lt;WiFi.h&gt;</span><span class="cp"></span>

<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">ssid</span> <span class="o">=</span> <span class="s">&quot;**********&quot;</span><span class="p">;</span>
<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">password</span> <span class="o">=</span> <span class="s">&quot;**********&quot;</span><span class="p">;</span>

<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="mi">115200</span><span class="p">);</span>
  <span class="nf">WiFi</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="n">ssid</span><span class="p">,</span> <span class="n">password</span><span class="p">);</span>
  <span class="k">while</span> <span class="p">(</span><span class="nf">WiFi</span><span class="p">.</span><span class="n">status</span><span class="p">()</span> <span class="o">!=</span> <span class="n">WL_CONNECTED</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 接続中...</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;.&quot;</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="kr">char</span><span class="o">*</span> <span class="n">ntpserver</span> <span class="o">=</span> <span class="s">&quot;10.64.7.184&quot;</span><span class="p">;</span> <span class="c1">// 学外なら、たとえば &quot;ntp.nict.jp&quot;</span>
<span class="hll">  <span class="n">configTime</span><span class="p">(</span><span class="mi">9</span> <span class="o">*</span> <span class="mi">3600</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">ntpserver</span><span class="p">);</span><span class="c1">//GMTとの時差(秒), サマータイムで進める時間(秒)</span>
</span><span class="p">}</span>

<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
  <span class="kr">struct</span> <span class="n">tm</span> <span class="n">localTime</span><span class="p">;</span>
  <span class="kr">char</span> <span class="n">buf</span><span class="p">[</span><span class="mi">30</span><span class="p">];</span>
  <span class="n">getLocalTime</span><span class="p">(</span><span class="o">&amp;</span><span class="n">localTime</span><span class="p">);</span>
  <span class="n">sprintf</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="s">&quot;&gt;&gt; %04d/%02d/%02d  %02d:%02d:%02d&quot;</span><span class="p">,</span>
          <span class="n">localTime</span><span class="p">.</span><span class="n">tm_year</span> <span class="o">+</span> <span class="mi">1900</span><span class="p">,</span>
          <span class="n">localTime</span><span class="p">.</span><span class="n">tm_mon</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span>
          <span class="n">localTime</span><span class="p">.</span><span class="n">tm_mday</span><span class="p">,</span>
          <span class="n">localTime</span><span class="p">.</span><span class="n">tm_hour</span><span class="p">,</span>
          <span class="n">localTime</span><span class="p">.</span><span class="n">tm_min</span><span class="p">,</span>
          <span class="n">localTime</span><span class="p">.</span><span class="n">tm_sec</span>
         <span class="p">);</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span>
  <span class="nf">delay</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
<div class="admonition warning">
<p class="first admonition-title">警告</p>
<p class="last">configTime() を行わない状況で、システム時間(localTime)を取得しようとすると、取得に数秒ほど時間がかかります。</p>
</div>
<p><a class="reference internal" href="#rtc01"><span class="std std-numref">リスト 17</span></a> は、RTCの時刻を表示するサンプルです。なお、5行目で <code class="docutils literal notranslate"><span class="pre">USE_NTP</span></code> に 1 が設定してあれば、RTCに時刻を設定します。常時Wifiネットワークに接続できない場合は、RTCを利用することが望ましいです。</p>
<div class="literal-block-wrapper docutils container" id="rtc01">
<div class="code-block-caption"><span class="caption-number">リスト 17 </span><span class="caption-text">src/rtc01.ino</span><a class="headerlink" href="#rtc01" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">&lt;M5StickCPlus.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;WiFi.h&gt;</span><span class="cp"></span>
<span class="c1">// #include &quot;time.h&quot;</span>

<span class="hll"><span class="cp">#define USE_NTP 0   </span><span class="c1">// NTPからRTCに時刻設定するなら1</span>
</span>
<span class="kr">void</span> <span class="nf">setRTCfromLT</span><span class="p">(</span><span class="kr">struct</span> <span class="n">tm</span> <span class="n">lt</span><span class="p">)</span> <span class="p">{</span>
  <span class="n">RTC_DateTypeDef</span> <span class="n">DateStruct</span><span class="p">;</span>
  <span class="n">DateStruct</span><span class="p">.</span><span class="n">Year</span> <span class="o">=</span> <span class="n">lt</span><span class="p">.</span><span class="n">tm_year</span> <span class="o">+</span> <span class="mi">1900</span><span class="p">;</span>
  <span class="n">DateStruct</span><span class="p">.</span><span class="n">Month</span> <span class="o">=</span> <span class="n">lt</span><span class="p">.</span><span class="n">tm_mon</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
  <span class="n">DateStruct</span><span class="p">.</span><span class="n">Date</span> <span class="o">=</span> <span class="n">lt</span><span class="p">.</span><span class="n">tm_mday</span><span class="p">;</span>
  <span class="n">DateStruct</span><span class="p">.</span><span class="n">WeekDay</span> <span class="o">=</span> <span class="n">lt</span><span class="p">.</span><span class="n">tm_wday</span><span class="p">;</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Rtc</span><span class="p">.</span><span class="n">SetData</span><span class="p">(</span><span class="o">&amp;</span><span class="n">DateStruct</span><span class="p">);</span>

  <span class="n">RTC_TimeTypeDef</span> <span class="n">TimeStruct</span><span class="p">;</span>
  <span class="n">TimeStruct</span><span class="p">.</span><span class="n">Hours</span>   <span class="o">=</span> <span class="n">lt</span><span class="p">.</span><span class="n">tm_hour</span><span class="p">;</span>
  <span class="n">TimeStruct</span><span class="p">.</span><span class="n">Minutes</span> <span class="o">=</span> <span class="n">lt</span><span class="p">.</span><span class="n">tm_min</span><span class="p">;</span>
  <span class="n">TimeStruct</span><span class="p">.</span><span class="n">Seconds</span> <span class="o">=</span> <span class="n">lt</span><span class="p">.</span><span class="n">tm_sec</span><span class="o">+</span><span class="mi">1</span><span class="p">;</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Rtc</span><span class="p">.</span><span class="n">SetTime</span><span class="p">(</span><span class="o">&amp;</span><span class="n">TimeStruct</span><span class="p">);</span>
<span class="p">}</span>

<span class="kr">void</span> <span class="nf">getRTC</span><span class="p">(</span><span class="kr">char</span><span class="o">*</span> <span class="n">buf</span><span class="p">)</span> <span class="p">{</span>
  <span class="n">RTC_DateTypeDef</span> <span class="n">DateStruct</span><span class="p">;</span>
  <span class="n">RTC_TimeTypeDef</span> <span class="n">TimeStruct</span><span class="p">;</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Rtc</span><span class="p">.</span><span class="n">GetData</span><span class="p">(</span><span class="o">&amp;</span><span class="n">DateStruct</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Rtc</span><span class="p">.</span><span class="n">GetTime</span><span class="p">(</span><span class="o">&amp;</span><span class="n">TimeStruct</span><span class="p">);</span>
  <span class="n">sprintf</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="s">&quot;%04d/%02d/%02d %02d:%02d:%02d&quot;</span><span class="p">,</span>
          <span class="n">DateStruct</span><span class="p">.</span><span class="n">Year</span><span class="p">,</span>  <span class="n">DateStruct</span><span class="p">.</span><span class="n">Month</span><span class="p">,</span>   <span class="n">DateStruct</span><span class="p">.</span><span class="n">Date</span><span class="p">,</span>
          <span class="n">TimeStruct</span><span class="p">.</span><span class="n">Hours</span><span class="p">,</span> <span class="n">TimeStruct</span><span class="p">.</span><span class="n">Minutes</span><span class="p">,</span> <span class="n">TimeStruct</span><span class="p">.</span><span class="n">Seconds</span>
         <span class="p">);</span>
<span class="p">}</span>

<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">M5</span><span class="p">.</span><span class="nf">begin</span><span class="p">();</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">setRotation</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="mi">115200</span><span class="p">);</span>

  <span class="k">if</span> <span class="p">(</span><span class="n">USE_NTP</span><span class="p">)</span> <span class="p">{</span>
    <span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">ssid</span> <span class="o">=</span> <span class="s">&quot;**********&quot;</span><span class="p">;</span>
    <span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">password</span> <span class="o">=</span> <span class="s">&quot;**********&quot;</span><span class="p">;</span>
    <span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">ntpserver</span> <span class="o">=</span> <span class="s">&quot;10.64.7.184&quot;</span><span class="p">;</span> <span class="c1">// &quot;ntp.nict.jp&quot;</span>
    <span class="nf">WiFi</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="n">ssid</span><span class="p">,</span> <span class="n">password</span><span class="p">);</span>
    <span class="k">while</span> <span class="p">(</span><span class="nf">WiFi</span><span class="p">.</span><span class="n">status</span><span class="p">()</span> <span class="o">!=</span> <span class="n">WL_CONNECTED</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 接続中...</span>
      <span class="nf">Serial</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;.&quot;</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="n">configTime</span><span class="p">(</span><span class="mi">9</span> <span class="o">*</span> <span class="mi">3600</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">ntpserver</span><span class="p">);</span>

    <span class="kr">struct</span> <span class="n">tm</span> <span class="n">localTime</span><span class="p">;</span>
    <span class="k">while</span> <span class="p">(</span><span class="n">localTime</span><span class="p">.</span><span class="n">tm_year</span> <span class="o">&lt;</span> <span class="mi">80</span><span class="p">)</span> <span class="p">{</span>
      <span class="n">getLocalTime</span><span class="p">(</span><span class="o">&amp;</span><span class="n">localTime</span><span class="p">);</span> <span class="nf">delay</span><span class="p">(</span><span class="mi">50</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="n">setRTCfromLT</span><span class="p">(</span><span class="n">localTime</span><span class="p">);</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
  <span class="kr">char</span> <span class="n">buf</span><span class="p">[</span><span class="mi">30</span><span class="p">];</span>
  <span class="n">getRTC</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span> <span class="c1">// bufに、日時文字列を書き込む</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillScreen</span><span class="p">(</span><span class="n">BLUE</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setCursor</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">50</span><span class="p">,</span> <span class="mi">4</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span>
  <span class="nf">delay</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
<div class="admonition note">
<p class="first admonition-title">注釈</p>
<p class="last">RTCに一旦時刻を設定しておくと、初期状態で書き込まれているプログラムFactoryTest の「BMP8563 RTC Time」でも、その時刻が表示されるようになります。</p>
</div>
</div>
<div class="section" id="webclient">
<h2>WebClient<a class="headerlink" href="#webclient" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p><a class="reference internal" href="#httpclient01"><span class="std std-numref">リスト 18</span></a> は、HTTP通信で天気予報Web APIに接続するサンプルです。HTTPClientクラスを用いると、ブラウザでURLを指定してWebページを開くように、WebサーバにGETメソッドやPOSTメソッドでリクエストを送信して、ステータスコードやレスポンスを取得することができます。このサンプルでは、シリアルコンソールに、天気予報をJSON形式で表示します。JSON(ジェイソン)とは、Javascriptのオブジェクトの形式でデータを表現する記法です。</p>
<div class="literal-block-wrapper docutils container" id="httpclient01">
<div class="code-block-caption"><span class="caption-number">リスト 18 </span><span class="caption-text">src/httpclient01.ino</span><a class="headerlink" href="#httpclient01" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">&lt;WiFi.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;HTTPClient.h&gt;</span><span class="cp"></span>

<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">ssid</span> <span class="o">=</span> <span class="s">&quot;**********&quot;</span><span class="p">;</span>
<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">password</span> <span class="o">=</span> <span class="s">&quot;**********&quot;</span><span class="p">;</span>

<span class="c1">// 天気予報API https://weather.tsukumijima.net/ から、千葉の天気を取得 </span>
<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">weatherapi_url</span> <span class="o">=</span> <span class="s">&quot;http://weather.tsukumijima.net/api/forecast/city/120010&quot;</span><span class="p">;</span>

<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="mi">115200</span><span class="p">);</span>
  <span class="nf">WiFi</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="n">ssid</span><span class="p">,</span> <span class="n">password</span><span class="p">);</span>
  <span class="k">while</span> <span class="p">(</span><span class="nf">WiFi</span><span class="p">.</span><span class="n">status</span><span class="p">()</span> <span class="o">!=</span> <span class="n">WL_CONNECTED</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 接続中...</span>
    <span class="nf">delay</span><span class="p">(</span><span class="mi">50</span><span class="p">);</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;.&quot;</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="nf">delay</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span>
  
  <span class="n">HTTPClient</span> <span class="n">http</span><span class="p">;</span>
  <span class="n">http</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="n">weatherapi_url</span><span class="p">);</span> <span class="c1">//HTTPでサーバに接続</span>
  <span class="kr">int</span> <span class="n">httpCode</span> <span class="o">=</span> <span class="n">http</span><span class="p">.</span><span class="n">GET</span><span class="p">();</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">httpCode</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
      <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="n">httpCode</span><span class="p">);</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">httpCode</span> <span class="o">==</span> <span class="n">HTTP_CODE_OK</span><span class="p">)</span> <span class="p">{</span>
      <span class="kr">String</span> <span class="n">payload</span> <span class="o">=</span> <span class="n">http</span><span class="p">.</span><span class="n">getString</span><span class="p">();</span>
      <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="n">payload</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">}</span>
  <span class="n">http</span><span class="p">.</span><span class="nf">end</span><span class="p">();</span>
<span class="p">}</span>

<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
<div class="admonition warning">
<p class="first admonition-title">警告</p>
<p class="last">https (SSL) 通信をする場合は、スケッチ例→HTTPClient→BasicHttpsClient を参照して、WiFiClientSecure クラスを使用してください。</p>
</div>
</div>
<div class="section" id="google-spreadsheet">
<h2>Google Spreadsheet にデータを送信する<a class="headerlink" href="#google-spreadsheet" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>HTTP通信で、サーバにデータを送信して格納したいとおもっても、適当なサーバを準備するのは手間がかかることがあります。</p>
<p>Google Apps Scriptを用いると、HTTP通信で Google Spreadsheet にデータを書き込んだり、読み取ったりするWebサービスを作成し、WebAPIとして公開することができます。</p>
<p>(Google Spreadsheetのメニューで) 拡張機能→Apps Script または、ツール→スクリプトエディタ で、<a class="reference internal" href="#doget"><span class="std std-numref">リスト 19</span></a> を「コード.gs」に書き込みます。15行目で「シート1」の一番下の行に、配列array の要素を追加します。19行目のgetRange(1,3).getValue()は、スプレッドシートのC1(3列1行)の値を取得しています。ここに「=average(C2:C200)」のようにしておくと、データの平均値を取得することもできます。</p>
<p>作成した「コード.gs」について、「公開」→「ウェブアプリケーションとして導入...」で、Webアプリとして公開できます。(なお、「新しいエディタ」では表示が異なるため、できない可能性があります。)</p>
<p>作成できたかどうかをパソコンから確認するには、コマンドラインから、以下のように入力します(ただし、curlが必要です。val1=10 と val2=20 のあいだは&記号ですので、シェルでバックグラウンド処理されないように、URLをシングルクォートで囲っています)</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">curl</span> <span class="o">-</span><span class="n">L</span>  <span class="s1">&#39;https://script.google.com/macros/s/XxXxXxXxXx/exec?val1=10&amp;val2=20&#39;</span>
</pre></div>
</div>
<div class="literal-block-wrapper docutils container" id="doget">
<div class="code-block-caption"><span class="caption-number">リスト 19 </span><span class="caption-text">src/doget.js</span><a class="headerlink" href="#doget" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-javascript notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="kd">function</span> <span class="nx">doGet</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
  <span class="kd">var</span> <span class="nx">spreadsheet</span> <span class="o">=</span> <span class="nx">SpreadsheetApp</span><span class="p">.</span><span class="nx">getActiveSpreadsheet</span><span class="p">();</span>
  <span class="kd">var</span> <span class="nx">sheet</span> <span class="o">=</span> <span class="nx">spreadsheet</span><span class="p">.</span><span class="nx">getSheetByName</span><span class="p">(</span><span class="s1">&#39;シート1&#39;</span><span class="p">);</span>
  <span class="kd">var</span> <span class="nx">now</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Date</span><span class="p">();</span>
  <span class="kd">var</span> <span class="nx">array</span> <span class="o">=</span> <span class="p">[];</span>
  <span class="nx">array</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">now</span><span class="p">);</span>
  
  <span class="k">for</span><span class="p">(</span><span class="kd">var</span> <span class="nx">k</span> <span class="k">in</span> <span class="nx">e</span><span class="p">[</span><span class="s1">&#39;parameter&#39;</span><span class="p">])</span> <span class="p">{</span>
    <span class="nx">array</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">k</span><span class="p">);</span>
    <span class="nx">array</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">e</span><span class="p">[</span><span class="s1">&#39;parameter&#39;</span><span class="p">][</span><span class="nx">k</span><span class="p">]);</span>
  <span class="p">}</span>
  <span class="kd">var</span> <span class="nx">params</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">e</span><span class="p">);</span>
  <span class="nx">array</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">params</span><span class="p">);</span>
<span class="hll">  <span class="nx">sheet</span><span class="p">.</span><span class="nx">appendRow</span><span class="p">(</span> <span class="nx">array</span> <span class="p">);</span>
</span>  
  <span class="kd">var</span> <span class="nx">lastRow</span> <span class="o">=</span> <span class="nx">sheet</span><span class="p">.</span><span class="nx">getLastRow</span><span class="p">();</span>

  <span class="kd">var</span> <span class="nx">output</span> <span class="o">=</span> <span class="nx">ContentService</span><span class="p">.</span><span class="nx">createTextOutput</span><span class="p">(</span><span class="nx">sheet</span><span class="p">.</span><span class="nx">getRange</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">3</span><span class="p">).</span><span class="nx">getValue</span><span class="p">()</span><span class="o">+</span><span class="s2">&quot; &quot;</span><span class="o">+</span><span class="nx">lastRow</span><span class="p">);</span>
  <span class="nx">output</span><span class="p">.</span><span class="nx">setMimeType</span><span class="p">(</span><span class="nx">ContentService</span><span class="p">.</span><span class="nx">MimeType</span><span class="p">.</span><span class="nx">TEXT</span><span class="p">);</span>
  <span class="k">return</span> <span class="nx">output</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
<div class="section" id="webserver">
<h2>WebServer<a class="headerlink" href="#webserver" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>すこし長いですが、<a class="reference internal" href="#httpserver01"><span class="std std-numref">リスト 20</span></a> は、80番ポートでHTTPでの通信を待ち受け(listenし)て、クライアントからの接続情報(ヘッダ情報)を返すWebサーバのシンプルな例です。クライアント(ブラウザ)からのリクエスト行のうち、 <code class="docutils literal notranslate"><span class="pre">GET</span></code> または <code class="docutils literal notranslate"><span class="pre">POST</span></code> ではじまる行があれば、変数 <code class="docutils literal notranslate"><span class="pre">meth</span></code> に格納します。つまり、変数 <code class="docutils literal notranslate"><span class="pre">meth</span></code> には、ブラウザで発行したリクエストのURLが含まれることになります。POSTメソッドで送信されていれば、リクエストボディに記述されたデータを変数 <code class="docutils literal notranslate"><span class="pre">post</span></code> に格納します。 クライアント(ブラウザ)に返す「レスポンス」は、 <code class="docutils literal notranslate"><span class="pre">client.println()</span></code> で送信します。最後に、<code class="docutils literal notranslate"><span class="pre">client.stop()</span></code> で、サーバ側から接続を切断します。</p>
<div class="literal-block-wrapper docutils container" id="httpserver01">
<div class="code-block-caption"><span class="caption-number">リスト 20 </span><span class="caption-text">src/httpserver01.ino</span><a class="headerlink" href="#httpserver01" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">&lt;WiFi.h&gt;</span><span class="cp"></span>

<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">ssid</span> <span class="o">=</span> <span class="s">&quot;**********&quot;</span><span class="p">;</span>
<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">password</span> <span class="o">=</span> <span class="s">&quot;**********&quot;</span><span class="p">;</span>

<span class="nf">WiFiServer</span> <span class="nf">server</span><span class="p">(</span><span class="mi">80</span><span class="p">);</span>

<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="mi">115200</span><span class="p">);</span>
  <span class="nf">WiFi</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="n">ssid</span><span class="p">,</span> <span class="n">password</span><span class="p">);</span>
  <span class="k">while</span> <span class="p">(</span><span class="nf">WiFi</span><span class="p">.</span><span class="n">status</span><span class="p">()</span> <span class="o">!=</span> <span class="n">WL_CONNECTED</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 接続中...</span>
    <span class="nf">delay</span><span class="p">(</span><span class="mi">50</span><span class="p">);</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;.&quot;</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="kr">String</span> <span class="n">ip</span> <span class="o">=</span> <span class="nf">WiFi</span><span class="p">.</span><span class="nf">localIP</span><span class="p">().</span><span class="n">toString</span><span class="p">();</span> <span class="c1">// m5デバイスのIPアドレス</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\n</span><span class="s">open http://%s</span><span class="se">\n\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">ip</span><span class="p">.</span><span class="n">c_str</span><span class="p">()</span> <span class="p">);</span>

<span class="hll">  <span class="n">server</span><span class="p">.</span><span class="nf">begin</span><span class="p">();</span> <span class="c1">// Webサーバを開始</span>
</span><span class="p">}</span>

<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
<span class="hll">  <span class="nf">WiFiClient</span> <span class="n">client</span> <span class="o">=</span> <span class="n">server</span><span class="p">.</span><span class="nf">available</span><span class="p">();</span>
</span>  <span class="k">if</span> <span class="p">(</span><span class="n">client</span><span class="p">)</span> <span class="p">{</span>
    <span class="kr">String</span> <span class="n">req</span> <span class="o">=</span> <span class="s">&quot;&quot;</span> <span class="p">;</span>
    <span class="kr">String</span> <span class="n">tmp</span> <span class="o">=</span> <span class="s">&quot;&quot;</span> <span class="p">,</span> <span class="n">meth</span> <span class="o">=</span> <span class="s">&quot;&quot;</span> <span class="p">;</span>
<span class="hll">    <span class="k">while</span> <span class="p">(</span><span class="n">client</span><span class="p">.</span><span class="nf">connected</span><span class="p">())</span> <span class="p">{</span>            <span class="c1">// loop while the client&#39;s connected</span>
</span>      <span class="k">if</span> <span class="p">(</span><span class="n">client</span><span class="p">.</span><span class="nf">available</span><span class="p">())</span> <span class="p">{</span>             <span class="c1">// if there&#39;s bytes to read from the client,</span>
        <span class="kr">char</span> <span class="n">c</span> <span class="o">=</span> <span class="n">client</span><span class="p">.</span><span class="nf">read</span><span class="p">();</span>             <span class="c1">// read a byte, then</span>
        <span class="n">req</span> <span class="o">+=</span> <span class="n">c</span><span class="p">;</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">c</span> <span class="o">==</span> <span class="sc">&#39;\n&#39;</span><span class="p">)</span> <span class="p">{</span>                    <span class="c1">// if the byte is a newline character</span>
          <span class="k">if</span> <span class="p">(</span><span class="n">tmp</span><span class="p">.</span><span class="n">length</span><span class="p">()</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>  <span class="c1">// end of request, break while loop</span>
            <span class="k">break</span><span class="p">;</span>
          <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="c1">//まだ継続</span>
            <span class="k">if</span> <span class="p">(</span><span class="n">tmp</span><span class="p">.</span><span class="n">startsWith</span><span class="p">(</span><span class="s">&quot;GET &quot;</span><span class="p">)</span> <span class="o">||</span> <span class="n">tmp</span><span class="p">.</span><span class="n">startsWith</span><span class="p">(</span><span class="s">&quot;POST &quot;</span><span class="p">)</span> <span class="p">)</span> <span class="p">{</span>
              <span class="n">meth</span> <span class="o">=</span> <span class="n">tmp</span><span class="p">;</span>
            <span class="p">}</span>
            <span class="n">tmp</span> <span class="o">=</span> <span class="s">&quot;&quot;</span><span class="p">;</span>
          <span class="p">}</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">c</span> <span class="o">!=</span> <span class="sc">&#39;\r&#39;</span><span class="p">)</span> <span class="p">{</span>  <span class="c1">// if you got anything else but a carriage return character,</span>
          <span class="n">tmp</span> <span class="o">+=</span> <span class="n">c</span><span class="p">;</span>      <span class="c1">// add it to the end of the currentLine</span>
        <span class="p">}</span>
      <span class="p">}</span>
<span class="hll">    <span class="p">}</span> <span class="c1">// end of while</span>
</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="n">meth</span><span class="p">);</span>
    <span class="k">if</span> <span class="p">(</span> <span class="n">meth</span><span class="p">.</span><span class="n">startsWith</span><span class="p">(</span><span class="s">&quot;GET /&quot;</span><span class="p">)</span> <span class="p">)</span> <span class="p">{</span>
      <span class="n">client</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;HTTP/1.1 200 OK&quot;</span><span class="p">);</span> <span class="c1">// header (with response code)</span>
      <span class="n">client</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;Content-Type:text/plain&quot;</span><span class="p">);</span>
      <span class="n">client</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;&quot;</span><span class="p">);</span> <span class="c1">// HTTPでは、header と body の区切りは改行</span>
      <span class="n">client</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="n">meth</span><span class="p">);</span>
      <span class="n">client</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;-- request --&quot;</span><span class="p">);</span>
      <span class="n">client</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="n">req</span><span class="p">);</span>
    <span class="p">}</span>

    <span class="k">if</span> <span class="p">(</span> <span class="n">meth</span><span class="p">.</span><span class="n">startsWith</span><span class="p">(</span><span class="s">&quot;POST &quot;</span><span class="p">)</span> <span class="p">)</span> <span class="p">{</span>
      <span class="kr">String</span> <span class="n">post</span> <span class="o">=</span> <span class="s">&quot;&quot;</span><span class="p">;</span>
      <span class="kr">char</span> <span class="n">buf</span><span class="p">[</span><span class="mi">257</span><span class="p">];</span>
      <span class="kr">int</span> <span class="n">n</span><span class="p">;</span>
      <span class="k">while</span> <span class="p">((</span><span class="n">n</span> <span class="o">=</span> <span class="n">client</span><span class="p">.</span><span class="nf">available</span><span class="p">())</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">n</span> <span class="o">&lt;</span> <span class="mi">256</span><span class="p">)</span> <span class="p">{</span>
          <span class="n">client</span><span class="p">.</span><span class="nf">readBytes</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span> <span class="p">;</span>
          <span class="n">buf</span><span class="p">[</span><span class="n">n</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span> <span class="p">;</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
          <span class="n">client</span><span class="p">.</span><span class="nf">readBytes</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span> <span class="mi">256</span><span class="p">)</span> <span class="p">;</span>
          <span class="n">buf</span><span class="p">[</span><span class="mi">256</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span> <span class="p">;</span>
        <span class="p">}</span>
      <span class="p">}</span>
      <span class="n">post</span> <span class="o">+=</span> <span class="n">buf</span> <span class="p">;</span>

      <span class="n">client</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;HTTP/1.1 200 OK&quot;</span><span class="p">);</span>
      <span class="n">client</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;Content-Type:text/plain&quot;</span><span class="p">);</span>
      <span class="n">client</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;&quot;</span><span class="p">);</span> <span class="c1">// HTTPでは、header と body の区切りは改行</span>
      <span class="n">client</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="n">meth</span><span class="p">);</span>
      <span class="n">client</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;-- request --&quot;</span><span class="p">);</span>
      <span class="n">client</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="n">req</span><span class="p">);</span>
      <span class="n">client</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;-- post data --&quot;</span><span class="p">);</span>
      <span class="n">client</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="n">post</span><span class="p">);</span>
    <span class="p">}</span>
    <span class="c1">// close the connection:</span>
<span class="hll">    <span class="n">client</span><span class="p">.</span><span class="nf">stop</span><span class="p">();</span>
</span>    <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot; --- Client Disconnected.&quot;</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="nf">delay</span><span class="p">(</span><span class="mi">100</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
<p>センサデータを返すだけなら問題ありませんが、クライアントからのデータを GET / POST で受信して処理する場合は、 <code class="docutils literal notranslate"><span class="pre">key1=val1&amp;key2=val2</span></code> のような文字列を要素に分解する必要がでてきます。あまり深入りしませんが、正規表現で文字列を照合・抽出する <code class="docutils literal notranslate"><span class="pre">Regexp</span></code> や、抽出した結果をハッシュ/辞書として保存する <code class="docutils literal notranslate"><span class="pre">Dictionary</span></code> ライブラリを導入すると、複雑なリクエストやデータを扱いやすくなるでしょう。
<a class="reference internal" href="#regexp01"><span class="std std-numref">リスト 21</span></a> に、RGBの色指定文字列などのリクエスト文字列をパースして辞書に追加するプログラムの断片を示します。<strong>注意:このプログラムは、単体では動作しません</strong></p>
<div class="literal-block-wrapper docutils container" id="regexp01">
<div class="code-block-caption"><span class="caption-number">リスト 21 </span><span class="caption-text">src/regexp01.ino</span><a class="headerlink" href="#regexp01" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">&lt;Regexp.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;Dictionary.h&gt;</span><span class="cp"></span>

<span class="n">Dictionary</span> <span class="o">*</span><span class="n">dict</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Dictionary</span><span class="p">();</span> <span class="c1">// 辞書/ハッシュ。キー文字列→値 を保持するデータ構造</span>

<span class="kr">void</span> <span class="nf">match_callback</span>  <span class="p">(</span><span class="kr">const</span> <span class="kr">char</span> <span class="o">*</span> <span class="n">match</span><span class="p">,</span>         <span class="o">//</span> <span class="n">matching</span> <span class="kr">string</span> <span class="p">(</span><span class="o">not</span> <span class="n">null</span><span class="o">-</span><span class="n">terminated</span><span class="p">)</span>
                      <span class="kr">const</span> <span class="kr">unsigned</span> <span class="kr">int</span> <span class="n">length</span><span class="p">,</span>  <span class="c1">// length of matching string</span>
                      <span class="kr">const</span> <span class="n">MatchState</span> <span class="o">&amp;</span> <span class="n">ms</span><span class="p">)</span>      <span class="c1">// MatchState in use (to get captures)</span>
<span class="p">{</span>
  <span class="kr">char</span> <span class="n">k</span> <span class="p">[</span><span class="mi">10</span><span class="p">];</span>   <span class="c1">// size must be large enough to hold captures</span>
  <span class="kr">char</span> <span class="n">v</span> <span class="p">[</span><span class="mi">10</span><span class="p">];</span>   <span class="c1">// size must be large enough to hold captures</span>
  <span class="n">ms</span><span class="p">.</span><span class="n">GetCapture</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
  <span class="n">ms</span><span class="p">.</span><span class="n">GetCapture</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
  <span class="n">dict</span><span class="o">-&gt;</span><span class="n">insert</span><span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">v</span><span class="p">);</span> <span class="c1">// 辞書に追加 (たとえば、 red→120 を追加)</span>
<span class="p">}</span>  <span class="c1">// end of match_callback</span>

<span class="c1">// たとえば、*cbuf = &quot;red=120&amp;green=255&amp;blue=9&quot; のような文字列を想定する</span>
<span class="kr">void</span> <span class="nf">param2dict</span><span class="p">(</span><span class="kr">char</span> <span class="o">*</span><span class="n">cbuf</span><span class="p">){</span>
      <span class="n">MatchState</span> <span class="n">ms</span> <span class="p">(</span><span class="n">cbuf</span><span class="p">);</span> <span class="c1">//正規表現マッチャーの作成</span>
      <span class="n">ms</span><span class="p">.</span><span class="n">GlobalMatch</span> <span class="p">(</span><span class="s">&quot;([a-z]+)=([0-9]+)&quot;</span><span class="p">,</span> <span class="n">match_callback</span><span class="p">);</span> <span class="c1">// (key)=(value) で複数回マッチングする。match_callback は別関数。</span>
      <span class="kr">int</span> <span class="n">r</span> <span class="o">=</span> <span class="n">dict</span><span class="o">-&gt;</span><span class="n">search</span><span class="p">(</span><span class="s">&quot;red&quot;</span><span class="p">).</span><span class="n">toInt</span><span class="p">();</span> <span class="c1">// 辞書 dict</span>
      <span class="kr">int</span> <span class="n">g</span> <span class="o">=</span> <span class="n">dict</span><span class="o">-&gt;</span><span class="n">search</span><span class="p">(</span><span class="s">&quot;green&quot;</span><span class="p">).</span><span class="n">toInt</span><span class="p">();</span>
      <span class="kr">int</span> <span class="n">b</span> <span class="o">=</span> <span class="n">dict</span><span class="o">-&gt;</span><span class="n">search</span><span class="p">(</span><span class="s">&quot;blue&quot;</span><span class="p">).</span><span class="n">toInt</span><span class="p">();</span>
      <span class="kr">int32_t</span> <span class="n">bgcolor</span> <span class="o">=</span> <span class="p">(</span><span class="kr">int</span><span class="p">(</span><span class="n">r</span> <span class="o">*</span> <span class="mi">31</span> <span class="o">/</span> <span class="mi">255</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="mi">11</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="kr">int</span><span class="p">(</span><span class="n">g</span> <span class="o">*</span> <span class="mi">63</span> <span class="o">/</span> <span class="mi">255</span><span class="p">)</span> <span class="o">&lt;&lt;</span> <span class="mi">5</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="kr">int</span><span class="p">(</span><span class="n">b</span> <span class="o">*</span> <span class="mi">31</span> <span class="o">/</span> <span class="mi">255</span><span class="p">));</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
<div class="section" id="mqtt">
<h2>MQTT<a class="headerlink" href="#mqtt" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>MQTT(Message Queue Telemetry Transport) は、センサデータをデバイス間で共有・流通させるときなどに使われる、軽量のメッセージ送受信プロトコルです。
ここで、「軽量」とは、HTTPに比べて、ヘッダ部分のデータが少ない、という意味です。
MQTTでは、サーバのことを「ブローカ」と呼びます。ここでは、データを送信するPublisherと、データを受信するSubscriberの2つのデバイスと、ブローカの3つの構成要素で説明します。</p>
<p>Publisherは、ブローカに接続しデータを送信します。このとき、 <strong>「トピック」</strong> と呼ばれる、データの登録先を文字列で指定します。また、retainデータとして送信するかどうかも指定します。retainとは「保持・維持」の意味で、最後に送ったデータをブローカに残しておきたい場合、rateinデータとします。
Subscriberは、ブローカに接続し、トピックをサブスクライブ(購読)します。このとき、トピックに書き込まれているretainデータがあれば、最初にそのデータを受信します。retainデータがなければ、Publisherが新しいデータをトピックに送信したタイミングで、データを受信します。
このような通信手段(プロトコル)を、パブリッシュ/サブスクライブモデル と呼びます。<a class="reference external" href="https://tech-blog.rakus.co.jp/entry/20180912/mqtt/iot/beginner">参考サイト:
IoT初心者向け!「MQTT」について簡単にまとめてみる</a></p>
<div class="section" id="mqtt-publish">
<h3>MQTT Publish<a class="headerlink" href="#mqtt-publish" title="このヘッドラインへのパーマリンク">¶</a></h3>
<p><a class="reference internal" href="#mqtt01pub"><span class="std std-numref">リスト 22</span></a> は、MQTT Publisherのサンプルです。実験用ブローカ(mqtt.istlab.info)に接続して、 <code class="docutils literal notranslate"><span class="pre">office/temp</span></code> というトピックにデータ(シリアルコンソールで送信した文字列)を書き込みます。 <strong>パスワードはここには書けませんので、講義ポータル資料を参照してください。</strong></p>
<div class="literal-block-wrapper docutils container" id="mqtt01pub">
<div class="code-block-caption"><span class="caption-number">リスト 22 </span><span class="caption-text">src/mqtt01pub.ino</span><a class="headerlink" href="#mqtt01pub" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1">// MQTT Publisher example </span>
<span class="c1">//#include &lt;M5StickCPlus.h&gt;</span>
<span class="cp">#include</span> <span class="cpf">&lt;WiFi.h&gt;</span><span class="cp"></span>
<span class="c1">// ライブラリで PubSubClient をいれておく</span>
<span class="cp">#include</span> <span class="cpf">&lt;PubSubClient.h&gt;</span><span class="cp"></span>

<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">ssid</span> <span class="o">=</span> <span class="s">&quot;**********&quot;</span><span class="p">;</span>
<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">password</span> <span class="o">=</span> <span class="s">&quot;**********&quot;</span><span class="p">;</span>

<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">server</span> <span class="o">=</span> <span class="s">&quot;mqtt.istlab.info&quot;</span><span class="p">;</span>
<span class="kr">const</span> <span class="kr">int</span>   <span class="n">port</span>     <span class="o">=</span> <span class="mi">1883</span><span class="p">;</span>
<span class="c1">// 注:学内ネットワークからは上記ポート番号に接続できない。</span>
<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">pubTopic</span> <span class="o">=</span> <span class="s">&quot;office/temp&quot;</span><span class="p">;</span> <span class="c1">//&quot;ex1/groupXX/sensor&quot;;</span>
<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">mquser</span>   <span class="o">=</span> <span class="s">&quot;ex1&quot;</span><span class="p">;</span>
<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">mqpass</span>   <span class="o">=</span> <span class="s">&quot;***PASSWORD***&quot;</span><span class="p">;</span>
<span class="nf">WiFiClient</span> <span class="n">wifiClient</span><span class="p">;</span>
<span class="kr">char</span><span class="o">*</span> <span class="n">clientid</span> <span class="o">=</span> <span class="s">&quot;m5stickc01_00000001&quot;</span><span class="p">;</span> <span class="c1">//デバイス個別に設定すればなんでもよい</span>
<span class="n">PubSubClient</span> <span class="nf">mqttClient</span><span class="p">(</span><span class="n">wifiClient</span><span class="p">);</span> <span class="c1">// MQTT Client</span>

<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="c1">// M5.begin();</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="mi">115200</span><span class="p">);</span>
  <span class="nf">WiFi</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="n">ssid</span><span class="p">,</span> <span class="n">password</span><span class="p">);</span>
  <span class="k">while</span> <span class="p">(</span><span class="nf">WiFi</span><span class="p">.</span><span class="n">status</span><span class="p">()</span> <span class="o">!=</span> <span class="n">WL_CONNECTED</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 接続中...</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;.&quot;</span><span class="p">);</span>
    <span class="nf">delay</span><span class="p">(</span><span class="mi">200</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span> <span class="nf">WiFi</span><span class="p">.</span><span class="nf">localIP</span><span class="p">().</span><span class="n">toString</span><span class="p">()</span> <span class="p">);</span> <span class="c1">//取得したIPアドレス</span>
  <span class="c1">// 参考:WiFiデバイスのMACアドレスを取得し、clientid として用いる</span>
  <span class="c1">// (18行目のclientidの定義を変更し、char clientid[20]とするのがのぞましい)</span>
  <span class="c1">//  uint8_t mac[6];</span>
  <span class="c1">//  esp_read_mac(mac, ESP_MAC_WIFI_STA);</span>
  <span class="c1">//  sprintf(clientid, &quot;%02X:%02X:%02X:%02X:%02X:%02X&quot;,</span>
  <span class="c1">//          mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] );</span>
  <span class="n">mqttClient</span><span class="p">.</span><span class="n">setServer</span><span class="p">(</span><span class="n">server</span><span class="p">,</span> <span class="n">port</span><span class="p">);</span>

  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">mqttClient</span><span class="p">.</span><span class="nf">connected</span><span class="p">())</span> <span class="p">{</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;Try (re)connecting...&quot;</span><span class="p">);</span>
    <span class="n">reconnect</span><span class="p">();</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
  <span class="c1">// シリアルコンソールから書き込みがあれば, publishする</span>
  <span class="kr">byte</span> <span class="n">mbuf</span><span class="p">[</span><span class="mi">100</span><span class="p">];</span>  <span class="kr">int</span> <span class="n">pos</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
  <span class="k">while</span> <span class="p">(</span><span class="nf">Serial</span><span class="p">.</span><span class="nf">available</span><span class="p">())</span> <span class="p">{</span> <span class="c1">// ノンブロッキング</span>
    <span class="n">mbuf</span><span class="p">[</span><span class="n">pos</span><span class="p">]</span>  <span class="o">=</span> <span class="nf">Serial</span><span class="p">.</span><span class="nf">read</span><span class="p">();</span>
    <span class="n">pos</span><span class="o">++</span><span class="p">;</span>
  <span class="p">}</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">pos</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">mbuf</span><span class="p">[</span><span class="n">pos</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">//改行をNULLに置き換える</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">((</span><span class="kr">char</span><span class="o">*</span><span class="p">)</span><span class="n">mbuf</span><span class="p">);</span>
    <span class="c1">// ブローカにデータを送信する。最後のfalse を true にすると、retained になる。</span>
    <span class="kr">bool</span> <span class="n">ret</span> <span class="o">=</span> <span class="n">mqttClient</span><span class="p">.</span><span class="n">publish</span><span class="p">(</span><span class="n">pubTopic</span><span class="p">,</span> <span class="n">mbuf</span><span class="p">,</span> <span class="n">pos</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="kr">false</span><span class="p">);</span> 
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">ret</span><span class="p">){</span>
      <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;publish failed.&quot;</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">}</span>
  <span class="nf">delay</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span>
<span class="p">}</span>

<span class="kr">void</span> <span class="nf">reconnect</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">mqttClient</span><span class="p">.</span><span class="nf">connected</span><span class="p">())</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">mqttClient</span><span class="p">.</span><span class="nf">connect</span><span class="p">(</span><span class="n">clientid</span><span class="p">,</span> <span class="n">mquser</span><span class="p">,</span> <span class="n">mqpass</span><span class="p">))</span> <span class="p">{</span>
      <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;Connected to MQTT Broker.&quot;</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
      <span class="nf">Serial</span><span class="p">.</span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;Connect Failed. state=%d&quot;</span><span class="p">,</span> <span class="n">mqttClient</span><span class="p">.</span><span class="n">state</span><span class="p">());</span>
    <span class="p">}</span>
  <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
<div class="section" id="mqtt-subscribe">
<h3>MQTT Subscribe<a class="headerlink" href="#mqtt-subscribe" title="このヘッドラインへのパーマリンク">¶</a></h3>
<p><a class="reference internal" href="#mqtt01sub"><span class="std std-numref">リスト 23</span></a> は、MQTT Subscriberのサンプルです。実験用ブローカ(mqtt.istlab.info)に接続して、 <code class="docutils literal notranslate"><span class="pre">office/temp</span></code> というトピックを購読します。 <strong>パスワードはここには書けませんので、講義ポータル資料を参照してください。</strong> JSON形式のデータを処理するときは、ArduinoJsonをつかってパージング/deserialize すると便利です(78行目以降にサンプルがあります)。</p>
<div class="literal-block-wrapper docutils container" id="mqtt01sub">
<div class="code-block-caption"><span class="caption-number">リスト 23 </span><span class="caption-text">src/mqtt01sub.ino</span><a class="headerlink" href="#mqtt01sub" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="c1">// MQTT Subscriber example </span>
<span class="c1">// #include &lt;M5StickCPlus.h&gt;</span>
<span class="cp">#include</span> <span class="cpf">&lt;WiFi.h&gt;</span><span class="cp"></span>
<span class="c1">// ライブラリで PubSubClient をいれておく</span>
<span class="cp">#include</span> <span class="cpf">&lt;PubSubClient.h&gt;</span><span class="cp"></span>
<span class="c1">// ライブラリで ArduinoJson v6.xをいれておく。</span>
<span class="c1">//        (注意:Arduino_Json v0.1.0 は別物)</span>
<span class="cp">#include</span> <span class="cpf">&lt;ArduinoJson.h&gt;</span><span class="cp"></span>

<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">ssid</span> <span class="o">=</span> <span class="s">&quot;**********&quot;</span><span class="p">;</span>
<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">password</span> <span class="o">=</span> <span class="s">&quot;**********&quot;</span><span class="p">;</span>

<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">server</span> <span class="o">=</span> <span class="s">&quot;mqtt.istlab.info&quot;</span><span class="p">;</span>
<span class="kr">const</span> <span class="kr">int</span>   <span class="n">port</span>     <span class="o">=</span> <span class="mi">1883</span><span class="p">;</span>
<span class="c1">// 注:学内ネットワークからは上記ポート番号に接続できない。</span>
<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">pubTopic</span> <span class="o">=</span> <span class="s">&quot;office/temp&quot;</span><span class="p">;</span> <span class="c1">// 例: ex1/groupXX/sensor </span>
<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">mquser</span>   <span class="o">=</span> <span class="s">&quot;ex1&quot;</span><span class="p">;</span>
<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">mqpass</span>   <span class="o">=</span> <span class="s">&quot;***PASSWORD***&quot;</span><span class="p">;</span>
<span class="nf">WiFiClient</span> <span class="n">wifiClient</span><span class="p">;</span>
<span class="kr">char</span><span class="o">*</span> <span class="n">clientid</span> <span class="o">=</span> <span class="s">&quot;m5stickc01_00000001&quot;</span><span class="p">;</span> <span class="c1">//デバイス個別に設定すればなんでもよい</span>
<span class="n">PubSubClient</span> <span class="nf">mqttClient</span><span class="p">(</span><span class="n">wifiClient</span><span class="p">);</span> <span class="c1">// MQTT Client</span>

<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
<span class="c1">//  M5.begin();</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="mi">115200</span><span class="p">);</span>
  <span class="nf">WiFi</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="n">ssid</span><span class="p">,</span> <span class="n">password</span><span class="p">);</span>
  <span class="k">while</span> <span class="p">(</span><span class="nf">WiFi</span><span class="p">.</span><span class="n">status</span><span class="p">()</span> <span class="o">!=</span> <span class="n">WL_CONNECTED</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// 接続中...</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;.&quot;</span><span class="p">);</span>
    <span class="nf">delay</span><span class="p">(</span><span class="mi">200</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span> <span class="nf">WiFi</span><span class="p">.</span><span class="nf">localIP</span><span class="p">().</span><span class="n">toString</span><span class="p">()</span> <span class="p">);</span> <span class="c1">//取得したIPアドレス</span>
  <span class="c1">// 参考:WiFiデバイスのMACアドレスを取得し、clientid として用いる</span>
  <span class="c1">// (18行目のclientidの定義を変更し、char clientid[20]とするのがのぞましい)</span>
  <span class="c1">//  uint8_t mac[6];</span>
  <span class="c1">//  esp_read_mac(mac, ESP_MAC_WIFI_STA);</span>
  <span class="c1">//  sprintf(clientid, &quot;%02X:%02X:%02X:%02X:%02X:%02X&quot;,</span>
  <span class="c1">//          mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] );</span>
<span class="hll">  <span class="n">mqttClient</span><span class="p">.</span><span class="n">setServer</span><span class="p">(</span><span class="n">server</span><span class="p">,</span> <span class="n">port</span><span class="p">);</span>
</span><span class="hll">  <span class="n">mqttClient</span><span class="p">.</span><span class="n">setCallback</span><span class="p">(</span><span class="n">callback_on_subscribe</span><span class="p">);</span>
</span>
  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">mqttClient</span><span class="p">.</span><span class="nf">connected</span><span class="p">())</span> <span class="p">{</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;Try (re)connecting...&quot;</span><span class="p">);</span>
    <span class="n">reconnect</span><span class="p">();</span>
  <span class="p">}</span>
  <span class="n">mqttClient</span><span class="p">.</span><span class="n">subscribe</span><span class="p">(</span><span class="n">pubTopic</span><span class="p">);</span>

<span class="p">}</span>

<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>

  <span class="n">mqttClient</span><span class="p">.</span><span class="nb">loop</span><span class="p">();</span> <span class="c1">// データがpublishされたら、callback_on_subscribe が呼ばれる</span>

  <span class="nf">delay</span><span class="p">(</span><span class="mi">100</span><span class="p">);</span>
<span class="p">}</span>

<span class="kr">void</span> <span class="nf">reconnect</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">mqttClient</span><span class="p">.</span><span class="nf">connected</span><span class="p">())</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">mqttClient</span><span class="p">.</span><span class="nf">connect</span><span class="p">(</span><span class="n">clientid</span><span class="p">,</span> <span class="n">mquser</span><span class="p">,</span> <span class="n">mqpass</span><span class="p">))</span> <span class="p">{</span>
      <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;Connected to MQTT Broker.&quot;</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
      <span class="nf">Serial</span><span class="p">.</span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;Connect Failed. state=%d&quot;</span><span class="p">,</span> <span class="n">mqttClient</span><span class="p">.</span><span class="n">state</span><span class="p">());</span>
    <span class="p">}</span>
  <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// データがPublishされたら、ここが実行される。(39行目でコールバック関数を設定しているため)</span>
<span class="kr">void</span> <span class="nf">callback_on_subscribe</span><span class="p">(</span><span class="kr">char</span><span class="o">*</span> <span class="n">topic</span><span class="p">,</span> <span class="kr">byte</span><span class="o">*</span> <span class="n">payload</span><span class="p">,</span> <span class="kr">unsigned</span> <span class="kr">int</span> <span class="n">len</span><span class="p">)</span> <span class="p">{</span>
  <span class="kr">char</span> <span class="n">buf</span><span class="p">[</span><span class="mi">100</span><span class="p">];</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;Message arrived [&quot;</span><span class="p">);</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="n">topic</span><span class="p">);</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="s">&quot;] &quot;</span><span class="p">);</span>
  <span class="k">for</span> <span class="p">(</span><span class="kr">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">len</span> <span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">buf</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="kr">char</span><span class="p">)</span><span class="n">payload</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
  <span class="p">}</span>
  <span class="n">buf</span><span class="p">[</span><span class="n">len</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="n">buf</span><span class="p">);</span>
  <span class="k">return</span><span class="p">;</span>
  <span class="c1">//  参考:JSON Parsing example</span>
  <span class="c1">//  StaticJsonDocument&lt;200&gt; sjdoc;</span>
  <span class="c1">//  deserializeJson(sjdoc, buf);</span>
  <span class="c1">//  int intval = sjdoc[&quot;intval&quot;];</span>
  <span class="c1">//  const char* str = sjdoc[&quot;string&quot;];</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
<div class="section" id="id17">
<h3>トピック名とワイルドカード<a class="headerlink" href="#id17" title="このヘッドラインへのパーマリンク">¶</a></h3>
<p>サブスクライブするときのトピック名には、ワイルドカードが指定できます。例えば、 <code class="docutils literal notranslate"><span class="pre">office/+</span></code>
と指定すると、 <code class="docutils literal notranslate"><span class="pre">office/temp</span></code> にも <code class="docutils literal notranslate"><span class="pre">office/humid</span></code> にもマッチします。<a class="reference external" href="http://devcenter.magellanic-clouds.com/learning/mqtt-spec.html">参考:MQTT の仕様</a></p>
</div>
<div class="section" id="mosquitto">
<h3>mosquitto コマンド例<a class="headerlink" href="#mosquitto" title="このヘッドラインへのパーマリンク">¶</a></h3>
<p>mosquitto は、オープンソースのMQTT Broker/Client 実装の1つです。参考までに、mosquitto クライアントを使用するコマンド例を示します。:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1">#(パブリッシュ。retainなし: -m &quot;メッセージ&quot; )</span>
   <span class="n">mosquitto_pub</span> <span class="o">-</span><span class="n">h</span> <span class="n">mqtt</span><span class="o">.</span><span class="n">istlab</span><span class="o">.</span><span class="n">info</span> <span class="o">-</span><span class="n">u</span> <span class="n">ex1</span> <span class="o">-</span><span class="n">P</span> <span class="n">PASS</span> <span class="o">-</span><span class="n">t</span> <span class="n">office</span><span class="o">/</span><span class="n">temp</span> <span class="o">-</span><span class="n">m</span> <span class="s2">&quot;data or message&quot;</span>
<span class="c1">#(パブリッシュ。retainあり: -r )</span>
   <span class="n">mosquitto_pub</span> <span class="o">-</span><span class="n">h</span> <span class="n">mqtt</span><span class="o">.</span><span class="n">istlab</span><span class="o">.</span><span class="n">info</span> <span class="o">-</span><span class="n">u</span> <span class="n">ex1</span> <span class="o">-</span><span class="n">P</span> <span class="n">PASS</span> <span class="o">-</span><span class="n">t</span> <span class="n">office</span><span class="o">/</span><span class="n">temp</span> <span class="o">-</span><span class="n">m</span> <span class="s2">&quot;data or message&quot;</span> <span class="o">-</span><span class="n">r</span>
<span class="c1">#(retainデータを削除。-n : send a null (zero length) message.)</span>
   <span class="n">mosquitto_pub</span> <span class="o">-</span><span class="n">h</span> <span class="n">mqtt</span><span class="o">.</span><span class="n">istlab</span><span class="o">.</span><span class="n">info</span> <span class="o">-</span><span class="n">u</span> <span class="n">ex1</span> <span class="o">-</span><span class="n">P</span> <span class="n">PASS</span> <span class="o">-</span><span class="n">t</span> <span class="n">office</span><span class="o">/</span><span class="n">temp</span> <span class="o">-</span><span class="n">n</span> <span class="o">-</span><span class="n">r</span>
<span class="c1">#(サブスクライブ)</span>
   <span class="n">mosquitto_sub</span> <span class="o">-</span><span class="n">h</span> <span class="n">mqtt</span><span class="o">.</span><span class="n">istlab</span><span class="o">.</span><span class="n">info</span> <span class="o">-</span><span class="n">u</span> <span class="n">ex1</span> <span class="o">-</span><span class="n">P</span> <span class="n">PASS</span> <span class="o">-</span><span class="n">t</span> <span class="n">office</span><span class="o">/</span><span class="n">temp</span>
</pre></div>
</div>
<p>3つ目の例に示すように、長さ0のretainデータを送信すると、retainデータを削除できます。</p>
<div class="admonition note">
<p class="first admonition-title">注釈</p>
<p class="last">サンプルでは文字列(ASCII)データを送受信していますが、値をbyte配列・バイナリで送受信することもできます。</p>
</div>
</div>
</div>
<div class="section" id="bluetooth-serial-protocol-profile-spp">
<h2>Bluetooth Serial Protocol Profile (SPP)<a class="headerlink" href="#bluetooth-serial-protocol-profile-spp" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>「Serial通信」では、開発用PCのシリアルコンソールをつかって、USB接続を介して、文字列を送受信しました。
「Wifi接続」のTelnetサーバでは、TCP/IP通信上でのTelnet接続を介して、文字列を送受信しました。</p>
<p>ここでは、Bluetoothを用いて、上記と同様、2台のデバイス間で文字列を送受信する例を示します。Bluetoth では、機器同士は同一の「プロファイル」という通信方式に対応している必要があります。Serial Protocol Profile は、Bluetooth無線通信で仮想シリアル接続を可能にするプロファイルです。</p>
<div class="admonition note">
<p class="first admonition-title">注釈</p>
<p class="last">基本的に <a class="reference external" href="http://robooptions.blog.fc2.com/blog-entry-9.html">ESP32同士をBluetoothシリアルでつないでみる</a> と同じです。</p>
</div>
<div class="section" id="mac">
<h3>(1) スレーブ用デバイスのMACアドレスを調べる<a class="headerlink" href="#mac" title="このヘッドラインへのパーマリンク">¶</a></h3>
<p><a class="reference internal" href="#bts01-slave"><span class="std std-numref">リスト 24</span></a> を、1台目のM5StickCPlusで実行し、BluetoothのMACアドレスを調べます。</p>
<div class="literal-block-wrapper docutils container" id="bts01-slave">
<div class="code-block-caption"><span class="caption-number">リスト 24 </span><span class="caption-text">src/bts01_slave.ino</span><a class="headerlink" href="#bts01-slave" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">&lt;M5StickCPlus.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&quot;BluetoothSerial.h&quot;</span><span class="cp"></span>

<span class="n">BluetoothSerial</span> <span class="n">SerialBT</span><span class="p">;</span>

<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">dname</span> <span class="o">=</span> <span class="s">&quot;BT_Serial_00&quot;</span><span class="p">;</span> <span class="c1">// Slave device name</span>

<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">M5</span><span class="p">.</span><span class="nf">begin</span><span class="p">();</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">setRotation</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillScreen</span><span class="p">(</span><span class="n">YELLOW</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">setTextColor</span><span class="p">(</span><span class="n">BLACK</span><span class="p">,</span> <span class="n">YELLOW</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setCursor</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setTextSize</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>

  <span class="nf">Serial</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="mi">115200</span><span class="p">);</span>
  <span class="n">SerialBT</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="n">dname</span><span class="p">);</span> <span class="c1">//Bluetooth device name</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;The device started, now you can pair it with bluetooth!&quot;</span><span class="p">);</span>

  <span class="kr">uint8_t</span> <span class="n">macBT</span><span class="p">[</span><span class="mi">6</span><span class="p">];</span>
  <span class="n">esp_read_mac</span><span class="p">(</span><span class="n">macBT</span><span class="p">,</span> <span class="n">ESP_MAC_BT</span><span class="p">);</span>
  <span class="kr">char</span> <span class="n">mac</span><span class="p">[</span><span class="mi">20</span><span class="p">];</span>
  <span class="n">sprintf</span><span class="p">(</span><span class="n">mac</span><span class="p">,</span> <span class="s">&quot;%02X:%02X:%02X:%02X:%02X:%02X&quot;</span><span class="p">,</span> <span class="n">macBT</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">macBT</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">macBT</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">macBT</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">macBT</span><span class="p">[</span><span class="mi">4</span><span class="p">],</span> <span class="n">macBT</span><span class="p">[</span><span class="mi">5</span><span class="p">]);</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="n">mac</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="n">mac</span><span class="p">);</span>

<span class="p">}</span>

<span class="kr">int</span> <span class="nf">line</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
  <span class="kr">char</span> <span class="n">c</span><span class="p">;</span>
  <span class="k">if</span> <span class="p">(</span><span class="nf">Serial</span><span class="p">.</span><span class="nf">available</span><span class="p">())</span> <span class="p">{</span>
    <span class="n">SerialBT</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="n">c</span> <span class="o">=</span> <span class="nf">Serial</span><span class="p">.</span><span class="nf">read</span><span class="p">());</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;read:%c</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">c</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">SerialBT</span><span class="p">.</span><span class="nf">available</span><span class="p">())</span> <span class="p">{</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="n">c</span> <span class="o">=</span> <span class="n">SerialBT</span><span class="p">.</span><span class="nf">read</span><span class="p">());</span>
    <span class="n">SerialBT</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="n">c</span> <span class="o">+</span> <span class="mi">0</span><span class="p">);</span>
    <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="n">c</span><span class="p">);</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">c</span> <span class="o">==</span> <span class="mh">0xa</span><span class="p">)</span> <span class="nf">line</span><span class="o">++</span><span class="p">;</span>
    <span class="k">if</span> <span class="p">(</span><span class="nf">line</span> <span class="o">&gt;</span> <span class="mi">7</span><span class="p">)</span> <span class="p">{</span>
      <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillScreen</span><span class="p">(</span><span class="n">YELLOW</span><span class="p">);</span>  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setCursor</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
      <span class="nf">line</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="p">}</span>
  <span class="p">}</span>

  <span class="n">M5</span><span class="p">.</span><span class="n">update</span><span class="p">();</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">M5</span><span class="p">.</span><span class="n">BtnA</span><span class="p">.</span><span class="n">wasReleasefor</span><span class="p">(</span><span class="mi">1000</span><span class="p">)</span> <span class="p">)</span> <span class="p">{</span>
    <span class="n">SerialBT</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;[A] was Pressed longer than 1s&quot;</span><span class="p">);</span>
  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">M5</span><span class="p">.</span><span class="n">BtnA</span><span class="p">.</span><span class="n">wasReleased</span><span class="p">())</span> <span class="p">{</span>
    <span class="n">SerialBT</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;[A] was Pressed&quot;</span><span class="p">);</span>
  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">M5</span><span class="p">.</span><span class="n">BtnB</span><span class="p">.</span><span class="n">wasReleasefor</span><span class="p">(</span><span class="mi">1000</span><span class="p">)</span> <span class="p">)</span> <span class="p">{</span>
    <span class="n">SerialBT</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;[B] was Pressed longer than 1s&quot;</span><span class="p">);</span>
  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">M5</span><span class="p">.</span><span class="n">BtnB</span><span class="p">.</span><span class="n">wasReleased</span><span class="p">())</span> <span class="p">{</span>
    <span class="n">SerialBT</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;[B] was Pressed&quot;</span><span class="p">);</span>
  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">M5</span><span class="p">.</span><span class="n">Axp</span><span class="p">.</span><span class="n">GetBtnPress</span><span class="p">()</span> <span class="o">==</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">SerialBT</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;[Power] was Pressed&quot;</span><span class="p">);</span>
  <span class="p">}</span>

  <span class="nf">delay</span><span class="p">(</span><span class="mi">20</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
<div class="section" id="id19">
<h3>(2) マスタ用デバイスにサンプルを書き込む<a class="headerlink" href="#id19" title="このヘッドラインへのパーマリンク">¶</a></h3>
<p><a class="reference internal" href="#bts01-master"><span class="std std-numref">リスト 25</span></a> を、2台目のM5StickCPlusで実行します。このとき、(1)で調べたMACアドレスを指定します。</p>
<div class="literal-block-wrapper docutils container" id="bts01-master">
<div class="code-block-caption"><span class="caption-number">リスト 25 </span><span class="caption-text">src/bts01_master.ino</span><a class="headerlink" href="#bts01-master" title="このコードへのパーマリンク">¶</a></div>
<div class="highlight-arduino notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">&lt;M5StickCPlus.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;BluetoothSerial.h&gt;</span><span class="cp"></span>

<span class="n">BluetoothSerial</span> <span class="n">SerialBT</span><span class="p">;</span>

<span class="kr">bool</span> <span class="n">willConnect</span> <span class="o">=</span> <span class="kr">true</span><span class="p">;</span>
<span class="kr">bool</span> <span class="nf">connected</span><span class="p">;</span>

<span class="kr">const</span> <span class="kr">char</span><span class="o">*</span> <span class="n">dname</span> <span class="o">=</span> <span class="s">&quot;BT_Serial_00&quot;</span><span class="p">;</span> <span class="c1">// Slave device name</span>

<span class="kr">void</span> <span class="nb">setup</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">M5</span><span class="p">.</span><span class="nf">begin</span><span class="p">();</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">setRotation</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillScreen</span><span class="p">(</span><span class="n">BLUE</span><span class="p">);</span>

  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">setTextColor</span><span class="p">(</span><span class="n">BLACK</span><span class="p">,</span> <span class="n">CYAN</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setCursor</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setTextSize</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>

  <span class="nf">Serial</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="mi">115200</span><span class="p">);</span>
  <span class="n">SerialBT</span><span class="p">.</span><span class="nf">begin</span><span class="p">(</span><span class="s">&quot;BT_Serial_01&quot;</span><span class="p">,</span> <span class="kr">true</span><span class="p">);</span>
  <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;The device started in master mode, make sure remote BT device is on!&quot;</span><span class="p">);</span>

  <span class="c1">// connect(address) is fast (upto 10 secs max), connect(name) is slow (upto 30 secs max) as it needs</span>
  <span class="c1">// to resolve name to address first, but it allows to connect to different devices with the same name.</span>
  <span class="c1">// Set CoreDebugLevel to Info to view devices bluetooth address and device names</span>
  <span class="k">if</span> <span class="p">(</span><span class="kr">false</span><span class="p">)</span> <span class="p">{</span>
    <span class="nf">connected</span> <span class="o">=</span> <span class="n">SerialBT</span><span class="p">.</span><span class="nf">connect</span><span class="p">(</span><span class="n">dname</span><span class="p">);</span>
  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="kr">uint8_t</span> <span class="n">address</span><span class="p">[</span><span class="mi">6</span><span class="p">]</span>  <span class="o">=</span> <span class="p">{</span><span class="mh">0x24</span><span class="p">,</span> <span class="mh">0xA1</span><span class="p">,</span> <span class="mh">0x60</span><span class="p">,</span> <span class="mh">0x47</span><span class="p">,</span> <span class="mh">0x84</span><span class="p">,</span> <span class="mh">0x4E</span><span class="p">};</span> <span class="c1">// MACアドレスが 24:A1:60:47:84:4E のとき</span>
    <span class="nf">connected</span> <span class="o">=</span> <span class="n">SerialBT</span><span class="p">.</span><span class="nf">connect</span><span class="p">(</span><span class="n">address</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="k">if</span> <span class="p">(</span><span class="nf">connected</span><span class="p">)</span> <span class="p">{</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;Connected Succesfully!&quot;</span><span class="p">);</span>
    <span class="n">M5</span><span class="p">.</span><span class="n">Beep</span><span class="p">.</span><span class="nf">tone</span><span class="p">(</span><span class="mi">2000</span><span class="p">,</span> <span class="mi">1000</span><span class="p">);</span>
    <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillScreen</span><span class="p">(</span><span class="n">CYAN</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="c1">// disconnect() may take upto 10 secs max</span>
  <span class="c1">//  if (SerialBT.disconnect()) {</span>
  <span class="c1">//    connected = false;</span>
  <span class="c1">//    Serial.println(&quot;Disconnected Succesfully!&quot;);</span>
  <span class="c1">//  }</span>
  <span class="c1">// this would reconnect to the name(will use address, if resolved) or address used with connect(name/address).</span>
  <span class="c1">//SerialBT.connect();</span>
<span class="p">}</span>

<span class="kr">void</span> <span class="nf">connectOrDisconnect</span><span class="p">(</span><span class="kr">bool</span> <span class="n">willCon</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">willCon</span> <span class="o">&amp;&amp;</span> <span class="nf">connected</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">willCon</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="nf">connected</span><span class="p">)</span> <span class="p">{</span>
      <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;Connected Succesfully!&quot;</span><span class="p">);</span>
      <span class="n">M5</span><span class="p">.</span><span class="n">Beep</span><span class="p">.</span><span class="nf">tone</span><span class="p">(</span><span class="mi">2000</span><span class="p">,</span> <span class="mi">1000</span><span class="p">);</span>
      <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillScreen</span><span class="p">(</span><span class="n">CYAN</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
      <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">SerialBT</span><span class="p">.</span><span class="nf">connected</span><span class="p">(</span><span class="mi">10000</span><span class="p">))</span> <span class="p">{</span>
        <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;Failed to connect. Make sure remote device is available and in range, then restart app.&quot;</span><span class="p">);</span>
        <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillScreen</span><span class="p">(</span><span class="n">PURPLE</span><span class="p">);</span>
      <span class="p">}</span>
    <span class="p">}</span>
  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span> <span class="n">SerialBT</span><span class="p">.</span><span class="nf">disconnect</span><span class="p">()</span> <span class="p">)</span> <span class="p">{</span>
      <span class="nf">connected</span> <span class="o">=</span> <span class="kr">false</span><span class="p">;</span>
      <span class="nf">Serial</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;Disconnected Succesfully!&quot;</span><span class="p">);</span>
      <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillScreen</span><span class="p">(</span><span class="n">BLUE</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">}</span>
<span class="p">}</span>
<span class="kr">int</span> <span class="nf">line</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="kr">void</span> <span class="nb">loop</span><span class="p">()</span> <span class="p">{</span>
  <span class="n">connectOrDisconnect</span><span class="p">(</span> <span class="n">willConnect</span> <span class="p">);</span>

  <span class="kr">char</span> <span class="n">c</span><span class="p">;</span>
  <span class="k">if</span> <span class="p">(</span><span class="nf">Serial</span><span class="p">.</span><span class="nf">available</span><span class="p">())</span> <span class="p">{</span>
    <span class="n">SerialBT</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="n">c</span> <span class="o">=</span> <span class="nf">Serial</span><span class="p">.</span><span class="nf">read</span><span class="p">());</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;read:%c</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">c</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">SerialBT</span><span class="p">.</span><span class="nf">available</span><span class="p">())</span> <span class="p">{</span>
    <span class="nf">Serial</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="n">c</span> <span class="o">=</span> <span class="n">SerialBT</span><span class="p">.</span><span class="nf">read</span><span class="p">());</span>
    <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">print</span><span class="p">(</span><span class="n">c</span><span class="p">);</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">c</span> <span class="o">==</span> <span class="mh">0xa</span><span class="p">)</span> <span class="nf">line</span><span class="o">++</span><span class="p">;</span>
    <span class="k">if</span> <span class="p">(</span><span class="nf">line</span> <span class="o">&gt;</span> <span class="mi">7</span><span class="p">)</span> <span class="p">{</span>
      <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillScreen</span><span class="p">(</span><span class="n">CYAN</span><span class="p">);</span>  <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="nf">setCursor</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
      <span class="nf">line</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="p">}</span>
  <span class="p">}</span>

  <span class="n">M5</span><span class="p">.</span><span class="n">update</span><span class="p">();</span>  <span class="n">M5</span><span class="p">.</span><span class="n">Beep</span><span class="p">.</span><span class="n">update</span><span class="p">();</span>
  <span class="k">if</span> <span class="p">(</span><span class="n">M5</span><span class="p">.</span><span class="n">BtnA</span><span class="p">.</span><span class="n">wasReleasefor</span><span class="p">(</span><span class="mi">1000</span><span class="p">)</span> <span class="p">)</span> <span class="p">{</span>
    <span class="n">SerialBT</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;[A] was Pressed longer than 1s&quot;</span><span class="p">);</span>
  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">M5</span><span class="p">.</span><span class="n">BtnA</span><span class="p">.</span><span class="n">wasReleased</span><span class="p">())</span> <span class="p">{</span>
    <span class="n">SerialBT</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;[A] was Pressed&quot;</span><span class="p">);</span>
  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">M5</span><span class="p">.</span><span class="n">BtnB</span><span class="p">.</span><span class="n">wasReleasefor</span><span class="p">(</span><span class="mi">1000</span><span class="p">)</span> <span class="p">)</span> <span class="p">{</span>
    <span class="n">SerialBT</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;[B] was Pressed longer than 1s&quot;</span><span class="p">);</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">SerialBT</span><span class="p">.</span><span class="nf">disconnect</span><span class="p">())</span> <span class="p">{</span>
      <span class="nf">connected</span> <span class="o">=</span> <span class="kr">false</span><span class="p">;</span>
      <span class="n">M5</span><span class="p">.</span><span class="n">Lcd</span><span class="p">.</span><span class="n">fillScreen</span><span class="p">(</span><span class="n">PURPLE</span><span class="p">);</span>
    <span class="p">}</span>
  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">M5</span><span class="p">.</span><span class="n">BtnB</span><span class="p">.</span><span class="n">wasReleased</span><span class="p">())</span> <span class="p">{</span>
    <span class="n">SerialBT</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;[B] was Pressed&quot;</span><span class="p">);</span>
  <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">M5</span><span class="p">.</span><span class="n">Axp</span><span class="p">.</span><span class="n">GetBtnPress</span><span class="p">()</span> <span class="o">==</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">SerialBT</span><span class="p">.</span><span class="nf">println</span><span class="p">(</span><span class="s">&quot;[Power] was Pressed&quot;</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="nf">delay</span><span class="p">(</span><span class="mi">20</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</td></tr></table></div>
</div>
</div>
</div>
<div class="section" id="bluetooth-low-energy">
<h2>Bluetooth Low Energy<a class="headerlink" href="#bluetooth-low-energy" title="このヘッドラインへのパーマリンク">¶</a></h2>
<p>アドバータイズ</p>
</div>
<div class="section" id="preference">
<h2>Preference<a class="headerlink" href="#preference" title="このヘッドラインへのパーマリンク">¶</a></h2>
</div>
<div class="section" id="id20">
<h2>電力制御<a class="headerlink" href="#id20" title="このヘッドラインへのパーマリンク">¶</a></h2>
</div>
<div class="section" id="id21">
<h2>その他<a class="headerlink" href="#id21" title="このヘッドラインへのパーマリンク">¶</a></h2>
<ul class="simple">
<li>CO2 (CCS811)</li>
<li>RCS-620S (Felica)</li>
<li>JJYClock</li>
<li>RTC(BM8563)</li>
<li>OTA</li>
</ul>
</div>
</div>


           </div>
           
          </div>
          <footer>
    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
        <a href="week2.html" class="btn btn-neutral float-right" title="2週目" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
        <a href="pre.html" class="btn btn-neutral float-left" title="事前準備" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
    </div>

  <hr/>

  <div role="contentinfo">
    <p>
        &#169; Copyright 2021, Motoki Miura.

    </p>
  </div>
    
    
    
    Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
    
    <a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
    
    provided by <a href="https://readthedocs.org">Read the Docs</a>. 

</footer>
        </div>
      </div>

    </section>

  </div>
  

  <script type="text/javascript">
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script>

  
  
    
   

</body>
</html>