Pages: 1 [2] 3   Go Down
Author Topic: graphical lcd (nokia 3310)  (Read 8229 times)
0 Members and 1 Guest are viewing this topic.
berlin
Offline Offline
Sr. Member
****
Karma: 0
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i just wanted to tell everyone, that i got the display working. there is still much for me to do. cleaning up the code and doing the setup again with a proper voltage regulator as pointed out by massimo. the diode-method works, but i'm not satisfied with the contrast and dirtiness of this solution.

the main problem still is that the code to use the display is quite big. i managed to interface a joystick with the same board, to control a cursor. every further processing has to be done externally on another board or a computer. so goodbye DIY arduino gameboy :-)

if anyone is interested in the code or setup now, just PM me.

kuk


Logged

Forum Administrator
Offline Offline
Newbie
*****
Karma: 3
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

cool

the best thing to do now is to write an article for the playground so that others can use it.

massimo
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Has this been written up and posted anywhere yet?
Very interested in working with the Color LCD that SparkFun sells.

Thanks.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 49
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

double ditto that!

ñ
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 91
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

http://www.display3000.com/html/screen-shots.html
http://www.shop-en.display3000.com/
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 7
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

did anyone figure out a code that will work with arduino yet???
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

there seem to be lots of pages describing how to hook one of these 3310 lcd's up but can anyone give me some pointers on how to go about to physically connect the darned thing? I followed the procedure on this page: http://www.microsyl.com/nokialcd/nokialcd.html , but simply couldn't get those wires soldered to the tiny connector! And made 2 of those little bits come off so now I need to look for another one smiley-sad

How do you guys wire the thing up?!?
Logged

berlin
Offline Offline
Sr. Member
****
Karma: 0
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Bas-l,

read the thread. it's basically all in there. the way i did it ( and how it worked for me) was basically like on the diagram and in the code. you just have to make sure that the voltage is around 3,3V max on the dipsplay.

i'd really like to help you more. But i gave away my prototype (it was a gift) and back then i didn't think it was necessary to document it... well.

i still have some displays around. i hope i'll find the time to do it again.

the code works though.

good luck,
kuk
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Kuk,

maybe I wasn't clear. My question is: how do you manage to physically connect wires to those teeny weeny small connectors on the display? I tried soldering wires directly on to them and I failed miserably, destroying 2 connectors (or rather 2 "pins", out of the 8 on the bottom/back of the display).

Are there connectors for sale somewhere that you can snap on that are easier to solder wires onto? If not, what's the trick to solder wires onto the display's connector?

I got 2 new 3310 lcd's off of ebay, for about 1$ each. Pretty cheap but would hate to ruin them as well smiley-wink

Thanks,

Bas.
Logged

berlin
Offline Offline
Sr. Member
****
Karma: 0
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

oh i see,

i know that there are at least to versions of the same display around. one is designed to be placed with its contacts on some conducting rubber. the contacts on those are _not_ solderable, or at least not as far as i know. you can buy this "conductive rubber" and put it between the display and a custom pcb. it is not at all cheap but you only need half of a sq.centimetre. and i once saw someone offering these small pieces on ebay.

the displays i have all come from a 3310. its contacts are small copper springs. they're small but i had no problems soldering them since it's copper.

hope that helped you more.

//kuk
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I still would like to know if the CODE has been posted anywhere?  Or if it would be possible for someone to send me a copy?

Thanks!
Logged

berlin
Offline Offline
Sr. Member
****
Karma: 0
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok, so here the working code.
part 1 because its to long for one reply...
Code:
#define LCD_X_RES                  84
#define LCD_Y_RES                  48



#define LCD_CACHE_SIZE             ((LCD_X_RES * LCD_Y_RES) / 8)

/*--------------------------------------------------------------------------------------------------
 Type definitions
 --------------------------------------------------------------------------------------------------*/



#define    LCD_CMD  0
#define    LCD_DATA  1

#define    PIXEL_OFF   0
#define    PIXEL_ON    1
#define    PIXEL_XOR   2

#define    FONT_1X  1
#define    FONT_2X  2


typedef unsigned int               word;
//  Mega8 port B pinout for LCD.
int CONTROL_LED=12;
int LCD_POWER_PIN      =       11;
int LCD_DC_PIN         =        2; //  PB0  4  Data Command
int LCD_CE_PIN         =        3; //  PB2  5  /CS   active low chip select ??
int SPI_MOSI_PIN       =        4; //  PB3  3  Serial   line
int LCD_RST_PIN        =        5; //  PB4  8   /RES RESET
int SPI_CLK_PIN        =        6; //  PB5  2  CLOCK

int voltometer        =         9;
// Public function prototypes

void LcdInit       ( void );
void LcdClear      ( void );
void LcdUpdate     ( void );
void LcdGotoXY     ( byte x, byte y );
void LcdChr        ( int size, byte ch );
void LcdStr        ( int size, byte *dataPtr );
void LcdPixel      ( byte x, byte y, int mode );
void LcdLine       ( byte x1, byte y1, byte x2, byte y2, int mode );
void LcdSendCmd ( byte data, int cd );


// This table defines the standard ASCII characters in a 5x7 dot format.


// Global Variables

byte  LcdCache [ LCD_CACHE_SIZE ];

int   LcdCacheIdx;
int   LoWaterMark;

int   HiWaterMark;
boolean  UpdateLcd;
 char sign;
  byte ser= 0; //from serial port

// This table defines the standard ASCII characters in a 5x7 dot format.
static const byte FontLookup [][5] =
{
  {
    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, 0x09, 0x01     }
  ,   // F
  {
    0x3E, 0x41, 0x49, 0x49, 0x7A     }
  ,   // 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, 0x0C, 0x02, 0x7F     }
  ,   // M
  {
    0x7F, 0x04, 0x08, 0x10, 0x7F     }
  ,   // N
  {
    0x3E, 0x41, 0x41, 0x41, 0x3E     }
     // O

  ,   // Y
  {
    0x61, 0x51, 0x49, 0x45, 0x43     }
    //Z
};
/*--------------------------------------------------------------------------------------------------
 
 Name         :  LcdSendCmd
 
 Description  :  Sends data to display controller.
 
 Argument(s)  :  data -> Data to be sent
 cd   -> Command or data (see/use enum)
 
 Return value :  None.
 
 --------------------------------------------------------------------------------------------------*/
void LcdSendCmd ( byte data, int cd )
{


  byte i = 8;

  byte mask;



  //

  if ( cd == LCD_DATA )
  {
    digitalWrite(LCD_DC_PIN,HIGH);
  }
  else
  {
    digitalWrite(LCD_DC_PIN,LOW) ;
  }




  while(0 < i) {

    mask = 0x01 << --i; // get bitmask and move to least significant bit
    // cause edge to fall
    digitalWrite(SPI_CLK_PIN,LOW); // tick
    delayMicroseconds(400);
    // set out byte
    if(data & mask){ // choose bit

      digitalWrite(SPI_MOSI_PIN,HIGH); // send 1

    }
    else{

      digitalWrite(SPI_MOSI_PIN,LOW); // send 0

    }

    // cause edge to rise

    digitalWrite(SPI_CLK_PIN,HIGH); // tock
    delayMicroseconds(400);





  }


}

/*--------------------------------------------------------------------------------------------------
 
 Name         :  LcdInit
 
 Description  :  Performs MCU SPI & LCD controller initialization.
 
 Argument(s)  :  None.
 
 Return value :  None.
 
 --------------------------------------------------------------------------------------------------*/
void LcdInit ( void )
{

  int m;


  //  Toggle display reset pin.
  digitalWrite(LCD_RST_PIN,LOW);
  delay(40);
  digitalWrite(LCD_RST_PIN,HIGH);

  //  Enable SPI port: No interrupt, MSBit first, Master mode, CPOL->0, CPHA->0, Clk/4
  // SPCR = 0x50;



  LcdSendCmd( 0x21, LCD_CMD );  // LCD Extended Commands.
  LcdSendCmd( 0xB3, LCD_CMD );  // Set LCD Vop (Contrast). //B1
  LcdSendCmd( 0x04, LCD_CMD );  // Set Temp coefficent. //0x04

  LcdSendCmd( 0x13, LCD_CMD );  // LCD bias mode 1:48. //0x13
  LcdSendCmd( 0x20, LCD_CMD );  // LCD Standard Commands, Horizontal addressing mode.

  LcdSendCmd( 0x0C, LCD_CMD );  // LCD in normal mode. 0x0d for inverse
  // LcdSendCmd( 0x0D, LCD_CMD );

  //  Reset watermark pointers.
  LoWaterMark = LCD_CACHE_SIZE;
  HiWaterMark = 0;
  


  
    LcdClear();
  LcdUpdate();
}

Logged

berlin
Offline Offline
Sr. Member
****
Karma: 0
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

part 2:

Code:


/*--------------------------------------------------------------------------------------------------
 
 Name         :  LcdContrast
 
 Description  :  Set display contrast.
 
 Argument(s)  :  contrast -> Contrast value from 0x00 to 0x7F.
 
 Return value :  None.
 
 Notes        :  No change visible at ambient temperature.
 
 --------------------------------------------------------------------------------------------------*/
void LcdContrast ( byte contrast )
{
  //  LCD Extended Commands.
  LcdSendCmd( 0x21, LCD_CMD );

  // Set LCD Vop (Contrast).
  LcdSendCmd( 0x80 | contrast, LCD_CMD );

  //  LCD Standard Commands, horizontal addressing mode.
  LcdSendCmd( 0x20, LCD_CMD );
}

/*--------------------------------------------------------------------------------------------------
 
 Name         :  LcdClear
 
 Description  :  Clears the display. LcdUpdate must be called next.
 
 Argument(s)  :  None.
 
 Return value :  None.
 
 --------------------------------------------------------------------------------------------------*/
void LcdClear ( void )
{
  int i;

  for ( i = 0; i < LCD_CACHE_SIZE; i++ )
  {
    LcdCache[i] = 0x00;
  }

  //  Reset watermark pointers.
  LoWaterMark = 0;
  HiWaterMark = LCD_CACHE_SIZE - 1;

  UpdateLcd = true;
}

/*--------------------------------------------------------------------------------------------------
 
 Name         :  LcdGotoXY
 
 Description  :  Sets cursor location to xy location corresponding to basic font size.
 
 Argument(s)  :  x, y -> Coordinate for new cursor position. Range: 1,1 .. 14,6
 
 Return value :  None.
 
 --------------------------------------------------------------------------------------------------*/
void LcdGotoXY ( byte x, byte y )
{
  LcdCacheIdx = (x - 1) * 6 + (y - 1) * 84;
}

/*--------------------------------------------------------------------------------------------------
 
 Name         :  LcdChr
 
 Description  :  Displays a character at current cursor location and increment cursor location.
 
 Argument(s)  :  size -> Font size. See enum.
 ch   -> Character to write.
 
 Return value :  None.
 
 --------------------------------------------------------------------------------------------------*/
void LcdChr ( int size, byte ch )
{
  byte i, c;
  byte b1, b2;
  int  tmpIdx;

  if ( LcdCacheIdx < LoWaterMark )
  {
    //  Update low marker.
    LoWaterMark = LcdCacheIdx;
  }

  if ( (ch < 0x20) || (ch > 0x7b) )
  {
    //  Convert to a printable character.
    ch = 65;
  }

  if ( size == FONT_1X )
  {
    for ( i = 0; i < 5; i++ )
    {
      LcdCache[LcdCacheIdx++] = FontLookup[ch - 65][i] << 1;
    }
  }
  else if ( size == FONT_2X )
  {
    tmpIdx = LcdCacheIdx - 84;

    if ( tmpIdx < LoWaterMark )
    {
      LoWaterMark = tmpIdx;
    }

    if ( tmpIdx < 0 ) return;

    for ( i = 0; i < 5; i++ )
    {
      c = FontLookup[ch - 32][i] << 1;
      b1 =  (c & 0x01) * 3;
      b1 |= (c & 0x02) * 6;
      b1 |= (c & 0x04) * 12;
      b1 |= (c & 0x08) * 24;

      c >>= 4;
      b2 =  (c & 0x01) * 3;
      b2 |= (c & 0x02) * 6;
      b2 |= (c & 0x04) * 12;
      b2 |= (c & 0x08) * 24;

      LcdCache[tmpIdx++] = b1;
      LcdCache[tmpIdx++] = b1;
      LcdCache[tmpIdx + 82] = b2;
      LcdCache[tmpIdx + 83] = b2;
    }

    //  Update x cursor position.
    LcdCacheIdx += 11;
  }

  if ( LcdCacheIdx > HiWaterMark )
  {
    //  Update high marker.
    HiWaterMark = LcdCacheIdx;
  }

  //  Horizontal gap between characters.
  LcdCache[LcdCacheIdx++] = 0x00;
}

/*--------------------------------------------------------------------------------------------------
 
 Name         :  LcdStr
 
 Description  :  Displays a character at current cursor location and increment cursor location
 according to font size.
 
 Argument(s)  :  size    -> Font size. See enum.
 dataPtr -> Pointer to null terminated ASCII string to display.
 
 Return value :  None.
 
 --------------------------------------------------------------------------------------------------*/
void LcdStr ( int size, byte *dataPtr )
{
  while ( *dataPtr )
  {
    LcdChr( size, *dataPtr++ );
  }
}

Logged

berlin
Offline Offline
Sr. Member
****
Karma: 0
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

part 3 and final:

Code:
/*--------------------------------------------------------------------------------------------------
 
 Name         :  LcdPixel
 
 Description  :  Displays a pixel at given absolute (x, y) location.
 
 Argument(s)  :  x, y -> Absolute pixel coordinates
 mode -> Off, On or Xor. See enum.
 
 Return value :  None.
 
 --------------------------------------------------------------------------------------------------*/
void LcdPixel ( byte x, byte y, int mode )
{
  word  index;
  byte  offset;
  byte  data;

  if ( x > LCD_X_RES ) return;
  if ( y > LCD_Y_RES ) return;

  index = ((y / 8) * 84) + x;
  offset  = y - ((y / 8) * 8);

  data = LcdCache[index];

  if ( mode == PIXEL_OFF )
  {
    data &= (~(0x01 << offset));
  }
  else if ( mode == PIXEL_ON )
  {
    data |= (0x01 << offset);
  }
  else if ( mode  == PIXEL_XOR )
  {
    data ^= (0x01 << offset);
  }

  LcdCache[index] = data;

  if ( index < LoWaterMark )
  {
    //  Update low marker.
    LoWaterMark = index;
  }

  if ( index > HiWaterMark )
  {
    //  Update high marker.
    HiWaterMark = index;
  }
}

/*--------------------------------------------------------------------------------------------------
 
 Name         :  LcdLine
 
 Description  :  Draws a line between two points on the display.
 
 Argument(s)  :  x1, y1 -> Absolute pixel coordinates for line origin.
 x2, y2 -> Absolute pixel coordinates for line end.
 mode   -> Off, On or Xor. See enum.
 
 Return value :  None.
 
 --------------------------------------------------------------------------------------------------*/
void LcdLine ( byte x1, byte y1, byte x2, byte y2, int mode )
{
  int dx, dy, stepx, stepy, fraction;

  dy = y2 - y1;
  dx = x2 - x1;

  if ( dy < 0 )
  {
    dy    = -dy;
    stepy = -1;
  }
  else
  {
    stepy = 1;
  }

  if ( dx < 0 )
  {
    dx    = -dx;
    stepx = -1;
  }
  else
  {
    stepx = 1;
  }

  dx <<= 1;
  dy <<= 1;

  LcdPixel( x1, y1, mode );

  if ( dx > dy )
  {
    fraction = dy - (dx >> 1);
    while ( x1 != x2 )
    {
      if ( fraction >= 0 )
      {
        y1 += stepy;
        fraction -= dx;
      }
      x1 += stepx;
      fraction += dy;
      LcdPixel( x1, y1, mode );
    }
  }
  else
  {
    fraction = dx - (dy >> 1);
    while ( y1 != y2 )
    {
      if ( fraction >= 0 )
      {
        x1 += stepx;
        fraction -= dy;
      }
      y1 += stepy;
      fraction += dx;
      LcdPixel( x1, y1, mode );
    }
  }

  UpdateLcd = true;
}

/*--------------------------------------------------------------------------------------------------
 
 Name         :  LcdUpdate
 
 Description  :  Copies the LCD cache into the device RAM.
 
 Argument(s)  :  None.
 
 Return value :  None.
 
 --------------------------------------------------------------------------------------------------*/
void LcdUpdate ( void )
{
  int i;
  
//always update everything for the moment
LoWaterMark = 0;
HiWaterMark = LCD_CACHE_SIZE - 1;


  if ( LoWaterMark < 0 ){
    LoWaterMark = 0;
  }
  else if ( LoWaterMark >= LCD_CACHE_SIZE ){
    LoWaterMark = LCD_CACHE_SIZE - 1;
  }

  if ( HiWaterMark < 0 ){
    HiWaterMark = 0;
  }
  else if ( HiWaterMark >= LCD_CACHE_SIZE ){
    HiWaterMark = LCD_CACHE_SIZE - 1;
  }

  //  Set base address according to LoWaterMark.
  LcdSendCmd( 0x80 | (LoWaterMark % LCD_X_RES), LCD_CMD );
  LcdSendCmd( 0x40 | (LoWaterMark / LCD_X_RES), LCD_CMD );

  //  Serialize the video buffer.
  for ( i = LoWaterMark; i <= HiWaterMark; i++ )
  {
    LcdSendCmd( LcdCache[i], LCD_DATA );
  }

  //  Reset watermark pointers.
  LoWaterMark = LCD_CACHE_SIZE - 1;
  HiWaterMark = 0;

  UpdateLcd = false;
}




void setup() {

  beginSerial(19200);
  //power the control led
  pinMode(CONTROL_LED,OUTPUT);


  pinMode(LCD_RST_PIN,OUTPUT);
  pinMode(LCD_DC_PIN ,OUTPUT);
  pinMode(LCD_CE_PIN ,OUTPUT);
  pinMode(SPI_MOSI_PIN ,OUTPUT);
  pinMode(SPI_CLK_PIN,OUTPUT);
 pinMode(voltometer,OUTPUT);



  //power the display
  pinMode(LCD_POWER_PIN,OUTPUT);
  //start
  digitalWrite(CONTROL_LED, HIGH);
  analogWrite(voltometer, 150);
  LcdInit();
  




}

void loop() {
 
LcdClear();
delay(100);
LcdGotoXY ( 7, 3 );  
    
LcdStr(1, "OK");

LcdUpdate();

delay(500);




}


hope you can work with it.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you for the code
I have got a problem when I compile my sketch


In function 'void loop()':
error: invalid conversion from 'const char*' to 'byte*'


could you help me ?

Code:
#include <lcdnokia.h>
void setup()
{
  beginSerial(19200);
  //power the control led
  pinMode(CONTROL_LED,OUTPUT);


  pinMode(LCD_RST_PIN,OUTPUT);
  pinMode(LCD_DC_PIN ,OUTPUT);
  pinMode(LCD_CE_PIN ,OUTPUT);
  pinMode(SPI_MOSI_PIN ,OUTPUT);
  pinMode(SPI_CLK_PIN,OUTPUT);
 pinMode(voltometer,OUTPUT);

  //power the display
  pinMode(LCD_POWER_PIN,OUTPUT);
  //start
  digitalWrite(CONTROL_LED, HIGH);
  analogWrite(voltometer, 150);
  LcdInit();

}

void loop()
  {
    LcdClear();
    delay(100);
    LcdGotoXY ( 7, 3 );
    LcdStr(1, "ok");
    LcdUpdate();
    delay(500);
 }

I use Kuk header's file:
http://alx.alxblog.com/arduino/
Logged

Pages: 1 [2] 3   Go Up
Jump to: