2019年4月21日日曜日

ESP32/arduino:I2C 転送速度設定

目的:

I2C アクセスの転送速度設定を行い、アクセス時間を確認する

I2C 転送速度設定方法:

Wire.bigin() ; の後で、
Wire.setClock(転送速度);
で行う。
設定を行わない場合(default)の転送速度は 100Kbit/S。
例えば、400Kbit/S に設定する場合は
Wire.setClock(400000);

アクセス時間は、アクセス前後で micros() ; で時間を測定する。
実行結果は概ね、

  100Kbit/S 400Kbit/S
単発リード 597 uS 307 uS
単発ライト 400 uS 191 uS
ダンプ 553 uS 268 uS

 単発リードとダンプ(22回の平均)で 40uSぐらいの差がある。
400Kbit/S では 周波数は 4倍だが、測定結果は 2倍程度。

結構、ESP32での処理にも時間がかかっているのかな?

例:

MCP23017 レジスタアクセスのスケッチに 転送速度設定、アクセス速度計測を追加する。

WEB画面サンプル:

使用方法等

 設定ファイルが無い状態では APモードで立ち上がるため、
 SSID : ESP32_AP
   ( パスワード : password )
に接続し、ブラウザで IPアドレス 192.168.4.1 に
アクセスして、WiFi 設定を行う。

WiFi設定変更で IPアドレス等を変更した場合は、
再起動で 変更した IPアドレス等が有効となる。

転送速度は ラジオボタンで選択。
"rd", "wr", "dmp" を行うと、1アクセス当たりの
アクセス速度が表示される。

<HTML, スケッチ>

構成は、MCP23017 レジスタアクセスと同じ。

<HTML> : 3種。 rdataフォルダの下に保存し、SPIFFSにアップロードする。
  • MAIN HTML (main.html)
  • WiFi設定 HTML (wifi_conf.html)
  • XHR 応答 HTML (resp_cnfld.html)

<スケッチ> : 4種。拡張子は .ino
  • MAIN (変数定義, setup, loop 関数) 
  • WIFI設定 (主に WiFI 設定用 の関数) 
  • WIFI処理 (主に MAIN処理(レジスタアクセス)の WEB画面処理 )
  • MAIN処理 (主に I2Cアクセス の関数)
以下、変更した HTML, スケッチを記す。

MAIN HTML (main.html)
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
<!DOCTYPE html><html lang='ja'><head><meta charset='UTF-8'>
<style>
    #base         {font-size:16pt; text-align:center; width:410px; border:solid 4px #93ff93; background-color:#f0f0f0; }
    #set_box1     {height:19pt;font-size:10pt; text-align:left; }
    #set_box2     {height:15pt;font-size:10pt; text-align:left; }
    #text_box     {font-size:10pt; margin : 3px 0px 0px 0px ;float:left ; text-align:left; width:150px;}
    #regname      {font-size:10pt; margin : 0px 0px 0px 0px ;float:left ; text-align:left; width:80px;border:solid 1px #000000;}
    #regadr       {font-size:10pt; margin : 0px 0px 0px 0px ;float:left ; text-align:left; width:40px;border:solid 1px #000000;}
    #regwdt       {font-size:10pt; margin : 0px 0px 0px 0px ;float:left ; text-align:left; width:100px;}
    #regrdt       {font-size:10pt; margin : 0px 3px 0px 0px ;float:left ; text-align:left; width:75px;border:solid 1px #000000;}
    #button       {font-size:12pt; margin : 10px 0px 10px 0px ;clear:both; }
    #btn_conf     {font-size:12pt; margin : 10px 0px 10px 0px ;text-align:left  ; width:83%; }
    #text_in      {height: 12pt ; margin:14px 0px 0px 5px ; font-size:8pt; float:right; }
    #radio_box    {font-size:10pt; float:left ;text-align:left; width:120px; margin: 0px 0px  0px 0px ; }
    input         {margin:0px 8px 0px 8px ;width:50px;}
    input.button  {margin:0px 8px 0px 8px ;width:100px;}
    input.btncnf  {margin:0px 0px 0px 28px ;width:100px;}
    input.radio   {margin:0px 8px 0px 0px ;width:10px;}
    output        {margin:0px 8px 0px 8px ;}
</style>
 
<title>MCP23017 Access</title></head>
 
<body>
<div id="base">
  <p>MCP23017 レジスタ アクセス</p>
  <form method='get'>
    <div id=set_box1>
      <div id=text_box>スレーブアドレス</div>
      <div id=regwdt> <span>0x</span><input type='text' name='sadr' value=$s_adr > </div>
    </div>
    <div id=set_box1>
      <div id=text_box>転送速度</div>
      <div id="radio_box">
        <input class="radio" type="radio" name="spd" id="std" value="std" $checked_std onclick="submit(this.value)">100Kbit/s 
      </div>
      <div id="radio_box">
        <input class="radio" type="radio" name="spd" id="fst" value="fst" $checked_fst onclick="submit(this.value)">400Kbit/s 
      </div>
    </div>
  </form>
  <form method='get'>
    <div id=set_box1>
      <div id=text_box>レジスタアドレス</div>
      <div id=regwdt> <span>0x</span><input  type='text' name='regadr' value=$reg_adr > </div>
    </div>
    <div id=set_box1>
      <div id=text_box>ライトデータ</div>
      <div id=regwdt> <span>0x</span><input  type='text' name='wrdt' value=$wr_dt > </div>
    </div>
    <div id=set_box1>
      <div id=text_box>リードデータ</div>
      <div id=regwdt> <span>0x</span><output  name='rddt' >$rd_dt</output>  </div>
    </div>
    <div id=set_box1>
      <div id=text_box>アクセス速度</div>
      <div id=regwdt> <output  name='acs_spd' >$acs_spd</output><span> uS</span>  </div>
    </div>
    <div id=button>
      <input class=button type='submit' name='read' value='rd' >
      <input class=button type='submit' name='write' value='wr' >
    </div>
  </form>
      <span>レジスタダンプ</span>
    <div id=set_box2>
      <div id=regname>レジスタ名</div>
      <div id=regadr>adr</div>
      <div id=regrdt>データ</div>
      <div id=regname>レジスタ名</div>
      <div id=regadr>adr</div>
      <div id=regrdt>データ</div>
    </div>
    <div id=set_box2>
      <div id=regname> IODIRA</div>
      <div id=regadr> 00</div>
      <div id=regrdt> <span>0x</span><output name='rddt00' >$rdt00</output> </div>
      <div id=regname> IODIRB</div>
      <div id=regadr> 01</div>
      <div id=regrdt> <span>0x</span><output name='rddt01' >$rdt01</output> </div>
    </div>
    <div id=set_box2>
      <div id=regname> IPOLA </div>
      <div id=regadr> 02</div>
      <div id=regrdt> <span>0x</span><output name='rddt02' >$rdt02</output> </div>
      <div id=regname> IOOLB</div>
      <div id=regadr> 03</div>
      <div id=regrdt> <span>0x</span><output name='rddt03' >$rdt03</output> </div>
    </div>
    <div id=set_box2>
      <div id=regname> GPINTENA </div>
      <div id=regadr> 04</div>
      <div id=regrdt> <span>0x</span><output name='rddt04' >$rdt04</output> </div>
      <div id=regname> GPINTENB</div>
      <div id=regadr> 05</div>
      <div id=regrdt> <span>0x</span><output name='rddt05' >$rdt05</output> </div>
    </div>
    <div id=set_box2>
      <div id=regname> DEFVALA </div>
      <div id=regadr> 06</div>
      <div id=regrdt> <span>0x</span><output name='rddt06' >$rdt06</output> </div>
      <div id=regname> DEFVALB</div>
      <div id=regadr> 07</div>
      <div id=regrdt> <span>0x</span><output name='rddt07' >$rdt07</output> </div>
    </div>
    <div id=set_box2>
      <div id=regname> INTCONA </div>
      <div id=regadr> 08</div>
      <div id=regrdt> <span>0x</span><output name='rddt08' >$rdt08</output> </div>
      <div id=regname> INTCONB</div>
      <div id=regadr> 09</div>
      <div id=regrdt> <span>0x</span><output name='rddt09' >$rdt09</output> </div>
    </div>
    <div id=set_box2>
      <div id=regname> IOCON   </div>
      <div id=regadr> 0a</div>
      <div id=regrdt> <span>0x</span><output name='rddt0a' >$rdt0a</output> </div>
      <div id=regname> IOCON  </div>
      <div id=regadr> 0b</div>
      <div id=regrdt> <span>0x</span><output name='rddt0b' >$rdt0b</output> </div>
    </div>
    <div id=set_box2>
      <div id=regname> GPPUA   </div>
      <div id=regadr> 0c</div>
      <div id=regrdt> <span>0x</span><output name='rddt0c' >$rdt0c</output> </div>
      <div id=regname> GPPUB  </div>
      <div id=regadr> 0d</div>
      <div id=regrdt> <span>0x</span><output name='rddt0d' >$rdt0d</output> </div>
    </div>
    <div id=set_box2>
      <div id=regname> INTFA   </div>
      <div id=regadr> 0e</div>
      <div id=regrdt> <span>0x</span><output name='rddt0e' >$rdt0e</output> </div>
      <div id=regname> INTFB  </div>
      <div id=regadr> 0f</div>
      <div id=regrdt> <span>0x</span><output name='rddt0f' >$rdt0f</output> </div>
    </div>
    <div id=set_box2>
      <div id=regname> INTCAPA </div>
      <div id=regadr> 10</div>
      <div id=regrdt> <span>0x</span><output name='rddt10' >$rdt10</output> </div>
      <div id=regname> INTCAPB </div>
      <div id=regadr> 11</div>
      <div id=regrdt> <span>0x</span><output name='rddt11' >$rdt11</output> </div>
    </div>
    <div id=set_box2>
      <div id=regname> GPIOA </div>
      <div id=regadr> 12</div>
      <div id=regrdt> <span>0x</span><output name='rddt12' >$rdt12</output> </div>
      <div id=regname> GPIOB</div>
      <div id=regadr> 13</div>
      <div id=regrdt> <span>0x</span><output name='rddt13' >$rdt13</output> </div>
    </div>
    <div id=set_box2>
      <div id=regname> OLATA </div>
      <div id=regadr> 14</div>
      <div id=regrdt> <span>0x</span><output name='rddt14' >$rdt14</output> </div>
      <div id=regname> OLATB</div>
      <div id=regadr> 15</div>
      <div id=regrdt> <span>0x</span><output name='rddt15' >$rdt15</output> </div>
    </div>
    <div id=set_box1>
      <div id=text_box>アクセス速度</div>
      <div id=regwdt> <output  name='dmp_spd' >$dmp_spd <span> uS</span></output> </div>
    </div>
    <form method='get'>
      <div id='button'>
        <input class='button' type='submit' name='dump' value='dmp' >
      </div>
    </form>
  <div id="btn_conf">
    <form method="get">
        <input class='btncnf' type='submit' name='config' id='config' value='WiFi設定画面'>
        <div id="text_in">
          <a href="#" onclick='cnfdl();'>設定をダウンロードする</a>
        </div>
     </form>
  </div>
</div>
 
<script>
  function cnfdl() {
    "use strict";
   
    var xhr = new XMLHttpRequest();
    xhr.open("get", "?cnfdl");
    xhr.setRequestHeader('Cache-Control', 'no-cache');
    xhr.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT');
    xhr.responseType = 'document' ;
    
    xhr.onreadystatechange = function() {
      if( (xhr.readyState == 4) && (xhr.status == 200) ) {
        var filename = "config.txt" ;
        var str = xhr.response.getElementById("output").innerHTML ;
        var blob = new Blob([str],{type:'text/plain'}) ;
        if (window.navigator.msSaveBlob) {
        //window.navigator.msSaveBlob(blob, filename);
          window.navigator.msSaveOrOpenBlob(blob,filename) ;
        }
        else {
          var objectURL = window.URL.createObjectURL(blob);
          var link = document.createElement("a");
          document.body.appendChild(link);
          link.href = objectURL;
          link.download = filename;
          link.click();
          document.body.removeChild(link);
        }
      }
    }
    xhr.send();
  }
</script>
 
</body>
</html>

WiFi設定 HTML (wifi_conf.html)  は、MCP23017 レジスタアクセスと同じ。
XHR 応答 HTML (resp_cnfld.html) は、MCP23017 レジスタアクセスと同じ。

MAIN (変数定義, setup, loop 関数)
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
/* +========================================================================+ */
/* | MCP23017 TEST                                                          | */
/* +========================================================================+ */
                                              //
#include <Wire.h>                             //
#include <WiFi.h>                             //
#include "FS.h"                               // SPIFFS 用
#include "SPIFFS.h"                           // SPIEES 用
                                              //
// +------------------------------------------------------------------------+
// | WiFi 設定用定義                                                        |
// +------------------------------------------------------------------------+
// AP モード用 WIFI 設定 ----------------------------------------------------
const char ssid[] = "ESP32_AP";               // SSID for softAP
const char pass[] = "password";               // password for softAP
const IPAddress ip(192, 168, 4, 1);           // IPアドレス for softAP
const IPAddress subnet(255, 255, 255, 0);     // サブネットマスク for softAP
// AP/STA 動作モードフラグ --------------------------------------------------
bool stamode = true ;                         // WiFi STA 接続モード : true
bool sta_exec = false ;                       // WiFi STA接続モード実行中フラグ
bool config_mode  = false ;                   // 初期設定モード ; true
bool config_exec = false ;                    // 初期設定実行中フラグ
// WiFi 設定ファイル用 ------------------------------------------------------
String s_config ;                             // 設定ファイル用 String
char wifi_ssid[128] = "" ;                    // SSID        for WiFi STA
char wifi_pass[128] = "" ;                    // password    for WiFi STA
IPAddress wifi_ip(192,168,1,66) ;             // IP Address  for WiFi STA
IPAddress wifi_gw(192,168,1,1)  ;             // gate way    for WiFi STA
IPAddress wifi_sm(255,255,255,0) ;            // subnet mask for WiFi STA
IPAddress wifi_dns(192,168,1,1) ;             // dns address for WiFi STA
char wifi_mode[16] = ""   ;                   // wifi mode
String foot_msg ="WiFi設定を変更した場合、反映するには再起動して下さい。" ;
                                              // リブートメッセージ用
bool config_dl = false ;                      // 設定ファイルダウンロード要求フラグ
 
WiFiServer server(80);
 
String html_CONF ;                            // 設定用 HTML
String html_MAIN ;                            // メイン HTML
String html_resp ;                            // XHR レスポンス用
 
// --------------------------------------------------------------------------
 
// +------------------------------------------------------------------------+
// | MCP23017 用定義                                                        |
// +------------------------------------------------------------------------+
bool wadr      = false ;                      // 2B モードフラグ
bool rd_req    = false ;                      // リード要求フラグ
bool wr_req    = false ;                      // ライト要求フラグ
bool dmp_req   = false ;                      // ダンプ要求フラグ
bool spdchg_req   = false ;                   // 速度変更要求フラグ
byte sadr      = 0x21 ;                       // slave address
byte regadr    = 0x0  ;                       // regadr
byte wrdt      = 0x00 ;                       // write data
byte rddt      = 0x00 ;                       // read date
byte dmpdt[32] = {0,0,0,0,0,0,0,0,            // dump data
                  0,0,0,0,0,0,0,0,            //         
                  0,0,0,0,0,0,0,0,            //         
                  0,0,0,0,0,0,0,0 } ;         //         
bool fstmod    = false ;                      // 転送速度 400Kモード(fst_mod)
 
float acstim = 0 ;                            // アクセス時間
float dmptim = 0 ;                            // ダンプ時アクセス時間
unsigned long start_tim ;                     // 開始時間
unsigned long end_tim ;                       // 終了時間
unsigned long exe_tim ;                       // 実行時間
 
/* +========================================================================+ */
/* | 初期設定                                                               | */
/* +========================================================================+ */
void setup()
{
  // +------------------------------------------------------------------------+
  // | Serial 出力用 SetUp                                                    |
  // +------------------------------------------------------------------------+
  Serial.begin(115200);                        // シリアル 開始
  SPIFFS.begin(true) ;                         // SPIFFS 開始
                                               //
  // +------------------------------------------------------------------------+
  // | WiFi 用 SetUp                                                          |
  // +------------------------------------------------------------------------+
  int res = 0 ;                                // 結果格納用 (ワーク)
                                               //
  // 初期設定用 HTML ファイルの読み込み ---------------------------------------
  res = rd_SPIFFS("/WiFi_Config.html",html_CONF) ;
                                               // html_CONF に Config.html を格納
  // 本体 HTML ファイルの読み込み ----------------------------------------------
  res = rd_SPIFFS("/main.html",html_MAIN) ;    // html_MAIN に main.html を格納
                                               //
  // レスポンス用HTML ファイルの読み込み ----------------------------------------
  res = rd_SPIFFS("/resp_cnfld.html",html_resp) ;
                                               // html_resp に resp_confld.html を格納
  // 初期設定ファイルを読み込み、グローバル変数に設定し、wifi,画面モードを決定 ---
  res = rd_config() ;                          //
                                               //
  // wifiモード(stamode) に応じて AP か STA かを選択してサーバー起動 -------------
  if (stamode == false) {                      // APモードの場合 softAP WiFi 開始
    start_AP_server() ;                        // APモードでサーバー起動
    sta_exec = false ;                         //
  } else {                                     // STAモードの場合 Wifi 開始
    start_STA_server() ;                       // APモードでサーバー起動
    sta_exec = true ;                          //
  }                                            //
                                               //
  // 実行中のモード (設定かメインか) を設定 -------------------------------------
  if (config_mode) config_exec = true ;        // config_mode なら config_exec を '1'
  else config_exec = false ;                   //
                                               //
  Serial.println("Server start!");             //
                                               //
  // +------------------------------------------------------------------------+
  // | メイン処理用設定                                                       |
  // +------------------------------------------------------------------------+
  Wire.begin();
  Wire.setClock(100000);
 
  // set direction IOA,IOB
  //I2C_BWR(MCP23017,IODIRA,0xFE) ;   // set IOA0 : output
  //I2C_BWR(MCP23017,IODIRB,0x7F) ;   // set IOB7 : output
  //I2C_BWR(MCP23017,GPPUA,0x80) ;    // set IOA7 : PullUp
 
}
 
 
/* +========================================================================+ */
/* | メインループ                                                           | */
/* +========================================================================+ */
void loop()
{
  // +------------------------------------------------------------------------+
  // | WiFi 処理                                                              |
  // +------------------------------------------------------------------------+
  WiFiClient client = server.available();
  String htmlwk = "" ;                            // html 用 ワーク変数
  String line   = "" ;                            // クライアントからの入力用
  int xhr = 0 ;                                   // xhr 要求フラグ
  
  // HTML クライアント処理 ------------------------------------------------------
  if (client) {
    Serial.println(" +++++++++++++++++ new client! +++++++++++++++++ ");
    while (client.connected()) {                  // クライアントから接続されたとき
      if (client.available()) {                   //
        line = client.readStringUntil('\n');      // 1行分取得
//      # ifdef DEBUG_HTML                        //
          Serial.println(line) ;                  //
//      # endif                                   //
        if (line.indexOf("GET /?") != -1) {       // GET 処理
          if (config_mode)                        // 初期設定用 フォームデータ処理
            set_form2param(line) ;                //   フォームデータを変数に格納
          else {                                  // メイン用 処理
            xhr = proc_form(line) ;               //   フォームデータのメイン処理
          }                                       //
        }                                         //
        // 最終行(空行)を受信した時 -------------------------------------------
        if (line.length() == 1 && line[0] == '\r'){  // 最終行判定
          if (stamode != sta_exec) {             // sta_mode が変わった場合
            if (strcmp(wifi_mode,"ap") == 0){    //  リブートメッセージを設定
              foot_msg = "アクセスポイントモードに移行します。<br>" ;
              foot_msg += "この画面を閉じてアクセスポイントに接続して下さい。" ;
             }else{
             foot_msg = "ステーションモードに移行します。<br>";
               foot_msg += "この画面を閉じて 設定したアドレスに接続して下さい。" ;
             }
            if (config_exec) {                    //   初期設定中なら
              send_CONF_html(client) ;            //     初期設定 HTML 送信
            } else {                              //   メイン画面なら
              send_MAIN_html(client) ;            //     メイン HTML 送信
            }                                     //    ( その後 リブート)
          } else {                                // sta_mode が変わらない場合
            if (config_mode) {                    //   次に初期設定を表示するなら
              send_CONF_html(client) ;            //     初期設定 HTML 送信
              config_exec = true ;                //
            } else {                              //   次にメイン画面なら
              if (rd_req) {                       //     リード要求フラグが ON なら
                start_tim = micros() ;            //     開始時刻を取得
                rddt = I2C_BRD(sadr,regadr) ;     //     リードを実行
                end_tim = micros() ;              //     終了時刻を取得
                exe_tim = (end_tim - start_tim) ; //     実行時間を取得
                acstim = (float)(exe_tim) ;        //     アクセス時間を取得
                rd_req = false ;                  //
              }                                   //
              if (wr_req) {                       //     ライト要求フラグが ON なら
                start_tim = micros() ;            //     開始時刻を取得
                I2C_BWR(sadr,regadr,wrdt) ;       //      ライトを実行
                end_tim = micros() ;              //     終了時刻を取得
                rddt = I2C_BRD(sadr,regadr) ;     //      リードを実行
                exe_tim = (end_tim - start_tim) ; //     実行時間を取得
                acstim = (float)(exe_tim) ;       //     アクセス時間を取得
                wr_req = false ;                  //
              }                                   //
              if (dmp_req) {                      //     ダンプ要求フラグが ON なら
                start_tim = micros() ;            //     開始時刻を取得
                reg_dmp() ;                       //      ダンプ動作を実行
                end_tim = micros() ;              //     終了時刻を取得
                exe_tim = (end_tim - start_tim) ; //     実行時間を取得
                dmptim = (float)(exe_tim)/22 ;    //     アクセス時間を取得
                dmp_req = false ;                 //
              }                                   //
              if (spdchg_req) {                   //     速度変更要求フラグが ON なら
                if (fstmod) {                     //       fstmod なら
                  Wire.setClock(400000);          //         400K
                } else {                          //       違えば
                  Wire.setClock(100000);          //         100K
                }                                 //
                spdchg_req = false ;              //
              }                                   //
              if (xhr) {                          //     XHR 応答の場合
                send_resp_html(client) ;          //       XHR 応答 送信
              } else {                            //     HTML 送信なら
                send_MAIN_html(client) ;          //     メイン HTML 送信
                config_exec = false ;             //
              }                                   //
            }                                     //
          }                                       //
          # ifdef DEBUG_HTML                      //
            Serial.println("Send HTML") ;         //
          # endif                                 //
          break ;                                 // ループ終了
        }                                         //
        //-------------------------------------------------------------------
      }
    }
    // 接続が切れた場合 ------------------------------------------------------
    client.stop();
    Serial.println("client disonnected");
    Serial.println("----------------------------------------------------");
  }
 
  if (stamode != sta_exec) {                      // sta_mode が変わった場合
    Serial.println("------------------- リブートします------------------- ");
    delay(500);                                   //
    ESP.restart() ;                               // リブート
  } else {
  }
  // --------------------------------------------------------------------------
}

WIFI設定 (主に WiFI 設定用 の関数)  は、MCP23017 レジスタアクセスと同じ。

WIFI処理 (主に MAIN処理(レジスタアクセス)の WEB画面処理 )
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
// *****************************************************************************
// * SPIFFS ファイルを String に読み込む                                       *
// *****************************************************************************
int rd_SPIFFS(String fname, String &sname) {     //
  File fp = SPIFFS.open(fname,"r") ;             // ファイルをオープンする
  if (!fp) {                                     //  オープン失敗の場合
    Serial.print(fname) ;                        //
    Serial.println(" : file open error") ;       //
    return -1 ;                                  //    戻り値 -1
  }else {                                        //  オープン出来たら
    sname = fp.readString() ;                    //    String変数に読み込む
    fp.close() ;                                 //
  }                                              //
  return 0 ;                                     //  オープン出来た時のみ
}                                                //    戻り値 0
                                                 //
// ****************************************************************************
// * ステーションモードで サーバーを起動                                      *
// ****************************************************************************
void start_STA_server() {
  int lpcnt = 0 ;                                    // ループカウント
  int lpcnt2 = 0 ;                                   // ループカウント2
 
  WiFi.config(wifi_ip, wifi_gw, wifi_sm, wifi_dns);  // Set fixed IP address
  delay(10) ;                                        //
  WiFi.begin(wifi_ssid, wifi_pass);                  // wifi 開始
  lpcnt = 0 ;                                        //
  lpcnt2 = 0 ;                                       //
  while (WiFi.status() != WL_CONNECTED) {            // 接続確認
      lpcnt += 1 ;                                   //
      if (lpcnt > 4) {                               //
        WiFi.begin(wifi_ssid, wifi_pass);            // 4回目(2秒) で再度開始指示
        lpcnt = 0 ;                                  //
        lpcnt2 += 1 ;                                //
      }                                              //
      if (lpcnt2 > 5) {                              // 2秒x5 接続できなければ、
        stamode = false ;                            // APモードにして
        ESP.restart() ;                              // 再起動
      }                                              //
      Serial.print(".");                             //
      delay(500);                                    //   0.5秒毎にチェック
  }                                                  //
  server.begin();                                    // サーバー開始
}
 
// *****************************************************************************
// * HTML 送信処理                                                             *
// *****************************************************************************
 
// ----------------------------------------------------------------------------
// - CONF_HTML 送信                                                           -
// ----------------------------------------------------------------------------
void send_MAIN_html(WiFiClient client) {
  String htmlwk ;
 
  htmlwk = html_MAIN ;                          // htmlwk に HTML をコピー
  htmlwk.replace("$s_adr",String(sadr,HEX)) ;       // 変数を値に置き換える
  htmlwk.replace("$reg_adr",String(regadr,HEX)) ;   // 変数を値に置き換える
  htmlwk.replace("$wr_dt",String(wrdt,HEX)) ;       // 変数を値に置き換える
  htmlwk.replace("$rd_dt",String(rddt,HEX)) ;       // 変数を値に置き換える
  htmlwk.replace("$rdt00",String(dmpdt[0],HEX)) ;  // 変数を値に置き換える
  htmlwk.replace("$rdt01",String(dmpdt[1],HEX)) ;  // 変数を値に置き換える
  htmlwk.replace("$rdt02",String(dmpdt[2],HEX)) ;  // 変数を値に置き換える
  htmlwk.replace("$rdt03",String(dmpdt[3],HEX)) ;  // 変数を値に置き換える
  htmlwk.replace("$rdt04",String(dmpdt[4],HEX)) ;  // 変数を値に置き換える
  htmlwk.replace("$rdt05",String(dmpdt[5],HEX)) ;  // 変数を値に置き換える
  htmlwk.replace("$rdt06",String(dmpdt[6],HEX)) ;  // 変数を値に置き換える
  htmlwk.replace("$rdt07",String(dmpdt[7],HEX)) ;  // 変数を値に置き換える
  htmlwk.replace("$rdt08",String(dmpdt[8],HEX)) ;  // 変数を値に置き換える
  htmlwk.replace("$rdt09",String(dmpdt[9],HEX)) ;  // 変数を値に置き換える
  htmlwk.replace("$rdt0a",String(dmpdt[10],HEX)) ;  // 変数を値に置き換える
  htmlwk.replace("$rdt0b",String(dmpdt[11],HEX)) ;  // 変数を値に置き換える
  htmlwk.replace("$rdt0c",String(dmpdt[12],HEX)) ;  // 変数を値に置き換える
  htmlwk.replace("$rdt0d",String(dmpdt[13],HEX)) ;  // 変数を値に置き換える
  htmlwk.replace("$rdt0e",String(dmpdt[14],HEX)) ;  // 変数を値に置き換える
  htmlwk.replace("$rdt0f",String(dmpdt[15],HEX)) ;  // 変数を値に置き換える
  htmlwk.replace("$rdt10",String(dmpdt[16],HEX)) ;  // 変数を値に置き換える
  htmlwk.replace("$rdt11",String(dmpdt[17],HEX)) ;  // 変数を値に置き換える
  htmlwk.replace("$rdt12",String(dmpdt[18],HEX)) ; // 変数を値に置き換える
  htmlwk.replace("$rdt13",String(dmpdt[19],HEX)) ; // 変数を値に置き換える
  htmlwk.replace("$rdt14",String(dmpdt[20],HEX)) ; // 変数を値に置き換える
  htmlwk.replace("$rdt15",String(dmpdt[21],HEX)) ; // 変数を値に置き換える
  htmlwk.replace("$footer",foot_msg ) ;         // 変数を値に置き換える
 
  if (fstmod) {                                 // fstmod(400K)の時
    htmlwk.replace("$checked_std","") ;         //
    htmlwk.replace("$checked_fst","checked") ;  //
  } else {                                      //
    htmlwk.replace("$checked_std","checked") ;  //
    htmlwk.replace("$checked_fst","") ;         //
  }                                             //
  htmlwk.replace("$acs_spd",String(acstim)) ;   // 変数を値に置き換える
  htmlwk.replace("$dmp_spd",String(dmptim)) ;   // 変数を値に置き換える
                                                //
  send_html(client,htmlwk) ;                    // HTML 送信処理
 
}
 
// ----------------------------------------------------------------------------
// - HTML 送信処理                                                            -
// ----------------------------------------------------------------------------
void send_html(WiFiClient client, String &html ) {
    client.println("HTTP/1.1 200 OK");           //
    client.println("Content-type:text/html");    //
    client.println();                            //
                                                 //
    client.print(html) ;                         //
 
    # ifdef DEBUG                                //
        Serial.println( " --- send html --- ");  //
    #endif                                       //
}
 
// ----------------------------------------------------------------------------
// - XHR RESPONSE_HTML 送信                                                   -
// ----------------------------------------------------------------------------
void send_resp_html(WiFiClient client) {        //
  String htmlwk ;                               // HTML 編集用 ワーク
                                                //
  htmlwk = html_resp ;                          // htmlwk に HTML をコピー
                                                //
  // 変数を値に変換-----------------------------//
  htmlwk.replace("$cnf_text",s_config) ;        // 変数に 設定文字列をセット
                                                //
  send_html(client,htmlwk) ;                    // HTML 送信処理
      Serial.print("xhr html  :"); Serial.println(htmlwk);
# ifdef DEBUG_WiFi                              //
      Serial.print("xhr value :"); Serial.println(duty);
#endif                                          //
}                                               //
                                                //
 
// *****************************************************************************
// * フォームデータ処理                                                        *
// *****************************************************************************
int  proc_form(String &line) {
  String s_work ="" ;
  int xhr = 0 ;
 
  if (line.indexOf("GET /?") != -1) {            // "form" が押下された時
    if (line.indexOf("config=") != -1) {         // wifi 設定なら
      config_mode = true ;                       //   設定モードにする
    }                                            //
    if (line.indexOf("cnfdl") != -1) {           // config.txt のダウンロード時
      config_dl = true ;                         //   設定ダウンロード要求フラグ ON
      xhr = 1 ;                                  //   XHR 応答にする。
    }                                            //
    if (line.indexOf("read") != -1) {            // "read" が押下された時
      if (line.indexOf("sadr=") != -1) {         //   sadr
        sadr   = getvalue_h(line,"sadr=") ;      //     sadr に続く数値を変数にセット
      }                                          //
      if (line.indexOf("regadr=") != -1) {       //   regadr
        regadr = getvalue_h(line,"regadr=") ;    //     sadr に続く数値を変数にセット
      }                                          //
      rd_req = true ;                            //   リード要求フラグを ON
    }                                            //
    if (line.indexOf("write") != -1) {           // "write" が押下された時
      if (line.indexOf("sadr=") != -1) {         //   sadr
        sadr   = getvalue_h(line,"sadr=") ;      //     sadr に続く数値を変数にセット
      }                                          //
      if (line.indexOf("regadr=") != -1) {       //   regadr
        regadr = getvalue_h(line,"regadr=") ;    //     sadr に続く数値を変数にセット
      }                                          //
      if (line.indexOf("wrdt=") != -1) {         //   wrdt
        wrdt   = getvalue_h(line,"wrdt=") ;      //     wrdt に続く数値を変数にセット
      }                                          //
      wr_req = true ;                            //   ライト要求フラグをON
    }                                            //
    if (line.indexOf("spd") != -1) {             // "転送速度" が選択された時
      s_work = getvalue_s(line,"spd=") ;         //     spd に続く文字列を変数にセット
      if (s_work == "std") {                     //     値が "std" なら
        fstmod = false ;                         //       fstmod は false
      } else {                                   //     違えば
        fstmod = true ;                          //       fstmod は true
      }                                          //
      spdchg_req = true ;                        //     速度変更要求
    }                                            //
    if (line.indexOf("dump") != -1) {            // "dump" が押下された時
      dmp_req = true ;                           //    ダンプ動作要求フラグを ON
    }                                            //
  }                                              //
  return xhr ;                                   //
}                                                //
                                                 //
// 要素名に続く値(文字列)を取得する --------------------------------------------
String getvalue_s(String &line,String param) {
  String val="" ;
  int pos = 0 ;
 
  if ((pos=line.indexOf(param)) != -1) {          // 要素名の位置を取得
    pos += param.length() ;                       //
    while(   (line.charAt(pos) != '&')            //
           & (line.charAt(pos) != ' ')            //
           & (line.charAt(pos) != '\n')) {        //
      val += line.charAt(pos++) ;                 //  '&' か ' ' か 行末 まで文字を取得
    }                                             //
  }                                               //
  return val ;                                    //  取得した文字列を返す
}
 
// 要素名に続く値(数値)を取得する ---------------------------------------------
int getvalue_i(String &line,String param) {
  String val="" ;
  int pos = 0 ;
 
  if ((pos=line.indexOf(param)) != -1) {          // 要素名の位置を取得
    pos += param.length() ;                       //
    while((line.charAt(pos) >= '0') & (line.charAt(pos) <= '9')) {
      val += line.charAt(pos++) ;                 //  数値でなくなるまで文字を
    }                                             //  取得
  }                                               //
  return val.toInt() ;                            //  数値に変換して返す
}
 
// 要素名に続く値(数値(HEX))を取得する ----------------------------------------
int getvalue_h(String &line,String param) {
  String val="" ;
  int pos = 0 ;
  byte c= 0 ;
  int dt = 0 ;
 
  if ((pos=line.indexOf(param)) != -1) {          // 要素名の位置を取得
    pos += param.length() ;                       //
    do {                                          //
      c = line.charAt(pos++) ;                    //
      if ((c>='0') & (c<='9')) {                  // 数値の場合
        dt = dt*16 + ( c - 0x30) ;                   //
      } else if ((c>='a') & (c<='f')) {           //
        dt = dt*16 + (c - 87) ;                      // 小文字 a~f の場合
      } else if ((c>='A') & (c<='F')) {           // 大文字 A~F の場合
        dt = dt*16 + (c - 55) ;                      //
      } else {                                    // 16進数値以外
        c = 0xff ;                                //
      }                                           //
    } while (c != 0xff) ;                         //
  }                                               //
  return dt ;                                     //  数値を返す
}
 
// -----------------------------------------------------------------------------


MAIN処理 (主に I2Cアクセス の関数)
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
/* +=======================================================================+ */
/* | MAIN 処理                                                             | */
/* +=======================================================================+ */
 
// I2C WR/READ ----------------------------------------------------------------
void I2C_BWR(byte TGT, byte REGADR, byte DATA) {
  Wire.beginTransmission(TGT);         // transmit to device #TGT
  Wire.write(REGADR);                  // send REG address (REGADR)
  Wire.write(DATA);                    // send write data (DATA)
  Wire.endTransmission();              // end transmit
}
 
byte I2C_BRD(byte TGT,byte REGADR) {
  byte data = 0 ;
  Wire.beginTransmission(TGT);         //  transmit to device #TGT
  Wire.write(REGADR);                  //  send REG address (REGADR)
  Wire.endTransmission();              //  end transmit
  Wire.requestFrom(TGT, 1);            // request 1 byte from slave device #TGT
  data = Wire.read();                  // receive 1 byte
   
  return data ;
}
 
void reg_dmp() {
                                                 //
  dmpdt[0]  = I2C_BRD(sadr,0) ;                  // REG0 リード
  dmpdt[1]  = I2C_BRD(sadr,1) ;                  // REG0 リード
  dmpdt[2]  = I2C_BRD(sadr,2) ;                  // REG0 リード
  dmpdt[3]  = I2C_BRD(sadr,3) ;                  // REG0 リード
  dmpdt[4]  = I2C_BRD(sadr,4) ;                  // REG0 リード
  dmpdt[5]  = I2C_BRD(sadr,5) ;                  // REG0 リード
  dmpdt[6]  = I2C_BRD(sadr,6) ;                  // REG0 リード
  dmpdt[7]  = I2C_BRD(sadr,7) ;                  // REG0 リード
  dmpdt[8]  = I2C_BRD(sadr,8) ;                  // REG0 リード
  dmpdt[9]  = I2C_BRD(sadr,9) ;                  // REG0 リード
  dmpdt[10]  = I2C_BRD(sadr,10) ;                // REG0 リード
  dmpdt[11]  = I2C_BRD(sadr,11) ;                // REG0 リード
  dmpdt[12]  = I2C_BRD(sadr,12) ;                // REG0 リード
  dmpdt[13]  = I2C_BRD(sadr,13) ;                // REG0 リード
  dmpdt[14]  = I2C_BRD(sadr,14) ;                // REG0 リード
  dmpdt[15]  = I2C_BRD(sadr,15) ;                // REG0 リード
  dmpdt[16]  = I2C_BRD(sadr,16) ;                // REG0 リード
  dmpdt[17]  = I2C_BRD(sadr,17) ;                // REG0 リード
  dmpdt[18]  = I2C_BRD(sadr,18) ;                // REG0 リード 18 : 0x12
  dmpdt[19]  = I2C_BRD(sadr,19) ;                // REG0 リード 19 : 0x13
  dmpdt[20]  = I2C_BRD(sadr,20) ;                // REG0 リード 20 : 0x14
  dmpdt[21]  = I2C_BRD(sadr,21) ;                // REG0 リード 21 : 0x15
 
}

  以下、メモ

<HTML>
  • MAIN HTML (main.html)
    (行#32~40)
     転送速度(100Kbit/S, 400Kbit/S) の選択ラジオボタン
     どちらをチェックするかは 変数 で指定
    (行#55~58)
     単発リード/ライトでのアクセス時間表示
    (行#161~164)
     ダンプ時のアクセス時間表示
     22レジスタリードの平均値
<スケッチ>
  • MAIN (変数定義, setup, loop 関数) 
    (行#51,60~66)
     速度設定、アクセス時間測定用の変数定義
    (行#115)
     初期の速度設定(100Kbit/S, なくても可)
    (行#175,177~179)
     単発リード時のアクセス時間測定
    (行#183,185,187,188)
     単発ライト時のアクセス時間測定
    (行#192,194~196)
     ダンプ時のアクセス時間測定
     22レジスタリードの為、その平均を算出
    (行#199~206)
     転送速度設定時の処理
     転送速度に応じて設定
    (行#236~)
     不要なコメント削除
  • WIFI処理 (主に MAIN処理(レジスタアクセス)の WEB画面処理 )
    (行#85~94)
     HTML送信時の処理で速度設定、アクセス速度の変数を値に置き換える。
    (行#169~177)
     フォームデータ処理で、転送速度が設定された時の処理を追加。
    (行#192,193,194,195)
     フォームデータの要素名の後の文字列を取得する関数で、区切り文字として ' '(スペース) を追加。
  • MAIN処理 (主に I2Cアクセス の関数)
    (行#11,20)
     シリアル出力(デバッグ用)を削除。
     アクセス速度の測定に影響する為。




0 件のコメント:

コメントを投稿