Hello, I just spent a good couple of hours getting my Bela to talk to a small 16x2 LCD panel so I thought I'd share my experience and code in case someone else wants to do it. This is C++ by the way, there was another thread about doing it over Pd.

I ordered my panel on eBay, similar to this one:
http://www.ebay.com/itm/Yellow-Display-IIC-I2C-TWI-SP-I-Serial-Interface-1602-16X2-LCD-Module-TOP-/321558565771?hash=item4ade62538b:g:R4gAAOSwZVlXmX5q

Note that it's not just the bare LCD panel, it has a small serial interface board. (otherwise you'd need lots of I/O pins, which I need for other things)

The panel talks at 5V levels so connecting it straight to the 3.3V I2C bus connector on the Bela (probably) won't work. To get around this, I got a small logic level converter board. Mine is a 4-channel, but only two are needed (for SCL and SDA). This is an example of a 2-ch, usually a few dollars, shipped.

http://www.ebay.com/itm/2-CH-I2C-IIC-Logic-Level-Converter-Module-Bi-Directional-5V-3V-for-Arduino-/131539592643?hash=item1ea05ee5c3

For prototyping I ran my 5V from the analog out 5V but I'll change that to a stronger supply as the display is a bit faded in this one.

Hardware:
- Connect the 5V supply to the Display's I2C VCC and to the converter board's "high-voltage" pin.
- Run the 3.3V from the Bela's I2C to the converter's "low-voltage".
- Run a GND from one of Bela's GND pins to the converter board and display's GND.
- Then run the Bela's I2C SDA and SCL signals each to a LV input of the converter board.
- Run the HV output for each of those two signals to the display's corresponding pins on I2C.
This sounds more complicated than it is. You're just powering the converter board and putting it between the two serial wires to convert levels.

Another option I read in the Pd thread is to use the analog audio outputs as 5V signals but then you'd have to deal with bit conversion and mostly render-loop sync for sending out your serial data. Seems the tiny converter board option is easier...

Software:
The library that ships with these things is meant for Arduino so a few things are missing and don't compile. I've modified the library source using the "capacitive-touch" example to compile and work with Bela's I2C library. From what I can tell this is the same "LiquidCrystal_I2C" V1 that's all over the net, but credit to the original author has been removed :-(

It's just two files so should be easy to drop in. Here they are. Sorry if it looks a mess, it wasn't that pretty to begin with and I've just hacked it to a functional level for Bela.
https://gist.github.com/anonymous/158f5e9fcf74f49fda89be9045948bbc

Check out the header for the API. I haven't tested all of it, but what I did worked fine. Example code in my render.cpp's setup()

LiquidCrystal_I2C lcd(0x3F, 16, 2); // My 16 x 2 panel sits at I2C address 0x3F, some are at 0x20 or 0x27, check when you buy
lcd.init();
lcd.noCursor();
lcd.print("Hello Bela!");
lcd.backlight();
lcd.setCursor(0, 1);
lcd.print("It works, yippee!");

And here's the result of that running on my pieced together prototype:

http://imgur.com/FivE1VH

Hope this helps someone.

Nice, I assume you are running those commands from an AuxiliaryTask, right?
If they were in the audio thread you would be getting dropouts and mode switches.

Thanks for sharing!

For now, I've only been testing from the setup function but yes, the plan is to have these commands issued from a low-priority thread.

2 years later
5 months later

Hi Rej, great stuff there, would you know how to scan for I2C addresses from BELA....?

*just found: i2cdetect -y -r 1

So I have the address, does that mean the hardware connections are fine? It still won't work though with code from Rej... 🙁

Sorry, no I didn't have to do any detecting. It sounds like you got that working though...

If you're working with a 1602 panel as well, did you try the other common addresses, just in case? ( 0x20 , 0x27 , 0x3F)

Also, make sure your contrast adjustment pot isn't all the way up or all the way down, it makes it impossible to see text. A good way to test if your board is talking to the panel is to turn off the backlight programmatically in setup().

13 days later

In my case the address is 0x27, but the backlight does not work: on or off, it makes no difference. Also, I had to turn the trimpot at the back of the I2C board in order to be able to see anything. I see there are two pins marked "LED" on the I2C board, but I don't see any voltages showing up there? Also, there are some pads labelled "Ax" Kx" (with x being a number between 1 and 4) on the LCD board, not sure if they are referring to cathode and anode and/or if there meant to be connected somehow?

Ah, I guess the makes are very different as well, I just can't get my MIDAS MCCOG21605C6W-BNMLWI to work.... i2cdetect reports 0x3E address and I've tried sending it all sorts but to no avail....the init procedure in the manual has 3 digit hex commands and the code I am appropriating operates with two digits.... there are no brightness pots or pads on this one.... hmmm....

Oh, also I have used the 3.3V supply from Bela, and no level shifters, so maybe that's why the backlight does not work for me?

@zlatk0 that panel seems fairly different from the one we have been using, so it's not entirely a surprise it requires a different communication protocol. Do you have a link to a known-working Arduino or similar library for it?

17 days later

Works directly without any issues for me. Thanks!

8 days later

So what is ar the LCDs that are tested and working with 3.3V from Bela?

Cheers....z

@Ward does yours work (including backlight) with 3.3V or did you have to use 5V?

great that looks very similar to mine except I don't have that jumper installed on the I2C board. Do you know that that is for? Maybe it will re-enable my backlight

For me it did not came with a jumper so I soldered my own using female headers. That turned on the lcd by default. After doing this you can still turn off the LCD if you want using the i2c class.

2 months later

Firstly, thanks to Rej for some very useful code which I have been using succesfully with a 40x4 LCD display.

Now for the bad news: out of the blue, for no reason which I can associate with any code changes, my code just refused to run - no error messages and the CPU load dropped from its normal 30-40% to less than 1%. I traced this to the LCD.init() command. Once commented out the rest of the code ran perfectly as before but without the display working of course. The LCD code runs as an Auxiliary task and changing the LCD made no difference.

Are there any general pointers which you could offer which might result in these kind of symptoms?

Many thanks.

Hmm I figure that there could be something going wrong with the I2c bus and the audio codec stops working.
- What image are you on (grep v0 /etc/motd)
- What I2C bus is the display connected to?
- Does the USR3 LED (or the LED on the BelaMini cape) keep blinking when the program is at "1%" CPU?

Well, you're not wrong! I'd assumed my careful hotmelt sealing of the i2C bus connexions on the level shifter board between Bela and the LCD was doing it's job. Well, all it was doing was hiding a tiny, barely perceptible copper whisker between the i2C clock and data lines. Problems solved!.

Sorry about wasting your time.

Regards and thanks