├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── am7020_http ├── am7020_http.ino └── config.h ├── am7020_https ├── AllTrustAnchors.h ├── am7020_https.ino └── config.h ├── am7020_mqtt ├── am7020_mqtt.ino └── config.h ├── am7020_mqtts ├── AllTrustAnchors.h ├── am7020_mqtts.ino └── config.h └── images ├── am7020_front.jpg ├── am7020_hw.jpg ├── am7020_pinout.jpg └── am7020_rear.jpg /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 FelixLin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AM7020 Arduino 範例程式碼 2 | [AM7020](https://atticedu.com/index.php/am7020.html) (SIMCOM SIM7020E) 窄頻物聯網(NBIoT)模組 Arduino 範例程式碼 3 | 4 | ![AM7020](images/am7020_front.jpg) 5 | 6 | ## 相依函式庫 dependent libraries 7 | * [tinyGSM](https://github.com/FelixLinSY/TinyGSM) (/w SIM7020 patch) 8 | * [ArduinoHttpClinet](https://github.com/FelixLinSY/ArduinoHttpClient) (/w SIM7020 patch) for HTTP/HTTPS 9 | * [PubSubClient](https://github.com/knolleary/pubsubclient) for MQTT/MQTTS 10 | * [SSLClinet](https://github.com/OPEnSLab-OSU/SSLClient) for HTTPS/MQTTS 11 | 12 | 為方便起見,也可以直接下載打包好的 [library 壓縮檔](https://bit.ly/am7020libn),下載後直接解壓縮到 Arduino/libraries 目錄下即可。 13 | 14 | 15 | ## 通訊協定與開發板支援表 16 | 17 | | Boards | HTTP | HTTPS | MQTT | MQTTS | 18 | | ------ | ------ | ------ |------ | ------ | 19 | | Arduino UNO/Nano | supported | | supported | | 20 | | Arduino Mega | supported | | supported | | 21 | | ESP32 | supported | supported | supported | supported | 22 | | Arduino MKR Series | supported | supported | supported | supported | 23 | 24 | ## 教學說明 25 | 待新增 26 | 27 | 28 | # AM7020 Arduino 29 | AM7020 (SIMCOM SIM7020E) NBIoT module example code for Arduino 30 | ![AM7020](images/am7020_front.jpg) 31 | 32 | ## dependent libraries 33 | * [tinyGSM](https://github.com/FelixLinSY/TinyGSM) (/w SIM7020 patch) 34 | * [ArduinoHttpClinet](https://github.com/FelixLinSY/ArduinoHttpClient) (/w SIM7020 patch) for HTTP/HTTPS 35 | * [PubSubClient](https://github.com/knolleary/pubsubclient) for MQTT/MQTTS 36 | * [SSLClinet](https://github.com/OPEnSLab-OSU/SSLClient) for HTTPS/MQTTS 37 | 38 | ## Supported protocol for Arduino boards 39 | 40 | | Boards | HTTP | HTTPS | MQTT | MQTTS | 41 | | ------ | ------ | ------ |------ | ------ | 42 | | Arduino UNO/Nano | supported | | supported | | 43 | | Arduino Mega | supported | | supported | | 44 | | ESP32 | supported | supported | supported | supported | 45 | | Arduino MKR Series | supported | supported | supported | supported | 46 | 47 | ## Tutorial 48 | TBD 49 | 50 | -------------------------------------------------------------------------------- /am7020_http/am7020_http.ino: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | #include 3 | #include 4 | 5 | #ifdef DEBUG_DUMP_AT_COMMAND 6 | #include 7 | StreamDebugger debugger(SerialAT, SerialMon); 8 | TinyGsm modem(debugger, AM7020_RESET); 9 | 10 | #else 11 | TinyGsm modem(SerialAT, AM7020_RESET); 12 | 13 | #endif 14 | 15 | TinyGsmClient tcpClient(modem); 16 | HttpClient httpClient = HttpClient(tcpClient, HTTP_SERVER, HTTP_PORT); 17 | 18 | void nbConnect(void); 19 | 20 | void setup() 21 | { 22 | SerialMon.begin(MONITOR_BAUDRATE); 23 | SerialAT.begin(AM7020_BAUDRATE); 24 | 25 | httpClient.connectionKeepAlive(); 26 | nbConnect(); 27 | } 28 | 29 | void loop() 30 | { 31 | static unsigned long timer = 0; 32 | char buff[100]; 33 | int state_code; 34 | String body; 35 | 36 | if (!modem.isNetworkConnected()) { 37 | nbConnect(); 38 | } 39 | 40 | if (millis() >= timer) { 41 | timer = millis() + UPLOAD_INTERVAL; 42 | 43 | /* Get Most Recent Data */ 44 | SerialMon.println(F("HTTP Get...")); 45 | sprintf(buff, "/%s", HTTP_API); 46 | httpClient.get(buff); 47 | state_code = httpClient.responseStatusCode(); 48 | body = httpClient.responseBody(); 49 | 50 | SerialMon.print(F("GET state code = ")); 51 | SerialMon.println(state_code); 52 | SerialMon.print(F("body = ")); 53 | SerialMon.println(body); 54 | 55 | /* Create Data */ 56 | SerialMon.println(F("HTTP Post...")); 57 | sprintf(buff, "/%s", HTTP_API); 58 | httpClient.post(buff, "application/json", "{\"value\": \"POST\"}"); 59 | 60 | state_code = httpClient.responseStatusCode(); 61 | body = httpClient.responseBody(); 62 | SerialMon.print(F("POST state code = ")); 63 | SerialMon.println(state_code); 64 | SerialMon.print(F("body = ")); 65 | SerialMon.println(body); 66 | } 67 | } 68 | 69 | void nbConnect(void) 70 | { 71 | SerialMon.println(F("Initializing modem...")); 72 | while (!modem.init() || !modem.nbiotConnect(APN, BAND)) { 73 | SerialMon.print(F(".")); 74 | } 75 | 76 | SerialMon.print(F("Waiting for network...")); 77 | while (!modem.waitForNetwork()) { 78 | SerialMon.print(F(".")); 79 | } 80 | SerialMon.println(F(" success")); 81 | } 82 | -------------------------------------------------------------------------------- /am7020_http/config.h: -------------------------------------------------------------------------------- 1 | #ifndef _CONFIG_H 2 | #define _CONFIG_H 3 | 4 | #define TINY_GSM_MODEM_SIM7020 5 | 6 | /* Define the serial console for debug prints, if needed */ 7 | //#define TINY_GSM_DEBUG SerialMon 8 | /* uncomment to dump all AT commands */ 9 | //#define DEBUG_DUMP_AT_COMMAND 10 | 11 | #define UPLOAD_INTERVAL 60000 12 | 13 | #define SerialMon Serial 14 | #define MONITOR_BAUDRATE 115200 15 | 16 | /* AM7020 module setup: Serial port, baudrate, and reset pin */ 17 | #if (defined ARDUINO_AVR_UNO) || (defined ARDUINO_AVR_NANO) 18 | /* Arduino Uno */ 19 | #include 20 | SoftwareSerial SoftSerial(8, 9); //RX:8 TX:9 21 | #define SerialAT SoftSerial 22 | #define AM7020_BAUDRATE 38400 23 | #define AM7020_RESET 7 24 | 25 | #elif defined ARDUINO_AVR_MEGA2560 26 | /* Arduino Mega2560 */ 27 | #define SerialAT Serial1 28 | #define AM7020_BAUDRATE 115200 29 | #define AM7020_RESET 7 30 | 31 | #elif (defined ARDUINO_SAMD_MKRZERO)|| (defined ARDUINO_SAMD_MKRWIFI1010) 32 | /* Arduino MKR Series */ 33 | #define SerialAT Serial1 34 | #define AM7020_BAUDRATE 115200 35 | #define AM7020_RESET A5 36 | 37 | #elif defined ARDUINO_ESP32_DEV 38 | /* ESP32 Boards */ 39 | #define SerialAT Serial2 40 | #define AM7020_BAUDRATE 115200 41 | #define AM7020_RESET 5 42 | 43 | #else 44 | /* add your own boards and uncomment it */ 45 | /* 46 | #define SerialAT Serial1 47 | #define AM7020_BAUDRATE 9600 48 | #define AM7020_RESET 7 49 | */ 50 | 51 | #endif 52 | 53 | /* set GSM PIN */ 54 | #define GSM_PIN "" 55 | 56 | // for taiwan mobile 57 | #define APN "twm.nbiot" 58 | #define BAND 28 59 | 60 | // for CHT 61 | //#define APN "internet.iot" 62 | //#define BAND 8 63 | 64 | 65 | // HTTP Server Setting, using Adafruit.io for example 66 | #define HTTP_PORT 80 67 | #define HTTP_SERVER "httpbin.org" 68 | #define HTTP_API "/anything" 69 | 70 | #endif /* _CONFIG_H */ 71 | -------------------------------------------------------------------------------- /am7020_https/AllTrustAnchors.h: -------------------------------------------------------------------------------- 1 | #ifndef _CERTIFICATES_H_ 2 | #define _CERTIFICATES_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" 6 | { 7 | #endif 8 | 9 | /* This file is auto-generated by the pycert_bearssl tool. Do not change it manually. 10 | * Certificates are BearSSL br_x509_trust_anchor format. Included certs: 11 | * 12 | * Index: 0 13 | * Label: Starfield Class 2 Certification Authority 14 | * Subject: OU=Starfield Class 2 Certification Authority,O=Starfield Technologies\, Inc.,C=US 15 | * Domain(s): httpbin.org 16 | */ 17 | 18 | #define TAs_NUM 1 19 | 20 | static const unsigned char TA_DN0[] = { 21 | 0x30, 0x68, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 22 | 0x02, 0x55, 0x53, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 23 | 0x13, 0x1c, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 24 | 0x54, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 25 | 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 26 | 0x55, 0x04, 0x0b, 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 27 | 0x6c, 0x64, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 28 | 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 29 | 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 30 | }; 31 | 32 | static const unsigned char TA_RSA_N0[] = { 33 | 0xb7, 0x32, 0xc8, 0xfe, 0xe9, 0x71, 0xa6, 0x04, 0x85, 0xad, 0x0c, 0x11, 34 | 0x64, 0xdf, 0xce, 0x4d, 0xef, 0xc8, 0x03, 0x18, 0x87, 0x3f, 0xa1, 0xab, 35 | 0xfb, 0x3c, 0xa6, 0x9f, 0xf0, 0xc3, 0xa1, 0xda, 0xd4, 0xd8, 0x6e, 0x2b, 36 | 0x53, 0x90, 0xfb, 0x24, 0xa4, 0x3e, 0x84, 0xf0, 0x9e, 0xe8, 0x5f, 0xec, 37 | 0xe5, 0x27, 0x44, 0xf5, 0x28, 0xa6, 0x3f, 0x7b, 0xde, 0xe0, 0x2a, 0xf0, 38 | 0xc8, 0xaf, 0x53, 0x2f, 0x9e, 0xca, 0x05, 0x01, 0x93, 0x1e, 0x8f, 0x66, 39 | 0x1c, 0x39, 0xa7, 0x4d, 0xfa, 0x5a, 0xb6, 0x73, 0x04, 0x25, 0x66, 0xeb, 40 | 0x77, 0x7f, 0xe7, 0x59, 0xc6, 0x4a, 0x99, 0x25, 0x14, 0x54, 0xeb, 0x26, 41 | 0xc7, 0xf3, 0x7f, 0x19, 0xd5, 0x30, 0x70, 0x8f, 0xaf, 0xb0, 0x46, 0x2a, 42 | 0xff, 0xad, 0xeb, 0x29, 0xed, 0xd7, 0x9f, 0xaa, 0x04, 0x87, 0xa3, 0xd4, 43 | 0xf9, 0x89, 0xa5, 0x34, 0x5f, 0xdb, 0x43, 0x91, 0x82, 0x36, 0xd9, 0x66, 44 | 0x3c, 0xb1, 0xb8, 0xb9, 0x82, 0xfd, 0x9c, 0x3a, 0x3e, 0x10, 0xc8, 0x3b, 45 | 0xef, 0x06, 0x65, 0x66, 0x7a, 0x9b, 0x19, 0x18, 0x3d, 0xff, 0x71, 0x51, 46 | 0x3c, 0x30, 0x2e, 0x5f, 0xbe, 0x3d, 0x77, 0x73, 0xb2, 0x5d, 0x06, 0x6c, 47 | 0xc3, 0x23, 0x56, 0x9a, 0x2b, 0x85, 0x26, 0x92, 0x1c, 0xa7, 0x02, 0xb3, 48 | 0xe4, 0x3f, 0x0d, 0xaf, 0x08, 0x79, 0x82, 0xb8, 0x36, 0x3d, 0xea, 0x9c, 49 | 0xd3, 0x35, 0xb3, 0xbc, 0x69, 0xca, 0xf5, 0xcc, 0x9d, 0xe8, 0xfd, 0x64, 50 | 0x8d, 0x17, 0x80, 0x33, 0x6e, 0x5e, 0x4a, 0x5d, 0x99, 0xc9, 0x1e, 0x87, 51 | 0xb4, 0x9d, 0x1a, 0xc0, 0xd5, 0x6e, 0x13, 0x35, 0x23, 0x5e, 0xdf, 0x9b, 52 | 0x5f, 0x3d, 0xef, 0xd6, 0xf7, 0x76, 0xc2, 0xea, 0x3e, 0xbb, 0x78, 0x0d, 53 | 0x1c, 0x42, 0x67, 0x6b, 0x04, 0xd8, 0xf8, 0xd6, 0xda, 0x6f, 0x8b, 0xf2, 54 | 0x44, 0xa0, 0x01, 0xab, 55 | }; 56 | 57 | static const unsigned char TA_RSA_E0[] = { 58 | 0x03, 59 | }; 60 | 61 | static const br_x509_trust_anchor TAs[] = { 62 | { 63 | { (unsigned char *)TA_DN0, sizeof TA_DN0 }, 64 | BR_X509_TA_CA, 65 | { 66 | BR_KEYTYPE_RSA, 67 | { .rsa = { 68 | (unsigned char *)TA_RSA_N0, sizeof TA_RSA_N0, 69 | (unsigned char *)TA_RSA_E0, sizeof TA_RSA_E0, 70 | } } 71 | } 72 | }, 73 | }; 74 | 75 | #ifdef __cplusplus 76 | } /* extern "C" */ 77 | #endif 78 | 79 | #endif /* ifndef _CERTIFICATES_H_ */ 80 | -------------------------------------------------------------------------------- /am7020_https/am7020_https.ino: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | #include 3 | #include 4 | #include 5 | 6 | #include "AllTrustAnchors.h" 7 | 8 | #ifdef DEBUG_DUMP_AT_COMMAND 9 | #include 10 | StreamDebugger debugger(SerialAT, SerialMon); 11 | TinyGsm modem(debugger, AM7020_RESET); 12 | 13 | #else 14 | TinyGsm modem(SerialAT, AM7020_RESET); 15 | 16 | #endif 17 | 18 | TinyGsmClient tcpClient(modem); 19 | SSLClient sslClient(tcpClient, TAs, (size_t)TAs_NUM, A0); 20 | HttpClient httpClient = HttpClient(sslClient, HTTP_SERVER, HTTP_PORT); 21 | 22 | void nbConnect(void); 23 | 24 | void setup() 25 | { 26 | SerialMon.begin(MONITOR_BAUDRATE); 27 | SerialAT.begin(AM7020_BAUDRATE); 28 | 29 | httpClient.connectionKeepAlive(); 30 | nbConnect(); 31 | } 32 | 33 | void loop() 34 | { 35 | static unsigned long timer = 0; 36 | char buff[100]; 37 | int state_code; 38 | String body; 39 | 40 | if (!modem.isNetworkConnected()) { 41 | nbConnect(); 42 | } 43 | 44 | if (millis() >= timer) { 45 | timer = millis() + UPLOAD_INTERVAL; 46 | 47 | /* Get Most Recent Data */ 48 | SerialMon.println(F("HTTPS Get...")); 49 | sprintf(buff, "/%s", HTTP_API); 50 | httpClient.get(buff); 51 | state_code = httpClient.responseStatusCode(); 52 | body = httpClient.responseBody(); 53 | 54 | SerialMon.print(F("GET state code = ")); 55 | SerialMon.println(state_code); 56 | SerialMon.print(F("body = ")); 57 | SerialMon.println(body); 58 | 59 | /* Create Data */ 60 | SerialMon.println(F("HTTPS Post...")); 61 | sprintf(buff, "/%s", HTTP_API); 62 | httpClient.post(buff, "application/json", "{\"value\": \"POST\"}"); 63 | 64 | state_code = httpClient.responseStatusCode(); 65 | body = httpClient.responseBody(); 66 | SerialMon.print(F("POST state code = ")); 67 | SerialMon.println(state_code); 68 | SerialMon.print(F("body = ")); 69 | SerialMon.println(body); 70 | } 71 | } 72 | 73 | void nbConnect(void) 74 | { 75 | SerialMon.println(F("Initializing modem...")); 76 | while (!modem.init() || !modem.nbiotConnect(APN, BAND)) { 77 | SerialMon.print(F(".")); 78 | } 79 | 80 | SerialMon.print(F("Waiting for network...")); 81 | while (!modem.waitForNetwork()) { 82 | SerialMon.print(F(".")); 83 | } 84 | SerialMon.println(F(" success")); 85 | } 86 | -------------------------------------------------------------------------------- /am7020_https/config.h: -------------------------------------------------------------------------------- 1 | #ifndef _CONFIG_H 2 | #define _CONFIG_H 3 | 4 | #define TINY_GSM_MODEM_SIM7020 5 | 6 | /* Define the serial console for debug prints, if needed */ 7 | // #define TINY_GSM_DEBUG SerialMon 8 | /* uncomment to dump all AT commands */ 9 | // #define DEBUG_DUMP_AT_COMMAND 10 | 11 | #define UPLOAD_INTERVAL 60000 12 | 13 | #define SerialMon Serial 14 | #define MONITOR_BAUDRATE 115200 15 | 16 | /* AM7020 module setup: Serial port, baudrate, and reset pin */ 17 | #if (defined ARDUINO_AVR_UNO) || (defined ARDUINO_AVR_NANO) 18 | /* Arduino Uno */ 19 | #include 20 | SoftwareSerial SoftSerial(8, 9); //RX:8 TX:9 21 | #define SerialAT SoftSerial 22 | #define AM7020_BAUDRATE 38400 23 | #define AM7020_RESET 7 24 | 25 | #elif defined ARDUINO_AVR_MEGA2560 26 | /* Arduino Mega2560 */ 27 | #define SerialAT Serial1 28 | #define AM7020_BAUDRATE 115200 29 | #define AM7020_RESET 7 30 | 31 | #elif (defined ARDUINO_SAMD_MKRZERO)|| (defined ARDUINO_SAMD_MKRWIFI1010) 32 | /* Arduino MKR Series */ 33 | #define SerialAT Serial1 34 | #define AM7020_BAUDRATE 115200 35 | #define AM7020_RESET A5 36 | 37 | #elif defined ARDUINO_ESP32_DEV 38 | /* ESP32 Boards */ 39 | #define SerialAT Serial2 40 | #define AM7020_BAUDRATE 115200 41 | #define AM7020_RESET 5 42 | 43 | #else 44 | /* add your own boards and uncomment it */ 45 | /* 46 | #define SerialAT Serial1 47 | #define AM7020_BAUDRATE 9600 48 | #define AM7020_RESET 7 49 | */ 50 | 51 | #endif 52 | 53 | /* set GSM PIN */ 54 | #define GSM_PIN "" 55 | 56 | // for taiwan mobile 57 | #define APN "twm.nbiot" 58 | #define BAND 28 59 | 60 | // for CHT 61 | //#define APN "internet.iot" 62 | //#define BAND 8 63 | 64 | 65 | // HTTP Server Setting, using Adafruit.io for example 66 | #define HTTP_PORT 443 67 | #define HTTP_SERVER "httpbin.org" 68 | #define HTTP_API "/anything" 69 | 70 | #endif /* _CONFIG_H */ 71 | -------------------------------------------------------------------------------- /am7020_mqtt/am7020_mqtt.ino: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | #include 3 | #include 4 | 5 | #ifdef DEBUG_DUMP_AT_COMMAND 6 | #include 7 | StreamDebugger debugger(SerialAT, SerialMon); 8 | TinyGsm modem(debugger, AM7020_RESET); 9 | 10 | #else 11 | TinyGsm modem(SerialAT, AM7020_RESET); 12 | 13 | #endif 14 | 15 | TinyGsmClient tcpClient(modem); 16 | PubSubClient mqttClient(MQTT_BROKER, MQTT_PORT, tcpClient); 17 | 18 | void mqttCallback(char *topic, byte *payload, unsigned int len); 19 | void mqttConnect(void); 20 | void nbConnect(void); 21 | 22 | void setup() 23 | { 24 | SerialMon.begin(MONITOR_BAUDRATE); 25 | SerialAT.begin(AM7020_BAUDRATE); 26 | 27 | randomSeed(analogRead(A0)); 28 | 29 | nbConnect(); 30 | mqttClient.setCallback(mqttCallback); 31 | mqttClient.setKeepAlive(300); 32 | } 33 | 34 | void loop() 35 | { 36 | static unsigned long timer = 0; 37 | char buff[10]; 38 | 39 | if (!mqttClient.connected()) { 40 | if (!modem.isNetworkConnected()) { 41 | nbConnect(); 42 | } 43 | SerialMon.println(F("=== MQTT NOT CONNECTED ===")); 44 | mqttConnect(); 45 | } 46 | 47 | if (millis() >= timer) { 48 | timer = millis() + UPLOAD_INTERVAL; 49 | sprintf(buff, "%ld", random(65535)); 50 | SerialMon.print(F("Publish: ")); 51 | SerialMon.println(buff); 52 | mqttClient.publish(MQTT_TOPIC, buff); 53 | } 54 | 55 | mqttClient.loop(); 56 | } 57 | 58 | void mqttCallback(char *topic, byte *payload, unsigned int len) 59 | { 60 | SerialMon.print(F("Message arrived [")); 61 | SerialMon.print(topic); 62 | SerialMon.print(F("]: ")); 63 | SerialMon.write(payload, len); 64 | SerialMon.println(); 65 | } 66 | 67 | void mqttConnect(void) 68 | { 69 | SerialMon.print(F("Connecting to ")); 70 | SerialMon.print(MQTT_BROKER); 71 | SerialMon.print(F("...")); 72 | 73 | // Connect to MQTT Broker 74 | String mqttid = ("MQTTID_" + String(random(65536))); 75 | while (!mqttClient.connect(mqttid.c_str(), MQTT_USERNAME, MQTT_PASSWORD)) { 76 | SerialMon.println(F(" fail")); 77 | } 78 | SerialMon.println(F(" success")); 79 | mqttClient.publish(MQTT_TOPIC, "00000"); 80 | mqttClient.subscribe(MQTT_TOPIC); 81 | } 82 | 83 | void nbConnect(void) 84 | { 85 | SerialMon.println(F("Initializing modem...")); 86 | while (!modem.init() || !modem.nbiotConnect(APN, BAND)) { 87 | SerialMon.print(F(".")); 88 | }; 89 | 90 | SerialMon.print(F("Waiting for network...")); 91 | while (!modem.waitForNetwork()) { 92 | SerialMon.print(F(".")); 93 | } 94 | SerialMon.println(F(" success")); 95 | } 96 | -------------------------------------------------------------------------------- /am7020_mqtt/config.h: -------------------------------------------------------------------------------- 1 | #ifndef _CONFIG_H 2 | #define _CONFIG_H 3 | 4 | #define TINY_GSM_MODEM_SIM7020 5 | 6 | /* Define the serial console for debug prints, if needed */ 7 | // #define TINY_GSM_DEBUG SerialMon 8 | /* uncomment to dump all AT commands */ 9 | // #define DEBUG_DUMP_AT_COMMAND 10 | 11 | #define UPLOAD_INTERVAL 60000 12 | 13 | #define SerialMon Serial 14 | #define MONITOR_BAUDRATE 115200 15 | 16 | 17 | /* AM7020 module setup: Serial port, baudrate, and reset pin */ 18 | #if (defined ARDUINO_AVR_UNO) || (defined ARDUINO_AVR_NANO) 19 | /* Arduino Uno */ 20 | #include 21 | SoftwareSerial SoftSerial(8, 9); //RX:8 TX:9 22 | #define SerialAT SoftSerial 23 | #define AM7020_BAUDRATE 38400 24 | #define AM7020_RESET 7 25 | 26 | #elif defined ARDUINO_AVR_MEGA2560 27 | /* Arduino Mega2560 */ 28 | #define SerialAT Serial1 29 | #define AM7020_BAUDRATE 115200 30 | #define AM7020_RESET 7 31 | 32 | #elif (defined ARDUINO_SAMD_MKRZERO)|| (defined ARDUINO_SAMD_MKRWIFI1010) 33 | /* Arduino MKR Series */ 34 | #define SerialAT Serial1 35 | #define AM7020_BAUDRATE 115200 36 | #define AM7020_RESET A5 37 | 38 | #elif defined ARDUINO_ESP32_DEV 39 | /* ESP32 Boards */ 40 | #define SerialAT Serial2 41 | #define AM7020_BAUDRATE 115200 42 | #define AM7020_RESET 5 43 | 44 | #else 45 | /* add your own boards and uncomment it */ 46 | /* 47 | #define SerialAT Serial1 48 | #define AM7020_BAUDRATE 9600 49 | #define AM7020_RESET 7 50 | */ 51 | 52 | #endif 53 | 54 | /* set GSM PIN */ 55 | #define GSM_PIN "" 56 | 57 | // for taiwan mobile 58 | #define APN "twm.nbiot" 59 | #define BAND 28 60 | 61 | // for CHT 62 | //#define APN "internet.iot" 63 | //#define BAND 8 64 | 65 | // MQTT Setting 66 | #define MQTT_BROKER "broker.hivemq.com" 67 | #define MQTT_PORT 1883 68 | #define MQTT_USERNAME "" 69 | #define MQTT_PASSWORD "" 70 | #define MQTT_TOPIC "temp/humidity" 71 | 72 | #endif /* _CONFIG_H */ 73 | -------------------------------------------------------------------------------- /am7020_mqtts/AllTrustAnchors.h: -------------------------------------------------------------------------------- 1 | #ifndef _CERTIFICATES_H_ 2 | #define _CERTIFICATES_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" 6 | { 7 | #endif 8 | 9 | /* This file is auto-generated by the pycert_bearssl tool. Do not change it manually. 10 | * Certificates are BearSSL br_x509_trust_anchor format. Included certs: 11 | * 12 | * Index: 0 13 | * Label: mosquitto.org 14 | * Subject: 1.2.840.113549.1.9.1=roger@atchoo.org,CN=mosquitto.org,OU=CA,O=Mosquitto,L=Derby,ST=United Kingdom,C=GB 15 | */ 16 | 17 | #define TAs_NUM 1 18 | 19 | static const unsigned char TA_DN0[] = { 20 | 0x30, 0x81, 0x90, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 21 | 0x13, 0x02, 0x47, 0x42, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 22 | 0x08, 0x0c, 0x0e, 0x55, 0x6e, 0x69, 0x74, 0x65, 0x64, 0x20, 0x4b, 0x69, 23 | 0x6e, 0x67, 0x64, 0x6f, 0x6d, 0x31, 0x0e, 0x30, 0x0c, 0x06, 0x03, 0x55, 24 | 0x04, 0x07, 0x0c, 0x05, 0x44, 0x65, 0x72, 0x62, 0x79, 0x31, 0x12, 0x30, 25 | 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x09, 0x4d, 0x6f, 0x73, 0x71, 26 | 0x75, 0x69, 0x74, 0x74, 0x6f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 27 | 0x04, 0x0b, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 28 | 0x55, 0x04, 0x03, 0x0c, 0x0d, 0x6d, 0x6f, 0x73, 0x71, 0x75, 0x69, 0x74, 29 | 0x74, 0x6f, 0x2e, 0x6f, 0x72, 0x67, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x09, 30 | 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x10, 0x72, 31 | 0x6f, 0x67, 0x65, 0x72, 0x40, 0x61, 0x74, 0x63, 0x68, 0x6f, 0x6f, 0x2e, 32 | 0x6f, 0x72, 0x67, 33 | }; 34 | 35 | static const unsigned char TA_RSA_N0[] = { 36 | 0xc1, 0x34, 0x1c, 0xa9, 0x88, 0xcd, 0xf4, 0xce, 0xc2, 0x42, 0x8b, 0x4f, 37 | 0x74, 0xc7, 0x1d, 0xef, 0x8e, 0x6d, 0xd8, 0xb3, 0x6a, 0x63, 0xe0, 0x51, 38 | 0x99, 0x83, 0xeb, 0x84, 0xdf, 0xdf, 0x32, 0x5d, 0x35, 0xe6, 0x06, 0x62, 39 | 0x7e, 0x02, 0x11, 0x76, 0xf2, 0x3f, 0xa7, 0xf2, 0xde, 0xd5, 0x9c, 0xf1, 40 | 0x2d, 0x9b, 0xa1, 0x6e, 0x9d, 0xce, 0xb1, 0xfc, 0x49, 0xd1, 0x5f, 0xf6, 41 | 0xea, 0x37, 0xdb, 0x41, 0x89, 0x03, 0xd0, 0x7b, 0x53, 0x51, 0x56, 0x4d, 42 | 0xed, 0xf1, 0x75, 0xaf, 0xcb, 0x9b, 0x72, 0x45, 0x7d, 0xa1, 0xe3, 0x91, 43 | 0x6c, 0x3b, 0x8c, 0x1c, 0x1c, 0x6a, 0xe4, 0x19, 0x8e, 0x91, 0x88, 0x34, 44 | 0x76, 0xa9, 0x1d, 0x19, 0x69, 0x88, 0x26, 0x6c, 0xaa, 0xe0, 0x2d, 0x84, 45 | 0xe8, 0x31, 0x5b, 0xd4, 0xa0, 0x0e, 0x06, 0x25, 0x1b, 0x31, 0x00, 0xb3, 46 | 0x4e, 0xa9, 0x90, 0x41, 0x62, 0x33, 0x0f, 0xaa, 0x0d, 0xf2, 0xe8, 0xfe, 47 | 0xcc, 0x45, 0x28, 0x1e, 0xaf, 0x42, 0x51, 0x5e, 0x90, 0xc7, 0x82, 0xca, 48 | 0x68, 0xcb, 0x09, 0xb3, 0x70, 0x3c, 0x9c, 0xaa, 0xca, 0x11, 0x66, 0x3d, 49 | 0x6c, 0x22, 0xa3, 0xf3, 0xc3, 0x32, 0xbb, 0x81, 0x4f, 0x33, 0xc7, 0xdd, 50 | 0xc8, 0xa8, 0x06, 0x7a, 0xc9, 0x58, 0xa5, 0xdc, 0xdc, 0xe8, 0xd7, 0x74, 51 | 0xb1, 0x85, 0x24, 0xe7, 0xe3, 0xee, 0x93, 0xf4, 0x8f, 0xf7, 0x6b, 0xd8, 52 | 0xb1, 0xfb, 0xd9, 0xe4, 0xaf, 0xbf, 0x73, 0xd0, 0x40, 0x59, 0x7d, 0xd0, 53 | 0x26, 0x4f, 0x16, 0x1a, 0xc2, 0x51, 0xc4, 0x47, 0x49, 0x2c, 0x68, 0x13, 54 | 0xac, 0xa3, 0x18, 0xe7, 0x67, 0xcf, 0xb7, 0xfa, 0x3e, 0xf7, 0x8b, 0x20, 55 | 0x1e, 0x7b, 0xe2, 0x44, 0x0e, 0x47, 0x0b, 0x7c, 0x78, 0xf9, 0xf4, 0xca, 56 | 0x27, 0x6b, 0x4c, 0x2d, 0x62, 0x72, 0xd8, 0xa4, 0x10, 0x3d, 0xe7, 0x1d, 57 | 0x88, 0x4c, 0x50, 0xe5, 58 | }; 59 | 60 | static const unsigned char TA_RSA_E0[] = { 61 | 0x01, 0x00, 0x01, 62 | }; 63 | 64 | static const br_x509_trust_anchor TAs[] = { 65 | { 66 | { (unsigned char *)TA_DN0, sizeof TA_DN0 }, 67 | BR_X509_TA_CA, 68 | { 69 | BR_KEYTYPE_RSA, 70 | { .rsa = { 71 | (unsigned char *)TA_RSA_N0, sizeof TA_RSA_N0, 72 | (unsigned char *)TA_RSA_E0, sizeof TA_RSA_E0, 73 | } } 74 | } 75 | }, 76 | }; 77 | 78 | #ifdef __cplusplus 79 | } /* extern "C" */ 80 | #endif 81 | 82 | #endif /* ifndef _CERTIFICATES_H_ */ 83 | -------------------------------------------------------------------------------- /am7020_mqtts/am7020_mqtts.ino: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | #include 3 | #include 4 | #include 5 | 6 | #include "AllTrustAnchors.h" 7 | 8 | #ifdef DEBUG_DUMP_AT_COMMAND 9 | #include 10 | StreamDebugger debugger(SerialAT, SerialMon); 11 | TinyGsm modem(debugger, AM7020_RESET); 12 | 13 | #else 14 | TinyGsm modem(SerialAT, AM7020_RESET); 15 | 16 | #endif 17 | 18 | TinyGsmClient tcpClient(modem); 19 | SSLClient sslClient(tcpClient, TAs, (size_t)TAs_NUM, A0); 20 | PubSubClient mqttClient(MQTT_BROKER, MQTT_PORT, sslClient); 21 | 22 | void mqttCallback(char *topic, byte *payload, unsigned int len); 23 | void mqttConnect(void); 24 | void nbConnect(void); 25 | 26 | void setup() 27 | { 28 | SerialMon.begin(MONITOR_BAUDRATE); 29 | SerialAT.begin(AM7020_BAUDRATE); 30 | 31 | randomSeed(analogRead(A0)); 32 | 33 | nbConnect(); 34 | mqttClient.setCallback(mqttCallback); 35 | mqttClient.setKeepAlive(300); 36 | } 37 | 38 | void loop() 39 | { 40 | static unsigned long timer = 0; 41 | char buff[10]; 42 | 43 | if (!mqttClient.connected()) { 44 | if (!modem.isNetworkConnected()) { 45 | nbConnect(); 46 | } 47 | SerialMon.println(F("=== MQTT NOT CONNECTED ===")); 48 | mqttConnect(); 49 | } 50 | 51 | if (millis() >= timer) { 52 | timer = millis() + UPLOAD_INTERVAL; 53 | sprintf(buff, "%ld", random(65535)); 54 | SerialMon.print(F("Publish: ")); 55 | SerialMon.println(buff); 56 | mqttClient.publish(MQTT_TOPIC, buff); 57 | } 58 | 59 | mqttClient.loop(); 60 | } 61 | 62 | void mqttCallback(char *topic, byte *payload, unsigned int len) 63 | { 64 | SerialMon.print(F("Message arrived [")); 65 | SerialMon.print(topic); 66 | SerialMon.print(F("]: ")); 67 | SerialMon.write(payload, len); 68 | SerialMon.println(); 69 | } 70 | 71 | void mqttConnect(void) 72 | { 73 | SerialMon.print(F("Connecting to ")); 74 | SerialMon.print(MQTT_BROKER); 75 | SerialMon.print(F("...")); 76 | 77 | // Connect to MQTT Broker 78 | String mqttid = ("MQTTID_" + String(random(65536))); 79 | while (!mqttClient.connect(mqttid.c_str(), MQTT_USERNAME, MQTT_PASSWORD)) { 80 | SerialMon.println(F(" fail")); 81 | } 82 | SerialMon.println(F(" success")); 83 | mqttClient.publish(MQTT_TOPIC, "00000"); 84 | mqttClient.subscribe(MQTT_TOPIC); 85 | } 86 | 87 | void nbConnect(void) 88 | { 89 | SerialMon.println(F("Initializing modem...")); 90 | while (!modem.init() || !modem.nbiotConnect(APN, BAND)) { 91 | SerialMon.print(F(".")); 92 | }; 93 | 94 | SerialMon.print(F("Waiting for network...")); 95 | while (!modem.waitForNetwork()) { 96 | SerialMon.print(F(".")); 97 | } 98 | SerialMon.println(F(" success")); 99 | } 100 | -------------------------------------------------------------------------------- /am7020_mqtts/config.h: -------------------------------------------------------------------------------- 1 | #ifndef _CONFIG_H 2 | #define _CONFIG_H 3 | 4 | #define TINY_GSM_MODEM_SIM7020 5 | 6 | /* Define the serial console for debug prints, if needed */ 7 | // #define TINY_GSM_DEBUG SerialMon 8 | /* uncomment to dump all AT commands */ 9 | // #define DEBUG_DUMP_AT_COMMAND 10 | 11 | #define UPLOAD_INTERVAL 60000 12 | 13 | #define SerialMon Serial 14 | #define MONITOR_BAUDRATE 115200 15 | 16 | 17 | /* AM7020 module setup: Serial port, baudrate, and reset pin */ 18 | #if (defined ARDUINO_AVR_UNO) || (defined ARDUINO_AVR_NANO) 19 | /* Arduino Uno */ 20 | #include 21 | SoftwareSerial SoftSerial(8, 9); //RX:8 TX:9 22 | #define SerialAT SoftSerial 23 | #define AM7020_BAUDRATE 38400 24 | #define AM7020_RESET 7 25 | 26 | #elif defined ARDUINO_AVR_MEGA2560 27 | /* Arduino Mega2560 */ 28 | #define SerialAT Serial1 29 | #define AM7020_BAUDRATE 115200 30 | #define AM7020_RESET 7 31 | 32 | #elif (defined ARDUINO_SAMD_MKRZERO)|| (defined ARDUINO_SAMD_MKRWIFI1010) 33 | /* Arduino MKR Series */ 34 | #define SerialAT Serial1 35 | #define AM7020_BAUDRATE 115200 36 | #define AM7020_RESET A5 37 | 38 | #elif defined ARDUINO_ESP32_DEV 39 | /* ESP32 Boards */ 40 | #define SerialAT Serial2 41 | #define AM7020_BAUDRATE 115200 42 | #define AM7020_RESET 5 43 | 44 | #else 45 | /* add your own boards and uncomment it */ 46 | /* 47 | #define SerialAT Serial1 48 | #define AM7020_BAUDRATE 9600 49 | #define AM7020_RESET 7 50 | */ 51 | 52 | #endif 53 | 54 | /* set GSM PIN */ 55 | #define GSM_PIN "" 56 | 57 | // for taiwan mobile 58 | #define APN "twm.nbiot" 59 | #define BAND 28 60 | 61 | // for CHT 62 | //#define APN "internet.iot" 63 | //#define BAND 8 64 | 65 | // MQTT Setting 66 | #define MQTT_BROKER "test.mosquitto.org" 67 | #define MQTT_PORT 8883 68 | #define MQTT_USERNAME "" 69 | #define MQTT_PASSWORD "" 70 | #define MQTT_TOPIC "temp/humidity" 71 | 72 | #endif /* _CONFIG_H */ 73 | -------------------------------------------------------------------------------- /images/am7020_front.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FelixLinSY/am7020_arduino/194ac91b19408aa8b7355122b1f5b7e2135b5799/images/am7020_front.jpg -------------------------------------------------------------------------------- /images/am7020_hw.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FelixLinSY/am7020_arduino/194ac91b19408aa8b7355122b1f5b7e2135b5799/images/am7020_hw.jpg -------------------------------------------------------------------------------- /images/am7020_pinout.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FelixLinSY/am7020_arduino/194ac91b19408aa8b7355122b1f5b7e2135b5799/images/am7020_pinout.jpg -------------------------------------------------------------------------------- /images/am7020_rear.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FelixLinSY/am7020_arduino/194ac91b19408aa8b7355122b1f5b7e2135b5799/images/am7020_rear.jpg --------------------------------------------------------------------------------