質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Webサーバー

Webサーバーとは、HTTPリクエストに応じて、クライアントに情報を提供するシステムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

3078閲覧

[ESP32]Webサーバ側からHTML(javascript)側へ配列を渡して、TABLEを生成したい

Mudo_Ayumu

総合スコア7

Webサーバー

Webサーバーとは、HTTPリクエストに応じて、クライアントに情報を提供するシステムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

1クリップ

投稿2021/09/30 07:16

前提

普段はハード設計や製造をしているソフト初心者です。今回初めてプログラミングをしています。事前にC言語の基本だけ軽く勉強しました。
ESP32にsoftAP機能とAsyncwebserverを実装して、非同期Webサーバとして運用しています。
基板にロータリーエンコーダが接続されており、HTML Webページ上から測定開始や、測定距離の記録などを行うアプリを実現したいと思っています。
イメージ説明

現状実現できていること

・タイマーを使ったロータリーエンコーダの高速読み取り
・カウント数、距離換算値などを非同期で更新
・各種ボタンを押した際にHTML側からサーバ側にPOSTし、画面遷移せずに関数を呼び出したりできる
イメージ説明

イメージ説明

行き詰っている部分

HTML画面上でENDボタンを押した際に、記録されている各配列のデータをTABLEとして
画面上に生成したいです。

サーバ側とHTML側(javascript側?)間の単一文字列のやり取りは実現できていますが、
サーバ側からHTML側に配列を渡す方法が分かりません。
その先で、渡された配列をもとに必要な行数を持ったTABLEを生成する方法もまだよく分かりません…

該当のソースコード

重要そうな部分のみ

Arduino

1//////////get処理////////// 2 3String getENC1_count() 4{ 5 sprintf( tempcbuf, "%20lld",enc1_count); 6 return String(tempcbuf); 7} 8String getENC1_dist() 9{ 10 dtostrf( enc1_dist, 10, 2, tempcbuf); 11 return String(tempcbuf); 12} 13 14String getsection_number() 15{ 16 sprintf( tempcbuf, "%d",section_number); 17 return String(tempcbuf); 18} 19 20String getsection_length() 21{ 22 section_length_display = enc1_dist - mark_point[section_number]; 23 dtostrf( section_length_display, 10, 2, tempcbuf); 24 return String(tempcbuf); 25} 26 27//////////function////////// 28 29void START_f() 30{ 31 if (!COUNT_EN) 32 { 33 COUNT_EN = 1 ; 34 if (!section_number) 35 { 36 mark_point[section_number] = enc1_dist ; 37 } 38 Serial.println("COUNT START NOW"); 39 Serial.print("COUNT_EN = ");Serial.println(COUNT_EN); 40 } 41 else 42 { 43 Serial.println("COUNT is already ENABLE"); 44 } 45} 46 47void mark_point_f() 48{ 49 mark_point[section_number + 1] = enc1_dist ; 50 section_length[section_number] = mark_point[section_number + 1] - mark_point[section_number]; 51 Serial.print("Section"); 52 Serial.print(section_number); 53 Serial.printf("\t区間長: "); 54 Serial.print(section_length[section_number]);Serial.print("[mm]"); 55 section_number ++; 56} 57 58void END_f() 59{ 60 Serial.printf("\n-----RESULT-----\n"); 61 int i ; 62 for ( i=0 ; section_number > i ; i++ ) 63 { 64 Serial.print("Section"); 65 Serial.print(i); 66 Serial.printf("\t区間長: "); 67 Serial.print(section_length[i]);Serial.print("[mm]"); 68 } 69 COUNT_EN = 0 ; 70} 71 72//////////HTTP////////// 73 74void HTTP_task(void *pvParameters) 75{ 76 // サーバーのルートディレクトリにアクセスされた時のレスポンス 77 server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ 78 request->send(SPIFFS, "/index.html", String(), false ); 79 delay(1) ; 80 }); 81 82 // POST解析&処理 83 server.on("/POST_Receiver", HTTP_POST, [](AsyncWebServerRequest *request) { 84 int params = request->params(); // 85 for(int i=0;i<params;i++) 86 { 87 AsyncWebParameter* p = request->getParam(i); 88 Serial.printf("POST[%s]: %s\n", p->name().c_str(), p->value().c_str()); 89 String param = p->value().c_str(); 90 if( param == "START" ){START_f();} 91 else if( param == "MARK" ){mark_point_f();} 92 else if( param == "END" ){END_f();} 93 else if( param == "RESET" ){RESET_f();} 94 } 95 delay(1) ; 96 }); 97 98 /////JavaScript 更新///// 99 server.on("/ENC1_count", HTTP_GET, [](AsyncWebServerRequest *request){ 100 request->send(200, "text/plain", getENC1_count()); 101 delay(1) ; 102 }); 103 104 server.on("/ENC1_dist", HTTP_GET, [](AsyncWebServerRequest *request){ 105 request->send(200, "text/plain", getENC1_dist()+" [mm]"); 106 delay(1) ; 107 }); 108 109 server.on("/section_number", HTTP_GET, [](AsyncWebServerRequest *request){ 110 request->send(200, "text/plain", getsection_number()); 111 delay(1) ; 112 }); 113 114 server.on("/section_length", HTTP_GET, [](AsyncWebServerRequest *request){ 115 request->send(200, "text/plain", getsection_length()+" [mm]"); 116 delay(1) ; 117 }); 118} 119 120//////////setup&loop////////// 121 122void setup() 123{ 124 Serial.begin(115200); 125 // SPIFFSのセットアップ 126 if(!SPIFFS.begin(true)) 127 { 128 Serial.println("An Error has occurred while mounting SPIFFS"); 129 return; 130 } 131 132 pinMode( ENC1_A , INPUT_PULLUP); 133 pinMode( ENC1_B , INPUT_PULLUP); 134 135 //無線LAN接続APモード 136 delay(200); 137 WiFi.mode(WIFI_AP); 138 WiFi.softAP(ap_ssid, ap_password); 139 WiFi.softAPConfig(ip, ip, subnet); 140 IPAddress myIP = WiFi.softAPIP(); 141 142 xTaskCreateUniversal(HTTP_task,"HTTP_task",8192,NULL,2,&httptaskHandle,APP_CPU_NUM); 143 144 // サーバースタート 145 server.begin(); 146 147 timer1 = timerBegin(0, 80, true); 148 timerAttachInterrupt(timer1, &ENC_READ, true); 149 timerAlarmWrite(timer1, 20 , true); 150 timerAlarmEnable(timer1); 151} 152 153void loop() 154{ 155 delay(200); 156}

HTML

1 <body> 2 3 <div class="title"> 4 <h1 class="title_item"> 5 <p>AsyncWebServer_TEST</p> 6 </h1> 7 </div> 8 9 <div class="ENC_stat"> 10 <SPAN>ENC COUNT : </SPAN><SPAN id="ENC1_count">%ENC_count%</SPAN> 11 </div> 12 <div class="ENC_stat"> 13 <SPAN>ENC DISTANCE : </SPAN><SPAN id="ENC1_dist">%ENC_dist%</SPAN> 14 </div> 15 <div class="ENC_stat2"> 16 <SPAN>SECTION NUMBER : </SPAN><SPAN id="section_number">%section_number%</SPAN> 17 </div> 18 <div class="ENC_stat2"> 19 <SPAN>SECTION LENGTH : </SPAN><SPAN id="section_length">%section_length%</SPAN> 20 </div> 21 22 <p id="OPERATING_STATUS">%OPERATING_STATUS%</p> 23 24 <div> 25 <button id="START" class="SW" type="button" name="ST_SW" value="START" onclick="POST_event(this.id);"><p class="SWtext">START</p></button> 26 <button id="MARK" class="SW" type="button" name="MK_SW" value="MARK" onclick="POST_event(this.id);"><p class="SWtext">MARK</p></button> 27 </div> 28 <div> 29 <button id="END" class="SW" type="button" name="END_SW" value="END" onclick="POST_event(this.id);"><p class="SWtext">END</p></button> 30 <button id="RESET" class="SW" type="button" name="RESET_SW" value="RESET" onclick="POST_event(this.id);"><p class="SWtext">RESET</p></button> 31 </div> 32 33 <div class="SECTION_DATA"> 34 <table> 35 <thead> 36 <tr><th>区間番号</th><th>積算長[mm]</th><th>区間長[mm]</th></tr> 37 </thead> 38 <tbody> 39 <tr><td>0</td><td>a</td><td>a</td></tr> 40 <tr><td>1</td><td>a+b</td><td>b</td></tr> 41 <tr><td>2</td><td>a+b+c</td><td>c</td></tr> 42 <tr><td>3</td><td>a+b+c+d</td><td>d</td></tr> 43 </tbody> 44 </table> 45 </div> 46 47<script> 48 //ENC1_count 49 var getENC1_count = function () 50 { 51 var xhr = new XMLHttpRequest(); 52 xhr.onreadystatechange = function() 53 { 54 if (this.readyState == 4 && this.status == 200) 55 { 56 document.getElementById("ENC1_count").innerHTML = this.responseText; 57 } 58 }; 59 xhr.open("GET", "/ENC1_count", true); 60 xhr.send(null); 61 } 62 setInterval(getENC1_count, 200); 63 64 //ENC1_dist 65 var getENC1_dist = function () 66 { 67 var xhr = new XMLHttpRequest(); 68 xhr.onreadystatechange = function() 69 { 70 if (this.readyState == 4 && this.status == 200) 71 { 72 document.getElementById("ENC1_dist").innerHTML = this.responseText; 73 } 74 }; 75 xhr.open("GET", "/ENC1_dist", true); 76 xhr.send(null); 77 } 78 setInterval(getENC1_dist, 200); 79 80 //section_number 81 var getsection_number = function () 82 { 83 var xhr = new XMLHttpRequest(); 84 xhr.onreadystatechange = function() 85 { 86 if (this.readyState == 4 && this.status == 200) 87 { 88 document.getElementById("section_number").innerHTML = this.responseText; 89 } 90 }; 91 xhr.open("GET", "/section_number", true); 92 xhr.send(null); 93 } 94 setInterval(getsection_number, 200); 95 96 //section_length 97 var getsection_length = function () 98 { 99 var xhr = new XMLHttpRequest(); 100 xhr.onreadystatechange = function() 101 { 102 if (this.readyState == 4 && this.status == 200) 103 { 104 document.getElementById("section_length").innerHTML = this.responseText; 105 } 106 }; 107 xhr.open("GET", "/section_length", true); 108 xhr.send(null); 109 } 110 setInterval(getsection_length, 200); 111 112 //OPERATING_STATUS 113 var getOPERATING_STATUS = function () 114 { 115 var xhr = new XMLHttpRequest(); 116 xhr.onreadystatechange = function() 117 { 118 if (this.readyState == 4 && this.status == 200) 119 { 120 document.getElementById("OPERATING_STATUS").innerHTML = this.responseText; 121 } 122 }; 123 xhr.open("GET", "/OPERATING_STATUS", true); 124 xhr.send(null); 125 } 126 setInterval(getOPERATING_STATUS, 1000); 127 128 //POST 129 function POST_event(buttonID) 130 { 131 var XHR = new XMLHttpRequest(); 132 var postDatas = new FormData(formDatas); 133 var formDatas = document.getElementById(buttonID).value; 134 postDatas.append("param", formDatas); 135 XHR.open("POST", "/POST_Receiver", true); 136 XHR.send(postDatas); 137 document.getElementById("text").innerHTML = formDatas; 138 setInterval(POST_event, 200); 139 } 140 141 </script> 142 </html>

以上、どなたかアドバイスいただけると嬉しいです

補足情報(FW/ツールのバージョンなど)

Arduino IDE 1.8.13

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ESP32で配列の情報を格納したJSON文字列を作成して、JavaScriptでJSON文字列をパースすればいいのではないでしょうか?

投稿2021/10/01 23:39

mkgt00

総合スコア165

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Mudo_Ayumu

2021/10/05 07:17

回答ありがとうございます。 JSONという要素の知識がないので、これから勉強してみます。 連想配列と似てて使い勝手が良さそうですね(連想配列もまだしっかりと勉強できていませんが…) 自分でもいろいろ考えてみました。 まだ実装できていないのですが、後々必要になってくるであろう機能としてログ生成(CSV)があるので、 計算時にSPIFFSにcsvファイルを作成してそこに各種計算データを格納しようという方向性で行こうと思っています。 なので、javascript側で該当のCSVを基にテーブル生成するように頑張ってみるつもりです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問