Close

Repetier and I2C LCD panel

I was having yet another bash at persuading my breadboard based hardware to work with the I2C connected LCD display as mentioned in my Panelolu post.

I have been bashing my head against a wall with the Repetier firmware for months. Every time I had it use the LCD and uploaded the firmware, the whole board would hang just as it reached the initialisation of the LCD display.

I had tried with the built-in I2C library as well as several other Liquid Crystal libraries, none of which would work with Repetier once the LCD part was enabled.

I could manage to talk to the PCF8574P  I2C chip and obtain the address with the Scanner program, I could also write my own code to talk to the LCD all of which seemed to work fine, yet no matter what I did the LCD would just not play ball with Repetier.

I decided to re-read a bunch of posts about the various Liquid Crystal I2C libraries along with checking the schematics used for each of them, re-check the pin configurations in Repetier and also how it was wired up on the board.

Eventually I discovered that I had the RS and RW pins backwards in uiconfig.h for Repetier and after one last compile and upload we had success and the LCD sprang into life. (kind of begs the question how it was working with the other pieces of software though).

This is my pin configuration for the LCD in uiconfig.h

/**
What display type do you use?
0 = No display
1 = LCD Display with 4 bit data bus
2 = LCD Display with 8 bit data bus (currently not implemented, fallback to 1)
3 = LCD Display with I2C connection, 4 bit mode
4 = Use the slower LiquiedCrystal library bundled with arduino. 
    IMPORTANT: You need to uncomment the LiquidCrystal include in Repetier.pde for it to work.
               If you have Sanguino and want to use the library, you need to have Arduino 023 or older. (13.04.2012)
*/
#define UI_DISPLAY_TYPE 3

// This is line 2 of the status display at startup
#define UI_VERSION_STRING2 “Orig. Mendel”

/** Number of columns per row

Typical values are 16 and 20
*/
#define UI_COLS 16
/**
Rows of your display. 2 or 4
*/
#define UI_ROWS 2

/* What type of chip is used for I2C communication
0 : PCF8574 or PCF8574A or compatible chips.
1 : MCP23017
*/
#define UI_DISPLAY_I2C_CHIPTYPE 0
// 0x40 till 0x4e for PCF8574, 0x40 for the adafruid RGB shield, 0x40 – 0x4e for MCP23017
#define UI_DISPLAY_I2C_ADDRESS 0x40
// For MCP 23017 define which pins should be output
#define UI_DISPLAY_I2C_OUTPUT_PINS 65504
// Set the output mask that is or’d over the output data. This is needed to activate
// a backlight switched over the I2C. 
// The adafruit RGB shields enables a light if the bit is not set. Bits 6-8 are used for backlight.
#define UI_DISPLAY_I2C_OUTPUT_START_MASK 0
// For MCP which inputs are with pullup. 31 = pins 0-4 for adafruid rgb shield buttons
#define UI_DISPLAY_I2C_PULLUP 31
/* How fast should the I2C clock go. The PCF8574 work only with the lowest setting 100000.
A MCP23017 can run also with 400000 Hz */
#define UI_I2C_CLOCKSPEED 100000L
/**
Define the pin
*/
#if UI_DISPLAY_TYPE==3 // I2C Pin configuration
#define UI_DISPLAY_RS_PIN _BV(4)
#define UI_DISPLAY_RW_PIN _BV(5)
#define UI_DISPLAY_ENABLE_PIN _BV(6)
#define UI_DISPLAY_D0_PIN _BV(0)
#define UI_DISPLAY_D1_PIN _BV(1)
#define UI_DISPLAY_D2_PIN _BV(2)
#define UI_DISPLAY_D3_PIN _BV(3)
#define UI_DISPLAY_D4_PIN _BV(0)
#define UI_DISPLAY_D5_PIN _BV(1)
#define UI_DISPLAY_D6_PIN _BV(2)
#define UI_DISPLAY_D7_PIN _BV(3)

The _BV values are the P0-P7 pins from the PCF8574P chip – I only needed P0-P6, D0-D4 are for the low nibble, D5-D8 for the high nibble, you can connect in 8-bit mode if you have enough pins (D0-D7), or you can connect in 4-bit mode (D5-D7), you just pretend that both sets are connected to the same pins and both the low and high nibble data is transferred over these 4 pins.

As mentioned in my Firmware and Making Fumes post, I have 10 pins to play with (13 if you include MOSI, MISO and SCK) on the sanguinololu.

Now I have reduced my LCD pin requirement from 6 to 2, I have a few more to play with, which means I can use the buzzer again, and still have 3 pins spare.

Physical Pin # Pin Name Sanguinololu Pin Arduino Use My Use
7 PB6 D7 MISO SD card MISO
6 PB5 D6 MOSI SD card MOSI
8 PB7 D5 SCK SD card SCK
40 PA0 A0/D31 GP I/O SD card CS
9 RST RST RST Reset Button
38 PA2 A2/D29 GP I/O Encoder 1
39 PA1 A1/D30 GP I/O Encoder 2
16 PD2 D10 RX1 Encoder C
37 PA3 A3/D28 GP I/O Buzzer
22 PC0 D16 SCL I2C LCD SCL
23 PC1 D17 SDA I2C LCD SDA
36 PA4 A4/D27 GP I/O Free
5 PB4 D4 PWM Free
17 PD3 D11 TX1 Free
Whilst at a first glance, this might not seem the most logical layout, it makes more sense if you look at the way the pins are actually laid out on the sanguinololu.

I believe I have mentioned it already, but I am not interested in running any firmware that will not compile against a relatively current version of Arduino, (trying to obtain any support for issues with older versions is quite simply a pain), as such I am only interested in firmware that will compile against Arduino 1.0 or greater (I am currently using 1.0.5).

I have not compiled in the extra code for the rotary encoder or the buzzer yet, but things are looking good for using an ATmega644P rather than needing the more expensive ATmega1284P, as the compiled code is only 47,928 bytes. Previously with the Marlin firmware, after enabling the LCD code, I was beyond the 64Kb limit of the ATmega644P.

Here is a possible interface board for the panelolu.

And without the components covering the connections.

The only real difference from the schematic is that the connections for pins 9 and 11 (P4 and P6) have been swapped in order to make wiring simpler.

Leave a Reply