OBD Source Code -Section 1- Without Car / Section 2 - With car

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers accelerometer.cpp Source File

accelerometer.cpp

00001 
00002 #include "mbed.h"
00003 #include "obd_libraries.h"
00004 #include "accelerometer.h"
00005 #include "common_definitions.h"
00006 
00007 #define IDLE    0
00008 #define ACTIVE  1
00009 
00010 I2C i2c(PB_9, PB_8);
00011 Serial pc(USBTX, USBRX);
00012 
00013 InterruptIn double_tap(PC_1);      // Pin assignment may vary
00014 InterruptIn inactivity(PC_0);      // Pin assignment may vary
00015 
00016 DigitalOut led(LED1);
00017 
00018 // INTERFACING ADXL345 ACCELEROMETER USING I2C 
00019 
00020 /*
00021 
00022 NOTE :
00023 Due to communication speed limitations, the maximum output
00024 data rate when using 400 kHz I2C is 800 Hz and scales linearly with
00025 a change in the I2C communication speed
00026 
00027 */
00028 
00029 //InterruptIn activity(PB_0);  // Button B1 (Blue)
00030 
00031 
00032 
00033 const int slave_address_acc = 0xA6;
00034 char axis_data[6] = {0,0,0,0,0,0};
00035 int16_t x_axis, y_axis, z_axis;
00036 char interrupt_source[2];
00037 char axis_data_start_address[2];
00038 char intr_source_address[2] = {0x30, 0};
00039 char all_interrupt_clear_command[2] = {0x2E, 0x00};
00040 char all_interrupt_enable_command[2] = {0x2E, 0x18};
00041 char activity_interrupt_disable_command[2] = {0x2E, 0x28};
00042 char inactivity_interrupt_disable_command[2] = {0x2E, 0x30};
00043 char accelerometer_status_registered = 0;
00044 unsigned int interrupt_source_duplicate;
00045 
00046 char previous_state = 0;
00047 char current_state = 0;
00048 
00049 extern long vehicle_speed;
00050 char current_speed, previous_speed;
00051 char speed_threshold = 10;
00052 
00053 //----------------------------------------------------------------------------------------------------------
00054 
00055 void char_to_int(char data_fetched)
00056 {
00057     unsigned int shifter;
00058     
00059     interrupt_source_duplicate = 0x00;
00060     
00061         for(shifter = 0; shifter < 8; shifter++)
00062         {
00063             interrupt_source_duplicate |= (((data_fetched >> shifter) & 0x01) << shifter); // Converts char data into unsigned int
00064         }   
00065 }
00066 
00067 //----------------------------------------------------------------------------------------------------------
00068 
00069 void print_data_bits(char data_fetched)
00070 {
00071     unsigned int shifter;
00072     
00073         for(shifter = 0; shifter < 8; shifter++)
00074         {
00075             pc.printf("%d",((data_fetched&0x80)>>7));
00076             data_fetched = data_fetched << 1;
00077         }
00078         pc.printf("\r\n\r\n");       
00079 }
00080 
00081 //----------------------------------------------------------------------------------------------------------
00082 
00083 /*----------------------------------------------------------------------------------------------------------
00084 
00085                 AS FAR NOW, ONE INTERRUPT PIN (INT1) OF ACCELEROMETER IS NOT WORKING
00086                     USE THIS TO CUSTOMIZE ACCELEROMETER WHEN THAT PIN IS WORKING
00087 
00088 void use_me_later() {
00089     char count;
00090     for(count = 0; count < 10; count++)
00091     {
00092         led = !led;
00093         wait(0.10);
00094     }
00095 }
00096 ----------------------------------------------------------------------------------------------------------*/
00097 
00098 void interrupt_sudden_jerk() 
00099 {
00100     char count;
00101     
00102     i2c.write(slave_address_acc, all_interrupt_clear_command, 2); 
00103     pc.printf("~~~ ENTERED SUDDEN JERK CONDITION ~~~\r\n\r\n");
00104 
00105         for(count = 0; count < 2; count++)
00106         {
00107             led = 1;
00108             wait(2);
00109             led = 0;
00110             wait(1);   
00111         }
00112 
00113     i2c.write(slave_address_acc, all_interrupt_enable_command, 2);
00114     
00115 }
00116 
00117 //*********************************************************************************************************
00118 
00119 // THE FOLLWOING CODE BLOCK IS THE MULITIPLEXED ISR FOR BOTH ACTIVITY & INACTIVITY INTERRUPT
00120 
00121 void interrupt_activity_inactivity() 
00122 {  
00123     char count;
00124     
00125     // The following statement disables all interrupts since no other interrupts must disturb at this point
00126     
00127     i2c.write(slave_address_acc, all_interrupt_clear_command, 2); 
00128     
00129     i2c.write(slave_address_acc, intr_source_address, 1);
00130     i2c.read(slave_address_acc, interrupt_source, 1);
00131     
00132     char_to_int(interrupt_source[0]);   // Coverts intr_source(char) to int & stores in intr_source_d
00133     
00134     pc.printf("INT Source = ");
00135     print_data_bits((interrupt_source_duplicate));
00136 
00137 //--------------------------------------------------------------------------------------------------------
00138         
00139         /* VERIFY WHETHER THE INTERRUPT IS BECAUSE OF ACTIVITY */
00140 
00141     //if((((int)intr_source) & 0x10) == 0x10)  
00142     if(interrupt_source_duplicate & 0x10)
00143     {
00144         /* THE FOLLOWING BLOCK IS USED JUST FOR VERIFICATION PURPOSE AND ARE NOT MANDATORY */        
00145         
00146         pc.printf("ENTERED ACTIVITY CONDITION\r\n\r\n");
00147         for(count = 0; count < 10; count++)
00148         {
00149             led = !led;
00150             wait(0.05);   
00151         }
00152 /* 
00153         fetch_vehicle_speed();
00154         previous_speed = vehicle_speed;
00155         wait(5);
00156         fetch_vehicle_speed();
00157         current_speed = vehicle_speed;
00158         
00159         //if((current_speed > previous_speed) && (current_speed > speed_threshold))   // Decision making regarding vehicle's current state
00160         if(current_speed == 79)
00161         {
00162             i2c.write(slave_address_acc, activity_interrupt_disable_command, 2); // Disables Activity interrupt & enables Inactivity interrupt
00163             pc.printf("\r\n>>> VEHICLE HAS STARTED FROM STOP <<<");
00164         }
00165 */
00166     }
00167 
00168 //--------------------------------------------------------------------------------------------------------
00169     
00170       /* VERIFY WHETHER THE INTERRUPT IS BECAUSE OF INACTIVITY */
00171 
00172     //if((((int)intr_source) & 0x08) == 0x08) // Verify whether it is inactivity interrupt
00173     if(interrupt_source_duplicate & 0x08)
00174     {
00175         /* THE FOLLOWING BLOCK IS USED JUST FOR VERIFICATION PURPOSE AND ARE NOT MANDATORY */
00176 
00177         pc.printf("ENTERED INACTIVITY CONDITION \r\n\r\n");
00178         for(count = 0; count < 10; count++)
00179         {
00180             led = !led;
00181             wait(0.2);
00182         }  
00183 /*
00184         fetch_vehicle_speed();
00185         
00186         if(vehicle_speed == 0)  // Decision making regarding vehicle's current state
00187         {
00188             i2c.write(slave_address_acc, inactivity_interrupt_disable_command, 2);  // Disables Inactivity interrupt & enables Activity interrupt
00189             pc.printf("\r\n>>> VEHICLE HAS STOPPED FROM START <<<");
00190         }     
00191 */
00192     }
00193 
00194 }
00195 
00196 //*********************************************************************************************************
00197 
00198 void initialize_accelerometer()
00199 {
00200     inactivity.rise(interrupt_activity_inactivity); // Attach the address of interrupt_activity_inactivity function to rising edge
00201     double_tap.rise(interrupt_sudden_jerk);
00202     pc.baud(38400);
00203     
00204     char cmd[2], cmd2[2], cmd3[5], cmd4[8], cmd5[3], cmd6[2], cmd7[2], cmd8[2];
00205     
00206     
00207     
00208 /* THE FOLLOWING GROUP OF COMMAND VARIABLES STORES THE CONFIGURATION VALUES TO BE WRITTEN TO THE ADXL345 ACCELEROMETER */    
00209     
00210     cmd[0] = 0x2D;      // Post the Register address of the slave (Have to write this into slave)
00211     cmd[1] = 0x08;      // Turn ON the Measure Bit
00212     
00213     cmd3[0] = 0x1D;     // Threshold Tap Register address
00214     cmd3[1] = 100;       // Threshold tap Register value
00215     cmd3[2] = 0x7F;     // Offset - X axis
00216     cmd3[3] = 0x7F;     // Offset - Y axis
00217     cmd3[4] = 0x05;     // Offset - Z axis
00218     
00219     
00220     cmd4[0] = 0x21;     // DUR Register address
00221     cmd4[1] = 0x15;     // DUR Register value providing maximum time to be held to generate an interrupt
00222     cmd4[2] = 0x15;     // Latent
00223     cmd4[3] = 0x45;     // Window Time
00224     cmd4[4] = 64;       // THRES_ACT register value 62.5mg/LSB , therfore value 32 indicates 2g activity
00225     cmd4[5] = 50;       // THRES_INACT Register 
00226     cmd4[6] = 5;        // TIME_INACT Register, making inactivity detection time = 5 secs
00227     cmd4[7] = 0x77;     // Activity, Inactivity detection enabled for all axis
00228     
00229     cmd5[0] = 0x2E;     // INT Enable Register address
00230     //cmd5[1] = 0x74;   // INT Enable Register value enabling Single Tap, Double Tap, Activity and Free Fall detection
00231     //cmd5[2] = 0x00;   // INT Map Register value mapping Single Tap event to INT1
00232     //cmd5[1] = 0x20;   // Enabling only the double tap interrupt
00233     //cmd5[2] = 0x20;   // Mapping the double tap interrupt to INT2 pin
00234     //cmd5[1] = 0x10;   // Enabling only the activity interrupt
00235     //cmd5[2] = 0x10;   // Mapping the sctivity interrupt to the INT2 pin
00236     //cmd5[1] = 0x08;   // Enabling only the inactivity interrupt
00237     //cmd5[2] = 0x08;   // Mapping the Inactivity interrupt to the INT2 pin
00238     cmd5[1] = 0x38;     // Enabling Activity & inactivity interrupt
00239     cmd5[2] = 0xDF;     // Activity--->INT1 & Inactivity--->INT2
00240     
00241     
00242     cmd6[0] = 0x2A;     // Address of the TAP_AXES Register
00243     cmd6[1] = 0x06;     // X & Y axis participate in tap detection
00244     
00245     cmd7[0] = 0x28;     // Address of the Threshold register for Free Fall detection
00246     cmd7[1] = 0x07;     // Recommeded value : 0x05 to 0x09 Refer datasheet
00247     
00248     cmd8[0] = 0x2C;     // Address of the BW RATE register
00249     cmd8[1] = 0x0D;     // Increased the data rate to 800Hz, default is 0x0A indicating 100Hz
00250             
00251     cmd2[0] = 0x31;     // Data format register address
00252     cmd2[1] = 0x04;     // Making the acceleration data as left justified
00253     
00254     axis_data_start_address[0] = 0x32;
00255     
00256     
00257     
00258     i2c.write(slave_address_acc, cmd, 2);
00259     i2c.write(slave_address_acc, cmd3, 5);
00260     i2c.write(slave_address_acc, cmd4, 8);
00261     i2c.write(slave_address_acc, cmd5, 3);
00262     i2c.write(slave_address_acc, cmd6, 2);
00263     i2c.write(slave_address_acc, cmd7, 2);
00264     i2c.write(slave_address_acc, cmd8, 2);
00265     i2c.write(slave_address_acc, cmd2, 2);
00266     
00267     
00268     //char dev_add[2] = {0x00,0};
00269     //i2c.write(slave_address_acc, dev_add, 1);
00270     //i2c.read(slave_address_acc, dev_add, 1);
00271     //print_data_bits(dev_add[0]);
00272     
00273     pc.printf("    ACCELEROMETER DATA LOG \r\n\r\n");
00274     
00275     while (1);
00276     
00277     pc.printf("\r\n CAME HERE \r\n");
00278   
00279   //  pc.printf("    ACCELEROMETER DATA LOG \r\n\r\n");
00280   
00281   //  while (1) {
00282 /*--------------------------------------------------------------------------------------------------------------------------------------               
00283         wait(1.0);
00284         pc.printf("STILL IN WHILE LOOP\r\n\r\n");       
00285 --------------------------------------------------------------------------------------------------------------------------------------*/
00286    // wait(0.25);
00287 //--------------------------------------------------------------------------------------------------------------------------------------       
00288 
00289                 // USE THE FOLLOWING BLOCK TO READ THE DATA IN X-AXIS, Y-AXIS & Z-AXIS 
00290     /*    
00291         i2c.write(slave_address_acc, axis_data_start_address, 1);
00292         i2c.read(slave_address_acc, axis_data, 6);
00293                
00294         x_axis = axis_data[1];  // Puts MSB data into respective axes
00295         y_axis = axis_data[3];
00296         z_axis = axis_data[5];
00297         
00298         if(x_axis & 0x80)                                           // Testing the signess of the x-axis data
00299             pc.printf("X-axis_1 = %d\r\n", (((~x_axis)+1)));        // Converts 2's complement data into decimal
00300         else
00301             pc.printf("X-axis_0 = %d\r\n", x_axis);
00302         
00303         if(y_axis & 0x80)                                           // Testing the signess of the y-axis data
00304             pc.printf("Y-axis_1 = %d\r\n", (((~y_axis)+1)));        // Converts 2's complement data into decimal
00305         else
00306             pc.printf("Y-axis_0 = %d\r\n", y_axis);
00307         
00308         if(z_axis & 0x80)                                           // Testing the signess of the y-axis data
00309             pc.printf("Z-axis_1 = %d\r\n\r\n", (((~z_axis)+1)));    // Converts 2's complement data into decimal
00310         else
00311             pc.printf("Z-axis_0 = %d\r\n\r\n",z_axis);
00312 */
00313 /*--------------------------------------------------------------------------------------------------------------------------------------      
00314 
00315 // THIS CAN BE USED WHEN THERE IS A NEED OF VERY HIGH LEVEL ACCURACY & USE INT16_T DATA TYPE
00316             
00317         x_axis  = (int)axis_data[1] << 8 | (int)axis_data[0];
00318         y_axis  = (int)axis_data[3] << 8 | (int)axis_data[2];
00319         z_axis  = (int)axis_data[5] << 8 | (int)axis_data[4];
00320         
00321 --------------------------------------------------------------------------------------------------------------------------------------*/       
00322    // }
00323 }
00324 
00325