I2C LCD using C


54 posts   Page 1 of 3   1, 2, 3
by lopezcontreras » Thu Jan 24, 2013 5:06 pm
Hi All:
I have just bought a LCD Shield Kit w/ 16x2 Character Display for raspberry PI from Adafruit. I have followed the tutorial and It works without problem. The tutorial and the demo program is done on Python but I would like to do the same using C. Could anyone give some instruccions on how to do it? Is there any tutorial, libraries y/o modules already availables?
Thanks in advance,
Joaquin.
Posts: 3
Joined: Thu Jan 24, 2013 4:56 pm
by dkossman » Sat Jan 26, 2013 3:22 am
I have the same intent - i'm an C programmer and am trying to avoid Python :-). I also need to integrate the display with other C code that I'm writing, which talks to a device on the serial port as well as to an I2C analog-to-digital converter.

I found these, but both are for the Arduino:
https://github.com/lincomatic/LiquidTWI2
https://github.com/adafruit/Adafruit-RG ... ld-Library

I was hoping someone out there has created versions of these for the Pi, but haven't found anything yet...

Don
Posts: 25
Joined: Tue Dec 25, 2012 12:35 am
Location: Los Angeles, California
by gordon@drogon.net » Sat Jan 26, 2013 11:08 am
I have included some I2C helper functions in the latest wiringPi release. There is also some sample code to drive the MCP23017 which is how this board works. (if it's the one I think it is - LCD + buttons?
http://www.adafruit.com/products/1115 )

So you'll need to get the latest wiringPi, but before that, you need the I2C development libraries installed. Unfortunately if you're not running Raspbian this may prove to be challenging, but if you are then:

Code: Select all
cd
sudo apt-get install libi2c-dev
git clone git://git.drogon.net/wiringPi
cd wiringPi
./build


make sure you see the message that indicates the I2C libraries are being built.

then you can easilly load the I2C modules with:

Code: Select all
gpio load i2c


then the usual:

Code: Select all
i2cdetect -y 0


should print the table with the device at 0x20. (use i2cdtect -y 1 on a Rev. 2 Pi)

Code: Select all
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: 20 21 -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --                         


(I have 2 mcp23017's on that display, one at 0x20 and one at 0x21)

After that, then have a look at: http://unicorn.drogon.net/q2w.c

This is code to use the MCP23017 on the Quick2Wire board, but all MCP23017's are the same on I2C, so it's not really that important. It has the setup details and you should be able to work out how to set bits in the 2 8-bit GPIO registers. All you need to do is work out which bits on which port are connected to what, and the Adafruit documentation will help there (although I've just looked and not found that, but the Python programs should have it all)

Once setup, you just use the wiringPiI2CWriteReg8() functions to write an 8-bit value into one of the mcp23017's registers, and the similar wiringPiI2CReadReg8() to read a value back. There is some documentation here: https://projects.drogon.net/raspberry-p ... c-library/

(And you can probably use this as an easy way to read the ADC from C too without setting up the /dev/ entries)


I am looking at better integrating devices like the mcp2307 into wiringPi, but for now that should be enough to get you going. If you want to see the commands to send to those displays, then have a look at the lcd.c library in the wiringPi directory - that's intended for a directly connected display, but the commands are all the same, you just need to send them via the I2C and mcp22017 interface.

-Gordon
--
Gordons projects: https://projects.drogon.net/
User avatar
Posts: 1544
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
by dkossman » Sat Jan 26, 2013 6:23 pm
Hi Gordon,

thanks very much for the detailed reply. I've been using WiringPi to talk to an Atlas Scientific ORP board on the Pi's serial port, so have the code installed and working. I'll dig into this and see how it goes...

FYI, I also just posted a query here (http://blog.lincomatic.com/?p=956 ) regarding a port of an Arduino/C I2C library , and got a response:

regards
Don
Posts: 25
Joined: Tue Dec 25, 2012 12:35 am
Location: Los Angeles, California
by lopezcontreras » Sun Feb 03, 2013 6:13 pm
Thanks Gordon and all of you.
As soon as I have some time I will try what you have posted.
Thanks again and I will post any advance I get.
regards,
Joaquin.
Posts: 3
Joined: Thu Jan 24, 2013 4:56 pm
by spbecker » Sun Feb 03, 2013 9:46 pm
This is just the sort of thing I was looking for! The Adafruit Python scripts are OK to make sure things work, but the language gives me the creeps. I'm going to give it a shot at creating a C library for talking to the LCD shield.
Posts: 4
Joined: Sun Feb 03, 2013 9:43 pm
by dkossman » Sun Feb 03, 2013 10:52 pm
spbecker wrote:This is just the sort of thing I was looking for! The Adafruit Python scripts are OK to make sure things work, but the language gives me the creeps. I'm going to give it a shot at creating a C library for talking to the LCD shield.


Please keep us posted on your progress!
Posts: 25
Joined: Tue Dec 25, 2012 12:35 am
Location: Los Angeles, California
by harvey7 » Mon Feb 04, 2013 2:14 am
I wrote a C header file with function-like macros for controlling the LCD from Adafruit for my Catchphrase device. The code I wrote within main() of my program imports a script of mine to interface with the Adafruit scripts. This is simpler to use and doesn't really have too many drawbacks. You can see how this is achieved if you visit my thread here(viewtopic.php?f=33&t=32161). Also, a zip is attached with the C code and all scripts. Hope this helps!
User avatar
Posts: 2
Joined: Sun Feb 03, 2013 2:24 am
by dkossman » Wed Feb 06, 2013 8:16 am
Which Adafruit python scripts are you using? can you provide details?
Looks like you put them here on your Pi: "/home/rasppi/src/py_scripts".

thx
Posts: 25
Joined: Tue Dec 25, 2012 12:35 am
Location: Los Angeles, California
by mmoller2k » Thu Feb 07, 2013 10:11 am
Thanks Gordon
I gave it a try and got it working in no time. While bit-banging the bits through an I2C interface is far from optimum, it sure was easy to implement. Here's my little mod of your lcd.c demo.
Code: Select all
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <errno.h>

#include <wiringPi.h>
#include <lcd.h>

int xio;

void lcd_pinMode(int pin, int mode);
void lcd_digitalWrite(int pin, int value);

int main (void)
{
  int fd2 ;

  printf ("Raspberry Pi LCD test program\n") ;

  xio = wiringPiI2CSetup (0x20);
  if (xio < 0){
    fprintf (stderr, "xio: Unable to initialise I2C: %s\n", strerror (errno));
    return 1;
  }
  wiringPiI2CWriteReg8 (xio, 0x0a, 0x84) ;  // IOCON - set BANK bit
  wiringPiI2CWriteReg8 (xio, 0x05, 0x84) ;  // IOCON - set ODR in bank 0
  wiringPiI2CWriteReg8 (xio, 0x00, 0x00) ;  // Port A -> Outputs

  digitalWrite = lcd_digitalWrite;
  pinMode = lcd_pinMode;

  fd2 = lcdInit(2, 16, 4, 1,2, 3,4,5,6, 0,0,0,0);

  if(fd2 < 0){
    printf ("lcdInit 2 failed\n") ;
    return 1 ;
  }

  sleep (1) ;

  lcdPosition (fd2, 0, 0) ; lcdPuts (fd2, "Gordon Henderson") ;
  lcdPosition (fd2, 0, 1) ; lcdPuts (fd2, "----------------") ;

  return 0;
}

void lcd_pinMode(int pin, int mode){}

void lcd_digitalWrite(int pin, int value)
{
  static oldval = 0;

  oldval &= ~(1 << pin);
  oldval |= value << pin;
  wiringPiI2CWriteReg8 (xio, 0x0a, oldval) ;
}

Posts: 31
Joined: Fri Dec 28, 2012 2:52 pm
by dkossman » Fri Feb 08, 2013 6:53 am
Thanks for posting this - I updated Raspbian and updated to the latest WiringPi, but when i run your program with my Adafruit 2x16 I2C LCD backpack, it turns on the backlight, and lights up all the bits in all 16 characters in the first row, and thats it. Any idea what might be wrong?

Don
Posts: 25
Joined: Tue Dec 25, 2012 12:35 am
Location: Los Angeles, California
by dkossman » Fri Feb 08, 2013 7:22 pm
One more bit of info - the display works fine using the Adafruit Python code...
Posts: 25
Joined: Tue Dec 25, 2012 12:35 am
Location: Los Angeles, California
by spbecker » Sun Feb 10, 2013 7:34 pm
Hmm, well I thought it'd be pretty easy to hack together some code that would make this work based on stuff that's already out there, but I'm having problems. In addition to the Adafruit python code, I found there is also an Adafruit C++ library for talking to the Arduino version of this shield (looks like the only difference is lack of a Pi gpio header)..

In general, I understand how the code is more or less working. However, it seems I don't understand either language well enough to know why certain bits of the code are doing what they're doing, which kind of makes it difficult to translate to wiringPi function calls.

/me goes back to the drawing board (meaning, it's finally about time to learn another language other than FORTRAN, R, and Matlab)
Posts: 4
Joined: Sun Feb 03, 2013 9:43 pm
by dkossman » Mon Feb 11, 2013 2:15 am
I have pretty much the same problem. I am reasonably fluent in C (though I hadn't coded for many years prior to getting a PI) but don't know Python, and C++ makes my brain hurt. If you make any progress, let me know, I'll do the same by posting here... I think (as Gordon has already mentioned) its going to boil down to figuring out the sequence of register writes required to control the display over I2C. In the meantime we can hope that someone else out there posts a nice library we can use :-).

regards
Don
Posts: 25
Joined: Tue Dec 25, 2012 12:35 am
Location: Los Angeles, California
by Arjan » Mon Feb 11, 2013 12:11 pm
Hi,

I've ordered the I2C_LCD from BitWizard http://www.bitwizard.nl/catalog/product_info.php?products_id=85

As soon as it arrives I am going to extend Mike's library (http://www.open.com.au/mikem/bcm2835/) with I2C functions.

Regards, Arjan
Posts: 131
Joined: Sat Sep 08, 2012 1:59 pm
by dkossman » Mon Feb 11, 2013 4:49 pm
I just took a look at the product page and documentation you linked, and it wasn't immediately clear whether the Bitwizard board is functionally identical to the Adafruit one - any idea if this is so? Is the Bitwizard device also based on the MPC23017 expander?

thx
Don
Posts: 25
Joined: Tue Dec 25, 2012 12:35 am
Location: Los Angeles, California
by Arjan » Mon Feb 11, 2013 4:56 pm
Don,

The slaves use an ATTINY44 processor.

Herewith the link to the protocol : http://www.bitwizard.nl/wiki/index.php/I2c_lcd_protocol

Regards, Arjan
Posts: 131
Joined: Sat Sep 08, 2012 1:59 pm
by Arjan » Tue Feb 12, 2013 6:21 pm
Herewith a patch for Mike's library version 1.17. The new functions are:
Code: Select all
void bcm2835_i2c_begin(void);
void bcm2835_i2c_end(void);
void bcm2835_i2c_setSlaveAddress(uint8_t addr);
void bcm2835_i2c_setClockDivider(uint16_t divider);
uint32_t bcm2835_i2c_write(char* buf, uint32_t len);


Please bear in mind that this is just a first release. I need to do some more testing and documenting the code.
Also attached an Eclipse CDT project for displaying the time on the I2C_LCD.

Regards, Arjan
Attachments
bcm2835-i2c.zip
(6.97 KiB) Downloaded 266 times
Posts: 131
Joined: Sat Sep 08, 2012 1:59 pm
by Arjan » Wed Feb 13, 2013 9:55 am
Please note that the previous attached patch has a limitation of writing 16 bytes (FIFO size). When you write more bytes, then a timeout error will occur.
Posts: 131
Joined: Sat Sep 08, 2012 1:59 pm
by spbecker » Thu Feb 14, 2013 1:08 am
dkossman:

I just ran across this:
https://github.com/symptog/rpi_lcd

Perfect!
Posts: 4
Joined: Sun Feb 03, 2013 9:43 pm
by dkossman » Thu Feb 14, 2013 6:23 am
Thanks! but unhappily, it doesn't seem to want to build - lots of errors. Haven't had time to dig in to figure out why. There's no discussion, few comments and no release notes. Maybe it is for a different flavor of Linux than Raspbian? I guess I'll need to create a github account and post some questions...

Don
Posts: 25
Joined: Tue Dec 25, 2012 12:35 am
Location: Los Angeles, California
by spbecker » Sat Feb 16, 2013 12:31 am
dkossman:

Yeah, upon further review, I think that code isn't so hot. It will build on Raspbian, but you have to do this first:

sudo apt-get remove i2c-dev-tools

And then this:
make lcdplate

Looking through all the code, I think he's done some really silly things (like daisy-chain including all the .c files), and he's also duplicated stuff from existing header files as well as lower level functions that wiringPi handles just fine. I think it's a good start though, as everything is already in C!
Posts: 4
Joined: Sun Feb 03, 2013 9:43 pm
by dkossman » Sat Feb 16, 2013 1:40 am
Thanks for looking into it - not sure that I want to remove i2c-dev-tools - that will break my ability to build my existing code (which includes support for an I2C-based ADS1115 a/d converter). I've posted an issue on his github project, I'll let you know if I hear anything back...

Don
Posts: 25
Joined: Tue Dec 25, 2012 12:35 am
Location: Los Angeles, California
by Defiant » Sat Feb 16, 2013 7:39 am
Want a ready solution? There is lcdproc
Posts: 150
Joined: Tue Oct 30, 2012 6:17 pm
Location: Hamburg, Germany
by dkossman » Sat Feb 16, 2013 7:40 pm
Thanks for the pointer. Have you actually tried this with the Adafruit 16x2 I2C backpack? I couldn't find any mention of it in the hardware section of the lcdproc site.
Posts: 25
Joined: Tue Dec 25, 2012 12:35 am
Location: Los Angeles, California