简介

STM32单片机、交流电压电流检测模块电路、WIFI模块电路组成。通过电压互感器TV1005M和电流互感器TA1005M分别检测交流电压和交流电流值,手机APP和WiFi模块互联后,可以实时显示交流电压、交流电流、功率和电量实时显示在手机上。当功率超过200W时,继电器自动断开。功率不超过200W时,可以手动控制继电器的开关。手机和WiFi模块连接后,手机上显示计时时间。

设计背景及其意义

交流电与人们的生活紧密联系,不论是学习、工作还是娱乐都离不开交流电。电网电压在使用中会因为各种突变引起电压电流突变。有时大的电压变化可能损坏用电设备,特别是在工厂出现这种情况将会造成巨大的经济损失。因此能够实时显示电网电压和用电电流并能把数值上传到上位机进行集中监控的电压电流仪表具有重要意义。

交流数字电压电流表是采用数字化测量技术,把连续的模拟量(交流输入电压)转换成不连续、离散的数字形式并加以显示的仪表。传统的指针式电压表功能单一、精度低,不能满足数字化时代的需求,采用单片机的数字电压表,精度高、抗干扰能力强,可扩展性强、集成方便,还可与PC进行实时通信。目前,由各种单片A/D 转换器构成的数字电压表,已被广泛用于电子及电工测量、工业自动化仪表、自动测试系统等智能化测量领域,显示出强大的生命力。

方案的设计

由STM32单片机核心板电路+交流电压电流检测模块电路+WIFI模块电路+指示灯电路组成。

控制方式的选择

选择STM32单片机,STM32系列处理器是意法半导体ST公司生产的一种基于ARM 7架构的32位、支持实时仿真和跟踪的微控制器。使用ARM最新的、先进架构的Cortex-M3内核,具有优异的实时性能、杰出的功耗控制、出众及创新的外设,并且最大程度的集成整合,十分易于开发,可使产品快速将进入市场。

无线遥控模块的选择

使用WIFI模块进行本系统数据的无线传输。Wi-Fi是一种可以将个人电脑、手持设备(如PDA、手机)等终端以无线方式互相连接的技术。Wi-Fi是一个无线网路通信技术的品牌,由Wi-Fi联盟(Wi-Fi Alliance)所持有。目的是改善基于IEEE 802.11标准的无线网路产品之间的互通性。Wi-Fi主要是用于替代工作场所一般局域网接入中使用的高速线缆的。这类应用有时也称作无线局域网(WLAN)。其覆盖性强,传输距离远。

硬件电路的设计

系统的功能分析及体系结构设计

  • 1、通过电压互感器TV1005M和电流互感器TA1005M分别检测交流电压和交流电流值,
  • 2、手机APP和WiFi模块互联后,可以实时显示交流电压、交流电流、功率和电量实时显示在手机上。
  • 3、当功率超过200W时,继电器自动断开。功率不超过200W时,可以手动控制继电器的开关。
  • 4、手机和WiFi模块连接后,手机上显示计时时间。

  • 名称:LYY520

  • IP及端口号:10.10.10.11:8080

接收内容

V:123A:12345P:1234567Q:1234567.89T:123R:1

说明:(只增加R部分命令及发送内容,其他未变动)

  • V:123 表示123V交流电压 字符5个长度不变 如12V 表示V:012
  • A:12345 表示12.345A交流电流
  • P:1234567 表示1234.567W 瞬时功率 即缩小1000倍
  • Q:1234567.89 表示1.23456789 度 缩小1000000倍 因为度的单位比较大kwh
  • T:1234 表示1234S 单片机设备运行时间
  • R:1 表示继电器接通 供电中 0表示断开即过载

发送内容:_或者# #断开供电 _接通供电。

系统总体结构

模块电路的设计

ESP8266WIFI模块电路设计电路设计

串口WIFI模块是新一代嵌入式WiFi模块,体积小,功耗低。采用UART接口。串口wifi模块是基于通用串行接口特性,符合IEEE802.11 协议栈网络标准,内置TCP/IP协议栈,使传统串口设备更好的加入无线网络。

ESP8266是一款超低功耗的模块,拥有业内极富竞争力的封装尺寸和超低能耗技术,专为移动设备和互联网的应用设计,可将用户的物理设备连接到WIFI无线网络上,进行互联网或局域网通信,实现联网功能。

ESP8266可广泛应用于智能电网、智能交通、智能家具、手持设备、工业控制等领域。WiFi模块电路图如下图所示。

WIFI模块实物图

TV、TA-1005-1M交流电压电流互感器模块电路设计

交流电流互感器模块型号为TV1005-1M。本交流电流互感器模块型号为TA1005M。

电压感器介绍

  • 电压互感器和变压器类似,是用来变换线路上的电压的仪器。电压互感器变换电压的目的,主要是用来给测量仪表和继电保护装置供电,用来测量线路的电压、功率和电能,或者用来在线路发生故障时保护线路中的贵重设备、电机和变压器,因此电压互感器的容量很小,一般都只有几伏安、几十伏安,最大也不超过一千伏安。特点是容量很小且比较恒定,正常运行时接近于空载状态
  • 它也有两个绕组,一个叫一次绕组,一个叫二次绕组。两个绕组都装在或绕在铁心上。两个绕组之间以及绕组与铁心之间都有绝缘,使两个绕组之间以及绕组与铁心之间都有电气隔离。电压互感器在运行时,一次绕组N1并联接在线路上,二次绕组N2并联接仪表或继电器。因此在测量高压线路上的电压时,尽管一次电压很高,但二次却是低压的,可以确保操作人员和仪表的安全。
  • 电压互感器本身的阻抗很小,一旦副边发生短路,电流将急剧增长而烧毁线圈。因此,电压互感器的原边接有熔断器,副边可靠接地,以免原、副边绝缘损毁时,副边出现对地高电位而造成人身和设备事故。
  • 线路上为什么需要变换电压呢?这是因为根据发电、输电和用电的不同情况,线路上的电压大小不一,而且相差悬殊,有的是低压220V和380V,有的是高压几万伏甚至几十万伏。要直接测量这些低压和高压电压,就需要根据线路电压的大小,制作相应的低压和高压的电压表和其他仪表和继电器。这样不仅会给仪表制作带来很大困难,而且更主要的是,要直接制作高压仪表,直接在高压线路上测量电压,那是不可能的,而且也是绝对不允许的。

模块特点

  • (1)体积小,精度高;印刷线路板直接焊接安装,使用方便,外形美观。
  • (2)全封闭,机械和耐环境性能好,电压隔离能力强,安全可靠。

使用环境条件

  • (1)环境温度:-55℃~+85℃;
  • (2)相对湿度:温度为40℃时不大于90%;
  • (3)大气压力:860~1060mbar(约为650~800mmHg)。

工作频率范围:20Hz~20kHz。

绝缘耐热等级:F级(155℃)。

安全特性

  • (1)绝缘电阻:常态时大于1000MΩ;
  • (2)抗电强度:可承受工频2000V50Hz /1分钟;
  • (3)阻燃性:符合UL94-Vo级。

输入电压:≤1000Vac

电流互感器介绍

  • 电电流互感器是依据电磁感应原理将一次侧大电流转换成二次侧小电流来测量的仪器。电流互感器是由闭合的铁心和绕组组成。它的一次侧绕组匝数很少,串在需要测量的电流的线路中。
  • 因此它经常有线路的全部电流流过,二次侧绕组匝数比较多,串接在测量仪表和保护回路中,电流互感器在工作时,它的二次侧回路始终是闭合的,因此测量仪表和保护回路串联线圈的阻抗很小,电流互感器的工作状态接近短路。电流互感器是把一次侧大电流转换成二次侧小电流来测量 ,二次侧不可开路。
  • 在发电、变电、输电、配电和用电的线路中电流大小悬殊,从几安到几万安都有。为便于测量、保护和控制需要转换为比较统一的电流,另外线路上的电压一般都比较高如直接测量是非常危险的。电流互感器就起到电流变换和电气隔离作用。
  • 电流互感器与变压器类似也是根据电磁感应原理工作,变压器变换的是电压而电流互感器变换的是电流罢了。电流互感器接被测电流的绕组(匝数为N1),称为一次绕组(或原边绕组、初级绕组);接测量仪表的绕组(匝数为N2)称为二次绕组(或副边绕组、次级绕组)。
  • 电流互感器一次绕组电流I1与二次绕组I2的电流比,叫实际电流比K。电流互感器在额定电流下工作时的电流比叫电流互感器额定电流比,用Kn表示。
  • Kn=I1n/I2n电流互感器(Current transformer 简称CT)的作用是可以把数值较大的一次电流通过一定的变比转换为数值较小的二次电流,用来进行保护、测量等用途。如变比为400/5的电流互感器,可以把实际为400A的电流转变为5A的电流。
  • 使用交流电流互感器将交流电流转换成0-5V的直流电源电压,单片机进行A/D转换后得到数字量,经计算后得出实际的交流电流。TA1005M可以检测最大交流电流为5A,其体积小,精度很高,电压隔离强,安全。电流互感器是由闭合的铁心和绕组组成。其主要靠电磁感应原理实现对电流信号的检测的。

特点

  • (1)输入线圈为内置式,印刷线路板直接焊接安装,外形美观;
  • (2)体积小,精度高;全封闭,机械和耐环境性好,电压隔离能力强、安全可靠。

使用环境条件

  • (1)环境温度:-55℃~+85℃;
  • (2)相对湿度:温度为40℃时不大于90%;
  • (3)大气压力:860~1060mbar(约为650~800mmHg)。

工作频率范围:20Hz~20kHz。

绝缘耐热等级:F级(155℃)。

安全特性

  • (1)绝缘电阻:常态时大于1000MΩ;
  • (2)抗电强度:可承受工频2000V50Hz /1分钟;
  • (3)阻燃性:符合UL94-Vo级。

最大检测电流:5A。

本交流电压电流互感器模块通过交流电压互感器和交流电流互感器来检测交流电压和交流电流值,以及通过5V继电器电路来负责是否切断。交流电压互感器型号为TV1005M,交流电流互感器型号为TA1005M。

交流电压电流互感器模块内部具体原理图如下图所示。R1为限流电阻,D1、D2为二极管,单向导电。电容均为滤波作用,让信号更加平稳。R2、R3为分压电阻,用来将采集的模拟信号转化为电压信号。LED2为电源指示灯,R6为限流电阻,保护LED灯。J1为220V交流电输入接口。J2为负载输入接口。RL1为5V继电器,在本电路设计中由于单片机引脚的电流驱动能力太小,不足以驱动继电器的通断。所以使9012三极管作为驱动元件驱动继电器。1N4007二极管,当继电器闭合或者断开瞬间会产生反向感应电动势,损害三极管,通过1N4007将反向电动势消除以保护三极管。LED1为继电器是否闭合指示灯,如果继电器闭合,则指示灯亮,否则,指示灯不亮,R4为限流电阻,保护二极管LED1。R5为限流电阻,保护三极管,当控制引脚RY1为高电平时,继电器闭合,否则,继电器不闭合。

交流电压电流互感器模块

交流电压电流互感器模块实物图

系统软件设计

程序流程图

原理图

Code

main.c

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "lcd.h"
#include "adc.h"
#include <stdio.h>
#include "timer.h"

//char tabDataV[5];//打印电压数组
//char tabDataA[7];//打印电流数组
//char tabDataP[9];//打印功率数组
//char tabDataQ[12];//打印电量数组
//char tabDataT[6];//打印时间数组
char tabData[42];//打印时间数组

unsigned int ACcurrent;        //市电电流
unsigned int ACvolt;        //市电电压
unsigned long PowerWt=0;//功率
float PowerQd=0;//功率
unsigned char relayFlag=1;
int main(void)
 { 
    u16 adcx;
    float temp;
    delay_init();             //延时函数初始化      
    uart_init(9600);         //串口初始化为115200
    TIM3_Int_Init(499,7199);//50ms       
    LED_Init();                  //初始化与LED连接的硬件接口
    LED0=0;
    Adc_Init();                  //ADC初始化        

    RELAY=1; //继电器打开
    relayFlag=1;    //继电器状态标识
    delay_ms(4000); 

    printf("AT+CIPMUX=1\r\n");           //允许链接
    delay_ms(1000);
    printf("AT+CIPSERVER=1,8080\r\n");       //创建端口号8080
    delay_ms(1000); 
    while(1)
    {
        adcx=Get_Adc_Average(ADC_Channel_1,10);// PA1 交流电压检测口 ad转换10次求平均值
        temp=(float)adcx*(3.3/4096);
        ACvolt=(unsigned int)(temp*303);//*303 互感器计算获取 以及1K电阻 用示波器检测校准得到
        if(ACvolt<15) ACvolt=0;

        adcx=Get_Adc_Average(ADC_Channel_2,10);    // PA2                                                       求平均值
        temp=(float)adcx*(3.3/4096);
        if(temp>0.02)
        {
            ACcurrent=(unsigned int)((temp-0.02)*3100);//*3950 互感器计算获取扩大1000倍 以及1K电阻 用示波器检测校准得到 0.02去除波动 防止误判断
        }
        else
        {
                ACcurrent=0;
        }
        if(ACcurrent<50)ACcurrent=0;//滤除电流
        PowerWt=ACvolt*ACcurrent;         //功率

        if(dealFlag==1)//处理标志
        {
            dealFlag=0;
            PowerQd=(float)PowerWt*1/60.0/60.0+PowerQd;    //累计电量 1表示1s 因为电流扩大了1000倍 因此该处也扩大了1000倍 且此处功率单位为W 除以1000为千瓦 结果为度 1度=1千瓦时
        }

        if(times>=9999)
        {times=0;}

        if(PowerWt/1000>200)
        {    
            RELAY=0;            //关闭继电器
            relayFlag=0;
        }        

        sprintf(tabData,"V:%03dA:%05dP:%07luQ:%010.2fT:%04dR:1",ACvolt,ACcurrent,PowerWt,PowerQd,times);        
//        sprintf(tabDataA,"A:%05d",ACcurrent);//电流
//        sprintf(tabDataP,"P:%07lu",PowerWt);//功率
//        sprintf(tabDataQ,"Q:%010.2f",PowerQd);//电量            
//        sprintf(tabDataT,"T:%04d",times);//时间
        if(relayFlag==1)
        {sprintf(tabData,"V:%03dA:%05dP:%07luQ:%010.2fT:%04dR:1",ACvolt,ACcurrent,PowerWt,PowerQd,times);        }//打印数据
        else 
        {sprintf(tabData,"V:%03dA:%05dP:%07luQ:%010.2fT:%04dR:0",ACvolt,ACcurrent,PowerWt,PowerQd,times);        }//打印数据


        printf("AT+CIPSEND=0,42\r\n");        //发送固定字节数据的at命令
        delay_ms(200);
        printf(tabData);                    //发送数据
        delay_ms(200);

        LED0=!LED0;        //数据发送    
        delay_ms(200);        //延时
    }                                                
}

adc.c

 #include "adc.h"
 #include "delay.h" 

//初始化ADC
//这里我们仅以规则通道为例
//我们默认将开启通道0~3                                                                       
void  Adc_Init(void)
{     
    ADC_InitTypeDef ADC_InitStructure; 
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1    , ENABLE );      //使能ADC1通道时钟


    RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M

    //PA1 作为模拟通道输入引脚                         
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;        //模拟输入引脚
    GPIO_Init(GPIOA, &GPIO_InitStructure);    

    ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值

    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;    //ADC工作模式:ADC1和ADC2工作在独立模式
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;    //模数转换工作在单通道模式
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;    //模数转换工作在单次转换模式
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;    //转换由软件而不是外部触发启动
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;    //ADC数据右对齐
    ADC_InitStructure.ADC_NbrOfChannel = 1;    //顺序进行规则转换的ADC通道的数目
    ADC_Init(ADC1, &ADC_InitStructure);    //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   


    ADC_Cmd(ADC1, ENABLE);    //使能指定的ADC1

    ADC_ResetCalibration(ADC1);    //使能复位校准  

    while(ADC_GetResetCalibrationStatus(ADC1));    //等待复位校准结束

    ADC_StartCalibration(ADC1);     //开启AD校准

    while(ADC_GetCalibrationStatus(ADC1));     //等待校准结束

//    ADC_SoftwareStartConvCmd(ADC1, ENABLE);        //使能指定的ADC1的软件转换启动功能

}                  
//获得ADC值
//ch:通道值 0~3
u16 Get_Adc(u8 ch)   
{
      //设置指定ADC的规则组通道,一个序列,采样时间
    ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );    //ADC1,ADC通道,采样时间为239.5周期                      

    ADC_SoftwareStartConvCmd(ADC1, ENABLE);        //使能指定的ADC1的软件转换启动功能    

    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束

    return ADC_GetConversionValue(ADC1);    //返回最近一次ADC1规则组的转换结果
}

u16 Get_Adc_Average(u8 ch,u8 times)
{
    u32 temp_val=0;
    u8 t;
    for(t=0;t<times;t++)
    {
        temp_val+=Get_Adc(ch);
        delay_ms(5);
    }
    return temp_val/times;
}

adc.h

#ifndef __ADC_H
#define __ADC_H    
#include "sys.h"

void Adc_Init(void);
u16  Get_Adc(u8 ch); 
u16 Get_Adc_Average(u8 ch,u8 times); 

#endif