Integrating wii motion plus i2c

Madtom

Member
I have been constantly searching the Internet and forums for how to integrate an 18m2+ with a motion plus.

I have recently connected a nunchuck to it and got it working well but it has a huge dead zone in the middle so instead i would like to use a motion plus to stabilise my quadrotor.

I have found some arduino code for the motion plus that says it starts at directory $53 and then once initialized moves to directory $52.

my code is on my other pc but off the top off my head looks like this

Init:
I2cslave $53,i2cslow,i2cbyte

Write i2c 0xF0,(0x55)
Pause 10
Writei2c 0xfb,(0x00)
Pause 10

I2cslave $52,i2cslow,i2cbyte
Main:
Writei2c 0,(0)
Pause 10
Readi2c (b0,b1,b2,b3,b4,b5)
Pause 10
Debug
Goto main
But all I get is 255 in most variables
As far as I know there are no other posts that I could find anywhere

Thanks in advance


Here is some of the resources I've been using

http://wiibrew.org/wiki/Wiimote/Extension_Controllers

http://www.musclera.com/wii-motionplus-demonstration/

http://arduino.cc/forum/index.php/topic,8661.0.html
 
Last edited:

Technical

Technical Support
Staff member
You need to change the 7 bit i2c address to the full 8 bit address (as used by PICAXE) instead.

7 bit = $52 = %01010010
8 bit = %10100100

7 bit = $53 = %01010011
8 bit = %10100110
 

Madtom

Member
So doesn't the picaxe read hex?

This would explain the numbers I get back
Although I had the nunchuck working on hex but it was at $A4

Thanks Technical

I will change these later today and post my results
 

Madtom

Member
I think I found the problem

Init:
I2cslave $53,i2cslow,i2cbyte

Write i2c 0xF0,(0x55)
Pause 10
Writei2c 0xfb,(0x00) <this is wrong it should be writei2c 0xfe,(0x04)
Pause 10

I2cslave $52,i2cslow,i2cbyte
Main:
Writei2c 0,(0)
Pause 10
Readi2c (b0,b1,b2,b3,b4,b5)
Pause 10
Debug
Goto main

That is what's stated on this forum anyway

http://forum.wiibrew.org/read.php?11,32585,32922

4th post down
 

westaust55

Moderator
Seemingly, the slave address $53 or better written in 8-bit form as $A6 is for intefacing via the Wii MotionPlus interface.

If you are directly connecting the Wii Nuncheck to your PICAXE then for the PICAXE use $A4. (7-bit addess = $52)

This extract of code for a PIC shows a sequence for a PIC connecting direct to a Nunchuck.

Code:
// Nunchuk Init: Initialize the nunchuk by sending I2C commands to make the 
// nunchuk "active". This particlular routine is different than others, but 
// this one works with generic/knockoffs such as the one I'm using. 

void nunchuck_init(void) {   
i2c_init();     
i2c_start();   
i2c_send(0xA4); // Device 0x52   
i2c_send(0xF0);   
i2c_send(0x55);   
i2c_stop();     
i2c_start();   
i2c_send(0xA4);   
i2c_send(0xFB);   
i2c_send(0x00);   
i2c_stop(); }   /
/ Nunchuk Read: Read the six bytes of data from the nunchuk. The read must be 
// preceded by sending a zero to the nunchuk. 
void nunchuck_read(unsigned int* array) {   
i2c_start();   
i2c_send(0xA4);   
i2c_send(0x00);   
i2c_stop();     
i2c_start();   
i2c_send(0xA5);   
array[0] = i2c_read();   
i2c_ack();   
array[1] = i2c_read();   
i2c_ack();   
array[2] = i2c_read();   
i2c_ack();   
array[3] = i2c_read();   
i2c_ack();   
array[4] = i2c_read();   
i2c_ack();   
array[5] = i2c_read();   
i2c_nack();   
i2c_stop(); }
so try

I2cslave $A4,i2cslow,i2cbyte
 

Madtom

Member
Yeah, what was I thinking.

I should have known they where 7 bit

Always pays to have someone else look at mistakes you may have overlooked

I was just reading one of the posts for arduino to see how they do it but it must be compatible with 7 bit.

So what is $52 in 8bit I'm not quite certain how to convert it in hex.

Or do I put it in binary convert that to 8bit then convert it back to hex

Thanks
 
Last edited:

hippy

Technical Support
Staff member
$53 as 7-bit binary is "1010011", to turn it into 8-bit one adds a zero to the right; "10100110", which is, in hex, $A6.

$52 as 7-bit binary is "1010010", to turn it into 8-bit one adds a zero to the right; "10100100", which is, in hex, $A4.

Using a calculator which shows hex, enter the 7-bit hex value and multiply by two to get the 8-bit value.
 

westaust55

Moderator
Most computers, microcontrollers and microprocessors all work in bytes or multiples thereof.

I2c comms is no different and each item of data is a byte which consists of 8 bits.
Slave addresses for most i2c devices are in effect 8 bits (and a few are 10 bits). PICAXE and many other chips only handle the 8 bit configuration.
The 8 bits typically are configures as follows:
- 4 bits (most significant bits) as hard defined data defined by the manufacturer and Philips/NXP inventers of i2c.
- 3 bits as chip address data to match address pin configuration
- 1 bit (least significant bit) as the read write bit

Some devices have more than 4 of the first address type bits and correspondingly less of the second type of address data bit.

Some chip manufacturers talk about 7 bit slave addressing and that is what these first/highest 7 bits represent. Then we must allow for the 8th bit for the read/write bits used for data direction control.

With the PICAXE, the read/write bit is automatically set correctly depending upon the i2c command we use so it is just as easy to leave it as zero (0) for the slave address definition

So now, knowing the above, if we are told the 7-bit slave address is $53 = binary %0101 0011. For 7 bits we drrop to most significant bit and the remaining bits (1&#8217;s and 0&#8217;s) are put into the top 7 bits and we put a 0 in the least significant bit (bit 0).
Now the complete slave address is %1010 0110 = $A6

For some microcontrollers and programming languages the user must define the read write bit so in datasheets and programs you might see reference to separate read ansd write addressing such as $A6 and $A7. But as mentioned, for the PICAXE you do not need to worry about the read write bit, just make sure the 7 bit part of the slave address is in the most significant/left most bit positions and a 0 in the least significant/right most bit.
 

westaust55

Moderator
So via the WMP interface board we need to look at:
Code:
// WMP Init: Initialize the WMP by sending I2C commands to make the WMP 
// "active". 
void motionPlus_init(void) { 
  i2c_init(); 
  
  i2c_start(); 
  i2c_send(0xA6); // Device 0x53 
  i2c_send(0xFE); 
  i2c_send(0x04); 
  i2c_stop(); 
} 
  
// WMP Read: Read the six bytes of data from the WMP. The read must be preceded 
// by sending a zero to the WMP. 
void motionPlus_read(unsigned int* array) { 
  i2c_start(); 
  i2c_send(0xA4); 
  i2c_send(0x00); 
  i2c_stop(); 
  
  i2c_start(); 
  i2c_send(0xA5); 
  array[0] = i2c_read(); 
  i2c_ack(); 
  array[1] = i2c_read(); 
  i2c_ack(); 
  array[2] = i2c_read(); 
  i2c_ack(); 
  array[3] = i2c_read(); 
  i2c_ack(); 
  array[4] = i2c_read(); 
  i2c_ack(); 
  array[5] = i2c_read(); 
  i2c_nack(); 
  i2c_stop();
So seemingly you code will need to be:
Code:
Init:
  I2cslave $A6,i2cslow,i2cbyte

  Write i2c 0xFE,(0x04)
  Pause 10


Main:
  I2cslave $A4,i2cslow,i2cbyte
  Readi2c 0, (b0,b1,b2,b3,b4,b5)
  Pause 10
  Debug
  Goto main
 
Last edited:

Madtom

Member
Wouldnt you put i2cslave $a4,i2cslow,i2cbyte before main so you are not re initializing it every loop

Also I have been finding lots of different versions of the initialisation sequence I think 0xfe,(0x04) is only half of it.
as a lot of other forums say you need to Writei2c 0xF0,(0x55) then writei2c 0xfe,(0x04) so like this:

Init:
I2cslave $A6,i2cslow,i2cbyte

Write i2c 0xf0,(0x55)
Pause 10
Write i2c 0xfe,(0x04)
Pause 10

I2cslave $A4,i2cslow,i2cbyte
Main:
Write i2c 0,(0)
Pause 10
Readi2c 0, (b1,b1,b2,b3,b4,b5)
Pause 250 ' I made this 250 to make it less jumpy under the vibrations of a quadrotor
Debug
Goto main

You also need that writei2c 0,(0) it is in your top snippet but you haven't put it in your bottom one
 
Last edited:

Madtom

Member
I will test westaus55's way then mine to see if either of them work but I can't get access to my setup untill tomorrow so I will post some results then
 

westaust55

Moderator
Wouldn't you put i2cslave $a4,i2cslow,i2cbyte before main so you are not re initializing it every loop
Yes - it would be better

Also I have been finding lots of different versions of the initialisation sequence I think 0xfe,(0x04) is only half of it.
as a lot of other forums say you need to Writei2c 0xF0,(0x55) then writei2c 0xfe,(0x04) so like this:
Unfortunately some folks who post data and write ups on the internet seem to post wrong data that may in fact never work leading to frustration of those who try to follow in their foot steps.
That can be half of the fun for a real experimenter - to sift the wheat (correct data) from the chaff (rubbish) and get the project working.

You also need that writei2c 0,(0) it is in your top snippet but you haven't put it in your bottom one
No, the programs written in assembler need to do that - as in, write the zero first and then switch to read mode.

But with the PICAXE, the zero can be written first as part of the i2cread or hi2cin commands.
If you look at the code snippet I posted you will see:
Readi2c 0, (b0,b1,b2,b3,b4,b5)​
whereas you originally had:
Readi2c (b0,b1,b2,b3,b4,b5​
That 0 is in effect the register address which will be sent by the PICAXE automatically before the PICAXE changes to reading/input mode.

If you first use an i2cwrite (or hi2cout) followed by i2cread (or hi2cin), as per your examples, in effect the PICAXE:
1. sends the slave address
2. sends the register address = 0
3. sends the data = 0
4. sends the slave address again
5. fetches the data.

steps 3 and 4 with confuse the nunchuck or other devices

the line as I later presented reduces the activity to:
1. sends the slave address
2. sends the register address = 0
3. fetches the data.

Which I suspect is far more likely to work correctly for the PICAXE.
 

Madtom

Member
Ok just looking at other codes (even the picaxe nunchuck ones) put that write command there, suppose its just putting the same thing twice.

I know what you mean by wrong data and sorting through to find the working ones are painful. I had not even heard about thee i2c bus untill two weeks ago and the picaxe help files on it aren't great. So False data just makes learning it hard.

Anyway I'll test it tomorrow and post some results

Also in an unrelated topic
Why can't the 18m2+ do more than two servos simultaneously I'm pretty sure the manual says it can do 8 but when you try to do 3 or more it won't respond after about 15 secs. (didn't think this question was big enough for its own thread).
 

westaust55

Moderator
Re the 18M2 and servo problems being experienced.

I am not aware of any problem/limitation. Yes you can control up to 8 Servomotors.

Others have successfully used 4 in this PICAXE project:
http://www.picaxeforum.co.uk/showthread.php?21970-18M2-4-Servo-Walking-Hexatron-with-IR-Sensor-to-see
http://www.picaxeforum.co.uk/blog.php?60409-Scientificfreek8479&tag=robot

Suggest that you do start a new thread on this topic.
Indicate whether you have a separate power supply for the servos.
Maybe post a schematic.
Certainly post your program code
 

Madtom

Member
Ok I will start a new thread but answer your questions here first

1. I don't have a separate power supply as I am using 4 esc/bec's which take the 7.4 volts from the battery and turn it into 5v the picaxe and rf receiver are then powered by this 5v. The rf receiver recieves signals from my radio control. And sends them to the picaxe(s) (am using three one for the front and back motors, one for the left and right motors, and one to read the motion plus)
(also I am still going to use three even if I can get one to run all servos for speed)
The picaxe mixes this ordinary 4ch imput signal into a quadrotor motor control signal. And each motor control signal is sent to the esc/bec's and therefor the motors.

2. Will photos do or would you prefer me to draw one up (there a lots of wires so a pic may not be so easy to follow)

3. Do you want the program code for the whole thing or just the servo bits. It also won't do more than two servos if I just go

Init:
Servo b.7,75
Servo b.6,75
Servo b.5,75
Main:
pulsin c.7,1,b7
Pulsin c.6,1,b6
Pulsin c.5,1,b5
Servopos b.7,b7
Servopos b.6,b6
Servopos b.5,b5
Goto main

This won't run my motors but if I get rid of the b5's it will
Actually even if I just tell 3 esc's to go to 150 it will still not respond but 2 will so I don't think it has anything to do with the pulsin bits
( if that code isn't right don't worry about it I can't get my actual code untill tomorrow)
Also I'm running it at the default 4mhz if you need that
 

Madtom

Member
Still not working with the motion plus

code im using

init:
i2cslave $A6,i2cslow,i2cbyte

writei2c 0xf0,(0x55)
pause 10
writei2c 0xfe,(0x04)
pause 10

i2cslave $A4,i2cslow,i2cbyte

main:
readi2c 0,(b0,b1,b2,b3,b4,b5)
pause 250
debug

goto main

also tried just

writei2c 0xfe,(0x04)
pause 10

in init but i didnt work either
 

Madtom

Member
Ok

Just found out
Writeic 0xf0,(0x55) is initialisation
And
Write 0xfe,(0x04) tells the motion plus to be active instead of using a nunchuck plugged into the bottom so I think it should be after
I2cslave $a4,i2cslow,i2cbyte

So its like sending the active command to an unused location so the mp can't read it so the motion plus still thinks the wiimote wants another accessories to be plugged in the bottom.

So it should now look like this

Init:

I2cslave $A6,i2cslow,i2cbyte

write 0xf0,(0x55)
Pause 10

I2cslave $a4,i2cslow,i2cbyte

Write 0xfe,(0x04)
Pause 10

Main:

Readi2c 0,(b0,b1,b2,b3,b4,b5)
Pause 250
Goto main
 

Madtom

Member
Can't test this latest one for half an hour so I don't know if it works yet I will post results here once I try it
 

Madtom

Member
On page 1 my first post showed a code that I latter replaced
Writei2c 0xfb,(0x00) with Writei2c 0xfe,(0x04) as I thought it was false data but maybe I was just suppose to put it later on so it looks like this

Init:
I2cslave $A6,i2cslow,i2cbyte

Write i2c 0xF0,(0x55)
Pause 10
Writei2c 0xfb,(0x00)
Pause 10

I2cslave $A4,i2cslow,i2cbyte

Write 0xfe,(0x04)
Pause 10

Main:

Readi2c (b0,b1,b2,b3,b4,b5)
Pause 10

Debug
Goto Main

If this doesn't work well I'm sick of the disappointment of it so I probably will just get an analog gyro
 

westaust55

Moderator
Based upon this website, http://randomhacksofboredom.blogspot.com.au/2009/06/wii-motion-plus-arduino-love.html

try this code:

Code:
Init:
	i2cslave $A6,i2cslow,i2cbyte
	i2cwrite $FE, ($04)     ; activate WM+
; WM+ jumps to address $A4 and is now active
i2cslave $A4,i2cslow,i2cbyte

Again:
	DO
		i2cread $0, (b0, b1, b2, b3, b4, b5) ; send a $0 as register, then read in 6 bytes of data
		PAUSE 1000
	LOOP
Errr - thats the same as what I suggested before.

Can we take a step back . . .
Can you sucessfully write to and read from an EEPROM or a DS3107 RTC?
lets ensure some basics are working first.
 

Madtom

Member
Haven't got an EEPROM or anything like that but I did manage to get it to run a nunchuck and read the data from its accelerometer and joystick which is pretty close to the motion plus exept it uses a different initialisation process
I did it on this exact chip

Quick question on the step up resistors. I have them going to the 3.3v side of my voltage regulator should they be on the 5v side
 

westaust55

Moderator
Haven't got an EEPROM or anything like that but I did manage to get it to run a nunchuck and read the data from its accelerometer and joystick which is pretty close to the motion plus exept it uses a different initialisation process
I did it on this exact chip

Quick question on the step up resistors. I have them going to the 3.3v side of my voltage regulator should they be on the 5v side
I take it that you have the PICAXE at say 5V and the Wii Motion+ at 3.3V or vice versa.
In this case you need a couple of 2N7000 FET transistors and four 4k7 Ohm pull-up resistors to create a bi-directional level shifter circuit for the clock and data lines.

Have a read here: http://www.picaxeforum.co.uk/showthread.php?20892-I2C-level-changing-IC-for-6

and here this the mentioned Philips/NXP document on i2c Level Shifting: http://ics.nxp.com/support/documents/interface/pdf/an97055.pdf
 

Madtom

Member
How would I wire that

And what do you mean level shifter circuit

Oh wait you mean so the power can go to the clock and data lines but not back to the power line so your clock and data lines don't mix


I have 5v to the picaxe and 3.3 to the motion plus
 

westaust55

Moderator
Did you look at the schematic diagram in section 2.3 (page 10) of the pdf in the second like I gave?

In post 2 at the first link I provided there is a ready made sparkfun level shifting module - available from littlebird electronics if you do not want to make your own.
If you do want to make your own then the sparkfun link in that same post has a link to a schematic for the module as a guide.

The reason for a level shifting circuit is to allow the transfer of data between two components without subjecting the lower voltage rated component to excessive/damaging voltages.
Applying 5V to a 3.3 V rated component - even as a signal from the 5 V supplied component may lead to failure of the 3.3 V component.
In the case of the i2c bus, the signal lines are open colelctor design and the data signal is bi-directional (and maybe even the clock signal if in the rare event there are multiple masters on the i2c bus). Becase it is bidirectional simple resistor dividers cannot be used as the data in obne direction would be far too low in voltage to allow the 5V device to "see" and high (1) signal state.
The transistor as shown in the schematic mentioned acts as a form of "switch" allowing the data to pass between the two voltage levels. But as the circuit is an open collector design, there must be pull up resistors on both sides of the transistor to the respective supply voltage level.
 

hippy

Technical Support
Staff member
If the interface was working for the nunchuck it seems unlikely it wouldn't also work as is for the motion plus.

Regardless, it would be easier to run the PICAXE at the same voltage as the Wii controller until you have things working rather than add ever more complexity into something that is not working.

It would also be worth re-checking the nunchuck code still works as that will give a known baseline everyone is working against.
 

Madtom

Member
Ok let's go back to basics so I can check over my curcuit

Running both the nunchuck and picaxe at 3.3v do I need pull up resistors

If so wouldnt your clock and data lines mix together or am I wiring it wrong

When I got the nunchuck to work it only worked for 5 mins then stopped don't know why maybe I had a loose connection
 

Madtom

Member
I think Ill just get a proper gyro

Is there any you would recommend

Analog would be preferable.

And not too expensive less than $50 would be nice

pin mount or on its own breakout board
 

westaust55

Moderator
Ok let's go back to basics so I can check over my curcuit

Running both the nunchuck and picaxe at 3.3v do I need pull up resistors
Yes, irrespective of the voltage (3.3 or 5 but same for both parts) the two i2c lines need pull-up resistors of say 4k7 Ohms to the supply voltage level.

If so wouldn't your clock and data lines mix together or am I wiring it wrong
We do not have your schematic to see how you are wiring the circuit.
In simple terms: The signals do not "mix" as the supply voltage in electronics terms is (or should) be sufficiently large and stable that, with the aid of decoupling capacitors across the supply lines, does not transfer signal noise to another signal line.


When I got the nunchuck to work it only worked for 5 mins then stopped don't know why maybe I had a loose connection
If the PICAXE was at 5V and the nunchuck at 3.3V there is the possibility that you have damaged the nunchuck.
 

hippy

Technical Support
Staff member
If the PICAXE was at 5V and the nunchuck at 3.3V there is the possibility that you have damaged the nunchuck.
I was thinking that, but if 5V was only applied through using the I2C pull-ups to 5V there should be a good chance it is okay. If the wii mote and nunchuck work with a wii then it should still work with a PICAXE.

Reading between the lines I would guess the nunchuck code for the PICAXE now isn't working. Unless the nunchuck doesn't work with a wii it could be worth persevering, taking a deep breath, rebuilding the circuit and getting it to work again.
 

hippy

Technical Support
Staff member
Also, having taken a quick look at a few links and example programs I would concur that westaust55 has his code right for the motion plus, and the version of it I'd try is -

Code:
HI2cSetup i2cmaster, $A6, i2cslow, i2cbyte
Pause 100
HI2cOut 0xFE, ( 0x04 )
Pause 100
HI2cSetup i2cmaster, $A4, i2cslow, i2cbyte
Do
  Hi2cIn 0, ( b0,b1,b2,b3,b4,b5 )
  Pause 100
  Debug
Loop
 

Madtom

Member
First I have been using both the picaxe and nunchuck at 3.3v for the time being my step up to 5v was just for the future when I integrate it with my quadro

2nd I think it is my step up wiring that is causing problems. what is the correct way to have it wired then I can compare it to mine. I can make a basic wiring diagram in paint or something but I just had the clock and data directly connect to the 3.3v line

Like this

-------------------------------------- data
|
4k7 r
|
-------------------------------------- 3.3v
|
4k7 r
|
-------------------------------------- clock

-------------------------------------- g

I just know this is wrong but I can't find the right way anywhere
I know it's probably a stupid mistake

Thanks
 

westaust55

Moderator
what is the correct way to have it wired then I can compare it to mine?
I can make a basic wiring diagram in paint or something but I just had the clock and data directly connect to the 3.3v line (via resistors)
What you have drawn is in fact the correct concept.
If you look in the PICAXE Manual 2 (V7.9) which is available
(a) here: http://www.picaxe.com/docs/picaxe_manual2.pdf and
(b) within the Programming Editor on the toolbar HELP / "PICAXE manual 2"

On page 79 and page 103 at the bottom of each page there is a diagram showing how to connect i2c bus pull-up resistors.



To do a schematic there are several software programs available. The one that I and some others use is DIPTRACE.
It is available from the software company for free for hobyy purposes Here: http://www.diptrace.com/
There is a limitation only in terms of the number of holes (for component leads) that you can have in a circuit but is still a very good option.
If you use that there are a couple of PICAXE related libraries available on this forum (prepared by mycroft and myself) here: http://www.picaxeforum.co.uk/showthread.php?10576
 

hippy

Technical Support
Staff member
A quick way to draw a schematic is in Paint or similar, even pen and paper and scan or photograph it.

A tip for hand drawing is to draw on a large bit of paper using thick felt-tip or board marker. You can draw light pencil lines first and they probably won't show in a scan or photo and in the reduced image things will look much tidier than any wobbly lines may look on the original.
 

Attachments

Last edited:

Madtom

Member
so do I need decoupling capacitors or not and if so what capacitance


I think I might rewire it just in case there is a dry solder or bad connection
I might have wired it up wrong or the Scl line might be connected to the Sda and sda to scl
 
Top