User avatar
FTrevorGowen
Forum Moderator
Forum Moderator
Posts: 5051
Joined: Mon Mar 04, 2013 6:12 pm
Location: Bristol, U.K.
Contact: Website

pigpio's i2cWriteBlockData cf. i2cset -y 1 ... i

Sun Apr 26, 2015 8:33 pm

I have a couple of I2C "display" devices that require a "block of data" to be sent to a dummy register (which is actually a "command code") :
http://www.cpmspectrepi.webspace.virgin ... ackpack_V2
http://www.cpmspectrepi.webspace.virgin ... SSD1306.29

Whilst this can be easily (but somewhat slowly for the second device) achieved via (a 'C' system call to) i2cset such as in this example (diagnostic output from my program):

Code: Select all

i2cset -y 1 0x3a 0x01 0x43 0x4c 0x31 0x20 0x4c 0x43 0x4d 0x31 0x36 0x30 0x32 0x20 0x23 0x31 i
where 0x01 is the dummy register of the display backpack equivalent to the "print string" command,

if I attempt to use pigpio's "i2cWriteBlockData" function thus (similar diagnostics):

Code: Select all

i2cWriteBlockData: handle=0 i2cReg=0x01 count=14...
... buf=0x43 0x4c 0x31 0x20 0x4c 0x43 0x4d 0x31 0x36 0x30 0x32 0x20 0x23 0x31
an extra byte appears to be inserted after the register/command code, resulting in an extra "graphics block-like" character before the wanted display string ("CL1 LCM1602 #1" in the above example).
Is this to be expected? Would I be better off using pigpio's "i2cWriteDevice" function instead? (How?). Or can anyone suggest another 'C' I2C library/method that provides equivalent behaviour to i2cset (wiringPi doesn't)?

Note: It's not that much of an issue for the backpack as there is a workaround via it's "write a single character" command - the major problem lies with the OLED display as the SSD1306 controller has commands (dummy registers) requiring up to 7 bytes of parameter data, all preceded by a command/data mode selection byte (ie. it's really a SPI device operating in an I2C "fashion").
Trev.
Still running Raspbian Jessie on some older Pi's (an A, B1, B2, B+, P2B, 3xP0, P0W) but Stretch on my 2xP3A+, P3B+, P3B, B+, A+ and a B2. See: https://www.cpmspectrepi.uk/raspberry_pi/raspiidx.htm

User avatar
joan
Posts: 14193
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: pigpio's i2cWriteBlockData cf. i2cset -y 1 ... i

Sun Apr 26, 2015 8:47 pm

These are all SMBus commands and are implemented by the Linux drivers.

The first thing I'd try is using i2cWriteI2CBlockData rather than i2cWriteBlockData. They take the same parameters but do slightly different things.

i2cWriteBlockData
S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P

i2cWriteI2CBlockData
S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P

User avatar
FTrevorGowen
Forum Moderator
Forum Moderator
Posts: 5051
Joined: Mon Mar 04, 2013 6:12 pm
Location: Bristol, U.K.
Contact: Website

Re: pigpio's i2cWriteBlockData cf. i2cset -y 1 ... i

Sun Apr 26, 2015 9:10 pm

joan wrote:These are all SMBus commands and are implemented by the Linux drivers.
The first thing I'd try is using i2cWriteI2CBlockData rather than i2cWriteBlockData. They take the same parameters but do slightly different things.
i2cWriteBlockData
S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P
i2cWriteI2CBlockData
S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P
Thanks @joan, I'll give that a go tomorrow - I did suspect that the count was being inserted but, when I reduced the number of characters sent to the second line of the display the same "block character" was displayed! (Probably from the, not yet user defined, programmable graphics set).
Trev.
Still running Raspbian Jessie on some older Pi's (an A, B1, B2, B+, P2B, 3xP0, P0W) but Stretch on my 2xP3A+, P3B+, P3B, B+, A+ and a B2. See: https://www.cpmspectrepi.uk/raspberry_pi/raspiidx.htm

User avatar
FTrevorGowen
Forum Moderator
Forum Moderator
Posts: 5051
Joined: Mon Mar 04, 2013 6:12 pm
Location: Bristol, U.K.
Contact: Website

Re: pigpio's i2cWriteBlockData cf. i2cset -y 1 ... i

Mon Apr 27, 2015 12:49 pm

FTrevorGowen wrote:
joan wrote:These are all SMBus commands and are implemented by the Linux drivers.
The first thing I'd try is using i2cWriteI2CBlockData rather than i2cWriteBlockData. They take the same parameters but do slightly different things.
i2cWriteBlockData
S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P
i2cWriteI2CBlockData
S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P
Thanks @joan, I'll give that a go tomorrow - I did suspect that the count was being inserted but, when I reduced the number of characters sent to the second line of the display the same "block character" was displayed! (Probably from the, not yet user defined, programmable graphics set).
Trev.
I've change the calls in my pigpio_wraps.c and all's working as required now. (Some tidying up to do and then onto the OLED testing :) )
Thanks again,
Trev.
Still running Raspbian Jessie on some older Pi's (an A, B1, B2, B+, P2B, 3xP0, P0W) but Stretch on my 2xP3A+, P3B+, P3B, B+, A+ and a B2. See: https://www.cpmspectrepi.uk/raspberry_pi/raspiidx.htm

User avatar
joan
Posts: 14193
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: pigpio's i2cWriteBlockData cf. i2cset -y 1 ... i

Mon Apr 27, 2015 2:15 pm

Just for the record you could have used i2cWriteDevice instead. The buffer would have needed to have 15 bytes instead of 14 with the first byte being the register (0x01).

In effect that would be

S Addr Wr [A] Data [A] Data [A] ... [A] Data [A] P

with the first Data byte being Comm.

User avatar
FTrevorGowen
Forum Moderator
Forum Moderator
Posts: 5051
Joined: Mon Mar 04, 2013 6:12 pm
Location: Bristol, U.K.
Contact: Website

Re: pigpio's i2cWriteBlockData cf. i2cset -y 1 ... i

Mon Apr 27, 2015 3:32 pm

joan wrote:Just for the record you could have used i2cWriteDevice instead. The buffer would have needed to have 15 bytes instead of 14 with the first byte being the register (0x01).
In effect that would be
S Addr Wr [A] Data [A] Data [A] ... [A] Data [A] P
with the first Data byte being Comm.
Had you not pointed me to i2cWriteI2CBlockData that's what I was thinking of trying. Given that the backpack and OLED controller don't really have a "register byte" following the address, in some ways it may be better (or less confusing) to use i2cWriteDevice (or a wrapped version thereof) directly rather than a function that emulates (and is similarly named as) i2cset -y 1 ... i.

Slightly off-topic, but still a pigpio related issue: I use GNU autotools methods to build my codes and, unfortunately, whilst I can test for pigpio.h with an appropriate configure.ac entry such as:

Code: Select all

# Check for pigpio.h ...
have_pigpio_h=no
AC_CHECK_HEADERS([pigpio.h], [have_pigpio_h=yes])

if test "x${have_pigpio_h}" = xno; then
   AC_MSG_WARN([
   **************************************
   Unable to find pigpio header ...
   Some program features may be disabled!
   **************************************])
fi

if test "x${have_pigpio_h}" = xyes; then

#AC_CHECK_LIB([pigpio], [i2cWriteByteData])
#AC_SEARCH_LIBS([i2cWriteByteData], [pigpio])
# Libraries needed to use pigpio etc. ...
   AC_SEARCH_LIBS([pthread_create], [pthread])
   AC_SEARCH_LIBS([clock_gettime], [rt])

   AC_MSG_NOTICE([
   ************************************
   pigpio header available ...
   (HAVE_PIGPIO_H defined in config.h)
   Full functionality available!
   ************************************])
fi
neither of the AC_CHECK_LIB or AC_SEARCH_LIBS mechanisms (commented out above) detect the presence of the pigpio library successfully and thus the -lpigpio linker directive is not automatically appended to the LIBS variable of my makefile etc. My current workaround is to add a direct reference in the src directories makefile.am:

Code: Select all

lcd_hi2c_demo_SOURCES = ../common/rcs_scm.h lcd_hi2c_demo.c
lcd_hi2c_demo_CPPFLAGS = -I$(top_srcdir)/common
lcd_hi2c_demo_LDADD = ../common/libparsel.a ../common/libi2c_chips.a \
../common/libi2c_wraps.a ../common/liblcd_disptools.a \
../common/libpigpio_wraps.a /usr/local/lib/libpigpio.a
which means that everything builds but that means that the code will no longer build (without the pigpio-based functionallity) if I move to another Pi on which pigpio has not installed without a re-edit of the makefile.am file. I'm not sure why the detection mechanism fails, unless it's something to do with pigpio's library type or permissions:

Code: Select all

[email protected] ~/i2c_spi_chips-0.0/src $ ls -laF /usr/local/lib/
total 364
drwxr-sr-x  5 root staff   4096 Apr 23 21:10 ./
drwxrwsr-x 10 root staff   4096 Jan  1  1970 ../
-rw-r--r--  1 root staff 211386 Apr 23 21:10 libpigpio.a
-rw-r--r--  1 root staff  62512 Apr 23 21:10 libpigpiod_if.a
lrwxrwxrwx  1 root staff     21 Jul 18  2014 libwiringPiDev.so -> libwiringPiDev.so.2.0*
-rwxr-xr-x  1 root staff  23229 Jul 18  2014 libwiringPiDev.so.2.0*
lrwxrwxrwx  1 root staff     18 Jul 18  2014 libwiringPi.so -> libwiringPi.so.2.0*
-rwxr-xr-x  1 root staff  47965 Jul 18  2014 libwiringPi.so.2.0*
drwxrwsr-x  4 root staff   4096 Jan  1  1970 python2.7/
drwxrwsr-x  3 root staff   4096 Jan  1  1970 python3.2/
drwxr-sr-x  3 root staff   4096 Jan  1  1970 site_ruby/
Trev.
Still running Raspbian Jessie on some older Pi's (an A, B1, B2, B+, P2B, 3xP0, P0W) but Stretch on my 2xP3A+, P3B+, P3B, B+, A+ and a B2. See: https://www.cpmspectrepi.uk/raspberry_pi/raspiidx.htm

User avatar
joan
Posts: 14193
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: pigpio's i2cWriteBlockData cf. i2cset -y 1 ... i

Mon Apr 27, 2015 3:42 pm

FTrevorGowen wrote: ...
...
which means that everything builds but that means that the code will no longer build (without the pigpio-based functionallity) if I move to another Pi on which pigpio has not installed without a re-edit of the makefile.am file. I'm not sure why the detection mechanism fails, unless it's something to do with pigpio's library type or permissions:

Code: Select all

[email protected] ~/i2c_spi_chips-0.0/src $ ls -laF /usr/local/lib/
total 364
drwxr-sr-x  5 root staff   4096 Apr 23 21:10 ./
drwxrwsr-x 10 root staff   4096 Jan  1  1970 ../
-rw-r--r--  1 root staff 211386 Apr 23 21:10 libpigpio.a
-rw-r--r--  1 root staff  62512 Apr 23 21:10 libpigpiod_if.a
lrwxrwxrwx  1 root staff     21 Jul 18  2014 libwiringPiDev.so -> libwiringPiDev.so.2.0*
-rwxr-xr-x  1 root staff  23229 Jul 18  2014 libwiringPiDev.so.2.0*
lrwxrwxrwx  1 root staff     18 Jul 18  2014 libwiringPi.so -> libwiringPi.so.2.0*
-rwxr-xr-x  1 root staff  47965 Jul 18  2014 libwiringPi.so.2.0*
drwxrwsr-x  4 root staff   4096 Jan  1  1970 python2.7/
drwxrwsr-x  3 root staff   4096 Jan  1  1970 python3.2/
drwxr-sr-x  3 root staff   4096 Jan  1  1970 site_ruby/
Trev.
I'm afraid I know nothing of this area. If you discover it is a permissions problems I'll see if I can change them during install.

User avatar
FTrevorGowen
Forum Moderator
Forum Moderator
Posts: 5051
Joined: Mon Mar 04, 2013 6:12 pm
Location: Bristol, U.K.
Contact: Website

Re: pigpio's i2cWriteBlockData cf. i2cset -y 1 ... i

Mon Apr 27, 2015 5:01 pm

joan wrote:
FTrevorGowen wrote: ...
...
which means that everything builds but that means that the code will no longer build (without the pigpio-based functionallity) if I move to another Pi on which pigpio has not installed without a re-edit of the makefile.am file. I'm not sure why the detection mechanism fails, unless it's something to do with pigpio's library type or permissions:

Code: Select all

[email protected] ~/i2c_spi_chips-0.0/src $ ls -laF /usr/local/lib/
total 364
drwxr-sr-x  5 root staff   4096 Apr 23 21:10 ./
drwxrwsr-x 10 root staff   4096 Jan  1  1970 ../
-rw-r--r--  1 root staff 211386 Apr 23 21:10 libpigpio.a
-rw-r--r--  1 root staff  62512 Apr 23 21:10 libpigpiod_if.a
lrwxrwxrwx  1 root staff     21 Jul 18  2014 libwiringPiDev.so -> libwiringPiDev.so.2.0*
-rwxr-xr-x  1 root staff  23229 Jul 18  2014 libwiringPiDev.so.2.0*
lrwxrwxrwx  1 root staff     18 Jul 18  2014 libwiringPi.so -> libwiringPi.so.2.0*
-rwxr-xr-x  1 root staff  47965 Jul 18  2014 libwiringPi.so.2.0*
drwxrwsr-x  4 root staff   4096 Jan  1  1970 python2.7/
drwxrwsr-x  3 root staff   4096 Jan  1  1970 python3.2/
drwxr-sr-x  3 root staff   4096 Jan  1  1970 site_ruby/
Trev.
I'm afraid I know nothing of this area. If you discover it is a permissions problems I'll see if I can change them during install.
It turned out that the issue was pigpio's dependency on the pthread and rt libraries - this info. needed to be added into the search macro for the (macro's) link test to work - ie. I should have used:

Code: Select all

AC_SEARCH_LIBS([gpioInitialise], [pigpio], , , [-lpthread -lrt])
Problem solved after visiting the main autoconf documentation website (instead of just referring to my copy of John Calcote's Autotools guide of 2010).
Trev.
Still running Raspbian Jessie on some older Pi's (an A, B1, B2, B+, P2B, 3xP0, P0W) but Stretch on my 2xP3A+, P3B+, P3B, B+, A+ and a B2. See: https://www.cpmspectrepi.uk/raspberry_pi/raspiidx.htm

User avatar
FTrevorGowen
Forum Moderator
Forum Moderator
Posts: 5051
Joined: Mon Mar 04, 2013 6:12 pm
Location: Bristol, U.K.
Contact: Website

Re: pigpio's i2cWriteBlockData cf. i2cset -y 1 ... i

Tue Apr 28, 2015 7:31 pm

(Back on-topic) ...
Just a quick update - I've now got everything working with the OLED device that I originally was doing with 'C' system calls to i2cset -y 1 ... i using (wrapped) i2cWriteI2CBlockData :D
Trev.
Still running Raspbian Jessie on some older Pi's (an A, B1, B2, B+, P2B, 3xP0, P0W) but Stretch on my 2xP3A+, P3B+, P3B, B+, A+ and a B2. See: https://www.cpmspectrepi.uk/raspberry_pi/raspiidx.htm

User avatar
joan
Posts: 14193
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: pigpio's i2cWriteBlockData cf. i2cset -y 1 ... i

Tue Apr 28, 2015 7:51 pm

I've looked at your site. You do like your displays!

If you're interested in optimising performance you can send far more data with i2cWriteDevice than the SMBus calls. You can probably update the OLED screen in one call from C rather than needing dozens of SMBus calls.

User avatar
FTrevorGowen
Forum Moderator
Forum Moderator
Posts: 5051
Joined: Mon Mar 04, 2013 6:12 pm
Location: Bristol, U.K.
Contact: Website

Re: pigpio's i2cWriteBlockData cf. i2cset -y 1 ... i

Tue Apr 28, 2015 10:26 pm

joan wrote:I've looked at your site. You do like your displays!
If you're interested in optimising performance you can send far more data with i2cWriteDevice than the SMBus calls. You can probably update the OLED screen in one call from C rather than needing dozens of SMBus calls.
Most of them were cheap enough to (crudely) assess "sample variation" in timing requirements, esp. the HD44780-based devices when using the 4-bit interface method.
The SMBus calls are fast enough for writing 8x8 bit character data (one call per character). The display is organised as 8 pages of 64 column (bit) data and, depending upon the addressing mode, could be written with one block of (8x64)+2 graphics data bytes or, on a one call per page basis (64+2 graphics data bytes) using i2cWriteDevice as you suggest**. The on-board controller is quite sophisticated, and has some quite complex options which, in some cases, are more appropriate for similar displays using its SPI interface mode AFICT.
Trev.
** the +2 being for the address and select data mode bytes.
Still running Raspbian Jessie on some older Pi's (an A, B1, B2, B+, P2B, 3xP0, P0W) but Stretch on my 2xP3A+, P3B+, P3B, B+, A+ and a B2. See: https://www.cpmspectrepi.uk/raspberry_pi/raspiidx.htm

Return to “Interfacing (DSI, CSI, I2C, etc.)”