基于STM32+ESP8266的HLW8032智能电表超额报警设计

目录

一、项目介绍

二、实物图片

三、视频

四、原理图

五、代码

六、资料清单

资料下载地址:基于STM32的HLW8032智能电表超额报警带WIFI和APP控制

一、项目介绍

        本文基于STM32单片机的设计方案,采用HLW8032功率计量芯片对监测的电流电压信号进行测量、转换、寄存,将相关电参数传递给STM32,再利用LCD1302显示屏和WiFi两种方式进行数据可视化,可在手机APP上查看数据。本测量装置能够获取电压、电流、有功功率、视在功率、无功功率、电能用量、功率因数等电参数,具备使用简单、成本较低、APP实时查看等优点。

二、实物图片

 

三、视频

视频地址

四、原理图

五、代码

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "usart2.h"
#include "LCD1602.h"
#include "esp8266.h"

/************************************************
 ALIENTEK 战舰STM32F103开发板实验13
 TFTLCD显示实验  
 技术支持:www.openedv.com
 淘宝店铺:http://eboard.taobao.com 
 关注微信公众平台微信号:"正点原子",免费获取STM32资料。
 广州市星翼电子科技有限公司  
 作者:正点原子 @ALIENTEK
************************************************/
extern u32 Voltage_Parameter_Reg,Voltage_Reg,Current_Reg,Current_Parameter_Reg,Power_Parameter_Reg,Power_Reg;
extern u8 Data_Updata_Reg;
extern u16 PF_Reg;
float ACVotage,ACCurrent,ActivePower,ApparentPower,PowerFactor,ElectricEnergy,E_Zero=0;
u8 Pre_Data_Updata_Reg;
u16 UpdataCount;
u32 PFCount,PF_OneDegree;
u8 menu;

u8 Flag_Alarm_A;
u8 Flag_Alarm_V;
u8 uart_key = 0;
u8 key_value = 0;

float ACVotage_H = 225.0,ACCurrent_H = 5.0;
//u8 buf[5]={11,12,12,12,12};
char Dis_Str[16];
 
void Get_HLW8032(void);

void Dis_Dat(void);

void Get_HLW8032(void);
void Proc_Key(u8 cmd);
void Proc_Alarm(void);
void Send_Data(void);

int main(void)
{	 
	u8 Cnt_Ma = 100;
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	 //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //禁用SWJ
	uart_init(9600);	 	//串口初始化为115200
	uart2_init(4800);	 	//串口初始化为115200
	LCD_Init();
	KEY_Init();
 	//LED_Init();			     //LED端口初始化
	Esp8266_Init();
	Relay = 0;
	LCD_Clear();
	LCD_Write_String(0,0,"System Init...  ");
	while(Cnt_Ma)
	{
		Cnt_Ma--;
		Get_HLW8032();
		delay_ms(30);
	}
  while(1) 
	{		 

    Get_HLW8032();
		//ACVotage = 1.2;
		//ACCurrent = 2.3;
		Dis_Dat();
		KEY_Scan(0);
		Proc_Key(key_value);
		Proc_Alarm();
		Send_Data();
		//delay_ms(500);	
	} 
}

void Send_Data(void)
{
	static u8 Run_Send_Cnt = 250;
	if(Run_Send_Cnt++ > 10)
	{
		Run_Send_Cnt = 0;
		printf("AT+CIPSEND=0,39\r\n");	   发送字符长度 
		delay_ms(500);
		printf("S:%05.1f,%05.1f,%05.1f,%05.1f,%d,%d,%05.3f;\r\n",ACVotage,ACCurrent,ACVotage_H,ACCurrent_H,Flag_Alarm_V,Flag_Alarm_A,ElectricEnergy-E_Zero);
	}
}

void Proc_Alarm(void)
{
	static u16 Run_Beep_Cnt = 0;
	if(ACVotage >= ACVotage_H)
		Flag_Alarm_V = 1;
	else
		Flag_Alarm_V = 0;
	
	if(ACCurrent >= ACCurrent_H)
		Flag_Alarm_A = 1;
	else
		Flag_Alarm_A = 0;
	
	if(Flag_Alarm_A == 1 || Flag_Alarm_V == 1)
	{
		Relay = 1;
		Run_Beep_Cnt = 500;
	}
	
	if(Run_Beep_Cnt > 0)
	{
		Run_Beep_Cnt--;
		Beep = 1;
	}
	else
		Beep = 0;
}

void Proc_Key(u8 cmd)
{
	if(cmd == 0)
	{
		cmd = uart_key;
		uart_key = 0;
	}
	if(cmd == 1)
	{
		menu++;
		key_value = 0;
		if(menu >= 3)
		{
			menu = 0;
		}
		Dis_Dat();
	}
	else if(cmd == 2)
	{
		key_value = 0;
		if(menu == 1)
		{
			if(ACVotage_H < 999)
				ACVotage_H++;
		}
		else if(menu == 2)
		{
			if(ACCurrent_H < 999)
				ACCurrent_H++;
		}
		else if(menu == 0)
		{
			E_Zero = ElectricEnergy;
		}
		
		Dis_Dat();
	}
	else if(cmd == 3)
	{
		key_value = 0;
		if(menu == 1)
		{
			if(ACVotage_H > 0)
				ACVotage_H--;
		}
		else if(menu == 2)
		{
			if(ACCurrent_H > 0)
				ACCurrent_H--;
		}
		Dis_Dat();
	}
	else if(cmd == 4)
	{
		key_value = 0;
		Relay = ~Relay;
	}
}

void Dis_Dat(void)
{
	static u8 Run_Dis_Cnt = 10;
	if(Run_Dis_Cnt++ > 10)
	{
		Run_Dis_Cnt = 0;
		if(menu == 0)
		{
			//ACVotage = ACCurrent = 1.12;
			//LCD_Clear();
			sprintf(Dis_Str,"V:%3.0fV,E:%3.3f",ACVotage,ElectricEnergy-E_Zero);
			LCD_Write_String(0,0,Dis_Str);
			sprintf(Dis_Str,"Current:%5.1f A ",ACCurrent);
			LCD_Write_String(0,1,Dis_Str);
			
			
			
			
			
		}
		else if(menu == 1)
		{
			//LCD_Clear();
			sprintf(Dis_Str,"Vol_H:%5.1f V  <",ACVotage_H);
			LCD_Write_String(0,0,Dis_Str);
			sprintf(Dis_Str,"Cur_H:%5.1f A   ",ACCurrent_H);
			LCD_Write_String(0,1,Dis_Str);
		}
		else if(menu == 2)
		{
			sprintf(Dis_Str,"Vol_H:%5.1f V   ",ACVotage_H);
			LCD_Write_String(0,0,Dis_Str);
			sprintf(Dis_Str,"Cur_L:%5.1f A  <",ACCurrent_H);
			LCD_Write_String(0,1,Dis_Str);
		}
	}
}
 
void Get_HLW8032(void)
{
	static u8 x=0;
	x++;
	if(x==12)x=0;
	//LED0=!LED0;	
	ACVotage=(Voltage_Parameter_Reg*1.88/Voltage_Reg);//电压有效值
	if(ACVotage<=15)
	 ACVotage=0;
	ACCurrent=(Current_Parameter_Reg*1.0/Current_Reg)/2;//电流有效值
	if(ACCurrent<0.1)//无电压时电压又飘移
	{
		ACCurrent=0;
		ApparentPower=0;
		ActivePower=0;
		PowerFactor=0;
	}
	if(ACVotage>2&&ACCurrent>0.1)//空载时电流有飘移
	{
	
	
		ApparentPower=ACVotage*ACCurrent;//视在功率
		ActivePower=Power_Parameter_Reg*1.88/Power_Reg;//有功功率
		PowerFactor=ActivePower/ApparentPower;//功率因数
	}
	/*printf ("电压有效值:%f\r\n",ACVotage);
	printf ("电流有效值:%f\r\n",ACCurrent);
	printf ("视在功率:%f\r\n",ApparentPower);
	printf ("有功功率:%f\r\n",ActivePower);
	printf ("功率因数:%f\r\n",PowerFactor);*/
	if(Pre_Data_Updata_Reg!=(Data_Updata_Reg&0x80))
	{
		UpdataCount++;
		Pre_Data_Updata_Reg=Data_Updata_Reg&0x80;
	}
	PFCount=UpdataCount*65536+PF_Reg;//脉冲信号个数
	PF_OneDegree=1000000000/Power_Parameter_Reg;
	PF_OneDegree=PF_OneDegree*3600/1.88;//1度电对应的脉冲个数;
	ElectricEnergy=(float)PFCount/(float)PF_OneDegree;//电能
	/*printf ("电能:%f\r\n",ElectricEnergy);*/
}


六、资料清单

  • 3
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
ESP8266可以通过SPI接口与HLW8032模块进行通信,从而实现电能监测功能。 首先,需要连接ESP8266HLW8032模块的SPI接口,具体连接方式可以参考HLW8032模块的数据手册。然后,在ESP8266中使用SPI库进行SPI通信,通过发送特定的命令和读取相应的寄存器值,即可获取电能监测数据。 以下是示例代码,可以根据具体情况进行修改和调试: ``` #include <SPI.h> // 定义HLW8032模块的寄存器地址 #define HLW8032_REG_V 0x01 // 电压值寄存器地址 #define HLW8032_REG_I 0x02 // 电流值寄存器地址 #define HLW8032_REG_P 0x03 // 功率值寄存器地址 #define HLW8032_REG_ENERGY 0x04 // 电能值寄存器地址 // 定义SPI接口的引脚 #define PIN_SPI_CS 10 // CS引脚 #define PIN_SPI_CLK 14 // CLK引脚 #define PIN_SPI_MISO 12 // MISO引脚 #define PIN_SPI_MOSI 13 // MOSI引脚 void setup() { // 初始化SPI接口 pinMode(PIN_SPI_CS, OUTPUT); digitalWrite(PIN_SPI_CS, HIGH); SPI.begin(); SPI.setClockDivider(SPI_CLOCK_DIV2); // 设置时钟分频为2 } void loop() { // 读取电压值 float v = readHLW8032(HLW8032_REG_V); Serial.print("Voltage: "); Serial.print(v); Serial.print(" V"); // 读取电流值 float i = readHLW8032(HLW8032_REG_I); Serial.print("Current: "); Serial.print(i); Serial.print(" A"); // 读取功率值 float p = readHLW8032(HLW8032_REG_P); Serial.print("Power: "); Serial.print(p); Serial.print(" W"); // 读取电能值 float energy = readHLW8032(HLW8032_REG_ENERGY); Serial.print("Energy: "); Serial.print(energy); Serial.print(" Wh"); delay(1000); // 延时1秒 } // 读取HLW8032模块的寄存器值 float readHLW8032(byte reg) { digitalWrite(PIN_SPI_CS, LOW); // 选中HLW8032模块 SPI.transfer(reg); // 发送寄存器地址 byte b1 = SPI.transfer(0x00); // 读取高8位数据 byte b2 = SPI.transfer(0x00); // 读取低8位数据 digitalWrite(PIN_SPI_CS, HIGH); // 取消选中HLW8032模块 // 将读取的数据转换为浮点数 uint16_t value = (b1 << 8) | b2; return (float)value / 100.0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

森旺电子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值