<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[COM.LTE Module(SIM7600G)でデータ送信ができません]]></title><description><![CDATA[<h1>タイトル</h1>
<p dir="auto">M5stack basicを用いて、COM.LTE Module(SIM7600G)によりデータ送信をする方法がわかりません。</p>
<h1>詳しい状況の説明</h1>
<p dir="auto">Arduino言語により、m5stack basicを用いたCOM.LTE Module(SIM7600G)の簡易的な通信システムを制作しています。<br />
データはGoogleスプレッドシートに表示させたいと考えています。<br />
wifi通信を用いた場合では、意図した通りにGoogleスプレッドシートにデータが表示されました。</p>
<p dir="auto">ところが、COM Xを用いた際には表示されないため困っています。</p>
<p dir="auto">通信強度とインターネット接続状況を確認するために、<br />
COM.LTEModule(SIM7600G)の公式HPよりArduino Example Code<br />
（<a href="https://docs.m5stack.com/en/module/comx_lte%EF%BC%89" target="_blank" rel="noopener noreferrer nofollow ugc">https://docs.m5stack.com/en/module/comx_lte）</a><br />
に記載されていたサンプルコードを用いました。</p>
<p dir="auto">ATコマンドを用いたプログラムのため、ネットワークの登録状況を確認するコマンドの「AT＋CREG?」を使用しました。結果は</p>
<p dir="auto">AT＋CREG?<br />
＋CREG?：0,3<br />
OK</p>
<p dir="auto">となったためインターネットには接続できていると考えています。<br />
ですがデータ通信を行うことができませんでした。<br />
wifi通信を用いた場合ではGoogleスプレッドシートにデータが表示されました。</p>
<p dir="auto">データ送信はHTTPリクエストのPOST通信を使用。以下の記事を参考にしました。<br />
（<a href="https://msr-r.net/m5stack-googlesheets/%EF%BC%89" target="_blank" rel="noopener noreferrer nofollow ugc">https://msr-r.net/m5stack-googlesheets/）</a></p>
<p dir="auto">COM XのLTEを用いた形でデータ送信を完成させたいと考えておりますが<br />
どのようにすれば良いのかアドバイスをいただけないでしょうか。</p>
<h1>使用しているUIFlowやArduinoライブラリのバージョン</h1>
<ul>
<li>Arduino IDE 2.3.3</li>
<li></li>
</ul>
<h1>コード</h1>
<p dir="auto">[M5stack basic のコード]</p>
<p dir="auto">#include &lt;M5Stack.h&gt;<br />
#include &lt;stdint.h&gt;<br />
#include &lt;vector&gt;<br />
#include "TFTTerminal.h"</p>
<p dir="auto">#include &lt;WiFi.h&gt;                                   //serial通信のinclude<br />
#include &lt;WiFiMulti.h&gt;<br />
#include &lt;HTTPClient.h&gt;<br />
#include &lt;ArduinoJson.h&gt;</p>
<p dir="auto">TFT_eSprite Disbuff      = TFT_eSprite(&amp;M5.Lcd);<br />
TFT_eSprite TerminalBuff = TFT_eSprite(&amp;M5.Lcd);<br />
TFTTerminal terminal(&amp;TerminalBuff);<br />
TaskHandle_t xhandle_lte_event = NULL;<br />
SemaphoreHandle_t command_list_samap;</p>
<p dir="auto">const int capacity = JSON_OBJECT_SIZE(2);           //serial通信をする<br />
StaticJsonDocument&lt;capacity&gt; json_request;<br />
char buffer[255];<br />
const char <em>url = "＊＊＊＊＊";<br />
unsigned long counter = 0;<br />
unsigned long tick = 0;<br />
const char</em> data = "Hello World";</p>
<p dir="auto">const String sim_apn = "<a href="http://ppsim.jp" target="_blank" rel="noopener noreferrer nofollow ugc">ppsim.jp</a>";<br />
const String sim_user = "pp@sim";<br />
const String sim_pass = "jpn";</p>
<p dir="auto">typedef enum {<br />
kQUERY_MO = 0,<br />
KTEST_MO,<br />
kASSIGN_MO,<br />
kACTION_MO,<br />
kQUERY_MT,<br />
kTEST_MT,<br />
kASSIGN_MT,<br />
kACTION_MT,<br />
kINFORM<br />
} LTEMsg_t;</p>
<p dir="auto">typedef enum {<br />
kErrorSendTimeOUT = 0xe1,<br />
kErrorReError     = 0xe2,<br />
kErroeSendError   = 0xe3,<br />
kSendReady        = 0,<br />
kSending          = 1,<br />
kWaitforMsg       = 2,<br />
kWaitforRead      = 3,<br />
kReOK<br />
} LTEState_t;</p>
<p dir="auto">struct ATCommand {<br />
uint8_t command_type;<br />
String str_command;<br />
uint16_t send_max_number;<br />
uint16_t max_time;<br />
uint8_t state;<br />
String read_str;<br />
uint16_t _send_count;<br />
uint16_t _send_time_count;</p>
<p dir="auto">} user;</p>
<p dir="auto">using namespace std;<br />
vector&lt;ATCommand&gt; serial_at;<br />
String zmmi_str;<br />
void LTEModuleTask(void* arg) {<br />
int Number = 0;<br />
String restr;<br />
while (1) {<br />
xSemaphoreTake(command_list_samap, portMAX_DELAY);</p>
<pre><code>    if (Serial2.available() != 0) {
        String str = Serial2.readString();
        restr += str;

        if (restr.indexOf("\r\n") != -1) {
        }

        if (restr.indexOf("+ZMMI:") != -1) {
            zmmi_str = restr;
        } else if ((restr.indexOf("OK") != -1) ||
                   (restr.indexOf("ERROR") != -1)) {
            Serial.print(restr);
            if (restr.indexOf("OK") != -1) {
                if ((serial_at[0].command_type == kACTION_MO) ||
                    (serial_at[0].command_type == kASSIGN_MO)) {
                    serial_at.erase(serial_at.begin());
                    Serial.printf("erase now %d\n", serial_at.size());
                } else {
                    serial_at[0].read_str = restr;
                    serial_at[0].state    = kWaitforRead;
                }
            } else if (restr.indexOf("ERROR") != -1) {
                serial_at[0].state = kErrorReError;
            } else {
            }
            restr.clear();
        }
    }

    if (serial_at.empty() != true) {
        Number = 0;
        switch (serial_at[0].state) {
            case kSendReady:
                Serial.printf(serial_at[0].str_command.c_str());
                Serial2.write(serial_at[0].str_command.c_str());
                serial_at[0].state = kSending;
                break;
            case kSending:

                if (serial_at[0]._send_time_count &gt; 0) {
                    serial_at[0]._send_time_count--;
                } else {
                    serial_at[0].state = kWaitforMsg;
                }
                /* code */
                break;
            case kWaitforMsg:
                if (serial_at[0]._send_count &gt; 0) {
                    serial_at[0]._send_count--;
                    serial_at[0]._send_time_count = serial_at[0].max_time;
                    Serial.printf(serial_at[0].str_command.c_str());
                    Serial2.write(serial_at[0].str_command.c_str());
                    restr.clear();
                    serial_at[0].state = 1;
                } else {
                    serial_at[0].state = kErrorSendTimeOUT;
                }
                /* code */
                break;
            case kWaitforRead:
                /* code */
                break;
            case 4:
                /* code */
                break;
            case kErrorSendTimeOUT:
                /* code */
                break;
            case 0xe2:
                /* code */
                break;
            default:
                break;
        }
    }
    xSemaphoreGive(command_list_samap);
    delay(10);
}
</code></pre>
<p dir="auto">}</p>
<p dir="auto">void AddMsg(String str, uint8_t type, uint16_t sendcount, uint16_t sendtime) {<br />
struct ATCommand newcommand;<br />
newcommand.str_command      = str;<br />
newcommand.command_type     = type;<br />
newcommand.max_time         = sendtime;<br />
newcommand.send_max_number  = sendcount;<br />
newcommand.state            = 0;<br />
newcommand._send_count      = sendcount;<br />
newcommand._send_time_count = sendtime;<br />
xSemaphoreTake(command_list_samap, portMAX_DELAY);<br />
serial_at.push_back(newcommand);<br />
xSemaphoreGive(command_list_samap);<br />
}</p>
<p dir="auto">uint8_t readSendState(uint32_t number) {<br />
xSemaphoreTake(command_list_samap, portMAX_DELAY);<br />
uint8_t restate = serial_at[number].state;<br />
xSemaphoreGive(command_list_samap);<br />
return restate;<br />
}</p>
<p dir="auto">uint32_t getATMsgSize() {<br />
xSemaphoreTake(command_list_samap, portMAX_DELAY);<br />
uint32_t restate = serial_at.size();<br />
xSemaphoreGive(command_list_samap);<br />
return restate;<br />
}<br />
String ReadMsgstr(uint32_t number) {<br />
xSemaphoreTake(command_list_samap, portMAX_DELAY);<br />
String restate = serial_at[number].read_str;<br />
xSemaphoreGive(command_list_samap);<br />
return restate;<br />
}</p>
<p dir="auto">bool EraseFirstMsg() {<br />
xSemaphoreTake(command_list_samap, portMAX_DELAY);<br />
serial_at.erase(serial_at.begin());<br />
xSemaphoreGive(command_list_samap);<br />
return true;<br />
}</p>
<p dir="auto">uint16_t GetstrNumber(String Str, uint32_t* ptrbuff) {<br />
uint16_t count = 0;<br />
String Numberstr;<br />
int indexpos = 0;<br />
while (Str.length() &gt; 0) {<br />
indexpos = Str.indexOf(",");<br />
if (indexpos != -1) {<br />
Numberstr      = Str.substring(0, Str.indexOf(","));<br />
Str            = Str.substring(Str.indexOf(",") + 1, Str.length());<br />
ptrbuff[count] = Numberstr.toInt();<br />
count++;<br />
} else {<br />
ptrbuff[count] = Str.toInt();<br />
count++;<br />
break;<br />
}<br />
}<br />
return count;<br />
}<br />
vector&lt;String&gt; restr_v;<br />
uint16_t GetstrNumber(String StartStr, String EndStr, String Str) {<br />
uint16_t count = 0;<br />
String Numberstr;<br />
int indexpos = 0;</p>
<pre><code>Str = Str.substring(Str.indexOf(StartStr) + StartStr.length(),
                    Str.indexOf(EndStr));
Str.trim();
restr_v.clear();

while (Str.length() &gt; 0) {
    indexpos = Str.indexOf(",");
    if (indexpos != -1) {
        Numberstr = Str.substring(0, Str.indexOf(","));
        Str       = Str.substring(Str.indexOf(",") + 1, Str.length());
        restr_v.push_back(Numberstr);
        count++;
    } else {
        restr_v.push_back(Numberstr);
        ;
        count++;
        break;
    }
}
return count;
</code></pre>
<p dir="auto">}</p>
<p dir="auto">String getReString(uint16_t Number) {<br />
if (restr_v.empty()) {<br />
return String("");<br />
}<br />
return restr_v.at(Number);<br />
}</p>
<p dir="auto">uint16_t GetstrNumber(String StartStr, String EndStr, String Str,<br />
uint32_t* ptrbuff) {<br />
uint16_t count = 0;<br />
String Numberstr;<br />
int indexpos = 0;</p>
<pre><code>Str = Str.substring(Str.indexOf(StartStr) + StartStr.length(),
                    Str.indexOf(EndStr));
Str.trim();

while (Str.length() &gt; 0) {
    indexpos = Str.indexOf(",");
    if (indexpos != -1) {
        Numberstr      = Str.substring(0, Str.indexOf(","));
        Str            = Str.substring(Str.indexOf(",") + 1, Str.length());
        ptrbuff[count] = Numberstr.toInt();
        count++;
    } else {
        ptrbuff[count] = Str.toInt();
        count++;
        break;
    }
}
return count;
</code></pre>
<p dir="auto">}<br />
uint32_t numberbuff[128];<br />
String readstr;</p>
<p dir="auto">bool isLTEConnected() {<br />
AddMsg("AT+CREG?\r\n", kQUERY_MT, 1000, 1000);<br />
while ((readSendState(0) == kSendReady) || (readSendState(0) == kSending) || (readSendState(0) == kWaitforMsg)) {<br />
delay(50);<br />
}<br />
String response = ReadMsgstr(0);<br />
EraseFirstMsg();</p>
<pre><code>// CREG応答が「+CREG: 0,1」「+CREG: 0,2」「+CREG: 0,3」であれば、ネットワークに登録されている
if (response.indexOf("+CREG: 0,1") != -1 || response.indexOf("+CREG: 0,2") != -1 || response.indexOf("+CREG: 0,3") != -1 ) {
    terminal.println("LTE connected to network.");
    return true;
} else {
    terminal.println("LTE not connected to network.");
    return false;
}
</code></pre>
<p dir="auto">}</p>
<p dir="auto">bool isInternetConnected() {<br />
HTTPClient http;</p>
<pre><code>// GoogleのURLで接続確認
if (!http.begin("http://www.google.com")) {
    terminal.println("HTTPClient init failed");
    return false;
}

int httpCode = http.GET(); // GETリクエストを送信

if (httpCode == 200) {
    terminal.println("Internet is connected.");
    http.end();
    return true;
} else {
    terminal.printf("Internet connection failed. HTTP Code: %d\n", httpCode);
    http.end();
    return false;
}
</code></pre>
<p dir="auto">}</p>
<p dir="auto">uint8_t restate;<br />
void setup() {<br />
// put your setup code here, to run once:<br />
M5.begin(true, true, true, false);<br />
Serial2.begin(115200, SERIAL_8N1, 5, 13);</p>
<pre><code>Disbuff.createSprite(320, 20);
Disbuff.fillRect(0, 0, 320, 20, BLACK);
Disbuff.drawRect(0, 0, 320, 20, Disbuff.color565(36, 36, 36));
Disbuff.pushSprite(0, 0);

TerminalBuff.createSprite(120, 220);
TerminalBuff.fillRect(0, 0, 120, 220, BLACK);
TerminalBuff.drawRect(0, 0, 120, 220, Disbuff.color565(36, 36, 36));
TerminalBuff.pushSprite(0, 20);
terminal.setGeometry(0, 20, 120, 220);

pinMode(2, OUTPUT);
digitalWrite(2, 0);

Disbuff.setTextColor(WHITE);
Disbuff.setTextSize(1);
for (int i = 0; i &lt; 100; i++) {
    Disbuff.fillRect(0, 0, 320, 20, Disbuff.color565(36, 36, 36));
    Disbuff.pushSprite(0, 0);
    Disbuff.setCursor(7, 7);
    Disbuff.printf("Reset Module %02d", i);
    Disbuff.pushSprite(0, 0);
    delay(10);
}
digitalWrite(2, 1);

xTaskCreate(LTEModuleTask, "LTEModuleTask", 1024 * 2, (void*)0, 4,
            &amp;xhandle_lte_event);
command_list_samap = xSemaphoreCreateMutex();
xSemaphoreGive(command_list_samap);


AddMsg("AT+CSQ\r\n", kQUERY_MT, 1000, 1000);
while ((readSendState(0) == kSendReady) || (readSendState(0) == kSending) ||
       (readSendState(0) == kWaitforMsg))
    delay(50);
restate = readSendState(0);
readstr = ReadMsgstr(0).c_str();
EraseFirstMsg();

terminal.print(readstr);


AddMsg("AT+CREG?\r\n", kQUERY_MT, 1000, 1000);
while ((readSendState(0) == kSendReady) || (readSendState(0) == kSending) ||
       (readSendState(0) == kWaitforMsg))
    delay(50);
restate = readSendState(0);
readstr = ReadMsgstr(0).c_str();
EraseFirstMsg();

terminal.print(readstr);


AddMsg("AT+CGDCONT = 1, \"IP\", \"ppsim.jp\"\r\n", kASSIGN_MT, 1000, 1000);
while ((readSendState(0) == kSendReady) || (readSendState(0) == kSending) ||
       (readSendState(0) == kWaitforMsg))
    delay(50);
restate = readSendState(0);
readstr = ReadMsgstr(0).c_str();
EraseFirstMsg();

terminal.print(readstr);


AddMsg("AT+CGAUTH = 1, \"pp@sim\", \"jpn\"\r\n", kASSIGN_MT, 1000, 1000);
while ((readSendState(0) == kSendReady) || (readSendState(0) == kSending) ||
       (readSendState(0) == kWaitforMsg))
    delay(50);
restate = readSendState(0);
readstr = ReadMsgstr(0).c_str();
EraseFirstMsg();

terminal.print(readstr);

// LTE接続確認
if (isLTEConnected()) {
    // インターネット接続確認
    if (isInternetConnected()) {
        terminal.println("SIM card is connected to the internet.");
    } else {
        terminal.println("SIM card is not connected to the internet.");
    }
} else {
    terminal.println("No LTE network connection.");
}
</code></pre>
<p dir="auto">}</p>
<p dir="auto">void loop() {<br />
M5.update();</p>
<pre><code>if (M5.BtnA.wasPressed()) {
    terminal.println("A button OK");

    counter++;
    tick = millis();

    json_request["counter"] = counter;
    json_request["tick"] = tick;

    serializeJson(json_request, Serial);
    Serial.println("");

    serializeJson(json_request, buffer, sizeof(buffer));
    terminal.println(buffer);
    delay(500);

    HTTPClient http;

    if (!http.begin(url)) {
        terminal.println("HTTPClient init failed");
        return;  // 接続失敗の場合は処理を中断
    }

    http.addHeader("Content-Type", "application/json");
    delay(500);

    terminal.println("post ready");
    int status_code = http.POST((uint8_t*)buffer, strlen(buffer));
    Serial.printf("status_code=%d\r\n", status_code);

    if (status_code != 200) {
        terminal.printf("HTTP POST failed, status code: %d\n", status_code);
    } else {
        Stream* resp = http.getStreamPtr();
        DynamicJsonDocument json_response(255);
        deserializeJson(json_response, *resp);
        serializeJson(json_response, Serial);
        Serial.println();
    }

    http.end();  
}
/*
if (M5.BtnB.wasPressed()) {
  delay(1000);
  esp_sleep_enable_timer_wakeup(10000);
  esp_sleep_enable_ext0_wakeup((gpio_num_t)M5.BtnA.wasPressed(), 0);
  esp_deep_sleep_start();

}
*/
if (M5.BtnC.wasPressed()) {

  while(1){
    AddMsg("AT+CSQ\r\n", kQUERY_MT, 1000, 1000);
    while ((readSendState(0) == kSendReady) || (readSendState(0) == kSending) ||
          (readSendState(0) == kWaitforMsg))
        delay(50);
    restate = readSendState(0);
    readstr = ReadMsgstr(0).c_str();
    EraseFirstMsg();

    terminal.print(readstr);

    AddMsg("AT+CREG?\r\n", kQUERY_MT, 1000, 1000);
    while ((readSendState(0) == kSendReady) || (readSendState(0) == kSending) ||
          (readSendState(0) == kWaitforMsg))
        delay(50);
    restate = readSendState(0);
    readstr = ReadMsgstr(0).c_str();
    EraseFirstMsg();

    terminal.print(readstr);

    delay(500);
    M5.update();
    if (M5.BtnA.wasPressed()) {
        AddMsg("ATD13800088888;\r\n", kQUERY_MT, 1000, 1000);
        while ((readSendState(0) == kSendReady) ||
              (readSendState(0) == kSending) ||
              (readSendState(0) == kWaitforMsg))
            delay(50);
        Serial.printf("Read state = %d \n", readSendState(0));
        readstr = ReadMsgstr(0).c_str();
        Serial.print(readstr);
        while (1) {
            M5.update();
            if (M5.BtnA.wasPressed()) break;
            delay(100);
        }
        EraseFirstMsg();
        AddMsg("AT+CHUP\r\n", kASSIGN_MO, 1000, 1000);
    }

    if (M5.BtnB.wasPressed()) {
    delay(1000);
    esp_sleep_enable_timer_wakeup(10000);
    esp_sleep_enable_ext0_wakeup((gpio_num_t)M5.BtnA.wasPressed(), 0);
    esp_deep_sleep_start();
    }
  }

}
</code></pre>
<p dir="auto">}</p>
<p dir="auto">[Googleスプレッドシートのコード]</p>
<p dir="auto">function doGet(e) {<br />
let id = '＊＊＊＊＊';<br />
let sheetName = 'シート1';<br />
var result;</p>
<pre><code>if (e.parameter == undefined) {
    result = 'Parameter undefined';
} else {
    var sheet = SpreadsheetApp.openById(id).getSheetByName(sheetName);
    var newRow = sheet.getLastRow() + 1;
    var rowData = [];

    rowData[0] = new Date();
    rowData[1] = e.parameter.chipid;
    rowData[2] = e.parameter.val0;
    rowData[3] = e.parameter.val1;
    rowData[4] = e.parameter.val2;

    var newRange = sheet.getRange(newRow, 1, 1, rowData.length);
    newRange.setValues([rowData]);
    result =  'Ok';
}
return ContentService.createTextOutput(result);
</code></pre>
<p dir="auto">}</p>
<pre><code>
ターミナルコマンド

[シリアルモニタ]
`` command ``
OK
AT+CSQ
AT+CSQ
AT+CSQ
+CSQ: 20,99
OK
AT+CREG?
+CREG: 0,3
OK
AT+CGDCONT = 1, "IP", "ppsin.jp"
OK
AT+CGAUTH = 1, "pp@sin", "jpn"
ERROR
AT+CREG?
+CREG: 0,3
OK
("counter":1,"tick":98705]
status_code=-1


[M５stack basic の画面]
`` command ``
OK

+CREG: 0,3

OK

OK
LTE connected to net
work.

Internet connection
failed. HTTP Code:-1

SIM card is not connected to the internet.

A button OK

("counter" : 1, "tick" : 98705)

post ready

HTTP POST failed, status code : -1</code></pre>
]]></description><link>https://community.m5stack.com/topic/7215/com-lte-module-sim7600g-でデータ送信ができません</link><generator>RSS for Node</generator><lastBuildDate>Thu, 07 May 2026 10:22:33 GMT</lastBuildDate><atom:link href="https://community.m5stack.com/topic/7215.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 19 Jan 2025 02:12:39 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to COM.LTE Module(SIM7600G)でデータ送信ができません on Sun, 16 Mar 2025 13:07:12 GMT]]></title><description><![CDATA[<p dir="auto">データ通信を行うことができたので、共有させていただきます。<br />
SIM7600のデータシートを参照し、通信を行うことができました。<br />
COM.LTE Module(SIM7600G)を使用することで、長距離におけるデータ伝送が可能です。</p>
<p dir="auto">使用する方がいましたら、参考にしてください。<br />
Va10, Va11, Va12にセンサで取得したデータを代入することで、<br />
観測機器を製作できます。</p>
<p dir="auto">[　M5stack Basic code　]</p>
<pre><code>#include &lt;M5Stack.h&gt;                                
#include &lt;stdint.h&gt;
#include &lt;vector&gt;
#include "TFTTerminal.h"

/*serial通信のinclude

#include &lt;WiFi.h&gt;
#include &lt;WiFiMulti.h&gt;
#include &lt;HTTPClient.h&gt;
#include &lt;ArduinoJson.h&gt;

*/

TFT_eSprite Disbuff      = TFT_eSprite(&amp;M5.Lcd);
TFT_eSprite TerminalBuff = TFT_eSprite(&amp;M5.Lcd);
TFTTerminal terminal(&amp;TerminalBuff);
TaskHandle_t xhandle_lte_event = NULL;
SemaphoreHandle_t command_list_samap;
uint32_t numberbuff[128];
String readstr;
uint8_t restate;

char buffer[255];

uint32_t    interval = 1; // unit:sec
uint16_t    chipid   = ESP.getEfuseMac() % 10000;
const char* deployid = "AKfycbw1vfUnV_E6B9O0tWaKMPKXkvahMsXIG-jrpk2SS2a1kGAAz59iQy1_p_H7kp7x8VnKsg";

const char *send_url = "https://script.google.com/macros/s/AKfycbyMcbm5u-ySil5s6LF6__EyyAVYMt9idkIRBaRBWk3ut3jR3A9VFe7lobGQE9qdBHuR/exec";

unsigned long counter = 0;
unsigned long tick = 0;
const char* data = "Hello World";

const String sim_apn = "ppsim.jp";  
const String sim_user = "pp@sim";
const String sim_pass = "jpn";

typedef enum {
    kQUERY_MO = 0,
    KTEST_MO,
    kASSIGN_MO,
    kACTION_MO,
    kQUERY_MT,
    kTEST_MT,
    kASSIGN_MT,
    kACTION_MT,
    kINFORM
} LTEMsg_t;

typedef enum {
    kErrorSendTimeOUT = 0xe1,
    kErrorReError     = 0xe2,
    kErroeSendError   = 0xe3,
    kSendReady        = 0,
    kSending          = 1,
    kWaitforMsg       = 2,
    kWaitforRead      = 3,
    kReOK
} LTEState_t;

struct ATCommand {
    uint8_t command_type;
    String str_command;
    uint16_t send_max_number;
    uint16_t max_time;
    uint8_t state;
    String read_str;
    uint16_t _send_count;
    uint16_t _send_time_count;

} user;

using namespace std;
vector&lt;ATCommand&gt; serial_at;
String zmmi_str;
void LTEModuleTask(void* arg) {
    int Number = 0;
    String restr;
    while (1) {
        xSemaphoreTake(command_list_samap, portMAX_DELAY);

        if (Serial2.available() != 0) {
            String str = Serial2.readString();
            restr += str;

            if (restr.indexOf("\r\n") != -1) {
            }

            if (restr.indexOf("+ZMMI:") != -1) {
                zmmi_str = restr;
            } else if ((restr.indexOf("OK") != -1) ||
                       (restr.indexOf("ERROR") != -1)) {
                Serial.print(restr);
                if (restr.indexOf("OK") != -1) {
                    if ((serial_at[0].command_type == kACTION_MO) ||
                        (serial_at[0].command_type == kASSIGN_MO)) {
                        serial_at.erase(serial_at.begin());
                        Serial.printf("erase now %d\n", serial_at.size());
                    } else {
                        serial_at[0].read_str = restr;
                        serial_at[0].state    = kWaitforRead;
                    }
                } else if (restr.indexOf("ERROR") != -1) {
                    serial_at[0].state = kErrorReError;
                } else {
                }
                restr.clear();
            }
        }

        if (serial_at.empty() != true) {
            Number = 0;
            switch (serial_at[0].state) {
                case kSendReady:
                    Serial.printf(serial_at[0].str_command.c_str());
                    Serial2.write(serial_at[0].str_command.c_str());
                    serial_at[0].state = kSending;
                    break;
                case kSending:

                    if (serial_at[0]._send_time_count &gt; 0) {
                        serial_at[0]._send_time_count--;
                    } else {
                        serial_at[0].state = kWaitforMsg;
                    }
                    /* code */
                    break;
                case kWaitforMsg:
                    if (serial_at[0]._send_count &gt; 0) {
                        serial_at[0]._send_count--;
                        serial_at[0]._send_time_count = serial_at[0].max_time;
                        Serial.printf(serial_at[0].str_command.c_str());
                        Serial2.write(serial_at[0].str_command.c_str());
                        restr.clear();
                        serial_at[0].state = 1;
                    } else {
                        serial_at[0].state = kErrorSendTimeOUT;
                    }
                    /* code */
                    break;
                case kWaitforRead:
                    /* code */
                    break;
                case 4:
                    /* code */
                    break;
                case kErrorSendTimeOUT:
                    /* code */
                    break;
                case 0xe2:
                    /* code */
                    break;
                default:
                    break;
            }
        }
        xSemaphoreGive(command_list_samap);
        delay(10);
    }
}

void AddMsg(String str, uint8_t type, uint16_t sendcount, uint16_t sendtime) {
    struct ATCommand newcommand;
    newcommand.str_command      = str;
    newcommand.command_type     = type;
    newcommand.max_time         = sendtime;
    newcommand.send_max_number  = sendcount;
    newcommand.state            = 0;
    newcommand._send_count      = sendcount;
    newcommand._send_time_count = sendtime;
    xSemaphoreTake(command_list_samap, portMAX_DELAY);
    serial_at.push_back(newcommand);
    xSemaphoreGive(command_list_samap);

    while ((readSendState(0) == kSendReady) || (readSendState(0) == kSending) ||
           (readSendState(0) == kWaitforMsg))
        delay(50);
    restate = readSendState(0);
    readstr = ReadMsgstr(0).c_str();
    EraseFirstMsg();

    terminal.print(readstr);

}

uint8_t readSendState(uint32_t number) {
    xSemaphoreTake(command_list_samap, portMAX_DELAY);
    uint8_t restate = serial_at[number].state;
    xSemaphoreGive(command_list_samap);
    return restate;
}

uint32_t getATMsgSize() {
    xSemaphoreTake(command_list_samap, portMAX_DELAY);
    uint32_t restate = serial_at.size();
    xSemaphoreGive(command_list_samap);
    return restate;
}
String ReadMsgstr(uint32_t number) {
    xSemaphoreTake(command_list_samap, portMAX_DELAY);
    String restate = serial_at[number].read_str;
    xSemaphoreGive(command_list_samap);
    return restate;
}

bool EraseFirstMsg() {
    xSemaphoreTake(command_list_samap, portMAX_DELAY);
    serial_at.erase(serial_at.begin());
    xSemaphoreGive(command_list_samap);
    return true;
}

uint16_t GetstrNumber(String Str, uint32_t* ptrbuff) {
    uint16_t count = 0;
    String Numberstr;
    int indexpos = 0;
    while (Str.length() &gt; 0) {
        indexpos = Str.indexOf(",");
        if (indexpos != -1) {
            Numberstr      = Str.substring(0, Str.indexOf(","));
            Str            = Str.substring(Str.indexOf(",") + 1, Str.length());
            ptrbuff[count] = Numberstr.toInt();
            count++;
        } else {
            ptrbuff[count] = Str.toInt();
            count++;
            break;
        }
    }
    return count;
}

vector&lt;String&gt; restr_v;
uint16_t GetstrNumber(String StartStr, String EndStr, String Str) {
    uint16_t count = 0;
    String Numberstr;
    int indexpos = 0;

    Str = Str.substring(Str.indexOf(StartStr) + StartStr.length(),
                        Str.indexOf(EndStr));
    Str.trim();
    restr_v.clear();

    while (Str.length() &gt; 0) {
        indexpos = Str.indexOf(",");
        if (indexpos != -1) {
            Numberstr = Str.substring(0, Str.indexOf(","));
            Str       = Str.substring(Str.indexOf(",") + 1, Str.length());
            restr_v.push_back(Numberstr);
            count++;
        } else {
            restr_v.push_back(Numberstr);
            ;
            count++;
            break;
        }
    }
    return count;
}

String getReString(uint16_t Number) {
    if (restr_v.empty()) {
        return String("");
    }
    return restr_v.at(Number);
}

uint16_t GetstrNumber(String StartStr, String EndStr, String Str,
                      uint32_t* ptrbuff) {
    uint16_t count = 0;
    String Numberstr;
    int indexpos = 0;

    Str = Str.substring(Str.indexOf(StartStr) + StartStr.length(),
                        Str.indexOf(EndStr));
    Str.trim();

    while (Str.length() &gt; 0) {
        indexpos = Str.indexOf(",");
        if (indexpos != -1) {
            Numberstr      = Str.substring(0, Str.indexOf(","));
            Str            = Str.substring(Str.indexOf(",") + 1, Str.length());
            ptrbuff[count] = Numberstr.toInt();
            count++;
        } else {
            ptrbuff[count] = Str.toInt();
            count++;
            break;
        }
    }
    return count;
}


//データ送信プログラム
void addRowToGoogleSheetsdoGet(float val0, float val1, float val2) {
//URL
  //String url = "https://script.google.com/macros/s/" + String(deployid) + "/exec?chipid=ESP" + String(chipid) + "&amp;val0=" + String(val0) + "&amp;val1=" + String(val1) + "&amp;val2=" + String(val2);
  String url =  String(send_url) + "?chipid=ESP" + String(chipid) + "&amp;val0=" + String(val0) + "&amp;val1=" + String(val1) + "&amp;val2=" + String(val2);

  terminal.println("[HTTP] begin...");
  terminal.println(url);
  terminal.println("[HTTP] POST...");

// コンテンツタイプの設定
  AddMsg("AT+HTTPPARA=\"CONTENT\",\"application/json\"\r\n", kASSIGN_MT, 1000, 1000);

// AT commmand : URLの設定 &amp; http post（今回はURLにデータを追加している）
  AddMsg("AT+HTTPPARA=\"URL\",\"" + url + "\"\r\n", kASSIGN_MT, 1000, 1000);

  delay(1000);
  terminal.println("[HTTP] GET...");

// HTTP GET リクエスト
  AddMsg("AT+HTTPACTION=0\r\n", kASSIGN_MT, 5000, 5000);

  delay(1000);
}


//データdopost送信プログラム
void addRowToGoogleSheetsdoPost(float val0, float val1, float val2) {
//URL
  //String url = "https://script.google.com/macros/s/" + String(deployid) + "/exec?chipid=ESP" + String(chipid) + "&amp;val0=" + String(val0) + "&amp;val1=" + String(val1) + "&amp;val2=" + String(val2);
  //String url =  String(send_url) + "?chipid=ESP" + String(chipid) + "&amp;val0=" + String(val0) + "&amp;val1=" + String(val1) + "&amp;val2=" + String(val2);

  String jsonPayload = "{\"chipid\":\"ESP" + String(chipid) + 
                     "\", \"val0\":" + String(val0) + 
                     ", \"val1\":" + String(val1) + 
                     ", \"val2\":" + String(val2) + "}";

  terminal.println("[HTTP] begin...");

  terminal.println("[HTTP] POST...");

  // HTTPヘッダーを設定
  AddMsg("AT+HTTPPARA=\"URL\",\"" + String(send_url) + "\"\r\n", kASSIGN_MT, 1000, 1000);
  AddMsg("AT+HTTPPARA=\"CONTENT\",\"application/json\"\r\n", kASSIGN_MT, 1000, 1000);

// データを送信
  AddMsg("AT+HTTPDATA=" + String(jsonPayload.length()) + ",10000\r\n", kASSIGN_MT, 1000, 1000);
  delay(100);
  AddMsg(jsonPayload + "\r\n", kASSIGN_MT, 1000, 1000);
  delay(100);
  AddMsg("AT+HTTPACTION=1\r\n", kASSIGN_MT, 5000, 5000);

  delay(1000);
  terminal.println("[HTTP] GET...");

// HTTP GET リクエスト
  AddMsg("AT+HTTPACTION=0\r\n", kASSIGN_MT, 5000, 5000);

  delay(1000);
}

void setup() {
    // put your setup code here, to run once:
    M5.begin(true, true, true, false); //LCD, SDカード, serial, I2Cの有効無効
    Serial2.begin(115200, SERIAL_8N1, 5, 13);

    Disbuff.createSprite(320, 20);
    Disbuff.fillRect(0, 0, 320, 20, BLACK);
    Disbuff.drawRect(0, 0, 320, 20, Disbuff.color565(36, 36, 36));
    Disbuff.pushSprite(0, 0);

    TerminalBuff.createSprite(120, 220);
    TerminalBuff.fillRect(0, 0, 120, 220, BLACK);
    TerminalBuff.drawRect(0, 0, 120, 220, Disbuff.color565(36, 36, 36));
    TerminalBuff.pushSprite(0, 20);
    terminal.setGeometry(0, 20, 120, 220);

    pinMode(2, OUTPUT);
    digitalWrite(2, 0);

    Disbuff.setTextColor(WHITE);
    Disbuff.setTextSize(1);
    for (int i = 0; i &lt; 100; i++) {
        Disbuff.fillRect(0, 0, 320, 20, Disbuff.color565(36, 36, 36));
        Disbuff.pushSprite(0, 0);
        Disbuff.setCursor(7, 7);
        Disbuff.printf("Reset Module %02d", i);
        Disbuff.pushSprite(0, 0);
        delay(10);
    }
    digitalWrite(2, 1);

    xTaskCreate(LTEModuleTask, "LTEModuleTask", 1024 * 2, (void*)0, 4,
                &amp;xhandle_lte_event);
    command_list_samap = xSemaphoreCreateMutex();
    xSemaphoreGive(command_list_samap);

    terminal.println("Initializing SIM7600...");

// モジュール起動確認
    AddMsg("AT\r\n", kQUERY_MT, 1000, 1000);

// 機能の追加（フルモード）
    AddMsg("AT+CFUN=1\r\n", kQUERY_MT, 1000, 1000);

// LTE接続
    AddMsg("AT+CGATT=1\r\n", kQUERY_MT, 1000, 1000);

//　通信強度
    AddMsg("AT+CSQ\r\n", kQUERY_MT, 1000, 1000);

//　インターネット登録状況
    AddMsg("AT+CREG?\r\n", kQUERY_MT, 1000, 1000);

// APN設定
    AddMsg("AT+CGDCONT = 1, \"IP\", \"" + sim_apn + "\"\r\n", kASSIGN_MT, 1000, 1000);

// 認証情報の設定 : 無くても良い
    //AddMsg("AT+CGAUTH = 1, \"" + sim_user + "\", \"" + sim_pass + "\"\r\n", kASSIGN_MT, 1000, 1000);

// PDPコンテキスト有効化
    AddMsg("AT+CGACT=1,1\r\n", kQUERY_MT, 1000, 1000);

// HTTP機能の初期化
    AddMsg("AT+HTTPINIT\r\n", kQUERY_MT, 1000, 1000);

// PDPコンテキストを設定
    AddMsg("AT+HTTPPARA=\"CID\",1\r\n", kQUERY_MT, 1000, 1000);

}

void loop() {
    M5.update();
    float val0 = random(0, 1000) / 10.0;
    float val1 = random(0, 1000) / 10.0;
    float val2 = random(0, 1000) / 10.0;

    terminal.print("ESP");
    terminal.println(chipid);
    terminal.printf("[val0] %.1f\n[val1] %.1f\n[val2] %.1f\n", val0, val1, val2);
    addRowToGoogleSheetsdoGet(val0, val1, val2);
    //addRowToGoogleSheetsdoPost(val0, val1, val2);
    delay(interval * 1000);

    if (M5.BtnC.wasPressed()) {
        terminal.println("Restarting...");
        delay(1000);
        esp_restart();  // ESP32をリセット
    }

    delay(1000);
    esp_sleep_enable_timer_wakeup(10000);
    esp_sleep_enable_ext0_wakeup((gpio_num_t)M5.BtnA.wasPressed(), 0);
    esp_deep_sleep_start();

}


/*本来のhttp post方法（仮）-----------------------------------------------------

// URL を設定
AddMsg("AT+HTTPPARA=\"URL\",\"" + url + "\"\r\n", kASSIGN_MT, 1000, 1000);

// コンテンツのタイプを設定（JSON 例）
AddMsg("AT+HTTPPARA=\"CONTENT\",\"application/json\"\r\n", kASSIGN_MT, 1000, 1000);

// 送信データの準備（例：50バイトのデータを10秒以内に送信）
AddMsg("AT+HTTPDATA=50,10000\r\n", kASSIGN_MT, 1000, 1000);
delay(100);  // 少し待機

// 送信する JSON データを設定（例）
AddMsg("{\"temperature\":25.5,\"humidity\":60}\r\n", kASSIGN_MT, 1000, 1000);
delay(100);

// HTTP POST を開始
AddMsg("AT+HTTPACTION=1\r\n", kASSIGN_MT, 1000, 1000);
delay(5000);  // 応答待機

// レスポンスを取得（HTTP GET）
AddMsg("AT+HTTPREAD\r\n", kASSIGN_MT, 1000, 1000);

--------------------------------------------------------------------------------*/
</code></pre>
<p dir="auto">[　Google Spread Sheet code　]</p>
<pre><code>function doGet(e) {
  Logger.log("Received GET request: " + JSON.stringify(e));

  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート1');
  if (!sheet) {
    return ContentService.createTextOutput("Error: Sheet not found").setMimeType(ContentService.MimeType.TEXT);
  }

  // パラメータを取得
  var chipid = e.parameter.chipid || "Unknown";
  var val0 = parseFloat(e.parameter.val0) || 0;
  var val1 = parseFloat(e.parameter.val1) || 0;
  var val2 = parseFloat(e.parameter.val2) || 0;

  // スプレッドシートにデータを記録
  sheet.insertRowBefore(2);
  sheet.getRange(2, 1).setValue(new Date()); // 受信日時
  sheet.getRange(2, 2).setValue(chipid);
  sheet.getRange(2, 3).setValue(val0);
  sheet.getRange(2, 4).setValue(val1);
  sheet.getRange(2, 5).setValue(val2);

  return ContentService.createTextOutput("Data received successfully").setMimeType(ContentService.MimeType.TEXT);
}
</code></pre>
<p dir="auto">以下は本プログラムの動作及び、システム構成です。</p>
<p dir="auto"><img src="/assets/uploads/files/1742129699102-com.lte_page-0001.jpg" alt="COM.LTE_page-0001.jpg" class=" img-fluid img-markdown" /><br />
<img src="/assets/uploads/files/1742129711430-com.lte_page-0002.jpg" alt="COM.LTE_page-0002.jpg" class=" img-fluid img-markdown" /><br />
<img src="/assets/uploads/files/1742129722203-com.lte_page-0003.jpg" alt="COM.LTE_page-0003.jpg" class=" img-fluid img-markdown" /><br />
<img src="/assets/uploads/files/1742129733672-com.lte_page-0004.jpg" alt="COM.LTE_page-0004.jpg" class=" img-fluid img-markdown" /><br />
<img src="/assets/uploads/files/1742129742017-com.lte_page-0005.jpg" alt="COM.LTE_page-0005.jpg" class=" img-fluid img-markdown" /><br />
<img src="/assets/uploads/files/1742129750099-com.lte_page-0006.jpg" alt="COM.LTE_page-0006.jpg" class=" img-fluid img-markdown" /></p>
]]></description><link>https://community.m5stack.com/post/28526</link><guid isPermaLink="true">https://community.m5stack.com/post/28526</guid><dc:creator><![CDATA[hakushiro]]></dc:creator><pubDate>Sun, 16 Mar 2025 13:07:12 GMT</pubDate></item></channel></rss>