Nokia 3310 LCD

The Nokia 3310 LCD assy on your Arduino:

Nokia 3310 LCD is low-cost, monochrome LCD with 84x48 display.   It is popular for 8-bit AVR/PIC projects.
I bought mine on nuelectronics.com




The joystick uses 1 analog port with 5 resistors.
You can program your own logo if you like and store it in the char.

Nokia 3310 LCD shield v1.0 with Joystick - Click Image to Close

Keywords:

LCD_3310_init
LCD_3310_write_byte
LCD_3310_draw_bmp_pixel
LCD_3310_write_string
LCD_3310_write_string_big
LCD_3310_write_char_big
LCD_3310_write_char
LCD_3310_set_XY
LCD_3310_clear



You can use the tool LCD Assistant to convert your own logo's into binairy code.
Here you can download the zip file: 







The code from the movie is below:


#include "nokia_3310_lcd.h"
#include "avr_bmp.h"


//keypad debounce parameter
#define DEBOUNCE_MAX 15
#define DEBOUNCE_ON  10
#define DEBOUNCE_OFF 3


#define NUM_KEYS 5


#define NUM_MENU_ITEM 4


// joystick number
#define UP_KEY 3
#define LEFT_KEY 0
#define CENTER_KEY 1
#define DOWN_KEY 2
#define RIGHT_KEY 4


// menu starting points


#define MENU_X 10 // 0-83
#define MENU_Y 1 // 0-5


// adc preset value, represent top value,incl. noise & margin,that the adc reads, when a key is pressed
// set noise & margin = 30 (0.15V@5V)
int  adc_key_val[5] ={30, 150, 360, 535, 760 };


// debounce counters
byte button_count[NUM_KEYS];
// button status - pressed/released
byte button_status[NUM_KEYS];
// button on flags for user program
byte button_flag[NUM_KEYS];


// menu definition
char menu_items[NUM_MENU_ITEM][12]={
"TEMPERATURE",
"CHAR MAP",
"BITMAP",
"ABOUT"
};


void (*menu_funcs[NUM_MENU_ITEM])(void) = {
temperature,
charmap,
bitmap,
about
};


char current_menu_item;


Nokia_3310_lcd lcd=Nokia_3310_lcd();


void setup()
{
  
   // setup interrupt-driven keypad arrays
   // reset button arrays
   for(byte i=0; i<NUM_KEYS; i++){
     button_count[i]=0;
     button_status[i]=0;
     button_flag[i]=0;
   }


  // Setup timer2 -- Prescaler/256
  TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
  TCCR2B &= ~(1<<WGM22);
  TCCR2B = (1<<CS22)|(1<<CS21);    


  ASSR |=(0<<AS2);


   // Use normal mode
   TCCR2A =0;  
     //Timer2 Overflow Interrupt Enable
     TIMSK2 |= (0<<OCIE2A);
     TCNT2=0x6;  // counting starts from 6;
   TIMSK2 = (1<<TOIE2);  


  SREG|=1<<SREG_I;


  lcd.LCD_3310_init();
  lcd.LCD_3310_clear();


   //menu initialization
   init_MENU();
   current_menu_item = 0;
}


/* loop */


void loop()
{
    byte i;
    for(i=0; i<NUM_KEYS; i++){
       if(button_flag[i] !=0){
          
            button_flag[i]=0;  // reset button flag
switch(i){


case UP_KEY:
// current item to normal display
lcd.LCD_3310_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_NORMAL );
current_menu_item -=1;
if(current_menu_item <0)  current_menu_item = NUM_MENU_ITEM -1;
// next item to highlight display
lcd.LCD_3310_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_HIGHLIGHT );
break;
case DOWN_KEY:
// current item to normal display
lcd.LCD_3310_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_NORMAL );
current_menu_item +=1;
if(current_menu_item >(NUM_MENU_ITEM-1))  current_menu_item = 0;
// next item to highlight display
lcd.LCD_3310_write_string(MENU_X, MENU_Y + current_menu_item, menu_items[current_menu_item], MENU_HIGHLIGHT );
break;
case LEFT_KEY:
          init_MENU();
current_menu_item = 0;
break;
case RIGHT_KEY:
         lcd.LCD_3310_clear();
(*menu_funcs[current_menu_item])();
          lcd.LCD_3310_clear();
init_MENU();
current_menu_item = 0;        
break;
}

}
    }
}


/* menu functions */


void init_MENU(void){


  byte i;


  lcd.LCD_3310_clear();


    lcd.LCD_3310_write_string(MENU_X, MENU_Y, menu_items[0], MENU_HIGHLIGHT );

  for (i=1; i<NUM_MENU_ITEM; i++){
    lcd.LCD_3310_write_string(MENU_X, MENU_Y+i, menu_items[i], MENU_NORMAL);
  }

}


// waiting for center key press
void waitfor_OKkey(){
  byte i;
  byte key = 0xFF;
while (key!= CENTER_KEY){
    for(i=0; i<NUM_KEYS; i++){
       if(button_flag[i] !=0){
           button_flag[i]=0;  // reset button flag
           if(i== CENTER_KEY) key=CENTER_KEY;
        }
     }
   }

}


void temperature()
{
        lcd.LCD_3310_write_string_big(10, 1, "+12.30", MENU_NORMAL);
        lcd.LCD_3310_write_string(78, 2, "C", MENU_NORMAL);
        lcd.LCD_3310_write_string(38, 5, "OK", MENU_HIGHLIGHT );
waitfor_OKkey();
}


void charmap(){
  char i,j;
   for(i=0; i<5; i++){
    for(j=0; j<14; j++){
      lcd.LCD_3310_set_XY(j*6,i);
      lcd.LCD_3310_write_char(i*14+j+32, MENU_NORMAL);
      }
    }




  lcd.LCD_3310_write_string(38, 5, "OK", MENU_HIGHLIGHT );
waitfor_OKkey();
}


void bitmap(){
  lcd.LCD_3310_draw_bmp_pixel(20,1, AVR_bmp, 48,24);
  lcd.LCD_3310_write_string(38, 5, "OK", MENU_HIGHLIGHT );
waitfor_OKkey();
}


void about(){


  lcd.LCD_3310_write_string( 0, 1, "Nokia 3310 LCD", MENU_NORMAL);
  lcd.LCD_3310_write_string( 0, 3, "nuelectronics", MENU_NORMAL);
lcd.LCD_3310_write_string(38, 5, "OK", MENU_HIGHLIGHT );
waitfor_OKkey();


}






// The followinging are interrupt-driven keypad reading functions
//  which includes DEBOUNCE ON/OFF mechanism, and continuous pressing detection




// Convert ADC value to key number
char get_key(unsigned int input)
{
char k;
  
for (k = 0; k < NUM_KEYS; k++)
{
if (input < adc_key_val[k])
{
        
    return k;
        }
}
  
    if (k >= NUM_KEYS)
        k = -1;     // No valid key pressed
  
    return k;
}


void update_adc_key(){
  int adc_key_in;
  char key_in;
  byte i;


  adc_key_in = analogRead(0);
  key_in = get_key(adc_key_in);
  for(i=0; i<NUM_KEYS; i++)
  {
    if(key_in==i)  //one key is pressed
    {
      if(button_count[i]<DEBOUNCE_MAX)
      {
        button_count[i]++;
        if(button_count[i]>DEBOUNCE_ON)
        {
          if(button_status[i] == 0)
          {
            button_flag[i] = 1;
            button_status[i] = 1; //button debounced to 'pressed' status
          }

        }
      }

    }
    else // no button pressed
    {
      if (button_count[i] >0)
      {
button_flag[i] = 0;
button_count[i]--;
        if(button_count[i]<DEBOUNCE_OFF){
          button_status[i]=0;   //button debounced to 'released' status
        }
      }
    }
  
  }
}


// Timer2 interrupt routine -
// 1/(160000000/256/(256-6)) = 4ms interval


ISR(TIMER2_OVF_vect) {
  TCNT2  = 6;
  update_adc_key();
}

Geen opmerkingen:

Een reactie posten