Last Updated: February 25, 2016
·
7.715K
· shantanubhadoria

Getting started with Device::SMBus on Raspberry Pi

A while back I wrote a perl library Device::SMBus to talk to the plethora of I2C devices available for a Raspberry Pi board. I2C is a serial hardware bus invented by Philips that allows you to connect multiple devices to the same hardware pins and talk to them using their unique device addresses.
http://en.wikipedia.org/wiki/I2C

Device::SMBus builds on top of a standard linux i2c library libi2c-dev to talk to these class of devices. Each device on the bus is addressed using its standard device address, and the systems interacts with these devices by setting/reading appropriate control registers and translating that information.

It was recently made aware to me that it is not straightforward using perl's Device::SMBus library with raspberry PI. It has a chain of dependencies that needs to be properly documented from start to end to make it easy to people who try to use it:

I use model B Pi with Adafruit 16 Channel PWM Servo Controller PCA9685 among other devices. You must have four servos or ESC -> Brushless motors connected to channel 4,5,6,7 for testing your I2C code using the PCA9685.

I have also interfaced to other I2C devices like L3GD20 Gyroscope, LSM303DLHC accelerometer and magnetometer, LPS331AP Altimeter. which may also be used to test this module if so desired. I have writter the perl modules for these devices as well. All three of these chipsets are available on Pololu's AltIMU board, however these chipsets may also be available on other boards by themselves.

I will skip over the hardware setup guide as that is not the purpose of this manual and there are enough instructions on wiring up i2c interfaces with raspberry Pi. We will strictly talk about software side of things here.

First install i2c dependencies and Moose using aptitude and build essential

sudo apt-get install libi2c-dev i2c-tools build-essential libmoose-perl

Install Device::SMBus

sudo cpan Device::SMBus

Open /etc/modprobe.d/raspi-blacklist.conf

sudo vim /etc/modprobe.d/raspi-blacklist.conf

Comment out the following line

blacklist i2c-bcm2708

To get

# blacklist i2c-bcm2708 

Open /etc/modules

sudo vim /etc/modules

Add these lines

i2c-dev
i2c-bcm2708

Restart the Pi

Prerequisite in this case to test Device::SMBus is Device::PCA9685 which in turn uses Device::SMBus as its base class. So we install it using CPAN

sudo cpan Device::PCA9685

Create a file esc_calibration.pl

use strict; 
use warnings; 
use FindBin qw($Bin); 
use lib "$Bin/../lib"; 

use Device::PWMGenerator::PCA9685; 

my $dev = Device::PWMGenerator::PCA9685->new( 
I2CBusDevicePath => '/dev/i2c-1', 
debug => 1, 
frequency => 400, 
); 
$dev->enable(); 

# Calibrate max duty cycle as 3600 and min(point at which esv cut off at 700 

my $dutycycle = 3600; 
$dev->setChannelPWM( 4, 0, $dutycycle ); 
$dev->setChannelPWM( 5, 0, $dutycycle ); 
$dev->setChannelPWM( 6, 0, $dutycycle ); 
$dev->setChannelPWM( 7, 0, $dutycycle ); 
sleep(2); 
my $dutycycle = 700; 
$dev->setChannelPWM( 4, 0, $dutycycle ); 
$dev->setChannelPWM( 5, 0, $dutycycle ); 
$dev->setChannelPWM( 6, 0, $dutycycle ); 
$dev->setChannelPWM( 7, 0, $dutycycle );

My original article at http://www.shantanubhadoria.com/article/getting-started-with-device-smbus-on-raspberry-pi-70/