国产芯片WiFi物联网智能插座—电耗采集功能设计
目錄
1、硬件設計
2、軟件設計
WiFi物聯網智能插座的電耗采集依托于合力為的HLW8110計量芯片實現,選取它的主要原因是精度不錯,價格美麗,并且可以通過串口驅動,使用便捷。
1、硬件設計
HLW8110是一款高精度的電能計量 IC,它采用 CMOS 制造工藝,主要用于單相計量應用。它能夠測量線電壓和電流,并能計算有功功率,視在功率和功率因素。該器件內部集成了二個∑-Δ型 ADC 和一個高精度的電能計量內核。輸入通道支持靈活的 PGA 設置,因此 HLW8110 適合與不同類型的傳感器使用,如電流互感器(CT)和低阻值分流器。
HLW8110 電能計量 IC 采用 3.3V 或 5.0V 電源供電,內置 3.579M 振蕩器,可以通過 UART 口進行數據通訊,波特率為 9600bps。
HLW8110的典型電路,外圍電路簡單,外圍器件非常少,單路通道可用于檢測負載設備的功率、電壓、電流和用電量,通過 UART 或接口傳輸數據至 MCU,HLW8110 內部可以設置功率過載、電壓過載和電流過載閥值,通過內部寄存器可以查詢,并可以檢測電壓過零點。
官方測試,使用采樣電阻或者互感器的理論數據誤差如下所示:
在使用之前先簡單設計一塊Demo板進行調測,實物模塊如下所示:
原理圖、PCB如下所示:
2、軟件設計
由于代碼量較多,部分配置代碼不再贅述,僅僅展示核心算法代碼。
讀取通道電流,實現代碼如下所示:
void Read_HLW8110_IA(void)
{ float a;Uart_Read_HLW8110_Reg(REG_RMSIA_ADDR,3);delay_ms(10);if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) ){U32_RMSIA_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]); printf("A通道電流寄存器:%lx\n " ,U32_RMSIA_RegData);}else{printf("A通道電流寄存器讀取出錯\r\n");B_Read_Error = 1;}//A通道電流PGA = 16,電壓通道PGA = 1;電流采樣電阻1mR,電壓采樣電阻1M//計算公式,U16_AC_I = (U32_RMSIA_RegData * U16_RMSIAC_RegData)/(電流系數* 2^23)if ((U32_RMSIA_RegData & 0x800000) == 0x800000){F_AC_I = 0;}else{a = (float)U32_RMSIA_RegData;a = a * U16_RMSIAC_RegData;a = a/0x800000; //電流計算出來的浮點數單位是mA,比如5003.12 a = a/1; // 1 = 電流系數a = a/1000; //a= 5003ma,a/1000 = 5.003A,單位轉換成Aa = a * D_CAL_A_I; //D_CAL_A_I是校正系數,默認是1F_AC_I = a;}
}
讀取通道電壓,實現代碼如下所示:
void Read_HLW8110_U(void)
{float a;Uart_Read_HLW8110_Reg(REG_RMSU_ADDR,3);delay_ms(10);if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) ){U32_RMSU_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);printf("電壓通道寄存器:%lx\n " ,U32_RMSU_RegData);}else{printf("電壓通道寄存器讀取出錯\r\n");B_Read_Error = 1;}//電壓//計算:U16_AC_V = (U32_RMSU_RegData * U16_RMSUC_RegData)/2^23if ((U32_RMSU_RegData &0x800000) == 0x800000){F_AC_V = 0;}else{a = (float)U32_RMSU_RegData;a = a*U16_RMSUC_RegData; a = a/0x400000; a = a/1; // 1 = 電壓系數a = a/100; //計算出a = 22083.12mV,a/100表示220.8312V,電壓轉換成Va = a*D_CAL_U; //D_CAL_U是校正系數,默認是1, F_AC_V = a;}
}
讀取通道功率,實現代碼如下所示:
void Read_HLW8110_PA(void)
{float a;float b;Uart_Read_HLW8110_Reg(REG_POWER_PA_ADDR,4);delay_ms(10);if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) ){U32_POWERPA_RegData = (unsigned long)(u8_RxBuf[0]<<24) + (unsigned long)(u8_RxBuf[1]<<16) + (unsigned long)(u8_RxBuf[2]<<8) + (unsigned long)(u8_RxBuf[3]);printf("A通道功率寄存器:%lx\n " ,U32_POWERPA_RegData);}else{printf("A通道功率寄存器讀取出錯\r\n");B_Read_Error = 1;}if (U32_POWERPA_RegData > 0x80000000){b = ~U32_POWERPA_RegData;a = (float)b;}elsea = (float)U32_POWERPA_RegData;//功率需要分正功和負功//計算,U16_AC_P = (U32_POWERPA_RegData * U16_PowerPAC_RegData)/(2^31*電壓系數*電流系數)//單位為W,比如算出來5000.123,表示5000.123Wa = a*U16_PowerPAC_RegData;a = a/0x80000000; a = a/1; // 1 = 電流系數a = a/1; // 1 = 電壓系數a = a * D_CAL_A_P; //D_CAL_A_P是校正系數,默認是1F_AC_P = a; //單位為W,比如算出來5000.123,表示5000.123W
}
讀取通道有功電量,實現代碼如下所示:
void Read_HLW8110_EA(void)
{float a;Uart_Read_HLW8110_Reg(REG_ENERGY_PA_ADDR,3); delay_ms(10);if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) ){U32_ENERGY_PA_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);printf("A通道有功電量寄存器:%lx\n " ,U32_ENERGY_PA_RegData);}else{printf("A通道有功電量寄存器讀取出錯\r\n");B_Read_Error = 1;}Uart_Read_HLW8110_Reg(REG_HFCONST_ADDR,2); delay_ms(10);if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) ){U16_HFConst_RegData = (unsigned int)(u8_RxBuf[0]<<8) + (unsigned int)(u8_RxBuf[1]);printf("HFCONST常數 = :%d\n " ,U16_HFConst_RegData);}else{printf("HFCONST常數寄存器讀取出錯\r\n");B_Read_Error = 1;}//電量計算,電量 = (U32_ENERGY_PA_RegData * U16_EnergyAC_RegData * HFCONST) /(K1*K2 * 2^29 * 4096)//HFCONST:默認值是0x1000, HFCONST/(2^29 * 4096) = 0x20000000a = (float)U32_ENERGY_PA_RegData; a = a*U16_EnergyAC_RegData;a = a/0x20000000; //電量單位是0.001KWH,比如算出來是2.002,表示2.002KWH a = a/1; // 1 = 電流系數a = a/1; // 1 = 電壓系數a = a * D_CAL_A_E; //D_CAL_A_E是校正系數,默認是1F_AC_E = a;F_AC_BACKUP_E = F_AC_E;
}
讀取通道的線性頻率,實現代碼如下所示:
void Read_HLW8110_LineFreq(void)
{float a;unsigned long b;Uart_Read_HLW8110_Reg(REG_UFREQ_ADDR,2);delay_ms(10);if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) ){b = (unsigned long)(u8_RxBuf[0]<<8) + (unsigned long)(u8_RxBuf[1]);printf("A通道線性頻率寄存器:%ld\n " ,b);}else{printf("A通道線性頻率寄存器讀取出錯\r\n");B_Read_Error = 1;}a = (float)b;a = 3579545/(8*a); F_AC_LINE_Freq = a;
}
讀取通道功率因素,實現代碼如下所示:
void Read_HLW8110_PF(void)
{float a;unsigned long b;//測量A通道的功率因素,需要發送EA+5A命令
//測量B通道的功率因素,需要發送EA+A5命令 Uart_Read_HLW8110_Reg(REG_PF_ADDR,3);delay_ms(10);if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) ){b = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);printf("A通道功率因素寄存器:%ld\n " ,b);}else{printf("讀取A通道功率因素寄存器出錯\r\n");B_Read_Error = 1;}if (b>0x800000) //為負,容性負載{a = (float)(0xffffff-b + 1)/0x7fffff;}else{a = (float)b/0x7fffff;}if (F_AC_P < 0.3) // 小于0.3W,空載或小功率,PF不準a = 0; //功率因素*100,最大為100,最小負100F_AC_PF = a;
}
讀取通道相位角,實現代碼如下所示:
void Read_HLW8110_Angle(void)
{float a; unsigned long b;Uart_Read_HLW8110_Reg(REG_ANGLE_ADDR,2);delay_ms(10);if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) ){b =(unsigned long)(u8_RxBuf[0]<<8) + (unsigned long)(u8_RxBuf[1]);printf("A通道線相角寄存器:%ld\n " ,b);}else{printf("A通道線相角寄存器出錯\r\n");B_Read_Error = 1;}if ( F_AC_PF < 55) //線性頻率50HZ{a = b;a = a * 0.0805;F_Angle = a;}else{//線性頻率60HZa = b;a = a * 0.0965;F_Angle = a;}if (F_AC_P < 0.5) //功率小于0.5時,說明沒有負載,相角為0{F_Angle = 0;}if (F_Angle < 90){a = F_Angle;printf("電流超前電壓:%f\n " ,a);}else if (F_Angle < 180){a = 180-F_Angle;printf("電流滯后電壓:%f\n " ,a); }else if (F_Angle < 360){a = 360 - F_Angle;printf("電流滯后電壓:%f\n " ,a); }else{a = F_Angle -360;printf("電流超前電壓:%f\n " ,a); }
}
?
總結
以上是生活随笔為你收集整理的国产芯片WiFi物联网智能插座—电耗采集功能设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 力扣(LeetCode)刷题,简单+中等
- 下一篇: 首款微控制器级树莓派 Pico,超廉价只