kumar singh
/
Dealer_20Mar
BLE Transmitter not working
Fork of Dealer_23Feb by
Diff: Accelerometer.cpp
- Revision:
- 11:77e595130230
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Accelerometer.cpp Fri Jan 27 18:30:02 2017 +0000 @@ -0,0 +1,426 @@ + +// INTERFACING ADXL345 ACCELEROMETER USING I2C + +/* +NOTE : + +ACTIVITY : ACCELEROMETER IS ACCELERATING AND ITS VALUES ARE GREATER THAN THE ACTIVITY THRESHOLD +INACTIVITY : ACCELEROMETER IS NOT IN ACCELERATION OR ACCELERATING VERY SLIGHTLY THAT ITS VALUES ARE BELOW THE INACTIVITY THRESHOLD +DOUBLE TAP : SUDDEN JERK CONDITION (IDENIFIED BY SUDDEN VARIATIONS IN THE ACCELERATION VALUES) + + +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 + +*/ +/* +#include "Accelerometer.h" + +#define DOUBLE_TAP_INTERRUPT 0x20 +#define ACTIVITY_INTERRUPT 0x10 +#define INACTIVITY_INTERRUPT 0x08 + +#define TAP_THRESHOLD 75 +#define ACTIVITY_THRESHOLD 64 // THRES_ACT register value 62.5mg/LSB , therfore value 32 indicates 2g activity +#define INACTIVITY_THRESHOLD 50 + +#define DUR_TIME 0x15 // DUR Register value providing maximum time to be held to generate an interrupt +#define LATENT_TIME 0x15 // The interrupt latency +#define WINDOW_TIME 0x45 // The time of the interrupt window in which the next tap will be detected +#define INACTIVITY_VALIDATION_TIME 5 // The time until which the acceleration must be held below the inactivity threshold to generate an inactvity interrupt + // Here the value 5 indicates literally 5 secs +#define X_AXIS_OFFSET 0x7F +#define Y_AXIS_OFFSET 0x7F +#define Z_AXIS_OFFSET 0x05 + + +I2C i2c(PB_9, PB_8); +RawSerial DEBUG_UART1(PA_9, PA_10);//USART1_TX->PA_9,USART1_RX->PA_10 + +InterruptIn activity(PB_0); +InterruptIn inactivity(PA_4); // As for now only this is used +DigitalOut led(LED1); + +const int slave_address_acc = 0xA6; +char axis_data[6] = {0,0,0,0,0,0}; + +char interrupt_source[2]; +char axis_data_start_address[2] = {0x32, 0}; +char intr_source_address[2] = {0x30, 0}; +char all_interrupt_clear_command[2] = {0x2E, 0x00}; +char all_interrupt_enable_command[2] = {0x2E, 0x38}; +char activity_interrupt_disable_command[2] = {0x2E, 0x08}; +char inactivity_interrupt_disable_command[2] = {0x2E, 0x30}; +char accelerometer_status_registered = 0; +unsigned int interrupt_source_duplicate; + +char threshold_offset_command[5]; +char act_inact_time_config_command[8]; +char interrupt_enable_command[3]; +char tap_axis_enable_command[2]; +char baud_rate_command[2]; +char data_format_command[2]; +char measure_bit_on_command[2]; + + +char previous_state = 0; +char current_state = 0; + +unsigned char vehicle_speed = 25; // Kmph +unsigned char current_speed, previous_speed, speed_threshold = 10; // Kmph + +unsigned char x_axis, y_axis, z_axis; + +unsigned char Motion_Detect_Status = FALSE; +uint8 Accelerometer_Interrupt_Generated = FALSE; +unsigned char Motion_Type_Detected = MOTION_TYPE_UNKNOWN; //By default set motion type as unknown +void Accelerometer_Process_thread(void const *args) ; + +//---------------------------------------------------------------------------------------------------------- + +// CONVERTS THE CHAR DATA TO UNSIGNED INTERGER DATA + +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 + } +} + +//---------------------------------------------------------------------------------------------------------- + +// LEAVE THIS ROUTINE COMMENTED (IT JUST PRINTS THE DATA IN BINARY FORMAT) + +void print_data_bits(char data_fetched) +{ + unsigned int shifter; + for(shifter = 0; shifter < 8; shifter++) + { + DEBUG_UART1.printf("%d",((data_fetched&0x80)>>7)); + data_fetched = data_fetched << 1; + } + DEBUG_UART1.printf("\r\n\r\n"); +} + +//---------------------------------------------------------------------------------------------------------- + +void get_vehicle_speed(void) +{ + // PASS OBD COMMAND "010D<CR>" AND FETCH THE VEHICLE SPEED AT THIS POINT +} + + +void interrupt_activity_inactivity() +{ + i2c.write(slave_address_acc, all_interrupt_clear_command, 2); + Motion_Detect_Status = TRUE; +} + +//---------------------------------------------------------------------------------------------------------- + //this thread is to send lora packets periodically. + void Accelerometer_Process_thread(void const *args) + { + DEBUG_UART1.baud(115200); + DEBUG_UART1.printf(" Hello\n"); + inactivity.rise(interrupt_activity_inactivity); // Attach the address of interrupt_activity_inactivity function to rising edge + + // THE FOLLOWING GROUP OF COMMAND VARIABLES STORES THE CONFIGURATION VALUES TO BE WRITTEN TO THE ADXL345 ACCELEROMETER + threshold_offset_command[0] = 0x1D; // Threshold Tap Register address + threshold_offset_command[1] = TAP_THRESHOLD; // Threshold tap Register value + threshold_offset_command[2] = X_AXIS_OFFSET; // Offset - X axis + threshold_offset_command[3] = Y_AXIS_OFFSET; // Offset - Y axis + threshold_offset_command[4] = Z_AXIS_OFFSET; // Offset - Z axis + + act_inact_time_config_command[0] = 0x21; // DUR Register address + act_inact_time_config_command[1] = DUR_TIME; + act_inact_time_config_command[2] = LATENT_TIME; + act_inact_time_config_command[3] = WINDOW_TIME; + act_inact_time_config_command[4] = ACTIVITY_THRESHOLD; + act_inact_time_config_command[5] = INACTIVITY_THRESHOLD; // THRES_INACT Register + act_inact_time_config_command[6] = INACTIVITY_VALIDATION_TIME; // TIME_INACT Register, making inactivity detection time = 5 secs + act_inact_time_config_command[7] = 0x77; // Activity, Inactivity detection enabled for all axis + + interrupt_enable_command[0] = 0x2E; // INT Enable Register address + interrupt_enable_command[1] = 0x38; // Enabling Double tap (sudden jerk), Activity & Inactivity Interrupts + interrupt_enable_command[2] = 0xFF; // Double tap (sudden jerk), Activity & inactivity interrupts are mapped to INT2 pin + + tap_axis_enable_command[0] = 0x2A; // Address of the TAP_AXES Register + tap_axis_enable_command[1] = 0x07; // X, Y & Z axis participate in tap detection + + baud_rate_command[0] = 0x2C; // Address of the BW RATE register + baud_rate_command[1] = 0x0D; // Increased the data rate to 800Hz, default is 0x0A indicating 100Hz + + data_format_command[0] = 0x31; // Data format register address + data_format_command[1] = 0x04; // Making the acceleration data as left justified + + measure_bit_on_command[0] = 0x2D; // Post the Register address of the slave (Have to write this into slave) + measure_bit_on_command[1] = 0x08; // Turn ON the Measure Bit + + i2c.write(slave_address_acc, threshold_offset_command, 5); + i2c.write(slave_address_acc, act_inact_time_config_command, 8); + i2c.write(slave_address_acc, interrupt_enable_command, 3); + i2c.write(slave_address_acc, tap_axis_enable_command, 2); + i2c.write(slave_address_acc, baud_rate_command, 2); + i2c.write(slave_address_acc, data_format_command, 2); + i2c.write(slave_address_acc, measure_bit_on_command, 2); + + DEBUG_UART1.printf(" ACCELEROMETER DATA LOG \r\n\r\n"); + + while (1) + { + if(Motion_Detect_Status) + { + // The following statement disables all interrupts since no other interrupts must disturb at this point + i2c.write(slave_address_acc, intr_source_address, 1); + i2c.read(slave_address_acc, interrupt_source, 1); // Reads the Interrupt Source Register + char_to_int(interrupt_source[0]); // Coverts intr_source(char) to int & stores in intr_source_duplicate + + Motion_Detect_Status = FALSE; + Motion_Type_Detected = MOTION_TYPE_UNKNOWN; + // USE THE FOLLOWING BLOCK TO READ THE DATA IN X-AXIS, Y-AXIS & Z-AXIS + //--------------------------------------------------------------------------------------------------------------------------------- + if(interrupt_source_duplicate & DOUBLE_TAP_INTERRUPT) // Check whether it is double tap (sudden jerk) interrupt + { + // ATTACH YOUR SUDDEN JERK EXECUTION ROUTINE HERE + i2c.write(slave_address_acc, inactivity_interrupt_disable_command, 2); // Disables Inactivity interrupt & enables Double Tap & Activity interrupt + DEBUG_UART1.printf("ENTERED SUDDEN JERK CONDITION \r\n\r\n"); // To be removed + interrupt_source_duplicate = 0x00; // Sudden jerk also comes with activity interrupt triggered, hence this statements makes the activity check fail + Motion_Type_Detected = MOTION_TYPE_TAP; + Accelerometer_Interrupt_Generated = TRUE; + } + //--------------------------------------------------------------------------------------------------------------------------------- + // VERIFY WHETHER THE INTERRUPT IS BECAUSE OF ACTIVITY + + if(interrupt_source_duplicate & ACTIVITY_INTERRUPT) + { + i2c.write(slave_address_acc, activity_interrupt_disable_command, 2); // Disables Activity interrupt & enables Inactivity interrupt + get_vehicle_speed(); + previous_speed = vehicle_speed; + wait(5); + get_vehicle_speed(); + current_speed = vehicle_speed; + if((current_speed > previous_speed) && (current_speed > speed_threshold)) + { + Motion_Type_Detected = MOTION_TYPE_STOP_TO_START; + Accelerometer_Interrupt_Generated = TRUE; + DEBUG_UART1.printf("VEHICLE HAS STARTED (STOP TO START) \r\n"); + // ATTACH UR STOP TO START ROUTINE HERE + } + } + //--------------------------------------------------------------------------------------------------------------------------------- + + // VERIFY WHETHER THE INTERRUPT IS BECAUSE OF INACTIVITY + if(interrupt_source_duplicate & INACTIVITY_INTERRUPT) + { + i2c.write(slave_address_acc, inactivity_interrupt_disable_command, 2); // Disables Inactivity interrupt & enables Activity interrupt + get_vehicle_speed(); + if(vehicle_speed == 0) + { + Motion_Type_Detected = MOTION_TYPE_START_TO_STOP; + Accelerometer_Interrupt_Generated = TRUE; + // ATTACH YOUR START TO STOP PROCESS OVERFLOW HERE + DEBUG_UART1.printf("VEHICLE HAS STOPPED (START TO STOP) \r\n"); + } + } + wait(0.25); + 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]; + } + Thread::wait(200); //wait for 100msec + } + }*/ + + +/* + +// INTERFACING ADXL345 ACCELEROMETER USING I2C + +/* +NOTE : + +ACTIVITY : ACCELEROMETER IS ACCELERATING AND ITS VALUES ARE GREATER THAN THE ACTIVITY THRESHOLD +INACTIVITY : ACCELEROMETER IS NOT IN ACCELERATION OR ACCELERATING VERY SLIGHTLY THAT ITS VALUES ARE BELOW THE INACTIVITY THRESHOLD +DOUBLE TAP : SUDDEN JERK CONDITION (IDENIFIED BY SUDDEN VARIATIONS IN THE ACCELERATION VALUES) + + +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 + +*/ + +/* + +//---------------------------------------------------------------------------------------------------------- + +// CONVERTS THE CHAR DATA TO UNSIGNED INTERGER DATA + +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 + } +} + +//---------------------------------------------------------------------------------------------------------- + +// LEAVE THIS ROUTINE COMMENTED (IT JUST PRINTS THE DATA IN BINARY FORMAT) + +void print_data_bits(char data_fetched) +{ + unsigned int shifter; + for(shifter = 0; shifter < 8; shifter++) + { + DEBUG_UART1.printf("%d",((data_fetched&0x80)>>7)); + data_fetched = data_fetched << 1; + } + DEBUG_UART1.printf("\r\n\r\n"); +} + +//---------------------------------------------------------------------------------------------------------- + +void get_vehicle_speed(void) +{ + // PASS OBD COMMAND "010D<CR>" AND FETCH THE VEHICLE SPEED AT THIS POINT +} + + +//void interrupt_activity_inactivity() +//{ + //i2c.write(slave_address_acc, all_interrupt_clear_command, 2); + //DEBUG_UART1.printf(" A"); + // Motion_Detect_Status = TRUE; +//} + +//---------------------------------------------------------------------------------------------------------- + //this thread is to send lora packets periodically. + void Accelerometer_Process_thread()//void const *args) + { + DEBUG_UART1.baud(115200); + // inactivity.rise(interrupt_activity_inactivity); // Attach the address of interrupt_activity_inactivity function to rising edge + + // THE FOLLOWING GROUP OF COMMAND VARIABLES STORES THE CONFIGURATION VALUES TO BE WRITTEN TO THE ADXL345 ACCELEROMETER + threshold_offset_command[0] = 0x1D; // Threshold Tap Register address + threshold_offset_command[1] = TAP_THRESHOLD; // Threshold tap Register value + threshold_offset_command[2] = X_AXIS_OFFSET; // Offset - X axis + threshold_offset_command[3] = Y_AXIS_OFFSET; // Offset - Y axis + threshold_offset_command[4] = Z_AXIS_OFFSET; // Offset - Z axis + + act_inact_time_config_command[0] = 0x21; // DUR Register address + act_inact_time_config_command[1] = DUR_TIME; + act_inact_time_config_command[2] = LATENT_TIME; + act_inact_time_config_command[3] = WINDOW_TIME; + act_inact_time_config_command[4] = ACTIVITY_THRESHOLD; + act_inact_time_config_command[5] = INACTIVITY_THRESHOLD; // THRES_INACT Register + act_inact_time_config_command[6] = INACTIVITY_VALIDATION_TIME; // TIME_INACT Register, making inactivity detection time = 5 secs + act_inact_time_config_command[7] = 0x77; // Activity, Inactivity detection enabled for all axis + + interrupt_enable_command[0] = 0x2E; // INT Enable Register address + interrupt_enable_command[1] = 0x38; // Enabling Double tap (sudden jerk), Activity & Inactivity Interrupts + interrupt_enable_command[2] = 0xFF; // Double tap (sudden jerk), Activity & inactivity interrupts are mapped to INT2 pin + + tap_axis_enable_command[0] = 0x2A; // Address of the TAP_AXES Register + tap_axis_enable_command[1] = 0x07; // X, Y & Z axis participate in tap detection + + baud_rate_command[0] = 0x2C; // Address of the BW RATE register + baud_rate_command[1] = 0x0D; // Increased the data rate to 800Hz, default is 0x0A indicating 100Hz + + data_format_command[0] = 0x31; // Data format register address + data_format_command[1] = 0x04; // Making the acceleration data as left justified + + measure_bit_on_command[0] = 0x2D; // Post the Register address of the slave (Have to write this into slave) + measure_bit_on_command[1] = 0x08; // Turn ON the Measure Bit + + i2c.write(slave_address_acc, threshold_offset_command, 5); + i2c.write(slave_address_acc, act_inact_time_config_command, 8); + i2c.write(slave_address_acc, interrupt_enable_command, 3); + i2c.write(slave_address_acc, tap_axis_enable_command, 2); + i2c.write(slave_address_acc, baud_rate_command, 2); + i2c.write(slave_address_acc, data_format_command, 2); + i2c.write(slave_address_acc, measure_bit_on_command, 2); + + DEBUG_UART1.printf(" ACCELEROMETER DATA LOG \r\n\r\n"); + + while (1) + { + if(Motion_Detect_Status) + { + // The following statement disables all interrupts since no other interrupts must disturb at this point + i2c.write(slave_address_acc, intr_source_address, 1); + i2c.read(slave_address_acc, interrupt_source, 1); // Reads the Interrupt Source Register + char_to_int(interrupt_source[0]); // Coverts intr_source(char) to int & stores in intr_source_duplicate + + Motion_Detect_Status = FALSE; + Motion_Type_Detected = MOTION_TYPE_UNKNOWN; + DEBUG_UART1.printf("Motion detected"); + DEBUG_UART1.putc(interrupt_source_duplicate); + // USE THE FOLLOWING BLOCK TO READ THE DATA IN X-AXIS, Y-AXIS & Z-AXIS + //--------------------------------------------------------------------------------------------------------------------------------- + if(interrupt_source_duplicate & DOUBLE_TAP_INTERRUPT) // Check whether it is double tap (sudden jerk) interrupt + { + // ATTACH YOUR SUDDEN JERK EXECUTION ROUTINE HERE + i2c.write(slave_address_acc, inactivity_interrupt_disable_command, 2); // Disables Inactivity interrupt & enables Double Tap & Activity interrupt + DEBUG_UART1.printf("ENTERED SUDDEN JERK CONDITION \r\n\r\n"); // To be removed + interrupt_source_duplicate = 0x00; // Sudden jerk also comes with activity interrupt triggered, hence this statements makes the activity check fail + Motion_Type_Detected = MOTION_TYPE_TAP; + Accelerometer_Interrupt_Generated = TRUE; + } + //--------------------------------------------------------------------------------------------------------------------------------- + / VERIFY WHETHER THE INTERRUPT IS BECAUSE OF ACTIVITY + + if(interrupt_source_duplicate & ACTIVITY_INTERRUPT) + { + i2c.write(slave_address_acc, activity_interrupt_disable_command, 2); // Disables Activity interrupt & enables Inactivity interrupt + get_vehicle_speed(); + previous_speed = vehicle_speed; + wait(5); + get_vehicle_speed(); + current_speed = vehicle_speed; + if((current_speed > previous_speed) && (current_speed > speed_threshold)) + { + Motion_Type_Detected = MOTION_TYPE_STOP_TO_START; + Accelerometer_Interrupt_Generated = TRUE; + DEBUG_UART1.printf("VEHICLE HAS STARTED (STOP TO START) \r\n"); + // ATTACH UR STOP TO START ROUTINE HERE + } + } + //--------------------------------------------------------------------------------------------------------------------------------- + + // VERIFY WHETHER THE INTERRUPT IS BECAUSE OF INACTIVITY + if(interrupt_source_duplicate & INACTIVITY_INTERRUPT) + { + i2c.write(slave_address_acc, inactivity_interrupt_disable_command, 2); // Disables Inactivity interrupt & enables Activity interrupt + get_vehicle_speed(); + if(vehicle_speed == 0) + { + Motion_Type_Detected = MOTION_TYPE_START_TO_STOP; + Accelerometer_Interrupt_Generated = TRUE; + // ATTACH YOUR START TO STOP PROCESS OVERFLOW HERE + DEBUG_UART1.printf("VEHICLE HAS STOPPED (START TO STOP) \r\n"); + } + } + wait(0.25); + 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]; + } + Thread::wait(200); //wait for 100msec + } + } + + +*/ \ No newline at end of file