ESP8266 UART

Hi. I'm trying to send a string from the ESP8266-01S module to PIC16F887 through UART and the string received by the PIC will be used to turn a LED on and off. The ESP has been programmed to send the string "LED1_ON" and "LED_OFF" at an interval of 2s. The PIC will turn on the LED when it receives "LED1_ON" and turn off the LED when it receives "LED1_OFF". So, the LED connected to the output pin of the PIC should be on and off every 2s. To check the string being received, I also print the string on the LCD. However, only letter 'N' and 'F' being printed on the LCD every 2s. I think the string is not being received correctly and that's causing the LED being off all the time.

I've programmed the ESP using Arduino IDE and programmed the PIC using MPLABX IDE. I don't know if it's the code on ESP side or the code on the PIC side that is causing the problem.

Code for ESP8266:

void setup() {
  Serial.begin(9600);     // Initialize the Serial interface with baud rate of 9600
}

void loop() {  
    Serial.print("LED1_ON");
    delay(2000);
    Serial.print("LED1_OFF");
    delay(2000);
}

Code for PIC:

#pragma config CONFIG1 = 0xECD4
#pragma config CONFIG2 = 0xFFFF

#define _XTAL_FREQ 8000000

/* LCD module connections */
#define LCD_RS       RD0
#define LCD_EN       RD1
#define LCD_D4       RD2
#define LCD_D5       RD3
#define LCD_D6       RD4
#define LCD_D7       RD5
#define LCD_RS_DIR   TRISD0
#define LCD_EN_DIR   TRISD1
#define LCD_D4_DIR   TRISD2
#define LCD_D5_DIR   TRISD3
#define LCD_D6_DIR   TRISD4
#define LCD_D7_DIR   TRISD5

#include <xc.h>
#include <stdio.h>         // for sprintf
#include <stdint.h>        // include stdint header
#include "UART.h"          // UART library
#include "LCD_LIB.h"       // LCD library

char UARTData[];

void __interrupt() ISR(){
    if(RCIF == 1){
        
        char i = 0;
        char c;
        
        while (UART_Data_Ready()){
            UARTData[i] = UART_GetC();
            i++;
            
            LCD_Goto(i,1);
            LCD_PutC(UARTData[i-1]);
            
            if (UARTData[i] == '\0')
                break;
        }
        
        if ( !(strcmp(UARTData, "LED1_ON")) )
            RA0 = 1;
        else
            RA0 = 0;
        
        RCIF = 0;
    }
}

void main(void) {
    
    OSCCON = 0x70;    // set internal oscillator to 8MHz
    TRISA  = 0;
    ANSEL  = 0;
    GIE    = 1;       // Enable global interrupt
    PEIE   = 1;       // Enable peripheral interrupt
    RCIE   = 1;       // Enable UART reception interrupt
    RA0    = 0;
    
    LCD_Begin();      // initialize LCD
    UART_Init(9600);  // initialize UART module with 9600 baud
    
    while(1);
    
    return;
}

LCD library for PIC:

#pragma warning disable 520

#include <stdint.h>

#define LCD_FIRST_ROW          0x80
#define LCD_SECOND_ROW         0xC0
#define LCD_THIRD_ROW          0x94
#define LCD_FOURTH_ROW         0xD4
#define LCD_CLEAR              0x01
#define LCD_RETURN_HOME        0x02
#define LCD_ENTRY_MODE_SET     0x04
#define LCD_CURSOR_OFF         0x0C
#define LCD_UNDERLINE_ON       0x0E
#define LCD_BLINK_CURSOR_ON    0x0F
#define LCD_MOVE_CURSOR_LEFT   0x10
#define LCD_MOVE_CURSOR_RIGHT  0x14
#define LCD_TURN_ON            0x0C
#define LCD_TURN_OFF           0x08
#define LCD_SHIFT_LEFT         0x18
#define LCD_SHIFT_RIGHT        0x1E

#ifndef LCD_TYPE
   #define LCD_TYPE 2           // 0=5x7, 1=5x10, 2=2 lines
#endif

__bit RS;

void LCD_Write_Nibble(uint8_t n);
void LCD_Cmd(uint8_t Command);
void LCD_Goto(uint8_t col, uint8_t row);
void LCD_PutC(char LCD_Char);
void LCD_Print(char* LCD_Str);
void LCD_Begin();

/* NOTE: The pin number for LCD_RS, LCD_D4, ... are defined in main file */
void LCD_Write_Nibble(uint8_t n)
{
    LCD_RS = RS;
    LCD_D4 = n & 0x01;
    LCD_D5 = (n >> 1) & 0x01;
    LCD_D6 = (n >> 2) & 0x01;
    LCD_D7 = (n >> 3) & 0x01;

    // send enable pulse
    LCD_EN = 0;
    __delay_us(1);
    LCD_EN = 1;
    __delay_us(1);
    LCD_EN = 0;
    __delay_us(100);
}

void LCD_Cmd(uint8_t Command)
{
    RS = 0;
    LCD_Write_Nibble(Command >> 4);
    LCD_Write_Nibble(Command);
    if((Command == LCD_CLEAR) || (Command == LCD_RETURN_HOME))
      __delay_ms(2);
}

void LCD_Goto(uint8_t col, uint8_t row)
{
    switch(row)
    {
        case 2:
            LCD_Cmd(LCD_SECOND_ROW + col - 1);
            break;
        case 3:
            LCD_Cmd(LCD_THIRD_ROW  + col - 1);
            break;
        case 4:
            LCD_Cmd(LCD_FOURTH_ROW + col - 1);
        break;
        default:      // case 1:
            LCD_Cmd(LCD_FIRST_ROW  + col - 1);
    }
}

void LCD_PutC(char LCD_Char)
{
    RS = 1;
    LCD_Write_Nibble(LCD_Char >> 4);
    LCD_Write_Nibble(LCD_Char );
}

void LCD_Print(char* LCD_Str)
{
    uint8_t i = 0;
    RS = 1;
    while(LCD_Str[i] != '\0')
    {
      LCD_Write_Nibble(LCD_Str[i] >> 4);
      LCD_Write_Nibble(LCD_Str[i++] );
    }
}

void LCD_Begin()
{
    RS = 0;

    LCD_RS     = 0;
    LCD_EN     = 0;
    LCD_D4     = 0;
    LCD_D5     = 0;
    LCD_D6     = 0;
    LCD_D7     = 0;
    LCD_RS_DIR = 0;
    LCD_EN_DIR = 0;
    LCD_D4_DIR = 0;
    LCD_D5_DIR = 0;
    LCD_D6_DIR = 0;
    LCD_D7_DIR = 0;

    __delay_ms(40);
    LCD_Cmd(3);
    __delay_ms(5);
    LCD_Cmd(3);
    __delay_ms(5);
    LCD_Cmd(3);
    __delay_ms(5);
    LCD_Cmd(LCD_RETURN_HOME);
    __delay_ms(5);
    LCD_Cmd(0x20 | (LCD_TYPE << 2));
    __delay_ms(50);
    LCD_Cmd(LCD_TURN_ON);
    __delay_ms(50);
    LCD_Cmd(LCD_CLEAR);
    __delay_ms(50);
    LCD_Cmd(LCD_ENTRY_MODE_SET | LCD_RETURN_HOME);
    __delay_ms(50);
}

UART library for PIC:

void UART_Init(const uint32_t baud_rate)
{
    int16_t n = ( _XTAL_FREQ / (16 * baud_rate) ) - 1;

    if (n < 0)
      n = 0;

    if (n > 255)  // low speed
    {
      n = ( _XTAL_FREQ / (64 * baud_rate) ) - 1;
      if (n > 255)
        n = 255;
      SPBRG = n;
      TXSTA = 0x20;  // transmit enabled, low speed mode
    }

    else   // high speed
    {
      SPBRG = n;
      TXSTA = 0x24;  // transmit enabled, high speed mode
    }

    RCSTA = 0x90;  // serial port enabled, continues receive enabled
}

__bit UART_Data_Ready()
{
    return RCIF;  // return RCIF bit (register PIR1, bit 5)
}

uint8_t UART_GetC()
{
    while (RCIF == 0) ;  // wait for data receive
    if (OERR)  // if there is overrun error
    {  // clear overrun error bit
      CREN = 0;
      CREN = 1;
    }
    return RCREG;        // read from EUSART receive data register
}
 
void UART_PutC(const char data)
{
    while (TRMT == 0);  // wait for transmit shift register to be empty
    TXREG = data;       // update EUSART transmit data register
}
 
void UART_Print(const char *data)
{
    uint8_t i = 0;
    while (data[i] != '\0')
        UART_PutC (data[i++]);
}

For the hardware part, I've use a level shifter between the ESP and the PIC. The TX of the ESP is connected to the RX of the PIC and the RX of the ESP is connected to the TX of the PIC.

Thanks for your help.

char UARTData[];

your buffer has no size

try this ,
char UARTData[16];

I've tried that, but it's still the same.

none of this should be done in the isr

   LCD_Goto(i,1);
            LCD_PutC(UARTData[i-1]);
           
            if (UARTData[i] == '\0')
                break;
        }
       
        if ( !(strcmp(UARTData, "LED1_ON")) )
            RA0 = 1;
        else
            RA0 = 0;

the isr should simply place rx data into the buffer providing the buffer is not full and reception enabled.
when a complete msg is is recorded or the buffer is full a flag should be set to signal main loop that data is ready to be processed.
the main loop can then act on the received msg, clear the buffer and allow the isr to resume reception

on the esp use
Serial.println("LED1_ON");

then the newline chr \n can be use to signal the pic that the message is complete and ready to process

1. Is the ISR() called upon after the arrival of each character from the ESP? Y/N?
2. When does RCIF becomes HIGH?
3. Does the UART_Data_Ready bit become HIGH after the arrival of each character?
4. Is the Serial FIFO Buffer concept of PIC Platform similar to that of Arduino? Y/N?

simple pic rx code to try [untested]
[your code seems to be a pretty ancient ver of xc8/mplabx so my use of SFRbits.bitname syntax might not compile]

#pragma config CONFIG1 = 0xECD4
#pragma config CONFIG2 = 0xFFFF

#define _XTAL_FREQ 8000000

/* LCD module connections */
#define LCD_RS       RD0
#define LCD_EN       RD1
#define LCD_D4       RD2
#define LCD_D5       RD3
#define LCD_D6       RD4
#define LCD_D7       RD5
#define LCD_RS_DIR   TRISD0
#define LCD_EN_DIR   TRISD1
#define LCD_D4_DIR   TRISD2
#define LCD_D5_DIR   TRISD3
#define LCD_D6_DIR   TRISD4
#define LCD_D7_DIR   TRISD5

#include <xc.h>
#include <stdio.h>         // for sprintf
#include <stdint.h>        // include stdint header
#include "UART.h"          // UART library
#include "LCD_LIB.h"       // LCD library

char UARTData[16];
volatile char rxCount,msgReady=0;

void __interrupt() ISR(){
    if(RCIF == 1){
        char c;
       
        while (UART_Data_Ready()){
            UARTData[rxCount] = UART_GetC();
            rxCount++;
         if(rxcount>15||RCREG==13){
            msgReady=1;
            PIE1bits.RCIE=0; //isr off
          }


        //RCIF = 0;// ?? that bit is readonly
    }
}

void main(void) {
     char inx=0;
    OSCCON = 0x70;    // set internal oscillator to 8MHz
    TRISA  = 0;
    ANSEL  = 0;
    GIE    = 1;       // Enable global interrupt
    PEIE   = 1;       // Enable peripheral interrupt
    RCIE   = 1;       // Enable UART reception interrupt //PIE1bits.RCIE=1
    RA0    = 0;
    
    LCD_Begin();      // initialize LCD
    UART_Init(9600);  // initialize UART module with 9600 baud
   
    while(1){
    if( msgReady){
          LCD_Goto(i,1);
         inx=0;
         while (rxCount++)
            LCD_PutC(UARTData[inx++]);
        msgReady=0;
        PIE1bits.RCIE=1;reenable isr
        RCSTAbits.CREN=0; //clear buffer over run error
        RCSTAbits.CREN=1;
     }
   
   }
}

Thanks for your help, but the LCD prints all the weird characters when I upload your code to the PIC. I have modified my code a little bit, declaring the array with size, and some other modification. It's working now, thank you.