1. 项目概述:用树莓派搭建一个低成本短信服务器
如果你手头有一台闲置的树莓派,又恰好有一些需要自动发送短信提醒的场景,比如服务器宕机报警、家庭安防通知,或者只是想折腾点有趣的物联网项目,那么这个用树莓派配合GPRS模块搭建的短信服务器,绝对值得一试。它本质上是一个能通过网页或命令行,向任意手机号码发送短信的微型系统。整个方案的核心成本极低,硬件部分主要就是一块几十块钱的GPRS模块和一个USB转串口工具,软件则完全基于开源生态。我最初做这个是为了给家里的智能家居系统增加一个不依赖网络的离线报警通道,实测下来非常稳定,已经连续运行了两年多。下面,我就把从硬件选型、组装、软件配置到最终部署的完整过程,以及我踩过的那些坑,毫无保留地分享出来。
2. 硬件选型与组装详解
2.1 核心硬件清单与选型逻辑
这个项目的硬件清单非常精简,但每一件都有其不可替代的作用。选择它们不仅仅是图便宜,更是基于稳定性和易用性的综合考虑。
- GPRS/GSM模块(约¥30-50):这是项目的“嘴巴”,负责与蜂窝网络通信。原文提到的“GPRS Shield 900/1800MHz”是一种典型的2G模块。选择它是因为2G网络覆盖广、模块价格低廉、功耗相对可控,且AT指令集成熟稳定。在国内,你需要确保模块支持中国移动/联通的900MHz和1800MHz频段。现在市面上更常见的是SIM800系列模块(如SIM800C),它们功能类似且文档丰富,是更好的选择。
- USB转TTL串口模块(约¥5-15):这是连接树莓派和GPRS模块的“翻译官”。为什么必须用它?因为树莓派自带的硬件串口(UART,位于GPIO的14/15引脚)默认被系统蓝牙占用,且电平是3.3V。而多数GPRS模块需要5V供电,且其串口通信电平可能不兼容。一个独立的USB转串口模块(如CH340、CP2102芯片的)可以完美解决供电和电平转换问题,并提供稳定的
/dev/ttyUSB0设备节点,让软件配置变得简单统一。 - 树莓派(任意型号):作为系统的“大脑”。Model B2(512MB RAM)或更新型号(如3B、4B)当然更好,但即使是Zero W也完全够用。系统资源消耗很小,主要运行一个轻量的Web服务器和后台命令。
- 预付费SIM卡:一张能正常发送短信的手机卡。注意,有些物联网卡或特定套餐可能关闭了短信发送功能,务必先用手机测试一下。同时,确保卡已插入模块并识别(通常会有网络状态指示灯)。
注意:供电是关键!GPRS模块在发送短信瞬间的峰值电流可能达到2A,仅靠USB转串口模块的5V引脚供电可能不足,会导致模块重启或发送失败。强烈建议为GPRS模块单独供电。最稳妥的方法是:使用一个5V/2A以上的电源适配器,其正极(VCC)同时连接到USB转串口模块的VCC引脚和GPRS模块的VCC引脚,所有设备的GND(地线)连接在一起。这样可以避免因电流不足导致的不稳定。
2.2 硬件连接与焊接要点
连接原理很简单:让树莓派通过USB转串口模块,与GPRS模块进行串口对话。具体引脚对应关系如下:
- USB转串口模块的TX->GPRS模块的RX(数据从树莓派发送到模块)
- USB转串口模块的RX->GPRS模块的TX(数据从模块发送到树莓派)
- USB转串口模块的VCC (5V)->GPRS模块的VCC(供电,如前所述,建议外接电源)
- USB转串口模块的GND->GPRS模块的GND(共地,必须连接!)
实际操作中,我强烈建议你使用杜邦线进行连接,并在连接前用万用表确认USB转串口模块的VCC引脚输出确实是5V。有些劣质模块输出可能不稳。焊接时,如果模块有排针,可以先焊接好排针再插杜邦线;如果直接焊接线材,注意做好绝缘,防止短路。
一个我踩过的坑:早期我曾尝试跳过USB转串口,直接将树莓派3.3V的GPIO串口连接到模块,结果通信极其不稳定,时好时坏。原因是电平不匹配和驱动能力不足。所以,不要省掉USB转串口模块,它能省去你无数调试时间。
3. 软件环境配置与Gammu调试
硬件连接好后,我们进入软件层面。核心软件是Gammu,它是一个功能强大的手机通讯工具箱,支持数百款手机和模块,我们用它来驱动GPRS模块。
3.1 系统准备与Gammu安装
首先,确保你的树莓派系统(如Raspbian)是最新的。通过SSH或直接连接显示器键盘操作。
# 更新软件源列表和升级现有软件包 sudo apt update sudo apt upgrade -y # 安装Gammu及其图形前端Wammu(用于初始调试很方便) sudo apt install gammu wammu -ywammu是一个图形界面,在桌面环境下可以直观地查看信号、读取短信等,但对于无头服务器(无显示器)模式,我们主要使用命令行工具gammu。
3.2 配置Gammu识别硬件
这是最关键的一步,告诉Gammu你的GPRS模块连接在哪里。
查找设备:将USB转串口模块插入树莓派USB口,然后执行:
ls /dev/ttyUSB*通常你会看到
/dev/ttyUSB0。如果连接了多个USB串口设备,可能会有ttyUSB1等。记下你的设备号。创建配置文件:Gammu的配置文件是
~/.gammurc(用户目录)或/etc/gammurc(全局)。我们先在用户目录创建:nano ~/.gammurc输入以下内容:
[gammu] # 端口改为你实际的设备,比如 /dev/ttyUSB0 port = /dev/ttyUSB0 # 连接速度,SIM800系列通常是115200 connection = at115200 # 名称,可自定义 name = my_gprs_module # 型号可以留空,Gammu会自动检测 model =按
Ctrl+O保存,Ctrl+X退出nano编辑器。测试连接:运行以下命令,如果配置正确,你会看到模块的详细信息。
gammu --identify成功的输出类似这样:
Device : /dev/ttyUSB0 Manufacturer : SIMCOM INCORPORATED Model : SIMCOM_SIM800C (c) Firmware : Revision:1418B02SIM800C32 IMEI : 862991234567890 SIM IMSI : 460001234567890这表示Gammu已经成功与你的GPRS模块“握手”,并读取到了IMEI和SIM卡信息。如果这一步失败,请按以下顺序排查:
- 权限问题:当前用户可能没有读写
/dev/ttyUSB0的权限。可以尝试sudo gammu --identify,或者将用户加入dialout组:sudo usermod -a -G dialout $USER,然后注销重新登录。 - 端口错误:确认
ls /dev/ttyUSB*的输出,修改配置文件中的port。 - 波特率错误:尝试其他常见波特率,如
at9600、at19200等。 - 硬件连接问题:检查TX/RX是否接反(这是最常见错误),检查供电是否充足,SIM卡是否插好,模块天线是否连接。
- 权限问题:当前用户可能没有读写
4. 构建网页版短信发送接口
让短信服务器通过网页操作,是最方便的使用方式。我们将创建一个简单的PHP页面。
4.1 安装Web服务器与PHP
树莓派上最轻量的是lighttpd,但Apache更常见。这里以Apache为例:
sudo apt install apache2 php php-cli -y安装完成后,在浏览器访问树莓派的IP地址(如http://192.168.1.100),应该能看到Apache的默认页面。
4.2 解决权限问题:让Web服务器能执行Gammu
这是安全且关键的一步。Apache以www-data用户身份运行,它默认无权直接访问硬件设备(/dev/ttyUSB0)或执行gammu命令。我们通过sudo授权,但要用安全的方式——无需密码地运行特定命令。
使用visudo命令安全地编辑sudo配置:
sudo visudo在文件末尾添加下面这行:
www-data ALL=(ALL) NOPASSWD: /usr/bin/gammu这行配置的意思是:用户www-data可以在任何主机上,以任何用户身份,无需密码地执行/usr/bin/gammu这个命令。 按Ctrl+O保存,Ctrl+X退出。
4.3 创建PHP短信发送脚本
现在,在Apache的网页目录(通常是/var/www/html/)下创建我们的短信发送页面,例如sms.php:
sudo nano /var/www/html/sms.php将以下PHP代码粘贴进去。这段代码不仅实现了基本功能,还增加了安全检查、错误处理和更友好的反馈:
<!DOCTYPE html> <html> <head> <title>树莓派短信服务器</title> <meta charset="utf-8"> <style> body { font-family: sans-serif; margin: 30px; background: #f5f5f5; } .container { background: white; padding: 25px; border-radius: 10px; max-width: 600px; margin: auto; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } h2 { color: #333; border-bottom: 2px solid #4CAF50; padding-bottom: 10px; } label { display: block; margin-top: 15px; font-weight: bold; color: #555; } textarea, input[type="text"] { width: 100%; padding: 10px; margin-top: 5px; border: 1px solid #ccc; border-radius: 5px; box-sizing: border-box; font-size: 14px; } button { background-color: #4CAF50; color: white; padding: 12px 25px; border: none; border-radius: 5px; cursor: pointer; font-size: 16px; margin-top: 20px; } button:hover { background-color: #45a049; } .result { margin-top: 25px; padding: 15px; background-color: #e8f5e9; border-left: 4px solid #4CAF50; white-space: pre-wrap; font-family: monospace; font-size: 13px; } .error { background-color: #ffebee; border-left-color: #f44336; } </style> </head> <body> <div class="container"> <h2>📱 树莓派短信发送平台</h2> <form method="post" action=""> <label for="numbers">收信号码(多个用英文逗号隔开):</label> <input type="text" id="numbers" name="numbers" placeholder="例如:13800138000,13912345678" required> <label for="message">短信内容(最多200字符):</label> <textarea id="message" name="message" rows="4" placeholder="请输入要发送的短信内容..." maxlength="200" required></textarea> <div>字符数: <span id="charCount">0</span>/200</div> <button type="submit" name="send">发送短信</button> </form> <?php if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['send'])) { $numbers = trim($_POST['numbers']); $message = trim($_POST['message']); // 基础验证 if (empty($numbers) || empty($message)) { echo '<div class="result error">错误:号码和内容不能为空。</div>'; exit; } if (strlen($message) > 200) { echo '<div class="result error">错误:内容超过200字符限制。</div>'; exit; } // 清理号码字符串,分割成数组 $numberArray = array_map('trim', explode(',', $numbers)); $validNumbers = []; foreach ($numberArray as $num) { // 简单的手机号格式验证(11位数字,以1开头) if (preg_match('/^1[3-9]\d{9}$/', $num)) { $validNumbers[] = $num; } else { echo "<div class='result error'>警告:号码 '$num' 格式不正确,已跳过。</div>"; } } if (empty($validNumbers)) { echo '<div class="result error">错误:没有有效的手机号码。</div>'; exit; } echo "<div class='result'><strong>发送报告:</strong>\n"; echo "========================\n"; // 对消息进行安全转义,防止shell注入 $escapedMessage = escapeshellarg($message); $successCount = 0; $failCount = 0; foreach ($validNumbers as $index => $phone) { // 构建Gammu命令。使用sudo并以www-data用户执行。 // -c 指定配置文件,避免依赖全局配置。 $command = "sudo -u www-data /usr/bin/gammu -c /etc/gammurc --sendsms TEXT " . escapeshellarg($phone) . " -text " . $escapedMessage . " 2>&1"; $output = []; $returnCode = 0; exec($command, $output, $returnCode); echo "\n--- 尝试发送给 $phone ---\n"; echo implode("\n", $output); if (strpos(implode(' ', $output), 'OK') !== false && $returnCode === 0) { echo " ✅ 发送成功\n"; $successCount++; } else { echo " ❌ 发送失败\n"; $failCount++; } // 在每条短信之间添加延迟,避免模块或网络处理不过来 // 根据你的网络状况调整,6秒是个保守值 if ($index < count($validNumbers) - 1) { sleep(6); } } echo "\n========================\n"; echo "总结:成功 $successCount 条,失败 $failCount 条。</div>"; } ?> </div> <script> // 实时显示文本域字符数 document.getElementById('message').addEventListener('input', function() { document.getElementById('charCount').textContent = this.value.length; }); </script> </body> </html>保存并退出。现在,通过浏览器访问http://你的树莓派IP/sms.php,你应该能看到一个简洁的发送界面。输入号码和内容,点击发送,下方会实时显示Gammu的命令行输出。
关键点解析与避坑:
escapeshellarg()函数:这是安全的重中之重。它将用户输入的手机号和消息内容用单引号包裹,确保即使输入中包含特殊字符(如;、|、&),也不会被shell误解为命令,从而有效防止命令注入攻击。sudo -u www-data:我们虽然配置了www-data可以无密码运行gammu,但在PHP的exec()中,默认用户可能不是www-data。使用sudo -u www-data显式地以www-data用户身份执行命令,确保权限一致。-c /etc/gammurc:指定Gammu配置文件的绝对路径,避免因环境变量问题找不到配置。我们需要把之前创建的配置文件复制到/etc/下:sudo cp ~/.gammurc /etc/gammurc。- 延迟
sleep(6):连续快速发送短信可能导致模块或SIM卡网络响应不过来。添加延迟是保证成功率的重要措施。你可以根据实际网络情况调整这个时间。
5. 进阶功能:实现短信定时发送(任务调度)
网页发送是即时的,但有时我们需要定时发送,比如每天早上的天气提醒、每周的备份报告。我们可以利用Linux自带的at命令来实现任务调度。
5.1 安装并配置at命令
首先安装at守护进程:
sudo apt install at -y确保atd服务已启动:sudo systemctl enable --now atd。
然后,我们需要扩展www-data用户的sudo权限,让它也能无密码使用at命令:
sudo visudo找到之前添加的那行,修改为:
www-data ALL=(ALL) NOPASSWD: /usr/bin/gammu, /usr/bin/at这样,PHP脚本就能通过sudo调用at命令来安排任务了。
5.2 创建定时发送PHP脚本
新建一个文件,例如sms_scheduler.php:
<!DOCTYPE html> <html> <head> <title>短信定时发送</title> <style>/* 样式参考上一个文件,此处省略以节省篇幅 */</style> </head> <body> <div class="container"> <h2>⏰ 短信定时发送调度器</h2> <form method="post" action=""> <label for="numbers">收信号码(仅第一个号码生效):</label> <input type="text" id="numbers" name="numbers" placeholder="13800138000" required> <label for="message">短信内容:</label> <textarea id="message" name="message" rows="4" required></textarea> <label for="schedule_time">发送时间(at命令格式):</label> <input type="text" id="schedule_time" name="schedule_time" placeholder="例如:now+10 minutes, 或 1430 (表示14:30), 或 tomorrow 9:00 AM" required> <small>提示:'now+10 minutes' (10分钟后), '1430' (今天14:30), 'tomorrow 9:00 AM', 'next friday'</small> <button type="submit" name="schedule">安排定时发送</button> </form> <?php if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['schedule'])) { $phone = trim($_POST['numbers']); $message = trim($_POST['message']); $timeExpr = trim($_POST['schedule_time']); // 基础验证 if (!preg_match('/^1[3-9]\d{9}$/', $phone)) { echo '<div class="result error">错误:手机号格式不正确。</div>'; exit; } if (empty($message) || empty($timeExpr)) { echo '<div class="result error">错误:内容和时间不能为空。</div>'; exit; } // 构建echo命令,将短信内容通过管道传递给gammu,再通过管道给at // 注意:at命令从标准输入读取要执行的命令 $escapedMessage = escapeshellarg($message); // 这里使用第一个号码,因为at调度单条命令时,多号码处理复杂 $gammuCommand = "/usr/bin/gammu -c /etc/gammurc --sendsms TEXT " . escapeshellarg($phone) . " -text " . $escapedMessage; // 完整的shell命令:将gammu命令echo出来,通过管道交给at在指定时间执行 $fullCommand = "echo " . escapeshellarg($gammuCommand) . " | sudo -u www-data /usr/bin/at " . escapeshellarg($timeExpr) . " 2>&1"; $output = []; exec($fullCommand, $output, $returnCode); echo "<div class='result'>"; echo "<strong>调度结果:</strong>\n"; echo "========================\n"; echo "目标号码: $phone\n"; echo "发送时间表达式: $timeExpr\n"; echo "--- 命令输出 ---\n"; echo implode("\n", $output); if ($returnCode === 0) { // 从at的输出中提取job id,例如“job 12 at Mon May 16 14:30:00 2023” preg_match('/job\s+(\d+)\s+at/', implode(' ', $output), $matches); $jobId = $matches[1] ?? '未知'; echo "\n✅ 定时任务安排成功!任务ID: $jobId\n"; echo "你可以使用 'sudo atq' 查看队列,或 'sudo atrm $jobId' 删除该任务。"; } else { echo "\n❌ 安排定时任务失败。请检查时间格式是否正确。"; } echo "</div>"; } ?> </div> </body> </html>5.3 at命令时间格式详解与实战技巧
at命令的时间格式非常灵活,但也是容易出错的地方。上面表单的提示只是一部分,这里详细列一下:
| 表达式示例 | 含义 |
|---|---|
now + 30 minutes | 30分钟后 |
now + 1 hour | 1小时后 |
now + 2 days | 2天后 |
17:30 | 今天下午5点30分(如果已过,则为明天) |
17:30 tomorrow | 明天下午5点30分 |
noon | 今天中午12点 |
midnight | 今晚午夜12点 |
teatime | 下午4点(英式茶时间) |
next week | 下周的此刻 |
next monday | 下周一上午10点(at的默认时间) |
2024-12-25 | 2024年圣诞节上午10点 |
管理定时任务:
- 查看队列:在树莓派终端执行
sudo atq,会列出所有等待执行的任务。 - 查看任务内容:任务详情保存在
/var/spool/at/目录下,但直接查看不便。更简单的方法是邮件,at命令的输出会邮寄给提交者。可以安装mailutils来查看:sudo apt install mailutils,然后看邮件mail。 - 删除任务:
sudo atrm <任务ID>,任务ID从atq命令中获取。
一个重要的限制与变通方案:如原文所述,通过echo “command” | at TIME这种方式,只能处理一条简单的命令。如果你想像即时发送那样处理多个号码,直接在at里用循环会比较麻烦。一个实用的变通方案是:将发送逻辑写成一个独立的Shell脚本,然后在at命令中调用这个脚本,并传递参数。
例如,创建/usr/local/bin/send_bulk_sms.sh:
#!/bin/bash # 脚本接收两个参数:号码列表(逗号分隔)和消息 NUMBERS=$1 MESSAGE=$2 IFS=',' read -ra ADDR <<< "$NUMBERS" for i in "${ADDR[@]}"; do /usr/bin/gammu -c /etc/gammurc --sendsms TEXT "$i" -text "$MESSAGE" sleep 6 done赋予执行权限:sudo chmod +x /usr/local/bin/send_bulk_sms.sh。 然后在PHP中,安排任务的命令就变成了:
echo "/usr/local/bin/send_bulk_sms.sh '13800138000,13912345678' '你的消息'" | at now+1 hour这样就能实现多号码的定时群发了。
6. 稳定性优化与日常维护
让这个短信服务器7x24小时稳定运行,还需要一些优化和维护工作。
6.1 开机自启动与看门狗
我们希望树莓派开机后,GPRS模块能自动就绪。可以创建一个systemd服务。
创建服务文件:sudo nano /etc/systemd/system/gprs-module-setup.service
[Unit] Description=Prepare GPRS Module on USB Serial After=network.target [Service] Type=oneshot # 有时USB设备加载需要时间,等待2秒 ExecStartPre=/bin/sleep 2 # 关键:设置USB转串口设备的权限,让www-data用户能读写 ExecStart=/bin/chmod 666 /dev/ttyUSB0 RemainAfterExit=yes [Install] WantedBy=multi-user.target启用并启动服务:
sudo systemctl daemon-reload sudo systemctl enable --now gprs-module-setup.service这个服务会在每次启动时,确保/dev/ttyUSB0设备对所有人可读写,解决可能的权限问题。
6.2 网络状态监控与自动重启
GPRS模块可能会因为信号不稳、SIM卡欠费等原因“死掉”。我们可以写一个简单的监控脚本,定期检查模块是否还能响应AT指令。
创建监控脚本/usr/local/bin/check_gprs.sh:
#!/bin/bash # 尝试通过Gammu发送一个空查询命令,超时设为10秒 TIMEOUT=10 if timeout $TIMEOUT gammu -c /etc/gammurc --identify > /dev/null 2>&1; then echo "$(date): GPRS模块状态正常" else echo "$(date): GPRS模块无响应,尝试重启服务..." # 记录日志 echo "$(date): GPRS模块故障" >> /var/log/gprs_monitor.log # 可以在这里加入更激进的操作,比如重启树莓派USB总线或系统 # sudo hub-ctrl -h 0 -P 2 -p 0 # 示例:使用hub-ctrl关闭再打开USB电源(需安装) # sleep 5 # sudo hub-ctrl -h 0 -P 2 -p 1 fi赋予执行权限:sudo chmod +x /usr/local/bin/check_gprs.sh。 然后通过cron定时任务,每5分钟检查一次:sudo crontab -e,添加一行:
*/5 * * * * /usr/local/bin/check_gprs.sh6.3 安全加固建议
这个网页接口暴露在局域网甚至互联网上(如果你做了端口转发),安全必须考虑。
- 基础认证:最简单的,在Apache中为
sms.php和sms_scheduler.php目录添加密码保护。使用htpasswd创建密码文件,并在Apache虚拟主机配置中添加Require valid-user。 - 使用HTTPS:如果从外网访问,务必配置SSL证书(Let‘s Encrypt免费),避免信息明文传输。可以使用
certbot轻松为Apache配置HTTPS。 - 限制访问IP:在Apache配置中,使用
Require ip 192.168.1.0/24来只允许局域网IP访问。 - 输入验证:我们前面的PHP脚本已经做了基础验证,但可以更严格,比如限制每天发送条数、验证手机号归属地等。
- 日志审计:记录所有发送请求的IP、时间、号码和内容摘要(注意隐私)。可以将PHP脚本中的发送记录追加到一个日志文件中。
7. 常见问题排查与解决实录
在实际搭建和使用过程中,你几乎一定会遇到下面这些问题。我把它们和解决方案整理成了表格,方便你快速对照排查。
| 问题现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
gammu --identify无输出或报错 | 1. 设备节点不对 2. 波特率不匹配 3. 权限不足 4. TX/RX接反 | 1.ls /dev/ttyUSB*确认设备名,更新.gammurc。2. 尝试修改 connection = at9600或at19200。3. 执行 sudo gammu --identify或将用户加入dialout组。4.重点检查:交换USB转串口模块上的TX和RX线与GPRS模块的连接。 |
| 发送短信失败,提示“No response in specified timeout” | 1. 模块供电不足 2. SIM卡无信号/欠费 3. 短信中心号码(SCA)未设置 | 1.外接5V/2A电源给模块单独供电,这是最常见原因。 2. 将SIM卡插入手机,确认有信号、能发短信、未欠费。 3. 用 gammu --getsmsc查看短信中心号,若无,用gammu --setsmsc设置(号码咨询运营商)。 |
| 网页点击发送后长时间无反应或报500错误 | 1. PHP执行权限问题 2. sudoers配置错误 3. Gammu配置文件路径错误 | 1. 在PHP脚本开头加error_reporting(E_ALL); ini_set('display_errors', 1);显示具体错误。2. 测试命令: sudo -u www-data /usr/bin/gammu --identify,看能否成功。3. 确认 /etc/gammurc文件存在且内容正确。 |
定时任务 (at命令) 未执行 | 1.atd服务未运行2. 时间格式错误 3. 命令语法在at环境中出错 | 1.sudo systemctl status atd确保服务是active (running)。2. 用 at now+1 minute加一个简单的测试命令(如echo test > /tmp/test.txt)看是否执行。3. 在 at命令中,尽量使用绝对路径,环境变量可能与shell不同。 |
| 模块偶尔能识别,经常掉线 | 1. USB接口或线缆接触不良 2. 电源纹波干扰 3. 模块自身故障或天线问题 | 1. 更换USB口、USB线、杜邦线试试。 2. 为树莓派和GPRS模块使用质量好的电源,避免共用劣质插排。 3. 确保天线已牢固连接,尝试将模块和天线放在信号更好的位置。 |
| 发送中文短信乱码 | 字符编码问题 | Gammu默认可能使用GSM 7-bit编码。尝试在发送命令中指定编码:gammu --sendsms TEXT 号码 -unicode -text “中文内容”。注意,Unicode短信长度限制为70字符。 |
最后,关于硬件本身,如果你发现手头的GPRS模块实在不稳定,可以考虑升级到4G Cat.1或NB-IoT模块。它们的功耗更低、网络更稳定,但价格会稍高,且配置方式(通常通过USB CDC-ACM或网口)有所不同,需要寻找对应的驱动和软件(如wvdial、ppp或模块商提供的SDK)。但对于绝大多数短信报警、通知类应用,一个稳定的2G模块加上本文的配置,已经足够可靠且极具性价比了。我的第一个版本就是用SIM800C做的,至今还在车库的角落里默默工作,提醒我车辆进出,从未掉过链子。