Ir ao conteúdo

Linguagem c para pic16f877A ajuda"Controle de níveis"


ejss

Posts recomendados

Postado

Boa noite a todos do forum que gostam de ajudar os que tem dificuldades, inventei de fazer um controle de níveis, não consegui deixar funcionando do jeito imaginado, por isso recorro aos que tem facilidade de programar pic16f877a usando linguagem c, abaixo segue o link da imagem do circuito:

http://img833.imageshack.us/img833/2555/semttulodo.jpg

E o proposito dessa brincadeira que já esta me deixando careca, é fazer com que quando for selecionada qualquer tecla de forma aleatória encha ou esvazie o balde de agua até o nível referente ao sensor, nesse projetinho uso um balde com agua e uma bomba de aquário, cujo afunção e mandar agua para o outro balde, uma solenoide1 quando acionada libera para encher e outra libera para esvaziar, ficarei muito feliz se puderem me ajudar abaixo segue o programa que fiz mas não esta do jeito esperado quem poder analisar e me ajudar ficarei muito gratificado:

#include <16F877A.h> //O PIC utilizado, obrigatório!
#FUSES NOWDT //Sem Watch dog, evitando reset
#FUSES XT //Crystal de oscilação igual a 4mhz
#FUSES PUT //Tempo de início do PIC
#FUSES NOPROTECT //Codigo sem proteção de leitura, [URL="http://forum.clubedohardware.com.br/"][COLOR=#ff6666]software[/COLOR][/URL] livre!
[/COLOR][COLOR=black]#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#use delay(clock=4000000) // Definição do clock utilizado. [/COLOR][COLOR=black]Obrigatório!
#include <lcd.C> //Inclusão da biblioteca de LCD. Obrigatório!
// D0 enable //Pinos utilizados pelo LCD. Podem ser alterados.
// D1 rs
// D2 rw
// D4 D4
// D5 D5
// D6 D6
// D7 D7
//set_tris_A(0x0f);
/*=====================
Meu Botões:
=======================*/
#define BOTAO_1 PIN_A0 //NIVEL 1.
#define BOTAO_2 PIN_A1 //NIVEL 2.
#define BOTAO_3 PIN_A2 //NIVEL 3.
#define BOTAO_4 PIN_A3
#define SENSOR_1 PIN_B3
#define SENSOR_2 PIN_B4
#define SENSOR_3 PIN_B5
#define SENSOR_4 PIN_B6
//Foram utilizados resistores pull-up e
//pull-down em todos os botões para
//evitar ruídos.
/*=====================
Minhas variáveis:
=======================*/
//int16 q=0; //Variável que incrementa a cada 0.5s dentro da interupção do timer1.
int N=0; //Variável dos segundos, incrementa na metade de q.
int N1=0; //Variável dos minutos. 0 a 59
int N2=0; //Variável das horas. 0 a 23.
int N3=0;
/*=====================
O programa Principal:
=======================*/
void main()
{
lcd_init(); //Inicializa o LCD (obrigatório)!

[/COLOR][COLOR=black]lcd_gotoxy (1,1); //Coluna 6, linha 1.
lcd_putc("Controle de Nivel");
delay_ms(1000);
lcd_putc ("\f");
delay_ms(1000);


while(1) //Loop Principal
{

if (input(BOTAO_1)==0) //Teste do botão.
{
delay_ms(100);
OUTPUT_HIGH(PIN_B0);
OUTPUT_HIGH(PIN_B1);
}
IF (INPUT(SENSOR_1)==0)
{
delay_ms(100);
OUTPUT_LOW(PIN_B0);
OUTPUT_LOW(PIN_B1);

while(1)
{
if (input(BOTAO_2)==0) //Teste do botão.
{
delay_ms(100);
OUTPUT_HIGH(PIN_B0);
OUTPUT_HIGH(PIN_B1);
}
IF (INPUT(SENSOR_2)==0)
{
delay_ms(50);
OUTPUT_LOW(PIN_B0);
OUTPUT_LOW(PIN_B1);
while(1)
{
if (input(BOTAO_3)==0) //Teste do botão.
{
delay_ms(100);
OUTPUT_HIGH(PIN_B0);
OUTPUT_HIGH(PIN_B1);
}
IF (INPUT(SENSOR_3)==0)
{
delay_ms(100);
OUTPUT_LOW(PIN_B0);
OUTPUT_LOW(PIN_B1);

while(1)
{
if (input(BOTAO_4)==0) //Teste do botão.
{
delay_ms(100);
OUTPUT_HIGH(PIN_B0);
OUTPUT_HIGH(PIN_B1);
}
IF (INPUT(SENSOR_4)==0)
{
delay_ms(50);
OUTPUT_LOW(PIN_B0);
OUTPUT_LOW(PIN_B1);
}
}
}
}
}
}
}
}
} [/COLOR]
[/COLOR]

Postado

Como te falei no outro tópico, farei o código p você.

Só terminar outras coisas por aqui.

Esqueci de perguntar uma coisa.

você diz q a solenoide 1 deixa o balde encher e a solenoide 2 deixa o balde esvaziar.

A bom entra onde nessa história?

Falou

Falou

Postado

Se você fizer o código pra ele, ele nunca aprenderá, dê umas dicas e deixe ele queimar alguns neurônios, como você fez quando aprendeu :D

Como te falei no outro tópico, farei o código p você.

Só terminar outras coisas por aqui.

Esqueci de perguntar uma coisa.

você diz q a solenoide 1 deixa o balde encher e a solenoide 2 deixa o balde esvaziar.

A bom entra onde nessa história?

Falou

Falou

Postado

você tem razão.....

O ideal seria isso mesmo.....

Até porq esse projeto é uma boa para aprender a programar....

Acabou q eu fiz.... mas deixarei sem comentários para que ele estude! :D

Veja que fiz todo o código usando apenas IF´s. Tem algumas condições que nem precisam estar alí... mas coloquei para você poder ver e quem sabe otimizar o código.

Tentei aqui e me parece funcionar do jeito correto.

Como funciona:

A princípio o balde está vazio, então todos os sensores estão en nível alto, de acordo com essa figura que vocês mesmo postou:

sensores.png

Imagino que quando o sensor está aberto, o PIC irá reconhecer nível alto.

Se a água ficar acima do sensor, ele fecha e o PIC reconhece como nível baixo.

Na simulação coloquei logic states para simular os sensores. Então todos devem começar em 1.

Quando você apertar um dos botões de 1 a 4, a água começará a subir... até que ela cubra o sensor e esse feche e ficque em nível baixo, então você deve colocar zero no logic state.

Dessa forma, a simulação irá funcionar de acordo com o programado.

Circuito:

simulacao.jpg

Código:

#include <16F877A.h>

#FUSES NOWDT
#FUSES XT
#FUSES PUT
#FUSES NOPROTECT
#FUSES NODEBUG
#FUSES NOLVP
#FUSES NOCPD
#use delay(clock=4000000)

#include <lcd.C>

#define BOTAO_1 PIN_C0
#define BOTAO_2 PIN_C1
#define BOTAO_3 PIN_C2
#define BOTAO_4 PIN_C3

#define SENSOR_1 PIN_B4
#define SENSOR_2 PIN_B5
#define SENSOR_3 PIN_B6
#define SENSOR_4 PIN_B7

#define SOLENOIDE_1 PIN_B0
#define SOLENOIDE_2 PIN_B2
#define BOMBA PIN_B1

int8 modo;

void main()
{
lcd_init();

while (TRUE)
{
if (!input(botao_1))
{
modo = 1;

printf(lcd_putc,"\fIndo ao nivel 1!");
delay_ms (200);

do
{
} while (!input(botao_1));
}

if (!input(botao_2))
{
modo = 2;

printf(lcd_putc,"\fIndo ao nivel 2!");
delay_ms (200);

do
{
} while (!input(botao_2));
}

if (!input(botao_3))
{
modo = 3;

printf(lcd_putc,"\fIndo ao nivel 3!");
delay_ms (200);

do
{
} while (!input(botao_3));
}

if (!input(botao_4))
{
modo = 4;

printf(lcd_putc,"\fIndo ao nivel 4!");
delay_ms (200);

do
{
} while (!input(botao_4));
}

switch (modo)
{
case 1:
{
if ((input(sensor_1)) && (input(sensor_2)) && (input(sensor_3)) && (input(sensor_4)))
{
output_high (solenoide_1);
output_high (bomba);
}

if ((!input(sensor_1)) && (input(sensor_2)) && (input(sensor_3)) && (input(sensor_4)))
{
output_low (solenoide_1);
output_low (bomba);
}

if ((!input(sensor_1) && (!input(sensor_2)) || (!input(sensor_3)) || (!input(sensor_4))))
{
output_high (solenoide_2);
}

if (input(sensor_1))
{
output_low (solenoide_2);
}
break;
}

case 2:
{
if (input(sensor_2) && (input(sensor_3)) && (input(sensor_4)))
{
output_high (solenoide_1);
output_high (bomba);
}
if (!input(sensor_2) && (input(sensor_3)) && (input(sensor_4)))
{
output_low (solenoide_1);
output_low (bomba);
}

if ((!input(sensor_2)) && (!input(sensor_3)) || (!input(sensor_4)))
{
output_high (solenoide_2);
}
if (input(sensor_2))
{
output_low (solenoide_2);
}
break;
}

case 3:
{
if ((input(sensor_3)) && (input(sensor_4)))
{
output_high (solenoide_1);
output_high (bomba);
}
if ((!input(sensor_3)) && (input(sensor_4)))
{
output_low (solenoide_1);
output_low (bomba);
}

if ((!input(sensor_3) && (!input(sensor_4))))
{
output_high (solenoide_2);
}
if (input(sensor_3))
{
output_low (solenoide_2);
}
break;
}

case 4:
{
if (input(sensor_4))
{
output_high (solenoide_1);
output_high (bomba);
}
if (!input(sensor_4))
{
output_low (solenoide_1);
output_low (bomba);
}
break;
}
}
}
}

Arquivos para simulação:

Projeto Nível de Água

  • 2 semanas depois...
Postado

MatheusLPS e jorgeletronico, não tenho palavras para agradecer pelo interesse de vocês em ter me ajudado, baixei algumas apostilas de programação em c e vou me dedicar o máximo para aprender sei que estou verde em mas vou me esforçar para amadurecer, MatheusLPS quando vi o codigo que voce fez e vi a simplicidade que foi escrito fiquei até invergonhado, mas beleza! Obs: no proteus a simulação ficou perfeita mas no projeto os níveis 1 e 2 funcionam direitinho o níveis 3 e 4 não funciona direito o pic trava o lcd não informa o nível direito, problema deboucing para resolver esse problema acrecentei ao codigo nos ifs que seleciona a tecla um delay_ms(100); até melhorou o funcionamento mas ainda não ficou 100%, o que eu posso fazer para solucionar o problema, meus caros de coração valeu mesmo pelo apoio.

você tem razão.....

O ideal seria isso mesmo.....

Até porq esse projeto é uma boa para aprender a programar....

Acabou q eu fiz.... mas deixarei sem comentários para que ele estude! :D

Veja que fiz todo o código usando apenas IF´s. Tem algumas condições que nem precisam estar alí... mas coloquei para você poder ver e quem sabe otimizar o código.

Tentei aqui e me parece funcionar do jeito correto.

Como funciona:

A princípio o balde está vazio, então todos os sensores estão en nível alto, de acordo com essa figura que vocês mesmo postou:

sensores.png

Imagino que quando o sensor está aberto, o PIC irá reconhecer nível alto.

Se a água ficar acima do sensor, ele fecha e o PIC reconhece como nível baixo.

Na simulação coloquei logic states para simular os sensores. Então todos devem começar em 1.

Quando você apertar um dos botões de 1 a 4, a água começará a subir... até que ela cubra o sensor e esse feche e ficque em nível baixo, então você deve colocar zero no logic state.

Dessa forma, a simulação irá funcionar de acordo com o programado.

Circuito:

simulacao.jpg

Código:

#include <16F877A.h>

#FUSES NOWDT
#FUSES XT
#FUSES PUT
#FUSES NOPROTECT
#FUSES NODEBUG
#FUSES NOLVP
#FUSES NOCPD
#use delay(clock=4000000)

#include <lcd.C>

#define BOTAO_1 PIN_C0
#define BOTAO_2 PIN_C1
#define BOTAO_3 PIN_C2
#define BOTAO_4 PIN_C3

#define SENSOR_1 PIN_B4
#define SENSOR_2 PIN_B5
#define SENSOR_3 PIN_B6
#define SENSOR_4 PIN_B7

#define SOLENOIDE_1 PIN_B0
#define SOLENOIDE_2 PIN_B2
#define BOMBA PIN_B1

int8 modo;

void main()
{
lcd_init();

while (TRUE)
{
if (!input(botao_1))
{
modo = 1;

printf(lcd_putc,"\fIndo ao nivel 1!");
delay_ms (200);

do
{
} while (!input(botao_1));
}

if (!input(botao_2))
{
modo = 2;

printf(lcd_putc,"\fIndo ao nivel 2!");
delay_ms (200);

do
{
} while (!input(botao_2));
}

if (!input(botao_3))
{
modo = 3;

printf(lcd_putc,"\fIndo ao nivel 3!");
delay_ms (200);

do
{
} while (!input(botao_3));
}

if (!input(botao_4))
{
modo = 4;

printf(lcd_putc,"\fIndo ao nivel 4!");
delay_ms (200);

do
{
} while (!input(botao_4));
}

switch (modo)
{
case 1:
{
if ((input(sensor_1)) && (input(sensor_2)) && (input(sensor_3)) && (input(sensor_4)))
{
output_high (solenoide_1);
output_high (bomba);
}

if ((!input(sensor_1)) && (input(sensor_2)) && (input(sensor_3)) && (input(sensor_4)))
{
output_low (solenoide_1);
output_low (bomba);
}

if ((!input(sensor_1) && (!input(sensor_2)) || (!input(sensor_3)) || (!input(sensor_4))))
{
output_high (solenoide_2);
}

if (input(sensor_1))
{
output_low (solenoide_2);
}
break;
}

case 2:
{
if (input(sensor_2) && (input(sensor_3)) && (input(sensor_4)))
{
output_high (solenoide_1);
output_high (bomba);
}
if (!input(sensor_2) && (input(sensor_3)) && (input(sensor_4)))
{
output_low (solenoide_1);
output_low (bomba);
}

if ((!input(sensor_2)) && (!input(sensor_3)) || (!input(sensor_4)))
{
output_high (solenoide_2);
}
if (input(sensor_2))
{
output_low (solenoide_2);
}
break;
}

case 3:
{
if ((input(sensor_3)) && (input(sensor_4)))
{
output_high (solenoide_1);
output_high (bomba);
}
if ((!input(sensor_3)) && (input(sensor_4)))
{
output_low (solenoide_1);
output_low (bomba);
}

if ((!input(sensor_3) && (!input(sensor_4))))
{
output_high (solenoide_2);
}
if (input(sensor_3))
{
output_low (solenoide_2);
}
break;
}

case 4:
{
if (input(sensor_4))
{
output_high (solenoide_1);
output_high (bomba);
}
if (!input(sensor_4))
{
output_low (solenoide_1);
output_low (bomba);
}
break;
}
}
}
}

Arquivos para simulação:

Projeto Nível de Água

Muito obrigado pelo apoio.

Postado

Descreva melhor seu problema.

Citando de forma detalhada porq o nível 3 e o nível 4 não fucionam.

Coolocou esses nívies na posiçã"ao correta? Talvez você possa ter trocado os dois de posiç"ao.

Falou

Postado

Meu caro amigo, o problema era o seguinte: quando apertava a tecla referente ao nível 3 quando o sensor_3 fechava, não sei porque motivo ele tipo repicava, causando erro no funcinamento, ele imediatamente entendia como se estivesse programado para que quando chegasse no nível 3 apagava as informações do lcd e ja mandava abrir a solenoide_2, e na maioria das vezes até travava o pic, e pela lógica do programa não era para acontecer, coloquei um delay_ms(250) no sensor_3, mas não adiantou, então resolvi ligar esse sensor_3 no pino RC4 do pic para fazer um teste e funcionou direitinho, pergunta será que o pino RB6 onde estava ligado o sensor_3 esta com defeito? Modifiquei o codigo e me diga se tem como reduzir mais do que este :


#FUSES NOWDT
#FUSES XT
#FUSES PUT
#FUSES NOPROTECT
#FUSES NODEBUG
#FUSES NOLVP
#FUSES NOCPD
#use delay(clock=4000000)
#include <lcd.C>
#define BOTAO_1 PIN_C0
#define BOTAO_2 PIN_C1
#define BOTAO_3 PIN_C2
#define BOTAO_4 PIN_C3
#define SENSOR_1 PIN_B4
#define SENSOR_2 PIN_B5
#define SENSOR_3 PIN_C4//PIN_B6
#define SENSOR_4 PIN_B7
#define SOLENOIDE_1 PIN_B0
#define SOLENOIDE_2 PIN_B2
#define BOMBA PIN_B1
int8 modo;
void main()
{
lcd_init();
lcd_gotoxy (2,1); //Coluna 6, linha 1.
lcd_putc("Projeto Nivel");
delay_ms(2000);
lcd_gotoxy (4,2);
lcd_putc("PIC16F877A");
delay_ms(2000);
lcd_putc ("\f");
delay_ms(1000);
lcd_gotoxy (1,1);
lcd_putc ("Iniciando");
lcd_gotoxy (10,1);
lcd_putc (".");
delay_ms(500);
lcd_gotoxy (11,1);
lcd_putc (".");
delay_ms(500);
lcd_gotoxy (12,1);
lcd_putc (".");
delay_ms(500);
lcd_gotoxy (13,1);
lcd_putc (".");
delay_ms(500);
lcd_gotoxy (14,1);
lcd_putc (".");
delay_ms(500);
lcd_gotoxy (15,1);
lcd_putc (".");
delay_ms(500);
lcd_gotoxy (16,1);
lcd_putc (".");
delay_ms(500);
lcd_putc ("\f");
delay_ms(1000);
lcd_gotoxy (3,1);
lcd_putc("Selecione o");
delay_ms(1000);
lcd_gotoxy (1,2);
lcd_putc(" Nivel Desejado");
delay_ms(1000);

while (TRUE)
{
if (!input(botao_1))
{
delay_ms (250);
modo = 1;

printf(lcd_putc,"\fIndo ao nivel 1!");
delay_ms (200);
}

if (!input(botao_2))
{
delay_ms (250);
modo = 2;

printf(lcd_putc,"\fIndo ao nivel 2!");
delay_ms (200);
}

if (!input(botao_3))
{
delay_ms (250);
modo = 3;

printf(lcd_putc,"\fIndo ao nivel 3!");
delay_ms (200);
}

if (!input(botao_4))
{
delay_ms (250);
modo = 4;

printf(lcd_putc,"\fIndo ao nivel 4!");
delay_ms (200);
}

switch (modo)
{
case 1:
{
if (input(sensor_1))
{
delay_ms (250);
output_high (solenoide_1);
output_high (bomba);
}

if (!input(sensor_1))
{
delay_ms (250);
output_low (solenoide_1);
output_low (bomba);
}

if (!input(sensor_2))
{
delay_ms (250);
output_high (solenoide_2);
}

if (input(sensor_1))
{
delay_ms (250);
output_low (solenoide_2);
}
break;
}

case 2:
{
if (input(sensor_2))
{
delay_ms (250);
output_high (solenoide_1);
output_high (bomba);
}
if (!input(sensor_2))
{
delay_ms (250);
output_low (solenoide_1);
output_low (bomba);
}

if (!input(sensor_3))
{
delay_ms (250);
output_high (solenoide_2);
}
if (input(sensor_2))
{
delay_ms (250);
output_low (solenoide_2);
}
break;
}

case 3:
{
if (input(sensor_3))
{
delay_ms (250);
output_high (solenoide_1);
output_high (bomba);
}
if (!input(sensor_3))
{
delay_ms (250);
output_low (solenoide_1);
output_low (bomba);
}

if (!input(sensor_4))
{
delay_ms (250);
output_high (solenoide_2);
}
if (input(sensor_3))
{
delay_ms (250);
output_low (solenoide_2);
}
break;
}

case 4:
{
if (input(sensor_4))
{
output_high (solenoide_1);
output_high (bomba);
}
if (!input(sensor_4))
{
output_low (solenoide_1);
output_low (bomba);
}
break;
}
}
}
}
#include <16F877A.h>
Postado

Olá ejss,

Engraçado você ter esse problema com o PINO B6... Era para funcionar conforme o combinado...

Se ele repicava, deve ser porque o contato não estava fechando direito.... e mesmo assim era p ele ficar repicando a bomba e a solenoide 1 e não a 2. Muito estranho.

Sobre o código, acredito que esteja bem pequeno já. Uma dica para que ele fique organizado é você colocar por exemplo a parte que mostra as mensagens de boas vindas e a contagem para início em um arquivo separado (.H) e chamar um afunção com o nome de por exemplo inicia() logo depois do main();.

Nesse caso, você precisa declarar no início do programa um #include <inicio.h> por exemplo e colocar sua rotina de início dentro da função void inicia() no arquivo .h.

Falou...

Postado

Boa noite Matheus, eu devo ter entendido errado porque eu tentei fazer mas deu erro, copiei a parte de boas vindas colei no bloco de notas salvei com o nome inicio.h, no codigo antes do void main() eu fiz #include <inicio.h> e depois do void main(), eu inclui inicio(); com certeza entendi errado e errei, como é que ficaria este detalhe de organizar esta parte do código?

  • 2 meses depois...
Postado
Faltou você colocar a mensagem de boas vindas do bloco de notas dentro de uma função chamada void inicio() { aqui fica a mensagem }

Falou

Boa noite MatheusLPS assim como na sua resposta anterior, coloquei a mensagem conforme a sua explicação e deu certo, o problema agora é que, passei o circuito para placa e o Pic trava reseta sozinho e quando estava no protoboard funcionava direitinho, com a sua experiência voce tem alguma dica que possa ser feito no codigo ou no hardware para que este problema seja eliminado?

Postado

Bem, que bom que minhas dicas valem de alguma coisa né :D

Se você fez a placa PCB igual a montagem da protoboard, seria para funcionar conforme o "combinado".

Não tenho experiencia em pcb pois tenho pavor delas. Não gosto de montar. Normalmente pago alguém para que monte para mim.

Posso te indicar uma conferencia das trilhas ou algo do tipo.....

Falou

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!