User avatar
frazelle09
Posts: 70
Joined: Mon May 07, 2012 5:04 am
Location: Mexicali, Baja California, Mexico

[SOLVED] How to connect a ITG3200/ITG3205 345 5883L and Pi B

Thu Mar 10, 2016 5:59 pm

How to connect a ITG3200/ITG3205 ADXL345 HMC5883L and Pi B

We are working towards controlling a parabolic solar hot water heater http://www.appropedia.org/Parabolic_Sol ... ter_Heater with a Raspi B, an IMU and some code from Jay Dosher https://github.com/polyideas/Raspberry-Pi-Solar-Tracker. We are not programmers but have been able to debug Jay's python program and port it to Python-3.x with the help of friends. Another friend soldered the header on to the IMU and we are now trying to figure out how to connect it to the Raspi B.

i was hoping Jay had a schematic somewhere and i thought i had seen one a while back, but can't find it anymore. i understand that it shouldn't be too hard since the connections are I2C. i think all we need is pitch and yaw and compass orientation if it has it - if that helps. Any help would be greatly appreciated!

Have a great morning! :)
Last edited by frazelle09 on Tue Mar 15, 2016 12:08 am, edited 1 time in total.
"The earth is one country and mankind its citizens."
Bahá'u'lláh
"La tierra es un sólo país y la humanidad sus ciudadanos."

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

Re: How to connect a ITG3200/ITG3205 ADXL345 HMC5883L and Pi

Thu Mar 10, 2016 6:48 pm

The module should have four pins labelled SDA, SCL, GND, and VCC.

Connections as follows

Code: Select all

Sensor     Pi
SDA  ---   pin 3 SDA
SCL  ---   pin 5 SCL
GND  ---   pin 6 Ground
VCC  ---   pin 1 3V3 
Add the following line to /boot/config.txt
dtparam=i2c_arm=on

Add the following line to /etc/modules (making sure there are no other i2c related lines)
i2c_dev

Install a useful I2C package
sudo apt-get install i2c-tools

Add yourself to the i2c group.
sudo adduser pi i2c

Reboot.

Your sensors should be detected when you do
i2cdetect -y 1

Edited to correct I2C entry in /boot/config.txt.
Last edited by joan on Thu Mar 10, 2016 10:49 pm, edited 1 time in total.

User avatar
frazelle09
Posts: 70
Joined: Mon May 07, 2012 5:04 am
Location: Mexicali, Baja California, Mexico

Re: How to connect a ITG3200/ITG3205 ADXL345 HMC5883L and Pi

Thu Mar 10, 2016 6:52 pm

Wow, Joan. Thanks a lot! Will try it out and see what happens.

Have a great day! :)
"The earth is one country and mankind its citizens."
Bahá'u'lláh
"La tierra es un sólo país y la humanidad sus ciudadanos."

User avatar
frazelle09
Posts: 70
Joined: Mon May 07, 2012 5:04 am
Location: Mexicali, Baja California, Mexico

Re: How to connect a ITG3200/ITG3205 ADXL345 HMC5883L and Pi

Thu Mar 10, 2016 9:03 pm

Am getting a No file error.

Code: Select all

Error: Could not open file `/dev/i2c-1' or `/dev/i2c/1': No such file or directory
Am running Jessey. i checked under /dev and there is no "i2c" anything. Am running as "pi".

Have a great afternoon! :)

P.S. i have a couple of quick questions - well i think they'll be quick. Could i have used Pi Pin 17 for the 3.3V and the Pi Pin 20 for ground?
"The earth is one country and mankind its citizens."
Bahá'u'lláh
"La tierra es un sólo país y la humanidad sus ciudadanos."

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

Re: How to connect a ITG3200/ITG3205 ADXL345 HMC5883L and Pi

Thu Mar 10, 2016 9:32 pm

Yes, you can use either of the two 3V3 pins and any of the ground pins.

As long as you added the entry to /boot/config.txt the /dev/i2c-1 entry should have appeared unless you have an ancient version of the firmware.

What does uname -a report?

User avatar
frazelle09
Posts: 70
Joined: Mon May 07, 2012 5:04 am
Location: Mexicali, Baja California, Mexico

Re: How to connect a ITG3200/ITG3205 ADXL345 HMC5883L and Pi

Thu Mar 10, 2016 10:06 pm

Thanks for the quick reply!

uname -a reports

Code: Select all

Linux Primerpi 4.1.13+ #826 PREEMPT Fri Nov 13 20:13:22 GMT 2015 armv6l GNU/Linux
Have a great afternoon! :)
"The earth is one country and mankind its citizens."
Bahá'u'lláh
"La tierra es un sólo país y la humanidad sus ciudadanos."

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

Re: How to connect a ITG3200/ITG3205 ADXL345 HMC5883L and Pi

Thu Mar 10, 2016 10:45 pm

What does lsmod | grep i2c report?

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

Re: How to connect a ITG3200/ITG3205 ADXL345 HMC5883L and Pi

Thu Mar 10, 2016 10:48 pm

In my earlier post I mistakenly said to add dtparam=i2c_vc=on to /boot/config.txt.

I should have said dtparam=i2c_arm=on.

User avatar
frazelle09
Posts: 70
Joined: Mon May 07, 2012 5:04 am
Location: Mexicali, Baja California, Mexico

Re: How to connect a ITG3200/ITG3205 ADXL345 HMC5883L and Pi

Thu Mar 10, 2016 11:04 pm

Joan, that's o.k. Here's the result of the grep

Code: Select all

[email protected] ~ $ lsmod | grep i2c
i2c_dev                 6730  0
i'll fix the other. Have a wonderful afternoon! :)

P.S. i corrected the grep output. We also corrected the line in config.txt and rebooted, but still get the same Error.
"The earth is one country and mankind its citizens."
Bahá'u'lláh
"La tierra es un sólo país y la humanidad sus ciudadanos."

User avatar
frazelle09
Posts: 70
Joined: Mon May 07, 2012 5:04 am
Location: Mexicali, Baja California, Mexico

Re: How to connect a ITG3200/ITG3205 ADXL345 HMC5883L and Pi

Sun Mar 13, 2016 2:54 am

Just ran across this after a net search for the error msg.>

http://www.runeaudio.com/forum/how-to-e ... t1287.html

The problem is that my distro doesn't have /etc/modules-load.d/raspberrypi.conf and don't know if i should create the "modules-load.d" subdirectory and the raspberrypi.conf file or not.

Have a great evening! :)
"The earth is one country and mankind its citizens."
Bahá'u'lláh
"La tierra es un sólo país y la humanidad sus ciudadanos."

User avatar
frazelle09
Posts: 70
Joined: Mon May 07, 2012 5:04 am
Location: Mexicali, Baja California, Mexico

Re: How to connect a ITG3200/ITG3205 ADXL345 HMC5883L and Pi

Mon Mar 14, 2016 7:08 pm

Well it appears i had an extra line in one of the files
device driver =
or something like that. Deleted it, rebooted and now have

Code: Select all

[email protected] /dev $ i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1e -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- 53 -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         
[email protected] /dev $ 
of course this was also only possible because i checked the contents of /dev and saw that although there is no i2c-1, there is a i2c-0, so i used 0 in the command and produced the above. Many thanks to Joan!

Where can i go to figure out what the above means?

Have a great afternoon! :)
"The earth is one country and mankind its citizens."
Bahá'u'lláh
"La tierra es un sólo país y la humanidad sus ciudadanos."

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

Re: [SOLVED] How to connect a ITG3200/ITG3205 345 5883L and

Tue Mar 15, 2016 9:14 am

Here is example code to read the sensors.

It uses my pigpio library (the Python module) but may be altered to use the standard Python smbus module.

The line BUS=1 should be changed to BUS=0 when using /dev/i2c-0.

ADXL345 (address 0x53)

Code: Select all

#!/usr/bin/env python

# i2c_ADXL345.py
# 2015-04-01
# Public Domain

import time
import struct
import sys

import pigpio # http://abyz.co.uk/rpi/pigpio/python.html

if sys.version > '3':
   buffer = memoryview

BUS=1

ADXL345_I2C_ADDR=0x53

RUNTIME=60.0

pi=pigpio.pi() # open local Pi

h = pi.i2c_open(BUS, ADXL345_I2C_ADDR)

if h >= 0: # Connected OK?

   # Initialise ADXL345.
   pi.i2c_write_byte_data(h, 0x2d, 0)  # POWER_CTL reset.
   pi.i2c_write_byte_data(h, 0x2d, 8)  # POWER_CTL measure.
   pi.i2c_write_byte_data(h, 0x31, 0)  # DATA_FORMAT reset.
   pi.i2c_write_byte_data(h, 0x31, 11) # DATA_FORMAT full res +/- 16g.

   read = 0

   start_time = time.time()

   while (time.time()-start_time) < RUNTIME:

      # 0x32 = X LSB, 0x33 = X MSB
      # 0x34 = Y LSB, 0x35 = Y MSB
      # 0x36 = Z LSB, 0x37 = Z MSB

      # < = little endian

      (s, b) = pi.i2c_read_i2c_block_data(h, 0x32, 6)

      if s >= 0:
         (x, y, z) = struct.unpack('<3h', buffer(b))
         print("{} {} {}".format(x, y, z))
         read += 1

   pi.i2c_close(h)

pi.stop()

print(read, read/RUNTIME)
HMC5883L (address 0x1E)

Code: Select all

#!/usr/bin/env python

# i2c_HMC5883L.py
# 2015-04-01
# Public Domain

import time
import struct
import sys

import pigpio # http://abyz.co.uk/rpi/pigpio/python.html

if sys.version > '3':
   buffer = memoryview

BUS=1

HMC5883L_I2C_ADDR=0x1E

RUNTIME=60.0

pi=pigpio.pi() # open local Pi

h = pi.i2c_open(BUS, HMC5883L_I2C_ADDR)

if h >= 0: # Connected OK?

   # Initialise HMC5883L.
   pi.i2c_write_byte_data(h, 0x00, 0xF8)  # CRA 75Hz.
   pi.i2c_write_byte_data(h, 0x02, 0x00)  # Mode continuous reads.

   read = 0

   start_time = time.time()

   while (time.time()-start_time) < RUNTIME:

      # 0x3 = X MSB, 0x4 = X LSB
      # 0x5 = Y MSB, 0x6 = Y LSB
      # 0x7 = Z MSB, 0x8 = Z LSB

      # > = big endian

      (s, b) = pi.i2c_read_i2c_block_data(h, 0x03, 6)

      if s >= 0:
         (x, y, z) = struct.unpack('>3h', buffer(b))
         print("{} {} {}".format(x, y, z))
         read += 1

   pi.i2c_close(h)

pi.stop()

print(read, read/RUNTIME)
ITG3205 (address 0x68)

Code: Select all

#!/usr/bin/env python

# i2c_ITG3205.py
# 2015-04-01
# Public Domain

import time
import struct
import sys

import pigpio # http://abyz.co.uk/rpi/pigpio/python.html

if sys.version > '3':
   buffer = memoryview

BUS=1

ITG_3205_I2C_ADDR=0x68

RUNTIME=60.0

# Registers.

ITG_3205_WHO_AM_I    = 0x00 # R/W
ITG_3205_SMPLRT_DIV  = 0x15 # R/W
ITG_3205_DLPF_FS     = 0x16 # R/W
ITG_3205_INT_CFG     = 0x17 # R/W
ITG_3205_INT_STATUS  = 0x1A # R
ITG_3205_TEMP_OUT_H  = 0x1B # R
ITG_3205_TEMP_OUT_L  = 0x1C # R
ITG_3205_GYRO_XOUT_H = 0x1D # R
ITG_3205_GYRO_XOUT_L = 0x1E # R
ITG_3205_GYRO_YOUT_H = 0x1F # R
ITG_3205_GYRO_YOUT_L = 0x20 # R
ITG_3205_GYRO_ZOUT_H = 0x21 # R
ITG_3205_GYRO_ZOUT_L = 0x22 # R
ITG_3205_PWR_MGM     = 0x3E # R/W

# DLPF_FS

ITG_3205_FS_SEL_2000_DEG_SEC = 0x18

ITG_3205_DLPF_CFG_256_8 = 0x00
ITG_3205_DLPF_CFG_188_1 = 0x01
ITG_3205_DLPF_CFG_98_1  = 0x02
ITG_3205_DLPF_CFG_42_1  = 0x03
ITG_3205_DLPF_CFG_20_1  = 0x04
ITG_3205_DLPF_CFG_10_1  = 0x05
ITG_3205_DLPF_CFG_5_1   = 0x06

# INT_CFG

ITG_3205_IC_ACTL             = 0x80
ITG_3205_IC_OPEN             = 0x40
ITG_3205_IC_LATCH_INT_EN     = 0x20
ITG_3205_IC_INT_ANYRD_2CLEAR = 0x10
ITG_3205_IC_ITG_RDY_EN       = 0x04
ITG_3205_IC_RAW_RDY_EN       = 0x01

# INT_STATUS

ITG_3205_IS_ITG_RDY      = 0x04
ITG_3205_IS_RAW_DATA_RDY = 0x01

# PWR_MGM

ITG_3205_PM_H_RESET = 0x80
ITG_3205_PM_SLEEP   = 0x40
ITG_3205_PM_STBY_XG = 0x20
ITG_3205_PM_STBY_YG = 0x10
ITG_3205_PM_STBY_ZG = 0x08

ITG_3205_PM_CLK_SEL_INTERNAL  = 0x00
ITG_3205_PM_CLK_SEL_X_GYRO    = 0x01
ITG_3205_PM_CLK_SEL_Y_GYRO    = 0x02
ITG_3205_PM_CLK_SEL_Z_GYRO    = 0x03
ITG_3205_PM_CLK_SEL_EXT_32768 = 0x04
ITG_3205_PM_CLK_SEL_EXT_192   = 0x05

pi=pigpio.pi() # open local Pi

h = pi.i2c_open(BUS, ITG_3205_I2C_ADDR)

if h >= 0: # Connected OK?

   # Initialise ITG_3205.

   pi.i2c_write_byte_data(h, ITG_3205_PWR_MGM, ITG_3205_PM_CLK_SEL_X_GYRO)
   #                         0x3E              0x01

   pi.i2c_write_byte_data(h, ITG_3205_SMPLRT_DIV, 0x07)
   #                         0x15                 0x07

   pi.i2c_write_byte_data(h, ITG_3205_DLPF_FS,
      ITG_3205_FS_SEL_2000_DEG_SEC | ITG_3205_DLPF_CFG_188_1)
   # 0x16  0x18| 0x01

   pi.i2c_write_byte_data(h, ITG_3205_INT_CFG, 0x00)
   # 0x17 0x00

   read = 0

   start_time = time.time()

   while (time.time()-start_time) < RUNTIME:

      # 0x1B = T MSB, 0x1C = T LSB
      # 0x1D = X MSB, 0x1E = X LSB
      # 0x1F = Y MSB, 0x20 = Y LSB
      # 0x20 = Z MSB, 0x22 = Z LSB

      # > = big endian

      (s, b) = pi.i2c_read_i2c_block_data(h, ITG_3205_TEMP_OUT_H, 8)

      if s >= 0:
         (t, x, y, z) = struct.unpack('>4h', buffer(b))
         t = 35 + ((t + 13200) / 280.0)
         print("{:.1f} {} {} {}".format(t, x, y, z))
         read += 1

   pi.i2c_close(h)

pi.stop()

print(read, read/RUNTIME)

User avatar
frazelle09
Posts: 70
Joined: Mon May 07, 2012 5:04 am
Location: Mexicali, Baja California, Mexico

Re: [SOLVED] How to connect a ITG3200/ITG3205 345 5883L and

Tue Mar 15, 2016 6:32 pm

!ow, Joan, you're the best!

Just d/l your program and followed the make instructions - uf - so easy!

Then, created the 3 files in /usr/bin and used Python-3.x to run them. Yea!!!

Thank you very much for such constant and patient hand-holding. It's so cool to see those measurements scroll down the term.

Now, to see if i can get this thing to work with Jay Dosher's program and well be GTG.

Have a wonderful evening - it must be evening across the pond and thanks again! :)
"The earth is one country and mankind its citizens."
Bahá'u'lláh
"La tierra es un sólo país y la humanidad sus ciudadanos."

User avatar
frazelle09
Posts: 70
Joined: Mon May 07, 2012 5:04 am
Location: Mexicali, Baja California, Mexico

Re: [SOLVED] How to connect a ITG3200/ITG3205 345 5883L and

Sun Apr 10, 2016 5:15 am

joan, someone who was trying to help posted the following as part of his reply...

"I am not familiar with that IMU or your code.
The code has errors and the maths isnt correct.

I did try and improve it, I also commented out the scale. The problem with this code is that it does not include tilt compensation.
You can see our full python code here;https://github.com/mwilliams03/BerryIMU ... erryIMU.py"

Code: Select all

#!/usr/bin/python
import smbus
import time
import math

bus = smbus.SMBus(0)
address = 0x1e

def read_byte(adr):
return bus.read_byte_data(address, adr)

def read_word_2c(adr):
high = bus.read_byte_data(address, adr)
low = bus.read_byte_data(address, adr+1)
mag_combined = (low | high <<8)
return mag_combined if mag_combined < 32768 else mag_combined - 65536

def write_byte(adr, value):
bus.write_byte_data(address, adr, value)

write_byte(0, 0b01110000) # Set to 8 samples @ 15Hz
write_byte(1, 0b00100000) # 1.3 gain LSb / Gauss 1090 (default)
write_byte(2, 0b00000000) # Continuous sampling

#scale = 0.92

x_out = read_word_2c(3)# * scale
y_out = read_word_2c(7)# * scale
z_out = read_word_2c(5)# * scale

#Calculate heading
heading = 180 * math.atan2(y_out,x_out)/M_PI
print ("HEADING %5.2f " % heading)
This is where the post comes from: http://ozzmaker.com/guide-to-interfacin ... pberry-pi/

What might your opinion be? Since i'm not a programmer, i'm at a loss as to which one to use.

Have a wonderful evening! :)
"The earth is one country and mankind its citizens."
Bahá'u'lláh
"La tierra es un sólo país y la humanidad sus ciudadanos."

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

Re: [SOLVED] How to connect a ITG3200/ITG3205 345 5883L and

Sun Apr 10, 2016 9:45 am

frazelle09 wrote: ...
This is where the post comes from: http://ozzmaker.com/guide-to-interfacin ... pberry-pi/

What might your opinion be? Since i'm not a programmer, i'm at a loss as to which one to use.

Have a wonderful evening! :)
Not really. The code you posted bears little relationship to the code I posted.

The blog author will understand that domain far better than I do. I'd certainly be guided by the author when he says there are errors and the maths is incorrect and tilt compensation needs to be added.

I'm afraid if the blog author couldn't correct the code I'd have zero chance of doing so.

User avatar
frazelle09
Posts: 70
Joined: Mon May 07, 2012 5:04 am
Location: Mexicali, Baja California, Mexico

Re: [SOLVED] How to connect a ITG3200/ITG3205 345 5883L and

Sun Apr 10, 2016 2:33 pm

Thanks, joan. i see that you are entirely correct. My bad. i guess it was pretty late and... i didn't compare the codes sufficiently to see that the one i have comes from somewhere else and is not yours. Arg.

Thank you again and have a great day! :)
"The earth is one country and mankind its citizens."
Bahá'u'lláh
"La tierra es un sólo país y la humanidad sus ciudadanos."

User avatar
frazelle09
Posts: 70
Joined: Mon May 07, 2012 5:04 am
Location: Mexicali, Baja California, Mexico

Re: [SOLVED] How to connect a ITG3200/ITG3205 345 5883L and

Wed Apr 13, 2016 6:11 pm

i've started trying to pare Jay's program down a little, eliminating the parts where he produces some sort of webpage.

i've also tried to massage your i2c_ADXL345.py program in order to provide just one reading, which is what i think his code is "looking for". Please excuse my rough attempts at coding. As i mentioned i know practically nothing about Python.

This is the part of Jay's program that i'm trying, at the moment, to replace with yours.
The lines curheading=999 were added by us (our friend from Denmark and i) in order to get Jay's program to finish and produce a result.

Code: Select all

#Get the heading from the IMU
#Translate the IMU from magnetic north to true north since the calcs use true north
def getcurheading():
	curheading = 999
	# The escape character for # is \x23 in hex
	serialport.write(b"\x23o0 \x23f")
	headresponse = serialport.readline()
	words = headresponse.split(b",")
	if len(words) > 2:
		try:
			curheading = (float(words[0])) + 180
			if curheading + Declination > 360: curheading = curheading - 360 + Declination
			else: curheading = curheading + Declination
		except:
			curheading = 999
	return curheading
Here is your "modified" program...

Code: Select all

#!/usr/bin/env python

# i2c_ADXL345.py  este es el accelerómetro de 3 ejes
# 2015-04-01
# Public Domain

import time
import struct
import sys

import pigpio # http://abyz.co.uk/rpi/pigpio/python.html

if sys.version > '3':
   buffer = memoryview

BUS=0

ADXL345_I2C_ADDR=0x53

#RUNTIME=60.0 This is the original line.
#RUNTIME=0.10 / This was the new line

pi=pigpio.pi() # open local Pi

h = pi.i2c_open(BUS, ADXL345_I2C_ADDR)

if h >= 0: # Connected OK?

   # Initialise ADXL345.
   pi.i2c_write_byte_data(h, 0x2d, 0)  # POWER_CTL reset.
   pi.i2c_write_byte_data(h, 0x2d, 8)  # POWER_CTL measure.
   pi.i2c_write_byte_data(h, 0x31, 0)  # DATA_FORMAT reset.
   pi.i2c_write_byte_data(h, 0x31, 11) # DATA_FORMAT full res +/- 16g.

   read = 0

#   start_time = time.time() ?part of the RUNTIME?

#   while (time.time()-start_time) < RUNTIME: ?part of the RUNTIME?

      # 0x32 = X LSB, 0x33 = X MSB
      # 0x34 = Y LSB, 0x35 = Y MSB
      # 0x36 = Z LSB, 0x37 = Z MSB

      # < = little endian

(s, b) = pi.i2c_read_i2c_block_data(h, 0x32, 6)

if s >= 0:
         (x, y, z) = struct.unpack('<3h', buffer(b))
         print("{} {} {}".format(x, y, z))
         read += 1

pi.i2c_close(h)

pi.stop()

print()
Your code now produces a beatiful...

Code: Select all

[email protected]:/usr/bin# python3 i2c_ADXL345.py
265 -17 -34
So, i guess we have two questions. How did i do on your program? and How do i get your program to just produce as output: 265 for the variable?

Have a great day! :)
"The earth is one country and mankind its citizens."
Bahá'u'lláh
"La tierra es un sólo país y la humanidad sus ciudadanos."

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