In this video I continue my series on the beaglebone to discuss the I2C bus and how we can connect and program devices attached to the bus using C/C++. I explain the use of i2c-tools on embedded Linux and then show how we can interface to a digital accelerometer (Bosch BMA180) or any other I2C device. Finally, I show how we can use sysfs to build a C++ class that wraps the functionality of the digital accelerometer. Source code included! This video builds on the three previous videos: The introduction to the Beaglebone; Setting up a C/C++ Development Environment; and, Programming with GPIOs. So, I recommend that you view those videos first.
The NXP I2C Specification document is at:
http://www.nxp.com/documents/user_manual/UM10204.pdf
The source code in this video is available through githhub:
1 | git clone git://github.com/derekmolloy/beaglebone |
Please note that I have mixed up the words bit and byte a few times in this video — apologies, I do know the difference(!) but I seem to have a problem when describing some points in this video.
Can we get QT source code?
@Dimitriy
Check out the third video in http://derekmolloy.ie/beaglebone/qt-with-embedded-linux-on-the-beaglebone/. You might get an idea how to use it with Qt.
Hi,
Is the QT run on a PC ?
If yes, how to you connect the data from Beaglebone to that PC /QT ?
Thanks
In this video – yes indeed. I used C++ sockets to send data from the Beaglebone to the PC. I’m using standard C++ sockets on the Beaglebone (client) and QT server sockets on the PC under Windows (server).
Hi,
Could you please let me know where the C++ socket code on beaglebone is …?
I suppose it should have include … But, none of the files on git has anything on socket.
Or do I miss something ?
Thank you so much
Same question, could you give a demo of how to setup the sockets?
Thank you!
Hello Derek,
Thank you very much for your effort in producing these amazing tutorials. Could you please make a video tutorial for using SPI devices?
Best regards,
Mantas
Hello Derek, I’m new with the beaglebone black and I wanted to ask you on how do you unlock the third i2c bus through angstrom? I already have two i2c buses ready from the first time i got it (I2C0 and I2C1) but Im trying to use the I2C2 thats on the pins 17 and 18 of the P9 header.
Thanks
@Zain
I2C-1 (see Derek’s P9 header table) is the only one that isn’t allocated (which confusingly is I2C-2 on the linux kernel). In order to use this you’ll have to change the device tree with an overlay as it’s not enabled by default.
I would suggest the easiest way would be following Derek’s GPIO programming video, for steps on using an overlay for the device tree but instead of using his overlay there is an overlay that comes with the BeagleBoneBlack firmware that is called “BB-I2C1-00A0.dtbo” located in the /sys/firmware/. Echo this overlay to the $SLOTS instead of Derek’s *.dtbo file and this will enable the I2C-1 on pins 17 and 18 of the P9 header. The process for using the I2C-1 is the same as using I2C-2 which is explained in the above video.
Note: Remember what is called I2C-1 by the pinmux (and Derek’s P9 header table) is refered to as i2c-2 in the linux kernel i.e. “i2cdetect -y -r 2″ instead of 1 in Derek’s video
Hope that helps,
Chris
Hello Derek. First of all, thank you for these awesome videos. I am using the beaglebone black with the latest version of Angstom installed, and I am trying to figure out how to get the i2c bus working. Are you going to make a video on the i2c bus for the beaglebone black? I am also interested in the question that Zain posted.
Thank you for your time.
I would like to see a tutorial on setting up network sockets on Beaglebone black and Linux, then setting up or creating a program to read the data from accelerometer sensors.
Derek,
I am trying to get i2c up and running with a melexis IR sensor. I had it connected to an Rpi, but for variuos reasons, the pi would not support this device. i2cdetect on the pi gave be slave address locations at 0x50-0x57 and 0x60 and 0x61. The bbb does not do this and I need to get into address 0x60 for my application.
Any thoughts on how to get the driver to see that address? I have tried echo …0x60 /sys/class etc. and several other incantations but no luck.
Hi Derek,
I am running Ubuntu. I need to use the I2C ports for my project. How would I change the I2C bus frequency?
It’s a setting in the overlay, you could use BB-I2C1-00A0.dtbo overlay as a template which is an overlay that comes with the firmware (you’ll find the *.dts file: “https://github.com/jadonk/cape-firmware”) and you’ll see theres a section for setting the clock frequency.
Chris
Hi Derek,
Are you using pullup resistors on the SDA and SCL lines? I can’t see them in your diagram or in the video, yet you mentioned them when discussusing I2C.
Steve
Hi Steve, they are on the Sparkfun breakout boards. Derek.
Hi Derek,
I believe you are mistaken on this one – the schematics for the BMA board from sparkfun (available at https://www.sparkfun.com/datasheets/Sensors/Accelerometer/BMA180_Breakout_v11.pdf) don’t show pull-up resistors.
The pull-up resistors are needed, however, but this is not an issue, as the configuration for pins 19 / 20 are configured to 0x73 by the I2C device tree overlay, which corresponds to 0b01110011, i.e. the BeagleBoneBlack’s internal pull-up is active. I’ve verified that I2C communications will work w/o external pull-ups in this configuration using an MCP23008 GPIO extender, as I was unsure whether the internal pull-ups work if the pins are not in GPIO mode.
Thanks Tobias, it looks like you are right. I was using a gyroscope too and may have mixed up the boards. I don’t really remember – it feels like a long time ago now! Thanks, Derek.
Hi Derek,
I have 2 question to ask.
1.) can beaglebone communicate at 1.8V i2c line?
2.) can beaglebone work as slave in i2c communication
I’m also seeking for an answer, if the BBB can work as an I2C slave. Did you find anything useful?
Hi Derek,
How the enable the third i2c channel on BeagleBone Black?
see my reply to @Ripudaman
sir
iam praveen,MTech student in NIELIT,calicut,kerala,india.iant to study about spi driver source code in bbb.
how i will get those information.
thankyou .
dear derek sir,
thanks a lot…it will be again very thankful if u provide us spi access a practical siomilar example . kindly provide.
Hi Derek,
I am facing the problem that i cant find the directory sys/devices/platform/omap in angstrom latest image for BB Black. please help what is this problem?
/sys/bus/i2c/devices/
I am planning to build a kernel driver for the same device. I will add it to your git(when I am done) if u r ok with it. Thanks for the video.
Derek,
Thank you for the tutorial, which greatly helped me to develop few lines of demo code for Beaglebone Black + ADXL345 accelerometer combination. I have posted the code on github for to benefit greater open source community. Below is the link.
https://github.com/mahengunawardena/BeagleboneBlack_I2C_ADXL345
Thank you again
Hi Derek,
I develop on the Debian Wheezy that ships with the Rev C BBBs these days and just wanted to note that the i2c device files reside in /sys/bus/i2c/devices on that distribution, rather than in /sys/devices/platform/omap as indicated in your video.. Maybe this will save someone a bit of time.
Thank you very much for the nice introduction videos. I’ve done quite a bit work on Atmel microcontrollers, and now work for the first time on a full-fledged ARM SBC, and you’ve saved me countless hours already.
Hii
How to use other I2C pins of BeagleBone Black.
KIndly Please guide
ripudaman
@Ripudaman
I2C-1 (see Derek’s P9 header table) is the only one that isn’t allocated (which confusingly is I2C-2 on the linux kernel). In order to use this you’ll have to change the device tree with an overlay as it’s not enabled by default.
I would suggest the easiest way would be following Derek’s GPIO programming video, for steps on using an overlay for the device tree but instead of using his overlay there is an overlay that comes with the BeagleBoneBlack firmware that is called “BB-I2C1-00A0.dtbo” located in the /sys/firmware/. Echo this overlay to the $SLOTS instead of Derek’s *.dtbo file and this will enable the I2C-1 on pins 17 and 18 of the P9 header. The process for using the I2C-1 is the same as using I2C-2 which is explained in the above video.
Note: Remember what is called I2C-1 by the pinmux (and Derek’s P9 header table) is refered to as i2c-2 in the linux kernel i.e. “i2cdetect -y -r 2” instead of 1 in Derek’s video
Hope that helps,
Chris
Hi Mr.Derek. I am Jahir hussain pursuing my under graduate in Electronics and Communication Engineering. Am doing a project where beaglebone black is used as an end device connected to cloud. C2000 Piccolo Processor from texas instruments is used to do Some signal processing. I need to interface C2000 with BBB else tell me how to do signal processing in BBB especially Bio signals……..
Hey Derek,
First of all thank you for your wiki! this was exactly what I was looking for to quickly get into customising the BBB (especially your HOW TO for setting up eclipse, that was frustrating me).
I was running through your code to get some ideas on how access other functions. You refer to a “I2C_SLAVE” macro when using ‘iotcl()’ function. I was reading that this is a Linux fetch all for the special files that are used for accessing drivers etc. and that this is device dependent. I can’t seem to find anything on the definition of these macros for the BBB. I was wondering if you could point me in the right direction on where I could find this kind of information for this device, obviously there are different macros for different devices, but I can’t seem to find them.
Thank you, (sorry for the long question)
Regards,
Chris Ley
Hello Christopher,
When using ioctl(), I think of it as calling a function. When you call a function you need to know the name of the function and the parameters you want to pass to the function. In our case, we pass these to ioctl. The ioctl signature typically looks like: ioctl(fd, FUNCTION_NAME, FUNCTION_ARGUMENTS).
In our case, “I2C_SLAVE” is passed as our FUNCTION_NAME and the slave address is passed as the FUNCTION_ARGUMENT. Let’s say we have opened a file to ‘/dev/i2c-1’ and this file is stored in a variable called ‘fd_i2c’. Now, we want to communicate to a specific I2C slave at address 0x42 (just as an example). We would first need to tell the file descriptor that our slave address will be 0x42. We do this using with a call to ioctl:
ioctl(fd_i2c, I2C_SLAVE, 0x42);
What this call does is acts as a “setter”. It will “set” the slave address to 0x42 on the file descriptor we have opened. Now, when we call read/write on this file descriptor, we will be reading and writing to the I2C slave device at address 0x42.
how to receive data through i2c in beaglebone black and how to check what data I have receive on beaglebone black?
thanks
Sir,
i am not able to unlock i2c file descriptor in bbb.
please provide me some solution .
thanks
I see you use the value directly from the register…
Does this mean that the read() function returns integers?
from your ReadI2CDeviceByte prototype i figured it saves the readings in
character strings….
But now i see you also use the value directly as the sensor value…. making me
think it reads in integers?
so wich is it?
Hi jp, I haven’t checked the code, but do you mean my use of char? When working with hexadecimal, char and byte are interchangeable. I added new code for my book which is publicly available for interfacing to I2C/SPI devices. Please see: https://github.com/derekmolloy/exploringBB/tree/master/library The documentation is at: http://exploringbeaglebone.com/API/ The I2C and SPI code is in the bus directory. Hope that helps, Derek.
Hi Derek,
Thank you for the tutorial. I’m trying to write HDMI kernel driver in user space. Just a prototype to understand user space device drivers in linux. My first protoptype was mapping a gpio pin (gpio1_28) from the expansion header and acknowledge every time on interrupt. This is working fine.
But when i configure my interrupt with i2c in dts file, call to blocking read() in my app fails with I/O error. Do you know how the interrupts are configured in beaglebone black for HDMI device? (HPD, EDID, RX anything)
Thanks
KK
Hey Derek,
Im at the step where you type cd /sys/devices/platform and then type ls. The next is when you type cd omap , and there’s my problem.I dont seem to have the file omap.Do you know why thats happenning and how can i get it?. I am also missing i2c-3.
Hoping for your answer, thanks in advance.
Good Morning Derek, it’s possible to write in bash the same library you wrote in c++? i want to write a library for this http://www.seeedstudio.com/depot/Grove-Relay-p-769.html
Derek,
I have been using and modifying your Chapter 8 example to make my own class for an i2c ADC. Problem I am having has to do with using readRegisters on a virtual i2c bus controlled by a PCA9544 i2c Multiplexer. I can only correctly read the starting register and the remainder returns as FF, as if it is busy or having an issue. It does work with other i2c devices on non-virtual buses. Also I know the virtual bus is working properly because the i2ctools have no issue in using them. I can dump all the registers from my device using i2cdump, just not the ::read method you’ve used in your code. I’m wondering if you have any ideas on the matter else I may just work from the i2cdump source to recreate what I need.
Thanks,
Bruce Glazier
Hi Derek,
Thank you for the tutorial. I would like to know if it’s possible to use two BBB links with i2c with one in master mode and the other one in slave mode without used a bit-banged.
Hoping for an answer. Thanks.
Jeremy
Hi Derek
Do you have any hints on using the am3358 in a multi-master system. Struggling to get anything meaningful out of it running as a slave.
Neal
Dear all,
please could you descrive how to disable default I2C interfaces? I need to use their pins as a GPIO instead… Thanks a lot!
AFAIK, you need to disable them by editing your device-tree and recompiling it.
This is what you’re going to need:
1 – select the function of the pins that are shared with i2c(SDL, SCL) via pinmux
2 – disable or remove or comment out the required i2c node from your device-tree.
3 – recompile your device-tree
4 – boot with this newly compiled device-tree
5 – export the new GPIO pins and use them.
A good introduction on device-tree can be found here: https://learn.adafruit.com/introduction-to-the-beaglebone-black-device-tree/device-tree-background and here: https://events.linuxfoundation.org/sites/events/files/slides/petazzoni-device-tree-dummies.pdf
Hi Derek. i have watched your video which is really useful but i do I’m struggling to get the device address (MPU-9250). i got to the following stage:
root@beaglebone:~# sudo i2cdetect -r 0
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-0 using read byte commands.
I will probe address range 0x03-0x77.
Continue? [Y/n] y
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: — — — — — — — — — — — — —
10: — — — — — — — — — — — — — — — —
20: — — — — UU — — — — — — — — — — —
30: — — — — UU — — — — — — — — — — —
40: — — — — — — — — — — — — — — — —
50: UU — — — — — — — — — — — — — — —
60: — — — — — — — — — — — — — — — —
70: UU — — — — — — —
root@beaglebone:~# sudo i2cdetect -r 1
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-1 using read byte commands.
I will probe address range 0x03-0x77.
Continue? [Y/n] y
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: — — — — — — — — — — — — —
10: — — — — — — — — — — — — — — — —
20: — — — — — — — — — — — — — — — —
30: — — — — — — — — — — — — — — — —
40: — — — — — — — — — — — — — — — —
50: — — — — UU UU UU UU — — — — — — — —
60: — — — — — — — — — — — — — — — —
70: — — — — — — — —
But even after connecting my device It is still the same. Any advise?
Thanks
Do you know what address you are expecting? The MPU9250 can have a couple set by AD0 (0x68 or ox69). I would check the I2C wiring as perhaps it is not being interrogated correctly by the BB.
Hi Derek,
I am using Beaglebone enhanced embedded mpu6050 to measure acceleration and angular velocity.
To change the sensitivity in ACCEL_CONFIG AND GYRO_CONFIG, I have written python code.
However through the code or by following the steps using i2cdetect, I cannot access Register 0x1b and 0x1c.
I am getting error “Could not set address to 0x68: Device or resource busy
Following are the steps in short
1. i2cdetect -l
Displays 3 I2C adapter
i2c-0 i2c OMAP I2C adapter I2C adapter
i2c-2 i2c OMAP I2C adapter I2C adapter
i2c-3 i2c i2c-0-mux (chan_id 0) I2C adapter
2. sudo i2cdetect -r 0
WARNING! This program can confuse your I2C bus, cause data loss and worse!
I will probe file /dev/i2c-0 using read byte commands.
I will probe address range 0x03-0x77.
Continue? [Y/n] Y
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: — — — — — — — — — — — — —
10: — — — — — — — — — — — — — — — —
20: — — — — UU — — — — — — — — — — —
30: — — — — UU — — — — — — — — — — —
40: — — — — — — — — — — — — — — — —
50: UU — — — — — — — — — — — UU — — —
60: — — — — — — — — UU — — — — — — —
70: UU — — — — — — —
3. root@beaglebone:/sys/devices/platform# ls
alarmtimer leds pm33xx.0 regulatory.0 uevent
bone_capemgr ocp pmu serial8250
cpufreq-voltdm.0 omap-pcm-audio power snd-soc-dummy
fixedregulator@0 oprofile-perf.0 reg-dummy soc
4. root@beaglebone:/sys/devices/platform/ocp/44e0b000.i2c/i2c-0# ls -al
total 0
drwxr-xr-x 11 root root 0 May 17 23:08 .
drwxr-xr-x 4 root root 0 May 17 23:15 ..
drwxr-xr-x 7 root root 0 May 17 23:08 0-0024
drwxr-xr-x 3 root root 0 May 17 23:08 0-0034
drwxr-xr-x 4 root root 0 May 17 23:08 0-0050
drwxr-xr-x 5 root root 0 May 17 23:08 0-005c
drwxr-xr-x 5 root root 0 May 17 23:08 0-0068
drwxr-xr-x 3 root root 0 May 17 23:08 0-0070
–w——- 1 root root 4096 May 17 23:08 delete_device
lrwxrwxrwx 1 root root 0 May 17 23:08 device -> ../../44e0b000.i2c
drwxr-xr-x 4 root root 0 May 17 23:08 i2c-3
drwxr-xr-x 3 root root 0 May 17 23:08 i2c-dev
-r–r–r– 1 root root 4096 May 17 23:08 name
–w——- 1 root root 4096 May 17 23:08 new_device
lrwxrwxrwx 1 root root 0 May 17 23:08 of_node -> ../../../../../firmware/dev
icetree/base/ocp/i2c@44e0b000
drwxr-xr-x 2 root root 0 May 17 23:08 power
5. root@beaglebone:/sys/devices/platform/ocp/44e0b000.i2c/i2c-0# sudo sh
6. # cd 0-0068
7. # cat name
mpu6050
8.root@beaglebone:~# sudo i2cdump 0 0x68
No size specified (using byte-data access)
Error: Could not set address to 0x68: Device or resource busy
How to query the register in case of embedded mpu6050 Beaglebone enhanced? For now, I just want to know what the sensitivity is set to.
Sir,
I am connecting LSM6DS3 IMU to Beaglebone Black need a c code. Could you please help for same.
thanks
hi Derek,
I am working on BBAI I am able to interface with DS1307 and able to read time and date, but want to set time and date values but not able to do. can you please help me out.