我们经常看到家中电力供应的电压波动,这可能会导致我们家用交流电器出现故障。今天,我们正在构建一种低成本的高低压保护电路,该电路将在高电压或低电压的情况下切断电器的电源。它还将在 16x2 LCD 上显示警告消息。在本项目中,我们使用PIC微控制器来读取输入电压并将其与参考电压进行比较,并采取相应的措施。
我们在PCB上制作了这个电路,并在PCB上增加了一个额外的电路用于相同的目的,但这次使用的是运算放大器LM358(不带微控制器)。出于演示目的,我们选择低电压限制为150v,高电压限制为200v。在这个项目中,我们没有使用任何继电器进行切断,我们只是使用LCD演示了它,请查看本文末尾的视频。但是用户可以将继电器连接到该电路,并将其与PIC的GPIO连接。
在这个高低压切断电路中,我们使用**PIC微控制器**在变压器,桥式整流器和分压器电路的帮助下读取交流电压,并在16x2 LCD上显示。然后,我们将交流电压与预定义的限值进行比较,并相应地在LCD上显示警报消息。就像如果电压低于150v,那么我们显示“低电压”,如果电压高于200v,那么我们在LCD上显示“高压”文本。我们可以在项目结束时给出的 PIC 代码中更改这些限制。在这里,我们使用风扇调节器来增加和减少输入电压,以便在视频中进行演示。
在该电路中,我们还添加了 一个简单的欠压和过压保护电路 ,而无需使用任何微控制器。在这个简单的电路中,我们使用LM358比较器来比较输入和基准电压。因此,我们在此项目中有三个选项:
在这里,我们演示了该项目的第一个选项。其中,我们将交流输入电压降压,然后使用桥式整流器将其转换为直流,然后再次将该直流电压映射到5v,最后将该电压馈送到PIC微控制器进行比较和显示。
在PIC微控制器中,我们已经读取了这个映射的直流电压,并根据该映射值,我们借助给定的公式计算了输入的交流电压:
volt= ((adcValue*240)/1023)
其中 adcValue 是 PIC 控制器 ADC 引脚上的等效直流输入电压值,伏特是施加的交流电压。这里我们采用240v作为最大输入电压。
或者,我们可以使用给定的方法来映射等效的直流输入值。
volt = map(adcVlaue, 530, 895, 100, 240)
其中ADC值是PIC控制器ADC引脚上的等效直流输入电压值,530是最小直流电压等效值,895是最大直流电压等效值。100v是最小映射电压,240v是最大映射电压。
PIC ADC 引脚上的 10mV 直流输入等于 2.046 ADC 等效值。因此,这里我们选择了 530 作为最小值,PIC 的 ADC 引脚上的电压将为:
(((530/2.046)*10)/1000) Volt
2.6V,将映射最小值为100VAC
(最大限制的计算相同)。
检查地图功能最后在PIC程序代码中给出。
这个项目的工作很容易。在这个项目中,我们使用了交流电压风扇调节器来演示它。我们在变压器的输入端安装了风扇调节器。然后通过增加或减少其电阻,我们获得了所需的电压输出。
在代码中,我们有固定的最大和最小电压值,用于高压和低电压检测。我们将200v固定为过压限制,150v为下限电压限制。现在,在电路上电后,我们可以看到LCD上的交流输入电压。当输入电压增加时,我们可以看到LCD上的电压变化,如果电压超过电压限制,则LCD将通过“高压警报”提醒我们,如果电压低于电压限制,则LCD将通过显示“低电压警报”消息来提醒我们。这样它也可以用作 电子断路器 。
我们可以进一步添加一个继电器,将任何交流电器连接到低压或高压的自动切断。我们只需要添加一行代码即可关闭设备,在显示代码的 LCD 警报消息下方。查看此处以将继电器与交流电器一起使用。
在高低压保护电路中,我们使用了LM358运算放大器,该运算放大器具有连接到PIC微控制器的2个和3个数字引脚的两个输出。分压器用于分压,并将其输出连接到PIC微控制器的第4个数字引脚。液晶屏以 4 位模式连接到 PIC 的端口。RS 和 EN 直接连接在 B0 和 B1 上,LCD 的数据引脚 D4、D5、D6 和 D7 分别连接在 B2、B3、B4 和 B5 上。在本项目中,我们使用了两个稳压器:7805用于微控制器电源,7812用于LM358电路。12v-0-12v降压变压器也用于降压交流电压。其余组件如下图所示。
这个项目的编程部分很容易。在此代码中,我们只需要使用来自分压器电路的映射0-5v电压来计算交流电压,然后将其与预定义的值进行比较。您可以在此项目之后检查完整的 PIC 代码。
首先,在代码中,我们包含一个标头并配置了PIC微控制器配置位。如果您不熟悉 PIC 编码,请在此处学习 PIC 微控制器及其配置位。
然后我们使用了一些功能来驱动LCD,比如void lcdbegin()用于初始化LCD,void lcdcmd(char ch)用于向LCD发送命令,void lcdwrite(char ch)用于将数据发送到LCD, *void lcdprint(char str ) 用于将字符串发送到LCD。 检查以下代码中的所有函数。
下面给定的函数用于映射值:
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
给定 int analogRead(int ch) 函数用于初始化和读取 ADC:
int analogRead(int ch)
{
int adcData=0;
if(ch == 0)
ADCON0 = 0x03; // adc channel 0
else if(ch == 1)
ADCON0 = 0x0b; //select adc channel 1
else if(ch == 2)
ADCON0 = 0x0b; //select adc channel 2
ADCON1 = 0b00001100; // select analog i/p 0,1 and 2 channel of ADC
ADCON2 = 0b10001010; //eqisation time holding cap time
while(GODONE==1); // start conversion adc value
adcData = (ADRESL)+(ADRESH<<8); //Store 10-bit output
ADON=0; // adc off
return adcData;
}
给定的线路用于获取ADC样本并计算它们的平均值,然后计算电压:
while(1)
{
long adcValue=0;
int volt=0;
for(int i=0;i<100;i++) // taking samples
{
adcValue+=analogRead(2);
delay(1);
}
adcValue/=100;
#if method == 1
volt= (((float)adcValue*240.0)/1023.0);
#else
volt = map(adcValue, 530, 895, 100, 240);
#endif
sprintf(result,"%d",volt);
最后给定函数用于执行结果操作:
if(volt > 200)
{
lcdcmd(1);
lcdprint("High Voltage");
lcdcmd(192);
lcdprint(" Alert ");
delay(1000);
}
else if(volt < 150)
{
lcdcmd(1);
lcdprint("Low Voltage");
lcdcmd(192);
lcdprint(" Alert ");
delay(1000);
}
这样我们就可以轻松地为我们的家构建低压高压保护电路。此外,您只需**添加一个继电器即可将任何交流电器连接到**它,以保护它免受电压波动的影响。只需将继电器与PIC MCU的任何通用引脚连接,并编写代码以使该引脚高低以及LCD警报消息代码。
#include
#include
#include
// CONFIG1H
#pragma config OSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
// CONFIG2L
#pragma config PWRT = ON // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = SBORDIS // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
#pragma config BORV = 3 // Brown Out Reset Voltage bits (Minimum setting)
// CONFIG2H
#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
// CONFIG3H
#pragma config CCP2MX = PORTC // CCP2 MUX bit (CCP2 input/output is multiplexed with RB1)
#pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config LPT1OSC = OFF // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)
// CONFIG4L
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
// CONFIG5L
#pragma config CP0 = OFF // Code Protection bit (Block 0 (000800-001FFFh) not code-protected)
#pragma config CP1 = OFF // Code Protection bit (Block 1 (002000-003FFFh) not code-protected)
#pragma config CP2 = OFF // Code Protection bit (Block 2 (004000-005FFFh) not code-protected)
#pragma config CP3 = OFF // Code Protection bit (Block 3 (006000-007FFFh) not code-protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF // Write Protection bit (Block 0 (000800-001FFFh) not write-protected)
#pragma config WRT1 = OFF // Write Protection bit (Block 1 (002000-003FFFh) not write-protected)
#pragma config WRT2 = OFF // Write Protection bit (Block 2 (004000-005FFFh) not write-protected)
#pragma config WRT3 = OFF // Write Protection bit (Block 3 (006000-007FFFh) not write-protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF // Table Read Protection bit (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF // Table Read Protection bit (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) not protected from table reads executed in other blocks)
#define rs RB0
#define en RB1
char result[10];
#define lcdport PORTB
#define method 0
void delay(unsigned int Delay)
{
int i,j;
for(i=0;ifor(j=0;j<1000;j++);
}
void lcdcmd(char ch)
{
lcdport= (ch>>2)& 0x3C;
rs=0;
en=1;
delay(1);
en=0;
lcdport= (ch<<2) & 0x3c;
rs=0;
en=1;
delay(1);
en=0;
}
void lcdwrite(char ch)
{
lcdport=(ch>>2) & 0x3c;
rs=1;
en=1;
delay(1);
en=0;
lcdport=(ch<<2) & 0x3c;
rs=1;
en=1;
delay(1);
en=0;
}
void lcdprint(char *str)
{
while(*str)
{
lcdwrite(*str);
str++;
}
}
void lcdbegin()
{
lcdcmd(0x02);
lcdcmd(0x28);
lcdcmd(0x0e);
lcdcmd(0x06);
lcdcmd(0x01);
}
int analogRead(int ch)
{
int adcData=0;
if(ch == 0)
ADCON0 = 0x03; // adc channel 0
else if(ch == 1)
ADCON0 = 0x0b; //select adc channel 1
else if(ch == 2)
ADCON0 = 0x0b; //select adc channel 2
ADCON1 = 0b00001100; // select analog i/p 0,1 and 2 channel of ADC
ADCON2 = 0b10001010; //eqisation time holding cap time
while(GODONE==1); // start conversion adc value
adcData = (ADRESL)+(ADRESH<<8); //Store 10-bit output
ADON=0; // adc off
return adcData;
}
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
void main()
{
//ADCON1 = 0b0001111; //all port is digital
TRISB=0x00;
TRISC=0x00;
TRISA=0xff;
lcdbegin();
lcdprint("HIGH/LOW Volt");
lcdcmd(192);
lcdprint("Detector by PIC");
delay(1000);
lcdcmd(1);
lcdprint("CircuitDigest");
lcdcmd(192);
lcdprint("Welcomes You");
delay(1000);
while(1)
{
long adcValue=0;
int volt=0;
for(int i=0;i<100;i++) // taking samples
{
adcValue+=analogRead(2);
delay(1);
}
adcValue/=100;
#if method == 1
volt= (((float)adcValue*240.0)/1023.0);
#else
volt = map(adcValue, 530, 895, 100, 240);
#endif
sprintf(result,"%d",volt);
lcdcmd(0x80);
lcdprint("H>200V L<150V");
lcdcmd(0xc0);
lcdprint("Voltage:");
lcdprint(result);
lcdprint(" V ");
delay(1000);
if(volt > 200)
{
lcdcmd(1);
lcdprint("High Voltage");
lcdcmd(192);
lcdprint(" Alert ");
delay(1000);
}
else if(volt < 150)
{
lcdcmd(1);
lcdprint("Low Voltage");
lcdcmd(192);
lcdprint(" Alert ");
delay(1000);
}
}
}
全部0条评论
快来发表一下你的评论吧 !