After playing the fighting robot with the gamepad for a period, I upgrade the controller this time. You may review the first two issues (Issue I, Issue II) for the making process. I do not use a gamepad, but self-made an arm-band type somatosensory interactive controller.
Previous Contents:
You must feel this name is too abstract. Specifically, it means acquiring the posture of arm with an acceleration sensor and then controlling the robot or others wirelessly.
I use following devices:
Xbee sensor extension board V5 1
Battery pack 1
Battery 5 (matching with battery pack)
numchuck connector and connection line 1
MMA 7361 accelerator sensor 1
Kneecap 1
Wii sub-controller numchuck 1
DFduino wireless module 1
I want to describe the hardware connection at first. Step 1, wear the kneecap on the left wrist. Why to choose a kneecap rather than a wrist guard? Because the kneecap allows larger space around the arm, and it is easier to make the knee cap; the wrist guard will be fully tightened on the wrist.
Wear the kneecap to the position between the thumb and index finger, and seam such part to make it look like a glove, and seam Arduino control panel and accelerator sensor on the knee. As shown in Figure 2, the connection line of accelerator sensor passes through the kneecap.
Figure 2 Fixing of Control Panel and Accelerator Sensor
Step 2, insert the Xbee sensor extension board V5 onto the Arduino control panel. Meanwhile, connect the connection line of accelerator sensor onto A0, A1 and A2, corresponding to three axial directions of X, Y, Z, and connect the Numchuck connector to the sensor extension board with the connection line. During connection, you shall notice the definition of pin. As shown in Figure 3, the end c of connector corresponds to A 4 and end c corresponds to A 5.
Figure 3 Connection of Sensor Extension Board
Step 3, as shown in Figure 4, connect the battery pack to the power input end of sensor extension board, and fix it between the kneecap and the arm.
Figure 4 Fixing of Battery Pack
Step 4, as shown in Figure 5, disassemble the DFduino wireless module in the remote control unit and install it on the sensor extension board.
Figure 5 Installation of DFduino Wireless Module
At last, Connect the sub-controller numchuck of Wii, and hold it in the right hand as shown in Figure 6. So far, the hardware part is completed.
Figure 6 Connection of numchuck
The software part is described as follows. My control idea of such controller is that, the robot will swing its arm when I stretch out my arm horizontally as shown in Figure 7; the robot will punch when I swing my arm forward as shown in Figure 8.
Figure 7 Stretching out the Arm Horizontally
Figure 8 Swinging the Arm Forward
The movement of robot relies on the joystick on the sub-controller numchuck as well as coordinated operation of Z key and C key on the numchuck. The corresponding relations of operation and robot motion are as shown in the table below.
The use of the sub-controller numchuck of Wii is introduced in Issue 12, 2010 and Issue 6, 2012 of Radio Magazine, so I just briefly describe it here. To use such sub-controller, Arduino needs to download a WiiChuck library file independently. With such library file, functions like wii.getAccelAxisX() and wii.getAccelAxisY() can be directly called from codes to directly acquire the value of joystick, acceleration value in the sub-controller and button value. I want to mention C key and Z key here. If both C key and Z key are not pressed, the sub-controller numchuck in my hand will return 0 respectively; if C key is pressed, it will return 0 for C key and 1 for Z key; however, if the Z key is pressed, it will return 0 for both keys; if both C key and Z key are pressed, it will return 0 for Z key and 1 for C key.
I want to emphasize the use of MMA7361 acceleration sensor as shown in Figure 9. The acceleration sensor is a type of electronic sensor which can measure the accelerating force. Through measuring the acceleration caused by the gravity, the inclination angle of equipment relatively to the horizontal plane can be calculated to analyze the movement method of equipment.
MMA7361 Acceleration Sensor
MMA7361 acceleration sensor is based on the micro capacitive three-axis acceleration sensor MMA7361 chip manufactured by Freescale. The chip adopts the signal conditioning, monopole low pass filter and temperature compensation technology, and provides two ranges of ±1.5g/6g. The user may select either of the 2 sensitivities. Such device is provided with the low-pass filtering and has been compensated of 0g.
The sensor has 3 three-core interfaces of analogs, representing the acceleration value of three axes: X, Y and Z, and the pin header welding holes are reserved. As I mentioned, we connect the acceleration output pins at axial directions of X, Y and Z to A0, A1 and A2 respectively.
Static Acceleration Output Value of Sensor
We use the range of 1.5 g. The figure above gives the static acceleration of sensor at each axial direction. The range is from -1.5 g to +1.5g, so the output voltage of pin is about 1.65V when the acceleration is 0 g. Due to the gravity, the upward acceleration of downward axis is 1 g (may be +1g or -1g, depending on different directions). We can convert the analog outputted by the sensor to the voltage value through the code below (taking X axis as example).
vol_x=analogRead(A0)*5.0/1024;
Then, convert the current upward acceleration through the voltage value according to the sensitivity--800mV/g at the range of 1.5 g. This code is as follows:
g_x =(vol_x-1.76)/0.8
However, in the actual application, due to the sensor difference, the output voltage at 0 g may not be 1.65 V. Thus, the acceleration sensor shall be calibrated based on the output voltage at 0 g currently before used.
However, it is not so troublesome here. You may deduce the current approximate posture of sensor only by judging whether the analog value returned is in an interval, to send the instruction to control the robot accordingly.
The detailed codes are as follows.
#include <stdlib.h>
#include "Wire.h"
#include "WiiChuck.h"
WiiChuck wii = WiiChuck();
int sensorAccelX,sensorAccelY,sensorAccelZ;
int sensorAccelWiiX,sensorAccelWiiY,sensorAccelWiiZ;
int sensorJoyX,sensorJoyY;
int buttonC,buttonZ;
void setup()
{
wii.init(); //
Serial.begin(57600);
}
void loop()
{
//
sensorAccelX = analogRead(A0);
sensorAccelY = analogRead(A1);
sensorAccelZ = analogRead(A2);
//
if (true == wii.read())
{
sensorAccelWiiX = wii.getAccelAxisX();
sensorAccelWiiY = wii.getAccelAxisY();
sensorAccelWiiZ = wii.getAccelAxisZ();
sensorJoyX = wii.getJoyAxisX();
sensorJoyY = wii.getJoyAxisY();
buttonZ = wii.getButtonZ();
buttonC = wii.getButtonC();
}
//
//
if((buttonZ == 1) && (buttonC == 1))
{
if(sensorJoyY > 200)
{
Serial.write(1);//
}
else if((sensorJoyY < 76) && (sensorJoyY > 40))
{
Serial.write(2); //
}
if((sensorJoyX < 76) && (sensorJoyX > 40))
{
Serial.write(15); //
}
else if(sensorJoyX > 200)
{
Serial.write(14); //
}
}
//
if(buttonZ == 0)
{
if(sensorJoyY > 200)
{
Serial.write(13); //
}
else if((sensorJoyY < 76) && (sensorJoyY > 40))
{
Serial.write(12); //
}
if((sensorJoyX < 76) && (sensorJoyX > 40))
{
Serial.write(8); //
}
else if(sensorJoyX > 200)
{
Serial.write(7); //
}
}
//
if((buttonZ == 1) && (buttonC == 0))
{
if(sensorJoyY > 200)
{
Serial.write(9); //
}
else if((sensorJoyY < 76) && (sensorJoyY > 40))
{
Serial.write(16); //
}
}
//
if(sensorAccelX > 500)
{
Serial.write(4); //
}
if(sensorAccelZ > 450)
{
Serial.write(6); //
}
//
if(sensorAccelWiiY < 154)
{
Serial.write(3); //
}
if(sensorAccelWiiX < 115)
{
Serial.write(5); //
}
delay(200);
}
To be continued...