亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

Arduino Mega 2560 短信查询温度:SIM800L + DHT22 远程监测

元器件清单

元器件数量备注
Arduino Mega 25601多串口优势明显
DHT22 温湿度传感器1数字输出,单总线
SIM800L GSM/GPRS 模块1短信收发,需 3.7-4.2V 供电
10kΩ 电阻1DHT22 数据线上拉
面包板1
跳线若干

项目背景

这是一个大型项目的子模块:发送短信 "InTemp" 给 Arduino,自动回复当前温度。作者在整合 DHT 库与 GPRS 库时遇到困难:库示例只能发送固定字符串,无法发送变量 (float 温度值)。经过数周搜索无果,最终找到解决方案:float → String → char 数组,现分享给社区。

软件库修改

使用 Seeeduino_GPRS 库,需修改 sim800.h 适配 Mega 硬件串口:

// 原库使用 SoftwareSerial (引脚 7/8)
#define SIM800_TX_PIN 8
#define SIM800_RX_PIN 7

// 修改为 Mega 硬件串口 Serial3 (引脚 14/15)
// 但作者因修改库困难,保留 SoftwareSerial 接在 10/11
#define SIM800_TX_PIN 10
#define SIM800_RX_PIN 11

建议:Mega 有 4 个硬件串口 (Serial1-Serial3),直接用 Serial3 更稳定,需修改库源码将 SoftwareSerial 替换为 HardwareSerial。

核心难点解决:float 发送短信

// 关键代码片段
float t = dht.readTemperature();  // 读取温度 (float)
String MyString = String(t, 0);   // float → String,保留 0 位小数
MyString = (MyString + " Degrees C"); // 拼接单位

// String → char 数组 (sendSMS 需 char*)
int str_len = MyString.length() + 1;
char char_array[str_len];
MyString.toCharArray(char_array, str_len);

// 发送短信
gprs.sendSMS("04xxxxxxxx", char_array); // 替换为真实手机号

硬件接线

模块引脚Arduino Mega 引脚
DHT22DATAD2
DHT22VCC5V
DHT22GNDGND
DHT22-10kΩ 上拉到 VCC
SIM800LTXDD10 (SoftwareSerial RX)
SIM800LRXDD11 (SoftwareSerial TX)
SIM800LVCC18650 电池 (3.7V) / 稳压模块
SIM800LGNDGND (共地!)

供电关键:SIM800L 发射峰值电流达 2A,必须用独立电源 (如 18650 锂电池 + 降压模块),不可直接用 Arduino 5V 供电。后续建议加装 DC-DC 稳压模块 (如 LM2596) 设为 4.0V。

Arduino Mega 2560 短信查询温度:SIM800L + DHT22 远程监测
面包板接线实物图

完整代码 (DHT_SIMPosting.ino)

// DHT 测试 + SIM800L 短信回复温度
// Written by ladyada, public domain (DHT 部分)

#include "DHT.h"
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

#include 
#include 
#define TIMEOUT 5000

GPRS gprs;
bool ITemp = false;
float temp;
String MyString;
#define LED_PIN 13
bool ledStatus = false;

char currentLine[500] = "";
int currentLineIndex = 0;
bool nextLineIsMessage = false;

void Reply() {
  Serial.println("GPRS - Send SMS Test ...");
  gprs.preInit();
  delay(1000);
  while (0 != gprs.init()) {
    delay(1000);
    Serial.print("init error\r\n");
  }
  Serial.println("Init success, start to send SMS message...");
  
  if (ITemp == true) {
    float t = dht.readTemperature();
    temp = t;
    ITemp = false;
  }
  
  MyString = String(temp, 0);
  MyString = (MyString + " Degrees C");
  
  int str_len = MyString.length() + 1;
  char char_array[str_len];
  MyString.toCharArray(char_array, str_len);
  
  gprs.sendSMS("04xxxxxxxx", char_array); // 修改为目标手机号
}

void setup() {
  Serial.begin(9600);
  Serial.println("DHTxx test!");
  dht.begin();
  
  gprs.preInit();
  delay(1000);
  while (0 != gprs.init()) {
    delay(1000);
    Serial.print("init error\r\n");
  }
  
  // 设置短信文本模式
  if (0 != gprs.sendCmdAndWaitForResp("AT+CMGF=1\r\n", "OK", TIMEOUT)) {
    Serial.println("ERROR: CMGF");
    return;
  }
  
  // 开启新短信指示 (+CMT:)
  if (0 != gprs.sendCmdAndWaitForResp("AT+CNMI=1,2,0,0,0\r\n", "OK", TIMEOUT)) {
    Serial.println("ERROR: CNMI");
    return;
  }
  
  Serial.println("Init success");
}

void loop() {
  delay(2000);
  
  // 定期读取温湿度 (串口监视器观察)
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  Serial.print("Humidity: "); Serial.print(h); Serial.println(" %");
  Serial.print("Temperature: "); Serial.print(t); Serial.println(" *C");
  
  SIM(); // 处理短信
}

void SIM() {
  digitalWrite(LED_PIN, ledStatus);
  Serial.println("Looking for SMS");
  
  if (gprs.serialSIM800.available()) {
    char lastCharRead = gprs.serialSIM800.read();
    
    // 按行读取 (\r 或 \n 结束)
    if (lastCharRead == '\r' || lastCharRead == '\n') {
      String lastLine = String(currentLine);
      
      // 检测到 +CMT: 新短信指示
      if (lastLine.startsWith("+CMT:")) {
        Serial.println(lastLine);
        nextLineIsMessage = true;
      } 
      // 读取短信内容行
      else if (lastLine.length() > 0) {
        if (nextLineIsMessage) {
          Serial.println(lastLine);
          
          // 解析指令
          if (lastLine.indexOf("InTemp") >= 0) {
            Serial.println("InTemp command received");
            ITemp = true;
            Reply();
          }
          // 可扩展其他指令
          // else if (lastLine.indexOf("LED ON") >= 0) { ... }
          
          nextLineIsMessage = false;
        }
      }
      
      // 清空行缓冲
      for (int i = 0; i < sizeof(currentLine); ++i) currentLine[i] = 0;
      currentLineIndex = 0;
    } else {
      currentLine[currentLineIndex++] = lastCharRead;
    }
  }
}

关键技术点总结

  1. float 发送短信:String(val, precision) → toCharArray() 是通用模式
  2. 短信解析:AT+CNMI=1,2,0,0,0 使模块主动上报 +CMT: 后跟内容行,按行状态机解析
  3. Mega 多串口优势:建议用 Serial1/2/3 直连 SIM800L,避免 SoftwareSerial 可靠性问题
  4. 供电设计:SIM800L 必须独立大电流电源,共地

参考资料

原理图

Arduino Mega 2560 短信查询温度:SIM800L + DHT22 远程监测
系统原理图

制造工艺

  1. 温控风扇DIY:媒体柜散热的继电器驱动方案
  2. 树莓派+$5 I²C传感器打造温度记录仪
  3. 树莓派2上使用DS18B20读取温度完整指南
  4. 树莓派专业温度监测:基于 DS18B20 传感器的完整指南
  5. 树莓派结合 Maxim 1-Wire 传感器与 DS2482 I2C 桥接器的多点温度测量
  6. 树莓派精准监测机柜温度:DS18B20 多点部署实战
  7. IoT 入门教程:树莓派流式传输温度数据
  8. 树莓派构建网络化实验室气象站:温湿度气压实时监测
  9. 树莓派 + MCP9808 + InfluxDB + Grafana:家庭温度监测系统
  10. 树莓派 2 运行 Windows IoT Core 打造 Rover 机器人:从入门到进阶指南
  11. AuGe12 金锗软钎焊合金——高强度耐腐蚀密封材料
  12. 铼:超高密度金属丝与耐火应用的理想材料