Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Maik Schmidt - Arduino A Quick-Start Guide, 2nd Edition (The Pragmatic Programmers) - 2015.pdf
Скачиваний:
184
Добавлен:
22.03.2016
Размер:
30 Мб
Скачать
☆

Chapter 6. Building a Motion-Sensing Game Controller • 102

breakout board you’re using!) Naturally, you’ll move around the accelerometer a lot, so it’s best to use long wires.

Now that we’ve connected the ADXL335 to the Arduino, let’s use it.

Bringing Your Accelerometer to Life

A pragmatic strategy to get familiar with a new device is to hook it up and see what data it delivers. The following program reads input values for all three axes and outputs them to the serial port:

MotionSensor/SensorTest/SensorTest.ino const unsigned int X_AXIS_PIN = A2; const unsigned int Y_AXIS_PIN = A1; const unsigned int Z_AXIS_PIN = A0;

const unsigned int BAUD_RATE = 9600;

void setup() { Serial.begin(BAUD_RATE);

}

void loop() { Serial.print(analogRead(X_AXIS_PIN)); Serial.print(" "); Serial.print(analogRead(Y_AXIS_PIN)); Serial.print(" "); Serial.println(analogRead(Z_AXIS_PIN)); delay(100);

}

report erratum • discuss

Finding and Polishing Edge Values • 103

Our test program is as simple as it can be. We define constants for the three analog pins and initialize the serial port in the setup function. Note that we didn’t set the analog pins to INPUT explicitly, because that’s the default anyway.

In the loop function, we constantly output the values we read from the analog pins to the serial port. Open the serial monitor and move the sensor around

—tilt it around the different axes. You should see output like this:

344 331 390

364 276 352

388 286 287

398 314 286

376 332 289

370 336 301

These values represent the data we get for the x-, y-, and z-axes. When you move the sensor only around the x-axis, for example, you can see that the first value changes accordingly. In the next section, we’ll take a closer look at these values.

Finding and Polishing Edge Values

The physical world often is far from perfect. That’s especially true for the data many sensors emit, and accelerometers are no exception. They vary slightly in the minimum and maximum values they generate, and they often jitter. They might change their output values even though you haven’t moved them, or they might not change their output values correctly. In this section, we’ll determine the sensor’s minimum and maximum values, and we’ll flatten the jitter.

Finding the edge values of the sensor is easy, but it cannot be easily automated. You have to constantly read the sensor’s output while moving it. Here’s a program that does the job:

MotionSensor/SensorValues/SensorValues.ino const unsigned int X_AXIS_PIN = A2; const unsigned int Y_AXIS_PIN = A1; const unsigned int Z_AXIS_PIN = A0; const unsigned int BAUD_RATE = 9600;

int min_x, min_y, min_z; int max_x, max_y, max_z;

void setup() { Serial.begin(BAUD_RATE); min_x = min_y = min_z = 1000; max_x = max_y = max_z = -1000;

}

report erratum • discuss

Chapter 6. Building a Motion-Sensing Game Controller • 104

void loop() {

const int x = analogRead(X_AXIS_PIN); const int y = analogRead(Y_AXIS_PIN); const int z = analogRead(Z_AXIS_PIN);

min_x = min(x, min_x); max_x = max(x, max_x); min_y = min(y, min_y); max_y = max(y, max_y); min_z = min(z, min_z); max_z = max(z, max_z);

Serial.print("x("); Serial.print(min_x); Serial.print("/"); Serial.print(max_x); Serial.print("), y("); Serial.print(min_y); Serial.print("/"); Serial.print(max_y); Serial.print("), z("); Serial.print(min_z); Serial.print("/"); Serial.print(max_z); Serial.println(")");

}

We declare variables for the minimum and maximum values of all three axes, and we initialize them with numbers that are definitely out of the sensor’s range (-1000 and 1000). In the loop function, we permanently measure the acceleration of all three axes and adjust the minimum and maximum values accordingly.

Compile and upload the sketch, then move the breadboard with the sensor in all directions, and then tilt it around all axes. Move it slowly, move it fast, tilt it slowly, and tilt it fast. Be careful when moving and rotating the breadboard that you don’t accidentally loosen a connection.

After a short while, the minimum and maximum values will stabilize, and you should get output like this:

x(247/649), y(253/647), z(278/658)

Write down these values, because we’ll need them later, and you’ll probably need them when you do your own sensor experiments.

Now let’s see how to get rid of the jitter. In principle, it’s simple. Instead of returning the acceleration data immediately, we collect the last readings and return their average. This way, small changes will be ironed out. The code looks as follows:

report erratum • discuss

Finding and Polishing Edge Values • 105

MotionSensor/Buffering/Buffering.ino

Line 1 const unsigned int X_AXIS_PIN = 2;

-const unsigned int Y_AXIS_PIN = 1;

-const unsigned int Z_AXIS_PIN = 0;

-const unsigned int NUM_AXES = 3;

5 const unsigned int PINS[NUM_AXES] = {

-X_AXIS_PIN, Y_AXIS_PIN, Z_AXIS_PIN

-};

-const unsigned int BUFFER_SIZE = 16;

-const unsigned int BAUD_RATE = 9600;

10

int

buffer[NUM_AXES][BUFFER_SIZE];

-

int

buffer_pos[NUM_AXES] = { 0 };

-

 

 

-void setup() {

-Serial.begin(BAUD_RATE);

15

}

-

 

-int get_axis(const int axis) {

-delay(1);

-buffer[axis][buffer_pos[axis]] = analogRead(PINS[axis]); 20 buffer_pos[axis] = (buffer_pos[axis] + 1) % BUFFER_SIZE;

-long sum = 0;

-for (unsigned int i = 0; i < BUFFER_SIZE; i++)

-sum += buffer[axis][i];

-return round(sum / BUFFER_SIZE);

25

}

-

 

-int get_x() { return get_axis(0); }

-int get_y() { return get_axis(1); }

-int get_z() { return get_axis(2); }

30 void loop() {

-Serial.print(get_x());

-Serial.print(" ");

-Serial.print(get_y());

-Serial.print(" ");

35

Serial.println(get_z());

-

}

 

As usual, we define some constants for the pins we use first. This time, we

 

also define a constant named NUM_AXES that contains the number of axes we

 

are measuring. We also have an array named PINS that contains a list of the

 

pins we use. This will help us keep our code more generic later.

 

In line 10, we declare buffers for all axes. They will be filled with the sensor

 

data we measure, so we can calculate average values when we need them.

 

We have to store our current position in each buffer, so in line 11, we define

 

an array of buffer positions.

 

setup only initializes the serial port; the real action takes place in get_axis.

report erratum • discuss

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]