OBD Source Code -Section 1- Without Car / Section 2 - With car
Dependencies: mbed
accelerometer.cpp
- Committer:
- bala0x07
- Date:
- 2017-02-27
- Revision:
- 0:e36d80703ed0
File content as of revision 0:e36d80703ed0:
#include "mbed.h"
#include "obd_libraries.h"
#include "accelerometer.h"
#include "common_definitions.h"
#define IDLE 0
#define ACTIVE 1
I2C i2c(PB_9, PB_8);
Serial pc(USBTX, USBRX);
InterruptIn double_tap(PC_1); // Pin assignment may vary
InterruptIn inactivity(PC_0); // Pin assignment may vary
DigitalOut led(LED1);
// INTERFACING ADXL345 ACCELEROMETER USING I2C
/*
NOTE :
Due to communication speed limitations, the maximum output
data rate when using 400 kHz I2C is 800 Hz and scales linearly with
a change in the I2C communication speed
*/
//InterruptIn activity(PB_0); // Button B1 (Blue)
const int slave_address_acc = 0xA6;
char axis_data[6] = {0,0,0,0,0,0};
int16_t x_axis, y_axis, z_axis;
char interrupt_source[2];
char axis_data_start_address[2];
char intr_source_address[2] = {0x30, 0};
char all_interrupt_clear_command[2] = {0x2E, 0x00};
char all_interrupt_enable_command[2] = {0x2E, 0x18};
char activity_interrupt_disable_command[2] = {0x2E, 0x28};
char inactivity_interrupt_disable_command[2] = {0x2E, 0x30};
char accelerometer_status_registered = 0;
unsigned int interrupt_source_duplicate;
char previous_state = 0;
char current_state = 0;
extern long vehicle_speed;
char current_speed, previous_speed;
char speed_threshold = 10;
//----------------------------------------------------------------------------------------------------------
void char_to_int(char data_fetched)
{
unsigned int shifter;
interrupt_source_duplicate = 0x00;
for(shifter = 0; shifter < 8; shifter++)
{
interrupt_source_duplicate |= (((data_fetched >> shifter) & 0x01) << shifter); // Converts char data into unsigned int
}
}
//----------------------------------------------------------------------------------------------------------
void print_data_bits(char data_fetched)
{
unsigned int shifter;
for(shifter = 0; shifter < 8; shifter++)
{
pc.printf("%d",((data_fetched&0x80)>>7));
data_fetched = data_fetched << 1;
}
pc.printf("\r\n\r\n");
}
//----------------------------------------------------------------------------------------------------------
/*----------------------------------------------------------------------------------------------------------
AS FAR NOW, ONE INTERRUPT PIN (INT1) OF ACCELEROMETER IS NOT WORKING
USE THIS TO CUSTOMIZE ACCELEROMETER WHEN THAT PIN IS WORKING
void use_me_later() {
char count;
for(count = 0; count < 10; count++)
{
led = !led;
wait(0.10);
}
}
----------------------------------------------------------------------------------------------------------*/
void interrupt_sudden_jerk()
{
char count;
i2c.write(slave_address_acc, all_interrupt_clear_command, 2);
pc.printf("~~~ ENTERED SUDDEN JERK CONDITION ~~~\r\n\r\n");
for(count = 0; count < 2; count++)
{
led = 1;
wait(2);
led = 0;
wait(1);
}
i2c.write(slave_address_acc, all_interrupt_enable_command, 2);
}
//*********************************************************************************************************
// THE FOLLWOING CODE BLOCK IS THE MULITIPLEXED ISR FOR BOTH ACTIVITY & INACTIVITY INTERRUPT
void interrupt_activity_inactivity()
{
char count;
// The following statement disables all interrupts since no other interrupts must disturb at this point
i2c.write(slave_address_acc, all_interrupt_clear_command, 2);
i2c.write(slave_address_acc, intr_source_address, 1);
i2c.read(slave_address_acc, interrupt_source, 1);
char_to_int(interrupt_source[0]); // Coverts intr_source(char) to int & stores in intr_source_d
pc.printf("INT Source = ");
print_data_bits((interrupt_source_duplicate));
//--------------------------------------------------------------------------------------------------------
/* VERIFY WHETHER THE INTERRUPT IS BECAUSE OF ACTIVITY */
//if((((int)intr_source) & 0x10) == 0x10)
if(interrupt_source_duplicate & 0x10)
{
/* THE FOLLOWING BLOCK IS USED JUST FOR VERIFICATION PURPOSE AND ARE NOT MANDATORY */
pc.printf("ENTERED ACTIVITY CONDITION\r\n\r\n");
for(count = 0; count < 10; count++)
{
led = !led;
wait(0.05);
}
/*
fetch_vehicle_speed();
previous_speed = vehicle_speed;
wait(5);
fetch_vehicle_speed();
current_speed = vehicle_speed;
//if((current_speed > previous_speed) && (current_speed > speed_threshold)) // Decision making regarding vehicle's current state
if(current_speed == 79)
{
i2c.write(slave_address_acc, activity_interrupt_disable_command, 2); // Disables Activity interrupt & enables Inactivity interrupt
pc.printf("\r\n>>> VEHICLE HAS STARTED FROM STOP <<<");
}
*/
}
//--------------------------------------------------------------------------------------------------------
/* VERIFY WHETHER THE INTERRUPT IS BECAUSE OF INACTIVITY */
//if((((int)intr_source) & 0x08) == 0x08) // Verify whether it is inactivity interrupt
if(interrupt_source_duplicate & 0x08)
{
/* THE FOLLOWING BLOCK IS USED JUST FOR VERIFICATION PURPOSE AND ARE NOT MANDATORY */
pc.printf("ENTERED INACTIVITY CONDITION \r\n\r\n");
for(count = 0; count < 10; count++)
{
led = !led;
wait(0.2);
}
/*
fetch_vehicle_speed();
if(vehicle_speed == 0) // Decision making regarding vehicle's current state
{
i2c.write(slave_address_acc, inactivity_interrupt_disable_command, 2); // Disables Inactivity interrupt & enables Activity interrupt
pc.printf("\r\n>>> VEHICLE HAS STOPPED FROM START <<<");
}
*/
}
}
//*********************************************************************************************************
void initialize_accelerometer()
{
inactivity.rise(interrupt_activity_inactivity); // Attach the address of interrupt_activity_inactivity function to rising edge
double_tap.rise(interrupt_sudden_jerk);
pc.baud(38400);
char cmd[2], cmd2[2], cmd3[5], cmd4[8], cmd5[3], cmd6[2], cmd7[2], cmd8[2];
/* THE FOLLOWING GROUP OF COMMAND VARIABLES STORES THE CONFIGURATION VALUES TO BE WRITTEN TO THE ADXL345 ACCELEROMETER */
cmd[0] = 0x2D; // Post the Register address of the slave (Have to write this into slave)
cmd[1] = 0x08; // Turn ON the Measure Bit
cmd3[0] = 0x1D; // Threshold Tap Register address
cmd3[1] = 100; // Threshold tap Register value
cmd3[2] = 0x7F; // Offset - X axis
cmd3[3] = 0x7F; // Offset - Y axis
cmd3[4] = 0x05; // Offset - Z axis
cmd4[0] = 0x21; // DUR Register address
cmd4[1] = 0x15; // DUR Register value providing maximum time to be held to generate an interrupt
cmd4[2] = 0x15; // Latent
cmd4[3] = 0x45; // Window Time
cmd4[4] = 64; // THRES_ACT register value 62.5mg/LSB , therfore value 32 indicates 2g activity
cmd4[5] = 50; // THRES_INACT Register
cmd4[6] = 5; // TIME_INACT Register, making inactivity detection time = 5 secs
cmd4[7] = 0x77; // Activity, Inactivity detection enabled for all axis
cmd5[0] = 0x2E; // INT Enable Register address
//cmd5[1] = 0x74; // INT Enable Register value enabling Single Tap, Double Tap, Activity and Free Fall detection
//cmd5[2] = 0x00; // INT Map Register value mapping Single Tap event to INT1
//cmd5[1] = 0x20; // Enabling only the double tap interrupt
//cmd5[2] = 0x20; // Mapping the double tap interrupt to INT2 pin
//cmd5[1] = 0x10; // Enabling only the activity interrupt
//cmd5[2] = 0x10; // Mapping the sctivity interrupt to the INT2 pin
//cmd5[1] = 0x08; // Enabling only the inactivity interrupt
//cmd5[2] = 0x08; // Mapping the Inactivity interrupt to the INT2 pin
cmd5[1] = 0x38; // Enabling Activity & inactivity interrupt
cmd5[2] = 0xDF; // Activity--->INT1 & Inactivity--->INT2
cmd6[0] = 0x2A; // Address of the TAP_AXES Register
cmd6[1] = 0x06; // X & Y axis participate in tap detection
cmd7[0] = 0x28; // Address of the Threshold register for Free Fall detection
cmd7[1] = 0x07; // Recommeded value : 0x05 to 0x09 Refer datasheet
cmd8[0] = 0x2C; // Address of the BW RATE register
cmd8[1] = 0x0D; // Increased the data rate to 800Hz, default is 0x0A indicating 100Hz
cmd2[0] = 0x31; // Data format register address
cmd2[1] = 0x04; // Making the acceleration data as left justified
axis_data_start_address[0] = 0x32;
i2c.write(slave_address_acc, cmd, 2);
i2c.write(slave_address_acc, cmd3, 5);
i2c.write(slave_address_acc, cmd4, 8);
i2c.write(slave_address_acc, cmd5, 3);
i2c.write(slave_address_acc, cmd6, 2);
i2c.write(slave_address_acc, cmd7, 2);
i2c.write(slave_address_acc, cmd8, 2);
i2c.write(slave_address_acc, cmd2, 2);
//char dev_add[2] = {0x00,0};
//i2c.write(slave_address_acc, dev_add, 1);
//i2c.read(slave_address_acc, dev_add, 1);
//print_data_bits(dev_add[0]);
pc.printf(" ACCELEROMETER DATA LOG \r\n\r\n");
while (1);
pc.printf("\r\n CAME HERE \r\n");
// pc.printf(" ACCELEROMETER DATA LOG \r\n\r\n");
// while (1) {
/*--------------------------------------------------------------------------------------------------------------------------------------
wait(1.0);
pc.printf("STILL IN WHILE LOOP\r\n\r\n");
--------------------------------------------------------------------------------------------------------------------------------------*/
// wait(0.25);
//--------------------------------------------------------------------------------------------------------------------------------------
// USE THE FOLLOWING BLOCK TO READ THE DATA IN X-AXIS, Y-AXIS & Z-AXIS
/*
i2c.write(slave_address_acc, axis_data_start_address, 1);
i2c.read(slave_address_acc, axis_data, 6);
x_axis = axis_data[1]; // Puts MSB data into respective axes
y_axis = axis_data[3];
z_axis = axis_data[5];
if(x_axis & 0x80) // Testing the signess of the x-axis data
pc.printf("X-axis_1 = %d\r\n", (((~x_axis)+1))); // Converts 2's complement data into decimal
else
pc.printf("X-axis_0 = %d\r\n", x_axis);
if(y_axis & 0x80) // Testing the signess of the y-axis data
pc.printf("Y-axis_1 = %d\r\n", (((~y_axis)+1))); // Converts 2's complement data into decimal
else
pc.printf("Y-axis_0 = %d\r\n", y_axis);
if(z_axis & 0x80) // Testing the signess of the y-axis data
pc.printf("Z-axis_1 = %d\r\n\r\n", (((~z_axis)+1))); // Converts 2's complement data into decimal
else
pc.printf("Z-axis_0 = %d\r\n\r\n",z_axis);
*/
/*--------------------------------------------------------------------------------------------------------------------------------------
// THIS CAN BE USED WHEN THERE IS A NEED OF VERY HIGH LEVEL ACCURACY & USE INT16_T DATA TYPE
x_axis = (int)axis_data[1] << 8 | (int)axis_data[0];
y_axis = (int)axis_data[3] << 8 | (int)axis_data[2];
z_axis = (int)axis_data[5] << 8 | (int)axis_data[4];
--------------------------------------------------------------------------------------------------------------------------------------*/
// }
}