Nuelectronics ethernet shield and Nokia LCD shield

Hi,

I'd like to be able to use the Nuelectronics ethernet shield and Nokia LCD shield together, so that I can display information from my home network on the screen. I've downloaded the schematics, and they seem to both use digital pins 9-11.

The LCD library has the following in a header file:

/* Pin definition for Arduino boards */

#define CS 10

#define CLK 13

#define DATA 11

#define RESET 9

#define BL_ON 8

and the website says this about the LCD screen:

The Nokia LCD is controlled by Arduino's SPI port at 3.3V logic.

Many thanks,

--James.

was this a question???

I'm not an expert but I think it can drive one SPI device at a time. Not like an I2C or 1-wire bus. Am I right?
And SPI pins are fixed.. like the latest ones.

Broadly, each SPI device on the bus needs one unique chip select pin (CS) and shares the other 3 pins (MISO, MOSI, SCK) with all the other devices. Only one device can be communicated to/from at a time AFAIK.

--Phil.

Has anybody managed to get these 2 shields working at the same time? I got a project where I get some weather data from a php file (parsed and ready to be used), and a Nokia LCD screen where I'm planning to show it, but as soon as I use the client.print, it just blanks the screen.....

Any ideas would be greatly appreciated....

I've started to delve into splitting off the CS/SS pin from the main SPI pins, clk, miso, mosi, from reading the 168/328/1280 datasheet and the SPI datasheet and some other atmel product note stuff, if the duemilanove/Mega is in SPI master mode (which it is for the LCD) then the SS pin location is not critical, so you can assign any pin you like, you just have to handle the toggling of 'a' pin connected to the slaves select pin when you want to send data, so you can share the data,miso,mosi pins, and assign a seperate pin for each SS.

The nokia_lcd library has the pins hardcoded, but it is possible to reassign them although its not as simple as its done using register poking rather than more human readable C code. I've sucessfully managed to reassign the pins in the library and breakout the LCD pins to work on a Mega.

Here's what I did with header PCF8833.h to get the lcd to work on a mega, the backlight and reset pins whilst called the same thing aren't assigned to the same ports 'under the hood' + the SPI pins are 'jumbled'.

Compare the AVR_ATmega1280 ifdef and define with the bottom 1/2 to get an idea of how to do the reassignment to suit you, use this http://spreadsheets.google.com/pub?key=rtHw_R6eVL140KS9_G8GPkA&gid=0 as a reference for the pin assignments. See below the code for an untested idea of what you need to look at for a start.

/*Added ifdef to allow the shield to work directly on a normal arduino mega board
  with the SPI pins broken out, Set RESET and BL_PINS according to your LCD wiring */
#ifdef __AVR_ATmega1280__
#define CS 53
#define CLK 52
#define DATA 51
#define RESET 9
#define BL_ON  8
#ifdef PB1
#define LCD_CS(x)           PORTB= (x)? (PORTB|(1<<PB0)) : (PORTB&~(1<<PB0))
#define LCD_CLK(x)          PORTB= (x)? (PORTB|(1<<PB1)) : (PORTB&~(1<<PB1))
#define LCD_DATA(x)         PORTB= (x)? (PORTB|(1<<PB2)) : (PORTB&~(1<<PB2))
#define LCD_RESET(x)        PORTH= (x)? (PORTH|(1<<PH6)) : (PORTH&~(1<<PH6))
#define LCD_BACKLIGHT(x)    PORTH= (x)? (PORTH|(1<<PH5)) : (PORTH&~(1<<PH5))
#else
#define LCD_CS(x)           PORTB= (x)? (PORTB|(1<<PORTB0)) : (PORTB&~(1<<PORTB0))
#define LCD_CLK(x)          PORTB= (x)? (PORTB|(1<<PORTB1)) : (PORTB&~(1<<PORTB1))
#define LCD_DATA(x)         PORTB= (x)? (PORTB|(1<<PORTB2)) : (PORTB&~(1<<PORTB2))
#define LCD_RESET(x)        PORTH= (x)? (PORTH|(1<<PORTH6)) : (PORTH&~(1<<PORTH6))
#define LCD_BACKLIGHT(x)    PORTH= (x)? (PORTH|(1<<PORTH5)) : (PORTH&~(1<<PORTH5))
#endif // End of PB1
#else // Every other arduino that this library worked with
#define CS      10
#define CLK 13
#define DATA 11
#define RESET 9
#define BL_ON  8
#ifdef PB1
#define LCD_CS(x)           PORTB= (x)? (PORTB|(1<<PB2)) : (PORTB&~(1<<PB2))
#define LCD_CLK(x)          PORTB= (x)? (PORTB|(1<<PB5)) : (PORTB&~(1<<PB5))
#define LCD_DATA(x)         PORTB= (x)? (PORTB|(1<<PB3)) : (PORTB&~(1<<PB3))
#define LCD_RESET(x)        PORTB= (x)? (PORTB|(1<<PB1)) : (PORTB&~(1<<PB1))
#define LCD_BACKLIGHT(x)    PORTB= (x)? (PORTB|(1<<PB0)) : (PORTB&~(1<<PB0))
#else
#define LCD_CS(x)           PORTB= (x)? (PORTB|(1<<PORTB2)) : (PORTB&~(1<<PORTB2))
#define LCD_CLK(x)          PORTB= (x)? (PORTB|(1<<PORTB5)) : (PORTB&~(1<<PORTB5))
#define LCD_DATA(x)         PORTB= (x)? (PORTB|(1<<PORTB3)) : (PORTB&~(1<<PORTB3))
#define LCD_RESET(x)        PORTB= (x)? (PORTB|(1<<PORTB1)) : (PORTB&~(1<<PORTB1))
#define LCD_BACKLIGHT(x)    PORTB= (x)? (PORTB|(1<<PORTB0)) : (PORTB&~(1<<PORTB0))
#endif
#endif

// PB5 = clock (SCK)=13,  PB2 = SS (CS)=10, PB3 = data(mosi) = 11, PB1 = reset =9, PB0 = backlight = 8
// PB1 = clock (SCK)=52,  PB0 = SS (CS)=53, PB2 = data(mosi) = 51, PH6 = reset = 9, PH5 = backlight = 8

I believe you will need to change this line:
#define LCD_CLK(x) PORTB= (x)? (PORTB|(1<<PB1)) : (PORTB&~(1<<PB1)) // for the mega

or this line:
#define LCD_CS(x) PORTB= (x)? (PORTB|(1<<PB2)) : (PORTB&~(1<<PB2)) // for the 168/328 boards

and this define:
#define CS 53 // 53 on the mega/10 on the 168/328

So if you wanted to make the CS pin analog 3 on a duemilanove (using the analog pin 3 as a digital pin) it would be:
#define LCD_CS(x) PORTC= (x)? (PORTC|(1<<PC3)) : (PORTC&~(1<<PC3)) // PORTC/PC3 for the 168/328 boards

and for the mega:
#define LCD_CS(x) PORTH= (x)? (PORTH|(1<<PH0)) : (PORTH&~(1<<PH0)) // PORTH/PH0 for the 1280 mega boards

And for either board:
#define CS 17

Please excuse my scrappy attempt at the ifdef for the 1280, it was my first attempt and it works for me, that was the main object of changing things, i also had issues with the PB/PORTB definitions too between boards, It'd would be nice to know if I got things right or how to correct it if not.

I'm really not sure why the CS,CLK and DATA #defines are there, they don't seem to be used at all it seems like the author was maybe exploring alternative methods for banging the data out to the screen.

You may also need to keep any eye on the spi registers to see if one lib is occupying the bus, you don't want to start sending data while the CS line is still active for the LCD and vice versa which is what is happening for you at the moment on top of both devices sharing the CS pin.

The nokia LCD library doesn't check the state of the registers it just switches the CS pin and starts sending data, the SDout pin from the PCF8833 isn't connected to the arduino so it doesn't wait for any data back either, so thats one issue to not have to worry about, I haven't looked at the ethernet code but I would take a guess and say that its running on an interrupt, so you may have issues to deal with there too.

Let me know if any of that helps or if you discover anything else.... :slight_smile:

Oh, one last thing the backlight pin (digital 8) could be tied to 5v to free up the pin. Of course whether you break out the backlight pin or not you will have to breakout the CS pin on one of the shields, (lcd I guess as its the top one), this could be done with a 8xsingle track bit of vero board, some long legged female stack headers and pins/headers to suit, with the bonus of getting extra gnd pins and SPI pins for other devices.

Erm, this really is the last thing... If you breakout the backlight pin you can dump it onto a pin with PWM (err, like pin 9......) to give you brightness control, no real reason they didn't do it on the 168s and I'm not really sure why they put the reset button on pin 9, it can safely be disconnected and could be re-routed to the arduino reset pin. the design of the LCD shield needs a little rethink IMHO as it only uses 4 necessary pins (data,clk, cs and analog 0 for the joystick) but blocks access to all the other pins :confused:

Regards,
Reggie.

Hello Reggie,

Thanks for your efford for looking into this.

I just bought this kit, because according the shop (nuelectronics) it should work together flawlessly...

But i'm just a beginner with the Arduino, I have the Freeduino, can somebody tell me what I should change for the normal freeduino, not the Mega?

Btw, the support from nuelectronics is just poor, they never reply to emails, I have 1 broken nokia LCD, but how do I get it back now?

I must say that it's disappointing that they aren't replying to your emails, I haven't had that issue myself, although I haven't tried emailing recently.

I can't advise on whether the freeduino would be a better choice as I don't have the ethernet shield to test.

Hi Reggie,

I have actually hardwired pins 10, 13, 11, 9, 8 to 4, 2, 3, 5, 6 and using the following in PCF8833.h

#define CS      4
#define CLK 2
#define DATA 3
#define RESET 5
#define BL_ON  6

#ifdef PB1
#define LCD_CS(x)           PORTD= (x)? (PORTD|(1<<PD4)) : (PORTD&~(1<<PD4))
#define LCD_CLK(x)          PORTD= (x)? (PORTD|(1<<PD2)) : (PORTB&~(1<<PD2))
#define LCD_DATA(x)         PORTD= (x)? (PORTD|(1<<PD3)) : (PORTB&~(1<<PD3))
#define LCD_RESET(x)        PORTD= (x)? (PORTD|(1<<PD5)) : (PORTB&~(1<<PD5))
#define LCD_BACKLIGHT(x)    PORTD= (x)? (PORTD|(1<<PD6)) : (PORTB&~(1<<PD6))
#else
#define LCD_CS(x)           PORTD= (x)? (PORTD|(1<<PORTD4)) : (PORTD&~(1<<PORTD4))
#define LCD_CLK(x)          PORTD= (x)? (PORTD|(1<<PORTD2)) : (PORTD&~(1<<PORTD2))
#define LCD_DATA(x)         PORTD= (x)? (PORTD|(1<<PORTD3)) : (PORTD&~(1<<PORTD3))
#define LCD_RESET(x)        PORTD= (x)? (PORTD|(1<<PORTD5)) : (PORTD&~(1<<PORTD5))
#define LCD_BACKLIGHT(x)    PORTD= (x)? (PORTD|(1<<PORTD6)) : (PORTD&~(1<<PORTD6))
#endif

But I don't get the screen to work properly. I have also followed your advice of just changing CS, but that did not work either. I'm using a 328 board + Ethernet Shield + Protoshield (for the hardwiring of the pins).

Any advice?

I'll get back to you on it later when I've had a chance to have a look at what you and the lcd are up to :slight_smile:

I've just dropped my phone down the toilet so I need to go and grab a decent torx set before I do anything else, curse you nokia....

Ok, well, it's a 328 chip, so the pinout is the same as my diecimila (upgraded to a 328 chip so its the definitely the same).

the issue is probably with the fact that you need to leave the CLK and DATA pins as they are, the pcf8833 code implicitly uses the arduinos SPI by registers name, so in effect they are hard-coded, you have also mixed portb stuff with portd on your reset and backlight defines, which probably won't work, does the backlight actually turn on?

Try this:

#define CS  4  // this is fine
#define CLK 13  // this should be connected to the SPI pins the same as the ethernet
#define DATA 11 // and this one
#define RESET 5 // this is fine
#define BL_ON  6 // this is fine

#ifdef PB1
#define LCD_CS(x)           PORTD= (x)? (PORTD|(1<<PD4)) : (PORTD&~(1<<PD4))
#define LCD_CLK(x)          PORTB= (x)? (PORTB|(1<<PB5)) : (PORTB&~(1<<PB5))  // SPI CLK
#define LCD_DATA(x)         PORTB= (x)? (PORTB|(1<<PB3)) : (PORTB&~(1<<PB3)) // SPI DATA
#define LCD_RESET(x)        PORTD= (x)? (PORTD|(1<<PD5)) : (PORTD&~(1<<PD5))
#define LCD_BACKLIGHT(x)    PORTD= (x)? (PORTD|(1<<PD6)) : (PORTD&~(1<<PD6))
#else
#define LCD_CS(x)           PORTD= (x)? (PORTD|(1<<PORTD4)) : (PORTD&~(1<<PORTD4))
#define LCD_CLK(x)          PORTB= (x)? (PORTB|(1<<PORTB5)) : (PORTB&~(1<<PORTB5))  //SPI CLK
#define LCD_DATA(x)        PORTB= (x)? (PORTB|(1<<PORTB3)) : (PORTB&~(1<<PORTB3)) //SPI DATA
#define LCD_RESET(x)        PORTD= (x)? (PORTD|(1<<PORTD5)) : (PORTD&~(1<<PORTD5))
#define LCD_BACKLIGHT(x)    PORTD= (x)? (PORTD|(1<<PORTD6)) : (PORTD&~(1<<PORTD6))
#endif

all things being equal that should work, the ethernet shield CS/SS pin should be connected as normal to pin 10, both the ethernet sheild and the nokia shield should be connected to pins 13(CLK) and 11(DATA), the nokia shields CS pin to pin4, and the reset and backlight to pin 5 and 6. Any other ethernet pins that I've missed should be connected as normal. but really, you should only have to 'break out' the CS pin from the nokia shield for it all to work.

let me know how it goes :slight_smile:

a little bit more information for you, I've dug through the ethershield library,
and the pins the shield uses are defined in enc28j60.c:

#define ENC28J60_CONTROL_CS     10
#define SPI_MOSI                11
#define SPI_MISO                12
#define SPI_SCK                13

so these definitely must be straight through connected, which they will be as standard, so its just the nokia pin connections from my last post that you need to make sure are correct.

Thanks Reggie. I just realised that my hard-wiring is not correct... I'll try again tonight coupled with your suggestions. Update to follow!

Hi Reggie. I have finished the re-wiring on the protoshield, and followed your advice of keeping port 13 & 11, the same, and wiring the other ports. Copied your code into my PCF8833.h file. I get a back-light, but nothing else.... How can I check what I'm doing wrong?

Is that with or without the ethernet shield plugged in? First thing would be to get it confirmed working without the ethernet shield plugged in.

I'll have a look at mine a bit later and see if I can get mine to run the same. I'll do it on my arduino mega though as the 328 is a bit tied up atm. the SPI implementation is the same, only the pins are different.

Just looking at and comparing the 2 libraries, it could be something to do with the initialisation routines, Which devices init function do you call first?

As far as I can tell the initialisation routines are the only place where the 2 libraries can interfere with each other but that's a bit of a guess. I 'll have a look at it a bit more in depth in the morning.

I think that as long as they are being initialised with the same settings (clock speed, master etc.) then only one of the .init() calls needs to be made, I think the ethernet shield sets its CS pin inactive and then changes the registers, I'm not sure entirely what the outcome of this would be but its the only thing that I can think of that could make it not work, this is assuming that the LCD shield works on its own with those settings.

Looks like this thread confirms that the wiring should work fine with the CS pin assigned wherever you like, http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1256888092

Seems to also suggest that there is an underlying issue with the ethernet shield + other devices, to be fair it could be down to the SPI implementation although I'm fairly certain that we would've seen a lot more posts indicating SPI issues.

Other things to try:

Leave both shields connected and then run a sketch on the arduino that uses the LCD shield but doesn't contain any code for the ethernet shield, let me know if it works or not. If it does then it points a finger at the init routines.

Reggie,

I haven't had time yet to change any of the pins but this is what I get.

When I connect the Nokia LCD ontop the Network shield, and I initialize the network first and then the LCD both will work. The LCD will give light and text and works ok.

But when I start messing with the TCP like sending a message, the screen will go bananas. But when it has finished I can write again to the LCD and it will show text again.

Ok, looks like we are starting to get somewhere, could you post the code that you are using please?

I've looked through the ethernet code and followed it as much as I can, it seems to behave nicely and do what its supposed to with regard to the CS pin. if the arduino is in master mode then you can use the SPI CS pin on the ethernet shield without issue, the ethernet shield seems to set itself up pretty much the same as the nokia shield, once its setup it only uses the toggling of the CS pin to send/recieve data.

Going right through the LCD shield code its a bit odd how it behaves with regard to SPI, the code is derived from the Olimex SAM7-EX256 board code, written by Jim Lynch, http://www.sparkfun.com/tutorial/Nokia%206100%20LCD%20Display%20Driver.pdf

it looks like the sam7-ex256 board has a superior SPI implementation, it seems that lcd has a dedicated SPI, as such the library just initialises the pins and the CS pin is left enabled, so its always connected, I think the arduino nokia shield lib attempts to deal with it and seems to follow some of the same principals but seems to be trying to make it more compatible and some other odd things with the clk pin, that don't seem to be described in the data sheet, so it seems like part of an implementation. it seems like it leaves the CS pin inactive while it sets up the spi, but tries to use the LCD_reset pin to enable the CS pin to start the initialisation, but as the CS pin is never taken low (Active) before the reset it doesn't setup properly. I'm really not sure why it spams the clk when its writing pixels either, disables hardware spi and all sorts :frowning: