Go Down

Topic: Multiple Nokia LCDs (Read 896 times) previous topic - next topic

bporter88

Hi guys,

I'm trying to run an array of Nokia 5110 screens off an Arduino. I can make one work perfectly happily, and with a data line input from a different pin on the Arduino, kind of make another work (it's a little odd, dunno why). But, basically, i have no idea how to go about having a bank of LCD screens set up so that they can show one large image for example. Or, the dream being, a game of Snake over 12 phone screens

Any help would be really appreciated.

Cheers,

Ben

semicolo

My 2cents, it should work if you tie all the D/C,SDIN,SCLK of the screens together to the arduino and use one different arduino pin for the SCE input of each screen.
you activate the screen you want to write to (or even more than one if you need to send the same data) and you send the data.
So a standard arduino should be able to drive 12 screens quite easily (you need 3 common pins and 12 SCE pins).

bporter88

Thanks for the reply,

That's got me much nearer understanding how to crack this little puzzle of mine. I am experimenting with just 2 screens at the minute and I can get data to appear as a string of text on each screen when duplicated. However, when trying to control each screen separately it fails to function with quite the same, well, it doesn't really work.

I'm sure there must be a better way of handling it, at the minute I am repeating the functions in the code and defining each as function 1(for screen1) and function2(for screen 2). This results in a very long, and messy code.

I feel like it's close to being solved, but getting the screens to act as one, say with a text scroll across multiple screens I'm presuming I would need to use an array and say that once the pixel has reached 84X then skip to the second display at pixel 1X?

Here is the code so far.....apologies for the mess.


bporter88

Code: [Select]

[code]
// The pins to use on the arduino
#define PIN_SCE   7   // blue wire
#define PIN_SCE2  8   // yellow wire - secondary data line
#define PIN_RESET 6   // orange wire
#define PIN_DC    5   // yellow wire
#define PIN_SDIN  4   // green wire
#define PIN_SCLK  3   // white wire

// COnfiguration for the LCD
#define LCD_C     LOW
#define LCD_D     HIGH
#define LCD_CMD   0

// Size of the LCD
#define LCD_X     84
#define LCD_Y     48

int scrollPosition = -10;

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 ?
,{0x00, 0x06, 0x09, 0x09, 0x06} // 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 LcdCharacter2(char character)
{
 LcdWrite2(LCD_D, 0x00);
 for (int index = 0; index < 5; index++)
 {
   LcdWrite2(LCD_D, ASCII[character - 0x20][index]);
 }
 LcdWrite2(LCD_D, 0x00);
}


void LcdClear(void)
{
 for (int index = 0; index < LCD_X * LCD_Y / 8; index++)
 {
   LcdWrite(LCD_D, 0x00);
 }
}

void LcdClear2(void)
{
 for (int index = 0; index < LCD_X * LCD_Y / 8; index++)
 {
   LcdWrite2(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_CMD, 0x21);  // LCD Extended Commands.
 LcdWrite(LCD_CMD, 0xBf);  // Set LCD Vop (Contrast). //B1
 LcdWrite(LCD_CMD, 0x04);  // Set Temp coefficent. //0x04
 LcdWrite(LCD_CMD, 0x14);  // LCD bias mode 1:48. //0x13
 LcdWrite(LCD_CMD, 0x0C);  // LCD in normal mode. 0x0d for inverse
 LcdWrite(LCD_C, 0x20);
 LcdWrite(LCD_C, 0x0C);
}

void LcdInitialise2(void)
{
 pinMode(PIN_SCE2,   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);

 LcdWrite2(LCD_CMD, 0x21);  // LCD Extended Commands.
 LcdWrite2(LCD_CMD, 0xBf);  // Set LCD Vop (Contrast). //B1
 LcdWrite2(LCD_CMD, 0x04);  // Set Temp coefficent. //0x04
 LcdWrite2(LCD_CMD, 0x14);  // LCD bias mode 1:48. //0x13
 LcdWrite2(LCD_CMD, 0x0C);  // LCD in normal mode. 0x0d for inverse
 LcdWrite2(LCD_C, 0x20);
 LcdWrite2(LCD_C, 0x0C);
}


void LcdString(char *characters)
{
 while (*characters)
 {
   LcdCharacter(*characters++);
 }
}

void LcdString2(char *characters)
{
 while (*characters)
 {
   LcdCharacter2(*characters++);
 }
}


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 LcdWrite2(byte dc, byte data)
{
 digitalWrite(PIN_DC, dc);
 digitalWrite(PIN_SCE2, LOW);
 shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data);
 digitalWrite(PIN_SCE2, HIGH);
}


/**
* gotoXY routine to position cursor
* x - range: 0 to 84
* y - range: 0 to 5
*/
void gotoXY(int x, int y)
{
 LcdWrite( 0, 0x80 | x);  // Column.
 LcdWrite( 0, 0x40 | y);  // Row.
}

void gotoXY2(int x, int y)
{
 LcdWrite2( 0, 0x80 | x);  // Column.
 LcdWrite2( 0, 0x40 | y);  // Row.
}



void drawBox(void)
{
 int j;
 for(j = 0; j < 84; j++) // top
 {
   gotoXY(j, 0);
   LcdWrite(1, 0x01);
 }

 for(j = 0; j < 84; j++) //Bottom
 {
   gotoXY(j, 5);
   LcdWrite(1, 0x80);
 }

 for(j = 0; j < 6; j++) // Right
 {
   gotoXY(83, j);
   LcdWrite(1, 0xff);
 }

 for(j = 0; j < 6; j++) // Left
 {
   gotoXY(0, j);
   LcdWrite(1, 0xff);
 }
}


void drawBox2(void)
{
 int j;
 for(j = 0; j < 84; j++) // top
 {
   gotoXY2(j, 0);
   LcdWrite2(1, 0x01);
 }

 for(j = 0; j < 84; j++) //Bottom
 {
   gotoXY2(j, 5);
   LcdWrite2(1, 0x80);
 }

 for(j = 0; j < 6; j++) // Right
 {
   gotoXY2(83, j);
   LcdWrite2(1, 0xff);
 }

 for(j = 0; j < 6; j++) // Left
 {
   gotoXY2(0, j);
   LcdWrite2(1, 0xff);
 }
}


void Scroll(String message)
{
 for (int i = scrollPosition; i < scrollPosition + 11; i++)
 {
   if ((i >= message.length()) || (i < 0))
   {
     LcdCharacter(' ');
   }
   else
   {
     LcdCharacter(message.charAt(i));
   }
 }
 scrollPosition++;
 if ((scrollPosition >= message.length()) && (scrollPosition > 0))
 {
   scrollPosition = -10;
 }
}


void Scroll2(String message)
{
 for (int i = scrollPosition; i < scrollPosition + 11; i++)
 {
   if ((i >= message.length()) || (i < 0))
   {
     LcdCharacter2(' ');
   }
   else
   {
     LcdCharacter2(message.charAt(i));
   }
 }
 scrollPosition++;
 if ((scrollPosition >= message.length()) && (scrollPosition > 0))
 {
   scrollPosition = -10;
 }
}

void setup(void)
{
 LcdInitialise();
 LcdClear();
 drawBox();
 drawBox2();

 gotoXY(7,1);
 LcdString("Ben Porter");
 gotoXY(14,2);
 LcdString("[Re_Map]");
 
 gotoXY2(7,1);
 LcdString2("Punto");
 gotoXY2(14,2);
 LcdString2("Loxford");
 
 
}

void loop(void)
{
 gotoXY(4,4);
 Scroll("Test");
 delay(200);
 
 gotoXY2(4,4);
 Scroll2("Testing");
 delay(200);
}
[/code]

semicolo

You seem on the right track.

You could add a parameter to your functions to pass the SCE pin of the screen you want to drive

Code: [Select]

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

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


Then call
LcdCharacter('A', PIN_SCE);
or
LcdCharacter('B', PIN_SCE2);
You get the idea.

Yes you have to do exacly that for scrolling, when something goes out of the first screen it must be sent to the next one.

Go Up