Go Down

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

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).

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.


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.

Hi there, so i've been working away and have made some progress, but now am completely stumped. I've been working with the Adafruit library and GFX library in order to simplify my code. I've linked up the screens to separate SCE pins to send the different data, and have called th 3 different screens at the start of the code Adafruit PCD display_1......display_2 etc.

This all makes sense logically, and works on the screens as individual entities. HOWEVER, when I add the screens together, only the last screen in the series displays what I want. It seems by calling "display_2.begin();" it removes any data travelling to screen 1. I've pasted my code below, but I was wondering if anyone knows why you can only seem to send data to one screen?

Code: [Select]
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>

// pin 3 - Serial clock out (SCLK)     - (green wire)
// pin 4 - Serial data out (DIN)       - (blue wire)
// pin 5 - Data/Command select (D/C)   - (white wire)
// pin 6 - LCD reset (RST)             - (yellow wire)
// pin 7 - LCD Pin Data_screen 1 (SCE)         
// pin 8 - LCD Pin Data_screen 2 (SCE)
// pin 9 - LCD Pin Data_screen 3 (SCE)


#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2


#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH  16

static unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };

Adafruit_PCD8544 display1 = Adafruit_PCD8544(3, 4, 5, 7, 6);
Adafruit_PCD8544 display2 = Adafruit_PCD8544(3, 4, 5, 8, 6);
Adafruit_PCD8544 display3 = Adafruit_PCD8544(3, 4, 5, 9, 6);


void setup()   {
  Serial.begin(9600);
 
  display1.begin();
  display2.begin();
  display3.begin();
  display1.setContrast(50);
  display2.setContrast(50);
  display3.setContrast(50);
}

void loop() {
 
  display1.setTextSize(1);
  display1.setTextColor(BLACK);
  display1.setCursor(0,0);
  display1.println("A");
  display1.fillCircle(display1.width()/2, display1.height()/2, 5, BLACK);
  display1.display();
  delay(100);
  display1.clearDisplay();
 
  display2.setTextSize(1);
  display2.setTextColor(BLACK);
  display2.setCursor(0,0);
  display2.println("B");
  display2.fillCircle(display2.width()/2, display2.height()/2, 10, BLACK);
  display2.display();
  delay(100);
  display2.clearDisplay();
 
  display3.setTextSize(1);
  display3.setTextColor(BLACK);
  display3.setCursor(0,0);
  display3.println("C");
  display3.fillCircle(display3.width()/2, display3.height()/2, 15, BLACK);
  display3.display();
  delay(100);
  display3.clearDisplay();
}


Much appreciated

B

Go Up