Sunteți pe pagina 1din 7

ARDUINO SENSORS

Standard
Last week I designed a PCB based on the power supply circuit I discussed in
the last blog post and I sent it to get manufactured. In the meantime Ive
been testing a resistive current sensor I made, and I also found this board
with all kinds of sensors I made a while back for a robot project. It has an
accelerometer&gyroscope (MPU6050), a photocell, thermistor and a distance
sensor (HC-SR04).

Im using the Arduino Mega for this project. The accelerometer


communicates via I2C and it uses the SDA and SCL pins on the
Arduino. *Note: In the Mega the SDA and SCL pins are at a different location
than the Arduino Uno (pin 20 &

21).
s the
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

Here
code for this project.
//Add Arduino Wire.h library, accelerometer uses I2C to communicate
#include "Wire.h"
//Install I2Cdev.h and MPU6050 library (.h and .c files)
//
#include "I2Cdev.h"
#include "MPU6050.h"
#include "math.h"
// MPU Accelerometer + Gyro values
MPU6050 accelgyro;
int ax, ay, az;
int gx, gy, gz;
int anglex = 0;
int angley = 0;
int anglez = 0;
int x = 0;
int y = 0;
int z = 0;
double xa = 0;
double ya = 0;
double alpha = 0;
double gyrox = 0;
double gyroy = 0;
double gyroz = 0;
double zz = 0;
unsigned long timer;
//Distance Sensor Values

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

#define trigPin 22
#define echoPin 23
double duration, distance;
double fdist = 0;
//Photoresistor
#define resPin A0
double lum = 0;
//temperature sensor
#define tmpPin A1
double deg = 0;

void setup() {
// initiate I2C
Wire.begin();
// initialize serial communication
// baud rate of 9600 works well
Serial.begin(9600);
// initialize device
Serial.println("Initializing I2C...");
accelgyro.initialize();
// verify connection
Serial.println("Testing device...");
Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "M
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(resPin, INPUT);
pinMode(tmpPin, INPUT);
//Set Timer, refresh value @ every "loop"
timer = micros();
}
void loop() {
// read accel/gyro values
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
gyrox = gx/131; //sensitivity 250, look at data sheet
gyroy = gy/131;
gyroz = gz/131;
anglex = ax - 300;
angley = ay - 300;
anglez = az - 16400;
//map values in the range of -90 to +90 degrees
x = map(anglex,-16300,16300,-90,90);
y = map(angley,-17000,17000,-90,90);
z = map(anglez,-2000,2000,-90,90);
alpha = 0.1;
// Complementary filter
xa = (1-alpha)*(xa+gyrox*(double((micros()-timer)/1000000))) + alpha*x;
ya = (1-alpha)*(ya+gyroy*(double((micros()-timer)/1000000))) + alpha*y;
zz += gyroz*((double)(micros()-timer)/1000000); // rotation around z-axis
Serial.print("x");
Serial.print(xa);
Serial.print(",");

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

Serial.print("y");
Serial.print(ya);
Serial.print(",");
Serial.print("r");
Serial.print(zz);
Serial.print(",");
timer = micros();
// read light sensor
double lm = double(analogRead(resPin))/4.00; // convert from 0-1023 to 0-255
lum = lum*0.75 + 0.25*lm;
Serial.print("lum");
Serial.print(lum);
Serial.print(",");

//read temperature sensor Vishay BC2396CT-ND , NTCLE100E3103JT2 - see datasheet


double tmp = double(analogRead(tmpPin));
//voltage divider 10K*1023/(vout) - 10K
double R = log(((10230000/tmp)-10000)/10000); // R/Rref, see datasheet
deg = 1/(0.003354016 + 0.0002569850*R + 0.000002620131*pow(R,2) + 0.000000063830
Serial.print(deg-273.15); Serial.print("C");
Serial.print(",");

//Distance Sensor
digitalWrite(trigPin,LOW);
delay(2);
digitalWrite(trigPin, HIGH);
delay(7);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin,HIGH);
distance = (duration/2)/29.1;
//final distance
//stabilize signal, sort of Complementary Filter
fdist = 0.75*fdist + 0.25*distance;
Serial.print(fdist); Serial.println("cm");
delay(10);

116
117
118
119
120
Ill explain some of the key lines in the code above. Lets starting with the
accelerometer/gyroscope module. The MPU6050 library provides functions
that allow us to capture the x,y and z values of the accelerometer. However,
these values are not very useful to us in their raw form. We need to map
them to an angle value and also filter the values to eliminate excessive
noise. In my case, the x values I acquired were in the range of -16300 < x <
16300. The following line of code converts the x value to an angle.
x = map(anglex,-16300,16300,-90,90);
1
Now that we have a meaningful x value we need to introduce a filter into our
code to eliminate the noise. Heres a comparison of the x values with and
without a
filter.

There are a number of different filters you can use such as Kalman,
Complementary, Extended Kalman etc. For this example well use the
Complementary filter since its the simplest and it does an adequate job as
seen in the figure above. You can noticed the HUGE spike in the graph, which

does not appear in the filtered values. The complementary filter equation is
as such:
where alpha is typically a small value (0.1, 0.05, 0.01 etc.).*Note: there is a
small delay between the raw angle and its filtered value. This can be
minimized by lowering thealpha value (ex. alpha = 0.05).
1
alpha = 0.1;
// Complimentary filter
2
xa = (1-alpha)*(xa+gyrox*(double((micros()-timer)/1000000))) + alpha*x;
3
This code will give you a good approximation of the tilt/rotation of the
platform. Next, both the photocell and thermistor are connected to
analogRead pins on the Arduino via a voltage divider provided by a 10k
resistor connected in series.

The thermistor has a


very specific formula that can be found on the datasheet. In this case Im
using a Vishay BC2396CT-ND. The formula corresponds to the Steinhart-Hart
equation:
The
datasheet gives the values of the coefficients A,B,C and D. Lastly, were
using an ultrasonic distance sensor. To get the distance the sensor sends a
pulse and measures the time it takes for the pulse to return.

Here, again, Im
using a complementary type filter to stabilize the values read by the sensor.

This is it! Heres the result:

S-ar putea să vă placă și