Modified 3310 arduino playground code

Here’s the modified demo code for the 3310 series Lcd displays.   The original version displayed “hello world” and gave all the codes for characters, but didn’t have any cursor control, so I added some.  The extras are a CR+LF and a reset that takes you back to the top left corner ready for the next frame, as well as a slightly modified clear screen that also resets the cursor.

Feel free to suggest any modifications, I’ll add them and update it.

Anyway,  here’s the code :

// Modified version of first listing on arduino playground
// Showing simple cursor control including carriage return
// plus line feed and resetting to top left.
// Original Code here:
// http://www.arduino.cc/playground/Code/PCD8544
// by Chris
//
// mods by telbonic.
// more stuff here:
// telbonic.wordpress.com
// --------------------------------------------------------

// For the function to turn number variables into chars
// --------------------------------------------------------
#include <stdlib.h>

#define PIN_SCE   7
#define PIN_RESET 6
#define PIN_DC    5
#define PIN_SDIN  4
#define PIN_SCLK  3

#define LCD_C     LOW
#define LCD_D     HIGH

#define LCD_X     84
#define LCD_Y     48

int value1 = 0;
char value2[5];
int cursor_position = 72; // counts from 72 (top left) to 1 (bottom right)

static const byte ASCII[][5] =
{
 {
 0x00, 0x00, 0x00, 0x00, 0x00            } // 20  
 ,{
 0x00, 0x00, 0x5f, 0x00, 0x00            } // 21 !
 ,{
 0x00, 0x07, 0x00, 0x07, 0x00            } // 22 "
 ,{
 0x14, 0x7f, 0x14, 0x7f, 0x14            } // 23 #
 ,{
 0x24, 0x2a, 0x7f, 0x2a, 0x12            } // 24 $
 ,{
 0x23, 0x13, 0x08, 0x64, 0x62            } // 25 %
 ,{
 0x36, 0x49, 0x55, 0x22, 0x50            } // 26 &
 ,{
 0x00, 0x05, 0x03, 0x00, 0x00            } // 27 '
 ,{
 0x00, 0x1c, 0x22, 0x41, 0x00            } // 28 (
 ,{
 0x00, 0x41, 0x22, 0x1c, 0x00            } // 29 )
 ,{
 0x14, 0x08, 0x3e, 0x08, 0x14            } // 2a *
 ,{
 0x08, 0x08, 0x3e, 0x08, 0x08            } // 2b +
 ,{
 0x00, 0x50, 0x30, 0x00, 0x00            } // 2c ,
 ,{
 0x08, 0x08, 0x08, 0x08, 0x08            } // 2d -
 ,{
 0x00, 0x60, 0x60, 0x00, 0x00            } // 2e .
 ,{
 0x20, 0x10, 0x08, 0x04, 0x02            } // 2f /
 ,{
 0x3e, 0x51, 0x49, 0x45, 0x3e            } // 30 0
 ,{
 0x00, 0x42, 0x7f, 0x40, 0x00            } // 31 1
 ,{
 0x42, 0x61, 0x51, 0x49, 0x46            } // 32 2
 ,{
 0x21, 0x41, 0x45, 0x4b, 0x31            } // 33 3
 ,{
 0x18, 0x14, 0x12, 0x7f, 0x10            } // 34 4
 ,{
 0x27, 0x45, 0x45, 0x45, 0x39            } // 35 5
 ,{
 0x3c, 0x4a, 0x49, 0x49, 0x30            } // 36 6
 ,{
 0x01, 0x71, 0x09, 0x05, 0x03            } // 37 7
 ,{
 0x36, 0x49, 0x49, 0x49, 0x36            } // 38 8
 ,{
 0x06, 0x49, 0x49, 0x29, 0x1e            } // 39 9
 ,{
 0x00, 0x36, 0x36, 0x00, 0x00            } // 3a :
 ,{
 0x00, 0x56, 0x36, 0x00, 0x00            } // 3b ;
 ,{
 0x08, 0x14, 0x22, 0x41, 0x00            } // 3c <
 ,{
 0x14, 0x14, 0x14, 0x14, 0x14            } // 3d =
 ,{
 0x00, 0x41, 0x22, 0x14, 0x08            } // 3e >
 ,{
 0x02, 0x01, 0x51, 0x09, 0x06            } // 3f ?
 ,{
 0x32, 0x49, 0x79, 0x41, 0x3e            } // 40 @
 ,{
 0x7e, 0x11, 0x11, 0x11, 0x7e            } // 41 A
 ,{
 0x7f, 0x49, 0x49, 0x49, 0x36            } // 42 B
 ,{
 0x3e, 0x41, 0x41, 0x41, 0x22            } // 43 C
 ,{
 0x7f, 0x41, 0x41, 0x22, 0x1c            } // 44 D
 ,{
 0x7f, 0x49, 0x49, 0x49, 0x41            } // 45 E
 ,{
 0x7f, 0x09, 0x09, 0x09, 0x01            } // 46 F
 ,{
 0x3e, 0x41, 0x49, 0x49, 0x7a            } // 47 G
 ,{
 0x7f, 0x08, 0x08, 0x08, 0x7f            } // 48 H
 ,{
 0x00, 0x41, 0x7f, 0x41, 0x00            } // 49 I
 ,{
 0x20, 0x40, 0x41, 0x3f, 0x01            } // 4a J
 ,{
 0x7f, 0x08, 0x14, 0x22, 0x41            } // 4b K
 ,{
 0x7f, 0x40, 0x40, 0x40, 0x40            } // 4c L
 ,{
 0x7f, 0x02, 0x0c, 0x02, 0x7f            } // 4d M
 ,{
 0x7f, 0x04, 0x08, 0x10, 0x7f            } // 4e N
 ,{
 0x3e, 0x41, 0x41, 0x41, 0x3e            } // 4f O
 ,{
 0x7f, 0x09, 0x09, 0x09, 0x06            } // 50 P
 ,{
 0x3e, 0x41, 0x51, 0x21, 0x5e            } // 51 Q
 ,{
 0x7f, 0x09, 0x19, 0x29, 0x46            } // 52 R
 ,{
 0x46, 0x49, 0x49, 0x49, 0x31            } // 53 S
 ,{
 0x01, 0x01, 0x7f, 0x01, 0x01            } // 54 T
 ,{
 0x3f, 0x40, 0x40, 0x40, 0x3f            } // 55 U
 ,{
 0x1f, 0x20, 0x40, 0x20, 0x1f            } // 56 V
 ,{
 0x3f, 0x40, 0x38, 0x40, 0x3f            } // 57 W
 ,{
 0x63, 0x14, 0x08, 0x14, 0x63            } // 58 X
 ,{
 0x07, 0x08, 0x70, 0x08, 0x07            } // 59 Y
 ,{
 0x61, 0x51, 0x49, 0x45, 0x43            } // 5a Z
 ,{
 0x00, 0x7f, 0x41, 0x41, 0x00            } // 5b [
 ,{
 0x02, 0x04, 0x08, 0x10, 0x20            } // 5c ¥
 ,{
 0x00, 0x41, 0x41, 0x7f, 0x00            } // 5d ]
 ,{
 0x04, 0x02, 0x01, 0x02, 0x04            } // 5e ^
 ,{
 0x40, 0x40, 0x40, 0x40, 0x40            } // 5f _
 ,{
 0x00, 0x01, 0x02, 0x04, 0x00            } // 60 `
 ,{
 0x20, 0x54, 0x54, 0x54, 0x78            } // 61 a
 ,{
 0x7f, 0x48, 0x44, 0x44, 0x38            } // 62 b
 ,{
 0x38, 0x44, 0x44, 0x44, 0x20            } // 63 c
 ,{
 0x38, 0x44, 0x44, 0x48, 0x7f            } // 64 d
 ,{
 0x38, 0x54, 0x54, 0x54, 0x18            } // 65 e
 ,{
 0x08, 0x7e, 0x09, 0x01, 0x02            } // 66 f
 ,{
 0x0c, 0x52, 0x52, 0x52, 0x3e            } // 67 g
 ,{
 0x7f, 0x08, 0x04, 0x04, 0x78            } // 68 h
 ,{
 0x00, 0x44, 0x7d, 0x40, 0x00            } // 69 i
 ,{
 0x20, 0x40, 0x44, 0x3d, 0x00            } // 6a j
 ,{
 0x7f, 0x10, 0x28, 0x44, 0x00            } // 6b k
 ,{
 0x00, 0x41, 0x7f, 0x40, 0x00            } // 6c l
 ,{
 0x7c, 0x04, 0x18, 0x04, 0x78            } // 6d m
 ,{
 0x7c, 0x08, 0x04, 0x04, 0x78            } // 6e n
 ,{
 0x38, 0x44, 0x44, 0x44, 0x38            } // 6f o
 ,{
 0x7c, 0x14, 0x14, 0x14, 0x08            } // 70 p
 ,{
 0x08, 0x14, 0x14, 0x18, 0x7c            } // 71 q
 ,{
 0x7c, 0x08, 0x04, 0x04, 0x08            } // 72 r
 ,{
 0x48, 0x54, 0x54, 0x54, 0x20            } // 73 s
 ,{
 0x04, 0x3f, 0x44, 0x40, 0x20            } // 74 t
 ,{
 0x3c, 0x40, 0x40, 0x20, 0x7c            } // 75 u
 ,{
 0x1c, 0x20, 0x40, 0x20, 0x1c            } // 76 v
 ,{
 0x3c, 0x40, 0x30, 0x40, 0x3c            } // 77 w
 ,{
 0x44, 0x28, 0x10, 0x28, 0x44            } // 78 x
 ,{
 0x0c, 0x50, 0x50, 0x50, 0x3c            } // 79 y
 ,{
 0x44, 0x64, 0x54, 0x4c, 0x44            } // 7a z
 ,{
 0x00, 0x08, 0x36, 0x41, 0x00            } // 7b {
 ,{
 0x00, 0x00, 0x7f, 0x00, 0x00            } // 7c |
 ,{
 0x00, 0x41, 0x36, 0x08, 0x00            } // 7d }
 ,{
 0x10, 0x08, 0x08, 0x10, 0x08            } // 7e ?
 ,{
 0x78, 0x46, 0x41, 0x46, 0x78            } // 7f ?
};

void LcdCharacter(char character)
{
 LcdWrite(LCD_D, 0x00);
 for (int index = 0; index < 5; index++)
 {
 LcdWrite(LCD_D, ASCII[character - 0x20][index]);
 }
 LcdWrite(LCD_D, 0x00);
}

void LcdReturn(void)
{
 // finish the old screen
 if (cursor_position <= 71){
 int bytesremain = cursor_position * 7;
 for (int index = 1; index <= bytesremain; index++)
 {
 LcdWrite(LCD_D, 0x00);
 }
 cursor_position = 72;
 }
}

// Basic carriage return function
// --------------------------------------------------------
void LcdCR(void)
{
 if (cursor_position >= 61){
 int bytesremain = (cursor_position - 60) * 7;
 for (int index = 1; index <= bytesremain; index++)
 {
 LcdWrite(LCD_D, 0x00);
 }
 cursor_position = 60;
 }
 if ((cursor_position >= 49) && (cursor_position < 60)){
 int bytesremain = (cursor_position - 48) * 7;
 for (int index = 1; index <= bytesremain; index++)
 {
 LcdWrite(LCD_D, 0x00);
 }
 cursor_position = 48;
 }
if ((cursor_position >= 37) && (cursor_position < 48)){
 int bytesremain = (cursor_position - 36) * 7;
 for (int index = 1; index <= bytesremain; index++)
 {
 LcdWrite(LCD_D, 0x00);
 }
 cursor_position = 36;
 }
if ((cursor_position >= 25) && (cursor_position < 36)){
 int bytesremain = (cursor_position - 24) * 7;
 for (int index = 1; index <= bytesremain; index++)
 {
 LcdWrite(LCD_D, 0x00);
 }
 cursor_position = 24;
 }
 if ((cursor_position >= 13) && (cursor_position < 24)){
 int bytesremain = (cursor_position - 12) * 7;
 for (int index = 1; index <= bytesremain; index++)
 {
 LcdWrite(LCD_D, 0x00);
 }
 cursor_position = 12;
 }
}

// Modified clear, resets the cursor to the top left
// but is slow
// --------------------------------------------------------
void LcdClear(void)
{
 // finish the old screen
 if (cursor_position <= 71){
 int bytesremain = cursor_position * 7;
 for (int index = 1; index <= bytesremain; index++)
 {
 LcdWrite(LCD_D, 0x00);
 }
 cursor_position = 72;
 }

 // clear the rest, reset cursor_position
 for (int index = 0; index < 504; index++)
 {
 LcdWrite(LCD_D, 0x00);
 }
}

void LcdInitialise(void)
{
 pinMode(PIN_SCE, OUTPUT);
 pinMode(PIN_RESET, OUTPUT);
 pinMode(PIN_DC, OUTPUT);
 pinMode(PIN_SDIN, OUTPUT);
 pinMode(PIN_SCLK, OUTPUT);
 digitalWrite(PIN_RESET, LOW);
 digitalWrite(PIN_RESET, HIGH);
 LcdWrite(LCD_C, 0x20);
 LcdWrite(LCD_C, 0x0C);
}

void LcdString(char *characters)
{
 while (*characters)
 {
 LcdCharacter(*characters++);
 cursor_position--;
 if (cursor_position < 1) {
 cursor_position += 72;
 }

 }
}

void LcdWrite(byte dc, byte data)
{
 digitalWrite(PIN_DC, dc);
 digitalWrite(PIN_SCE, LOW);
 shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data);
 digitalWrite(PIN_SCE, HIGH);
}

void setup(void)
{
 LcdInitialise();
 LcdClear();
}

// Main loop, displays whatever is coming in on the
// six analog inputs.
// --------------------------------------------------------
void loop(void)
{
 LcdReturn ();
 LcdString ("Analog0:");
 value1 = analogRead (0) ;
 itoa (value1, value2, 10) ;
 LcdString (value2) ;

 LcdCR ();

 LcdString ("Analog1:");
 value1 = analogRead (1) ;
 itoa (value1, value2, 10) ;
 LcdString (value2) ;

 LcdCR ();

 LcdString ("Analog2:");
 value1 = analogRead (2) ;
 itoa (value1, value2, 10) ;
 LcdString (value2) ;

 LcdCR ();

 LcdString ("Analog3:");
 value1 = analogRead (3) ;
 itoa (value1, value2, 10) ;
 LcdString (value2) ;

 LcdCR ();

 LcdString ("Analog4:");
 value1 = analogRead (4) ;
 itoa (value1, value2, 10) ;
 LcdString (value2) ;

 LcdCR ();

 LcdString ("Analog5:");
 value1 = analogRead (5) ;
 itoa (value1, value2, 10) ;
 LcdString (value2) ;
}

Nokia 3310 Lcd

While working on a low frequency oscillator (LFO) for my modular synthesiser to be, I used a bunch of shift registers and some LED’s to fashion a display so I could see what was going on.  To cut a long story short, it worked but didn’t really convey enough information, and using a sparkfun LCD shield or some other prefabricated unit seemed to be cheating.

I had a bunch of old mobile phones in a drawer and decided to pull them apart to see if anyone out there had connected any of the screens.  On closer inspection they all either had teeny little interface connectors or those horrid flat plastic ribbon cables, with the exception of the Nokia 3320.  This little beauty had a row of little copper pins that pushed against and made contact with little pads on the main circuit board of the phone.  I thought I could either make a breakout board to screw it to, or solder ribbon cable to the pins (if I was really careful).

So, I got to reading.

I found this:  http://code.rancidbacon.com/LearningAboutArduinoNokiaLCD

which led me on to this: http://www.flickr.com/photos/12058013@N07/2203300707/

rapidly followed by: http://www.arduino.cc/playground/Code/PCD8544

Now this combination nearly worked.  I managed to solder a ribbon onto the screen (fiddly).  I added a small bit of stripboard for the circuit.  I used the 3.3v supply on my freeduino instead of the line of diodes.

The “hello world” text did show, just for a fraction of a second, with the screen filling with black until I had the digital version of the old pirate p45 (a large black square).   Repeated resets of the arduino showed that it did this every time.  I checked the connections (check!), double checked the circuit (check!), triple checked the soldering on the tiny row of pins (check!).  All was fine.

Then after more reading I found that others using similar interfaces used an electrolytic cap between Vo and GND, like so:

3310 Lcd to arduino interface, with cap mod

This worked like a dream, displaying “Hello World!” for anyone interested enough to be bothered to look, which included myself and our 10 year old.  The wife is very well practiced in the art of “thats nice dear”.

Once I’ve got the software sorted, I’ll post a modified version of the stuff on the playground which includes the ability to add carriage returns and returns the cursor to the top left, and can display information from variables.  In the meantime, thanks Kuk-i and everyone else who contributed to making our lives easier.

Hello

Welcome to the place where I keep track of my projects.  Don’t expect anything and we’ll get along just fine.  I’m a beginner in electronics, but I’m doing ok.  You probably know better than me, so feel free to point at things and tell me the right way to do them.