身份证读取设备开发解决方案:1、Windows下开发Qt程序demo读取身份证信息

article/2025/9/27 9:54:40

身份证读取设备开发解决方案:1、Windows下开发Qt程序demo读取身份证信息


文章目录

  • 身份证读取设备开发解决方案:1、Windows下开发Qt程序demo读取身份证信息
    • 1. 前言
    • 2. 身份证读取模块
    • 3. Qt5开发简单上位机读取身份证信息
      • 1. 注意的点
      • 2. 部分源码
      • 3. 结果展示
      • 4. 碎片代码
    • 4. 问题记录
      • 发送指令没有回复
      • 读取照片返回-22错误

1. 前言

我们的门禁设备有一个新的需求,需要不但可以刷小区制作的门禁卡,还支持刷身份证进小区,开始时只有一个身份证的认证读取模块,没有开发案例和经验,摸索了一段时间后还是不行,最后找到一个封装模块,可以很方便的进行二次开发,适用于Windows、Linux、Android、单片机(但是要获取身份证照片的话目前建议的是使用Android或Windows,对应有解码库,Linux需要特殊处理,单片机暂时没提,要处理的话可能比较麻烦)。

2. 身份证读取模块

这个是京东的链接地址:https://item.jd.com/29630924722.html#crumb-wrap

由于身份证读取模块的特殊性,所以是比价贵的,基本都是在¥1000+,包括一个公安部授权的模块和一系列公安部授权解码照片等信息的软件等。

如果不需要二次开发的话可以直接购买现成的设备,需要二次开发的话根据设备外设情况确认,我们是使用的ttl串口方式,这样可以多平台使用,Windows、Android、单片机都可以通过串口协议直接读取身份证信息。

下面我将使用Qt5开发一个简单的上位机进行身份证信息读取,相关的串口协议在买了模块后厂家回提供。

3. Qt5开发简单上位机读取身份证信息

这里只开发一个简单的demo,根据协议选择并设置串口,之后根据串口协议寻卡、选卡、读卡,读卡成功后控制蜂鸣器发声。

1. 注意的点

  • 1、读取身份证信息时由于长度较长,大致在1000+个字节,所以如果全部获取完整的串口信息需要注意一下,我这里是根据报头和固定长度来确定的,发现报头后判断报文类型,确认是读取身份证的回复后一直到读到固定大小为止,期间的报文全部缓存追加;
  • 2、高低字节互换并转unicode才是结果,这个也比较麻烦,思路是将根据偶数序号分割读取到的内容后高低字节转换并将两个字节合并为16位的ushort数组存储,之后直接转换ushort数组为utf16即可;
  • 3、照片解码需要license、相关软件和库,目前支持Linux、Android、Windows,所以单片机开发的需要注意一下,解码照片需要上位机配合。
  • 4、最好使用最新的解码动态库,license软件、动态库dll都放在exe运行目录下,且运行时需要使用管理员权限,运行完成后就会在exe目录下生成bmp图片,由于其没有头文件只有动态库,所以需要了解一下Qt直接调用动态库不需要头文件的方式。

2. 部分源码

由于涉及协议,所以无法上传工程文件,只展示部分内容,提供解析字节码到unicode再到字符串这个过程便于部分同学爬坑。

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLibrary>QSerialPort *serialPort;
QByteArray readBuff;MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);serialPort = new QSerialPort;searchSerialPort();
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_connectBtn_clicked()
{QString portName = ui->portBox->currentText();qInfo()<<"FILE:"<<__FILE__ << "LINE:" << __LINE__ <<"portName:"<<portName;serialPort->setPortName(ui->portBox->currentText());                   //串口名serialPort->setBaudRate(ui->baudRateLineEdit->text().toInt());                   //波特率serialPort->setDataBits(QSerialPort::Data8);         //数据位serialPort->setStopBits(QSerialPort::OneStop);       //停止位serialPort->setParity(QSerialPort::NoParity);        //奇偶校验serialPort->setFlowControl(QSerialPort::NoFlowControl);if (serialPort->open(QIODevice::ReadWrite)){qWarning()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"Port have been opened";ui->statusBar->showMessage("串口连接成功!");connect(serialPort, SIGNAL(readyRead()), this, SLOT(parseSerialData()));}else{qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"open com failed";return;}connect(serialPort, static_cast<void (QSerialPort::*)(QSerialPort::SerialPortError)>(&QSerialPort::error),this, handleSerialError);ui->connectBtn->setEnabled(false);ui->closeBtn->setEnabled(true);
}void MainWindow::handleSerialError(QSerialPort::SerialPortError error) {if (error == QSerialPort::ResourceError) {QMessageBox::critical(this, tr("error"), "串口连接中断,请检查是否正确连接!");} else {ui->statusBar->showMessage(serialPort->errorString());}
}static QByteArray g_IDNumCardInfo;
static bool readIDNumCardFlag = false;static QString getName() {ushort name[15];for(int i = 0; i < 15; i++) {name[i] = g_IDNumCardInfo[8+2*i+1] << 8;name[i] = name[i] + (g_IDNumCardInfo[8+2*i] & 0x00ff);qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<QString().sprintf("%02x",name[i]);}QString nameRes = QString::fromUtf16(name, 15);qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<< nameRes;return nameRes;
}static QString getSex() {ushort sex[1];for(int i = 0; i < 1; i++){sex[i] = g_IDNumCardInfo[8+30+2*i+1] << 8;sex[i] = sex[i] + (g_IDNumCardInfo[8+30+2*i] & 0x00ff);qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<QString().sprintf("%02x",sex[i]);}QString sexRes = QString::fromUtf16(sex, 1);if(sexRes == "1") {sexRes = "男";} else if(sexRes == "2") {sexRes = "女";} else if(sexRes == "9") {sexRes = "其他";}qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<< sexRes;return sexRes;
}static QString getNation() {ushort nation[2];for(int i = 0; i < 2; i++) {nation[i] = g_IDNumCardInfo[8+30+2+2*i+1] << 8;nation[i] = nation[i] + (g_IDNumCardInfo[8+30+2+2*i] & 0x00ff);qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<QString().sprintf("%02x",nation[i]);}int nationTmp = QString::fromUtf16(nation, 2).toInt();qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<nationTmp;QString nationRes;switch (nationTmp) {case 1:nationRes = "汉";break;case 2:nationRes = "蒙古";break;case 3:nationRes = "回";break;case 4:nationRes = "藏";break;case 5:nationRes = "维吾尔";break;case 6:nationRes = "苗";break;case 7:nationRes = "彝";  //yizu彝族break;case 8:nationRes = "壮";break;case 9:nationRes = "布依";break;case 10:nationRes = "朝鲜";break;case 11:nationRes = "满";break;case 12:nationRes = "侗";  //侗族dongzubreak;case 13:nationRes = "瑶";break;case 14:nationRes = "白";break;case 15:nationRes = "土家";break;case 16:nationRes = "哈尼";break;case 17:nationRes = "哈萨克";break;case 18:nationRes = "傣";  //傣族daizubreak;case 19:nationRes = "黎";break;case 20:nationRes = "傈僳";  //傈僳族lisuzubreak;case 21:nationRes = "佤";  //佤族wazubreak;case 22:nationRes = "畲";  //畲族shezubreak;case 23:nationRes = "高山";break;case 24:nationRes = "拉祜";  //拉祜lahubreak;case 25:nationRes = "水";break;case 26:nationRes = "东乡";break;case 27:nationRes = "纳西";break;case 28:nationRes = "景颇";break;case 29:nationRes = "柯尔克孜";break;case 30:nationRes = "土";break;case 31:nationRes = "达斡尔";  //dawoerbreak;case 32:nationRes = "仫佬族";  //mulaozubreak;case 33:nationRes = "羌";  //qiangbreak;case 34:nationRes = "布朗";break;case 35:nationRes = "撒拉";break;case 36:nationRes = "毛南";break;case 37:nationRes = "仡佬";  //仡佬族gelaozubreak;case 38:nationRes = "锡伯";break;case 39:nationRes = "阿昌";break;case 40:nationRes = "普米";break;case 41:nationRes = "塔吉克";break;case 42:nationRes = "怒";break;case 43:nationRes = "乌孜别克";break;case 44:nationRes = "俄罗斯";break;case 45:nationRes = "鄂温克";break;case 46:nationRes = "德昂";break;case 47:nationRes = "独龙";break;case 48:nationRes = "裕固";break;case 49:nationRes = "京";break;case 50:nationRes = "塔塔尔";break;case 51:nationRes = "独龙";break;case 52:nationRes = "鄂伦春";break;case 53:nationRes = "赫哲";break;case 54:nationRes = "门巴";break;case 55:nationRes = "珞巴";break;case 56:nationRes = "基诺";break;default:break;}qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__ << nationRes;return nationRes;
}static QString getBirth() {ushort birth[8];for(int i = 0; i < 8; i++) {birth[i] = g_IDNumCardInfo[8+30+2+4+2*i+1] << 8;birth[i] = birth[i] + (g_IDNumCardInfo[8+30+2+4+2*i] & 0x00ff);qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<QString().sprintf("%02x",birth[i]);}QString birthRes = QString::fromUtf16(birth, 8);qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<birthRes;return birthRes;
}static QString getAddress() {ushort address[35];for(int i = 0; i < 35; i++) {address[i] = g_IDNumCardInfo[8+30+2+4+16+2*i+1] << 8;address[i] = address[i] + (g_IDNumCardInfo[8+30+2+4+16+2*i] & 0x00ff);qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<QString().sprintf("%02x",address[i]);}QString addressRes = QString::fromUtf16(address, 35);qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<addressRes;return addressRes;
}static QString getIDCardNum() {ushort idCardNum[18];for(int i = 0; i < 18; i++) {idCardNum[i] = g_IDNumCardInfo[8+30+2+4+16+70+2*i+1] << 8;idCardNum[i] = idCardNum[i] + (g_IDNumCardInfo[8+30+2+4+16+70+2*i] & 0x00ff);qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<QString().sprintf("%02x",idCardNum[i]);}QString idCardNumRes = QString::fromUtf16(idCardNum, 18);qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<idCardNumRes;return idCardNumRes;
}static QString getIssuingAuthority() {ushort issuingAuthority[15];for(int i = 0; i < 15; i++) {issuingAuthority[i] = g_IDNumCardInfo[8+30+2+4+16+70+36+2*i+1] << 8;issuingAuthority[i] = issuingAuthority[i] + (g_IDNumCardInfo[8+30+2+4+16+70+36+2*i] & 0x00ff);qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<QString().sprintf("%02x", issuingAuthority[i]);}QString issuingAuthorityRes = QString::fromUtf16(issuingAuthority, 15);qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<issuingAuthorityRes;return issuingAuthorityRes;
}static QString getEffectiveStartDate() {ushort effectiveStartDate[8];for(int i = 0; i < 8; i++) {effectiveStartDate[i] = g_IDNumCardInfo[8+30+2+4+16+70+36+30+2*i+1] << 8;effectiveStartDate[i] = effectiveStartDate[i] + (g_IDNumCardInfo[8+30+2+4+16+70+36+30+2*i] & 0x00ff);qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<QString().sprintf("%02x", effectiveStartDate[i]);}QString effectiveStartDateRes = QString::fromUtf16(effectiveStartDate, 8);qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<effectiveStartDateRes;return effectiveStartDateRes;
}static QString getEffectiveEndDate() {ushort effectiveEndDate[8];for(int i = 0; i < 8; i++) {effectiveEndDate[i] = g_IDNumCardInfo[8+30+2+4+16+70+36+30+16+2*i+1] << 8;effectiveEndDate[i] = effectiveEndDate[i] + (g_IDNumCardInfo[8+30+2+4+16+70+36+30+16+2*i] & 0x00ff);qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<QString().sprintf("%02x", effectiveEndDate[i]);}QString effectiveEndDateRes = QString::fromUtf16(effectiveEndDate, 8);qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<effectiveEndDateRes;return effectiveEndDateRes;
}typedef int (*pcom_open)(char* , char* , int );
static int getPhoto() {uchar photo[1024];char dst[38556];for(int i = 0; i < 1024; i++) {photo[i] = g_IDNumCardInfo[8+30+2+4+16+70+36+30+16+16+36+i] & 0xff;//        qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<QString().sprintf("%02x", photo[i]);}//Qt中只调用动态库不需要头文件的方式QLibrary mylib("DLL_File.dll");int res;if(mylib.load()) {pcom_open open = (pcom_open)mylib.resolve("unpack");if(open) {res = open((char*)photo, dst, 1);}qDebug()<<"res:"<<res;return res;}return -1;
}void MainWindow::parseSerialData() {readBuff.clear();readBuff = serialPort->readAll();for(int i = 0; i < readBuff.size(); i++) {if(readBuff[i].operator == (0xEA) &&readBuff[i+1].operator == (0xEB) &&readBuff[i+2].operator == (0xEC) &&readBuff[i+3].operator == (0xED)) {if(readBuff[7].operator == (0xA4)) {ui->statusBar->showMessage(QString("蜂鸣器:").append(readBuff.toHex().toUpper()));}else if(readBuff[7].operator == (0xB0)) {ui->statusBar->showMessage(QString("身份证寻卡:").append(readBuff.toHex().toUpper()));}else if(readBuff[7].operator == (0xB1)) {ui->statusBar->showMessage(QString("身份证选卡:").append(readBuff.toHex().toUpper()));}else if (readBuff[7].operator == (0xB4)) {ui->statusBar->showMessage(QString("身份证读取:").append(readBuff.toHex().toUpper()));qDebug()<<readBuff.size();//触发读到身份证的标志,直到读取完所有的身份证信息readIDNumCardFlag = true;}}}qDebug() << "FILE:" << __FILE__ << "LINE:" << __LINE__ << "读取到的报文:" << readBuff.toHex();if(readIDNumCardFlag) {qDebug()<<g_IDNumCardInfo.size();if(g_IDNumCardInfo.size() < 1290) {qDebug()<<g_IDNumCardInfo.size();g_IDNumCardInfo = g_IDNumCardInfo.append(readBuff);if(g_IDNumCardInfo.size() == 1290) {qDebug()<<g_IDNumCardInfo.toHex();QString IDCardInfo;//30字节姓名IDCardInfo = getName().append("\n");//2字节性别IDCardInfo.append(getSex()).append("\n");//4字节民族IDCardInfo.append(getNation()).append("\n");//16字节出生IDCardInfo.append(getBirth()).append("\n");//70字节住址IDCardInfo.append(getAddress()).append("\n");//36字节身份证号IDCardInfo.append(getIDCardNum()).append("\n");//30字节签发机关IDCardInfo.append(getIssuingAuthority()).append("\n");//16字节有效起始日期IDCardInfo.append(getEffectiveStartDate()).append("\n");//16字节有效截至日期IDCardInfo.append(getEffectiveEndDate()).append("\n");//36字节备用信息,暂为空//1024字节照片信息if(getPhoto() == 1) {QPixmap img;img.load("zp.bmp");ui->imgLabel->clear();ui->imgLabel->setPixmap(img);ui->IDCard2InfoLabel->setText(IDCardInfo);}g_IDNumCardInfo.clear();readIDNumCardFlag = false;} else if(g_IDNumCardInfo.size() > 1290) {readIDNumCardFlag = false;g_IDNumCardInfo.clear();}}}
}void MainWindow::on_closeBtn_clicked()
{serialPort->clearError();serialPort->clear();serialPort->close();ui->closeBtn->setEnabled(false);ui->connectBtn->setEnabled(true);ui->statusBar->showMessage("串口断开完成!");
}void MainWindow::searchSerialPort()
{ui->portBox->clear();foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {QSerialPort serialTmp;serialTmp.setPort(info);ui->portBox->addItem(info.portName());if(serialTmp.open(QIODevice::ReadWrite)){serialTmp.close();}else{qCritical()<<"file:"<<__FILE__<<"line:"<<__LINE__<<"串口打开失败,或串口已打开";QMessageBox::warning(this, "提示信息", QString("串口打开失败,串口已打开:%1").arg(info.portName()));}}ui->portBox->setCurrentIndex(ui->portBox->count() - 1);
}

3. 结果展示

在这里插入图片描述

4. 碎片代码

通过Qlabel显示图片:

QPixmap img;
img.load("zp.bmp");
ui->imgLabel->clear();
ui->imgLabel->setPixmap(img);ui->IDCard2InfoLabel->setText(IDCardInfo);

不需要头文件直接加载dll动态库:

//定义函数指针
typedef int (*pcom_open)(char* , char* , int );//Qt中只调用动态库不需要头文件的方式
QLibrary mylib("DLL_File.dll");
int res;
if(mylib.load()) {pcom_open open = (pcom_open)mylib.resolve("unpack");if(open) {res = open((char*)photo, dst, 1);}qDebug()<<"res:"<<res;return res;
}

还有比较有趣的就是直到了56个民族的发音。

4. 问题记录

发送指令没有回复

在最初使用串口工具进行测试时发现发送寻卡、选卡和读卡指令时一直没有回复报文:

在这里插入图片描述

然后一边找客服解答一边写了串口代码测试发现有回复,然后尝试勾选了Hex发送、Hex显示、加时间戳和分包显示后正常了,这个就尴尬了,当指令为16进制时需要注意你的串口测试工具是否开启了16进制,否则发送的指令很有可能没有回复:

在这里插入图片描述

读取照片返回-22错误

编译后在当前目录运行即可,使用Qt creator运行时没有找到解码软件。给到的身份证解码模组的软件、动态库等都是放到exe的当前目录下的。


http://chatgpt.dhexx.cn/article/DA1emoX1.shtml

相关文章

最新web/java/jsp实现发送手机短信验证码和邮箱验证码的注册登录功能(详细)

最新web/java/jsp实现发送手机短信验证码和邮箱验证码的注册登录功能&#xff08;详细&#xff09; 最近几天有人需要帮忙做一个关于发送验证码的功能&#xff0c;之前没有做过&#xff0c;于是我鼓捣一阵子&#xff0c;记录一下关于web项目中注册登录常用的手机验证码和邮箱验…

uniapp中注册手机号短信验证码

一、效果图 二、输入手机号页面 <template><view><view classlogin-tel><view classtel-main><view classlogin-from><view classlogin-user><text classuser-text>手机号</text><input type"number" focustrue…

阿里云手机验证码注册(可以使用阿里云提供的测试模板,不用个人申请)

目录 打开阿里云&#xff1a;&#xff08;绑定手机号码&#xff09;&#xff0c;不用申请模板和签名手机验证码注册流程&#xff1a;实现流程创建springboot工程&#xff0c;添加依赖编写applicatioin配置文件编写controller&#xff0c;根据手机号发送短信编写service&#xf…

抖音实战~手机号验证码一键注册登录流程(限制手机终端登录)

文章目录 一、手机号验证码二、前端2.1. 点击登陆流程2.2. 点击登录源码 三、后端登录3.1. 登录流程图3.2. 流程简述3.3. 手机号验证码登录流程 一、手机号验证码 二、前端 2.1. 点击登陆流程 1.先校验手机号是否合法&#xff1f;不合法&#xff0c;则提示“请输入正确的手机…

会话——验证码注册与记住密码登录

文章目录 1、需求分析2、用户登录功能2.1、流程分析2.2、代码实现2.3、结果演示 3、登录记住密码功能3.1、流程分析3.2、代码实现3.3、结果演示 4、用户注册功能4.1、流程分析4.2、代码实现4.3、结果演示 5、注册验证码功能5.1、流程分析5.2、代码实现5.3、结果演示 1、需求分析…

关于烧写ESP8285核心板的相关事项

首先需要一个CH340的usb 转ttl 板子 然后连接到8285 脚管对应 TTL ---- 8285 VCC----VCC RXD----TX0 TXD----RX0 GND----GND 在通电之前先要把8285的GND 和io 0 连在ttl 板子的 GND上 烧写软件要设置正确否则无法启动

esp32 esp8285 wf6000OTA升级小记

近期做了3个IOT芯片的OTA升级&#xff0c;记录下&#xff1a; 最开始做完的是ESP32,升级流程也简单&#xff0c;初始烧录到固定区&#xff0c;然后OTA升级就会在user1,user2两个区内来回升&#xff0c;升级的文件是同一个&#xff08;即同一个文件&#xff0c;先升级就是user1…

Ubuntu18.04 上 ESP8285 的 esp-at release_v2.2.0.0 编译环境搭建

1 环境搭建前提 1.1 安装编译 ESP-IDF 需要的软件包&#xff1a; sudo apt-get install git wget flex bison gperf python3 python3-pip python3-setuptools cmake ninja-build ccache libffi-dev libssl-dev dfu-util1.2 安装 Python 3.8 sudo apt-get install python3.8-…

探索ESP8285(3)通过EMQX服务器点亮一个LED灯

CCC_122&#xff1a;博客只用于学习交流&#xff0c;不涉及任何商业用途&#xff0c;如果有错误之处&#xff0c;欢迎指正。 在上一个博客的基础上 探索ESP8285&#xff08;2&#xff09;搭建Windows版MQTT服务器 我们来通过EMQX服务器点亮ESP8285模块上的LED灯。 首先查得E…

乐鑫esp8266学习rtos3.0笔记第10篇:内置仅1M的Esp8285,如何攻破最棘手的OTA问题,大大节省资源成本开发产品;

本系列博客学习由非官方人员 半颗心脏 潜心所力所写&#xff0c;仅仅做个人技术交流分享&#xff0c;不做任何商业用途。如有不对之处&#xff0c;请留言&#xff0c;本人及时更改。 1、 Esp8266之 搭建开发环境&#xff0c;开始一个“hellow world”串口打印。 2、 Esp8266之…

晶科鑫 | 国产26MHz晶振匹配Espressif(乐鑫) ESP8285/ESP8266芯片案例

【应用】国产26MHz频率晶振应用于物联网WIFI物联网模块&#xff08;串口转WiFi模块&#xff09;&#xff0c;Espressif(乐鑫) ESP8285/ESP8266芯片匹配测试OK ESP8285其实是ESP8266的升级版本&#xff0c;两者可以共用同一套SDK&#xff0c;只是ESP8285内部集成了1MB Flash&…

ESP8285烧写问题备忘

1 问题现象 ESP8285 烧写了固件&#xff0c;怎么都跑不起来&#xff0c;串口打印如下信息&#xff1a; ets Jan 8 2013,rst cause:2, boot mode:(3,7)load 0x4010f000, len 1384, room 16 tail 8 chksum 0xef csum 0xef csum err ets_main.c 2 问题原因 上乐鑫官网查了 ESP…

ESP8285 多个bin文件合并烧录

可通过两种方式烧录固件&#xff0c;一种是基于esp-idf开发时&#xff0c;中命令终端执行make flash命令烧录&#xff1b;二是使用ESPFlashDownloadTool工具。 bin文件说明 ESP8285/ESP8266的固件一般包含4个bin文件。 查看各bin文件的路径 以带OTA的固件为例&#xff0c;在…

ESP8285+WS2812+MAX9814制作的音乐律动氛围灯

该项目主要参考了立创EDA开源广场的项目&#xff1a; esp8285芯片ESP-01F模块为主控&#xff0c;MAX9814音频采集模块&#xff0c;WS2812 2020rgb灯珠&#xff0c;Arduino编程环境简单制作一个律动灯条。 因为正在学习硬件PCB&#xff0c;所以只能算是一个仿照。 硬件&#x…

探索ESP8285(2)搭建Windows版MQTT服务器

CCC_122&#xff1a;博客只用于学习交流&#xff0c;不涉及任何商业用途&#xff0c;如果有错误之处&#xff0c;欢迎指正。 MQTT服务器有多个选择&#xff0c;例如EMQX&#xff0c;Mosquitto&#xff0c;Apollo&#xff0c;以下我们选择比较简单的EMQX来搭建MQTT的服务器。 一…

峥果智能连接不到服务器,峥果浴霸 ESP8285版本 固件

ESP ZINGUO 峥果智能浴霸个人固件. 作者声明 注意: 本项目主要目的为作者本人自己学习及使用峥果智能浴霸而开发&#xff0c;本着开源精神及造福网友而开源&#xff0c;仅个人开发&#xff0c;可能无法做到完整的测试&#xff0c;所以不承担他人使用本项目照成的所有后果。 严禁…

ESP8266 简单研究 ESP8285 研究

网址&#xff1a; http://wiki.ai-thinker.com/esp8266 ESP8266 系列模组专题 概述 ESP8266 系列模组是深圳市安信可科技有限公司开发的一系列基于乐鑫ESP8266的超低功耗的UART-WiFi模块的模组&#xff0c;可以方便地进行二次开发&#xff0c;接入云端服务&#xff0c;实现…

基于RK3399ESP8285自动售货柜项目—MP08开发板端代码详解

基于RK3399&ESP8285自动售货柜项目—②MP08开发板端代码详解 本系列文章将详细讲解该基于RK3399及ESP8285自动售货柜的完整实现方法&#xff0c;从硬件连接到网络通信再到软件实现&#xff0c;本产品所用开发板为RK3399以及MP08_2019/11/03 , 如有疑问与见解&#xff0c;可…

ESP8285 ESP-AT编译流程和操作步骤

ESP8282ESP-AT编译流程和操作步骤 ESP8285 相当于ESP8266EX 1M SPI Flash ,他的编译工具和ESP-AT 都是跟ESP8266EX 一样的. 他的AT指令不能做OTA分区. 由于flash空间原因. 个人理解 配置好 esp8285 的编译工具链 setup-toolchain export PATH"$PATH:$HOME/xtensa-lx1…

Sipeed M1W内部esp8285固件烧录教程

Sipeed 的K210是真的香啊&#xff0c;但是内部的这个esp8285是做的真的不咋地。买回来之后这个8285折腾死我了&#xff0c;好几次固件出问题&#xff0c;掉固件&#xff0c;问了客户姐姐和群主“泽畔”大佬才解决&#xff0c;所以总结下。 下载固件&#xff1a; 首先我们需要先…