Ho usato il listato presente nella pagina che hai postato...
/*
Copyright (c) 2010-2011 George Rhoten
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
If you need some reference material take a look at the following:
Instrumentation in Earthquake Seismology (Modern Approaches in Geophysics)
by Jens Havskov, Gerardo Alguacil
BMA180 digital, triaxial acceleration sensor data sheet
by Bosch Sensortec
The original source code can be found at:
http://www.centralnexus.com/seismograph/details_bma180.html
*/
#include <Wire.h>
// ADXL345
#define DEVICE ((byte)0x40) //BMA180 device address
#define DATA_X0 0x02 //X-Axis Data 0
#define DATA_X1 0x03 //X-Axis Data 1
#define DATA_Y0 0x04 //Y-Axis Data 0
#define DATA_Y1 0x05 //Y-Axis Data 1
#define DATA_Z0 0x06 //Z-Axis Data 0
#define DATA_Z1 0x07 //Z-Axis Data 1
#define DATA_TEMP 0x08 //Temperature
#define SOFT_RESET 0x10 //soft_reset
#define SOFT_RESET_VAL 0xB6 //soft_reset value to reset
#define AXIS_SHIFT 2 //Amount to right shift data. The first 2 bits are status bits.
// USGS suggests rates of 20, 40 or 200 samples per second for natural earthquakes.
//#define DELAY_RATE 9990 //~100Hz
//#define DELAY_RATE 6600 //~150Hz
#define DELAY_RATE 4993 //~200Hz
// LED
#define COMMON_ANODE 4
#define RED_PIN 3
#define BLUE_PIN 5
#define GREEN_PIN 6
#define LED_VALUE_SHIFT 4
#define GRAVITY 255
#define ANALOG_MAX 0xFF
#define USE_LED 1
/**
* The value in relation to 0xFF within the range value.
*/
static byte pinMagnitudeRangeToTop(byte range, int value) {
if (value < 0) {
value = -value;
}
if (value > 255) {
return (byte)ANALOG_MAX - range;
}
return (byte)ANALOG_MAX - (byte)(((float)value / (float)GRAVITY) * (float)range);
}
//Writes val to address register on device
static void writeTo(byte address, byte val) {
Wire.beginTransmission(DEVICE); //start transmission to device
Wire.send(address); // send register address
Wire.send(val); // send value to write
Wire.endTransmission(); //end transmission
}
//reads num bytes starting from address register on device in to buff array
static void readFrom(byte address, byte num, byte *buff) {
Wire.beginTransmission(DEVICE); //start transmission to device
Wire.send(address); //sends address to read from
Wire.endTransmission(); //end transmission
Wire.requestFrom(DEVICE, num); // request num bytes from device
num = Wire.available(); //device may send less than requested (abnormal)
while(num-- > 0) {
*(buff++) = Wire.receive(); // receive a byte
}
}
/**
* Writes val to address register on device if it's different from
* the current value. This decreases the wear and tear on the EEPROM.
*/
static void writeOptionallyTo(byte address, byte val, byte mask) {
byte value = 0;
readFrom(address, sizeof(value), &value);
if ((value & mask) != (val & mask)) {
// Keep the unmasked values, and changed the masked values.
writeTo(address, (value & ~mask) | (val & mask));
}
}
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(115200); // start serial for output
Serial.flush();
// Wait for readings to settle down.
// 10ms Pause is required to write registers.
delay(15);
writeOptionallyTo(0x0D, 0x10, 0x10); // Enable register write
// I can't figure out how to modify the EEPROM.
// So we reset upon startup.
// Change calibration values based on new mode.
// Each chip will need their own calibration.
// Note: some offset values affect the spikiness of the values. You should test your values.
writeOptionallyTo(0x3A, 0x76, 0xFF); // original offset MSB z=0x78 when mode_config=0
writeOptionallyTo(0x39, 0x5C, 0xFF); // original offset MSB y=0x60 when mode_config=0
writeOptionallyTo(0x38, 0x6D, 0xFF); // original offset MSB x=0x70 when mode_config=0
writeOptionallyTo(0x36, 0x7C, 0xFF); // original offset LSB z=0x4, y=0xC when mode_config=0
// Need a range of existing gravity + 1 G movment to get up to a 9.0M earthquake.
writeOptionallyTo(0x35, 0xC4, 0xFF); // original offset LSB x=0x1, range+12bit=0x4 when mode_config=0
writeOptionallyTo(0x30, 0x01, 0x03); // Change mode_config to lower noise mode
writeOptionallyTo(0x21, 0x00, 0x04); // Turn off adv_int
/* Earthquakes have a nominal frequency range of 0.001–50 Hz. The P and S
* waves of >2.0M earthquakes usually have a frequency of 0.1-10 Hz. The
* higher frequencies are attenuated by the bedrock. So you need to be
* close to the epicenter to measure the higher frequencies. In order to
* accurately record the lower frequencies, the bandwidth measurement must
* be lowered in the sensor. When equal to 0x8 or 0x9, the gravity will be
* cancelled out.
*/
writeOptionallyTo(0x20, 0x20, 0xF0); // Change bandwidth. 0x2=40Hz 0x3=75Hz Originally 0x4
writeOptionallyTo(0x0D, 0x00, 0x10); // Disable register write for protection
#if USE_LED
//3 color LED
pinMode(COMMON_ANODE, OUTPUT);
digitalWrite(COMMON_ANODE, HIGH);
pinMode(RED_PIN, OUTPUT);
digitalWrite(RED_PIN, HIGH);
pinMode(GREEN_PIN, OUTPUT);
digitalWrite(GREEN_PIN, HIGH);
pinMode(BLUE_PIN, OUTPUT);
digitalWrite(BLUE_PIN, HIGH);
#endif
}
void loop()
{
// 2 byte endian marker
// 6 byte buffer for saving data read from the device
// 2 byte checksum in case there is a reset in the middle of a packet.
int axis[5] = {0x8081, 0, 0, 0, 0};
// There are 1,000,000 microseconds per second,
// and we want to sample about 200 per second.
// This gives us about the right rate with the rest of the overhead.
delayMicroseconds(DELAY_RATE - (int)(micros() % DELAY_RATE));
// Each axis reading comes in 14 bit resolution (2 bytes little endian).
readFrom(DATA_X0, 6, (byte*)(axis+1)); //read the acceleration data
// Remove status and 0 bits
axis[1] = axis[1] >> AXIS_SHIFT;
axis[2] = axis[2] >> AXIS_SHIFT;
axis[3] = axis[3] >> AXIS_SHIFT;
// Calculate checksum.
axis[4] = axis[1] + axis[2] + axis[3];
// Write whole packet.
Serial.write((byte *)axis, sizeof(axis));
#if USE_LED
analogWrite(RED_PIN, pinMagnitudeRangeToTop(0xFF, axis[1]>>LED_VALUE_SHIFT));
analogWrite(GREEN_PIN, pinMagnitudeRangeToTop(0xFF, axis[2]>>LED_VALUE_SHIFT));
analogWrite(BLUE_PIN, pinMagnitudeRangeToTop(0xFF, axis[3]>>LED_VALUE_SHIFT));
#endif
}