COM.LTE Module(SIM7600G)でデータ送信ができません
-
タイトル
M5stack basicを用いて、COM.LTE Module(SIM7600G)によりデータ送信をする方法がわかりません。
詳しい状況の説明
Arduino言語により、m5stack basicを用いたCOM.LTE Module(SIM7600G)の簡易的な通信システムを制作しています。
データはGoogleスプレッドシートに表示させたいと考えています。
wifi通信を用いた場合では、意図した通りにGoogleスプレッドシートにデータが表示されました。ところが、COM Xを用いた際には表示されないため困っています。
通信強度とインターネット接続状況を確認するために、
COM.LTEModule(SIM7600G)の公式HPよりArduino Example Code
(https://docs.m5stack.com/en/module/comx_lte)
に記載されていたサンプルコードを用いました。ATコマンドを用いたプログラムのため、ネットワークの登録状況を確認するコマンドの「AT+CREG?」を使用しました。結果は
AT+CREG?
+CREG?:0,3
OKとなったためインターネットには接続できていると考えています。
ですがデータ通信を行うことができませんでした。
wifi通信を用いた場合ではGoogleスプレッドシートにデータが表示されました。データ送信はHTTPリクエストのPOST通信を使用。以下の記事を参考にしました。
(https://msr-r.net/m5stack-googlesheets/)COM XのLTEを用いた形でデータ送信を完成させたいと考えておりますが
どのようにすれば良いのかアドバイスをいただけないでしょうか。使用しているUIFlowやArduinoライブラリのバージョン
- Arduino IDE 2.3.3
コード
[M5stack basic のコード]
#include <M5Stack.h>
#include <stdint.h>
#include <vector>
#include "TFTTerminal.h"#include <WiFi.h> //serial通信のinclude
#include <WiFiMulti.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>TFT_eSprite Disbuff = TFT_eSprite(&M5.Lcd);
TFT_eSprite TerminalBuff = TFT_eSprite(&M5.Lcd);
TFTTerminal terminal(&TerminalBuff);
TaskHandle_t xhandle_lte_event = NULL;
SemaphoreHandle_t command_list_samap;const int capacity = JSON_OBJECT_SIZE(2); //serial通信をする
StaticJsonDocument<capacity> json_request;
char buffer[255];
const char url = "*****";
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<ATCommand> 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 > 0) { serial_at[0]._send_time_count--; } else { serial_at[0].state = kWaitforMsg; } /* code */ break; case kWaitforMsg: if (serial_at[0]._send_count > 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);
}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() > 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<String> 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() > 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() > 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;
}
uint32_t numberbuff[128];
String readstr;bool isLTEConnected() {
AddMsg("AT+CREG?\r\n", kQUERY_MT, 1000, 1000);
while ((readSendState(0) == kSendReady) || (readSendState(0) == kSending) || (readSendState(0) == kWaitforMsg)) {
delay(50);
}
String response = ReadMsgstr(0);
EraseFirstMsg();// 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; }
}
bool isInternetConnected() {
HTTPClient http;// 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; }
}
uint8_t restate;
void setup() {
// put your setup code here, to run once:
M5.begin(true, true, true, false);
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 < 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, &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."); }
}
void loop() {
M5.update();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(); } } }
}
[Googleスプレッドシートのコード]
function doGet(e) {
let id = '*****';
let sheetName = 'シート1';
var result;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);
}
ターミナルコマンド [シリアルモニタ] `` 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 [M5stack 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