Showing posts with label Tutorial. Show all posts
Showing posts with label Tutorial. Show all posts

Tuesday, April 19, 2016

Graphic 128x64 LCD interface with Atmega8 and Arduino

This tutorial describes how to interface between a 128x64 graphic LCD and an 8-bit
micro-controller. The techniques described here are useful for any other controller type and
interfacing technique. The micro-controller is connected via its I/O lines and all signals to the LCD are controlled directly by software. All control electronics, contrast control and bias circuits and temperature compensation circuits are built into the module. Each of these circuits is described separately below.

Display mapping: Individual pixels can be controlled by writing a byte to a specific address. Each address is mapped to a corresponding set of 8 pixels on the display. Please refer to Figure 1. Note that the order of the columns is reversed. The first byte of data entered after setting the address registers to 0 will appear in the upper right of the display.






This display has blue/yelow backlight and white/black writing, and with it (and the right library) you can really cool graphical effects such as screen rotation, change text fonts, text rotation and, of course, draw. I published a short video on YouTube showing some of these functions:

The display has 20 pins, numbered from right to left, as we can see in the picture below. It can be used to communicate with the Arduino both serial and parallel manner. In this article, where the LCD refresh rate is not a critical point, we will use the serial communication, occupying only 4 Arduino ports:
The circuit uses a potentiometer (used a 50K) for adjusting the display contrast, and power is made ​​by 5v power supply. 

Method 1: Uses 13 IO Lines
download Proteus simulation file

Graphic 128x64 LCD interface with AVR Arduino


Code for Method 1:

Save this as "GraphicLCD.h"

#include <avr/io.h>
#include <string.h>
//#include <avr/pgmspace.h> 
#include <avr/interrupt.h>

#define RS    PA1  
#define E     PA3  
#define CS1    PC3  
#define CS2    PC2
#define RST    PC1

#define DATA   PORTD


void Delay1();
void InitLCD();
void LCDout(char a);
void Epulse();
void PutPixel(unsigned char x,unsigned char y,char color);
void LCD_Clear();
void line(char x0, char y0, char x1, char y1,char color);
void rect(char x0, char y0, char x1, char y1,char color);
//void circle(int xCenter, int yCenter, int radius, char c);
void DisplayChar(unsigned char x,unsigned char y, char d);
void DisplayText(unsigned char x, unsigned char y, char d[21]);
void DisplayCharSmall(unsigned char x,unsigned char y, char d);
char Pix[128][8];
//char mystr[16], Height[4], Height1[4],bits;
//uint32_t WordOfData; 
//long Cunt;
//int Height;
/*--------------------------------------------------------------------------------------------------
                                     Character generator

             This table defines the standard ASCII characters in a 5x7 dot format.
--------------------------------------------------------------------------------------------------*/
PROGMEM static const char FontLookup [][5] =
{
 {0x00, 0x00, 0x00, 0x00, 0x00},// (space) 
 {0x00, 0x00, 0x5F, 0x00, 0x00},// ! 
 {0x00, 0x07, 0x00, 0x07, 0x00},// " 
 {0x14, 0x7F, 0x14, 0x7F, 0x14},// # 
 {0x24, 0x2A, 0x7F, 0x2A, 0x12},// $ 
 {0x23, 0x13, 0x08, 0x64, 0x62},// % 
 {0x36, 0x49, 0x55, 0x22, 0x50},// & 
 {0x00, 0x05, 0x03, 0x00, 0x00},// ' 
 {0x00, 0x1C, 0x22, 0x41, 0x00},// ( 
 {0x00, 0x41, 0x22, 0x1C, 0x00},// ) 
 {0x08, 0x2A, 0x1C, 0x2A, 0x08},// * 
 {0x08, 0x08, 0x3E, 0x08, 0x08},// + 
 {0x00, 0x50, 0x30, 0x00, 0x00},// , 
 {0x08, 0x08, 0x08, 0x08, 0x08},// - 
 {0x00, 0x30, 0x30, 0x00, 0x00},// . 
 {0x20, 0x10, 0x08, 0x04, 0x02},// / 
 {0x3E, 0x51, 0x49, 0x45, 0x3E},// 0 
 {0x00, 0x42, 0x7F, 0x40, 0x00},// 1 
 {0x42, 0x61, 0x51, 0x49, 0x46},// 2 
 {0x21, 0x41, 0x45, 0x4B, 0x31},// 3 
 {0x18, 0x14, 0x12, 0x7F, 0x10},// 4 
 {0x27, 0x45, 0x45, 0x45, 0x39},// 5 
 {0x3C, 0x4A, 0x49, 0x49, 0x30},// 6 
 {0x01, 0x71, 0x09, 0x05, 0x03},// 7 
 {0x36, 0x49, 0x49, 0x49, 0x36},// 8 
 {0x06, 0x49, 0x49, 0x29, 0x1E},// 9 
 {0x00, 0x36, 0x36, 0x00, 0x00},// : 
 {0x00, 0x56, 0x36, 0x00, 0x00},// ; 
 {0x00, 0x08, 0x14, 0x22, 0x41},// < 
 {0x14, 0x14, 0x14, 0x14, 0x14},// = 
 {0x41, 0x22, 0x14, 0x08, 0x00},// > 
 {0x02, 0x01, 0x51, 0x09, 0x06},// ? 
 {0x32, 0x49, 0x79, 0x41, 0x3E},// @ 
 {0x7E, 0x11, 0x11, 0x11, 0x7E},// A 
 {0x7F, 0x49, 0x49, 0x49, 0x36},// B 
 {0x3E, 0x41, 0x41, 0x41, 0x22},// C 
 {0x7F, 0x41, 0x41, 0x22, 0x1C},// D 
 {0x7F, 0x49, 0x49, 0x49, 0x41},// E 
 {0x7F, 0x09, 0x09, 0x01, 0x01},// F 
 {0x3E, 0x41, 0x41, 0x51, 0x32},// G 
 {0x7F, 0x08, 0x08, 0x08, 0x7F},// H 
 {0x00, 0x41, 0x7F, 0x41, 0x00},// I 
 {0x20, 0x40, 0x41, 0x3F, 0x01},// J 
 {0x7F, 0x08, 0x14, 0x22, 0x41},// K 
 {0x7F, 0x40, 0x40, 0x40, 0x40},// L 
 {0x7F, 0x02, 0x04, 0x02, 0x7F},// M 
 {0x7F, 0x04, 0x08, 0x10, 0x7F},// N 
 {0x3E, 0x41, 0x41, 0x41, 0x3E},// O 
 {0x7F, 0x09, 0x09, 0x09, 0x06},// P 
 {0x3E, 0x41, 0x51, 0x21, 0x5E},// Q 
 {0x7F, 0x09, 0x19, 0x29, 0x46},// R 
 {0x46, 0x49, 0x49, 0x49, 0x31},// S 
 {0x01, 0x01, 0x7F, 0x01, 0x01},// T 
 {0x3F, 0x40, 0x40, 0x40, 0x3F},// U 
 {0x1F, 0x20, 0x40, 0x20, 0x1F},// V 
 {0x7F, 0x20, 0x18, 0x20, 0x7F},// W 
 {0x63, 0x14, 0x08, 0x14, 0x63},// X 
 {0x03, 0x04, 0x78, 0x04, 0x03},// Y 
 {0x61, 0x51, 0x49, 0x45, 0x43},// Z 
 {0x00, 0x00, 0x7F, 0x41, 0x41},// [ 
 {0x02, 0x04, 0x08, 0x10, 0x20},// "\" 
 {0x41, 0x41, 0x7F, 0x00, 0x00},// ] 
 {0x04, 0x02, 0x01, 0x02, 0x04},// ^ 
 {0x40, 0x40, 0x40, 0x40, 0x40},// _ 
 {0x00, 0x01, 0x02, 0x04, 0x00},// ` 
 {0x20, 0x54, 0x54, 0x54, 0x78},// a 
 {0x7F, 0x48, 0x44, 0x44, 0x38},// b 
 {0x38, 0x44, 0x44, 0x44, 0x20},// c 
 {0x38, 0x44, 0x44, 0x48, 0x7F},// d 
 {0x38, 0x54, 0x54, 0x54, 0x18},// e 
 {0x08, 0x7E, 0x09, 0x01, 0x02},// f 
 {0x08, 0x14, 0x54, 0x54, 0x3C},// g 
 {0x7F, 0x08, 0x04, 0x04, 0x78},// h 
 {0x00, 0x44, 0x7D, 0x40, 0x00},// i 
 {0x20, 0x40, 0x44, 0x3D, 0x00},// j 
 {0x00, 0x7F, 0x10, 0x28, 0x44},// k 
 {0x00, 0x41, 0x7F, 0x40, 0x00},// l 
 {0x7C, 0x04, 0x18, 0x04, 0x78},// m 
 {0x7C, 0x08, 0x04, 0x04, 0x78},// n 
 {0x38, 0x44, 0x44, 0x44, 0x38},// o 
 {0x7C, 0x14, 0x14, 0x14, 0x08},// p 
 {0x08, 0x14, 0x14, 0x18, 0x7C},// q 
 {0x7C, 0x08, 0x04, 0x04, 0x08},// r 
 {0x48, 0x54, 0x54, 0x54, 0x20},// s 
 {0x04, 0x3F, 0x44, 0x40, 0x20},// t 
 {0x3C, 0x40, 0x40, 0x20, 0x7C},// u 
 {0x1C, 0x20, 0x40, 0x20, 0x1C},// v 
 {0x3C, 0x40, 0x30, 0x40, 0x3C},// w 
 {0x44, 0x28, 0x10, 0x28, 0x44},// x 
 {0x0C, 0x50, 0x50, 0x50, 0x3C},// y 
 {0x44, 0x64, 0x54, 0x4C, 0x44},// z 
 {0x00, 0x08, 0x36, 0x41, 0x00},// { 
 {0x00, 0x00, 0x7F, 0x00, 0x00},// | 
 {0x00, 0x41, 0x36, 0x08, 0x00},// } 
 {0x08, 0x08, 0x2A, 0x1C, 0x08},// -> 
 {0x08, 0x1C, 0x2A, 0x08, 0x08} // <- 
};

//Hex And Decimal Numbers in 3 X 5 Format 
PROGMEM static const char FontLookup1 [][3] =
{
    { 0xF8, 0x88, 0xF8 },   // 0
    { 0x48, 0xF8, 0x08 },   // 1
    { 0xB8, 0xA8, 0xE8 },   // 2
    { 0xA8, 0xA8, 0xF8 },   // 3
    { 0xE0, 0x20, 0xF8 },   // 4
    { 0xE8, 0xA8, 0xB8 },   // 5
    { 0xF8, 0xA8, 0xB8 },   // 6
    { 0x80, 0x80, 0xF8 },   // 7
    { 0xF8, 0xA8, 0xF8 },   // 8
    { 0xE8, 0xA8, 0xF8 },   // 9
 { 0xF8, 0xA0, 0xF8 },   // A
    { 0xF8, 0xA8, 0x50 },   // B
    { 0xF8, 0x88, 0x88 },   // C
    { 0x88, 0xF8, 0xF8 },   // D
    { 0xF8, 0xA8, 0xA8 },   // E
    { 0xF8, 0xA0, 0xA0 },   // F
 { 0x00, 0x00, 0x00 },   // Space
};

/*********************************************************************************/
/*         MAIN PROGRAM                                 */
/*********************************************************************************/
/*********************************************************************************/
/*         LCD out                                   */
/*********************************************************************************/
void LCDout(char a)
{
 PORTD = a;
 Epulse();
}

/*********************************************************************************/
/*         DELAY 100mSec                                */
/*********************************************************************************/
void Delay1()
{
 int t;
  for(t=0;t<125;t++);
}

/*********************************************************************************/
/*         Init LCD                                     */
/*********************************************************************************/

void InitLCD()
{
    DDRD = 0xFF;
 DDRA |=(1<<RS);
 DDRA |=(1<<E);
 DDRC |=(1<<CS1);
 DDRC |=(1<<CS2);
 DDRC |=(1<<RST);

 PORTC &= ~(1<<RST);   //Make sure rst state
 Delay1();
 PORTC |= (1<<RST);   //Make sure rst state
 Delay1();

 PORTA &=~(1<<RS);  //Command mode
    PORTC |= (1<<CS1);  //CS1 CS2 selected
    PORTC |= (1<<CS2);  //CS1 CS2 selected
 LCDout(0x3F);   //LCD on
 LCDout(0xC0);   //z-axis to zero 

 Delay1();
 Delay1();
 PORTC &=~ (1<<CS1);  
    PORTC &=~ (1<<CS2);  
}

/*********************************************************************************/
/*         Enable Pulse                                 */
/*********************************************************************************/
void Epulse()
{
 //E=PA3
 PORTA = PORTA | 0x08;
 PORTA = PORTA & 0xF7;
}

/*********************************************************************************/
/*         PUT PIXEL(X,Y,color)                         */
/*********************************************************************************/
void PutPixel(unsigned char x,unsigned char y, char color)
{

//Inverse Display
//x = 127-x;
//y = 63-y;

unsigned char c,y1;
c=0;
y1=y; //+3
   
   while(y1 >= 8)
   {
     y1=y1-8;
  c++;
   }

if (x < 64)
{
 PORTA &=~(1<<RS);  //Command mode
    PORTC |= (1<<CS1);  //CS1 selected
 PORTC &=~(1<<CS2);
 c = c & 0x07;
 LCDout(0xB8 | c);  //C (y-axis) is having 3-bit address
 x = x & 0x3F;
 LCDout(0x40 | x);  //C (x-axis) is having 3-bit address
}
else
{
 x = x - 64;
 PORTA &=~(1<<RS);  //Command mode
 PORTC &=~(1<<CS1);  
    PORTC |= (1<<CS2);  //CS2 selected
 c = c & 0x07;
 LCDout(0xB8 | c);  //C (y-axis) is having 3-bit address
 x = x & 0x3F;
 LCDout(0x40 | x);  //C (x-axis) is having 3-bit address
 x = x+64;
}
 
 PORTA |= (1<<RS); 
  if(color==1)
  {
  Pix [x][c]=(Pix [x][c]) | (1<<y1) ;  //y1 is having bit position to set
  LCDout(Pix [x][c]);
 }
 else
 {
  Pix [x][c] &=~ (1<<y1);  //y1 is having bit position to reset
  LCDout(Pix [x][c]);
 }
}

/*********************************************************************************/
/*         LCD CLEAR                                    */
/*********************************************************************************/

void LCD_Clear()
{
unsigned char x,y;
 
unsigned char c;
c=0;
   for(y=0;y<8;y++)
    {
 c=y;
   for(x=0;x<128;x++)
    {
     Pix[x][y]=0x00;
  //=======================
   if ( x < 64)
   {
    PORTA &=~(1<<RS);  //Command mode
       PORTC |= (1<<CS1);  //CS1 selected
    PORTC &=~(1<<CS2);
    c = c & 0x07;
    LCDout(0xB8 | c);  //C (y-axis) is having 3-bit address
    x = x & 0x3F;
    LCDout(0x40 | x);  //C (x-axis) is having 3-bit address
   }
   else
   {
    x = x - 64;
    PORTA &=~(1<<RS);  //Command mode
    PORTC &=~(1<<CS1);  
       PORTC |= (1<<CS2);  //CS2 selected
    c = c & 0x07;
    LCDout(0xB8 | c);  //C (y-axis) is having 3-bit address
    x = x & 0x3F;
    LCDout(0x40 | x);  //C (x-axis) is having 3-bit address
    x = x+64;
   }
   PORTA |=(1<<RS);
   LCDout(0x00);
  //=======================
   
    }
    }
}
/*********************************************************************************/
/*         LINE(X0,Y0,X1,Y1,color)                      */
/*********************************************************************************/

void line(char x0, char y0, char x1, char y1,char color) 
{
 int dy = y1 - y0;
 int dx = x1 - x0;
 int stepx, stepy;
 if (dy < 0) { dy = -dy; stepy = -1; 
 } else { stepy = 1; 
 }
  if (dx < 0) { dx = -dx; stepx = -1; 
 } else { stepx = 1; 
 }
 dy <<= 1;        // dy is now 2*dy
 dx <<= 1;        // dx is now 2*dx
 
 PutPixel(x0, y0,color);

 if (dx > dy) {
  int fraction = dy - (dx >> 1); // same as 2*dy - dx
  while (x0 != x1) {
   if (fraction >= 0) {
    y0 += stepy;
    fraction -= dx;   // same as fraction -= 2*dx
   }
     x0 += stepx;
     fraction += dy;     // same as fraction -= 2*dy
     PutPixel(x0, y0,color);
  }
 } else {
  int fraction = dx - (dy >> 1);
  while (y0 != y1) {
   if (fraction >= 0) {
    x0 += stepx;
    fraction -= dy;
   }
  y0 += stepy;
  fraction += dx;
  PutPixel(x0, y0,color);
  }
 }
} 
/*********************************************************************************/
/*         RECT(X0,Y0,X1,Y1,color)                      */
/*********************************************************************************/
void rect(char x0, char y0, char x1, char y1,char color)
{
 line(x0,y0,x1,y0,color);
 line(x0,y0,x0,y1,color);
 line(x0,y1,x1,y1,color);
 line(x1,y0,x1,y1,color); 
}

/*********************************************************************************/
/*         Circle(X0,Y0,radius,color)                   */
/*********************************************************************************/
void circle(int xCenter, int yCenter, int radius, char c)
    {
        int x, y, r2;

        r2 = radius * radius;
        PutPixel(xCenter, yCenter + radius,c);
        PutPixel(xCenter, yCenter - radius,c);
        PutPixel(xCenter + radius, yCenter,c);
        PutPixel(xCenter - radius, yCenter,c);
        x = 1;
        y = (int) (sqrt(r2 - 1) + 0.5);
        while (x < y) {
            PutPixel(xCenter + x, yCenter + y,c);
            PutPixel(xCenter + x, yCenter - y,c);
            PutPixel(xCenter - x, yCenter + y,c);
            PutPixel(xCenter - x, yCenter - y,c);
            PutPixel(xCenter + y, yCenter + x,c);
            PutPixel(xCenter + y, yCenter - x,c);
            PutPixel(xCenter - y, yCenter + x,c);
            PutPixel(xCenter - y, yCenter - x,c);
            x += 1;
            y = (int) (sqrt(r2 - x*x) + 0.5);
        }
        if (x == y) {
            PutPixel(xCenter + x, yCenter + y,c);
            PutPixel(xCenter + x, yCenter - y,c);
            PutPixel(xCenter - x, yCenter + y,c);
            PutPixel(xCenter - x, yCenter - y,c);
        }
    }
/*********************************************************************************/
/*         Display Text (5x7)                       */
/*********************************************************************************/
void DisplayChar(unsigned char x,unsigned char y, char d)
{
unsigned char r,c,c1;
d=d-32;
 for(r=0;r<5;r++)
 {
  c1=0;   //4
  for(c=0;c<8;c++)
  {
   PutPixel(x+r,y+c1,((0x01) & (pgm_read_byte(&FontLookup[d][r]) >> c )));//>>(c+3)
   c1=c1+1;
  }
 }
}
/*********************************************************************************/
/*         Display Text (3x5)                       */
/*********************************************************************************/
void DisplayCharSmall(unsigned char x,unsigned char y, char d)
{
unsigned char r,c,c1;
 for(r=0;r<3;r++)
 {
  c1=4;  
  for(c=0;c<5;c++)
  {
   PutPixel(x+r,y+c1,((0x01) & (pgm_read_byte(&FontLookup1[d][r]) >> (c+3))));
   c1=c1-1;
  }
 }
}

/*********************************************************************************/
/*         Display Text (5x7)                       */
/*********************************************************************************/
void DisplayText(unsigned char x, unsigned char y, char d[21])
{
int i;
int j;
j=strlen(d);
 for (i=0;i<j;i++)
 {
  DisplayChar((i*6)+x,y,d[i]);
 } 
}


Main Program File: save as main.c



/*********************************************************************************/
/*   blog.circuits4you.com */
/*  128x64 Graphic LCD Demo Code */
/*********************************************************************************/
#include <avr/io.h>
#include <string.h>
#include <avr/pgmspace.h> 
#include "GraphicLCD.h"


void Delay();
void Wait();
/*********************************************************************************/
/*         MAIN PROGRAM                                 */
/*********************************************************************************/
int main(void)
{
 Delay();
 InitLCD(); 
 LCD_Clear(); 

 DisplayText(1,3,"blog.circuits4you.com");
 DisplayText(1,15,"   GLCD 128x64 Demo ");
 circle(40,40,20,1);
 line(20,20,64,64,1);
 rect(15,15,100,60,1);
 //PutPixel(unsigned char x,unsigned char y, char color);
 //line(char x0, char y0, char x1, char y1,char color) 
 //DisplayCharSmall(unsigned char x,unsigned char y, char d)


  Wait();
  Wait();
  Wait();
  Wait();
  LCD_Clear();
  Delay100ms();
}

/*********************************************************************************/
/*      100 mSec Delay                    */
/*********************************************************************************/
void Delay100ms()
{
int k;
 for(k=-29000;k<29000;k++)
 {
  asm("nop");
 }
}
/*********************************************************************************/
/*         DELAY 100mSec                                */
/*********************************************************************************/
void Delay()
{
 int t;
  for(t=-22500;t<22500;t++);
}
/****************************************************************************************/
/*           WAIT                                              */
/****************************************************************************************/
void Wait()
{
  Delay100ms();
  Delay100ms();
  Delay100ms();
  Delay100ms();
  Delay100ms();
  Delay100ms();
  Delay100ms();
  Delay100ms();
  Delay100ms();
  Delay100ms();
  Delay100ms();
}

Method 2 uses only 8 IO Lines:
download Proteus simulation file
Graphic 128x64 LCD interfacing

GraphicLCD.h file for above circuit

main program remains same for both circuits





Saturday, April 2, 2016

Wireless Serial using nRF24L01+

This project is very useful in many application where wireless reliable serial communication is required. It give bidirectional communication, You need to have same code in both arduino, no need of separate configuration for receiver or transmitter. It is more advantageous and cost saving than using Xbee, Zegbee Modules.

This circuit is consists of Arduino Pro Mini 3.3V 8MHz and nRF24L01+ RF Module, this make it very low cost and reliable, it can communicate at longer distances when we use nRF24L01+ PA LNA module.

The code is done with most advance possible conditions here I am using custom serial software routine instead of arduino serial to make possible to have 256bytes of serial buffer. arduino have only 64 bytes of serial buffer for longer serial data use of internal buffer causes problems so I made my own serial rutine

Let's look at its advantages nRF24L01+ modules are very cheap and low power consuming, you can power your circuit using 3V battery also, that's why I am using Arduino Pro Mini 3.3V 8MHz, you can use any arduino board, only take care that supply to nRF24L01+ module must be 3.3V, nRF24L01+ can take 5V on its IO lines so no need to have any level conversion circuits.

Applications of this projects are limitless you can use it for your robotic applications, remote sensing, wireless remote control, RC air craft as nRF24L01+ PA LNA module can give open air 1000 meter range.

Components required:
1. nRF24L01+ Quantity 2.
2. Two arduino boards.

Introduction to nRF24L01+:
The nRF24L01+ is a single chip 2.4GHz transceiver with an embedded baseband protocol engine, suitable for ultra low power wireless applications. The nRF24L01+ is designed for operation in the world wide ISM frequency band at 2.400-2.4835GHz.

To design a radio system with the nRF24L01+, you simply need an microcontroller and a few external passive components.

You can operate and configure the nRF24L01+ through a Serial Peripheral Interface (SPI). The register map, which is accessible through the SPI, contains all configuration registers in the nRF24L01+ and is accessible in all operation modes of the chip.

The embedded baseband protocol engine is based on paket communication and supports various modes from manual operation to advanced autonomous protocol operation.

Internal FIFOs ensure a smooth data flow between the radio front end and the system's microcontroller. Enhanced Shock-Burst reduces system cost by handling all the high speed link layer operations.

The radio front end uses GFSK modulation. It has user configurable parameters like frequency channel, output power and air data rate. nRF24L01+ supports an air data rate of 250kbps, 1Mbps and 2Mbps. The high air data rate combined with two power saving modes make the nRF24L01+ very suitable for ultra low power designs.


Step 1: Circuit Connections of nRF24L01+ with Arduino Pro Mini you can use Arduino Uno also with same code and connections

Wireless Serial Communication circuit


Step 2: Programming
RF24 library is required you can download it from arduino web site
You can modify the program if you want to control your robotics with wireless serial.
At serial send subroutine wireless received  data is sent to serial, and when serial data is received it is put into buffer then transmitter through nRF24L01+

Use same code in both arduino boards.
//Blog.Circuits4you.com Wireless serial communication
//26-Jan-2015
//DO NOT FORGET BAUD RATE SETTINGS FOR 8MHz MINI PRO

#include <avr/io.h>
#include <avr/interrupt.h>
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

RF24 radio(9,10);
const uint64_t pipes[2] = { 0xDEDEDEDEE7LL, 0xDEDEDEDEE9LL };

char SerialBuffer[256] = "";
char RecvPayload[128] = "";
int i,TimeOut=10,dataBufferIndex=0;

void setup() {
  radio.begin();
  
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_MAX);
  radio.setChannel(70);
  
  radio.enableDynamicPayloads();
  radio.setRetries(15,15);
  radio.setCRCLength(RF24_CRC_16);

  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1,pipes[1]);  
  
  radio.startListening();
   
  
  USART_Init();  
  SREG=0x80;  
  delay(500);
}

void loop() {
  nRF_receive();  
  
  if(TimeOut==0 && dataBufferIndex>0)
  {
    serial_receive();        // Send this buffer out to radio
  }
  else
  {
    TimeOut--;
  }
}

void USART_vSendByte(char u8Data)
{
  // Wait if a byte is being transmitted
  while((UCSR0A & (1<<UDRE0)) == 0);
  // Transmit data
  UDR0 = u8Data; 
}

/****************************************************************************************/
/*                                                                          USART INIT                                        */
/****************************************************************************************/
void USART_Init()
{
  /*Set baud rate */
  UBRR0H = 0;
  UBRR0L = 51;  //103 @ 16MHz  51 @ 8MHz
  //Set double speed enabled 
  UCSR0A |= (1<<U2X0);
   
  /*Enable receiver and transmitter */
  UCSR0B = (1<<RXEN0)|(1<<TXEN0) | (1<<RXCIE0);
  /* Set frame format: 8data, 2stop bit */
  UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}
/****************************************************************************************/
/*           USART ISR                                         */
/****************************************************************************************/
SIGNAL(USART_RX_vect)
{
        char incomingByte = UDR0;
        SerialBuffer[dataBufferIndex++]=incomingByte;    
        TimeOut=2000;
 sei();
 return; 
}
/****************************************************************************************/
/*                RF Receive                                                            */
/****************************************************************************************/
void nRF_receive(void) {
  int len = 0;
  if ( radio.available() ) {
      bool done = false;
      while ( !done ) {
        len = radio.getDynamicPayloadSize();
        done = radio.read(&RecvPayload,len);
        delay(5);
      }
  
    RecvPayload[len] = 0; // null terminate string
    
     for(i=0;i<len;i++)
    {
      USART_vSendByte(RecvPayload[i]);      
    }
    RecvPayload[0] = 0;  // Clear the buffers
  }  

}

void serial_receive(void)
{
        char SendPayLoad[32];
        // swap TX & Rx addr for writing
        radio.openWritingPipe(pipes[1]);
        radio.openReadingPipe(0,pipes[0]);  
        radio.stopListening();
        
        if(dataBufferIndex<31)      //as nRF24L02 have only 32 byte of buffer to send more bytes it need to be splitted
        {          
          bool ok = radio.write(&SerialBuffer,dataBufferIndex);
        }
        else  
        {
          for(i=0;i<30;i++)
          {
            SendPayLoad[i]=SerialBuffer[i];
          }
            bool ok = radio.write(&SendPayLoad,30);    //First 30 Bytes are sent
          
          if((dataBufferIndex-30)<31)    //If remainging bytes are less than 31
          {
              for(i=0;i<(dataBufferIndex-30);i++)
              {
                SendPayLoad[i]=SerialBuffer[i+30];
              }
            bool ok = radio.write(&SendPayLoad,(dataBufferIndex-30));    //Remaining Bytes are sent
          }
          else                            //Remaining bytes are more than 31 i.e total is greater than 60
          {
                      for(i=0;i<30;i++)
                      {
                        SendPayLoad[i]=SerialBuffer[i+30];    
                      }
                        bool ok = radio.write(&SendPayLoad,30);    //60 Bytes are sent
                      
                      if((dataBufferIndex-60)<31)    //If remainging bytes are less than 31 
                      {
                          for(i=0;i<(dataBufferIndex-30);i++)
                          {
                            SendPayLoad[i]=SerialBuffer[i+60];
                          }
                        bool ok = radio.write(&SendPayLoad,(dataBufferIndex-60));    //Remaining Bytes are sent
                      }
          }
        }
        // restore TX & Rx addr for reading       
        radio.openWritingPipe(pipes[0]);
        radio.openReadingPipe(1,pipes[1]); 
        radio.startListening();  

        SerialBuffer[0] = 0;  // Clear the buffers
        dataBufferIndex = 0;
} // end serial_receive()  

#ifndef min
#define min(a,b) ( (a) < (b) ? (a) : (b) )
#endif
 
void mid(const char *src, size_t start, size_t length, char *dst, size_t dstlen)
{       size_t len = min( dstlen - 1, length);
 
        strncpy(dst, src + start, len);
        // zero terminate because strncpy() didn't ? 
        if(len < length)
                dst[dstlen-1] = 0;
}

Step 3: Testing of Wireless Serial
1. Open serial terminal of both boards
2. What ever you send from one board serial terminal will appear it in other serial terminal and vice versa.
3. Points to remember Wireless nRF24L01+ module will not work if they are placed very close, at least have 2 to 3 meter distance between them to work properly
4. Check baud rate in serial init routine, I think I am using 19200 BAUD it depends on your board 8MHz or 16MHz