pwrkey直接接地 sim7020_玩转 ESP32 + Arduino (十九) SIM800L调试(基于TTGO T-CALL)

本文介绍了如何使用ESP32与SIM800L模块进行串口通信,通过LiLyGO T-CALL开发板进行硬件连接,并使用TinyGSM库进行GPRS网络连接。实验包括串口调试助手的使用、2G网络连接以及通过TinyGSM库操作SIM800L进行网络初始化和信号灯控制。还展示了如何将数据上传至OneNet平台,实现温湿度监测功能。
摘要由CSDN通过智能技术生成

关于SIM800L

关于我使用的开发板LiLyGO T-CALL

这里我使用了一块开发板: LiLyGO T-CALL (SIM800L_AXP192_VERSION_20200327版本)

其github地址:https://github.com/Xinyuan-LilyGO/LilyGo-T-Call-SIM800

一. 初识LiLyGO T-CALL

259cd473ba5e

根据原理图, 我们可以得到以下结论

1.SIM800L电源使能引脚接在ESP32的GPIO23引脚

259cd473ba5e

2.SIM800L开关机引脚接在ESP32的GPIO4引脚

3.SIM800L复位引脚接在ESP32的GPIO5引脚

259cd473ba5e

4. SIM800L的串口接在了ESP32的26, 27引脚

259cd473ba5e

二. 实验1: PC端通过串口调试助手调试SIM800L

259cd473ba5e

思路: 串口0收到PC的信息就转发给串口1, 串口0 收到串口1的信息就转发给PC

#include

#define MODEM_RST 5 //SIM800L复位引脚接在GPIO5

#define MODEM_PWRKEY 4 //SIM800L开关机引脚接在GPIO4

#define MODEM_POWER_ON 23 //SIM800L电源引脚接在GPIO23

#define MODEM_TX 27 //SIM800L串口TX引脚接在GPIO27

#define MODEM_RX 26 //SIM800L串口RX引脚接在GPIO26

#define SerialMon Serial //调试串口为UART0

#define SerialAT Serial1 //AT串口为UART1

void setup()

{

pinMode(MODEM_POWER_ON, OUTPUT); //电源引脚

pinMode(MODEM_PWRKEY, OUTPUT); //开关机键引脚

// 先打开SIM800L的电源

digitalWrite(MODEM_POWER_ON, HIGH);

//根据手册要求拉下PWRKEY 1秒钟以上 可以开机

digitalWrite(MODEM_PWRKEY, HIGH);

delay(100);

digitalWrite(MODEM_PWRKEY, LOW);

delay(1000);

digitalWrite(MODEM_PWRKEY, HIGH);

//开启串口

SerialMon.begin(115200);

SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);

}

void loop()

{

while (SerialAT.available())

{

SerialMon.write(SerialAT.read());

}

while (SerialMon.available())

{

SerialAT.write(SerialMon.read());

}

}

三. 更进一步 用tinyGSM库操作SIM800L

这里我们使用了库 tinyGSM

tinyGSM和我们之前的wifi库差不多

不过多了一个modem(猫)的概念, 就是我们要把SIM800L实例化为一个modem, 像这样:TinyGsm modem(SerialAT);

下面这个程序主要就是我们创建一个modem并操作他的过程, 顺便测试了一下2G网络连接需要多久(实测10秒左右)

关于client的内容并没有在这个例程里, 下节再探讨.

#include

#define MODEM_RST 5 //SIM800L复位引脚接在GPIO5

#define MODEM_PWRKEY 4 //SIM800L开关机引脚接在GPIO4

#define MODEM_POWER_ON 23 //SIM800L电源引脚接在GPIO23

#define MODEM_TX 27 //SIM800L串口TX引脚接在GPIO27

#define MODEM_RX 26 //SIM800L串口RX引脚接在GPIO26

#define SerialMon Serial //调试串口为UART0

#define SerialAT Serial1 //AT串口为UART1

#define TINY_GSM_MODEM_SIM800 // Modem is SIM800

//引入TinyGSM库. 在引入之前要定义好TINY_GSM_MODEM_SIM800,让它知道我们用的模块型号

#include

// 创建一个关联到SerialAT的SIM800L模型

TinyGsm modem(SerialAT);

//初始化SIM800L

void setupModem()

{

pinMode(MODEM_POWER_ON, OUTPUT); //电源引脚

pinMode(MODEM_PWRKEY, OUTPUT); //开关机键引脚

// 先打开SIM800L的电源

digitalWrite(MODEM_POWER_ON, HIGH);

//根据手册要求拉下PWRKEY 1秒钟以上 可以开机

digitalWrite(MODEM_PWRKEY, HIGH);

delay(100);

digitalWrite(MODEM_PWRKEY, LOW);

delay(1000);

digitalWrite(MODEM_PWRKEY, HIGH);

}

void setup()

{

esp_sleep_enable_timer_wakeup(20000000); //创建一个esp睡眠闹钟

SerialMon.begin(115200);//初始化调试串口

SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);//初始化AT串口

setupModem(); //SIM800L物理开机

SerialMon.println("Initializing modem...");

modem.init(); //开机后modem初始化一下

String modemInfo = modem.getModemInfo();

SerialMon.print("Modem: ");

SerialMon.println(modemInfo);

//测试连接网络

SerialMon.print("Waiting for network...");

while (!modem.waitForNetwork(240000L))

{

SerialMon.print(".");

delay(500);

}

SerialMon.println(" OK");

//测试关闭SIM800L信号灯

SerialMon.println("Turning off SIM800 Red LED...");

modem.sendAT("+CNETLIGHT=0");

delay(10000);

//测试打开SIM800L信号灯

SerialMon.println("Turning on SIM800 Red LED...");

modem.sendAT("+CNETLIGHT=1");

delay(10000);

//去休眠吧

SerialMon.println("now I wanna ESP32sleep and disable SIM800L for a while!(20sec)");

delay(100);

esp_deep_sleep_start();

}

void loop()

{

}

四. 使用SIM800L连接2G网络并将数据上传至OneNet平台

本例程实现了以下功能:

通过SIM800L连接网络

连接OneNet平台(通过旧版MQTT协议)

调用SHT20的库采集温湿度

将温湿度信息上传至OneNet

每5分钟采集一次, 采集完成就休眠

#include

#include "PubSubClient.h"

#include "aliyun_mqtt.h"

#include "ArduinoJson.h"

#include "Ticker.h"

#include "uFire_SHT20.h"

/*-------------------------------SIM800L 硬件定义----------------------------------*/

#define MODEM_RST 5 //SIM800L复位引脚接在GPIO5

#define MODEM_PWRKEY 4 //SIM800L开关机引脚接在GPIO4

#define MODEM_POWER_ON 23 //SIM800L电源引脚接在GPIO23

#define MODEM_TX 27 //SIM800L串口TX引脚接在GPIO27

#define MODEM_RX 26 //SIM800L串口RX引脚接在GPIO26

//串口定义

#define SerialMon Serial //调试串口为UART0

#define SerialAT Serial1 //AT串口为UART1

/*-------------------------------其他硬件定义-------------------------------------*/

#define LED_G 13

uFire_SHT20 sht20;

/*-------------------------------Modem相关定义-------------------------------------*/

#define TINY_GSM_MODEM_SIM800 // Modem is SIM800

//引入TinyGSM库. 在引入之前要定义好TINY_GSM_MODEM_SIM800,让它知道我们用的模块型号

#include

// 创建一个关联到SerialAT的SIM800L模型

TinyGsm modem(SerialAT);

// 创建一个GSM型的网络客户端

TinyGsmClient gsmclient(modem);

PubSubClient client(gsmclient);

// Your GPRS credentials (leave empty, if missing)

const char apn[] = "CMNET"; // Your APN

const char gprsUser[] = ""; // User

const char gprsPass[] = ""; // Password

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

/*-------------------------------云平台相关定义-------------------------------------*/

const char *mqtt_server = "183.230.40.39"; //onenet 的 IP地址

#define mqtt_devid "626108102" //设备ID

#define mqtt_pubid "370025" //产品ID

#define mqtt_password "test123" //鉴权信息

char msg_buf[200]; //发送信息缓冲区

char dataTemplate[] = "{\"TEMP\":%.2f,\"HUMI\":%.2f}"; //信息模板

char msgJson[75]; //要发送的json格式的数据

unsigned short json_len = 0; //json长度

/*-------------------------------初始化SIM800L-------------------------------------*/

void setupModem()

{

pinMode(MODEM_POWER_ON, OUTPUT); //电源引脚

pinMode(MODEM_PWRKEY, OUTPUT); //开关机键引脚

// 先打开SIM800L的电源

digitalWrite(MODEM_POWER_ON, HIGH);

//根据手册要求拉下PWRKEY 1秒钟以上 可以开机

digitalWrite(MODEM_PWRKEY, HIGH);

delay(100);

digitalWrite(MODEM_PWRKEY, LOW);

delay(1000);

digitalWrite(MODEM_PWRKEY, HIGH);

SerialMon.println("Initializing modem...");

modem.init(); //开机后modem初始化一下

}

/*-------------------------------SIM800L连接GPRS-------------------------------------*/

void modemToGPRS()

{

//连接网络

SerialMon.print("Waiting for network...");

while (!modem.waitForNetwork(240000L))

{

SerialMon.print(".");

delay(500);

}

SerialMon.println(" OK");

//连接GPRS接入点

SerialMon.print(F("Connecting to APN: "));

SerialMon.print(apn);

while (!modem.gprsConnect(apn, gprsUser, gprsPass))

{

SerialMon.print(".");

delay(10000);

}

SerialMon.println(" OK");

}

/*-------------------------------向云平台发送温湿度数据-------------------------------*/

void sendTempAndHumi()

{

if (client.connected())

{

snprintf(msgJson, 40, dataTemplate, sht20.temperature(), sht20.humidity()); //将模拟温湿度数据套入dataTemplate模板中, 生成的字符串传给msgJson

json_len = strlen(msgJson); //msgJson的长度

msg_buf[0] = char(0x03); //要发送的数据必须按照ONENET的要求发送, 根据要求,数据第一位是3

msg_buf[1] = char(json_len >> 8); //数据第二位是要发送的数据长度的高八位

msg_buf[2] = char(json_len & 0xff); //数据第三位是要发送数据的长度的低八位

memcpy(msg_buf + 3, msgJson, strlen(msgJson)); //从msg_buf的第四位开始,放入要传的数据msgJson

msg_buf[3 + strlen(msgJson)] = 0; //添加一个0作为最后一位, 这样要发送的msg_buf准备好了

Serial.print("public message:");

Serial.println(msgJson);

client.publish("$dp", (uint8_t *)msg_buf, 3 + strlen(msgJson)); //发送数据到主题$dp

}

}

/*-------------------------------向云平台断线重连-------------------------------------*/

void clientReconnect()

{

if (modem.isNetworkConnected())

{

while (!client.connected()) //再重连客户端

{

Serial.println("reconnect MQTT...");

if (client.connect(mqtt_devid, mqtt_pubid, mqtt_password))

{

Serial.println("connected");

}

else

{

Serial.println("failed");

Serial.println(client.state());

Serial.println("try again in 5 sec");

delay(5000);

}

}

}

else

{

Serial.println("网络断了,不可能连上了, 把数据存在本地等待下一次联网吧");

}

}

void setup()

{

pinMode(LED_G, OUTPUT);

Wire.begin();

sht20.begin();

SerialMon.begin(115200); //初始化调试串口

SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX); //初始化AT串口

setupModem(); //SIM800L物理开机

modemToGPRS(); //modem连接GPRS

//连接OneNet并上传数据

Serial.println("connecting to ALI IOT...");

client.setServer(mqtt_server, 6002); //设置客户端连接的服务器,连接Onenet服务器, 使用6002端口

client.connect(mqtt_devid, mqtt_pubid, mqtt_password); //客户端连接到指定的产品的指定设备.同时输入鉴权信息

if (client.connected())

sendTempAndHumi();

else //如果客户端没连接ONENET, 重新连接

clientReconnect();

delay(500);

//进入睡眠

esp_sleep_enable_timer_wakeup(300000000);

Serial.println("now sleep");

esp_deep_sleep_start();

}

void loop()

{

client.loop();

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值