Ir ao conteúdo
  • Cadastre-se

Projeto pic16f628a com dht22 e esp8266


Posts recomendados

  • Membro VIP

Saudações,
Não estou conseguindo enviar informações para a plataforma ThingSpeak, as funções do DHT22 estão funcionando perfeitamente pois já testei com LCD, e a configuração do Timer1 também pois já testei separado.
Mas nesse meu projeto algo está errado porque não consigo enviar dados de umidade e temperatura para meu canal no ThingSpeak.
Liguei a porta Rx do ESP8266 na porta Tx do PIC já com divisor de tensão de 3.3V. A porta Tx do ESP8266 liguei na porta RX do PIC. E as portas GPIO0, RST, CH_PD e VCC estão conectados no 3.3v. Porta GND está no terra.
O LED (BREATHING_LIGHT) está piscando aleatoriamente, porém a configuração do Timer1 está correta.
Espero que alguém possa me dar uma luz sobre o que pode estar errado, notem que alterei as informações de “SSID”, “SENHA_WIFI” e “CHAVE” por motivos de segurança:


//Programa : PIC na IoT com ThingSpeak e DHT22 usando PIC16F628A
//Autor : Marcos Roberto Baungartner RA: 9902012531
//Data 29/04/2017


//Diretivas para o pré-processador
#include <16F628A.h> //Inclui Header do PIC16F628A
#FUSES HS //Oscilador Interno e portas como IO <Habilitado>
#FUSES NOMCLR //Master Clear (Reset) <Desabilitado>
#FUSES NOWDT //Watch Dog Timer <Desabilitado>
#FUSES PUT //Power-Up Timer <Habilitado>
#FUSES BROWNOUT //Resetar quando detectar brownout <Habilitado>
#FUSES NOLVP //Gravação em baixa-tensão <Desabilitado>
#FUSES NOCPD //Proteção do memória EEPROM <Desabilitado>
#FUSES NOPROTECT //Proteção para leitura do código <Desabilitado>
#use delay(clock = 20000000) //Clock de 4MHz (clock útil de 1MHz)

#use rs232(baud=115200,parity=N,xmit=PIN_B2,rcv=PIN_B1,bits=8,ERRORS)
#priority INT_TIMER1, INT_RDA //INT_EXT,//ordem de prioridade das interrupções (ordem decrescente de prioridade)

//defines gerais:
#define DATA PIN_A0
#define BREATHING_LIGHT PIN_A1
#define TAMANHO_COMANDO_MODO_ESTACAO sizeof(ComandoModoEstacao);
#define TAMANHO_COMANDO_CONECTA_ROTEADOR sizeof(ComandoConectaRoteador);
#define TAMANHO_COMANDO_MULTI_CONEXOES sizeof(ComandoMultiplasConexoes);
#define TAMANHO_COMANDO_HTTP_THINGSPEAK sizeof(ComandoConectaHTTPThingspeak);
#define TAMANHO_COMANDO_SEND_THINGSPEAK sizeof(ComandoSendDadoThingspeak);

#define VALOR_INICIAL_TIMER1 3036

#define ESTADO_MODO_ESTACAO 0
#define ESTADO_CONECTA_ROTEADOR 1
#define ESTADO_MULTI_CONEXOES 2
#define ESTADO_HTTP_THINGSPEAK 3
#define ESTADO_SEND_THINGSPEAK 4

#define TEMPO_SEND_THINGSPEAK 30 //envio para o thingspeak é feito em um período de 30s
#define VALOR_MAX_CONTADOR_TEMPO_THINGSPEAK TEMPO_SEND_THINGSPEAK*20

#define SIM 1
#define NAO 0

char ContadorIntTimer;
long ContadorEnvioDadosThingspeak;
volatile char EstadoMaquinaESP8266;
char DeveEnviarDadoThingspeak;
unsigned char ContadorIntTimerSensor, umidade_byte1, umidade_byte2, temperatura_byte1, temperatura_byte2, paridade_byte, timeOut;
unsigned long temperatura_2byte, umidade_2byte;
float temperatura = 0, umidade = 0;

//prototypes
//void ConfigInterrupcaoEXT(void);
void ConfigInterrupcaoUART(void);
void ConfigTimer1(void);
void ESP8266SetaModoEstacao(void);
void ESP8266ConectaRoteador(void);
void ESP8266MultiplasConexoes(void);
void ESP8266HTTPThingspeak(void);
void ESP8266PreparaEnvioHTTP(void);
void ESP8266SendThingspeak(char valor);
void SetupESP8266(void);


/*********************** FUNÇOES DO SENSOR DHT22 ****************************************************/
//Envia sinal de start para o sensor
void startSignal() {
set_tris_a(0b00000000); //Configura RA0 como output
output_low(DATA); //Pino DATA envia 0 para o sensor
delay_ms(20);
output_high(DATA); //Pino DATA envia 1 para o sensor
delay_us(30);
set_tris_a(0b00000001); //Configura RA0 como input
}

//Checa resposta do sensor
unsigned char checkResponse() {
delay_us(40);

if(!input(DATA)) {
delay_us(80);

if(input(DATA)) {
delay_us(40);
return 1;
}
else
return 0;
}
}

//Função para ler os dados do sensor DHT22
unsigned char readData() {
unsigned char j=0, dataByte=0;

if(timeOut) break;

for(j = 0; j <= 7; j++) {
while(!input(DATA)){ // Espera até que a porta DATA vá para High
delay_us(1);
}

delay_us(30);

if(!input(DATA)) { //Se continuar em Low apos 30us, bit = 0

dataByte &= ~(1 << (7 - j)); //Zera bit (7-j)
}
else { //Se estiver em High apos 30us, bit = 1
dataByte |= (1 << (7 - j)); //Seta bit (7-j)
while(input(DATA)){ //Espera até que a porta DATA vá para Low
delay_us(1);
}
}
}
return dataByte;
}
/***************************************************************************/

/*
//tratamento da interrupção externa
#int_EXT
void EXT_isr(void) {
//debouncing
delay_ms(10);
// código caso necessite de uma interrupção externa
}
*/

//tratamento da interrupção serial
#INT_RDA
void serial_isr() {
char ByteLido;
ByteLido = getc();
}

//tratamento da interrupção de timer
#INT_TIMER1
void TrataTimer1() {
ContadorIntTimer++;
ContadorEnvioDadosThingspeak++;
ContadorIntTimerSensor++;
//contabiliza tempo de envio do dado ao thingspeak
if (ContadorEnvioDadosThingspeak >= VALOR_MAX_CONTADOR_TEMPO_THINGSPEAK)
DeveEnviarDadoThingspeak = SIM;

//controla tempo para piscada do breathing light
if (ContadorIntTimer >= 20) { //cada "tick" do timer1 tem 0,05s. Logo, 20 "tiks" equivalem a 1 segundo
//troca o estado da saída do breathing light
output_toggle(BREATHING_LIGHT);
ContadorIntTimer = 0;
}

//controla tempo para leitura do sensor

while(ContadorIntTimerSensor >= 40) {
//inicia leitura do sensor
startSignal();
if(checkResponse()) {
umidade_byte1 = readData(); //primeiro byte da umidade: bit 15 ~ bit 8
umidade_byte2 = readData(); //segundo byte da umidade bit: 7 ~ bit 0
temperatura_byte1 = readData(); //primeiro byte da temperatura: bit 15 ~ bit 8
temperatura_byte2 = readData(); //segundo byte da temperatura: bit 7 ~ bit 0
paridade_byte = readData(); //byte da paridade bit: 7 ~ bit 0
if(paridade_byte == (umidade_byte1 + umidade_byte2 + temperatura_byte1 + temperatura_byte2) & 0xFF) {
umidade_2byte = umidade_byte1;
umidade_2byte = (umidade_2byte << 8) | umidade_byte2;
temperatura_2byte = temperatura_byte1;
temperatura_2byte = (temperatura_2byte << 8) | temperatura_byte2;
if(temperatura_2byte > 0x8000) { //Se temperatura for maior que 1000 0000 (binario)
temperatura_2byte &= 0x7FFF; //Temperatura recebe 14bits, pois o bit 15 representa sinal
temperatura = temperatura_2byte;
temperatura *= -1;
}
else {
temperatura = temperatura_2byte;
}
umidade = umidade_2byte;

ContadorIntTimerSensor = 0;
}
}
}

//configura timer e religa interrupções
set_timer1(VALOR_INICIAL_TIMER1);
}


//função de configuração da interrupção UART
//parametros: nenhum
//saida: nenhum
void ConfigInterrupcaoUART(void) {
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
}

//função de configuração da interrupção externa
//parametros: nenhum
//saida: nenhum
/*
void ConfigInterrupcaoEXT(void) {
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
ext_int_edge(L_TO_H);
}
*/

//função de configuração do Timer1
//parametros: nenhum
//saida: nenhum
void ConfigTimer1(void) {
// - Frequencia do oscilador interno (20000000/4) = 5Mhz (por default, o PIC funciona a 1/4 da frequencia de clock estabelecida)
// - Se o Timer1 tem 16 bits, seu valor máximo de contagem é 0xFFFF (65535)
// - Com 5MHz de frequencia util, cada ciclo de máquina terá, em segundos: 1 / 5MHz = 0,0000002 (0,2us)
// - Utilizando o prescaler do microcontrolador em 4 (ou seja, a frequencia util do timer1 é 1/4 da frequencia util do pic), temos:
// Periodo minimo "contável" pelo Timer1 = (1 / (5MHz/4)) = 0,0000008 (0,8us)
// - Logo, a cada 16 bits contados, teremos: 65536 * 0,8us = 0,0524288s
// - visando maior precisão, sera feito um timer de 0,05s. Logo:
// 0,0524288s --- 65536
// 0,05s --- x x = 62500
// Logo, o valor a ser setado no timer1 é: 65536 - 62500 = 3036 (Aplicar esse numero na linha 6 do pic_esp8266.h)
ContadorIntTimer = 0;
setup_timer_1(T1_INTERNAL| T1_DIV_BY_4);
set_timer1(VALOR_INICIAL_TIMER1);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
}

//função que configura o ESP8266 para operar em modo estação (se conecta em um roteador)
//parametros: nenhum
//saida: nenhum
void ESP8266SetaModoEstacao(void) {
puts("AT+CWMODE=1\r\n\0");
delay_ms(500);
}

//função que conecta o ESP8266 em um roteador
//parametros: nenhum
//saida: nenhum
void ESP8266ConectaRoteador(void) {
puts("AT+CWJAP=\"SSID\",\"SENHA_WIFI\"\r\n\0");
delay_ms(7000);
}

//função que configura o ESP8266 para operar com multiplas conexoes
//parametros: nenhum
//saida: nenhum
void ESP8266MultiplasConexoes(void) {
puts("AT+CIPMUX=1\r\n\0");
delay_ms(500);
}

//função que conecta o ESP8266 via HTTP ao Thingspeak
//parametros: nenhum
//saida: nenhum
void ESP8266HTTPThingspeak(void) {
puts("AT+CIPSTART=4,\"TCP\",\"184.106.153.149\",80\r\n\0");
delay_ms(5000);
}

//função que prepara o ESP8266 para enviar dados via HTTP ao Thingspeak
//parametros: nenhum
//saida: nenhum
void ESP8266PreparaEnvioHTTP(void) {
puts("AT+CIPSEND=4,46\r\n\0");
delay_ms(500);
}

//função que envia um dado ao Thingspeak
//parametros: dado (número de 1 byte)
//saida: nenhum
void ESP8266SendThingspeak(float valor1, float valor2) {
char ComandoEnvioDadoHTTP[71];

memset(ComandoEnvioDadoHTTP,0,sizeof(ComandoEnvioDadoHTTP));
sprintf(ComandoEnvioDadoHTTP,"GET /update?key=CHAVE&field1=%.1f&field2=%.1f\r\n\0", valor1, valor2);
puts(ComandoEnvioDadoHTTP);
delay_ms(5000);
}

//função que inicializa, configura e conecta ESP8266 ao roteador
//parametros: nenhum
//saida: nenhum
void SetupESP8266(void) {
ESP8266SetaModoEstacao();
ESP8266ConectaRoteador();
ESP8266MultiplasConexoes();
}

//programa principal
void main(void) {

//inicializa maquina de controle da ESP8266
EstadoMaquinaESP8266 = ESTADO_MODO_ESTACAO;

//configura Timer1
ConfigTimer1();

//inicializa contador de tempo de envio de dados para o Thingspeak
ContadorEnvioDadosThingspeak = 0;
DeveEnviarDadoThingspeak = NAO;

//configuração das interrupções (UART e interrupção externa)
ConfigInterrupcaoUART();
//ConfigInterrupcaoEXT();

//inicializa, configura e conecta ESP8266 ao roteador
SetupESP8266();

while(TRUE) {

output_high(PIN_B3);
if (DeveEnviarDadoThingspeak == SIM) {

ESP8266HTTPThingspeak();
ESP8266PreparaEnvioHTTP();
ESP8266SendThingspeak(umidade, temperatura);
ContadorEnvioDadosThingspeak = 0;
DeveEnviarDadoThingspeak = NAO;
}
}
}

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

penso que você deve isolar os problemas: 1º leia corretamente o dht22 e (p.ex.) envie o dado prum terminal.

Depois, com o dado consistente em mãos, envie pro seu sistema.

Dica: provavelmente o fabricante do dht22 disponibiliza algum exemplo de comunicação com ele. Não reinvente a roda. Use-a.

Link para o comentário
Compartilhar em outros sites

  • Membro VIP
Em 2017-5-29 às 07:54, Isadora Ferraz disse:

penso que você deve isolar os problemas: 1º leia corretamente o dht22 e (p.ex.) envie o dado prum terminal.

Depois, com o dado consistente em mãos, envie pro seu sistema.

Dica: provavelmente o fabricante do dht22 disponibiliza algum exemplo de comunicação com ele. Não reinvente a roda. Use-a.

 

Mas foi exatamente o que fiz, li o Datasheet e criei as funções de comunicação, estas estão funcionando perfeitamente pois já as testei isoladamente com LCD, então o problema não é com o DHT22.
O problema parece estar em alguma interrupção, vou fazer testes limpando a Flag das interrupções e testar os comandos AT do ESP8266 isoladamente em um programa a parte, porque pelo que vi ele conecta na internet com sucesso mas não está entrando na função que envia os dados para o ThingSpeak.

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

pois é, você está no caminho certo. Tente desabilitar qualquer interrupt ou fazer algum sincronismo\protocolo entre o loop principal e a interrupt. Algo como: 'só interrompa se não estiver conversando' ou 'neste momento pode conversar'

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber 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...