Sensors Knowledge Base

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Sensors Knowledge Base

Discussions

Sort by:
Hi Everyone, As I am often asked for a simple bare metal example code illustrating the use of the accelerometer vector-magnitude function, I have decided to share here one of my examples I created for the FXLS8471Q accelerometer while working with the Freescale FRDM-KL25Z platform and FRDM-FXS-MULT2-B sensor expansion board. This example code complements the Python code snippet from the AN4692. The FXLS8471Q is set for detection of a change in tilt angle exceeding 17.25° from the horizontal plane. Once an event is triggered, an interrupt will be generated on the INT1 pin: void FXLS8471Q_Init (void) {      FXLS8471Q_WriteRegister(A_VECM_THS_MSB_REG, 0x84);            // Threshold value set to 300mg or ~17.25°    FXLS8471Q_WriteRegister(A_VECM_THS_LSB_REG, 0xCC);          FXLS8471Q_WriteRegister(A_VECM_CNT_REG, 0x01);                // Debounce timer period set to 80ms          FXLS8471Q_WriteRegister(A_VECM_INITX_MSB_REG, 0x00);    FXLS8471Q_WriteRegister(A_VECM_INITX_LSB_REG, 0x00);    FXLS8471Q_WriteRegister(A_VECM_INITY_MSB_REG, 0x00);    FXLS8471Q_WriteRegister(A_VECM_INITY_LSB_REG, 0x00);    FXLS8471Q_WriteRegister(A_VECM_INITZ_MSB_REG, 0x10);          // Set Z-axis to 1g  as a reference value    FXLS8471Q_WriteRegister(A_VECM_INITZ_LSB_REG, 0x00);          FXLS8471Q_WriteRegister(A_VECM_CFG_REG, 0x78);                // Event latch enabled, A_VECM_INITX/Y/Z used as initial reference, acceleration vector-magnitude detection feature enabled          FXLS8471Q_WriteRegister(CTRL_REG4, 0x02);                     // Acceleration vector-magnitude interrupt enabled    FXLS8471Q_WriteRegister(CTRL_REG5, 0x02);                     // Acceleration vector-magnitude interrupt routed to INT1 - PTA5          FXLS8471Q_WriteRegister(CTRL_REG1, 0x29);                     // ODR = 12.5Hz, Active mode } In the ISR, only the interrupt flag is cleared and the  INT_SOURCE (0x0C) register is read in order to clear the SRC_A_VECM status bit and deassert the INT1 pin, as shown on the screenshot below. void PORTA_IRQHandler() {    PORTA_PCR5 |= PORT_PCR_ISF_MASK;                              // Clear the interrupt flag    IntSource = FXLS8471Q_ReadRegister(INT_SOURCE_REG);           // Read the INT_SOURCE register to clear the SRC_A_VECM bit   } Attached you can find the complete source code. If there are any questions regarding this simple example code, please feel free to ask below. Your feedback or suggestions are also welcome. Regards, Tomas
View full article
Hello Freescale Community, Most of the new Freescale Sensors in our portfolio come in very small packages, some of them as small as 2x2x1mm, which is awesome! However, one of the problems that we detected last year is that many customers struggle in the evaluation stage of the project due to the small packages. They should either, buy an evaluation board or spend valuable time designing and manufacturing a PCB just for testing our devices. Our goal with this project is to share with our community the Freescale Sensors Breakout Boards we designed for this specific purpose, so you can easily manufacture your own sensor boards or modify our designs to fit  your specific application. This way you can easily evaluate Freescale sensors. The boards were designed to be used in a prototype board (DIP style pins) and they can communicate to any MCU thru IIC or SPI (depending on the sensor). These designs were made using Eagle Layout 6.5, if you want to modify the designs you can do it with the free version of Eagle CAD (for non-commercial purposes), or you can send the gerber files (included in the zip files) to your preferred PCB manufacturer. The following designs are available: + Altimeter: MPL3115A2 Breakout Board + Accelerometer: MMA845x Breakout Board MMA865x Breakout Board MMA8491 Breakout Board FXLN83xx Breakout Board FXLS8471 Breakout Board MMA690x Breakout Board + Accelerometer + Magnetometer (6-DOF): FXOS8700 Breakout Board + Gyroscope: FXAS2100x Breakout Board The above .ZIP files, contains the following design information: - Schematic Source File (.SCH) - Schematic (.PDF) - Layout Source File (.BRD) - Layout Images (.jpg) - Gerber Files (GTL, GBL, GTS, GBS, GTO, GBO, GKO, XLN). - PCB Render Image (.png created in OSH park) - BOM (.xls) Additional content: If you want to modify our designs, please download the attached library file "Freescale_Sensors_v2.lbr" and add it to your Eagle Library repository. We'll be more than glad to respond to your questions and please, let us know what you think. -Freescale Sensor's Support team.
View full article
Hi Everyone,   As I am often asked for a simple bare metal example code illustrating the use of the accelerometer transient detection function, I have decided to share here one of my examples I created for the FXLS8471Q accelerometer while working with the NXP FRDM-KL25Z platform and FRDM-FXS-MULT2-B sensor expansion board.   This example code complements the Python code snippet from the AN4693. The FXLS8471Q is set for detection of an “instantaneous” acceleration change exceeding 315mg for a minimum period of 40 ms on either the X or Y axes. Once an event is triggered, an interrupt will be generated on the INT1 pin:   void FXLS8471Q_Init (void) { FXLS8471Q_WriteRegister(TRANSIENT_THS_REG, 0x85); // Set threshold to 312.5mg (5 x 62.5mg ) FXLS8471Q_WriteRegister(TRANSIENT_COUNT_REG, 0x02); // Set debounce timer period to 40ms FXLS8471Q_WriteRegister(TRANSIENT_CFG_REG, 0x16); // Enable transient detection for X and Y axis, latch enabled FXLS8471Q_WriteRegister(CTRL_REG4, 0x20); // Acceleration transient interrupt enabled FXLS8471Q_WriteRegister(CTRL_REG5, 0x20); // Route acceleration transient interrupt to INT1 - PTA5 FXLS8471Q_WriteRegister(CTRL_REG1, 0x29); // ODR = 12.5Hz, Active mode } ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍     In the ISR, only the interrupt flag is cleared and the TRANSIENT_SRC (0x1E) register is read in order to clear the SRC_TRANS status bit and deassert the INT1 pin, as shown on the screenshot below.   void PORTA_IRQHandler() { PORTA_PCR5 |= PORT_PCR_ISF_MASK; // Clear the interrupt flag IntSource = FXLS8471Q_ReadRegister(TRANSIENT_SRC_REG); // Read the TRANSIENT_SRC register to clear the SRC_TRANS flag in the INT_SOURCE register EventCounter++; } ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍       Attached you can find the complete source code. If there are any questions regarding this simple example code, please feel free to ask below. Your feedback or suggestions are also welcome.   Regards, Tomas
View full article
"Android as a Platform for Sensor Fusion Education and Evaluation" presented at 2013 Sensors Expo & Conference by Michael Stanley.
View full article
Hi Everyone,   If you are interested in a simple bare metal example code illustrating the use of the FXLS8471Q orientation detection function, please find below one of my examples I created for the FXLS8471Q accelerometer while working with the NXP FRDM-KL25Z platform and FRDMSTBC-A8471 board.   This example code complements the code snippet from the  AN4068.   void FXLS8471Q_Init (void) { FXLS8471Q_WriteRegister(CTRL_REG1, 0x00); // Standby mode FXLS8471Q_WriteRegister(PL_CFG_REG, 0x40); // Enable orientation detection FXLS8471Q_WriteRegister(PL_BF_ZCOMP_REG, 0x43); // Back/Front trip point set to 75°, Z-lockout angle set to 25° FXLS8471Q_WriteRegister(P_L_THS_REG, 0x14); // Threshold angle = 45°, hysteresis = 14° FXLS8471Q_WriteRegister(PL_COUNT_REG, 0x05); // Debounce counter set to 100ms at 50Hz FXLS8471Q_WriteRegister(CTRL_REG3, 0x00); // Push-pull, active low interrupt FXLS8471Q_WriteRegister(CTRL_REG4, 0x10); // Orientation interrupt enabled FXLS8471Q_WriteRegister(CTRL_REG5, 0x10); // Route orientation interrupt to INT1 - PTD4 FXLS8471Q_WriteRegister(CTRL_REG1, 0x21); // ODR = 50Hz, Active mode }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍     In the ISR, only the interrupt flag is cleared and the PL_STATUS (0x10) register is read in order to:   - Clear the SRC_LNDPRT flag in the INT_SOURCE register and deassert the INT1 pin, as shown on the screenshot below. - Get orientation information. 0x82 in this example corresponds to "Portrait down" orientation.   void PORTD_IRQHandler() { PORTD_PCR4 |= PORT_PCR_ISF_MASK; // Clear the interrupt flag PL_Status = FXLS8471Q_ReadRegister(PL_STATUS_REG); // Read the PL_STATUS register to clear the SRC_LNDPRT flag in the INT_SOURCE register }‍‍‍‍‍‍‍‍‍‍       Attached you can find the complete source code. If there are any questions regarding this simple example code, please feel free to ask below.    Regards, Tomas
View full article
Hi Everyone,   In this document I would like to present a simple bare-metal example code/demo for the FXLN8371Q Xtrinsic three axis, low-power, low-g, analog output accelerometer. I have created it while working with the Freescale FRDM-KL25Z development platform and FXLN8371Q breakout board. The FreeMASTER tool is used to visualize the acceleration data that are read from the FXLN8371Q through ADC.   This example illustrates:   1. Initialization of the MKL25Z128 MCU (mainly ADC, PORT and PIT modules). 2. Simple offset calibration. 3. Accelerometer outputs reading using ADC and conversion of the 10-bit ADC values to real acceleration values in g’s. 4. Visualization of the output values in the FreeMASTER tool.   1. The FXLN8371Q breakout board (schematic is attached below) needs to have the following pins connected to the FRDM-KL25Z board:   J4-1 (VDD) => J9-4 (P3V3) J4-2 (XOUT) => J10-2 (PTB0/ADC0_SE8) J4-3 (YOUT) => J10-4 (PTB1/ADC0_SE9) J4-4 (ZOUT) => J10-6 (PTB2/ ADC0_SE12) J4-6 (GND) => J9-14 (GND) J3-3 (ST) => J9-14 (GND) J3-4 (EN) => J9-4 (P3V3)   The PIT (Periodic Interrupt Timer) is used to read the output data periodically at a fixed rate of ~200Hz. The MCU is, therefore, configured as follows.   void MCU_Init(void) {      //ADC0 module initialization      SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK;        // Turn on clock to ADC0 module      SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK;       // Turn on clock to Port B module      PORTB_PCR0 |= PORT_PCR_MUX(0x00);        // PTB0 pin is ADC0 SE8 input      PORTB_PCR1 |= PORT_PCR_MUX(0x00);        // PTB1 pin is ADC0 SE9 input      PORTB_PCR2 |= PORT_PCR_MUX(0x00);        // PTB2 pin is ADC0 SE12 input      ADC0_CFG1 |= ADC_CFG1_ADLSMP_MASK | ADC_CFG1_MODE(0x02);             // Long sample time, single-ended 10-bit conversion                           //PIT module initialization      SIM_SCGC6 |= SIM_SCGC6_PIT_MASK;         // Turn on clock to PIT module      PIT_LDVAL0 = 52400;                      // Timeout period = ~5ms (200Hz)      PIT_MCR = PIT_MCR_FRZ_MASK;              // Enable clock for PIT, freeze PIT in debug mode                               //Enable PIT interrupt on NVIC          NVIC_ICPR |= 1 << ((INT_PIT - 16) % 32);      NVIC_ISER |= 1 << ((INT_PIT - 16) % 32); }   2. The simplest offset calibration method consists of placing the board on a flat surface so that X is at 0g, Y is at 0g and Z is at +1g. 16 samples are recorded and then averaged. The known sensitivity needs to be subtracted from the +1g reading to calculate an assumed 0g offset value for Z.   void Calibrate(void) {      unsigned int Count = 0;                    do                   // Accumulate 16 samples for X, Y, Z      {         ADC0_SC1A = ADC_SC1_ADCH(0x08);               // Process ADC measurements on ADC0_SE8/XOUT                                                                while(!(ADC0_SC1A & ADC_SC1_COCO_MASK)){};         Xout_10_bit += ADC0_RA;                                                                                                      ADC0_SC1A = ADC_SC1_ADCH(0x09);               // Process ADC measurements on ADC0_SE9/YOUT                while(!(ADC0_SC1A & ADC_SC1_COCO_MASK)){};         Yout_10_bit += ADC0_RA;                                                                                                            ADC0_SC1A = ADC_SC1_ADCH(0x0C);                while(!(ADC0_SC1A & ADC_SC1_COCO_MASK)){};    // Process ADC measurements on ADC0_SE12/ZOUT               Zout_10_bit += ADC0_RA;                                                         Count++;                        } while (Count < 16);                    X_offset = (float) Xout_10_bit / 16;                             // Compute X-axis offset by averaging all 16 X-axis samples      Y_offset = (float) Yout_10_bit / 16;                             // Compute Y-axis offset by averaging all 16 Y-axis samples      Z_offset = ((float) Zout_10_bit / 16) - SENSITIVITY_2G;          // Compute Z-axis offset by averaging all 16 Z-axis samples and subtracting the known sensitivity                      PIT_TCTRL0 = PIT_TCTRL_TIE_MASK | PIT_TCTRL_TEN_MASK;          // Enable PIT interrupt and PIT                                      }   3. Reading the FXLN8371Q datasheet, the output voltage when there is no acceleration is typically 0.75V and it should typically change by 229mV per 1g of acceleration in ±2g mode. The signal from a 10-bit ADC gives me a number from 0 to 1023. I will call these “ADC units”.  0V maps to 0 ADC units, VDDA (2.95V on the FRDM-KL25Z board) maps to 1023 ADC units and let’s assume it is linear in between. This means that zero acceleration on an axis should give me a reading of 260 ADC units (0.75V / 2.95V x 1023 ADC units) on the pin for that axis. Also, a change of 1 ADC unit corresponds to a voltage difference of 2.95V / 1023 ADC units = 2.884mV/ADC unit. Since the datasheet says a 1g acceleration typically corresponds to 229mV voltage difference, I can easily convert it to ADC units/g:   229 mV/g = 229 mV/g x (1023 ADC units) / 2.95V = 79.4 ADC units/g = SENSITIVITY_2g   Using this calculated sensitivity and measured offset, I convert the 10-bit ADC values to real acceleration values in g’s in the PIT ISR as follows.   void PIT_IRQHandler() {      ADC0_SC1A = ADC_SC1_ADCH(0x08);                    // Process ADC measurements on ADC0_SE8/XOUT                                                  while(!(ADC0_SC1A & ADC_SC1_COCO_MASK)){};      Xout_10_bit = ADC0_RA;                                         ADC0_SC1A = ADC_SC1_ADCH(0x09);                    // Process ADC measurements on ADC0_SE9/YOUT                while(!(ADC0_SC1A & ADC_SC1_COCO_MASK)){};      Yout_10_bit = ADC0_RA;                                               ADC0_SC1A = ADC_SC1_ADCH(0x0C);                    // Process ADC measurements on ADC0_SE12/ZOUT                while(!(ADC0_SC1A & ADC_SC1_COCO_MASK)){};      Zout_10_bit = ADC0_RA;                    Xout_g = ((float) Xout_10_bit - X_offset) / SENSITIVITY_2G;         // Compute X-axis output value in g's      Yout_g = ((float) Yout_10_bit - Y_offset) / SENSITIVITY_2G;         // Compute Y-axis output value in g's      Zout_g = ((float) Zout_10_bit - Z_offset) / SENSITIVITY_2G;         // Compute Z-axis output value in g's                     PIT_TFLG0 |= PIT_TFLG_TIF_MASK;          // Clear PIT interrupt flag }   4. The calculated values can be watched in the "Variables" window on the top right of the Debug perspective or in the FreeMASTER application. To open and run the FreeMASTER project, install the FreeMASTER application and FreeMASTER Communication Driver.       I guess this is enough to let you start experimenting with the FXLN83xxQ family of analog accelerometers. Attached you can find the complete source code written in the CW for MCU's v10.6 including the FreeMASTER project.   If there are any questions regarding this simple application, do not hesitate to ask below. Your feedback or suggestions are also welcome.   Regards, Tomas Original Attachment has been moved to: FRDM-KL25Z-FXLN8371Q-Basic-read-using-ADC.zip Original Attachment has been moved to: FreeMASTER---FRDM-KL25Z-FXLN8371Q-Basic-read-using-ADC.zip
View full article
The following video shows how to run the FRDM 6DOF Bare Board eCompass using the FRDM-K22. This algorithm uses the FXOS8700 contained on the Freedom Board. In order to get more information about the Sensor Fusion Library for Kinetis MCU's 5.0, please refer to the following link: Sensor Fusion|Freescale I hope this material will be useful for you. David
View full article
Hi Everyone, In my previous tutorial, I demonstrated how to import an ISSDK based example project into MCUXpresso IDE, build and run it on the Freedom board (FRDM-KL27Z). If you want to visualize/log sensor data, easily change sensor settings (ODR, Range, Power Mode) or directly read and write sensor registers, you can use the Freedom Sensor Toolbox-Community Edition (STB-CE) as described below or in the STBCEUG. 1. Connect the SDA port (J13) on the FRDM-KL27Z board to a USB port on your computer. 2. Open STB-CE GUI by double clicking the Freedom Sensor Toolbox (CE) shortcut located on your desktop. 3. Select "Out of Box Sensor Demonstration". 4. Select the Project to be launched and click on Continue. Base Board Name – FRDM-KL27Z Shield Board Name – OnBoard Project Name – MMA8451 Accelerometer Demo 5. The ISSDK-based MMA8451 Accelerometer Demo firmware is loaded to the KL27Z MCU and the MMA8451 Accelerometer Demo v1.0 GUI launched. 6. In the Main screen you can change basic MMA8451Q accelerometer settings (ODR, Range, Power Mode), enable embedded functions (Landsacpe/Portrait, Pulse/Tap, Freefall, Transient), start/stop accelerometer data streaming and/or logging.   7. The Register screen (MMA8451) provides low-level access (R/W) to the MMA8451Q registers along with a detailed description of the selected register. 8. To change the bit value, simply click on the corresponding cell (make sure you selected the Standby mode before writing a new value to the selected register). I hope you find this simple document useful. f there are any questions, please feel free to ask below.  Regards, Tomas
View full article
The FXLN83XX is a 3-axis, low-power, low-g accelerometer along with a CMOS signal conditioning and control ASIC in a small 3 x 3 x 1 mm QFN package. The analog outputs for the X, Y, and Z axes are internally compensated for zero-g offset and sensitivity, and then buffered to the output pads. The outputs have a fixed 0 g offset of 0.75 V, irrespective of the VDD supply voltage. The bandwidth of the output signal for each axis may be independently set using external capacitors. The host can place the FXLN83XXQ into a low-current shutdown mode to conserve power. Here is a Render of the FXLN83XX Breakout Board downloaded from OSH park: Layout Design for this board: In the attachments section, you can find the Schematic Source File (SCH), Schematic PDF File, Layout Source File (BRD), Gerber Files (GTL, GBL, GTS, GBS, GTO, GBO, GKO, XLN) and BOM files.    If you're interested in more designs like this breakout board for other sensors, please go to Freescale Sensors Breakout Boards Designs – HOMEFreescale Sensors Breakout Boards Designs – HOME
View full article
Hi Everyone,   In this document I would like to go through a simple bare-metal example code I created for the recently released FRDMSTBC-A8471 development board with the NXP FXLS8471Q 3-axis linear accelerometer. This board is compatible with most NXP Freedom development boards and I decided to use one of the most popular - FRDM-KL25Z. The FreeMASTER tool is used to visualize the acceleration data that are read from the FXLS8471Q using an interrupt technique through the SPI interface. I will not cover the Sensor Toolbox software and Intelligent Sensing Framework (ISF) which also support this board.   This example illustrates:   1. Initialization of the MKL25Z128 MCU (mainly SPI and PORT modules). 2. SPI data write and read operations. 3. Initialization of the FXLS8471Q to achieve the highest resolution. 4. Simple offset calibration based on the AN4069. 5. Output data reading using an interrupt technique. 6. Conversion of the output values from registers 0x01 – 0x06 to real acceleration values in g’s. 7. Visualization of the output values in the FreeMASTER tool.     1. As you can see in the FRDMSTBC-A8471​/FRDM-KL25Z​ schematics and the image below, SPI signals are routed to the SPI0 module of the KL25Z MCU and the INT1 output is connected to the PTD4 pin. The PTD0 pin (Chip Select) is not controlled automatically by SPI0 module, hence it is configured as a general-purpose output. The INT1 output of the FXLS8471Q is configured as a push-pull active-low output, so the corresponding PTD4 pin configuration is GPIO with an interrupt on falling edge.The core/system clock frequency is 20.97 MHz and SPI clock is 524.25 kHz.     The MCU is, therefore, configured as follows.   /****************************************************************************** * MCU initialization function ******************************************************************************/   void MCU_Init(void) {   //SPI0 module initialization   SIM_SCGC4 |= SIM_SCGC4_SPI0_MASK; // Turn on clock to SPI0 module   SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK; // Turn on clock to Port D module   PORTD_PCR1 = PORT_PCR_MUX(0x02); // PTD1 pin is SPI0 CLK line   PORTD_PCR2 = PORT_PCR_MUX(0x02); // PTD2 pin is SPI0 MOSI line   PORTD_PCR3 = PORT_PCR_MUX(0x02); // PTD3 pin is SPI0 MISO line   PORTD_PCR0 = PORT_PCR_MUX(0x01); // PTD0 pin is configured as GPIO (CS line driven manually)   GPIOD_PSOR |= GPIO_PSOR_PTSO(0x01); // PTD0 = 1 (CS inactive)   GPIOD_PDDR |= GPIO_PDDR_PDD(0x01); // PTD0 pin is GPIO output     SPI0_C1 = SPI_C1_SPE_MASK | SPI_C1_MSTR_MASK; // Enable SPI0 module, master mode   SPI0_BR = SPI_BR_SPPR(0x04) | SPI_BR_SPR(0x02); // BaudRate = BusClock / ((SPPR+1) * 2^(SPR+1)) = 20970000 / ((4+1) * 2^(2+1)) = 524.25 kHz     //Configure the PTD4 pin (connected to the INT1 of the FXLS8471Q) for falling edge interrupts   PORTD_PCR4 |= (0|PORT_PCR_ISF_MASK| // Clear the interrupt flag                   PORT_PCR_MUX(0x1)| // PTD4 is configured as GPIO                   PORT_PCR_IRQC(0xA)); // PTD4 is configured for falling edge interrupts     //Enable PORTD interrupt on NVIC   NVIC_ICPR |= 1 << ((INT_PORTD - 16)%32);   NVIC_ISER |= 1 << ((INT_PORTD - 16)%32); }     2. The FXLS8471Q uses the ‘Mode 0′ SPI protocol, which means that an inactive state of clock signal is low and data are captured on the leading edge of clock signal and changed on the falling edge.   The falling edge on the CS pin starts the SPI communication. A write operation is initiated by transmitting a 1 for the R/W bit. Then the 8-bit register address, ADDR[7:0] is encoded in the first and second serialized bytes. Data to be written starts in the third serialized byte. The order of the bits is as follows:   Byte 0: R/W, ADDR[6], ADDR[5], ADDR[4], ADDR[3], ADDR[2], ADDR[1], ADDR[0] Byte 1: ADDR[7], X, X, X, X, X, X, X Byte 2: DATA[7], DATA[6], DATA[5], DATA[4], DATA[3], DATA[2], DATA[1], DATA[0]   The rising edge on the CS pin stops the SPI communication.   Below is the write operation which writes the value 0x3D to the CTRL_REG1 (0x3A).   Similarly a read operation is initiated by transmitting a 0 for the R/W bit. Then the 8-bit register address, ADDR[7:0] is encoded in the first and second serialized bytes. The data is read from the MISO pin (MSB first).   The screenshot below shows the read operation which reads the correct value 0x6A from the WHO_AM_I register (0x0D).   Multiple read operations are performed similar to single read except bytes are read in multiples of eight SCLK cycles. The register address is auto incremented so that every eighth next clock edges will latch the MSB of the next register.   A burst read of 6 bytes from registers 0x01 to 0x06 is shown below. It also shows how the INT1 pin is automatically cleared by reading the acceleration output data.     3. The dynamic range is set to ±2g and to achieve the highest resolution, the LNOISE bit is set and the lowest ODR (1.56Hz) and the High Resolution mode are selected (more details in AN4075). The DRDY interrupt is enabled and routed to the INT1 interrupt pin that is configured to be a push-pull, active-low output.   /****************************************************************************** * FXLS8471Q initialization function ******************************************************************************/   void FXLS8471Q_Init (void) {   FXLS8471Q_WriteRegister(CTRL_REG2, 0x02); // High Resolution mode   FXLS8471Q_WriteRegister(CTRL_REG3, 0x00); // Push-pull, active low interrupt   FXLS8471Q_WriteRegister(CTRL_REG4, 0x01); // Enable DRDY interrupt   FXLS8471Q_WriteRegister(CTRL_REG5, 0x01); // DRDY interrupt routed to INT1-PTD4   FXLS8471Q_WriteRegister(CTRL_REG1, 0x3D); // ODR = 1.56Hz, Reduced noise, Active mode   }     4. A simple offset calibration method is implemented according to the AN4069​.   /****************************************************************************** * Simple accelerometer offset calibration ******************************************************************************/   void FXLS8471Q_Calibrate (void) {   unsigned char reg_val = 0;     while (!reg_val) // Wait for a first set of data    {     reg_val = FXLS8471Q_ReadRegister(STATUS_REG) & 0x08;   }      FXLS8471Q_ReadMultiRegisters(OUT_X_MSB_REG, 6, AccData); // Read data output registers 0x01-0x06       Xout_14_bit = ((short) (AccData[0]<<8 | AccData[1])) >> 2; // Compute 14-bit X-axis output value   Yout_14_bit = ((short) (AccData[2]<<8 | AccData[3])) >> 2; // Compute 14-bit Y-axis output value   Zout_14_bit = ((short) (AccData[4]<<8 | AccData[5])) >> 2; // Compute 14-bit Z-axis output value      Xoffset = Xout_14_bit / 8 * (-1); // Compute X-axis offset correction value   Yoffset = Yout_14_bit / 8 * (-1); // Compute Y-axis offset correction value   Zoffset = (Zout_14_bit - SENSITIVITY_2G) / 8 * (-1); // Compute Z-axis offset correction value      FXLS8471Q_WriteRegister(CTRL_REG1, 0x00); // Standby mode to allow writing to the offset registers   FXLS8471Q_WriteRegister(OFF_X_REG, Xoffset);   FXLS8471Q_WriteRegister(OFF_Y_REG, Yoffset);   FXLS8471Q_WriteRegister(OFF_Z_REG, Zoffset);      FXLS8471Q_WriteRegister(CTRL_REG1, 0x3D); // ODR = 1.56Hz, Reduced noise, Active mode }     5. In the ISR, only the interrupt flag is cleared and the DataReady variable is set to indicate the arrival of new data.   /****************************************************************************** * PORT D Interrupt handler ******************************************************************************/   void PORTD_IRQHandler() {   PORTD_PCR4 |= PORT_PCR_ISF_MASK; // Clear the interrupt flag   DataReady = 1; }     6. The output values from accelerometer registers 0x01 – 0x06 are first converted to signed 14-bit values and afterwards to real values in g’s.   if (DataReady)     // Is a new set of data ready? {   DataReady = 0;     FXLS8471Q_ReadMultiRegisters(OUT_X_MSB_REG, 6, AccData); // Read data output registers 0x01-0x06                                                    Xout_14_bit = ((short) (AccData[0]<<8 | AccData[1])) >> 2; // Compute 14-bit X-axis output value   Yout_14_bit = ((short) (AccData[2]<<8 | AccData[3])) >> 2; // Compute 14-bit Y-axis output value   Zout_14_bit = ((short) (AccData[4]<<8 | AccData[5])) >> 2; // Compute 14-bit Z-axis output value                                        Xout_g = ((float) Xout_14_bit) / SENSITIVITY_2G; // Compute X-axis output value in g's   Yout_g = ((float) Yout_14_bit) / SENSITIVITY_2G; // Compute Y-axis output value in g's   Zout_g = ((float) Zout_14_bit) / SENSITIVITY_2G; // Compute Z-axis output value in g's }     7. The calculated values can be watched in the "Variables" window on the top right of the Debug perspective or in the FreeMASTER application. To open and run the FreeMASTER project, install the FreeMASTER 2.0 application and FreeMASTER Communication Driver.         Attached you can find the complete source code written in the CW for MCU's v10.6​ including the FreeMASTER project.   If there are any questions regarding this simple application, please feel free to ask below. Your feedback or suggestions are also welcome.   Regards, Tomas
View full article
Hi Everyone,   I would like to share here one of my examples I created for the FXLS8471Q accelerometer while working with the Freescale FRDM-KL25Z platform and FRDM-FXS-MULT2-B sensor expansion board. It illustrates the use of the embedded FIFO buffer to collect the 14-bit acceleration data that are read from the FIFO using an interrupt technique through the SPI interface. For details on the configurations of the FIFO buffer as well as more specific examples and application benefits, please refer to the AN4073.   The FXLS8471Q is initialized as follows:   void FXLS8471Q_Init (void) {/* The software reset does not work properly in SPI mode as described in Appendix A of the FXLS8471Q data sheet. Therefore the following piece of the code is not used. I have shortened R46 on the FRDM-FXS-MULTI-B board to activate a hardware reset. FXLS8471Q_WriteRegister(CTRL_REG2, 0x40); // Reset all registers to POR values */   FXLS8471Q_WriteRegister(CTRL_REG1, 0x00); // Standby mode FXLS8471Q_WriteRegister(F_SETUP_REG, 0xA0); // FIFO Fill mode, 32 samples   FXLS8471Q_WriteRegister(CTRL_REG4, 0x40); // Enable FIFO interrupt, push-pull, active low   FXLS8471Q_WriteRegister(CTRL_REG5, 0x40); // Route the FIFO interrupt to INT1 - PTA5   FXLS8471Q_WriteRegister(CTRL_REG1, 0x19); // ODR = 100Hz, Active mode }       In the ISR, only the interrupt flag is cleared and the FIFO_DataReady variable is set to indicate that the FIFO is full.   void PORTA_IRQHandler() { PORTA_PCR5 |= PORT_PCR_ISF_MASK; // Clear the interrupt flag FIFO_DataReady = 1; }       Once the FIFO_DataReady variable is set, the STATUS register (0x00) is read to clear the FIFO interrupt status bit and deassert the INT1 pin. Afterwars the FIFO is read using a 192-byte (3 x 2 x 32 bytes) burst read starting from the OUT_X_MSB register (0x01). Then the raw acceleration data are converted to signed 14-bit values and real values in g’s.   if (FIFO_DataReady) { FIFO_DataReady = 0; FIFO_Status = FXLS8471Q_ReadRegister(STATUS_REG); // Read the Status register to clear the FIFO interrupt status bit FXLS8471Q_ReadMultiRegisters(OUT_X_MSB_REG, 6*Watermark_Val, AccelData); // Read the FIFO using a burst read     for (i = 0; i < Watermark_Val; i++)   { // 14-bit accelerometer data   Xout_Accel_14_bit[i] = ((short) (AccelData[0 + i*6]<<8 | AccelData[1 + i*6])) >> 2; // Compute 14-bit X-axis acceleration output values   Yout_Accel_14_bit[i] = ((short) (AccelData[2 + i*6]<<8 | AccelData[3 + i*6])) >> 2; // Compute 14-bit Y-axis acceleration output values  Zout_Accel_14_bit[i] = ((short) (AccelData[4 + i*6]<<8 | AccelData[5 + i*6])) >> 2; // Compute 14-bit Z-axis acceleration output values   // Accelerometer data converted to g's   Xout_g[i] = ((float) Xout_Accel_14_bit[i]) / SENSITIVITY_2G; // Compute X-axis output values in g's  Yout_g[i] = ((float) Yout_Accel_14_bit[i]) / SENSITIVITY_2G; // Compute Y-axis output values in g's   Zout_g[i] = ((float) Zout_Accel_14_bit[i]) / SENSITIVITY_2G; // Compute Z-axis output values in g's   } }       Deassertion of the INT1 pin after reading the STATUS register (0x00).       ODR is set to 100Hz, so the FIFO is read every 320 ms (10 ms x 32 samples).       The calculated values can be watched in the "Variables" window on the top right of the Debug perspective.       Attached you can find the complete source code written in the CW for MCU's 10.6. If there are any questions regarding this simple example project, please feel free to ask below. Your feedback or suggestions are also welcome.   Regards, Tomas Original Attachment has been moved to: FRDM-KL25Z-FXLS8471Q-FIFO.rar
View full article
Hi Everyone, In this tutorial I intend to run through my simple bare metal example code I created for the Freescale FRDM-KL25Z platform and the FRDM-STBC-AGM01 board containing a three axis accelerometer + magnetometer (FXOS8700CQ) and a three axis gyroscope (FXAS21002C). I will not cover the Sensor Fusion library and the ISF which also support this board. The FreeMASTER tool is used to visualize all the data that are read from both sensors using an interrupt technique through the I 2 C interface. This example illustrates: 1. Initialization of the MKL25Z128 MCU (mainly I 2 C and PORT modules). 2. I 2 C data write and read operations. 3. Initialization of the FXOS8700CQ and FXAS21002C. 4. Simple accelerometer offset calibration based on the AN4069. 5. Output data reading using an interrupt technique. 6. Conversion of the output raw values to real values in g’s, µT, dps and °C. 7. Visualization of the calculated values in the FreeMASTER tool. 1. As you can see in the FRDM-STBC-AGM01 schematic, both sensors are controlled via I 2 C by default. With jumpers J6 and J7 in their default position (2-3), the I 2 C signals are routed to the I2C1 module (PTC1 and PTC2 pins) of the KL25Z MCU. The INT1_8700 output is connected to the PTD4 pin and the INT1_21002 pin to the PTA5 pin of the KL25Z MCU. These both interrupt pins are configured as push-pull active-low outputs, so the corresponding PTD4/PTA5 pin configuration is GPIO with an interrupt on falling edge. The MCU is, therefore, configured as follows. void MCU_Init(void) {      //I2C1 module initialization      SIM_SCGC4 |= SIM_SCGC4_I2C1_MASK;        // Turn on clock to I2C1 module      SIM_SCGC5 |= SIM_SCGC5_PORTC_MASK;       // Turn on clock to Port C module      PORTC_PCR1 |= PORT_PCR_MUX(0x2);         // PTC1 pin is I2C1 SCL line      PORTC_PCR2 |= PORT_PCR_MUX(0x2);         // PTC2 pin is I2C1 SDA line      I2C1_F  |= I2C_F_ICR(0x14);              // SDA hold time = 2.125us, SCL start hold time = 4.25us, SCL stop hold time = 5.125us      I2C1_C1 |= I2C_C1_IICEN_MASK;            // Enable I2C1 module                       //Configure the PTD4 pin (connected to the INT1 of the FXOS8700CQ) for falling edge interrupts      SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK;       // Turn on clock to Port D module      PORTD_PCR4 |= (0|PORT_PCR_ISF_MASK|      // Clear the interrupt flag                       PORT_PCR_MUX(0x1)|      // PTD4 is configured as GPIO                       PORT_PCR_IRQC(0xA));    // PTD4 is configured for falling edge interrupts                   //Configure the PTA5 pin (connected to the INT1 of the FXAS21002) for falling edge interrupts      SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;       // Turn on clock to Port A module      PORTA_PCR5 |= (0|PORT_PCR_ISF_MASK|      // Clear the interrupt flag                       PORT_PCR_MUX(0x1)|      // PTA5 is configured as GPIO                       PORT_PCR_IRQC(0xA));    // PTA5 is configured for falling edge interrupts                          //Enable PORTD interrupt on NVIC      NVIC_ICPR |= 1 << ((INT_PORTD - 16)%32);      NVIC_ISER |= 1 << ((INT_PORTD - 16)%32);                //Enable PORTA interrupt on NVIC      NVIC_ICPR |= 1 << ((INT_PORTA - 16)%32);      NVIC_ISER |= 1 << ((INT_PORTA - 16)%32); } 2. The 7-bit I 2 C slave address of the FXOS8700CQ is 0x1E since both SA0 and SA1 pins are shorted to GND. The address of the FXAS21002C is 0x20 since SA0 pin is also shorted to GND. The two screenshots below show the write operation which writes the value 0x25 to the CTRL_REG1 (0x2A) of the FXOS8700CQ and 0x16 to the CTRL_REG1 (0x13) of the FXAS21002C. Here is the single byte read from the WHO_AM_I register. As you can see, it returns the correct value 0xC7 for the FXOS8700CQ and 0xD7 for the FXAS21002C. Finally, a burst read of 12 bytes from the FXOS8700CQ output data registers (0x01 – 0x06 and 0x33 – 0x38) and 6 bytes from the FXAS21002C output data registers (0x01 – 0x06) is shown below. 3. At the beginning of the initialization, all registers are reset to their default values by setting the RST bit of the CTRL_REG2 register. Then the FXOS8700CQ is initialized as shown below. void FXOS8700CQ_Init (void) {      I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, CTRL_REG2, 0x40);          // Reset all registers to POR values      Pause(0x631);          // ~1ms delay            I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, XYZ_DATA_CFG_REG, 0x00);   // +/-2g range with 0.244mg/LSB              I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, M_CTRL_REG1, 0x1F);        // Hybrid mode (accelerometer + magnetometer), max OSR      I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, M_CTRL_REG2, 0x20);        // M_OUT_X_MSB register 0x33 follows the OUT_Z_LSB register 0x06 (burst read)                       I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, CTRL_REG2, 0x02);          // High Resolution mode      I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, CTRL_REG3, 0x00);          // Push-pull, active low interrupt      I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, CTRL_REG4, 0x01);          // Enable DRDY interrupt      I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, CTRL_REG5, 0x01);          // DRDY interrupt routed to INT1 - PTD4      I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, CTRL_REG1, 0x25);          // ODR = 25Hz, Reduced noise, Active mode   } And here is the initialization of the FXAS21002C. void FXAS21002C_Init (void) {      I2C_WriteRegister(FXAS21002C_I2C_ADDRESS, GYRO_CTRL_REG1, 0x40);     // Reset all registers to POR values      Pause(0x631);        // ~1ms delay            I2C_WriteRegister(FXAS21002C_I2C_ADDRESS, GYRO_CTRL_REG0, 0x03);     // High-pass filter disabled, +/-250 dps range -> 7.8125 mdps/LSB = 128 LSB/dps      I2C_WriteRegister(FXAS21002C_I2C_ADDRESS, GYRO_CTRL_REG2, 0x0C);     // Enable DRDY interrupt, routed to INT1 - PTA5, push-pull, active low interrupt      I2C_WriteRegister(FXAS21002C_I2C_ADDRESS, GYRO_CTRL_REG1, 0x16);     // ODR = 25Hz, Active mode        } 4. A simple accelerometer offset calibration method is implemented according to the AN4069. void FXOS8700CQ_Accel_Calibration (void) {      char X_Accel_offset, Y_Accel_offset, Z_Accel_offset;            FXOS8700CQ_DataReady = 0;           while (!FXOS8700CQ_DataReady){}           // Is a first set of data ready?      FXOS8700CQ_DataReady = 0;            I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, CTRL_REG1, 0x00);          // Standby mode                 I2C_ReadMultiRegisters(FXOS8700CQ_I2C_ADDRESS, OUT_X_MSB_REG, 6, AccelMagData);          // Read data output registers 0x01-0x06                     Xout_Accel_14_bit = ((short) (AccelMagData[0]<<8 | AccelMagData[1])) >> 2;          // Compute 14-bit X-axis acceleration output value      Yout_Accel_14_bit = ((short) (AccelMagData[2]<<8 | AccelMagData[3])) >> 2;          // Compute 14-bit Y-axis acceleration output value      Zout_Accel_14_bit = ((short) (AccelMagData[4]<<8 | AccelMagData[5])) >> 2;          // Compute 14-bit Z-axis acceleration output value                   X_Accel_offset = Xout_Accel_14_bit / 8 * (-1);          // Compute X-axis offset correction value      Y_Accel_offset = Yout_Accel_14_bit / 8 * (-1);          // Compute Y-axis offset correction value      Z_Accel_offset = (Zout_Accel_14_bit - SENSITIVITY_2G) / 8 * (-1);          // Compute Z-axis offset correction value                   I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, OFF_X_REG, X_Accel_offset);                  I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, OFF_Y_REG, Y_Accel_offset);           I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, OFF_Z_REG, Z_Accel_offset);                        I2C_WriteRegister(FXOS8700CQ_I2C_ADDRESS, CTRL_REG1, 0x25);          // Active mode again } 5. In the ISRs, only the interrupt flags are cleared and the DataReady variables are set to indicate the arrival of new data. void PORTD_IRQHandler() {      PORTD_PCR4 |= PORT_PCR_ISF_MASK;          // Clear the interrupt flag      FXOS8700CQ_DataReady = 1;  } void PORTA_IRQHandler() {      PORTA_PCR5 |= PORT_PCR_ISF_MASK;          // Clear the interrupt flag      FXAS21002C_DataReady = 1;  } 6. The output values from accelerometer registers 0x01 – 0x06 are first converted to signed 14-bit integer values and afterwards to real values in g’s. Similarly, the output values from magnetometer registers 0x33 – 0x38 are first converted to signed 16-bit integer values and afterwards to real values in microtesla (µT). if (FXOS8700CQ_DataReady)          // Is a new set of accel + mag data ready? {                  FXOS8700CQ_DataReady = 0;                                                                                                                          I2C_ReadMultiRegisters(FXOS8700CQ_I2C_ADDRESS, OUT_X_MSB_REG, 12, AccelMagData);         // Read FXOS8700CQ data output registers 0x01-0x06 and 0x33 - 0x38                     // 14-bit accelerometer data      Xout_Accel_14_bit = ((short) (AccelMagData[0]<<8 | AccelMagData[1])) >> 2;        // Compute 14-bit X-axis acceleration output value      Yout_Accel_14_bit = ((short) (AccelMagData[2]<<8 | AccelMagData[3])) >> 2;        // Compute 14-bit Y-axis acceleration output value      Zout_Accel_14_bit = ((short) (AccelMagData[4]<<8 | AccelMagData[5])) >> 2;        // Compute 14-bit Z-axis acceleration output value                              // Accelerometer data converted to g's      Xout_g = ((float) Xout_Accel_14_bit) / SENSITIVITY_2G;        // Compute X-axis output value in g's      Yout_g = ((float) Yout_Accel_14_bit) / SENSITIVITY_2G;        // Compute Y-axis output value in g's      Zout_g = ((float) Zout_Accel_14_bit) / SENSITIVITY_2G;        // Compute Z-axis output value in g's                               // 16-bit magnetometer data                   Xout_Mag_16_bit = (short) (AccelMagData[6]<<8 | AccelMagData[7]);          // Compute 16-bit X-axis magnetic output value      Yout_Mag_16_bit = (short) (AccelMagData[8]<<8 | AccelMagData[9]);          // Compute 16-bit Y-axis magnetic output value      Zout_Mag_16_bit = (short) (AccelMagData[10]<<8 | AccelMagData[11]);        // Compute 16-bit Z-axis magnetic output value                                                         // Magnetometer data converted to microteslas      Xout_uT = (float) (Xout_Mag_16_bit) / SENSITIVITY_MAG;        // Compute X-axis output magnetic value in uT      Yout_uT = (float) (Yout_Mag_16_bit) / SENSITIVITY_MAG;        // Compute Y-axis output magnetic value in uT      Zout_uT = (float) (Zout_Mag_16_bit) / SENSITIVITY_MAG;        // Compute Z-axis output magnetic value in uT              } Similarly, the output values from gyroscope registers 0x01 – 0x06 are first converted to signed 16-bit integer values and afterwards to real values in degrees per second. Temperature is also read out from the 0x12 register. if (FXAS21002C_DataReady)         // Is a new set of gyro data ready? {                  FXAS21002C_DataReady = 0;                                                                                                                                       I2C_ReadMultiRegisters(FXAS21002C_I2C_ADDRESS, GYRO_OUT_X_MSB_REG, 6, GyroData);         // Read FXAS21002C data output registers 0x01-0x06                                   // 16-bit gyro data      Xout_Gyro_16_bit = (short) (GyroData[0]<<8 | GyroData[1]);           // Compute 16-bit X-axis output value      Yout_Gyro_16_bit = (short) (GyroData[2]<<8 | GyroData[3]);           // Compute 16-bit Y-axis output value      Zout_Gyro_16_bit = (short) (GyroData[4]<<8 | GyroData[5]);           // Compute 16-bit Z-axis output value                                           // Gyro data converted to dps      Roll = (float) (Xout_Gyro_16_bit) / SENSITIVITY_250;          // Compute X-axis output value in dps      Pitch = (float) (Yout_Gyro_16_bit) / SENSITIVITY_250;         // Compute Y-axis output value in dps      Yaw = (float) (Zout_Gyro_16_bit) / SENSITIVITY_250;           // Compute Z-axis output value in dps                               // Temperature data      Temp = I2C_ReadRegister(FXAS21002C_I2C_ADDRESS, GYRO_TEMP_REG);                   }   7. The calculated values can be watched in the "Variables" window on the top right of the Debug perspective or in the FreeMASTER application. To open and run the FreeMASTER project, install the FreeMASTER application​ and FreeMASTER Communication Driver. I guess this is enough to let you start experimenting with the FRDM-STBC-AGM01 board. Attached you can find the complete source code written in the CW for MCU's v10.6 including the FreeMASTER project. If there are any questions regarding this simple application, do not hesitate to ask below. Your feedback or suggestions are also welcome. Regards, Tomas
View full article
Hi, The MMA865x, 3-axis, 10-bit/12-bit accelerometer that has industry leading performance in a small 2 x 2 x 1 mm DFN package. This accelerometer is packed with embedded functions that include flexible user-programmable options and two configurable interrupt pins. Overall power savings is achieved through inertial wake-up interrupt signals that monitor events and remain in a low-power mode during periods of inactivity. Here is a Render of the MMA865x Breakout- Board downloaded from OSH park: Layout Design for this board: In the attachments section, you can find the Schematic Source File (SCH), Schematic PDF File, Layout Source File (BRD), Gerber Files (GTL, GBL, GTS, GBS, GTO, GBO, GKO, XLN) and BOM files. If you're interested in more designs like this breakout board for other sensors, please go to Freescale Sensors Breakout Boards Designs – HOME
View full article
Video clip associated with "Android as a Platform for Sensor Fusion Education and Evaluation" presented at 2013 Sensors Expo & Conference by Michael Stanley.
View full article
This is a step-by-step guide document to set the FRDM-K64F-AGM01 on the Freescale Sensor Fusion Toolbox Software.
View full article
The MMA690x, a SafeAssure solution, is a dual axis, Low g, XY, Sensorbased on Freescale’s HARMEMS technology, with an embedded DSP ASIC, allowing for additional processing of the digital signals. Here is a Render of the MMA690x Breakout Board downloaded from OSH park: Layout Design for this board: In the attachments section, you can find the Schematic Source File (SCH), Schematic PDF File, Layout Source File (BRD), Gerber Files (GTL, GBL, GTS, GBS, GTO, GBO, GKO, XLN) and BOM files.   If you're interested in more designs like this breakout board for other sensors, please go to Freescale Sensors Breakout Boards Designs – HOME
View full article
clicktaleID