/************************************************************************ * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU License V2. * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License, version 2 for more details * * * * Bare bones ADXL345 i2c example for Arduino 1.0 * * by Jens C Brynildsen * * This version is not reliant of any external lib * * (Adapted for Arduino 1.0 from http://code.google.com/p/adxl345driver)* * * * Demonstrates use of ADXL345 (using the Sparkfun ADXL345 breakout) * * with i2c communication. Datasheet: * * http://www.sparkfun.com/datasheets/Sensors/Accelerometer/ADXL345.pdf * * If you need more advanced features such as freefall and tap * * detection, check out: * * https://github.com/jenschr/Arduino-libraries * ***********************************************************************/ //#include //SoftwareSerial Library #include //USIWire library #define output(directions,pin) (directions |= pin) // set port direction for output #define set(port,pin) (port |= pin) // set port pin #define clear(port,pin) (port &= (~pin)) // clear port pin #define pin_test(pins,pin) (pins & pin) // test for port pin #define bit_test(byte,bit) (byte & (1 << bit)) // test for bit set #define bit_delay_time 104 // bit delay for 9600 with overhead #define bit_delay() _delay_us(bit_delay_time) // RS232 bit delay #define half_bit_delay() _delay_us(bit_delay_time/2) // RS232 half bit delay #define char_delay() _delay_ms(10) // char delay #define serial_port PORTB #define serial_direction DDRB #define serial_pins PINB #define serial_pin_in (1 << PB0) #define serial_pin_out (1 << PB1) unsigned long startMillis; //some global variables available anywhere in the program unsigned long currentMillis; const unsigned long period = 1000; //the value is a number of milliseconds const byte redPin = 2; //red LED const byte bluePin = 3; //blue LE //SoftwareSerial MySerial(10, 9); // RX, TX #define DEVICE (0x53) // Device address as specified in data sheet byte _buff[6]; char _serial[50]; char POWER_CTL = 0x2D; //Power Control Register char DATA_FORMAT = 0x31; char DATAX0 = 0x32; //X-Axis Data 0 char DATAX1 = 0x33; //X-Axis Data 1 char DATAY0 = 0x34; //Y-Axis Data 0 char DATAY1 = 0x35; //Y-Axis Data 1 char DATAZ0 = 0x36; //Z-Axis Data 0 char DATAZ1 = 0x37; //Z-Axis Data 1 int x,y,z; void put_char(volatile unsigned char *port, unsigned char pin, char txchar) { // // send character in txchar on port pin // assumes line driver (inverts bits) // // start bit // clear(*port,pin); bit_delay(); // // unrolled loop to write data bits // if bit_test(txchar,0) set(*port,pin); else clear(*port,pin); bit_delay(); if bit_test(txchar,1) set(*port,pin); else clear(*port,pin); bit_delay(); if bit_test(txchar,2) set(*port,pin); else clear(*port,pin); bit_delay(); if bit_test(txchar,3) set(*port,pin); else clear(*port,pin); bit_delay(); if bit_test(txchar,4) set(*port,pin); else clear(*port,pin); bit_delay(); if bit_test(txchar,5) set(*port,pin); else clear(*port,pin); bit_delay(); if bit_test(txchar,6) set(*port,pin); else clear(*port,pin); bit_delay(); if bit_test(txchar,7) set(*port,pin); else clear(*port,pin); bit_delay(); // // stop bit // set(*port,pin); bit_delay(); // // char delay // bit_delay(); } void put_string(volatile unsigned char *port, unsigned char pin, char *str) { // // print a null-terminated string // static int index; index = 0; while (1) { if (str[index] == 0) break; put_char(port, pin, str[index]); ++index; } } void setup() { set(serial_port, serial_pin_out); output(serial_direction, serial_pin_out); Wire.begin(); // join i2c bus (address optional for master) // MySerial.begin(9600); // start serial for output. Make sure you set your Serial Monitor to the same! put_string(&serial_port, serial_pin_out, "init\n" ); //Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register. writeTo(DATA_FORMAT, 0x01); //Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register. writeTo(POWER_CTL, 0x08); startMillis = millis(); } void loop() { readAccel(); // read the x/y/z tilt // // not sending any results to the serial port right now // //sprintf(_serial, "x: %d,y: %d,z: %d\n",x,y,z); //put_string(&serial_port, serial_pin_out, _serial ); if (y>-20 ) { //movement detected startMillis = millis(); digitalWrite(bluePin, HIGH); } else { // no movement yet if (millis() - startMillis > period) { digitalWrite(bluePin, LOW); digitalWrite(redPin, HIGH); } } delay(500); // only read every 0,5 seconds } void readAccel() { uint8_t howManyBytesToRead = 6; readFrom( DATAX0, howManyBytesToRead, _buff); //read the acceleration data from the ADXL345 // each axis reading comes in 10 bit resolution, ie 2 bytes. Least Significat Byte first!! // thus we are converting both bytes in to one int x = (((int)_buff[1]) << 8) | _buff[0]; y = (((int)_buff[3]) << 8) | _buff[2]; z = (((int)_buff[5]) << 8) | _buff[4]; } void writeTo(byte address, byte val) { Wire.beginTransmission(DEVICE); // start transmission to device Wire.write(address); // send register address Wire.write(val); // send value to write Wire.endTransmission(); // end transmission } // Reads num bytes starting from address register on device in to _buff array void readFrom(byte address, int num, byte _buff[]) { Wire.beginTransmission(DEVICE); // start transmission to device Wire.write(address); // sends address to read from Wire.endTransmission(); // end transmission Wire.beginTransmission(DEVICE); // start transmission to device Wire.requestFrom(DEVICE, num); // request 6 bytes from device int i = 0; while(Wire.available()) // device may send less than requested (abnormal) { _buff[i] = Wire.read(); // receive a byte i++; } Wire.endTransmission(); // end transmission }