Ir ao conteúdo
  • Cadastre-se

Outro Comunicação serial entre NodeMCU e Atmega328P


Posts recomendados

Boa noite, estou tentando fazer uma comunicação serial entre um NodeMCU e um ATMEGA328P, a principio a comunicação serial que criei funciona muito bem entre o PC-NodeMCU e entre o PC-ATMEGA, porém quando tento fazer a comunicação entre NodeMCU-ATMEGA as coisas funcionam parcialmente, o que ocorre é que a string enviada do ATMEGA para o NodeMCU e recebida numa boa e tratada e os dados são printados no APP BLYNK. porém quando tento enviar um comando através de uma string do NodeMCU para o ATMEGA este não executa corretamente.

 

Descrição do que ocorre, eu envio um comando através do BLYNC para o NodeMCU este por sua vez envia uma string pela serial com a mensagem "#P1*" para ATMEGA nele o led do rx pisca porém não executa o meu comando.

 

Tem duas possibilidades aonde o erro pode estar sendo estas no envio pelo NodeMCU ou no recebimento pelo ATMEGA.

 

Abaixo o código para o ATMEGA e para o NodeMCU respectivamente.

 

ATMEGA

 

#define F_CPU 16000000UL

#include <avr/io.h>
#include <util/delay.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <avr/interrupt.h>

#define FOSC 16000000 // Clock Speed
#define BAUD 1200
#define MYUBRR FOSC/16/BAUD-1

// Variaveis do ADC
float Tc = 11.55;                                // Variavél que armazena a temperatura convertida para Celsus

int pont = 0;
int frame_ok = 0;

char ch[10] = "\0";
char atualiza_status[10] = "\0";

int Tempo = 16666;
volatile char msbyte = 0;						// Variavél que armazena os bits mais significativos
volatile char lsbyte = 0;						// variavél que armazena os bits menos significativos

volatile int cont = 120;

void config_uC()
{
	DDRB |= (1<<PB5)|(1<<PB0);
	PORTB &= ~(1<<PB5);
	PORTB &= ~(1<<PB0);
}

void config_interrupt_timer(){

	cli();										// Desabilita todas as interrupções para configuração

	TCCR1A = 0x00;
	TCCR1B = (1<<WGM12)|(1<<CS11);				// Modo de operação: CTC; preescaler de 1:8
	OCR1A =	0;									// Inicia o timer em valor diferente de zero

	TIMSK1 |= (1<<OCIE1A);						// Habilita interrupção pelo timer1

	sei();										// Reabilita todas as interrupções

}

void USART_Init( unsigned int ubrr)
{
	
	/*Set baud rate */
	UBRR0H = (unsigned char)(ubrr>>8);
	UBRR0L = (unsigned char)ubrr;
	
	/*Enable receiver and transmitter */
	UCSR0B = (1<<RXEN0)|(1<<TXEN0);
	
	/* Set frame format: 8data, 1stop bit */
	UCSR0C = (3<<UCSZ00);
	
}

void USART_Transmit( unsigned char data )
{
	
	/* Wait for empty transmit buffer */
	while (!( UCSR0A & (1<<UDRE0)));
	
	/* Put data into buffer, sends the data */
	UDR0 = data;
	
}

unsigned char USART_Receive( void )
{
	
	/* Wait for data to be received */
	while (!(UCSR0A & (1<<RXC0)));
	
	/* Get and return received data from buffer */
	return UDR0;
	
}

void USART_putstring(char* StringPtr)
{
	while (*StringPtr != 0x00)
	{
		
		USART_Transmit(*StringPtr);
		StringPtr++;
		
	}
}

void USART_getstring()
{
	if((UCSR0A & (1<<RXC0)))
	{
		ch[pont] = UDR0;
		
		if (ch[0] != 0x23)
		{
			pont = 0;
		}
		
		if((ch[pont] == 0x2A) && (ch[0] == 0x23))
		{
			frame_ok = 1;
			pont = 0;
		}
		else
		{
			pont++;
		}
	}
}

void on_off()
{
	if(ch[2] == 0x31)
	{
		//USART_putstring("ON");	
		PORTB |= (1<<PB5);
	}
	else
	{
		//USART_putstring("OFF");	
		PORTB &= ~(1<<PB5);
	}
}

void status(float temp)
{
	USART_Transmit(0x23);
	
	USART_Transmit(0x43);
	int temp2 = temp*100;
	sprintf(atualiza_status,"%d",temp2);
	USART_putstring(atualiza_status);
	
	USART_Transmit(0x2A);
}

void led_pisca()
{
	PORTB |= (1<<PB0);
	_delay_ms(100);
	PORTB &= ~(1<<PB0);
	_delay_ms(100);	
}

void comando()
{
	if (frame_ok)
	{
		switch(ch[1])
		{		
			case 'P':
			on_off();
			led_pisca();
			break;
		}
		
		frame_ok = 0;
		memset(ch, '\0', sizeof(ch));
	}
}

ISR(TIMER1_COMPA_vect)			// Função da Interrupção pelo Timer0
{								
	USART_getstring();
	
	cont--;
}

int main(void)
{
	config_uC();
	config_interrupt_timer();
	USART_Init(MYUBRR);
	
	msbyte = (Tempo & 0xFF00) >> 8;
	lsbyte = Tempo;
			
	OCR1AH = msbyte;
	OCR1AL = lsbyte;
	
	while (1)
	{			
		comando();
		
		Tc = Tc + 1.0;

		status(Tc);
		
		while(cont != 0);
		cont = 120;
	}
}

NodeMCU

 

#define BLYNK_PRINT Serial

#include <string.h>

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "e8093a41d5a94af3b7dfb954998bbf31";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "Copel71";
char pass[] = "36927100";

int pont = 0;
int frame_ok = 0;
char chr[14] = "\0";

float Temp = 0.0;

BLYNK_WRITE(V0)
{
  int pinValue = param.asInt(); // assigning incoming value from pin V1 to a variable

  if(pinValue)
  {
    Serial.print("#P1*");
  }
  else
  {
    Serial.print("#P0*");
  }
}

BLYNK_READ(V3)
{
  // This command writes Arduino's uptime in seconds to Virtual Pin (5)
  Blynk.virtualWrite(V3, Temp);
}

void USART_getstring()
{
  if(Serial.available()>0)
  {
    int ch = Serial.read();
    chr[pont] = ch;

    if(chr[0] != 0x23)
    {
      pont = 0;
    }

    if((chr[pont] == 0x2A) && (chr[0] == 0x23))
    {
      pont = 0;
      frame_ok = 1;
    }
    else
    {
      pont++;
    }
  }
}

void setup()
{
  Serial.begin(1200);

  Blynk.begin(auth, ssid, pass);
}

void loop()
{
  Blynk.run();

  USART_getstring();

  if(frame_ok)
  {
    Temp = ((chr[2]-0x30)*1000+(chr[3]-0x30)*100+(chr[4]-0x30)*10+(chr[5]-0x30))/100.0;
    frame_ok = 0;
  }
}

Se alguém poder me ajudar.

Link para o comentário
Compartilhar em outros sites

Não tenho todos os equipamentos nem em simulação para fazer o teste que você quer...

Mas eu pego strings assim, desse código abaixo que peguei em um site por ai e modifiquei :

 

EDITADO, achei o site da onde tirei isso https://www.paulotrentin.com.br/programacao/dicas/lendo-uma-string-com-arduino-via-serial/

Claro isso ai não foi feito para teu código, mas você pode adaptar. Usei no meu projeto e ele obedecia certinho...

 

adicionado 6 minutos depois

Retirando meu código modificado do projeto que fiz uhauhauhauha

 

X)

 

Boa sorte ai... espero o resto do povo aqui da comunidade, como sempre

Link para o comentário
Compartilhar em outros sites

@Bommu Perneta Então ontem continuei os teste com os dois equipamento e percebi que esse problema quando envio mais do que um byte para o meu ATMEGA, quando envio um byte  do NodeMCU para o ATMEGA ele recebe de boa e faz a ação, porém quando envio uma string ele não funciona, o mais engraçado é que quando envio a mesma string pelo computador ela funciona no ATMEGA na boa.

 

Meu problema pode estar no envio pelo TX do NodeMCU ou no recebimento pelo RX do ATMEGA.

 

Alguém da uma forcinha que esse problema ta tenso.

Link para o comentário
Compartilhar em outros sites

Então consegui resolver em parte o problema de comunicação, porém na inicialização do NodeMCU a um problema, ele envia uma string com vários caracteres e essa string bagunça parte minha comunicação serial onde o ATMEGA para de receber os dados enviados no NodeMCU, acredito que fazendo que essa string não seja enviado resolva o problema, o problema é como.

 

Se alguém saber uma maneira de não ser enviado essa string usando o Blynk. agradeço.

Link para o comentário
Compartilhar em outros sites

Hum... olá de novo. Se ainda não resolveu...

Se é um uma coisa normal que sai quando você liga ... tipo testes de pinos e coisa do tipo... teria uma forma do teu ci ignorar tudo isso, seria colocando palavras chaves para início  ou talvez no fim da comunicação, como se fosse um chave de protocolo. Você pode também esperar um tempo mesmo com millis para normalizar essa comunicação... Acredito que seriam algumas das possibilidades.

 

Mas não sei se isso lhe ajuda muito... enfim..

adicionado 0 minutos depois

colocando if é claro...

Link para o comentário
Compartilhar em outros sites

Consegui fazer funcionar mas a solução que dei foi a seguinte, no NodeMCU eu inicializo a USART depois de ter conectado no wifi, assim evitando na inicialização aquelas mensagem estranhas, porém se cair a conexão ao se reconectar ele ainda envia essas mensagens estranhas e esse bug da mesmo com eu colocando no protocolo de comunicação um inicio e fim de mensagem, como exemplo "#Sxxxx*" onde "#" é o inicio e o "*" é o fim da mensagem. É uma coisa estranha o que acontece.

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

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...