TinyGSM-Code für low power optimieren

Für das Projekt Minimal Hardware Design GSM-Stockwaage mit TTGO T-Call schaue ich mir gerade die TinyGSM-Bibliothek genauer an. Diese Arduino-Bibliothek regelt den Zugriff auf das GSM/GPRS-Modul SIM800 für die Internet-Verbindung.

Ersten code findet man bei den Beispiel sketches der Bibliothek, bzw. auch ein angepasstes Beispiel für den T-Call (power-Management einschalten) im GIThub-Repo von TTGO Ich frage mich gerade, wie man

  • den Verbindungsaufbau möglichst kurz macht, um hier unnötig verbrauchte Energie zu sparen und
  • den code möglichst robust gestaltet, d.h. vor allem Endlosschleifen vermeidet, wenn das Modem den Server nicht findet, da der Server down ist oder sich nicht ins Telefonnetz einwählen kann usw.

Der Test-sketch unter test-sketches/test_tinygsm-lib_with_ttgo-t-call-sim800c at main · ClemensGruber/test-sketches · benötigt im Schnitt etwa 32 Sekunden mit angeschaltetem debug auf der Seriellen. Aber auch mal 50 Sekunden (mit ca. 10 Durchläufen getestet).

Hier die gesamte debug-Ausgabe für einen Durchgang:

22:57:55.367 -> ets Jun  8 2016 00:22:57
22:57:55.367 -> 
22:57:55.367 -> rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
22:57:55.367 -> configsip: 0, SPIWP:0xee
22:57:55.367 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
22:57:55.367 -> mode:DIO, clock div:1
22:57:55.367 -> load:0x3fff0018,len:4
22:57:55.367 -> load:0x3fff001c,len:1216
22:57:55.367 -> ho 0 tail 12 room 4
22:57:55.367 -> load:0x40078000,len:10944
22:57:55.367 -> load:0x40080400,len:6388
22:57:55.367 -> entry 0x400806b4
22:57:55.546 -> VBUS:4960.60 mV 0.00 mA ,BATTERY: 0.00
22:57:56.616 -> Initializing modem...
22:57:56.616 -> AT
22:57:56.916 -> AT
22:57:57.218 -> AT
22:57:57.548 -> AT
22:57:57.817 -> AT
22:57:58.118 -> AT
22:57:58.418 -> AT
22:57:58.718 -> AT
22:57:59.019 -> AT
22:57:59.319 -> AT
22:57:59.636 -> AT
22:57:59.921 -> AT
22:57:59.921 -> ⸮AT
22:58:00.507 -> AT
22:58:00.823 -> AT
22:58:01.123 -> AT
22:58:01.424 -> AT
22:58:01.724 -> AT
22:58:01.824 -> ⸮AT
22:58:02.009 -> 
22:58:02.009 -> OK
22:58:02.009 -> AT&W
22:58:02.056 -> 
22:58:02.056 -> OK
22:58:02.056 -> AT+CFUN=0
22:58:02.056 -> 
22:58:02.056 -> OK
22:58:02.056 -> AT+CFUN=1,1
22:58:02.056 -> 
22:58:02.056 -> OK
22:58:05.052 -> [9569] ### TinyGSM Version: 0.10.9
22:58:05.052 -> [9569] ### TinyGSM Compiled Module:  TinyGsmClientSIM800
22:58:05.052 -> AT
22:58:05.353 -> AT
22:58:05.654 -> AT
22:58:05.954 -> AT
22:58:06.254 -> AT
22:58:06.254 -> ⸮⸮AT
22:58:06.534 -> ⸮AT
22:58:07.156 -> AT
22:58:07.449 -> AT
22:58:07.757 -> AT
22:58:08.057 -> AT
22:58:08.204 -> ⸮AT
22:58:08.357 -> 
22:58:08.357 -> OK
22:58:08.357 -> ATE0
22:58:08.357 -> 
22:58:08.357 -> OK
22:58:08.357 -> AT+CMEE=2
22:58:08.357 -> 
22:58:08.357 -> OK
22:58:08.357 -> AT+GMM
22:58:08.357 -> 
22:58:08.357 -> SIMCOM_SIM800C
22:58:08.357 -> 
22:58:08.357 -> OK
22:58:08.357 -> [12870] ### Modem: SIMCOM SIM800C
22:58:08.357 -> [12870] ### Modem: SIMCOM SIM800C
22:58:08.357 -> AT+CLTS=1
22:58:08.357 -> 
22:58:08.357 -> OK
22:58:08.357 -> AT+CBATCHK=1
22:58:08.357 -> 
22:58:08.357 -> OK
22:58:08.357 -> AT+CPIN?
22:58:08.357 -> 
22:58:08.357 -> +CME ERROR: CFUN state is 0 or 4
22:58:09.359 -> AT+CPIN?
22:58:09.359 -> 
22:58:09.359 -> RDY
22:58:09.359 -> 
22:58:09.359 -> +CFUN: 1
22:58:09.359 -> 
22:58:09.359 -> +CME ERROR: SIM busy
22:58:10.360 -> AT+CPIN?
22:58:10.360 -> 
22:58:10.360 -> +CPIN: READY
22:58:10.360 -> 
22:58:10.360 -> +CPIN: READY
22:58:10.360 -> 
22:58:10.360 -> OK
22:58:10.360 -> Turning on SIM800 Red LED...
22:58:10.360 -> AT+CNETLIGHT=1
22:58:10.360 -> Waiting for network...AT+CREG?
22:58:10.360 -> 
22:58:10.360 -> OK
22:58:10.576 -> 
22:58:10.576 -> Call Ready
22:58:10.576 -> 
22:58:10.576 -> +CREG: 0,2
22:58:10.576 -> 
22:58:10.576 -> OK
22:58:10.861 -> AT+CREG?
22:58:10.861 -> 
22:58:10.861 -> +CREG: 0,2
22:58:10.861 -> 
22:58:10.861 -> OK
22:58:11.108 -> AT+CREG?
22:58:11.108 -> 
22:58:11.108 -> +CREG: 0,2
22:58:11.108 -> 
22:58:11.108 -> OK
22:58:11.361 -> AT+CREG?
22:58:11.361 -> 
22:58:11.361 -> SMS Ready
22:58:11.361 -> 
22:58:11.361 -> +CREG: 0,2
22:58:11.361 -> 
22:58:11.361 -> OK
22:58:11.624 -> AT+CREG?
22:58:11.624 -> 
22:58:11.624 -> +CREG: 0,2
22:58:11.624 -> 
22:58:11.624 -> OK
22:58:11.862 -> AT+CREG?
22:58:11.862 -> 
22:58:11.862 -> +CREG: 0,2
22:58:11.862 -> 
22:58:11.862 -> OK
22:58:12.109 -> AT+CREG?
22:58:12.109 -> 
22:58:12.109 -> +CREG: 0,2
22:58:12.109 -> 
22:58:12.109 -> OK
22:58:12.363 -> AT+CREG?
22:58:12.363 -> 
22:58:12.363 -> +CREG: 0,2
22:58:12.363 -> 
22:58:12.363 -> OK
22:58:12.626 -> AT+CREG?
22:58:12.626 -> 
22:58:12.626 -> +CREG: 0,2
22:58:12.626 -> 
22:58:12.626 -> OK
22:58:12.864 -> AT+CREG?
22:58:12.864 -> 
22:58:12.864 -> +CREG: 0,2
22:58:12.864 -> 
22:58:12.864 -> OK
22:58:13.111 -> AT+CREG?
22:58:13.111 -> 
22:58:13.111 -> +CREG: 0,2
22:58:13.111 -> 
22:58:13.111 -> OK
22:58:13.365 -> AT+CREG?
22:58:13.365 -> 
22:58:13.365 -> +CREG: 0,2
22:58:13.365 -> 
22:58:13.365 -> OK
22:58:13.628 -> AT+CREG?
22:58:13.628 -> 
22:58:13.628 -> +CREG: 0,2
22:58:13.628 -> 
22:58:13.628 -> OK
22:58:13.866 -> AT+CREG?
22:58:13.913 -> 
22:58:13.913 -> +CREG: 0,2
22:58:13.913 -> 
22:58:13.913 -> OK
22:58:14.166 -> AT+CREG?
22:58:14.166 -> 
22:58:14.166 -> +CREG: 0,2
22:58:14.166 -> 
22:58:14.166 -> OK
22:58:14.413 -> AT+CREG?
22:58:14.413 -> 
22:58:14.413 -> +CREG: 0,2
22:58:14.413 -> 
22:58:14.413 -> OK
22:58:14.629 -> AT+CREG?
22:58:14.629 -> 
22:58:14.629 -> +CREG: 0,2
22:58:14.629 -> 
22:58:14.629 -> OK
22:58:14.914 -> AT+CREG?
22:58:14.914 -> 
22:58:14.914 -> +CREG: 0,2
22:58:14.914 -> 
22:58:14.914 -> OK
22:58:15.168 -> AT+CREG?
22:58:15.168 -> 
22:58:15.168 -> +CREG: 0,2
22:58:15.168 -> 
22:58:15.168 -> OK
22:58:15.415 -> AT+CREG?
22:58:15.415 -> 
22:58:15.415 -> +CREG: 0,2
22:58:15.415 -> 
22:58:15.415 -> OK
22:58:15.669 -> AT+CREG?
22:58:15.669 -> 
22:58:15.669 -> +CREG: 0,2
22:58:15.669 -> 
22:58:15.669 -> OK
22:58:15.916 -> AT+CREG?
22:58:15.916 -> 
22:58:15.916 -> +CREG: 0,2
22:58:15.916 -> 
22:58:15.916 -> OK
22:58:16.169 -> AT+CREG?
22:58:16.169 -> 
22:58:16.169 -> +CREG: 0,2
22:58:16.169 -> 
22:58:16.169 -> OK
22:58:16.416 -> AT+CREG?
22:58:16.416 -> 
22:58:16.416 -> +CREG: 0,2
22:58:16.416 -> 
22:58:16.416 -> OK
22:58:16.670 -> AT+CREG?
22:58:16.670 -> 
22:58:16.670 -> +CREG: 0,2
22:58:16.670 -> 
22:58:16.670 -> OK
22:58:16.917 -> AT+CREG?
22:58:16.917 -> 
22:58:16.917 -> +CREG: 0,2
22:58:16.917 -> 
22:58:16.917 -> OK
22:58:17.171 -> AT+CREG?
22:58:17.171 -> 
22:58:17.171 -> +CREG: 0,2
22:58:17.171 -> 
22:58:17.171 -> OK
22:58:17.464 -> AT+CREG?
22:58:17.464 -> 
22:58:17.464 -> +CREG: 0,2
22:58:17.464 -> 
22:58:17.464 -> OK
22:58:17.687 -> AT+CREG?
22:58:17.687 -> 
22:58:17.687 -> +CREG: 0,5
22:58:17.687 -> 
22:58:17.687 -> OK
22:58:17.687 ->  OK
22:58:17.687 -> AT+CREG?
22:58:17.734 -> 
22:58:17.734 -> +CREG: 0,5
22:58:17.734 -> 
22:58:17.734 -> OK
22:58:17.734 -> Connected to mobile network
22:58:17.734 -> Connecting to APN: iot.1nce.netAT+CIPSHUT
22:58:17.734 -> 
22:58:17.734 -> SHUT OK
22:58:17.734 -> AT+CGATT=0
22:58:17.734 -> 
22:58:17.734 -> OK
22:58:17.734 -> AT+SAPBR=3,1,"Contype","GPRS"
22:58:17.734 -> 
22:58:17.734 -> OK
22:58:17.734 -> AT+SAPBR=3,1,"APN","iot.1nce.net"
22:58:17.734 -> 
22:58:17.734 -> OK
22:58:17.734 -> AT+CGDCONT=1,"IP","iot.1nce.net"
22:58:17.819 -> 
22:58:17.819 -> OK
22:58:17.819 -> AT+CGACT=1,1
22:58:18.172 -> 
22:58:18.172 -> *PSUTTZ: 2021,8,26,20,58,17,"+8",1
22:58:18.172 -> [22671] ### Network time and time zone updated.
22:58:18.172 -> 
22:58:18.172 -> DST: 1
22:58:18.172 -> [22672] ### Daylight savings time state updated.
22:58:18.172 -> 
22:58:18.172 -> +CIEV: 10,"26203","o2 - de","o2 - de", 0, 0
22:58:23.283 -> 
22:58:23.283 -> +CTZV: +8,1
22:58:23.283 -> [27789] ### Network time zone updated.
22:58:23.283 -> 
22:58:23.283 -> *PSUTTZ: 2021,8,26,20,58,23,"+8",1
22:58:23.283 -> [27800] ### Network time and time zone updated.
22:58:23.283 -> 
22:58:23.283 -> DST: 1
22:58:23.283 -> [27801] ### Daylight savings time state updated.
22:58:23.684 -> 
22:58:23.684 -> OK
22:58:23.684 -> AT+SAPBR=1,1
22:58:23.984 -> 
22:58:23.984 -> OK
22:58:23.984 -> AT+SAPBR=2,1
22:58:23.984 -> 
22:58:23.984 -> +SAPBR: 1,1,"100.125.18.1"
22:58:23.984 -> 
22:58:23.984 -> OK
22:58:23.984 -> AT+CGATT=1
22:58:23.984 -> 
22:58:23.984 -> OK
22:58:23.984 -> AT+CIPMUX=1
22:58:23.984 -> 
22:58:23.984 -> OK
22:58:23.984 -> AT+CIPQSEND=1
22:58:23.984 -> 
22:58:23.984 -> OK
22:58:23.984 -> AT+CIPRXGET=1
22:58:23.984 -> 
22:58:23.984 -> OK
22:58:23.984 -> AT+CSTT="iot.1nce.net","",""
22:58:24.031 -> 
22:58:24.031 -> OK
22:58:24.031 -> AT+CIICR
22:58:24.031 -> 
22:58:24.031 -> OK
22:58:24.031 -> AT+CIFSR;E0
22:58:24.031 -> 
22:58:24.031 -> 100.125.18.1
22:58:24.031 -> 
22:58:24.031 -> OK
22:58:24.031 -> AT+CDNSCFG="8.8.8.8","8.8.4.4"
22:58:24.031 -> 
22:58:24.031 -> OK
22:58:24.031 ->  OK
22:58:24.031 -> Connecting to open-hive.org
22:58:24.031 -> AT+CIPCLOSE=0,1
22:58:24.031 -> 
22:58:24.031 -> +CME ERROR: operation not allowed
22:58:24.031 -> AT+CIPSSL=0
22:58:24.031 -> 
22:58:24.031 -> OK
22:58:24.031 -> AT+CIPSTART=0,"TCP","open-hive.org",80
22:58:24.031 -> 
22:58:24.031 -> OK
22:58:24.748 -> 
22:58:24.748 -> 0, CONNECT OK
22:58:24.748 ->  OK
22:58:24.748 -> Read sensors:
22:58:24.886 -> basic battery lavel: 0.00
22:58:24.886 -> /apiary/upload.php?user=[your-user-name]&id=[your-id]&node=10&dataset=timestamp-by-server,0.00
22:58:24.886 -> Performing HTTP GET request...
22:58:24.886 -> AT+CIPSEND=0,102
22:58:24.886 -> 
22:58:24.886 -> >GET /apiary/upload.php?user=[your-user-name]&id=[your-id]&node=10&dataset=timestamp-by-server,0.00 HTTP/1.1
22:58:24.886 ->  
22:58:24.886 -> DATA ACCEPT:0,102
22:58:24.886 -> AT+CIPSEND=0,21
22:58:24.886 -> 
22:58:24.886 -> >Host: open-hive.org
22:58:24.886 ->  
22:58:24.886 -> DATA ACCEPT:0,21
22:58:24.886 -> AT+CIPSEND=0,21
22:58:24.886 -> 
22:58:24.886 -> >Connection: close
22:58:24.886 -> 
22:58:24.886 ->  
22:58:24.886 -> DATA ACCEPT:0,21
22:58:24.886 -> AT+CIPSEND=0,2
22:58:24.886 -> 
22:58:24.886 -> >
22:58:24.886 ->  
22:58:24.886 -> DATA ACCEPT:0,2
22:58:24.886 -> AT+CIPRXGET=4,0
22:58:24.886 -> 
22:58:24.886 -> +CIPRXGET: 4,0,0
22:58:24.886 -> 
22:58:24.886 -> OK
22:58:24.886 -> AT+CIPSTATUS=0
22:58:24.933 -> 
22:58:24.933 -> +CIPSTATUS: 0,0,"TCP","87.230.20.183","80","CONNECTED"
22:58:24.933 -> 
22:58:24.933 -> OK
22:58:25.387 -> AT+CIPRXGET=4,0
22:58:25.387 -> 
22:58:25.387 -> +CIPRXGET: 4,0,0
22:58:25.387 -> 
22:58:25.387 -> OK
22:58:25.387 -> AT+CIPSTATUS=0
22:58:25.434 -> 
22:58:25.434 -> +CIPSTATUS: 0,0,"TCP","87.230.20.183","80","CONNECTED"
22:58:25.434 -> 
22:58:25.434 -> OK
22:58:25.888 -> AT+CIPRXGET=4,0
22:58:25.888 -> 
22:58:25.888 -> +CIPRXGET: 4,0,0
22:58:25.888 -> 
22:58:25.888 -> OK
22:58:25.888 -> AT+CIPSTATUS=0
22:58:25.935 -> 
22:58:25.935 -> +CIPSTATUS: 0,0,"TCP","87.230.20.183","80","CONNECTED"
22:58:25.935 -> 
22:58:25.935 -> OK
22:58:25.935 -> 
22:58:25.935 -> +CIPRXGET: 1,0
22:58:25.935 -> AT+CIPRXGET=4,0
22:58:25.935 -> 
22:58:25.935 -> +CIPRXGET: 4,0,208
22:58:25.935 -> 
22:58:25.935 -> OK
22:58:25.935 -> AT+CIPRXGET=2,0,208
22:58:25.988 -> 
22:58:25.988 -> +CIPRXGET: 2,0,208,0
22:58:25.988 -> HTTP/1.1 200 OK
22:58:25.988 -> Date: Thu, 26 Aug 2021 20:58:25 GMT
22:58:25.988 -> Server: Apache
22:58:25.988 -> X-Powered-By: PHP
22:58:25.988 -> Content-Length: 27
22:58:25.988 -> Connection: close
22:58:25.988 -> Content-Type: text/html
22:58:25.988 -> 
22:58:25.988 -> ok: open-hive
22:58:25.988 -> ok: hiveeyes
22:58:25.988 -> 
22:58:25.988 -> OK
22:58:25.988 -> HTTP/1.1 200 OK
22:58:25.988 -> Date: Thu, 26 Aug 2021 20:58:25 GMT
22:58:25.988 -> Server: Apache
22:58:25.988 -> X-Powered-By: PHP
22:58:25.988 -> Content-Length: 27
22:58:25.988 -> Connection: close
22:58:25.988 -> Content-Type: text/html
22:58:25.988 -> 
22:58:25.988 -> ok: open-hive
22:58:25.988 -> ok: hiveeyes
22:58:26.389 -> AT+CIPRXGET=4,0
22:58:26.389 -> 
22:58:26.389 -> +CIPRXGET: 4,0,0
22:58:26.389 -> 
22:58:26.389 -> OK
22:58:26.389 -> AT+CIPSTATUS=0
22:58:26.436 -> 
22:58:26.436 -> +CIPSTATUS: 0,0,"TCP","87.230.20.183","80","REMOTE CLOSING"
22:58:26.436 -> 
22:58:26.436 -> OK
22:58:26.436 -> 
22:58:26.436 -> AT+CIPCLOSE=0,1
22:58:26.436 -> 
22:58:26.436 -> 0, CLOSE OK
22:58:26.436 -> Server disconnected
22:58:26.436 -> AT+CIPSHUT
22:58:26.436 -> 
22:58:26.436 -> SHUT OK
22:58:26.436 -> AT+CGATT=0
22:58:26.483 -> 
22:58:26.483 -> +SAPBR 1: DEACT
22:58:26.689 -> 
22:58:26.689 -> OK
22:58:26.689 -> GPRS disconnected
22:58:26.689 -> AT+CPOWD=1
22:58:27.136 -> 
22:58:27.136 -> NORMAL POWER DOWNPoweroff
22:58:27.136 -> Runtime: 31
22:58:27.136 -> 

Dabei gibt es noch einige Fehlermeldungen, denen wir uns zuerst widmen sollten. Der erste ist +CME ERROR: CFUN state is 0 or 4 und +CME ERROR: SIM busy der vermutlich damit zusammen hängt.

AT+CPIN erwatet vermutlich die Eingabe der SIM-Pin, diese habe bei der verwendeten Karte deaktiviert, und mit

const char simPIN[] = ""; // SIM card PIN code, if any

im code auch nicht spezifiziert.

22:58:08.357 -> AT+CPIN?
22:58:08.357 -> 
22:58:08.357 -> +CME ERROR: CFUN state is 0 or 4
22:58:09.359 -> AT+CPIN?
22:58:09.359 -> 
22:58:09.359 -> RDY
22:58:09.359 -> 
22:58:09.359 -> +CFUN: 1
22:58:09.359 -> 
22:58:09.359 -> +CME ERROR: SIM busy
22:58:10.360 -> AT+CPIN?
22:58:10.360 -> 
22:58:10.360 -> +CPIN: READY
22:58:10.360 -> 
22:58:10.360 -> +CPIN: READY
22:58:10.360 -> 
22:58:10.360 -> OK

Die Vergabe einer Pin im code (ohne das bei der SIM-Karte einzurichten) führ übrigens zu dieser Ausgabe:

23:20:53.647 -> AT+CPIN?
23:20:53.647 -> 
23:20:53.647 -> +CME ERROR: CFUN state is 0 or 4
23:20:54.649 -> AT+CPIN?
23:20:54.649 -> 
23:20:54.649 -> RDY
23:20:54.649 -> 
23:20:54.649 -> +CFUN: 1
23:20:54.649 -> 
23:20:54.649 -> +CME ERROR: SIM busy
23:20:55.652 -> AT+CPIN?
23:20:55.652 -> 
23:20:55.652 -> +CPIN: READY
23:20:55.652 -> 
23:20:55.652 -> +CPIN: READY
23:20:55.652 -> 
23:20:55.652 -> OK
23:20:55.652 -> Turning on SIM800 Red LED...
23:20:55.652 -> AT+CNETLIGHT=1
23:20:55.652 -> AT+CPIN?
23:20:55.652 -> 
23:20:55.652 -> OK
23:20:55.852 -> 
23:20:55.852 -> Call Ready
23:20:55.852 -> 
23:20:55.852 -> +CPIN: READY
23:20:55.852 -> 
23:20:55.852 -> OK
23:20:55.852 -> AT+CPIN="1234"
23:20:55.906 -> 
23:20:55.906 -> +CME ERROR: operation not allowed
23:20:55.906 -> Waiting for network...AT+CREG?
23:20:55.906 -> 

Mir erschließt sich hier nicht was der Fehler ist, es funktioniert ja dann auch. Ein timing-Problem? Irgend etwas scheint beim Modem noch nicht initialisiert zu sein was es später ist?

16:14:32.631 -> Connecting to open-hive.org
16:14:32.631 -> AT+CIPCLOSE=0,1
16:14:32.631 -> 
16:14:32.631 -> +CME ERROR: operation not allowed
16:14:32.631 -> AT+CIPSSL=0
16:14:32.631 -> 
16:14:32.631 -> OK
16:14:32.631 -> AT+CIPSTART=0,"TCP","open-hive.org",80
16:14:32.684 -> 
16:14:32.684 -> OK

Zu +CME ERROR: operation not allowed habe ich das gefunden: Web client can't connect to the sample webside (AT+CIPCLOSE=0,1 +CME ERROR: operation not allowed). · Issue #466 · vshymanskyy/TinyGSM · GitHub auch da ist es bei mir so, dass die connection ja doch funktioniert, nur nicht gleich, beim bug-report wird empfohlen ein delay von 10 Sekunden einzubauen, was low power mäßig keine gute Idee ist. So lassen wie es ist?

modem.waitForNetwork weglassen?

Dazu ist mir aufgefallen, dass Rui Santos in seinem T-Call-tutorial auf randomnerdtutorials.com hier direkt zum Code von Rui diesen Codblock einfach weg lässt, der allerdings in allen example sketches der TinyGSM-lib drinnen steht:

SerialMon.print("Waiting for network...");
if (!modem.waitForNetwork(240000L)) {
    SerialMon.println(" fail");
    delay(10000);
    return;
}
SerialMon.println(" OK");

Und tatsächlich, wenn ich den in meinem sketch auskommentiere, verringert sich dir runtime auf um die 28 Sekunden, also 4 Sekunden schneller!

Die Doku sagt dazu nur:

Wait for network registration to be successful
    modem.waitForNetwork(600000L)

Welche Risiken gehe ich ein, wenn ich das weglasse?

modem.init(); statt modem.restart(); verwenden?

Ein weiterer Punkt ist, dass ich momentan modem.restart(); verwende. Im Beispiel-code steht schon, dass das lange dauer kann und eine Alternative modem.init(); sei

// Restart takes quite some time
// To skip it, call init() instead of restart()

allerdings steht irgenwo auch

// Or, use modem.init() if you don't need the complete restart

Was ist denn der Unterschied zwischen restart und init? Und wann brauche ich den “kompletten restart”? [edit] Dazu noch gefunden: GitHub - vshymanskyy/TinyGSM: A small Arduino library for GSM modules, that just works

Initialize the modem
    modem.init() or modem.restart()
    restart generally takes longer than init but ensures the module doesn't have lingering connections

Jedenfalls läuft der code mit init

//  modem.restart();
    modem.init();

in ca. 20 Sekunden einmal durch, also nochmal 8 Sekunden schneller!

Meine Lösung wäre hier (ist das ausreichend?) statt bisher:

SerialMon.print("Connecting to ");
SerialMon.println(server);
if (!client.connect(server, port)) {
    SerialMon.println(" fail server connection");
    delay(10000);
    return;
}
SerialMon.println(" OK");

das zu verwenden:

SerialMon.print("Connecting to ");
SerialMon.println(server);
if (!client.connect(server, port)) {
    SerialMon.println(" fail server connection");
    // in case server connection could not established
    goSleeping();

    // old code - will never be called
    delay(10000);
    return;
}
SerialMon.println(" OK");

mit diesem code als goSleeping()-Funktion:

void goSleeping()
{
  modem.gprsDisconnect();
  SerialMon.println(F("GPRS disconnected"));

  // Switch LED for network connection off 
  digitalWrite(LED_GPIO, LED_OFF);

  // after all off
  modem.poweroff();
  SerialMon.println(F("Poweroff"));
        
  // print runtime in seconds
  SerialMon.print(F("Runtime: "));
  SerialMon.println(millis() / 1000);
  SerialMon.println();

  // put ESP32 into deep sleep mode (with timer wake up)
  // Configure the wake up source as timer wake up  
  SerialMon.flush(); 
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  esp_deep_sleep_start();
}

D.h. die loop läuft bei einem Verbindungsfehler nicht mehr ununterbrochen im Kreis, sondern es wird nach einem Fehler nicht nochmals versucht, sondern erst die normale Schlafzeit abgewartet. Gleiches dann für if (!modem.waitForNetwork(240000L)) {... falls wir es brauchen und für if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {...

1 Like

Ich kenne mich mit mit den Modem Geschichten zwar nicht aus, aber es schaut für mich ganz OK aus. Du könntest aber Mal versuchen, das ’ !modem.waitForNetwork(240000L)’ erst direkt vor der eigentlichen Übertragung zu setzen.

Für mich schaut es so aus das Das Modem noch ein paar sec. braucht, bis es eine Verbindung hat.
Dieses wird denke ich durch die Zeit, die die Sensorabfrage dauert überbrückt. Wenn jetzt ein Sensor ausfällt, Auskonfiguriert oder durch einen besseren Treiber schneller wird. Könnte bei deinem jetzigen Code das Modem evtl. noch nicht bereit sein die Daten zu Senden. Und er würde in diesem Fall gar nichts mehr senden.
Die Fehlersuche wär dann auch etwas verwirrender, wenn man sich daran nicht erinnert.

Ich weiß nicht genau, was beim Modem-Initialisieren alles passiert und ob das parallel zum Auslesen der Sensoren sinnvoll ist. Ich möchte vermeiden, dass z. B. das Modem gerade sendet wenn wenige cm daneben die Wägezellenkabel Daten liefern. Daher war meine bisherige Strategie: Erst Sensoren lesen und dann Modem anwerfen.

Das ist gerade mein aktueller code

bool gsmMakeTCPConnection()
{
  // GSM startup
  /* do we need this here - after measuring - or can we call this in setup()?
     would be nice to power modem first when it is needed and waste no power before
  */
  setupModem();
  delay(1000);
  
  // initialize modem 
  #ifdef isDebug 
    Serial.println("initializing modem ...");
  #endif
  // restart takes quite some time, use modem.init() if you don't need the complete restart
  //modem.restart();
  modem.init();

  // turn on / off _network_ (status) LED to reduce current consumption
  #ifdef isDebugGsmNetLED
    turnOnNetlight();
  #else
    turnOffNetlight();
  #endif
  // the _status_ light cannot be turned off, only physically removable
  //turnOffStatuslight();

/*  
  // output modem information 
  String modemInfo = modem.getModemInfo();
  Serial.print("Modem: ");
  Serial.println(modemInfo);
*/

  // unlock SIM card with your PIN if needed
  if (strlen(simPIN) && modem.getSimStatus() != 3 ) {
    modem.simUnlock(simPIN);
  }

/*
  // do we need waitForNetwork? 
  Serial.print("waiting for network ... ");
  if (!modem.waitForNetwork()) {
    Serial.println("fail");
    Serial.println();

    delay(100);
    return false;
  }
  Serial.println(" OK");

  if (modem.isNetworkConnected()) {
    //debug
    #ifdef isDebug 
      Serial.println("Connected to mobile network");
    #endif
    #ifdef isDebugGreenOnboardLED
      // When the network connection is successful, turn on the indicator
      digitalWrite(LED_GPIO, LED_ON);
    #endif
  }
*/
  // make TCP / GPRS connection 
  
  // connect to GPRS / APN
  //debug
  #ifdef isDebug 
    Serial.print(F("connecting to GPRS / APN "));
    Serial.print(apn);
    Serial.print(F("... "));
  #endif
  if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
    #ifdef isDebug 
      Serial.println("failed");
      Serial.println();
    #endif
    
    delay(100);  // in case the GSM / GPRS connection could not enabled  ??? gsm_disconnect();
    return false;
  }
  #ifdef isDebug 
    Serial.println("ok");  
    Serial.println();
  #endif
  
  // When the network connection is successful, turn on the indicator
  #ifdef isDebugGreenOnboardLED
    // When the network connection is successful, turn on the indicator
    digitalWrite(LED_GPIO, LED_ON);
  #endif

  return true;
}

waitForNetwork() prüft mit dem übergebenen Timeout (oder default 60s) ob sich das Modem im Netz erfolgreich registriert hat (mittels isNetworkConnected() → getRegistrationStatus()).
Das ist also nur eine Status-Abfrage die dem Modem etwas Zeit verschafft, es wird keine Aktion am Modem ausgeführt. Kann ohne funktionieren, muss aber nicht :slight_smile:

Was auf jeden Fall weggelassen werden kann (im auskommentierten Teil), ist die if-Abfrage von isNetworkConnected() direkt nach waitForNetwork(), denn das ist redundant (siehe oben).

1 Like