PDA

View Full Version : PIC16F88 I2C Accelerometer Help



dkibel
- 5th May 2015, 15:14
Im using a pic16f88 in conjuction with a MMA7455 accelerometer to make an auto leveling jack system. I have run into the problem of not being able to get the I2C functions from the inclinometer to register within the pic. Any help would be much appreciated. Below is the current code i have. I am not sure how to navigate the read/write functions correctly in order to get the value from the Y axis only. I know that the register is $07 but im not sure where to go from here.

Thanks!

#CONFIG
__cONFIG _CONFIG1, _INTRC_IO & _PWRTE_ON & _MCLR_OFF & _LVP_OFF
#endconfig
'
'Set the internal oscillator frequency (8 MHz)
Include "modedefs.bas"
DEFINE OSC 8
OSCCON.4 = 1
OSCCON.5 = 1
OSCCON.6 = 1


'Setup A/D Converter
ANSEL = 0 'turn off all A/D converters


TRISA= %00000010
TRISB= %00110000




up1 var PORTA.0 'motor1 up
up2 var PORTA.7 'motor2 up
button_level var PORTA.1
DPIN1 var PORTB.4 'data pin
DPIN2 var PORTB.5
CPIN1 var PORTA.2 'clock
CPIN2 var PORTA.3
y1 var byte[8]
y2 var byte[8]
led var PORTB.6


start:
clear
low button_level
low led
low up1
low up2


pause 100

if (button_level==1) then
goto level
else
goto start
endif

goto start


end


level:
clear
For y1 = 0 To 7
i2cwrite DPIN1, CPIN1, $07, y1, [y1]
pause 1
next y1

For y2 = 0 To 7
i2cwrite DPIN2, CPIN2, $07, y2, [y2]
pause 1
next y2


For y1 = 0 To 7
i2cread DPIN1, CPIN1, $07, y1, [y1]
PAUSE 1
next y1

For y2 = 0 To 7
I2CREAD DPIN2, CPIN2, $07, y2, [y2]
PAUSE 1
next y2

if (y1>y2) then
gosub blink
goto jack2up
endif

if (y1<y2) then
gosub blink
pause 500
gosub blink
goto jack1up
endif
goto start


jack2up:
high up2

For y2 = 0 To 7
I2CREAD DPIN2, CPIN2, $07, y2, [y2]
PAUSE 1
next y2
if (y1=<y2) then
low up2
else
goto jack2up
endif
goto start


jack1up:
high up1
For y1 = 0 To 7
i2cread DPIN1, CPIN1, $07, y1, [y1]
PAUSE 10
next y1

if (y1>=y2) then
low up1
else
goto jack1up
endif
goto start


blink:
high led
pause 500
low led
return

mark_s
- 5th May 2015, 16:17
Here is an example for Basic Stamp. They are using the MMA7455 in the SPI
mode and not I2C, apparently it can do both


https://www.parallax.com/downloads/mma7455-3-axis-accelerometer-basic-stamp-demo-code

Not that you want to change devices, but as a side note. The ADXL335 accelerometer module
found on Ebay cheap, outputs 3 analog voltages which makes it really easy to connect to a pic.

Tabsoft
- 5th May 2015, 22:23
Are you using PICBasic or PICBasic Pro?
It makes a difference.

Tabsoft
- 5th May 2015, 22:50
Perhaps this will help.

Looking at the MMA7455 datasheet the I2C Device address is "$1D"
Also to communicate using I2C with the MMA7455 you need to make sure that MMA7455's CS pin is pulled high.

You should not have to issue a write then a read.
I2CRead does this for you.

With PBP Pro, to issue a PBP I2CRead command here is the syntax:
I2CREAD DataPin, ClockPin, Control,{Address,}[Var{,Var...}]{,Label}
"Control" is the MMA7455 I2C Slave Address "$1D"
"Address" is the MMA7455 Register address you want to read, in this case "$07" for "YOUT8".
"Var" will be a single Byte variable because you are only reading a single byte from the MMA7455.

So something like this.

yout var byte 'Holds the value read from the MMA7455 YOUT8 register
addr var byte 'Holds register address

addr = $07 'Assign $07 to access the MMA7455's YOUT8 register

I2CREAD DPIN1, CPIN1, $1D, addr, [yout]

Tabsoft
- 6th May 2015, 02:52
After reading a couple other forums, the MMA7455L slave address of $1D is a 7bit address so you need to left shift $1D 1 bit. This makes the address $3A. ($1D << 1 = $3A).
In an 8bit I2C address the upper 7bits is the device address <7:1> and the LSB <0> is the R/W bit.


So in binary:
$1D = %0001 1101 (7bit address)
$3A = %0011 1010 (7bit address + R/W bit)

The I2CREAD statement should look like this.
addr var byte
yout var byte

addr $07

I2CREAD DPIN1, CPIN1, $3A, addr, [yout]

Hopefully this will work for you. :smile:

dkibel
- 7th May 2015, 04:46
After looking over your last post im confident that should work. At this point I'm kicking my group members but for not buying us analog inclinometers which would have saved me about 12-15 hours working on this one function. I will load up my current program with your suggestion on it tomorrow. If it works i will load a video onto youtube and link the video. Until then, if i am wanting to read the values and and use them to compare angles (like in the original program) is it necessary to both read and write or should i just write or vice versa. This type of programming evades me. I'm essentially reading both "Yout" values for 2 inclinometers on 1 PIC and using it co compare angles until i can get them to be even.

Tabsoft
- 7th May 2015, 13:49
As I stated in my earlier post, to READ data using the I2CREAD command, PBP will handle the low-level
I2C protocol actions to the target I2C device. (PBP acts as the I2C Master)
This information can be gleaned from the PBP manual as well, but maybe not as concise? ;-)

For example, if you want to read the data from register ($07) and the I2C device's 7bit slave address is ($1D).




''Read a single byte from device ($1D) (7bit addr) from register ($07).

myData var byte ' byte variable to hold the received data from Target device
myAddr var byte ' byte variable to hold Target device's 8bit slave address
myReg var byte ' byte variable to hold the Target device's Register address

DPIN1 var PORTB.4 'data pin
CPIN1 var PORTA.2 'clock

myAddr = $3A ' 7bit slave address left-shifted 1 bit to make an 8bit address and make bit0 (R/W) "0". ($1D << 1 = $3A)
myReg = $07 ' Address of Target device's Register to Read

I2CREAD DPIN1, CPIN1, myAddr, myReg, [myData]



Now this is what happens:
1. PBP transmits a start condition (ST) to the Target device, slave address ($1D), with the R/W bit set to "0" for a write.
2. PBP waits for an acknowledgement from the Target device.
3. PBP transmits the 8bit address of the register to read. ($07)
4. PBP waits for an acknowledgement from the Target device.
5. PBP transmits a repeated start (SR) condition to the Target device, slave address ($1D), with the R/W bit set to "1" for a read of the register in step 3.
6. PBP waits for an acknowledgement from the Target device.
7. PBP clocks in the byte of data sent from the Target device for the register asked for ($07) and stores it in the myData variable.
8. PBP issues a Stop Condition to the Target device once the 8 bits of data are clocked in and stored in the myData variable.

Writing data to an I2C device is similar in that PBP handles the low-level I2C protocol actions for you.

BTW
You should read the MMA7455L datasheet.
As with any device, you will need to make sure you configure the MMA7455L correctly for your application use.
Device default settings in general may not fit a person's application.
Also, it provides information on how to communicate with it and how connect the MCU to it.
All of the information is in there. :-).