1. 项目概述:短信转发器的核心价值与应用场景
短信转发器这个看似简单的工具,在实际生活中能解决很多痛点场景。我最早做这个项目是因为工作需要同时管理多个业务号码,但又不方便随身携带多部手机。通过4G模组+开源方案的组合,成功实现了多卡短信统一管理,实测半年稳定运行无漏报。
这类设备的核心功能是通过硬件模块接收SIM卡短信,再按设定规则转发到指定终端(手机/服务器/邮箱)。相比商业解决方案,DIY方案的优势在于:①完全掌控数据流向 ②可深度定制转发规则 ③硬件成本可控制在百元内。特别适合需要管理副卡短信、接收验证码、监控设备告警等场景。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 硬件选型与核心组件解析
2.1 4G通信模组选型要点
主流可选型号包括:
- 移远EC20(性价比首选)
- 广和通L610(工业级稳定性)
- 中移物联ML302(内置eSIM)
实测发现EC20在信号强度-110dBm时仍能稳定通信,搭配PCB天线即可满足室内使用。特别注意要选择支持LuatOS固件的版本(如EC20-CN-01),这是后续开发的关键。
2.2 主控板的选择
推荐组合方案:
- 低成本方案:ESP32-C3(带WiFi备用通道)
- 高性能方案:STM32F407(工业级可靠性)
- 极简方案:直接用LuatOS开发板(如Air724)
我在初期测试时发现,当短信并发量较大时(如验证码轰炸场景),ESP32的队列处理能力明显优于STM32,建议选择ESP32-C3(约25元)作为入门选择。
3. 软件架构设计与关键实现
3.1 LuatOS开发环境搭建
- 下载Luatools集成开发环境(V2.1.56+)
- 安装USB驱动(特别注意CH340G版本匹配)
- 创建新项目时选择:
lua复制project_type = "EC20" syslib = {uart=1,log=1,sms=1,net=1}
重要提示:首次烧录前务必执行
sys.restore()恢复出厂设置,避免残留配置冲突
3.2 短信接收核心代码
lua复制-- 短信接收回调函数
sys.subscribe("SMS_RECEIVE", function(phone, date, msg)
local prefix = string.match(msg, "%[(%w+)%]") -- 提取消息前缀
if prefix == "ALERT" then -- 紧急告警即时转发
publish_mqtt("sms/alert", phone.."|"..msg)
else -- 普通短信存入队列
table.insert(sms_queue, {phone, msg})
end
end)
-- MQTT消息发布函数
function publish_mqtt(topic, payload)
local mqttc = mqtt.create(nil, "mqtt.服务器地址")
mqttc:connect()
mqttc:publish(topic, payload)
end
3.3 数据转发协议设计
推荐采用紧凑型二进制协议:
code复制| 头标识(0xAA) | 手机号长度(1B) | 手机号(nB) | 短信长度(2B) | 短信内容(nB) | CRC16(2B) |
实测这种设计比JSON格式节省40%以上流量,特别适合4G按量计费场景。
4. 典型问题排查与优化技巧
4.1 信号不稳定解决方案
- 天线选型:优先选用IPEX接口外接天线(增益≥3dBi)
- 位置优化:使用
AT+CSQ命令检测信号强度(>15为佳) - 备用方案:配置WiFi回传通道(ESP32特有功能)
4.2 短信丢失处理
通过以下方法确保零丢失:
lua复制-- 在init.lua中添加存储备份
local sms_backup = io.open("/sms_backup.txt", "a")
sys.subscribe("SMS_RECEIVE", function(...)
sms_backup:write(os.date()..table.concat({...}, "|").."\n")
sms_backup:flush()
end)
4.3 电源管理优化
使用TP4056充电模块时,注意修改Rprog电阻:
code复制充电电流(mA) = 1200/Rprog(kΩ)
实测值建议设置在500-800mA之间,既能保证4G模组峰值功耗需求,又不会导致锂电池过热。
5. 进阶功能扩展思路
5.1 多卡轮询方案
通过SIM800C模块+多路复用器实现:
lua复制function check_sim_slot(slot)
uart.write(1, "AT+CSIMSWITCH="..slot.."\r\n")
sys.wait(1000)
return uart.read(1, 100)
end
5.2 云端规则引擎集成
通过HTTP回调实现动态规则:
lua复制local rule = http.request("GET", "https://api.example.com/rules/"..phone)
if rule.status == 200 then
forward_to = json.decode(rule.body).target
end
5.3 本地关键词过滤
高效实现方案:
lua复制local filter_words = {"促销", "贷款", "赌博"}
function contains_sensitive(msg)
for _, word in ipairs(filter_words) do
if string.find(msg, word) then
return true
end
end
return false
end
6. 成品组装与测试要点
6.1 结构设计建议
- 使用3D打印外壳时预留散热孔(孔径≥2mm)
- SIM卡座选择翻盖式(避免长期使用接触不良)
- 指示灯布局:
- 蓝色:4G信号
- 绿色:电源
- 红色:短信触发
6.2 压力测试方案
- 使用AT命令模拟短信轰炸:
bash复制for i in {1..100}; do echo "AT+CMGS=\"13800138000\"\r\nTEST$i\x1A" > /dev/ttyUSB0; done - 监控内存泄漏:
lua复制sys.timerLoopStart(function() log.info("mem", rtos.meminfo("sys")) end, 5000)
6.3 功耗优化实测数据
不同模式下的电流消耗:
| 工作模式 | 平均电流 | 峰值电流 |
|---|---|---|
| 待机 | 12mA | 80mA |
| 短信接收 | 180mA | 350mA |
| 数据发送 | 220mA | 500mA |
建议搭配2000mAh锂电池可实现7-10天续航(每天20条短信)
