สร้างเว็บEngine by iGetWeb.com
Cart รายการสินค้า (0)

arduino ติดต่อ ADXL335

arduino ติดต่อ ADXL335

มี Sensor ชนิดนึง ที่ใช้วัดความเอียง นั้นก็คือ Accelerometer และ Gyroscope


มือใหม่หลายคนจะไม่เข้าใจถึงความแตกต่างระหว่าง Sensor สองชนิดนี้









Accelerometer คืออะไร ?


ถ้าแปลตรงตัวก็คือ Acceleration + Meter หรือมิเตอร์ความเร่ง ตามนิยามก็คือ Sensor วัดความเร่งเพิ่มขึ้น หรือลดลง (ในหน่วย m/s2)
ตย. ความเร่งของแรงโน้มถ่วงก็คือ 9.8 m/s2 หรือ a (มาจาก Acceleration) นั่นเอง


โดยหลักการทำงาน ให้นึกถึงห้องสี่เหลี่ยมเล็กๆ ที่ทุกด้านของกำแพงจะมีสปริงติดอยู่
เวลาที่ห้องนี้เอียงไปทางใดทางหนึ่ง สปริงก็จะยุบไปด้านนั้นๆ โดยติ๊ต่างว่าแรงดันของสปริงมีน้อยกว่าแรงโน้มถ่วงของโลก
และใช้วงจรไฟฟ้าในการดึง Output Analog ออกมาใช้งาน (หรือ Output Digital ซึ่งก็แล้วแต่ตัว Sensor เอง)





เราจะใช้ Accelerometer สำหรับเป็นตัวชี้ว่าอยู่ในสถานะ Static (นิ่งเฉย) หรือ Dynamic (เคลื่อนไหวทันทีทันใด หรือหยุดทันทีทันใด) นั่นทำให้ Accelerometer เป็น sensor สำหรับบอกสถานะการเอียงได้เป็นอย่างดี (Tilt Sensor)

Sensor พวกนี้ทำอะไรได้บ้าง ถ้ามองใกล้ๆ ตัวก็คือ iPhone ของพี่ๆ น้องๆ นี้แหละครับ


แล้ว Gyroscope คืออะไร ?

Sensor Gyro จะทำหน้าที่วัดความเร็วเชิงมุม ก็คือโอเมก้าในวิชาฟิสิกส์ นี้แหละ (วัตถุนี้จะหมุนรอบแกนด้วยความเร็วเท่าใด ?) พูดด้วยนิยามอาจจะไม่เข้าใจว่าต่างกันอย่างไร





ยกตัวอย่าง ถ้าเราจับ Accelerometer มาเอียงแล้ววัด Output เราจะได้ค่า ค่านึงซึ่งบ่งบอกถึงการเอียงในรูปแบบนั้นๆ ถ้าเราเปลี่ยนไปค่านี้ก็จะเปลี่ยนตาม
แต่ถ้าเราจับ Gyro มาเอียงแล้ววัด Output เราจะพบว่า Output ของ Gyro จะออกก็ต่อเมื่อเกิดการเอียง หรือกำลังจะเอียง หรือเกิดการเคลื่อนไหว (วัตถุอยู่นิ่ง Gyro วัดค่าไม่ได้ เพราะไม่มีความเร็ว)




แล้ว Gyro มีบทบาทอย่างไร ?


ในเมื่อ Accelerometer สามารถวัดความเอียงได้เรียบร้อย ไม่มีความจำเป็นจะต้องวัดความเร็วเชิงมุม ?
เพราะว่า Output ของ Accelerometer มีผลกับแรงโน้มถ่วง นั่นหมายถึงค่า Output ของ Accelerometer ไม่มีทางหยุดนิ่งเฉย แม้ปล่อยทิ้งไว้ มันก็จะวิ่งขึ้นๆ ลงๆ สั่นไปสั่นมา ต่างกับ Gyro ที่ปล่อยทิ้งไว้ค่า Output ที่ได้ก็จะนิ่ง ไม่เกิดการสั่น
และถ้าเรานำ Output ของ Gyro มาใช้กรรมวิธีการ Discrete Integral ก็จะสามารถหามุมได้ (เพราะ Output ของ Gyro เป็นความเร็วเชิงมุม)


ส่วนกรรมวิธีในการ Integral ใน MCU เราจะใช้ Discrete Integral ผมชอบพูดว่าเป็นการอินทิเกรตมือ หลักการคล้ายๆ กับการคูณใน MCU


การคูณใน MCU ทำได้โดยการบวก ไปจนครบจำนวนครั้ง การอินทิเกรตก็เหมือนกัน ให้มองกลับไปที่รากฐานการอินทิเกรต ถ้ามีกราฟมาให้มันก็คือพื้นที่ใต้กราฟ เราจะอินทิเกรตเราทำได้โดยแบ่งพื้นที่ใต้กราฟเป็นเส้นเล็กๆ แล้วหาพื้นที่เล็กๆ นั้น จากนั้นก็จับมารวมกัน


ถ้าเราแบ่งพื้นที่เล็กๆ นั้นด้วยเวลา t0, t1, t2, tn
นั่นก็คือเอาพื้นที่ ที่เวลา t0 มารวมกับพื้นที่ ที่เวลา t1 เอาพื้นที่ไปรวมกับพื้นที่ที่เวลา t2 ไล่ไปเรื่อยๆ ถึง tn โดยไม่สนใจว่าพื้นที่นั้นมีค่าเป็นบวกหรือลบ สุดท้ายแล้วคำตอบจะบอกเราเองว่าผลลัพท์ที่ได้ ชี้ไปในทิศทางใด


นี้เป็นสาเหตุให้เกิดการผสมผสานระหว่าง Sensor สองตัวนี้ ทำให้มีทฤษฎีมารองรับมากมาย อธิเช่น Kalman Filter, Complementary Filter ใช้การผสมผสานข้อดีของทั้งสอง Sensor

code ตัวอย่างที่ใช้ในการทดสอบ

int x, y, z;

void setup()
{
  Serial.begin(9600);      // sets the serial port to 9600
}

void loop()
{
  x = analogRead(0);       // read analog input pin 0
  y = analogRead(1);       // read analog input pin 1
  z = analogRead(2);       // read analog input pin 1
  Serial.print("accelerations are x, y, z: ");
  Serial.print(x, DEC);    // print the acceleration in the X axis
  Serial.print(" ");       // prints a space between the numbers
  Serial.print(y, DEC);    // print the acceleration in the Y axis
  Serial.print(" ");       // prints a space between the numbers
  Serial.println(z, DEC);  // print the acceleration in the Z axis
  delay(100);              // wait 100ms for next reading
}

อีกตัวอย่างครับ

const int xpin = 0;
const int ypin = 1;
const int zpin = 2;// analog: Z axis output from accelerometer
 
const float arduino_power_supply = 5;
const float sensor_power_supply = 3.3;
const float zero_g_bias = sensor_power_supply / 2;
  
void setup() {
  Serial.begin   (9600);
  Serial.print ("x axis g's");
  Serial.print ("\t");
  Serial.print ("y axis g's");
  Serial.print ("\t");
  Serial.print ("z axis g's");
  Serial.println();
  delay(1000);
}
void loop() {
  float voltage_x = (analogRead(xpin)) * arduino_power_supply / 1024;
  float x = (voltage_x - zero_g_bias) * 1000 / 330;
  Serial.print(x);
  Serial.print ("\t");
  
  float voltage_y = (analogRead(ypin)) * arduino_power_supply / 1024;
  float y = (voltage_y - zero_g_bias) * 1000 / 330;
  Serial.print(y);
  Serial.print ("\t");
  
  float voltage_z = (analogRead(zpin)) * arduino_power_supply / 1024;
  float z = (voltage_z - zero_g_bias) * 1000 / 330;
  Serial.print(z);
  
  Serial.println();
  delay(200);
}



ค่าที่แสดงออก มา

//===================================

x axis g's      y axis g's      z axis g's
3.53      3.45      4.04
3.61      3.06      2.98
1.95      1.68      0.80
0.60      1.21      1.08
0.62      0.85      1.50
1.47      0.86      1.03
1.91      1.61      0.86
0.88      1.09      0.62
0.33      0.55      1.03
0.25      0.16      0.67
0.85      0.44      0.21
1.09      0.93      0.25
0.62      1.09      0.78
0.18      0.39      1.11
0.51      0.08      0.44
1.01      0.70      0.10
0.96      1.08      0.59
0.36      0.62      1.01
0.25      0.20      0.73
0.44      0.96      0.90
0.12      0.33      0.96
0.82      0.16      0.31
1.14      0.83      0.13
0.47      1.03      0.75
0.13      0.34      1.06
0.59      0.08      0.38
1.04      0.73      0.07
0.88      1.12      0.68
-0.03      0.20      0.55
-0.44      -0.42      0.12
0.39      -0.05      0.12
0.07      -0.16      -0.58
0.85      0.72      0.23
0.65      1.03      0.93
0.05      0.16      0.57
-1.81      -2.29      -1.98
-0.55      -1.01      -0.86
0.23      0.00      -0.50

view