
EDA-Pager寻呼机
简介
本项目使用ESP32C3主控,结合ML307C的LTE模组实现的基于LTE网络的寻呼机/传呼机/BB机,支持消息转发,验证码识别。
简介:本项目使用ESP32C3主控,结合ML307C的LTE模组实现的基于LTE网络的寻呼机/传呼机/BB机,支持消息转发,验证码识别。开源协议
:GPL 3.0
描述
本项目使用 ESP32C3 主控,结合 ML307C LTE模组实现的基于LTE网络的寻呼机/传呼机/BB机。系统通过 LTE 控制信令与 IMS 通道接收短消息,实现 短信的接收、存储、显示及转发 等功能,支持 SMS over NAS 与 SMS over IP(IMS) 两种短信承载方式,具备良好的网络兼容性与可靠性。
固件功能
项目参数
硬件设计
主控选用 ESP32C3系列 模组,集成 WiFi 功能,提供丰富的 GPIO 接口。 板载 USB 转串口芯片,方便程序下载和调试。
本项目的烧录方式是USB烧录,因为硬件串口需要完全用于LTE模组通讯。如果采用全新的ESP32C3模组,首次烧录时需要先按住BOOT键-点击RST键-松开BOOT键即可进入烧录模式,否则串口会一直跳。本项目选用USB烧录方案,但此方案需要注意布局布线、信号干扰及等长类差分问题,好处是无需烧录器,无需USB转串口模块,直接使用TypeC线上电后即可出现端口号。
MCU部分采用ME6217C33M5G LDO供电,上游电源来自IP5306升压输出的5V 2.4A,足矣驱动ESP32C3。
LTE模组选用ML307C,此模组功能很多,除了LTE功能外,也可做IO扩展功能,带有ADC,PWM等功能,模组PWR部分已配置4.7K上拉实现开机自启动,USIM的IO连接SIM卡座,USIM1还可接个ESIM来切卡,但本项目考虑布局和焊接问题所以去除。考虑到ML307C封装的焊接问题,非必要焊盘均以替换成丝印,方便走线同时也能避免新手焊接造成底部连锡,仅需焊接最外围邮票孔即可。
ML307C系列模组支持PPP拨号通讯协议,可通过USB走RNDIS实现4G网卡上网功能,通过接入TYPEC后主机设备会识别成有线网卡,如未识别需手动在设备管理器切换驱动。需要注意的是使用此功能则必须焊接模组底部USB信号线焊盘,建议使用加热台或风枪。
LTE模组电源供电依照数据手册要求供应3.9V电路,因电路较大所以选用DCDC降压电路,最大供应电流2A,符合数据手册要求。
屏幕部分选用LCD 128X32 ST7920驱动,背光部分通过MOS管控制,使用SPI协议驱动,所以中间DB的IO没有使用,封装上留空用于走线。
选用IP5306管理芯片,支持升压,路径管理等功能的充放一体芯片,为器件提供电源及为电池充电。此IC需要注意,必须焊接底部EPAD,PCB设计中已为底部开插件焊盘孔,可使用烙铁锡丝焊接。 电源键按键对应PCB中右下角按键中最右侧的按键,单击开机,双击关机。
三个按键分别对应PCB中右下角按键从左往右的三个功能键,最右侧的按键是IP5306的电源键。扬声器这里实际用的是无源蜂鸣器,使用扬声器也可以。
软件开发
完整源码请在附件查看
本项目采用功能模块化。
- config_manager.h/.cpp: 数据存储器类
- config.h: IO定义及软件配置
- display.h/.cpp: 屏幕显示类
- lte_module.h/.cpp: 步态运动类定义和接口声明
- http_client.h/.cpp: HTTP请求类
- sms_types.h: 短信的数据接口定义
- speaker.h/.cpp: speakerle类定义
- web_server.h/.cpp: web服务器类
- wifi_manager.h/.cpp: wifi管理类
- main.cpp: 程序主入口
config_manager
此类用于将配置数据存储进非易失存储器,避免断电后掉电
#ifndef CONFIG_MANAGER_H
#define CONFIG_MANAGER_H
#include
#include
// 配置管理类
class ConfigManager {
public:
ConfigManager();
// 加载配置
void load();
// 保存配置
void save();
// 检查是否已配置
bool isConfigured() const;
// 设置配置完成标志
void setConfigured(bool configured);
// WiFi配置
String wifiSSID;
String wifiPassword;
// HTTP配置
String httpMethod;
String httpUrl;
bool httpForwardEnabled;
// 短信转发配置
bool smsForwardEnabled;
String smsForwardNumber;
// 显示配置
int backlightBrightness;
int backlightMode; // 0=关闭, 1=常亮, 2=收到消息时开启
private:
Preferences preferences;
};
#endif
config.h
板级配置文件,用于配置IO引脚定义及其他自定义配置
class #ifndef CONFIG_H
#define CONFIG_H
// 硬件引脚定义
// ST7920显示屏引脚
#define LCD_CLK 4 // IO4 - 时钟
#define LCD_MOSI 6 // IO6 - 数据
#define LCD_CS 7 // IO7 - 片选
// 按键引脚
#define BTN_LEFT 1 // IO1 - 收信模式按键
#define BTN_MID 2 // IO2 - 确定按键
#define BTN_RIGHT 3 // IO3 - 转发模式按键
// 蜂鸣器引脚
#define BTN_SPK 5 // IO5 - 蜂鸣器
// 背光引脚
#define LCD_BACKLIGHT 0 // IO0 - 背光控制
// 背光模式
enum BacklightMode {
BACKLIGHT_OFF = 0, // 关闭
BACKLIGHT_ALWAYS_ON = 1, // 常亮
BACKLIGHT_ON_MESSAGE = 2 // 收到消息时开启
};
// 显示配置
#define MAX_DISPLAY_WIDTH 128
#define SCROLL_DELAY 150
#define SCROLL_STEP 2
// 通信配置
#define SERIAL_BAUD 115200
#define AT_TIMEOUT 2000
// HTTP配置
#define MIN_SEND_INTERVAL 5000 // 最小发送间隔(ms)
// 时间同步配置
#define TIME_SYNC_INTERVAL 60000 // 时间同步间隔(1分钟)
// WiFi配置
#define AP_SSID "EDA-Pager"
#define AP_PASSWORD "12345678"
#define WEB_SERVER_PORT 80
#endif
display.h
定义了一些屏幕显示部分的功能
#ifndef DISPLAY_H
#define DISPLAY_H
#include
#include "sms_types.h"
// 显示管理类
class Display {
public:
Display();
// 初始化显示屏
void begin();
// 显示短信内容(带滚动)
void showSms(const SmsData& sms);
// 手动滚动控制
void scrollLeft(int step = 10); // 向左滚动(文本向左移动)
void scrollRight(int step = 10); // 向右滚动(文本向右移动)
void enableAutoScroll(); // 启用自动滚动
void disableAutoScroll(); // 禁用自动滚动
bool isAutoScrollEnabled(); // 检查是否启用自动滚动
// 显示等待消息
void showWaiting(WorkMode mode, const String& date, const String& time);
// 显示文本消息
void showMessage(const String& line1, const String& line2 = "", const String& line3 = "");
// 显示配置信息
void showConfigInfo(const String& apIP, const String& staIP, bool wifiConnected);
// 显示验证码
void showVerificationCode(const String& code, const String& sender);
// 背光控制
void setBacklightMode(int mode);
void updateBacklight();
void turnOnBacklight();
void turnOffBacklight();
private:
U8G2_ST7920_128X64_F_SW_SPI u8g2;
int scrollOffset;
unsigned long lastScrollTime;
int backlightBrightness;
bool autoScrollEnabled; // 自动滚动开关
int maxScrollOffset; // 最大滚动偏移量
int backlightMode; // 背光模式
unsigned long backlightOnTime; // 背光开启时间
bool backlightOn; // 背光状态
};
#endif
http_client.h
项目构建配置文件,定义目标平台、分区表和编译选项。
#ifndef HTTP_CLIENT_H
#define HTTP_CLIENT_H
#include
#include
// HTTP客户端类
class HttpClient {
public:
HttpClient();
// 发送HTTP请求
bool sendRequest(const String& url, const String& method, const String& smsContent);
// 获取最后一次错误信息
String getLastError() const { return lastError; }
// 获取最后一次HTTP状态码
int getLastHttpCode() const { return lastHttpCode; }
private:
String lastError;
int lastHttpCode;
unsigned long lastSendTime;
// 替换URL中的占位符
String replacePlaceholder(const String& url, const String& smsContent);
// URL编码
String urlEncode(const String& str);
// URL解码
String urlDecode(const String& str);
// JSON字符串转义
String escapeJsonString(const String& str);
// 解析查询参数并转换为JSON
String parseQueryParamsToJson(const String& queryParams, const String& smsContent);
// 发送GET请求
bool sendGetRequest(const String& url);
// 发送POST请求
bool sendPostRequest(const String& url, const String& smsContent);
};
#endif
lte_module.h
项目构建配置文件,定义目标平台、分区表和编译选项。
#ifndef HTTP_CLIENT_H
#define HTTP_CLIENT_H
#include
#include
// HTTP客户端类
class HttpClient {
public:
HttpClient();
// 发送HTTP请求
bool sendRequest(const String& url, const String& method, const String& smsContent);
// 获取最后一次错误信息
String getLastError() const { return lastError; }
// 获取最后一次HTTP状态码
int getLastHttpCode() const { return lastHttpCode; }
private:
String lastError;
int lastHttpCode;
unsigned long lastSendTime;
// 替换URL中的占位符
String replacePlaceholder(const String& url, const String& smsContent);
// URL编码
String urlEncode(const String& str);
// URL解码
String urlDecode(const String& str);
// JSON字符串转义
String escapeJsonString(const String& str);
// 解析查询参数并转换为JSON
String parseQueryParamsToJson(const String& queryParams, const String& smsContent);
// 发送GET请求
bool sendGetRequest(const String& url);
// 发送POST请求
bool sendPostRequest(const String& url, const String& smsContent);
};
#endif
sms_types.h
项目构建配置文件,定义目标平台、分区表和编译选项。
#ifndef HTTP_CLIENT_H
#define HTTP_CLIENT_H
#include
#include
// HTTP客户端类
class HttpClient {
public:
HttpClient();
// 发送HTTP请求
bool sendRequest(const String& url, const String& method, const String& smsContent);
// 获取最后一次错误信息
String getLastError() const { return lastError; }
// 获取最后一次HTTP状态码
int getLastHttpCode() const { return lastHttpCode; }
private:
String lastError;
int lastHttpCode;
unsigned long lastSendTime;
// 替换URL中的占位符
String replacePlaceholder(const String& url, const String& smsContent);
// URL编码
String urlEncode(const String& str);
// URL解码
String urlDecode(const String& str);
// JSON字符串转义
String escapeJsonString(const String& str);
// 解析查询参数并转换为JSON
String parseQueryParamsToJson(const String& queryParams, const String& smsContent);
// 发送GET请求
bool sendGetRequest(const String& url);
// 发送POST请求
bool sendPostRequest(const String& url, const String& smsContent);
};
#endif
speaker.h
项目构建配置文件,定义目标平台、分区表和编译选项。
#ifndef SPEAKER_H #define SPEAKER_H #include class Speaker { public: Speaker(uint8_t pin); void begin(); void speak(uint16_t freq, uint16_t duration); void beep(uint16_t duration = 100); void speakStart(); void speakNotify(); void mute(); void unmute(); bool isMuted() const { return _muted; } private: uint8_t _pin; bool _muted; }; #endif
web_server.h
项目构建配置文件,定义目标平台、分区表和编译选项。
#include "config_manager.h"
#include "http_client.h"
#include "display.h"
#include "sms_types.h"
#include "speaker.h"
// Web服务器类
class WebServer {
public:
WebServer(ConfigManager& config, HttpClient& httpClient, Display& display,
SmsData* smsHistory, int* smsHistoryCount, Speaker& speaker);
// 启动Web服务器
void begin();
// 检查配置是否完成
bool isConfigCompleted() const { return configCompleted; }
// 获取WiFi连接状态
bool isWiFiConnected() const { return wifiConnected; }
// 设置WiFi连接状态
void setWiFiConnected(bool connected) { wifiConnected = connected; }
private:
AsyncWebServer server;
ConfigManager& configManager;
HttpClient& httpClient;
Display& display;
Speaker& speaker;
SmsData* smsHistory;
int* smsHistoryCount;
bool configCompleted;
bool wifiConnected
void setupRoutes();
};
#endif
wifi_manager.h
项目构建配置文件,定义目标平台、分区表和编译选项。
// WiFi管理类
class WiFiManager {
public:
WiFiManager();
// 启动AP模式
void startAP(const char* ssid, const char* password);
// 连接到WiFi
bool connect(const String& ssid, const String& password);
// 检查是否已连接
bool isConnected() const;
// 获取AP IP地址
String getAPIP() const;
// 获取STA IP地址
String getSTAIP() const;
private:
bool connected;
};
#endif
安装结构
项目采用双外壳结构,包含前壳及后壳。
- 屏幕部分采用限位孔固定,先装入屏幕后压入主板
- 按钮及扬声器和侧面TypeC均已开孔
- 突出部分加入倒角加强
- 后盖较简单,压入限位使用
RNDIS 4G USB网卡测试

拓展方向
本项目提供了一个基础的LTE寻呼机方案,你可以基于此项目进行以下拓展:
- 增加MQTT功能,组成自建
- 增加蓝牙通知功能,将手机通知推送到寻呼机上
- 增加GPS功能,获取当前位置信息
- 增加SOS紧急联系人报告功能
注意事项
立创商城采购物料清单
| 数量 | 器件 | 商城编号 |
|---|---|---|
| 4 | 19-217/GHC-YR1S2/6T | C2986059 |
| 1 | 2.7kΩ | C96256 |
| 2 | 22uF | C6119901 |
| 1 | 1nF | C46653 |
| 4 | 100nF | C28233 |
| 4 | 10uF | C15850 |
| 5 | 22uF | C45783 |
| 2 | 100nF | C5137467 |
| 1 | SMN-303 | C266888 |
| 1 | 4.7uH | C167208 |
| 1 | 1uH | C167203 |
| 1 | TS665CJ | C393938 |
| 1 | AO3400A | C347475 |
| 8 | 10kΩ | C17414 |
| 1 | 100kΩ | C149504 |
| 1 | 20kΩ | C4328 |
| 1 | 82kΩ | C17840 |
| 1 | 2Ω | C17606 |
| 1 | 500mΩ | C28319 |
| 4 | 5.1kΩ | C27834 |
| 1 | 4.7kΩ | C2907326 |
| 1 | BWIPX-1-001E | C496552 |
| 3 | KH-6X6X9H-TJ | C2837519 |
| 4 | TS3425BA | C2681476 |
| 1 | ME6217C33M5G | C427602 |
| 1 | ML307C-DC-CN | C48982539 |
| 1 | JW5359MSOTB#TR | C42685544 |
| 1 | 2.4GHz 天线 | C2934560 |
| 1 | IP5306 | C181692 |
| 2 | TYPE-C 16PIN 2MD(073) | C2765186 |
非商城物料采购清单
| 数量 | 器件 |
|---|---|
| 1 | 3.7V聚合物电池 |
💡 提示:部分通用元件可选择等效型号,重点关注封装及电气参数一致性。
下表列出了本项目 ESP32C3 未合并固件烧录时的分区布局,地址与文件路径对应关系如下,可直接用于命令行烧录或 Flash 工具导入配置。
| 烧录地址 | 文件路径 | 说明 |
|---|---|---|
| 0x0 | bootloader.bin | Bootloader 启动加载程序 |
| 0x8000 | partition-table.bin | 分区表 |
| 0xe000 | boot_app0.bin | 二级Boot |
| 0x10000 | firmware.bin | 主程序固件 |
💡 提示:使用 esptool.py 可执行如下命令进行烧录:
esptool.py write_flash 0x0 bootloader.bin 0x8000 partition-table.bin 0xe000 boot_app0.bin 0x10000 firmware.bin
设计图
未生成预览图,请在编辑器重新保存一次BOM
暂无BOM
克隆工程知识产权声明&复刻说明
本项目为开源硬件项目,其相关的知识产权归创作者所有。创作者在本平台上传该硬件项目仅供平台用户用于学习交流及研究,不包括任何商业性使用,请勿用于商业售卖或其他盈利性的用途;如您认为本项目涉嫌侵犯了您的相关权益,请点击上方“侵权投诉”按钮,我们将按照嘉立创《侵权投诉与申诉规则》进行处理。
请在进行项目复刻时自行验证电路的可行性,并自行辨别该项目是否对您适用。您对复刻项目的任何后果负责,无论何种情况,本平台将不对您在复刻项目时,遇到的任何因开源项目电路设计问题所导致的直接、间接等损害负责。









