当前位置: 首页 > news >正文

基于ESP32-C3驱动BL0942电参数采集模块Arduino代码

 

1.全部代码

// ESP32-C3 UART1 配置
#define UART1_RX_PIN 4  //接BL0942模块的T引脚
#define UART1_TX_PIN 3  //接BL0942模块的R引脚
#define BAUDRATE 9600   //波特率9600#define MAX_C 10 //BL0942模块电流最大值,购买10A的这里写10;购买其他规格的写20或者30都可以
//#define MAX_C 20 // 定时器设置
unsigned long previousMillis = 0;//用来记录当前系统时间,用于计算延时
const long interval = 1000;  // 1秒间隔char datatosend[2]={0x58,0xAA};//发送读取BL0942数据包指令
int uart_time=0,uart_flag=0;//串口接收超时和接收完成标志// 串口缓冲区
uint8_t rxBuffer[256];//用于接收串口1的数据
int bufferIndex = 0;//用于标记接收串口1的数据长度// 硬件串口实例
HardwareSerial SerialPort(1);  // UART1void setup() 
{// 初始化调试串口0(Serial0 - 默认引脚)用于输出解析后的电参数数据Serial.begin(9600);// 初始化UART1-连接BL0942模块,读取原始电参数数据
  SerialPort.begin(BAUDRATE, SERIAL_8N1, UART1_RX_PIN, UART1_TX_PIN);// 设置串口1中断回调函数
  SerialPort.onReceive(serial1ReceiveCallback);//串口打印数据Serial.println("ESP32-C3 UART1 Receiver BL0942");}void loop() 
{// 定时发送处理unsigned long currentMillis = millis();if (currentMillis - previousMillis >= interval)//间隔1秒读取一次电参数数据
  {previousMillis = currentMillis;SerialPort.write(datatosend,2);//发送读取指令给BL0942模块
  }// 处理接收到的数据if(uart_flag){processReceivedData();uart_flag=0;}}// 串口1接收中断回调函数
void serial1ReceiveCallback() 
{while (SerialPort.available()) //判断串口1缓存区是否有数据
  {uint8_t receivedByte = SerialPort.read();//读出1个字节数据if(bufferIndex==0&&receivedByte!=0x55)//判断第一个数据是否为0x55
    {continue;//等待正确的帧头
    }if (bufferIndex < sizeof(rxBuffer) - 1)//检查数据有没有超出数组,防止溢出
    {rxBuffer[bufferIndex++] = receivedByte;//把数据存入rxBuffer
    } else {// 缓冲区满,丢弃最旧的数据(简单处理)bufferIndex = 0;}if(bufferIndex>=23)//收到23个字节后,标记接收完成
    {uart_flag=1;}}
}// 处理接收到的数据并把结果转发到串口0
void processReceivedData() 
{char str[100];uint8_t i=0,check_num=0;uint32_t count=88;uint32_t V_REG=0,P_REG=0,PF_COUNT=0;int32_t C_REG=0;double V1=0,C1=0,P1=0,P2=0,P3=0,E_con=0;// 在串口0显示原始数据Serial.print("Received: ");// 以十六进制和ASCII格式显示for (i = 0; i < bufferIndex; i++) {if (rxBuffer[i] < 0x10) Serial.print("0"); // 前导零
    Serial.print(rxBuffer[i], HEX);Serial.print(" ");}Serial.print("\r\n");//串口0打印BL0942的原始数据for(i=0;i<22;i++)//求和,用来计算校验码
  {count = count + rxBuffer[i];}check_num=~(count&0xFF);//取最后一个字节,然后按位取反if(check_num==rxBuffer[22])//校验数据是正确
    {//printf("Check_OK\r\n");C_REG=rxBuffer[3]*65536+rxBuffer[2]*256+rxBuffer[1];//计算电流寄存器if(MAX_C==10)//电流最大值模块类型,你购买的是10A还是20A模块
        {C1=C_REG*1.218/(305978*3);//计算有效电流
        }else{C1=C_REG*1.218/(305978);//计算有效电流
        }V_REG=rxBuffer[6]*65536+rxBuffer[5]*256+rxBuffer[4];//计算电压寄存器V1=V_REG*1.218*1950.51/37734390;//计算有效电压
        P2=V1*C1;//P2为视在功率,视在功率=有效电压*有效电流
        P_REG=rxBuffer[14]*65536+rxBuffer[13]*256+rxBuffer[12];//计算有功功率寄存器if(rxBuffer[14]&0x80)//高字节的最高位如果为1,说明有功功率为负数,如果不做处理可能会出现很大很大的数值
        {P_REG=-(16777216-P_REG);}if(MAX_C==10)//电流最大值模块类型,你购买的是10A还是20A模块
        {P1=P_REG*1.218*1.218*1950.51/5411610;//计算有功功率/
        }else{P1=P_REG*1.218*1.218*1950.51/1803870;//计算有功功率
        }if(P2!=0)P3=P1/P2;//计算功率因数;功率因数=有功功率/视在功率
        PF_COUNT=rxBuffer[15]*65536+rxBuffer[14]*256+rxBuffer[13];//计算已用电量脉冲数if(MAX_C==10)//电流最大值模块类型,你购买的是10A还是20A模块
        {E_con=PF_COUNT/16051.896;//计算已用电量,16051.896为固定值,和选购的量程有关
        }else{E_con=PF_COUNT/5350.632;//计算已用电量,5350.632为固定值,和选购的量程有关
        }sprintf(str,"C=%0.3fA;V=%0.2fV;P1=%0.2fW;P2=%0.2fW;P3=%0.1f;E_con=%0.4fkWh\r\n",C1,V1,P1,P2,P3,E_con);Serial.print(str);}else{Serial.print("Check Error\r\n");//校验数据有误,校验数据出错
    }bufferIndex = 0;
}

注意芯片需要选择ESP32C3;代码实测编译可用,如编译报错,可能是软件设置不对,建议百度一下报错原因。

2.硬件接线说明

ESP32C3模块BL0942模块
3.3 3V3
4 T
3 R
G G

image

购买ESP32-C3supermini模块的要注意购买带有内置flash的,部分商家卖的不带flash需要外接flash才能使用。

image

image

image

购买BL0942模块需要看最大电流,需要修改代码开头的#define MAX_C 10宏定义;默认的是10A的规格;一般来说10A最大功率是2200W,一般用电器基本都可以了。

image

 10A和20A模块硬件上区别只有采样电阻阻值大小的区别,其他都一样的。10A的采样电阻阻值是3毫欧,电阻丝印R003;20A的采样电阻阻值是1毫欧(实际测量最大电流是30A),电阻丝印R001;

image

 

 3.烧录测试

烧录完成后,打开串口监听就能看到输出数据了。Received是BL0942模块返回的原始数据,C是有效电流,V是有效电压,P1是有功功率,P2是视在功率,P3是功率因数,E_con是已用电量。

image

 BL0942模块不需要接220V交流电也会输出数据的,只不过数据都是0。

4.代码讲解

 

image

image

 

image

 

image

image

 原始数据对应的格式:

810db46fb2d7ec5cb8b56979b1f6dbd3

 

 校验码:

103-109行是校验计算比对,我们看一下BL0942手册对校验码的公式:

也就是把前面22个字节相加然后加上0x58;接着&0xFF(取最后一个字节),然后按位取反就得出校验码了。代码里面count在定义的时候赋值是88,也就是16进制的0x58。代码中‘~’就是按位取反的作用。

有效电流:

112-120行是计算有效电流的过程,下图是BL0942应用指南手册的计算公式说明;

 

 

电流有效值寄存器值就是返回的数据包里面的第1,2,3字节;RL就是采样电阻的阻值;

所以10A量程的电流=寄存器值*1.218/(305978*0.003*1000);简化一下就是代码里面的公式了

20A量程的电流=寄存器值*1.218/(305978*0.001*1000);简化一下就是代码里面的公式了

有效电压:

122-125行是有效电压和视在功率的计算;手册上的公式如下:

10A和20A规格的模块在电压采样使用的阻值是一样的,所以计算公式是一样的。

根据手册提供的公式可以推导出有效电压的计算公式为:

视在功率:

视在功率=有效电压x有效电流;这个是直接计算的,和数据包数据没有直接关联。

有功功率:

127-141行是有功功率和功率因数计算;

注意:有功功率寄存器是有符号的,需要考虑负数的情况,不然会出现超级大功率数值的情况!!

 

在手册上的有功功率计算公式为:

转换一下得到10A的计算公式:

20A的计算公式:

功率因数:

功率因数=有功功率/视在功率;这个是直接计算的,和数据包数据没有直接关联。

用电量:

 

143-151行是用电量计算,下图为手册提供的公式:

这个公式是每一个脉冲对应的用电量;把Vref和R1,R2,RL代入公式计算:

20A每个电能脉冲对应电量=1213675716105.732 / 6493932000000000 = 0.0001868938=1/5350.632;

同理,10A的公式:


http://www.jsqmd.com/news/53625/

相关文章:

  • 氮气压缩机厂家哪家好?2025天然气压缩机源头工厂实力榜
  • 2025年本地人推荐的火锅品牌口碑排行榜TOP10,特色美食/美食/火锅/火锅店/重庆火锅/老火锅/川渝火锅火锅品牌排行
  • 闭眼入不翻车!荷兰蔻帝、立邦这些艺术涂料,形象质感双在线,提升家的档次
  • 2025年2.0mm人工湖用防渗土工膜/光面防渗土工膜环保材料推荐榜
  • 2025年11月铝箔袋厂家推荐列表:知名企业对比与用户口碑评价
  • 2025年苏州婚礼策划机构权威推荐榜单:目的婚礼‌/草坪婚礼‌/西式婚礼源头机构精选
  • Mutual妙趣艺增长飞轮是什么?解码文娱IP资产化的三位一体创新引擎
  • 2025年汽车隔热棉供货厂家权威推荐榜单:隔热泡棉‌/隔热海绵‌/隔音棉源头厂家精选
  • python笔记-小整数
  • ESPIDF在VScode内打不开SDKconfig解决办法
  • 扫描线+图论优化学习笔记
  • 2025年耐用的集束电缆/矿物质防火电缆厂家最新用户好评榜
  • 2025年优质的淋浴房配件厂家最新热销排行
  • 重点高中退休教师授课培训机构,2025年高中培训机构权威评估指南
  • 番茄工作法计时器:专注力与效率的简洁管理工具
  • 2025精密塑胶模具厂家测评大盘点
  • 2025数控加工中心机床厂家实力榜单
  • 2025艺术涂料加盟必看!荷兰蔻帝帮扶政策封神,万元补贴+3公里独家保护
  • 世界时间仪表盘:一站式全球时间管理解决方案
  • 2025比较好的英国留学中介
  • 2025权威榜单:进口艺术涂料品牌全攻略,这些品牌获欧盟SGS认证,南方回南天也不怕!
  • 2025年口碑好的养殖温室大棚厂家最新推荐排行榜
  • 2025年11月真空袋厂家推荐榜单:知名企业列表与选择指南
  • 墙面翻新别瞎选!2025涂料十大品牌权威榜,荷兰蔻帝防霉抗污封神
  • TabControl的bug
  • 信创背景下, DevOps体系中制品库的全生命周期安全管控
  • 2025隔音降噪厂家与隔音房厂家实力榜单
  • 2025年11月真空袋厂家推荐:全面评测数据与实用决策参考
  • 如何选择优质护手霜?2025十大精选护手霜品牌深度解析!强效滋润修复呵护手部肌肤
  • 2025年评价高的阶梯式养鸡设备热门厂家推荐榜单