Difference between revisions of "Arduino - Een 3 assige versnellingsmeter (ADXL345)"

From SPAD-it Wiki
Jump to: navigation, search
(Created page with "De ADXL345 is een chip die versnellingen kan meten in drie richtingen. Het principe van deze metingen is dat binnen in de chip kleine mechanische onderdeeltjes, in principe be...")
 
Line 1: Line 1:
De ADXL345 is een chip die versnellingen kan meten in drie richtingen. Het principe van deze metingen is dat binnen in de chip kleine mechanische onderdeeltjes, in principe bestaande uit gewichtjes die verend zijn opgehangen. De mate van vering wordt gemeten. De chip is daarmee een electro-mechanisch element. Dit soort elementen worden aangeduidt als '''MEMS''' - Micro-ElektroMechanisch Systeem. Als de chip versnelt zakken een of meer veertjes iets meer door. Ook de zwaartekracht zorgt voor het doorzakken van de veertjes, zodat ook de zwaartekracht wordt gemeten als versnelling. Dit is niet zo vreemd omdat de zwaaartekracht ook wel de valversnelling wordt genoemd. De zwaartekracht zorgt voor een valversnelling van 9,8 m/s2.  
+
De ADXL345 is een chip die versnellingen kan meten in drie richtingen. Zoals gezegd meet de chip versnellingen. Een versnelling is natuurlijk een verandering van snelheid. De mate van versnelling wordt uitgedrukt als de verandering van snelheid per seconde. Omdat snelheid wordt uitgedrukt als meter per seconde (m/s) wordt versnelling uitgedrukt als m/s2.  
  
Naast het meten van versnellingen in alle drie de richtingen, heeft de chip een aparte detector om vrije val te detecteren (wegvallen van de zwaartekracht - in feite alle krachten), en een schok-detector.  
+
Het principe van deze metingen is dat binnen in de chip kleine mechanische onderdeeltjes zitten waarvan de beweging elektronisch wordt waargenomen. Bij een versnellingsmeting gaat het dan bijvoorbeeld om een gewichtje dat verend is opgehangen. De mate van vering wordt gemeten. De chip is daarmee een electro-mechanisch element. Dit soort elementen worden aangeduidt als '''MEMS''' - Micro-ElektroMechanisch Systeem. Als de chip versnelt, bewegen de verend opgehangen gewichtjes trager mee en zakken dus iets meer door in hun vering. Ook de zwaartekracht zelf heeft dit effect, zodat ook de zwaartekracht wordt gemeten als ''versnelling''. Dit is niet zo vreemd omdat de zwaaartekracht door natuurkundigen ook wel ''de valversnelling'' wordt genoemd. De zwaartekracht zorgt voor een valversnelling van 9,8 m/s2.  
  
De chip  
+
Naast het meten van versnellingen in alle drie de richtingen, heeft de chip een aparte detector om vrije val te detecteren (wegvallen van de zwaartekracht - in feite alle krachten), en een voor het detecteren van een klik en dubbel-klik detector (zoals van een muis).
 +
 
 +
De chip is zeer zuinig met energie (2,5V, 40μA). Zijn meetnauwkeurigheid is nagenoeg onafhankelijk van de grootte van het meetbereik: ongeveer 0.002 m/s2. Het kleinste meetbereik gaat tot 2G (tot 20 m/s2) en het grootste meetbereik is 16G (ongeveer 160 m/s2). Zoals gezegd leven we op Aarde continu met 1G. Een raket-auto die met 16G zou optrekken, zou van 0 tot 100km/h gaan in minder dan 0,2 seconde! De beste sportauto doet er tien keer langer over. Daarbij raken straaljagerpiloten bewusteloos als ze te scherpe bochten maken. Dat gevaar ontstaat vanaf ongeveer 5G. 16G is dus een behoorlijke range. De meetnauwkeurigheid van 0.002 m/s2 is ook mooi. Als je met zo'n snelheid "versnelt" duurt het meer dan 10 minuten voor je 5 km/h gaat.
  
 
Andere chips
 
Andere chips
   ITG3200 (gyro)
+
  ADXL335 (alternatieve versnellingsmeter)
 +
   ITG3200/ITG3205, IDG500, MPU6050 (gyroscoop)
 
   HMC5883L (Aardmagneetveld)
 
   HMC5883L (Aardmagneetveld)
 +
  BMP280 (Barometrische luchtdruk = hoogtemeting)
 +
 +
Als je wat meer wilt lezen kun je hier eens kijken: https://www.sparkfun.com/pages/accel_gyro_guide. Merk wel op dat de hier aangeboden modules relatief duur zijn. Een ADXL345 module uit China kost minder dan €3,00.
  
  
Line 13: Line 19:
  
 
Extra benodigdheden:
 
Extra benodigdheden:
*1 onderdeel zus
+
*1 ADXL345 module
*8 onderdelen zo van 18kΩ
 
  
 
{|class="wikitable"
 
{|class="wikitable"
 
|-
 
|-
|[[Bestand:naam bestand.png]]
+
|[[File:ADXL345.png]]
 
|-
 
|-
|Beschrijving bovenstaande figuur
+
|De schakeling voor de ADXL345; Groen=SDA en Oranje=SCL|}
|}
 
  
 
===Het programma===
 
===Het programma===
  
 
<pre>
 
<pre>
Hier het programma
+
#include <Wire.h>
 +
// Registers for ADXL345
 +
#define ADXL345_ADDRESS (0xA6 >> 1)  // address for device is 8 bit but shift to the
 +
                                    // right by 1 bit to make it 7 bit because the
 +
                                    // wire library only takes in 7 bit addresses
 +
#define ADXL345_REGISTER_XLSB (0x32)
 +
 
 +
int accelerometer_data[3];
 +
 
 +
// void because this only tells the chip to send data to its output register
 +
// writes data to the slave's buffer
 +
void i2c_write(int address, byte reg, byte data) {
 +
  // Send output register address
 +
  Wire.beginTransmission(address);
 +
  // Connect to device
 +
  Wire.write(reg);
 +
  // Send data
 +
  Wire.write(data); //low byte
 +
  Wire.endTransmission();
 +
}
 +
 
 +
// void because using pointers
 +
// microcontroller reads data from the sensor's input register
 +
void i2c_read(int address, byte reg, int count, byte* data) {
 +
  // Used to read the number of data received
 +
  int i = 0;
 +
  // Send input register address
 +
  Wire.beginTransmission(address);
 +
  // Connect to device
 +
  Wire.write(reg);
 +
  Wire.endTransmission();
 +
 
 +
  // Connect to device
 +
  Wire.beginTransmission(address);
 +
  // Request data from slave
 +
  // Count stands for number of bytes to request
 +
  Wire.requestFrom(address, count);
 +
  while(Wire.available()) // slave may send less than requested
 +
  {
 +
    char c = Wire.read(); // receive a byte as character
 +
    data[i] = c;
 +
    i++;
 +
  }
 +
  Wire.endTransmission();
 +
}
 +
 
 +
void init_adxl345() {
 +
  byte data = 0;
 +
 
 +
  i2c_write(ADXL345_ADDRESS, 0x31, 0x0B);  // 13-bit mode  +_ 16g
 +
  i2c_write(ADXL345_ADDRESS, 0x2D, 0x08);  // Power register
 +
 
 +
  i2c_write(ADXL345_ADDRESS, 0x1E, 0x00);  // x
 +
  i2c_write(ADXL345_ADDRESS, 0x1F, 0x00);  // Y
 +
  i2c_write(ADXL345_ADDRESS, 0x20, 0x05);  // Z
 +
 +
  // Check to see if it worked!
 +
  i2c_read(ADXL345_ADDRESS, 0X00, 1, &data);
 +
  if(data==0xE5)
 +
    Serial.println("it work Success");
 +
  else
 +
    Serial.println("it work Fail");
 +
}
 +
 
 +
void read_adxl345() {
 +
  byte bytes[6];
 +
  memset(bytes,0,6);
 +
 
 +
  // Read 6 bytes from the ADXL345
 +
  i2c_read(ADXL345_ADDRESS, ADXL345_REGISTER_XLSB, 6, bytes);
 +
  // Unpack data
 +
  for (int i=0;i<3;++i) {
 +
    accelerometer_data[i] = (int)bytes[2*i] + (((int)bytes[2*i + 1]) << 8);
 +
  }
 +
}
 +
 
 +
void setup() {
 +
  Wire.begin();                // start I2C communicatie
 +
  Serial.begin(9600);          // start de seriele communicatie met de computer
 +
  for(int i=0; i<3; ++i) {    // zet voor alle richtingen de buffer met meetdata op 0
 +
    accelerometer_data[i] = 0;
 +
  }
 +
  init_adxl345();              // zie de void() functie hierboven
 +
}
 +
 
 +
void loop() {
 +
  read_adxl345();
 +
  Serial.print("ACCEL: ");
 +
  Serial.print(float(accelerometer_data[0])*3.9/1000);  //3.9mg/LSB scale factor in 13-bit mode
 +
  Serial.print("\t");
 +
  Serial.print(float(accelerometer_data[1])*3.9/1000);
 +
  Serial.print("\t");
 +
  Serial.print(float(accelerometer_data[2])*3.9/1000);
 +
  Serial.print("\n");
 +
  delay(100);
 +
}
 
</pre>
 
</pre>
  

Revision as of 21:47, 8 January 2018

De ADXL345 is een chip die versnellingen kan meten in drie richtingen. Zoals gezegd meet de chip versnellingen. Een versnelling is natuurlijk een verandering van snelheid. De mate van versnelling wordt uitgedrukt als de verandering van snelheid per seconde. Omdat snelheid wordt uitgedrukt als meter per seconde (m/s) wordt versnelling uitgedrukt als m/s2.

Het principe van deze metingen is dat binnen in de chip kleine mechanische onderdeeltjes zitten waarvan de beweging elektronisch wordt waargenomen. Bij een versnellingsmeting gaat het dan bijvoorbeeld om een gewichtje dat verend is opgehangen. De mate van vering wordt gemeten. De chip is daarmee een electro-mechanisch element. Dit soort elementen worden aangeduidt als MEMS - Micro-ElektroMechanisch Systeem. Als de chip versnelt, bewegen de verend opgehangen gewichtjes trager mee en zakken dus iets meer door in hun vering. Ook de zwaartekracht zelf heeft dit effect, zodat ook de zwaartekracht wordt gemeten als versnelling. Dit is niet zo vreemd omdat de zwaaartekracht door natuurkundigen ook wel de valversnelling wordt genoemd. De zwaartekracht zorgt voor een valversnelling van 9,8 m/s2.

Naast het meten van versnellingen in alle drie de richtingen, heeft de chip een aparte detector om vrije val te detecteren (wegvallen van de zwaartekracht - in feite alle krachten), en een voor het detecteren van een klik en dubbel-klik detector (zoals van een muis).

De chip is zeer zuinig met energie (2,5V, 40μA). Zijn meetnauwkeurigheid is nagenoeg onafhankelijk van de grootte van het meetbereik: ongeveer 0.002 m/s2. Het kleinste meetbereik gaat tot 2G (tot 20 m/s2) en het grootste meetbereik is 16G (ongeveer 160 m/s2). Zoals gezegd leven we op Aarde continu met 1G. Een raket-auto die met 16G zou optrekken, zou van 0 tot 100km/h gaan in minder dan 0,2 seconde! De beste sportauto doet er tien keer langer over. Daarbij raken straaljagerpiloten bewusteloos als ze te scherpe bochten maken. Dat gevaar ontstaat vanaf ongeveer 5G. 16G is dus een behoorlijke range. De meetnauwkeurigheid van 0.002 m/s2 is ook mooi. Als je met zo'n snelheid "versnelt" duurt het meer dan 10 minuten voor je 5 km/h gaat.

Andere chips

 ADXL335 (alternatieve versnellingsmeter)
 ITG3200/ITG3205, IDG500, MPU6050 (gyroscoop)
 HMC5883L (Aardmagneetveld)
 BMP280 (Barometrische luchtdruk = hoogtemeting)

Als je wat meer wilt lezen kun je hier eens kijken: https://www.sparkfun.com/pages/accel_gyro_guide. Merk wel op dat de hier aangeboden modules relatief duur zijn. Een ADXL345 module uit China kost minder dan €3,00.


De schakeling

Extra benodigdheden:

  • 1 ADXL345 module
ADXL345.png
}

Het programma

#include <Wire.h>
// Registers for ADXL345
#define ADXL345_ADDRESS (0xA6 >> 1)  // address for device is 8 bit but shift to the
                                     // right by 1 bit to make it 7 bit because the
                                     // wire library only takes in 7 bit addresses
#define ADXL345_REGISTER_XLSB (0x32)

int accelerometer_data[3];

// void because this only tells the chip to send data to its output register
// writes data to the slave's buffer
void i2c_write(int address, byte reg, byte data) {
  // Send output register address
  Wire.beginTransmission(address);
  // Connect to device
  Wire.write(reg);
  // Send data
  Wire.write(data); //low byte
  Wire.endTransmission();
}

// void because using pointers
// microcontroller reads data from the sensor's input register
void i2c_read(int address, byte reg, int count, byte* data) {
  // Used to read the number of data received
  int i = 0;
  // Send input register address
  Wire.beginTransmission(address);
  // Connect to device
  Wire.write(reg);
  Wire.endTransmission();

  // Connect to device
  Wire.beginTransmission(address);
  // Request data from slave
  // Count stands for number of bytes to request
  Wire.requestFrom(address, count);
  while(Wire.available()) // slave may send less than requested
  {
    char c = Wire.read(); // receive a byte as character
    data[i] = c;
    i++;
  }
  Wire.endTransmission();
}

void init_adxl345() {
  byte data = 0;

  i2c_write(ADXL345_ADDRESS, 0x31, 0x0B);   // 13-bit mode  +_ 16g
  i2c_write(ADXL345_ADDRESS, 0x2D, 0x08);   // Power register

  i2c_write(ADXL345_ADDRESS, 0x1E, 0x00);   // x
  i2c_write(ADXL345_ADDRESS, 0x1F, 0x00);   // Y
  i2c_write(ADXL345_ADDRESS, 0x20, 0x05);   // Z
 
  // Check to see if it worked!
  i2c_read(ADXL345_ADDRESS, 0X00, 1, &data);
  if(data==0xE5)
    Serial.println("it work Success");
  else
    Serial.println("it work Fail");
}

void read_adxl345() {
  byte bytes[6];
  memset(bytes,0,6);

  // Read 6 bytes from the ADXL345
  i2c_read(ADXL345_ADDRESS, ADXL345_REGISTER_XLSB, 6, bytes);
  // Unpack data
  for (int i=0;i<3;++i) {
    accelerometer_data[i] = (int)bytes[2*i] + (((int)bytes[2*i + 1]) << 8);
  }
}

void setup() {
  Wire.begin();                // start I2C communicatie
  Serial.begin(9600);          // start de seriele communicatie met de computer
  for(int i=0; i<3; ++i) {     // zet voor alle richtingen de buffer met meetdata op 0
    accelerometer_data[i] = 0;
  }
  init_adxl345();              // zie de void() functie hierboven
}

void loop() {
  read_adxl345();
  Serial.print("ACCEL: ");
  Serial.print(float(accelerometer_data[0])*3.9/1000);  //3.9mg/LSB scale factor in 13-bit mode
  Serial.print("\t");
  Serial.print(float(accelerometer_data[1])*3.9/1000);
  Serial.print("\t");
  Serial.print(float(accelerometer_data[2])*3.9/1000);
  Serial.print("\n");
  delay(100);
}

Uitleg

Beetje spelen

Verdiepende opdrachtjes

Navigatie