วันจันทร์ที่ 3 กันยายน พ.ศ. 2555

how to fix google chrome error ..(0xc0000005)


First right click on Google chrome sortcut
Click on properties









 

















Than double space and write this command

 --no-sandbox






 



















Apply 
And open google chrome

Simple and easy



See This Video


Link : http://atif980.blogspot.com/2011/11/how-to-fix-google-chrome-error.html

วันพุธที่ 22 สิงหาคม พ.ศ. 2555

PIC16F84A + temperatura DHT11

LIBRERIA:

//----------------------------------------------------------//


#define dht11 PIN_B0
#bit dht_io = 0x86.0 // este es el bit 0 del tris b para ponerlo como entrada o salida
#byte puerto_b = 0x06

byte dht_dat[5]; // Creo un array de tipo byte de 5 ya que asi en el programa principal podemos mostrar cada dato
//individualmente sin necesidad de punteros
//los datos obtenidos son en este orden: 
//dato 0= parte entera de la humedad
//dato1= parte decimal de la humedad
//dato2= parte entera de la temeperatura
//dato3= parte decimal de la temperatura
//dato4= dato de comprobacion para saber si la captura es correcta

//#use rs232(baud=9600,xmit=PIN_B7,rcv=PIN_B6,bits=8,parity=N,FORCE_SW) // conexion rs232 por si acaso alguien la necesita


void iniciar_dht();//para iniciar el sensor
void leer_dht();//para comenzar la captura de datos el sensor
byte leer_dht_dat();//funcion de captura de datos del sensor
void mostrar_dht();// mostrar datos

//--------------------------------funcion inicializar
void iniciar()
{

dht_io=0;
delay_ms(1);
OUTPUT_HIGH(dht11);

}//-------------------

//----------------------funcion de leer el dht-------------
void leer_dht()
{
//------- variables
byte GlobalErr=0;
byte dht_in;
byte i;

byte dht_check_sum;




//-----------------
dht_io=0; // configurar el pin como salida
OUTPUT_HIGH(dht11);
OUTPUT_LOW(dht11);
delay_ms(18);// retardo indicado por el fabricante
OUTPUT_HIGH(dht11);
delay_us(22);// entre 22 y 28 us 
dht_io=1;// configurar el pin como entrada
delay_us(5);// retardo indicado por el fabricante esta entre los 22 y 28 us
dht_in=input(dht11);
if(dht_in)
 {
  GlobalErr=1;
  printf("<dht11 start condition 1 not met");
  return;
 }
 delay_us(80);
 dht_in=input(dht11);
 if(!dht_in) 
 {
  GlobalErr=2;
  printf("<dht11 start condition 2 not met");
  return;
 }
  delay_us(80);
  for (i=0; i<5; i++)
  {
    dht_dat [i]= leer_dht_dat(); // capturando datos
  }
 
  dht_io=0;// configura el puerto como salida

OUTPUT_HIGH(dht11);

dht_check_sum = dht_dat[0]+dht_dat[1]+dht_dat[2]+dht_dat[3]; // comprobacion si la lectura es correcta
if(dht_dat[4]!=dht_check_sum)
{
 GlobalErr=3;
 printf("DHT11 checksum error");

}
dht_dat[0]=dht_dat[0]+5;
dht_dat[2]=dht_dat[2]+2;
// por ajustar segun caracteristicas +- 5%
//printf("Current humdity = ");
 //printf("%d",dht_dat[0]+5);
  //printf(".");
  //printf("%d",dht_dat[1]+50);
  //printf(" RH  ");
 //printf("temperature = ");
  //printf("%d",dht_dat[2]+2); // por ajustar segun caracteristicas +- 2ºC
  //printf(".");
  //printf("%d",dht_dat[3]+50);
  //
  //printf("C \n ");
 // delay_ms(2000);



}// fin de funcion leer dht

//------------------------funcion recoger bits del dht
byte leer_dht_dat()
{
byte i = 0;
 byte result=0;
 for (i=0; i< 8; i++) {
  //We enter this during the first start bit (low for 50uS) of the byte
  //Next: wait until pin goes high
  while(input(dht11)==0);
  delay_us(30);
  if (input(dht11)==1)//Was: if(PINC & _BV(dht_PIN))
  {
  result |=(1<<(7-i));
  }
  while (input(dht11)==1);
  //Was: while((PINC & _BV(dht_PIN)));
 }
 //end of "for.."
 return result;
}

//---------------------------------------------------------


a continuacion voy a poner un ejemplo hecho con el PIC16F84A pero puede utilizarse para cualquier PIC

EJEMPLO:
//--------------------------------------------------------------------------------

#include <16F84A.h>
#include <dht11.h>  //esta es la libreria creada por mi
#FUSES NOWDT                    //desactiva el wath dog
#FUSES XT                       //Crystal  <= 4mhz
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading

#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_B5,rcv=PIN_B4,BITS=8,PARITY=N)

void main()
{

   //setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);

   // TODO: USER CODE!!

delay_ms(5000);
printf("iniciando..\n");
   do
{




delay_ms(10);
 iniciar();
leer_dht();

printf("Humedad = ");
 printf("%d",dht_dat[0]);
 delay_ms(20);
 printf(",");
  printf("%d ",dht_dat[1]);
  delay_ms(20);
 printf("Temperatura = ");
 printf("%d ",dht_dat[2]);
 delay_ms(20);
  printf(",");
  printf("%d ",dht_dat[3]);
  delay_ms(20);
printf("\n...terminado..\n");

  delay_ms(2000);

}while(true);


}

//-------------------------------------------------------


Link  http://www.todopic.com.ar/foros/index.php?topic=35680.0

วันจันทร์ที่ 20 สิงหาคม พ.ศ. 2555

Interface DHT21 with PIC


Code: Select all
/***********************************************************
 * Description:
     AM2301 Humility & Tempreture seosor.
 * Test configuration:
     MCU:             PIC16F688
     dev.board:       F688 LCD board
     Oscillator:      internal RC , 4.0000 MHz
     Ext. Modules:    Character LCD 2x16
     SW:              mikroC PRO for PIC 4.15

 * NOTES:
 
************************************************************/

typedef unsigned char  U8;  /* defined for unsigned 8-bits integer variable */

//----------------Definition zone---------------//
unsigned char  U8FLAG,U8comdata;
unsigned char  U8checkdata,U8checkdata_temp,U8temp;
unsigned char  U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L;
unsigned char  U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp;
unsigned int   U16RH_data,U16T_data;
//-----------------------------------------------//


//---------------Defination for sensor IO interface--------//
sbit iobit at RA5_bit;
sbit iobit_Direction at TRISA5_bit;
//-----------------------------------------------//


void rd8bit(void){
    U8 i;
    for(i=0;i<8;i++){
        U8FLAG=2;
        while((!iobit) && U8FLAG++);
        Delay_10us();
        Delay_10us();
        Delay_10us();
        U8temp=0;
        if(iobit) U8temp=1;     // bit rd is 1, set U8temp=1
        U8FLAG=2;
        while((iobit) && U8FLAG++);
        if(U8FLAG==1)break;
        U8comdata<<=1;
        U8comdata|=U8temp;
    }
}

void rdbus(void){
iobit_Direction=0;
iobit=0;
Delay_us(500);
iobit=1;
Delay_10us();
Delay_10us();
Delay_10us();
Delay_10us();
iobit=1;
iobit_Direction=1;            // TRISA5_bit = 1;  //set RA5 pin as input
    if(!iobit){
        U8FLAG=2;
        while((!iobit)&&U8FLAG++);
        U8FLAG=2;
        while((iobit)&&U8FLAG++);
        rd8bit();
        U8RH_data_H_temp=U8comdata;
        rd8bit();
        U8RH_data_L_temp=U8comdata;
        rd8bit();
        U8T_data_H_temp=U8comdata;
        rd8bit();
        U8T_data_L_temp=U8comdata;
        rd8bit();
        U8checkdata_temp=U8comdata;
        iobit=1;
        U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
          if(U8temp==U8checkdata_temp){
             U8RH_data_H=U8RH_data_H_temp;
             U8RH_data_L=U8RH_data_L_temp;
             U8T_data_H=U8T_data_H_temp;
             U8T_data_L=U8T_data_L_temp;
             U8checkdata=U8checkdata_temp;

             U16RH_data<<=8;
             U16RH_data|=U8RH_data_H;
             U16RH_data<<=8;
             U16RH_data|=U8RH_data_L;
             U16T_data<<=8;
             U16T_data|=U8T_data_H;
             U16T_data<<=8;
             U16T_data|=U8T_data_L;
          }//CRC checked

    }//read data-bus.
}//rdbus-end

Interface DHT11 with ATMEL


Code:
//****************************************************************//
//                 Program for AM230x series 
//MCU:  AT89S52 ,   Frequency of crystal oscillator: 11.0592MHz
//Function: Transmit RH & Temp. Data via PC interface ,  Baud rate 9600 
//Connection: P2.0 connected with DHT sensor   
// Company  : Aosong Electronics   
//****************************************************************//
//
//
#include <reg51.h>
#include <intrins.h> 
//
typedef unsigned char  U8;       /* defined for unsigned 8-bits integer variable         */
typedef signed   char  S8;       /* defined for signed 8-bits integer variable         */
typedef unsigned int   U16;      /* defined for unsigned 16-bits integer variable         */
typedef signed   int   S16;      /* defined for signed 16-bits integer variable         */
typedef unsigned long  U32;      /* defined for unsigned 32-bits integer variable      */
typedef signed   long  S32;      /* defined for signed 32-bits integer variable          */
typedef float          F32;      /* single precision floating point variable (32bits)    */
typedef double         F64;      /* double precision floating point variable (64bits)    */
//
#define uchar unsigned char
#define uint unsigned int
#define   Data_0_time    4

//----------------------------------------------//
//----------------Definition for IO interface--------------------//
//----------------------------------------------//
sbit  P2_0  = P2^0 ;
sbit  P2_1  = P2^1 ;
sbit  P2_2  = P2^2 ;
sbit  P2_3  = P2^3 ;
//----------------------------------------------//
//----------------Definition zone--------------------//
//----------------------------------------------//
U8  U8FLAG,k;
U8  U8count,U8temp;
U8  U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
U8  U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
U8  U8comdata;
U8  outdata[5];  
U8  indata[5];
U8  count, count_r=0;
U8  str[5]={"RS232"};
U16 U16temp1,U16temp2;
//
//
SendData(U8 *a)
{
   outdata[0] = a[0]; 
   outdata[1] = a[1];
   outdata[2] = a[2];
   outdata[3] = a[3];
   outdata[4] = a[4];
   count = 1;
   SBUF=outdata[0];
}
//
//
void Delay(U16 j)
    {      U8 i;
       for(;j>0;j--)
     {    
      for(i=0;i<27;i++);

     }
    }
       void  Delay_10us(void)
      {
        U8 i;
        i--;
        i--;
        i--;
        i--;
        i--;
        i--;
       }
//
//   
void  COM(void)
      {
     
           U8 i;
       for(i=0;i<8;i++)      
       {
      
             U8FLAG=2;
   
         while((!P2_0)&&U8FLAG++);
         Delay_10us();
         Delay_10us();
         Delay_10us();
           U8temp=0;
        if(P2_0)U8temp=1;
          U8FLAG=2;
       while((P2_0)&&U8FLAG++);
          

          if(U8FLAG==1)break;

          
         U8comdata<<=1;
            U8comdata|=U8temp;        //0
        }//rof
      
   }

//--------------------------------
//-----Sub-program for reading %RH ------------
//--------------------------------
//----All the variable bellow is global variable--------
//----Temperature's high 8bit== U8T_data_H------
//----Temperature's low 8bit== U8T_data_L------
//----Humidity's high 8bit== U8RH_data_H-----
//----Humidity's low 8bit== U8RH_data_L-----
//----Check-sum 8bit == U8checkdata-----
//--------------------------------
void RH(void)
   {

           P2_0=0;
      Delay(5);
      P2_0=1;
      Delay_10us();
      Delay_10us();
      Delay_10us();
      Delay_10us();
      P2_0=1;     
      if(!P2_0)        
      {
      U8FLAG=2;
      while((!P2_0)&&U8FLAG++);
      U8FLAG=2;
      while((P2_0)&&U8FLAG++);
      COM();
      U8RH_data_H_temp=U8comdata;
      COM();
      U8RH_data_L_temp=U8comdata;
      COM();
      U8T_data_H_temp=U8comdata;
      COM();
      U8T_data_L_temp=U8comdata;
      COM();
      U8checkdata_temp=U8comdata;
      P2_0=1;
    
      U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
      if(U8temp==U8checkdata_temp)
      {
           U8RH_data_H=U8RH_data_H_temp;
           U8RH_data_L=U8RH_data_L_temp;
        U8T_data_H=U8T_data_H_temp;
           U8T_data_L=U8T_data_L_temp;
           U8checkdata=U8checkdata_temp;
      }//fi
      }//fi

   }
   
//----------------------------------------------
//               main()
//----------------------------------------------
void main()
{
   U8  i,j;
   

   TMOD = 0x20;     
   TH1 = 253;        
   TL1 = 253;
   TR1 = 1;          
   SCON = 0x50;     
   ES = 1;
   EA = 1;           
   TI = 0;
   RI = 0;
   SendData(str) ;   
   Delay(1);         
   while(1)
   {  

      //------------------------
      //    Transfer humiture read subroutine
      RH();
      //--------------------------

      str[0]=U8RH_data_H;
      str[1]=U8RH_data_L;
      str[2]=U8T_data_H;
      str[3]=U8T_data_L;
      str[4]=U8checkdata;
      SendData(str) ;  
   
      Delay(20000);
   }//elihw
   
}// main


void RSINTR() interrupt 4 using 2
{
   U8 InPut3;
   if(TI==1) 
   {
      TI=0;
      if(count!=5) 
      {
         SBUF= outdata[count];
         count++;
      }
   }
   
   if(RI==1)    
   {   
      InPut3=SBUF;
      indata[count_r]=InPut3;
      count_r++;
      RI=0;                         
      if (count_r==5)
      {
         
         count_r=0;
      str[0]=indata[0];
       str[1]=indata[1];
         str[2]=indata[2];
          str[3]=indata[3];
             str[4]=indata[4];
             P0=0;
      }
   }
}


Interface DHT11 with Arduino


Have got hold of a DHT 11 humidity sensor that outputs a digital signal to indicate temperature and humidty.

However seem to be having a few issues trying to get a pic to communicate successfully, and retrieve the data, and then display it on an lcd

I am using an 18f4550, and have some sample code for an Arduino, but am unable to convert it.

I have attached the sample code below.

Code:
 Select all
#define DHT11_PIN 0      // ADC0

byte read_dht11_dat()
{
   byte i = 0;
   byte result=0;
   for(i=0; i< 8; i++){
      
      
      while(!(PINC & _BV(DHT11_PIN)));  // wait for 50us
      delayMicroseconds(30);
      
      if(PINC & _BV(DHT11_PIN)) 
         result |=(1<<(7-i));
              while((PINC & _BV(DHT11_PIN)));  // wait '1' finish
         
      
   }
   return result;
}


void setup()
{
   DDRC |= _BV(DHT11_PIN);
   PORTC |= _BV(DHT11_PIN);
   
     Serial.begin(19200);
  
Serial.println("Ready");
   }
   
void loop()
{
   byte dht11_dat[5];
   byte dht11_in;
   byte i;
   // start condition
   // 1. pull-down i/o pin from 18ms
   PORTC &= ~_BV(DHT11_PIN);
   delay(18);
   PORTC |= _BV(DHT11_PIN);
   delayMicroseconds(40);
   
   DDRC &= ~_BV(DHT11_PIN);
   delayMicroseconds(40);
   
   dht11_in = PINC & _BV(DHT11_PIN);
   
   if(dht11_in){
      Serial.println("dht11 start condition 1 not met");
      return;
   }
   delayMicroseconds(80);
   
   dht11_in = PINC & _BV(DHT11_PIN);
   
   if(!dht11_in){
      Serial.println("dht11 start condition 2 not met");
      return;
   }
   delayMicroseconds(80);
   // now ready for data reception
   for (i=0; i<5; i++)
      dht11_dat[i] = read_dht11_dat();
      
   DDRC |= _BV(DHT11_PIN);
   PORTC |= _BV(DHT11_PIN);
   
        byte dht11_check_sum = dht11_dat[0]+dht11_dat[1]+dht11_dat[2]+dht11_dat[3];
   // check check_sum
   if(dht11_dat[4]!= dht11_check_sum)
   {
      Serial.println("DHT11 checksum error");
   }
   
   Serial.print("Current humdity = ");
   Serial.print(dht11_dat[0], DEC);
   Serial.print(".");
   Serial.print(dht11_dat[1], DEC);
   Serial.print("%  ");
   Serial.print("temperature = ");
   Serial.print(dht11_dat[2], DEC);
   Serial.print(".");
   Serial.print(dht11_dat[3], DEC);
   Serial.println("C  ");
   
   delay(2000);
}



Could anyone offer any suggestions ?

P.S Link for data sheet http://www.aosong.com/english/Upload/PicFiles/20091281822579047.pdf

thanks ;)

วันอาทิตย์ที่ 19 สิงหาคม พ.ศ. 2555

แกะรอย LCD 3310 NOKIA


  พวกเราใช้มือถือกันนับวันจะยิ่งมีความทันสมัยมากขึ้นไปเรื่อย ๆ ทั้งระบบ กล้องมือถือ , ฟังเพลง mp3 , การเชื่อมต่อ Bluetooth  นับว่าเป็นสินค้าที่มีราคาเปลี่ยนแปลงตามเทคโนโลยีเหมือน ๆ กับ คอมพิวเตอร์ ยิ่งเทคโนโลยีล้าสมัย ราคายิ่งต่ำ และสุดท้าย จะกลายเป็นของเหลือใช้ ตกรุ่น แต่ถ้าเราหันมามองอีกมุมหนึ่ง อะไหล่ ของเครื่องโทรศัพท์มือถือรุ่นเก่า ๆ อย่างเช่น หน้าจอแสดงผลของ NOKIA รุ่น 3310 สามารถนำมาใช้ในการประดิษฐ์สำหรับงาน อิเล็กทรอนิกส์ embedded ได้อย่างคุ้มค่า เพราะ LCD ตัวนี้ สามารถแสดงผลได้ทั้งตัวอักษร ตัวเลข หรือแม้กระทั่งกำหนดลักษณะการแสดงผลเองได้อิสระ ตามที่เราออกแบบ และมีราคาถูกกว่า LCD ที่เราซื้อกันตามบ้านหม้อครับ ดังนั้น LCD 3310 จึงเหมาะสำหรับนักอิเล็กทรอนิกส์ที่ต้องการ DISPLAY ราคาถูกเพื่อนำไปใช้ต่อเข้ากับ MCU ชนิดต่าง ๆ นำไปแสดงผลตามต้องการ
         LCD NOKIA 3310 ถูกนำมาประดิษฐ์ร่วมกับอุปกรณ์ต่าง ๆ จนเป็นชิ้นงานได้แล้ว ผู้ที่นำมาใช้ มีทั้งในประเทศไทย และต่างประเทศ ในวันนี้ถึงตาคุณแล้วครับ ThaiEasyElec.com จะขอแกะรอยการนำมาใช้งาน DISPLAY 3310 ให้ท่านที่ไม่เคยใช้ ลองไปใช้งานกันครับ
(ขอบคุณรูปตัวอย่างจาก wara.com by Jnut)
  

บทนำ

         LCD 3310 NOKIA นี้เรียกตามบริษัทผู้ผลิต (Manufacturer Part Number) คือ LPH7779 ซึ่งผลิตโดย Philips Semiconductor โดยมีไอซี PCD8544 รวมอยู่แล้วในตัวเดียว ดังนั้นเราเพียงหา datasheet PCD8544 เพื่ออ่านคุณลักษณะการเชื่อมต่ออย่างละเอียดได้ก็พอครับ ถือได้ว่าเป็น Graphic LCD ชนิดหนึ่ง ดังนั้นการใช้งานคือ การหา MCU มาแล้วเชื่อมต่อเข้ากับ LCD ได้เลย การติดต่อจะใช้รูปแบบของ SPI communication ซึ่งย่อมาจาก Serial Peripheral Interface (ไม่ใช้ UART หรือที่เรียกกันติดปากว่า serial port นะครับ อย่าสับสน) สำหรับ SPI มีการใช้อย่างไร ขอให้ลองศึกษาเพิ่มเติมโดย search ใน google ก็จะเจอครับ โดยจะต้องเลือก MCU ที่มี SPI Interface เข้ากับ LCD 3310 เช่น พวก PIC ทั้งหลายครับ

ขนาดของ 
LCD 3310


รูปที่ 1 ขนาดของ 
LCD 3310 
ตามรูปที่ 1 หน่วยในรูปเป็น มิลลิเมตร 
(mm) 

ทั้งชิ้นอุปกรณ์มีความ กว้าง × ยาว 
38.5 mm × 35.5 mm 
ตัวหน้าจอแสดงผล กว้าง × ยาว 
30 mm 
× 22 mm
โดยมีความละเอียดหน้าจอ 
(resolution) เท่ากับ 84 × 48 pixels 

ส่วนขนาดของช่อง 
Pin มีความยาว 16 mm

ตำแหน่งขาสัญญาณ 
Pin1 – Pin8 LCD 3310


รูปที่ 2 ขาสัญญาณที่ใช้ทั้งหมด 
(Pin1-Pin8)
Pin
Signal
Description
Port
1VDDขาไฟเลี้ยงสำหรับ LCD โดยใช้ voltage ช่วง 2.7  7 voltPower
2SCLKขาสัญญาณ clock ของ LCD ซึ่งกำหนดค่า max สุดคือ 4 Mbits/sInput
3SDINย่อมาจาก serial data input เป็นขาที่ใช้ในการรับข้อมูล เพื่อแสดงผลที่หน้าจอ LCDInput
4D/Cขาที่ใช้เลือกควบคุม ระหว่าง ให้รับข้อมูล data(D) / ส่งคำสั่งcommand(C) ซึ่ง active lowInput
5SCEขาที่ enable ตัวจอ LCD ให้ทำงาน(active low)Input
6GNDขา groundPower
7VOUTขาไฟเลี้ยงขาออกของ LCD โดยขานี้ต้องต่อ electrolytic capacitorsจาก VOUT ไปยัง GND โดยใช้ค่าได้ตั้งแต่ 1 uF ถึง 10 uFPower
8RESขา reset (active low)Input
จะเห็นว่า เราจะมีขาสัญญาณที่เกี่ยวข้องในการควบคุมการทำงานต่าง ๆ อยู่ 5 ขา ซึ่งเราต้องติดต่อในการเขียนโปรแกรมควบคุมLCD ประกอบด้วย ขา 2 SCLK , ขา 3 SDIN , ขา 4 D/C ,  ขา 5 SCE, ขา 8 RES
สำหรับจอ Nokia 5110 (GLCD5110) จะมีขาเรียงดังนี้
http://www.thaieasyelec.com/images/catalog_images/1291917207.jpghttp://www.thaieasyelec.com/images/catalog_images/1291917246.jpg
http://www.thaieasyelec.com/images/catalog_images/1298712912.jpg

หลักการทำงานของ LCD 3310
แบ่งการทำงานออกเป็น 2 โหมด คือ command(C) โหมด กับ data(D) โหมด โดยอาศัยขาสัญญาณ D/C เพื่อเลือกโหมด  มีรายละเอียดโหมด ดังนี้
1. data(D) โหมด ใช้สำหรับ รับข้อมูล เพื่อนำข้อมูลไปแสดงผลบนหน้าจอ
2. command(C) โหมด ใช้สำหรับ รับคำสั่ง (active low) เพื่อกำหนดตำแหน่งของการเริ่มต้นเขียนข้อมูล  และ กำหนดค่า config ต่างๆให้แก่ LCD นอกจากนั้นยังควบคุมให้แสดงผลปกติ หรือแบบ Inverse ได้ด้วย

การระบุตำแหน่งบนหน้าจอแสดงผลของ LCD 3310
หน้าจอของ LCD จะประกอบไปด้วยจำนวนจุดทั้งหมดเท่ากับ 48 x 84 pixels  เป็นจำนวนคอลัมน์ (column) ได้เท่ากับ 84 คอลัมน์ และ จำนวนแถว (row) 48 แถวด้วยกัน โดยแถวทั้ง 48 แถวนั้น จะแสดงผลออกมาได้เป็น 6 บรรทัด 
6 บรรทัดมาอย่างไร
เนื่องจากไอซี PCD8544 เก็บไฟล์ทีละ 1  byte หรือ 8 bits มาแสดงผล โดยเก็บข้อมูลจากซ้ายไปขวา บนสุดมาล่างสุด ดังนั้น 48 pixels คือ 48 bits ทำให้เรามีจำนวนบรรทัด สำหรับแสดง ผลเท่ากับ 48 / 8 = 6 บรรทัด ถ้าไม่เข้าใจ ดูรูปประกอบครับ ช่วยได้เยอะ
เมื่อ LCD 3310 รับข้อมูลเพื่อแสดงผล มันจะรับแบบต่อเนื่อง จากบรรทัดแรก (บนสุด) แสดงจนครบทั้ง  84  คอลัมน์(pixels) จากซ้ายไปขวาก่อน จึงขึ้นแถวที่ 2 แล้วแสดงให้ครบทั้ง  84  คอลัมน์(pixels)ใหม่ ไปเรื่อย ๆ จนสุดท้าย บรรทัดที่ 6 ครับ
เพื่อให้เข้าใจและเห็นภาพมากขึ้น ถึงการเรียกตำแหน่ง pixels ต่าง ๆ ใน LCD จะขอยกตัวอย่าง โดยใช้โปรแกรมการออกแบบตัวอักษรจาก amontec.com ครับ ชื่อโปรแกรม FlashLCD design ซึ่งเป็นตัวที่เขาสร้างมาให้เราใช้ฟรีครับ แต่บางเมนู ก็ไม่สามารถใช้ได้ครับ
download >>  FastLCD จาก amontec.com
ส่วนวิธีการใช้งาน ผมจะสาธิตคร่าว ๆ อยู่ 5 ส่วนครับ ที่เหลือ ลองศึกษาใช้งานเอง ไม่ยากครับ

ส่วนที่ 1 ไว้ใช้ plot จุดครับ คลิกเมาส์ปุ่มซ้ายจะจุดสีดำ ส่วนคลิกเมาส์ปุ่มขวา ที่จุดดำจะกลายเป็นสีขาว
ส่วนที่ 2 ไว้ใช้ save file ซึ่งข้อมูลจะออกมาในรูปชุดข้อมูลแบบ hex ขนาดก้อนละ 1 ไบต์
ส่วนที่ 3 ไว้ undo กับ clear หน้าจอครับ
ส่วนที่ 4 ไว้ให้เลือกแสดงเส้น grid ตามความละเอียดที่เราต้องการ , กำหนดขนาดของหน้าจอ , และปุ่ม zoom
การกำหนดขนาด (ส่วนที่ 4 ปุ่มที่ 3) จะเป็นตัวกำหนด column และ row
 
ส่วนที่ 5 ไว้เลื่อนสิ่งที่เราวาดลงไป ให้ไปทางซ้าย ขวา บน ล่าง สลับด้านซ้ายขวา บนล่าง
ผมขอแสดงตัวอย่างอักษร TH ครับ โดยตำแหน่งเริ่มต้นของการแสดงผล จะเริ่มต้นที่มุมซ้ายบน และแสดงจาก ซ้ายมือไปยังขวามือ เมื่อหันหน้าจอเขาหาตัวผู้มอง โดยถ้าใช้การแสดงผลโหมดการแสดงผลปกติ เราจะได้ต้องกำหนดให้ bit ที่เราต้องการเป็นแสดงผล "1" (ให้จุดดำขึ้นบนหน้าจอ) และ ไม่ต้องการให้แสดงผลเป็น "0" (ไม่ให้จุดดำขึ้นหน้าจอ)

วาดเสร็จ ก็กดปุ่มส่วนที่ 2 save งานครับ
  
ผมขยาย grid ให้ใหญ่ขึ้นเพื่อแสดงให้เห็นว่าจำนวน pixels ส่วนนี้ คือ 16 columns x 8 rows ส่วนของอักษร T และ H นั้น ใช้ pixels ตัวละ 6 columns x 8 rows และผมเว้นวรรคตัวอักษรใช้ pixels 2 columns x 8 rows
 
เมื่อเปิดไฟล์ที่เรา save ไว้ด้วย notepad จะเห็นกลุ่มข้อมูล เป็นก้อน ๆ แสดงเลขเป็นแบบ hex ก้อนละ 1 byte หรือ 8 bits
ตัวอักษร T นั้น ใช้ pixels ตัวละ 6 columns x 8 rows ดังนั้นกลุ่มข้อมูลที่ประกอบกันทำให้เป็นตัวอักษร T ได้นั้นคือ 0x03,0x03,0xff,0xff,0x03,0x03

0x03  => 0 0 0 0 0 0 1 1
0x03  => 0 0 0 0 0 0 1 10xff    => 1 1 1 1 1 1 1 1
0xff    => 1 1 1 1 1 1 1 10x03  => 0 0 0 0 0 0 1 10x03  => 0 0 0 0 0 0 1 1
คงจะมองภาพออกแล้วนะครับ กลับมาดูข้อมูลที่ LCD 3310 ได้รับ มันก็จะรับเป็นก้อน ยาว ๆ ต่อเนื่องไปเรื่อย ๆ ครับ (ส่วนที่ highlight คืออักษร TH ที่เราวาดไป)

แล้วที่กล่าวว่า 84  คอลัมน์(pixels) จากซ้ายไปขวา ก็คือดังรูปครับ
กลับมาดูข้อมูลที่ LCD 3310 ได้รับ มันจะสิ้นสุด บรรทัดแรกตรงช่วงที่ผม highlight ครับ

ผมจะขยับ อักษร TH ไปท้ายสุดของบรรทัดครับ แล้วมาดูข้อมูลกันว่ามันขยับตามหรือไม่
ผลลัพธ์ครับ
ที่นี่เราลองจินตนาการครับ ว่าถ้าเรากำหนดจุด x,y แล้วให้แสดงผล คาบเกี่ยวบรรทัดกัน จะออกมาเป็นอย่างไร

ผลลัพธ์ครับ
ดังนั้น เวลาเขียนโปรแกรมป้อนข้อมูลให้แสดงผลนั้น จึงง่ายมากครับ เราเพียงออกแบบการแสดงผลของเราไว้ให้ครบ แล้วเราก็เขียนโปรแกรมย่อยส่วนนั้นแยกไป กำหนดจุด x,y ป้อนข้อมูลต่าง ๆ เก็บไว้เป็นชุด display แล้วจึงเรียกใช้งานโปรแกรมย่อยนั้นครับ
สรุปคือ เราสามารถสร้างตัวอักษร สร้างรูป สัญลักษณ์ ฯลฯ เองได้ทั้งหมดครับ เราจะออกแบบโดยใช้ FlashLCD design  จะทำให้มองภาพรวมออก และสามารถไปเขียนโปรแกรมได้ ดังนั้น LCD 3310 ตัวนี้ จึงให้อิสระของการแสดงผลตามที่ใจเราต้องการครับ เช่นตัวอย่าง จากรูป แสดงอักษรภาษาอังกฤษ TH จะได้ประมาณ 10 ตัวอักษรใน 1 บรรทัด(ผมรวมเว้นวรรคด้วยครับ) หรือเราอาจจะออกแบบตัวอักษรออกมาใหม่ แล้วอาจทำให้ได้ 14 ตัวอักษรใน 1 บรรทัด ก็อาจเป็นได้ครับ แล้วแต่เราออกแบบครับ
หลักการเขียนโปรแกรมควบคุมการแสดงผล LCD 3310ส่วนใหญ่ที่พบเห็นจะใช้ภาษาซี ในการเขียนโปรแกรมควบคุมด้วย MCU ครับ ฟังก์ชั่นที่จำเป็นสำหรับการติดต่อ เขียนโปรแกรมเหมือนกับการติดต่อ LCD ทั่ว ๆ ไปครับกล่าวคือ เราต้องส่งคำสั่งติดต่อกับ LCD ก่อน เพียงครั้งเดียว หลังจากนั้นก็จะเป็นส่วนการส่งคำสั่งเพื่อแสดงผล (อย่าลืม Initail ค่าสำหรับ SPI Interface ด้วยนะครับ) ในหัวข้อนี้ผมจะขอสรุปคำสั่งที่ใช้ติดต่อกับ LCD NOKIA 3310 ครับ 
1.เริ่มต้น ขา 5 SCE  ส่ง 0 เพื่อให้ LCD ทำงาน (active low)
2.ทำ function set โดย ขา 4 D/C  เมื่อต้องการส่งคำสั่ง ให้ส่ง  0 (active low) หลังจากนั้น ให้ส่งข้อมูลคำสั่งไปที่ ขา 3 SDIN มีรูปแบบดังนี้
DB 0 => H extended instruction set mode
             0 => basic instruction set ในกลุ่มคำสั่งนี้เป็นการกำหนดค่าตำแหน่ง display x,y
                     รวมถึง inverse mode
             1 => extended instruction set ในกลุ่มนี้เป็นการกำหนด ค่าอุณหภูมิ , ค่า Bias ,
                     ค่า Vop (ปรับความเข้ม)
DB 1 => V entry mode
             0 => horizontal address
             1 => vertical address
DB 2 => PD คือ power down control
             0 = chip active
             1 = chip power down control
DB 3 => 0
DB 4 => 0
DB 5 => 1
DB 6 => 0
DB 7 => 0
ตัวอย่าง function set
function set  0x20
 set LCD basic instruction set
0x08 LCD blank (all off)
0x0C LCD in normal mode
0xC4 Vop ค่าปรับความเข้มของจอ 0xc4 ถ้าน้อยกว่านี้จางมากกว่าเข้ม
0x09 LCD in inverse mode (all on)
function set  0x21 set LCD extended instruction set
0x13 LCD bias mode 1:48
0x06 Set Temp coefficient.
function set  0x20 horizontal mode from left to right  โดยเป็นโหมด default อัตโนมัติ หากไม่ได้กำหนดค่า

function set  0x22 for vertical addressing
 

Documents: