/*
This is a 16x2 LCD display demonstration. 25 Jun 2013
Author: Pranav Pareek (http://www.pranavpareek.com)

Connection as follows:
* VEE = GND
* EN = PORTC.6
* RS = PORTC.7
* RW = PORTB.4
* LCD D4 = PORTB.0
* LCD D5 = PORTB.1
* LCD D6 = PORTB.2
* LCD D7 = PORTB.3
* B/L+ = ICSP Pin 2
* B/L- = ICSP Pin 3

*/

#define EN 8
#define RS 9
#define RW 4
#define LED 12


void lcd_cmd_data(unsigned char cmd, int rs) {
    if(rs == 1) {
        digitalWrite(RS,HIGH);
    }
    else {
        digitalWrite(RS,LOW);
    }
    digitalWrite(EN,LOW);
    PORTB = ((cmd >> 4) & 0x0F);
    digitalWrite(EN,HIGH);
    delay(10);
    digitalWrite(EN,LOW);
    PORTB = (cmd & 0x0F);
    digitalWrite(EN,HIGH);
    delay(10);
    digitalWrite(EN,LOW);
}

void init_lcd() {
    digitalWrite(RW,LOW);
    digitalWrite(RS,LOW);
    digitalWrite(EN,LOW);
    PORTB = 0x03;
    delay(50);
    digitalWrite(EN,HIGH);
    digitalWrite(EN,LOW);
    delay(10);
    digitalWrite(EN,HIGH);
    digitalWrite(EN,LOW);
    delay(10);
    digitalWrite(EN,HIGH);
    digitalWrite(EN,LOW);
    delay(10);
    PORTB = 0x02;
    digitalWrite(EN,HIGH);
    digitalWrite(EN,LOW);
    lcd_cmd_data(0x28, 0);
    delay(250);
    lcd_cmd_data(0x0E, 0);
    delay(250);
    lcd_cmd_data(0x01, 0);
    delay(250);
    lcd_cmd_data(0x06, 0);
    delay(250);
    lcd_cmd_data(0x80, 0);
    delay(250);    
}

void puts_lcd(const char * string) {
    lcd_cmd_data(0x08, 0);
    while(*string) {
        lcd_cmd_data(*string++, 1);
    }
    lcd_cmd_data(0x0E, 0);
}

void pos_xy(int posX, int posY) {
    if(posX<40) {
        if(posY) {
            posX|=0b01000000;
        }
        posX|=0b10000000;
        lcd_cmd_data(posX, 0);
    }
}

 void setup() {
    pinMode(RS,OUTPUT);
    pinMode(EN,OUTPUT);
    pinMode(RW,OUTPUT);
    pinMode(LED,OUTPUT);
    init_lcd();
    puts_lcd("  16x2 LCD Demo ");
    pos_xy(0,1);
    puts_lcd("PranavPareek.Com");
 }
 
  void loop() {
    digitalWrite(LED,HIGH);
    delay(250);
    digitalWrite(LED,LOW);
    delay(250);
  }
