I2C Accelerometer

alband

Senior Member
Hello again.

This is the carry-on of the "readadc accuracy" thread although I doubt it will be as humorous as most of the carry-ons.

The problem at hand is trying to get a PICAXE to communicate with an accelerometer via I2C. The accelerometer does work, or at least I'm 99% sure it works, as it is the 2nd one I've bought and gives the same results. Also, this type of accel can be read using analogue outputs (hence the previous thread's name) and those work fine.

This is the datasheet for the accelerometer.

As for the code; The most successful code "on the market" at the moment is this:
Code:
		#PICAXE28X2
pause 1000
high B.5
high B.4
pause 1000
setfreq m1

		i2cslave %00110010,255,i2cbyte

		let b1 = 0
		SERTXD("RESET")

main:		pause 50
		readi2c 3,(b0)
		sertxd (#b0,",")
		goto main
This however (as you'd imagine) doesn't work. The data transaction to read from the accelerometer should go like this:
Code:
Master:                        S0011001W 00000011 S0011001R         NAP
Slave:                                  A        A         AXXXXXXXX
however this is what seems to be happening:
Code:
Master:                        S0011001W
Slave:
See the first attachment for a scope trace of the two lines.

I've tried using an EEPROM chip instead, and managed to get that working with similar code.

Because the accel is not acknowledging, the slave address must be wrong. Therefore, I decided to try ever possible slave address before I came back. This took a while to write out because, for some reason I cant use a variable as the slave address and simply increment it. Therefore I had to write out 128 addresses (the last bit is zero so 128 not 256). With the above code, I received "255" repeatedly. When I tried with each slave address, I didn't get any response except "RESET" over an over.
This is very strange because at the end of the code, I put the "end" command at the end of the code, so it should repeat the "RESET". I've attached the code for this. During this code, there doesn't seem to be any activity on the I2C lines (using th scope) so I assume there must be something wrong with the code.

I'll try to get a Diptrace of the circuit together, but I still have to install diptrace on my recently wiped computer.

The description of it though is this:
PICAXE28X2 connected up in normal way (breadboard)
Accelerometer soldered onto it's own board with the correct SCL and SDA line connected to the PICAXE with 4k7 pull-ups.
ADDR on the accel is held high.
Enable on the accel is connected to B.5 on the PICAXE.
MOT enable on the accel is connected to B.4 on the PICAXE
FF/MOT interrupt on the accel is connected to an LED (the LED flashes if I tap the accel; more proof the accel works).

Thanks in advance as usual and sorry about pre-post. :rolleyes:

David.
 

Attachments

Last edited:

Dippy

Moderator
Can you redo your scope trace with your interpretation of the 1s and 0s.
i.e. stick it in a graphics editor and mark where you think the 1s and 0s are.
 

husslemk4

New Member
Hello,
I have just been reading through the data sheet, looks like a nice module. Have you tried to tie the nCS pin high to enable i2c mode. Also I may be wrong on this point but in the line

Code:
i2cslave %00110010,255,i2cbyte
Why have you used 255 instead of i2cfast, I just have not seen that before.

On page 14 of the data sheet it says that upon power up the master must write to the control registers, so you may need to do a little it of setting up before reading any of the X, Y or Z registers. I think you need to write %11000010 to CTRL_REGB so that the unit has time to process ADC data, and I think you can leave CTRL_REGC as its default i.e. %0000000. Then hopefully you should be able to enter "main" on your program and read register 3.
 

alband

Senior Member
Yes, nCS is high.

I didn't know I could use 255 as a mode either, until our local techical assistant told me ;) (see post 63).

It is another speed, which is a lot slower, allowing my scope to see whats going on.

That bit about the registers sounds good, although, in that code, it would still go through this process first (addressing the slave) and would need to acknowledge. However, I'll give it a go! :p
 

alband

Senior Member
Yep, just tried this:

Code:
		#PICAXE28X2
pause 1000
high B.5
high B.4
pause 1000
setfreq m1

		i2cslave %00110010,255,i2cbyte

		let b1 = 0
		SERTXD("RESET")

main:		pause 50
		writei2c %00001101,(%11000010)
		sertxd (#b0,",")
		goto main
and it give exactly the same result on the scope.

I clearly won't be able to use it without writing that section first though, so thanks :)
It must just be that slave address. It will be pointless trying to guess what the address is randomly, so I need to get that code working that has all the addresses. I don't know what's wrong with it though. :confused: I will at least change all of it's read's to write's.
 

husslemk4

New Member
ahh ok, my mistake.

Perhaps that could be an issue though, on table 2 p4 it says that the i2c rate is 400 KHz?? Just reading through it again, I can't see anything suggesting it has any other speeds, however you can change the timing for SPI mode. But I may be wrong again
 

alband

Senior Member
ahh ok, my mistake.

Perhaps that could be an issue though, on table 2 p4 it says that the i2c rate is 400 KHz?? Just reading through it again, I can't see anything suggesting it has any other speeds, however you can change the timing for SPI mode. But I may be wrong again
Your asking all the same questions that I did and others did in my previous thread which is comforting.

Hippy in post 70 in the other thread:
Yes, with 400kHz max, anything up to that will do. It should be possible to run I2C down to almost zero-Hz speeds.
That particular question is one I asked. I does say in that table though that it is 400Khz as typical and doesn't give a min or max. I can try at 400Khz but the only way I can tell if I've got it write is by doing the initial write, then trying to read the outputs. This means there is lots that could go wrong anyway and I would be none-the-wiser.
This is getting seriously close to having to get a better scope :eek::rolleyes:
 

husslemk4

New Member
I have just been reading your original post on readadc, so apologies for bringing up suggestions you may have already heard. I know how frustrating it is to try and get something working. I spend the last few days trying to interface an I2C module, funny enough also an accelerometer.
 

hippy

Ex-Staff (retired)
I'm at a loss as to what's going wrong. That the chip doesn't respond to I2C Device Address suggests it's wired correctly but the address is wrong or there is something wrong with the wiring.

I would measure the voltages on all the pins to check they are as expected and toggle a line at a time from the PICAXE and check the corresponding pin does toggle.

In your circuit, LED D2 from FF/MOT is straight to 0V; that will likely need a current limiting resistor fitted.

It would also be worthwhile updating your circuit to show all connections then giving the circuit to someone else to verify that what you have matches. It's very easy to convince oneself repeatedly that what there is is correct even though it isn't. Can you post a photograph of your PCB or whatever ?
 
Last edited:

hippy

Ex-Staff (retired)
You can also run the following program and see if you get any "OK" messages ...

#Picaxe 28X2
#Terminal 1200
Pause 1000
High B.5
High B.4
Pause 1000
SetFreq M1
For b0 = %00010000 To %11101110 Step 2
I2cSlave b0, 255, I2CBYTE
I2cRead 7,(b1)
SerTxd( "OK Addr ",#b0, CR, LF )
Next
SerTxd( "Done" )
 

Dippy

Moderator
Thanks for the interpretation.

I notice a small glitch after the part marked 'not ack'. Does that happen still if Accel not connected?
In fact what does it all look like if Accel not connected.

That App Note looks useful, particularly REGB.

Re: I2C.
It looks a bit confused.
The part marked ?? is almost as though it was starting another transaction SDA-high & SCL-Low.
But its difficult to say without it sitting on my bench.
I wish you luck! And do have a look at config register settings.
 

alband

Senior Member
Apologies, I missed some of the connections to the accel on the first schematic. Here is an updated version.

This is what I think the problem is.

As hussy11 has shown, I need to write to CTRL_REGB first, then a few other as indicated on p3 of that app notes sheet. p22 of the datasheet outlines what CTRL_REGB does. In particular, bit7 of CTRL_REGB is called "CLKhld"
CLKhld allows the KXPS5 to hold the serial clock, SCL, low in I2C mode to force the transmitter into
a wait state during A/D conversions.
CLKhld = 1 – SCL held low during A/D conversions
CLKhld = 0 – SCL unaffected
CLKhld should be set to 0 when Enable is set to 0 (disabled) to prevent potential holding of the CLK
line.
As a default, CTRL_REGB is 01000010 which means CLKhld is off. Perhaps the accelerometer is going to acknowledge eventually but needs to hold the clock low; forcing the PICAXE to wait. It would't be able to do this from start-up because CLKhld is off. To solve this, would I need to bit-bang the first comunication, so that the PICAXE ignores the lack of ACK bit?

Clearly, the slave address could be wrong, but I don't know what is wrong with my code in post 1 that should be able to "find" the correct address.

@Dippy, the trace looks EXACTLY the same without the accel's SDA and SCL lines attached. That seems significant to me, but I'm not sure why.

I will also attach pictures of the breadboard, but I doubt it will be much help. I have to restart my PC first though before I can get the picture onto the PC so I'll add the pictures in a reply.
 

Attachments

alband

Senior Member
I've just tried it with the following code
Code:
		#PICAXE28X2
pause 1000
high B.5
high B.4
pause 1000
setfreq m1

		i2cslave %10100100,255,i2cbyte

		let b1 = 0
		SERTXD("RESET")
				
		pause 50
		writei2c %00001101,(%11000010)
		pause 50
		writei2c %00001100,(%00000000)
		pause 50
		writei2c %00001000,(%00001110)
		pause 50
		writei2c %00001001,(%00010100)
		pause 50
		writei2c %00001010,(%01010101)
		pause 50
		writei2c %00001011,(%00010101)
		
main:		for b1 = %00000000 to %00000101
		pause 50
		readi2c b1,(b0)
		sertxd (#b0,",")
		next
		sertxd (CR,LF)
		goto main
This writes some "good" values to the registers needed (as per the app notes sheet) then it reads all the X,Y,Z (LSB & MSB).
However, it only returns "13" repeatedly.:confused:
 

hippy

Ex-Staff (retired)
Looks like none of the I2C accesses are causing a 28X2 reset ( as appeared to be happening before ) so the test wasn't that useful ( and was actually flawed ! ) but it does seem that at least one of the addresses may have got through from your scope trace and further experimenting.

Over lunch I'll try and come up with more useful test code.

Added : try this ...

#Picaxe 28X2
#Terminal 1200

Pause 1000
High B.5
High B.4
Pause 1000
SetFreq M1
SerTxd( "Start", CR, LF )
For b0 = %00010000 To %11101110 Step 2
Gosub TestThis
Next
SerTxd( "Done", CR, LF )
End

TestThis:
I2cSlave b0, 255, I2CBYTE
For b1 = 1 To 15
I2cWrite 9,(b1)
Pause 10
I2cRead 9,(b2)
If b1 <> b2 Then : Return : End If
Next
SerTxd( "OK Addr ",#b0, CR, LF )
Return

Important : Take the I2C Eeprom out of circuit; that's what's responding to the %1010xxxx addresses :)
 
Last edited:

alband

Senior Member
Yes, I actually just did an addition to your previous code and found that it was the EEPROM that was responding. The weird thing is that it responded (differently) to 3 slave addresses.
Code:
Code:
#Picaxe 28X2
#Terminal 1200
Pause 1000
High B.5
High B.4
Pause 1000
SetFreq M1
		
		For b0 = %00010000 To %11101110 Step 2
		I2cSlave b0, 255, I2CBYTE
		I2cRead 3,(b1)
		SerTxd( "OK Addr ",#b0,",",#b1, CR, LF )
		Next
		SerTxd("Done")
Response (look @ ~160)
Code:
OK Addr 16,255
OK Addr 18,255
OK Addr 20,255
OK Addr 22,255
OK Addr 24,255
OK Addr 26,255
OK Addr 28,255
OK Addr 30,255
OK Addr 32,255
OK Addr 34,255
OK Addr 36,255
OK Addr 38,255
OK Addr 40,255
OK Addr 42,255
OK Addr 44,255
OK Addr 46,255
OK Addr 48,255
OK Addr 50,255
OK Addr 52,255
OK Addr 54,255
OK Addr 56,255
OK Addr 58,255
OK Addr 60,255
OK Addr 62,255
OK Addr 64,255
OK Addr 66,255
OK Addr 68,255
OK Addr 70,255
OK Addr 72,255
OK Addr 74,255
OK Addr 76,255
OK Addr 78,255
OK Addr 80,255
OK Addr 82,255
OK Addr 84,255
OK Addr 86,255
OK Addr 88,255
OK Addr 90,255
OK Addr 92,255
OK Addr 94,255
OK Addr 96,255
OK Addr 98,255
OK Addr 100,255
OK Addr 102,255
OK Addr 104,255
OK Addr 106,255
OK Addr 108,255
OK Addr 110,255
OK Addr 112,255
OK Addr 114,255
OK Addr 116,255
OK Addr 118,255
OK Addr 120,255
OK Addr 122,255
OK Addr 124,255
OK Addr 126,255
OK Addr 128,255
OK Addr 130,255
OK Addr 132,255
OK Addr 134,255
OK Addr 136,255
OK Addr 138,255
OK Addr 140,255
OK Addr 142,255
OK Addr 144,255
OK Addr 146,255
OK Addr 148,255
OK Addr 150,255
OK Addr 152,255
OK Addr 154,255
OK Addr 156,255
OK Addr 158,255
OK Addr 160,33
OK Addr 162,99
OK Addr 164,13
OK Addr 166,13
OK Addr 168,255
OK Addr 170,255
OK Addr 172,255
OK Addr 174,255
OK Addr 176,255
OK Addr 178,255
OK Addr 180,255
OK Addr 182,255
OK Addr 184,255
OK Addr 186,255
OK Addr 188,255
OK Addr 190,255
OK Addr 192,255
OK Addr 194,255
OK Addr 196,255
OK Addr 198,255
OK Addr 200,255
OK Addr 202,255
OK Addr 204,255
OK Addr 206,255
OK Addr 208,255
OK Addr 210,255
OK Addr 212,255
OK Addr 214,255
OK Addr 216,255
OK Addr 218,255
OK Addr 220,255
OK Addr 222,255
OK Addr 224,255
OK Addr 226,255
OK Addr 228,255
OK Addr 230,255
OK Addr 232,255
OK Addr 234,255
OK Addr 236,255
OK Addr 238,255
Done
I got the same conclusion from your code too.
This does show that the accel still isn't responding for some reason :(:confused: It is definitely working, because all the other features are working (on the other chip too) so perhaps there is something wrong with the nCS input. It is currently soldered to VDD so that should be fine.
 

BeanieBots

Moderator
Might just be a coincidence but interesting how 160 = $A0 = %10100000
and that 160 to 167 would cover the address range of A0 - A2 on the EEPROM.
Where those lines floating?
 

alband

Senior Member
I wondered if that was the case, but they have been tied low using wire (as opposed to resistors).
 

hippy

Ex-Staff (retired)
My money's on miswiring, pinout error, dodgy connection, broken wire or something similar if you haven't blown the SDA/SCL interface on the chip. I can only suggest the earlier tests to check those. Plus strip it all down completely, everything removed from the breadboard, re-assemble it ( using different holes ) and try again - ideally get someone else to do that. I really do mean complete strip down to bare board.

You could try running the test code in post #20 on a 28X1 or 18X ( or write bit-banged I2C code for one of the other PICAXE ) and you could also try using SPI, though if there's a wiring problem I doubt that will fare much better.

Unfortunately it's not easy to remotely look over a shoulder. Maybe cut the circuit down to the bare minimum, post a high-res pic of the setup which clearly shows where everything is wired to on the breadboard and to the accelerometer itself.
 

BeanieBots

Moderator
Sorry, but I'm with Hippy on this one.
Good photo might show up something, they have in the past!

Once you've convinced yourself the circuit is good, it becomes almost impossible to see any errors. I've been there myself. Let someone else look.
 

Dippy

Moderator
Yes, I'll 'third' that.

We can't see your wiring let alone check it.
We don't know if you've accidentally splashed a chip.
Sadly, you're now into the realm of methodical and tedious checking.
That means checking your wiring visually and electrically for continuity and component checking.

We've probably exhausted most of the "have you tried"s.
Good luck. It ain't always easy. Most of us have been there and can sympathise.

If it were me I'd contact the Manufacturer's Technical Support and say you're not getting any I2C response and ask for suggestions. People 'in the know' may give an instant response.
None here have (apparently) used that chip.
Don't be scared to email them, they won't bite or send the boys round :)
They might be glad of someone to speak to.
(At least that's how Microchip always seem ... I think they enjoy humouring me!)
 

alband

Senior Member
I've re-arranged the breadboard so there is much fewer wires and stuff, and it is generally easier to see. This also has the benefit of getting around that "I'm certain it's right" mide-set (that said, I've tested the EEPROM chip). I've got a couple of really nice high res shots of the BB and an ok shot of the accel board. the problem is, they are a total of 10Mb :eek:

There is no way I can post them on here, the max attachment size is only about 2Mb.
 

hippy

Ex-Staff (retired)
There should be some JPEG optimising software somewhere which should drastically cut the size down without sacrificing too much quality. It's really being able to see where the wires actually go to - which I admit can be difficult to achieve.
 

Dippy

Moderator
Haven't you got CorelDraw, PainShop pro, Seriff Paint , or one of many dozens of bits of arty software - all these can do a great job with shrinking and compressing.
 

Technical

Technical Support
Staff member
Not sure why you are playing with all those slave addresses, there are only two options.
%001100x0 where X can be 0 or 1 depending on your hardware address bit (which must not be floating - note your original schematic does show floating)

Note you must also pulse ENABLE - are you doing this - we would connect both Enable and MOT_Enable to PICAXE output pins.

Also we would never trust the power-on reset values (as they are copied form EEPROM when enable is pulsed), no harm in writing what you want! If this doesn't work then it is safe to assume
1) hardware has faulty setup
2) datasheet is wrong
3) chip doesn't work

Code:
symbol ENABLE = PORT.PIN
symbol MOT_ENABLE = PORT.PIN
hi2csetup i2cmaster, %001100x0, i2cslow, i2cbyte 'replace x with 0 or 1
 
init:
  low ENABLE
  pause 500
  high ENABLE
  low  MOT_ENABLE  
  pause 500
  hi2cout $0C,($00,$42)
  pause 500
 
main:  do
  hi2cin 0,(b0,b1,b2,b3,b4,b5)
  debug
  loop
 
Last edited:

alband

Senior Member
Right, I've been having trouble getting the images small enough. I haven't been able to install PSP on this PC (dunno why) so I had to move them to PC's that have it etc...

Anyway, they are all 1Mb-ish so I had to make them .txt files, rename them to .jpg, as you would.

@technical: Currently, I haven't been pulsing enable. Do you mean pulsing low or high? Currently, I've just had it tied low with 10k (see latest schematic) and pulling it high after switch-on. Surely this has the same affect as pulsing low?

I've been trying lots of different addresses because it isn't acknowledging at all. If the datasheet is wrong, and I just continue trying the address it suggests, then I may never get it. So after each adjustment, it makes sense to try every address.

And of course, I can't load any values until I can get it to acknowledge.


I emailed the people at Kionix and they emailed back almost instantly, they put me in touch with technical support (even though I'm not a large scale business customer which apparently is not the norm) and they have given me the standard hints. I'm not going to bother them again any time soon as I'm pushing my luck just having them answer at all. I highly recommend them for there communication though.

Urgh, It wont accemt the pictures as .txt files. This is going to take ages and they may end up being quite poor quality. I have one picture though that is within limits at this time so I attach that then reply with the others (that are of the BB)

Addit: Oh and I tried your code technical and it just returned 255, so it still wasn't acknowledging.
 

Attachments

hippy

Ex-Staff (retired)
Have you got a track diagram of the breakout board as I cannot work out what's what and it doesn't seem to add up for me.

Also, given it's an LGA package, how do you know you've got usable connections between the breakout board and the chip ? Was it pre-assembled ?
 

alband

Senior Member
I haven't got a diagram but it is the same aa any standard BB. Blue and red represent powerlines that run allong the BB. The holes in the middle run accross the BB with a break in the middle. It's just like the standard BB that loads in PEBBLE.
Where in the picture does this not make sense?

I cannot be 100% sure there are connections under the i2c pins until it works. However, it is a startalingly easy package to solder. Cover the pins with flux jelly, "stick" the accel to this then add solder on the outside of each track and it flows the short distance undurneath the accel.

All the other connections are good because they have been working. I used exactly the same method to solder those pins so there is no reason why the i2c pins are bad. I've also continuity checked the pins with each others and there are no shorts. I will get you some better pictures of the accel board in the morning that are smaller but better quality; they should re-assure you.
I am 99% sure they are good joints.
 

hippy

Ex-Staff (retired)
It's the breakout board ( not breadboard ) which I cannot follow. It's not how I'd expect it to be for the pinout given in the datasheet.

There seems to be no pad opposite pin 1 ( for pin 13 ), no pad ( or nothing connected ) for pin 14, and two pads at the bottom where I'd expect one for pin 7.

I'd have expected the breakout board for such a small component to have taken the tracks and pads straight out ( up, down, left or right ) from where the pins are on the package but this doesn't seem to be the case. I therefore cannot work out how the solder pads relate to pin number for pins 7 to 14, therefore cannot tell if it is wired correctly or not.
 

alband

Senior Member
Ah right. Don't worry, there just wasn't any point in extending all three VDD pads out, they are connected underneath. I also moved the bits at the bottom around so that capacitors could be added. I'll get a picture of it on here before it was soldered to shouw you what I mean.
 

hippy

Ex-Staff (retired)
Thanks. Looks okay to me ... so back to continuity checking all connections and testing each line can be toggled by the PICAXE, plus explicitly setting the enable lines low at the start of program before bringing them High later.
 

alband

Senior Member
All the inputs are held low with resistors but I can try putting them low with the PICAXE first.

@Dippy: the idea is that the solder wi is underneath. I touchthe outside of the pad with a wet iron and it wicks under to the pad. If you mean any shorts between pads; I can check them all against each other.

I really hope I find something wrong!
 
Top