Login| Sign Up| Help| Contact|

Patent Searching and Data


Title:
ACOUSTIC AND VIBRATION SENSING APPARATUS AND METHOD FOR MONITORING CUTTING TOOL OPERATION
Document Type and Number:
WIPO Patent Application WO/2017/083120
Kind Code:
A1
Abstract:
A universal manufacturing vise jaw plate for use on a machine tool with a vise fixture, and configured for real-time operational data collection and analysis. The vise plate comprises a combination of acoustic and vibration sensors with a plate for cutting tool monitoring applications.

Inventors:
BHINGE RAUNAK (US)
CHEN YUNG-CHIH (US)
CHOI JINSU (US)
DAI JENNIFER (US)
MUSIAL WOJCIECH (US)
GENTILE RHETT (US)
DORNFELD DAVID
Application Number:
PCT/US2016/059441
Publication Date:
May 18, 2017
Filing Date:
October 28, 2016
Export Citation:
Click for automatic bibliography generation   Help
Assignee:
UNIV CALIFORNIA (US)
International Classes:
B23Q17/09
Foreign References:
JPH07308847A1995-11-28
CN204639977U2015-09-16
JP2002268742A2002-09-20
US4911002A1990-03-27
KR950005451A1995-03-20
Attorney, Agent or Firm:
O'BANION, John (US)
Download PDF:
Claims:
CLAIMS

What is claimed is

1 . An apparatus for monitoring operation of a machine tool while ining a workpiece restrained by a vise, the apparatus comprising:

(a) a universal vise jaw plate coupled to the vise and the workpiece;

(b) a sensor assembly disposed within a cavity of the vise jaw plate;

(c) the sensor assembly comprising:

(i) a processor;

(ii) an accelerometer coupled to the processor;

(iii) an acoustic sensor coupled to the processor;

(iv) a memory storing instructions executable by the processor;

(v) wherein said instructions, when executed by the processor, perform steps of acquiring vibration data and acoustic data from the accelerometer and acoustic sensor to perform real-time monitoring of the machine tool.

2. The apparatus of claim 1 , the sensor assembly further comprising:

(vi) a wireless transceiver connected to the processor, the wireless transceiver configured for transmitting the acquired vibration data and acoustic data to an external device.

3. The apparatus of claim 1 , further comprising:

(d) a sensor housing fitted within the cavity of the vise jaw plate, the sensor housing configured for housing the sensor assembly.

4. The apparatus of claim 1 , wherein said instructions when executed by the processor, further perform steps comprising:

acquiring vibration data from the accelerometer and storing the data in a buffer with timestamps;

acquiring acoustic data from the acoustic sensor and storing the data in a buffer with timestamps; and

combining the collected vibration and acoustic data for real-time monitoring of the machine tool.

5. The apparatus of claim 4, wherein said instructions when executed by the processor, further perform steps comprising:

wirelessly sending the combined data in a single data package to an external data monitoring device.

6. The apparatus of claim 4, wherein said real-time monitoring comprises determining a condition of the machine tool from the combined data.

7. The apparatus of claim 4, wherein the accelerometer is sampled at a frequency to provide high resolution data of the vibrations of the workpiece due to cutting forces applied with the machine tool.

8. The apparatus of claim 4, wherein the acoustic sensor is sampled at a frequency to provide high frequency data of the workpiece due to cutting forces applied with the machine tool.

9. A method for monitoring operation of a machine tool, the method comprising:

coupling a universal vise jaw plate coupled to a vise and a workpiece; acquiring vibration data and acoustic data from a location within the vise jaw plate; and

determining a condition of the machine tool as a function of the acquired accelerometer and acoustic data.

10. The method of claim 9, further comprising:

wirelessly transmitting the acquired vibration data and acoustic data to an external device.

1 1 . The method of claim 9, further comprising:

acquiring vibration data from an accelerometer at the location within the vise base plate and storing the data in a buffer with timestamps;

acquiring acoustic data from an acoustic sensor at the location within the vise base plate and storing the data in a buffer with timestamps; and

combining the collected vibration and acoustic data for real-time monitoring of the machine tool condition.

12. The method of claim 1 1 , further comprising:

wirelessly sending the combined data in a single data package to an external a data monitoring device.

13. The method of claim 1 1 , wherein acquiring vibration data comprises sampling the accelerometer at a frequency to provide high resolution data of the vibrations of the workpiece due to cutting forces applied with the machine tool.

14. The method of claim 1 1 , wherein acquiring acoustic data comprises sampling the acoustic sensor at a frequency to provide high frequency data of the workpiece due to cutting forces applied with the machine tool.

15. An apparatus for monitoring operation of a machine tool while machining a workpiece restrained by a vise and a universal vise jaw plate coupled to the vise and workpiece, the apparatus comprising:

(a) a processor; and

(b) a memory storing instructions executable by the processor;

(c) wherein said instructions, when executed by the processor, perform steps comprising:

(i) acquiring vibration data and acoustic data from a location within the vise jaw plate; and

(ii) determining a condition of the machine tool as a function of the acquired accelerometer and acoustic data.

16. The apparatus of claim 15, wherein said instructions, when executed by the processor, further perform steps comprising:

(iii) wirelessly transmitting the acquired vibration data and acoustic data to an external device.

17. The apparatus of claim 15, wherein determining a condition of the machine tool comprises:

acquiring vibration data from an accelerometer at the location within the vise base plate and storing the data in a buffer with timestamps;

acquiring acoustic data from an acoustic sensor at the location within the vise base plate and storing the data in a buffer with timestamps; and

combining the collected vibration and acoustic data for real-time monitoring of the machine tool condition.

18. The apparatus of claim 17, said instructions configured to perform steps further comprising:

wirelessly sending the combined data in a single data package to an external a data monitoring device.

19. The apparatus of claim 17, wherein acquiring vibration data comprises sampling the accelerometer at a frequency to provide high resolution data of the vibrations of the workpiece due to cutting forces applied with the machine tool.

20. The apparatus of claim 17, wherein acquiring acoustic data comprises sampling the acoustic sensor at a frequency to provide high frequency data of the workpiece due to cutting forces applied with the machine tool.

Description:
ACOUSTIC AND VIBRATION SENSING APPARATUS AND METHOD FOR MONITORING CUTTING TOOL OPERATION

CROSS-REFERENCE TO RELATED APPLICATIONS

[0001] This application claims priority to, and the benefit of, U.S. provisional patent application serial number 62/254,686 filed on November 12, 2015, incorporated herein by reference in its entirety.

STATEMENT REGARDING FEDERALLY SPONSORED RESEARCH OR DEVELOPMENT

Not Applicable

INCORPORATION-BY-REFERENCE OF

COMPUTER PROGRAM APPENDIX

[0003] Not Applicable

NOTICE OF MATERIAL SUBJECT TO COPYRIGHT PROTECTION

[0004] A portion of the material in this patent document is subject to

copyright protection under the copyright laws of the United States and of other countries. The owner of the copyright rights has no objection to the facsimile reproduction by anyone of the patent document or the patent disclosure, as it appears in the United States Patent and Trademark Office publicly available file or records, but otherwise reserves all copyright rights whatsoever. The copyright owner does not hereby waive any of its rights to have this patent document maintained in secrecy, including without limitation its rights pursuant to 37 C.F.R. § 1 .14.

BACKGROUND

[0005] 1 . Technical Field

[0006] This description pertains generally to machine tool operation, and more particularly to sensing for cutting tool operation. [0007] 2. Background Discussion

[0008] Generally, machine tools use vise fixtures on their beds to clamp a workpiece in place during the manufacturing process. A cutting tool is used in manufacturing operations such as drilling and milling to remove material from a workpiece at a certain material removal rate in order to create a feature. During the process of material removal, the cutting tool wears out. The condition of the cutting tool during the process of material removal depends on several factors, as well as random chance, and is impossible to know precisely a priori. Cutting with a worn cutting tool has adverse effects on the quality of the feature produced as well as the machine tool itself. For example, cutting with a worn cutting tool may result in cutting tool failures which lead to unexpected downtime, poor quality production, and stress on the machine tool.

[0009] Typically, cutting tools are replaced with a predefined set frequency in order to avoid cutting with a worn out tool. The cutting tool replacement frequency is generally based on prior knowledge of the cutting process and historical tool failures, and does not depend on the actual condition of the cutting tool. This leads to inefficiencies in cutting tool usage such that a cutting tool in a good condition is replaced prematurely, or a cutting tool in a bad condition is used for too long resulting in adverse effects described above.

[0010] It is currently difficult to monitor the current condition of the cutting tool in real-time to be able to diagnose the life of the cutting tool. Several attempts, especially involving the cutting tool or the tool holder, have been made at extracting data indicative of the condition of the cutting tool, but no data source with a common location across different machine tools has been developed to date.

BRIEF SUMMARY

[0011] The technology described herein is a universal manufacturing vise jaw plate for use on a machine tool with a vise fixture, and configured for real-time operational data collection and analysis. In one embodiment, the technology comprises a combination of acoustic and vibration sensors with the form factor of a universal manufacturing vise jaw plate for cutting tool monitoring applications. However, the technology is not restricted to machine tools alone, but can also be used in material handling equipment with universal vise jaws for real-time data collection. Beneficially, the technology will provide manufacturers with a source of real-time operational data that is indicative of the cutting tool condition when using machine tools with vise fixtures. The technology can be used in place of ordinary vise jaw plates, a design which is standardized across many machine tools.

[0012] Further aspects of the technology will be brought out in the following portions of the specification, wherein the detailed description is for the purpose of fully disclosing preferred embodiments of the technology without placing limitations thereon. BRIEF DESCRIPTION OF THE SEVERAL VIEWS

OF THE DRAWING(S)

[0013] The technology described herein will be more fully understood by reference to the following drawings which are for illustrative purposes only:

[0014] FIG. 1 shows a perspective view of a sensor housing and universal vise jaw plate assembly according to an embodiment of the technology described herein.

[0015] FIG. 2 is a perspective view of the sensor housing for fitting within the jaw plate assembly of FIG. 1.

[0016] FIG. 3 is a perspective view of the sensor housing assembled with sensor electronics according to an embodiment of the technology described herein.

[0017] FIG. 4 shows a functional block diagram of the sensor electronics assembly of the jaw plate assembly according to an embodiment of the technology described herein.

[0018] FIG. 5 is a schematic circuit diagram showing connections between certain components of the sensor electronics assembly shown in FIG. 4.

[0019] FIG. 6 is a flow diagram showing steps of data acquisition and processing according to an embodiment of the technology described herein.

DETAILED DESCRIPTION

[0020] FIG. 1 shows a perspective view of a sensor housing and universal vise jaw plate assembly 10 according to an embodiment of the present technology. The universal vise jaw plate assembly 10 comprises a vise jaw plate 12 housing an acoustic and vibration sensing apparatus 20 for monitoring the operation of cutting tools while using a vise (not shown).

[0021] The vise jaw plate 12 is generally one of a pair of plates used for clamping and locking the position of a workpiece with respect to the cutting tool (not shown). The plate 12 comprises a pair of countersunk thru holes 14 for mounting the plate to one side of the vise (the second plate (not shown) is mounted on the opposing side of the clamp.) Universal vise jaw plates typically come in different sizes for different machine tools, the most frequently used being the 4", 6", and 8" vise jaw plates. These vise jaw plates can be used with any vise from any vise manufacturer due to the standardized design. This ensures a common location of the sensors across different machine tools and vises and, hence, ensures a common data source and comparable data.

[0022] FIG. 1 illustrates a standard 6" vise jaw plate 12 that has been

modified to include a hollowed-out pocket 16 according to an embodiment of the technology described herein. Fitted within the pocket 16 of the vise jaw plate12 is a sensor housing 20, which is shown in greater detail in FIG. 2. The sensor housing 20 is preferably press-fit into the pocket of 16 the vise jaw plate 12. However, other fastening means are also contemplated. Finger pockets 22, 26 at the top of the sensor housing 20 allow for easy access and replacement of the sensor housing. Sensor housing 20 further comprises a lateral cavity 24 for housing the sensor electronics assembly or package 30, as shown in FIG. 3.

[0023] FIG. 4 shows a functional block diagram of the sensor electronics assembly 30 of the jaw plate assembly 10. In one embodiment, the components used in the sensor assembly 30 comprise an accelerometer 32 for measuring vibration and a microphone 34 for acoustic sensing. Both sensors 32, 34 are coupled to a processor (e.g. MCU 36), which is configured to control operation of the sensors 32, 34, in addition to process data received from sensors 32, 34, via application programming 48.

Application programming 48 comprises instructions stored in memory 46 and executable on processor 36. Processor 36 is also coupled to wireless transceiver 38 for communication with an external device 40. Sensor package 30 is powered via a battery 42, which may be recharged via charger 44.

[0024] In one exemplary embodiment, the accelerometer 32 comprises a Bosch BMX055 digital 9-axis accelerometer, microphone 34 comprises an InvenSense ICS-43432 low-noise microphone with l 2 S digital output, MCU 36 comprises a Teensy 3.2 microcontroller, wireless transceiver 38 comprises a CC2541 Bluetooth communication module, and battery 42 comprises a 3.7V 170mAh LiPo battery. It is appreciated that the above embodiment is for illustrative purposes only, and other component configurations are also contemplated.

[0025] FIG. 5 is a schematic circuit diagram showing pinouts and

connections between accelerometer 32, microphone 34, MCU 36 and wireless transceiver 38 electronics of the sensor package 30. It is appreciated that the connections are not restricted to those shown in FIG. 5, but different communication pins on the processor 36 (e.g. Teensy 3.2) can be used for the same results.

[0026] Referring now to sensing method 100 shown in the process flow diagram of FIG. 6, one preferred sensing embodiment utilizes two streams of real-time data (e.g. vibration data and acoustic data) that are acquired from sensing circuitry 30. At step 102, the accelerometer 32 is sampled at a frequency of 1000Hz to provide high resolution data of the vibrations of the workpiece due to the cutting forces. Data from the accelerometer is collected in a buffer with timestamps at step 104. At step 106, the acoustic sensor (e.g., microphone 34) is sampled at 8000Hz to provide high frequency information of the cutting forces, as well as the instantaneous condition of the tool and cutting conditions. Data from the acoustic sensor is collected in a buffer with timestamps at step 108. At step 1 10, the two sources of data are combined together with their timestamps and sent wirelessly in a single data package through wireless data transceiver 38 to a data monitoring device 40 such as a computer, a process controller, and/or a visual display. In one embodiment, wireless communication is accomplished via a Bluetooth Low Energy (BLE) module.

[0027] While sensor electronics assembly 30 is primarily configured to

acquire vibration data and acoustic data, it is appreciated that other forms of sensors, e.g. thermometers, pressure sensors, strain gauges, etc.) may also be implemented to acquire additional sensor data (e.g. temperature, pressure, strain, etc.).

[0028] In one embodiment, the accelerometer 32 communicates using the l 2 C protocol, whereas the microphone communicates using the l 2 S protocol. The wireless (Bluetooth) data communication is over serial data transfer. The output data may be further processed using via external device 40 via applications such as tool condition monitoring and process optimization. Table 1 provides an embodiment of instructions contained in application programming 48 the may be executable on a processor 36 (e.g. Teensy 3.2 microcontroller) to perform the functions shown in method 10 of FIG. 6.

[0029] Embodiments of the present technology may be described with

reference to flowchart illustrations of methods and systems according to embodiments of the technology, and/or algorithms, formulae, or other computational depictions, which may also be implemented as computer program products. In this regard, each block or step of a flowchart, and combinations of blocks (and/or steps) in a flowchart, algorithm, formula, or computational depiction can be implemented by various means, such as hardware, firmware, and/or software including one or more computer program instructions embodied in computer-readable program code logic. As will be appreciated, any such computer program instructions may be loaded onto a computer, including without limitation a general purpose computer or special purpose computer, or other programmable processing apparatus to produce a machine, such that the computer program instructions which execute on the computer or other programmable processing apparatus create means for implementing the functions specified in the block(s) of the flowchart(s).

[0030] Accordingly, blocks of the flowcharts, algorithms, formulae, or

computational depictions support combinations of means for performing the specified functions, combinations of steps for performing the specified functions, and computer program instructions, such as embodied in computer-readable program code logic means, for performing the specified functions. It will also be understood that each block of the flowchart illustrations, algorithms, formulae, or computational depictions and combinations thereof described herein, can be implemented by special purpose hardware-based computer systems which perform the specified functions or steps, or combinations of special purpose hardware and computer-readable program code logic means.

[0031] Furthermore, these computer program instructions, such as

embodied in computer-readable program code logic, may also be stored in a computer-readable memory that can direct a computer or other programmable processing apparatus to function in a particular manner, such that the instructions stored in the computer-readable memory produce an article of manufacture including instruction means which implement the function specified in the block(s) of the flowchart(s). The computer program instructions may also be loaded onto a computer or other programmable processing apparatus to cause a series of operational steps to be performed on the computer or other programmable processing apparatus to produce a computer-implemented process such that the instructions which execute on the computer or other programmable processing apparatus provide steps for implementing the functions specified in the block(s) of the flowchart(s), algorithm(s), formula(e), or computational depiction(s).

[0032] It will further be appreciated that the terms "programming" or

"program executable" as used herein refer to one or more instructions that can be executed by a processor to perform a function as described herein. The instructions can be embodied in software, in firmware, or in a combination of software and firmware. The instructions can be stored local to the device in non-transitory media, or can be stored remotely such as on a server, or all or a portion of the instructions can be stored locally and remotely. Instructions stored remotely can be downloaded (pushed) to the device by user initiation, or automatically based on one or more factors. It will further be appreciated that as used herein, that the terms processor, computer processor, central processing unit (CPU), and computer are used synonymously to denote a device capable of executing the instructions and communicating with input/output interfaces and/or peripheral devices.

[0033] From the description herein, it will be appreciated that that the

present disclosure encompasses multiple embodiments which include, but are not limited to, the following:

[0034] 1 . An apparatus for monitoring operation of a machine tool while machining a workpiece restrained by a vise, the apparatus comprising: (a) a universal vise jaw plate coupled to the vise and the workpiece; (b) a sensor assembly disposed within a cavity of the vise jaw plate; (c) the sensor assembly comprising: (i) a processor; (ii) an accelerometer coupled to the processor; (iii) an acoustic sensor coupled to the processor; (iv) a memory storing instructions executable by the processor; (v) wherein said

instructions, when executed by the processor, perform steps of acquiring vibration data and acoustic data from the accelerometer and acoustic sensor to perform real-time monitoring of the machine tool.

[0035] 2. The apparatus of any preceding embodiment, the sensor

assembly further comprising: (vi) a wireless transceiver connected to the processor, the wireless transceiver configured for transmitting the acquired vibration data and acoustic data to an external device.

[0036] 3. The apparatus of any preceding embodiment, further comprising:

(d) a sensor housing fitted within the cavity of the vise jaw plate, the sensor housing configured for housing the sensor assembly.

[0037] 4. The apparatus of any preceding embodiment, wherein said instructions when executed by the processor, further perform steps comprising: acquiring vibration data from the accelerometer and storing the data in a buffer with timestamps; acquiring acoustic data from the acoustic sensor and storing the data in a buffer with timestamps; and combining the collected vibration and acoustic data for real-time monitoring of the machine tool.

[0038] 5. The apparatus of any preceding embodiment, wherein said

instructions when executed by the processor, further perform steps comprising: wirelessly sending the combined data in a single data package to an external data monitoring device.

[0039] 6. The apparatus of any preceding embodiment, wherein said realtime monitoring comprises determining a condition of the machine tool from the combined data.

[0040] 7. The apparatus of any preceding embodiment, wherein the

accelerometer is sampled at a frequency to provide high resolution data of the vibrations of the workpiece due to cutting forces applied with the machine tool.

[0041] 8. The apparatus of any preceding embodiment, wherein the

acoustic sensor is sampled at a frequency to provide high frequency data of the workpiece due to cutting forces applied with the machine tool.

[0042] 9. A method for monitoring operation of a machine tool, the method comprising: coupling a universal vise jaw plate coupled to a vise and a workpiece; acquiring vibration data and acoustic data from a location within the vise jaw plate; and determining a condition of the machine tool as a function of the acquired accelerometer and acoustic data.

[0043] 10. The method of any preceding embodiment, further comprising: wirelessly transmitting the acquired vibration data and acoustic data to an external device.

[0044] 1 1 . The method of any preceding embodiment, further comprising: acquiring vibration data from an accelerometer at the location within the vise base plate and storing the data in a buffer with timestamps; acquiring acoustic data from an acoustic sensor at the location within the vise base plate and storing the data in a buffer with timestamps; and combining the collected vibration and acoustic data for real-time monitoring of the machine tool condition.

[0045] 12. The method of any preceding embodiment, further comprising: wirelessly sending the combined data in a single data package to an external a data monitoring device.

[0046] 13. The method of any preceding embodiment, wherein acquiring vibration data comprises sampling the accelerometer at a frequency to provide high resolution data of the vibrations of the workpiece due to cutting forces applied with the machine tool.

[0047] 14. The method of any preceding embodiment, wherein acquiring acoustic data comprises sampling the acoustic sensor at a frequency to provide high frequency data of the workpiece due to cutting forces applied with the machine tool.

[0048] 15. An apparatus for monitoring operation of a machine tool while machining a workpiece restrained by a vise and a universal vise jaw plate coupled to the vise and workpiece, the apparatus comprising: (a) a processor; and (b) a memory storing instructions executable by the processor; (c) wherein said instructions, when executed by the processor, perform steps comprising: (i) acquiring vibration data and acoustic data from a location within the vise jaw plate; and (ii) determining a condition of the machine tool as a function of the acquired accelerometer and acoustic data.

[0049] 16. The apparatus of any preceding embodiment, wherein said

instructions, when executed by the processor, further perform steps comprising: (iii) wirelessly transmitting the acquired vibration data and acoustic data to an external device.

[0050] 17. The apparatus of any preceding embodiment, wherein

determining a condition of the machine tool comprises: acquiring vibration data from an accelerometer at the location within the vise base plate and storing the data in a buffer with timestamps; acquiring acoustic data from an acoustic sensor at the location within the vise base plate and storing the data in a buffer with timestamps; and combining the collected vibration and acoustic data for real-time monitoring of the machine tool condition.

[0051] 18. The apparatus of any preceding embodiment, said instructions configured to perform steps further comprising: wirelessly sending the combined data in a single data package to an external a data monitoring device.

[0052] 19. The apparatus of any preceding embodiment, wherein acquiring vibration data comprises sampling the accelerometer at a frequency to provide high resolution data of the vibrations of the workpiece due to cutting forces applied with the machine tool.

[0053] 20. The apparatus of any preceding embodiment, wherein acquiring acoustic data comprises sampling the acoustic sensor at a frequency to provide high frequency data of the workpiece due to cutting forces applied with the machine tool.

[0054] Although the description herein contains many details, these should not be construed as limiting the scope of the disclosure but as merely providing illustrations of some of the presently preferred embodiments. Therefore, it will be appreciated that the scope of the disclosure fully encompasses other embodiments which may become obvious to those skilled in the art.

[0055] In the claims, reference to an element in the singular is not intended to mean "one and only one" unless explicitly so stated, but rather "one or more." All structural, chemical, and functional equivalents to the elements of the disclosed embodiments that are known to those of ordinary skill in the art are expressly incorporated herein by reference and are intended to be encompassed by the present claims. Furthermore, no element, component, or method step in the present disclosure is intended to be dedicated to the public regardless of whether the element, component, or method step is explicitly recited in the claims. No claim element herein is to be construed as a "means plus function" element unless the element is expressly recited using the phrase "means for". No claim element herein is to be construed as a "step plus function" element unless the element is expressly recited using the phrase "step for"

Table 1

Firmware

/^include "Wire.h"

include <i2cj3.h>

include <SPI.h>

include <Adafruit_GFX.h>

include <Adafruit_PCD8544.h> /* I2S digital audio */

#include <i2s.h>

/* Timekeeping library

#include <Time.h> */

// TODO: this is probably not needed for us.

// Using NOKIA 5110 monochrome 84 x 48 pixel display

// pin 7 - Serial clock out (SCLK)

// pin 6 - Serial data out (DIN)

// pin 5 - Data/Command select (D/C)

// pin 3 - LCD chip select (SCE)

// pin 4 - LCD reset (RST)

Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 3, 4);

// See MS5637-02BA03 Low Voltage Barometric Pressure Sensor Data Sheet http://www.meas-spec.com/downloads/MS5637-02BA03.pdf

#define MS5637_RESET OxlE

#define MS5637_CONVERT_Dl 0x40

#define MS5637_CONVERT_D2 0x50

#define MS5637_ADC_READ 0x00

// BMX055 data sheet http://ae- bst.resource.bosch.com/media/products/dokumente/bmx055/BST-B MX055-DS000- 01v2.pdf

// The BMX055 is a conglomeration of three separate motion sensors packaged together but

// addressed and communicated with separately by design

// Accelerometer registers

#define BMX055 ACC WHOAMI 0x00 // should return OxF A

//#define BMX055 ACC Reserved 0x01

#define BMX055 ACC D X LSB 0x02

#define BMX055 ~ ACC " D " X MSB 0x03

#define BMX055 ~ ACC " D " " Y " LSB 0x04

#define BMX055 " ACC " D " " Y " MSB 0x05

#define BMX055 " ACC " D " " z " LSB 0x06 #define BMX055_ACC_D_Z_MSB 0x07 #define BMX055_ACC_D_TEMP 0x08 #define BMX055_ACC_INT_STATUS_0 0x09 #define BMX055_ACC_INT_STATUS_1 OxOA #defme BMX055_ACC_INT_STATUS_2 OxOB #defme BMX055_ACC_INT_STATUS_3 OxOC //#define BMX055_ACC_Reserved OxOD

#define BMX055 ACC FIFO STATUS OxOE #define BMX055 ACC PMU RANGE OxOF #defme BMX055 ACC PMU BW 0x10 #defme BMX055 ACC PMU LPW Ox 11 #define BMX055_ACC_PMU_LOW_POWER 0x12 #define BMX055_ACC_D_HBW 0x13 #define BMX055 ACC BGW SOFTRESET 0x14 //#define BMX055_ACC_Reserved 0x15

#defme BMX055_ACC_INT_EN_0 Ox 16 #define BMX055_ACC_INT_EN_l 0x17 #defme BMX055_ACC_INT_EN_2 Ox 18 #define BMX055_ACC_INT_MAP_0 0x19 #define BMX055_ACC_INT_MAP_l OxlA #define BMX055_ACC_INT_MAP_2 OxlB //#define BMX055_ACC_Reserved OxlC

//#define BMX055_ACC_Reserved OxlD

#define BMX055_ACC_INT_SRC OxlE //#define BMX055 ACC Reserved OxlF

#defme BMX055 ACC INT OUT CTRL 0x20

#define BMX055 ~ ACC INT RST LATCH 0x21

#define BMX055 " ACC INT " 0 0x22

#define BMX055 " ACC INT " " l 0x23

#define BMX055 " ACC INT " " 2 0x24

#define BMX055 ~ ACC " INT " " 3 0x25

#define BMX055 " ACC " INT " " 4 0x26

#define BMX055 " ACC " INT " " 5 0x27

#define BMX055 " ACC " INT " " 6 0x28

#define BMX055 " ACC " INT " " 7 0x29

#define BMX055 " ACC " INT " " 8 0x2A

#define BMX055 " ACC " INT " " 9 0x2B

#define BMX055 " ACC " INT " " A 0x2C

#defme BMX055 " ACC " INT " " B 0x2D

#define BMX055 " ACC " INT " " c 0x2E

#define BMX055 " ACC " INT " D 0x2F

#defme BMX055 " ACC FIFO CONFIG O 0x30

//#defme BMX055_ACC_Reserved 0x31

#defme BMX055_ACC_PMU_SELF_TEST 0x32 #define BMX055_ACC_TRIM_NVM_CTRL 0x33 #define BMX055_ACC_BGW_SPI3_WDT 0x34 //#define BMX055 ACC Reserved 0x35 #define BMX055_ACC_OFC_CTRL 0x36

#defme BMX055 ACC OFC SETTING 0x37

#defme BMX055_ACC_OFC_OFFSET_X 0x38

#defme BMX055_ACC_OFC_OFFSET_Y 0x39

#define BMX055_ACC_OFC_OFFSET_Z 0x3A

#define BMX055_ACC_TRIM_GPO 0x3B

#define BMX055_ACC_TRIM_GPl 0x3C

//#define BMX055_ACC_Reserved 0x3D

#defme BMX055_ACC_FIFO_CONFIG_1 0x3E

#define BMX055 ACC FIFO DATA 0x3F

// BMX055 Gyroscope Registers

#define BMX055 GYRO WHOAMI 0x00 // should return OxOF

//#define BMX055_GYRO_Reserved 0x01

#define BMX055_GYRO_RATE_X_LSB 0x02

#defme BMX055_GYRO_RATE_X_MSB 0x03

#define BMX055_GYRO_RATE_Y_LSB 0x04

#defme BMX055_GYRO_RATE_Y_MSB 0x05

#defme BMX055_GYRO_RATE_Z_LSB 0x06

#define BMX055_GYRO_RATE_Z_MSB 0x07

//#define BMX055_GYRO_Reserved 0x08

#defme BMX055_GYRO_INT_STATUS_0 0x09

#defme BMX055_GYRO_INT_STATUS_1 OxOA

#defme BMX055_GYRO_INT_STATUS_2 OxOB

#define BMX055_GYRO_INT_STATUS_3 OxOC

//#define BMX055_GYRO_Reserved OxOD

#defme BMX055_GYRO_FIFO_STATUS OxOE

#define BMX055 GYRO RANGE OxOF

#defme BMX055 GYR0 BW Ox 10

#defme BMX055 GYR0 LPM 1 Ox 1 1

#defme BMX055 GYRO LPM2 Ox 12

#defme BMX055 GYR0 RATE HBW Ox 13

#defme BMX055 GYRO BGW SOFTRESET 0x14

#defme BMX055_GYRO_INT_EN_0 Ox 15

#define BMX055_GYRO_INT_EN_1 0x16

#defme BMX055_GYRO_INT_MAP_0 Ox 17

#defme BMX055_GYR0_INT_MAP_1 Ox 18

#defme BMX055_GYRO_INT_MAP_2 Ox 19

#defme BMX055_GYR0_INT_SRC_1 Ox 1 A

#define BMX055_GYRO_INT_SRC_2 Ox IB

#defme BMX055_GYRO_INT_SRC_3 Ox 1 C

//#define BMX055_GYRO_Reserved OxlD

#define BMX055_GYRO_FIFO_EN OxlE

//#defme BMX055_GYRO_Reserved OxlF

//#defme BMX055_GYRO_Reserved 0x20

#defme BMX055_GYR0_INT_RST_L ATCH 0x21

#defme BMX055 GYRO HIGH TH X 0x22 #define BMX055_GYRO_HIGH_DUR_X 0x23

#define BMX055_GYRO_HIGH_TH_Y 0x24

#define BMX055_GYRO_HIGH_DUR_Y 0x25

#define BMX055_GYRO_HIGH_TH_Z 0x26

#define BMX055_GYRO_HIGH_DUR_Z 0x27

//#define BMX055_GYRO_Reserved 0x28

//#define BMX055_GYRO_Reserved 0x29

//#define BMX055_GYRO_Reserved 0x2 A

#define BMX055 GYRO SOC 0x31

#define BMX055_GYRO_A_FOC 0x32

#define BMX055_GYRO_TRIM_NVM_CTRL 0x33

#define BMX055_GYRO_BGW_SPI3_WDT 0x34

//#define BMX055_GYRO_Reserved 0x35

#define BMX055 GYRO OFC 1 0x36

#define BMX055_GYRO_OFC2 0x37

#define BMX055_GYRO_OFC3 0x38

#define BMX055_GYRO_OFC4 0x39

#define BMX055_GYRO_TRIM_GP0 0x3A

#define BMX055_GYRO_TRIM_GP1 0x3B

#define BMX055 GYRO BIST 0x3C

#defme BMX055_GYRO_FIFO_CONFIG_0 0x3D

#defme BMX055 GYRO FIFO CONFIG 1 0x3E

// BMX055 magnetometer registers

#defme BMX055_MAG_WHOAMI 0x40 // should return 0x32

#define BMX055_MAG_Reserved 0x41

#define BMX055_MAG_XOUT_LSB 0x42

#define BMX055_MAG_XOUT_MSB 0x43

#define BMX055_MAG_YOUT_LSB 0x44

#define BMX055_MAG_YOUT_MSB 0x45

#define BMX055_MAG_ZOUT_LSB 0x46

#define BMX055_MAG_ZOUT_MSB 0x47

#define BMX055_MAG_ROUT_LSB 0x48

#define BMX055_MAG_ROUT_MSB 0x49

#define BMX055_MAG_INT_STATUS 0x4A

#defme BMX055_MAG_PWR_CNTL 1 0x4B

#defme BMX055_MAG_PWR_CNTL2 0x4C

#define BMX055_MAG_INT_EN_1 0x4D

#define BMX055_MAG_INT_EN_2 0x4E

#defme BMX055_MAG_LOW_THS 0x4F

#define BMX055_MAG_HIGH_THS 0x50

#defme BMX055_MAG_REP_XY 0x51

#define BMX055_MAG_REP_Z 0x52

/* Trim Extended Registers */

#defme BMM050_DIG_X1 0x5D // needed for magnetic field calculation

#define BMM050_DIG_Yl 0x5E

#define BMM050 DIG Z4 LSB 0x62 #define BMM050 DIG Z4 MSB 0x63

#define BMM050 DIG X2 0x64

#define BMM050 DIG Y2 0x65

#define BMM050 DIG Z2 LSB 0x68

#define BMM050 DIG Z2 MSB 0x69

#define BMM050 DIG ZI LSB 0x6A

#define BMM050 DIG ZI MSB 0x6B

#define BMM050 DIG XYZI LSB 0x6C

#define BMM050 DIG XYZI MSB 0x6D

#define BMM050 DIG Z3 LSB 0x6E

#define BMM050 DIG Z3 MSB 0x6F

#define BMM050 DIG XY2 0x70

#define BMM050 DIG XY1 0x71

// EM7180 SENtral register map

// see

http://www.emdeveloper.com/downloads/7180/EMSentral_EM718 0_Register_Map_vl_3. pdf

//

#define EM7180_QX 0x00 // this is a 32-bit normalized floating point number read from registers 0x00-03

#define EM7180_QY 0x04 // this is a 32-bit normalized floating point number read from registers 0x04-07

#define EM7180_QZ 0x08 // this is a 32-bit normalized floating point number read from registers 0x08-0B

#define EM7180_QW OxOC // this is a 32-bit normalized floating point number read from registers OxOC-OF

#define EM7180_QTIME 0x10 // this is a 16-bit unsigned integer read from registers 0x10-11

#define EM7180_MX Ox 12 // int 16_t from regi sters Ox 12- 13

#defme EM7180_MY 0x14 // intl6_t from registers 0x14-15

#defme EM7180_MZ 0x16 // intl6_t from registers 0x16-17

#defme EM7180 MTFME 0x18 // uintl6_t from registers 0x18-19

#defme EM7180_AX Oxl A // intl6_t from registers Oxl A- IB

#defme EM7180_AY OxlC // intl6_t from registers OxlC-lD

#defme EM7180_AZ OxlE // intl6_t from registers OxlE-lF

#define EM7180_ATIME 0x20 // uintl6_t from registers 0x20-21

#defme EM7180_GX 0x22 // intl6_t from registers 0x22-23

#defme EM7180_GY 0x24 // intl6_t from registers 0x24-25

#defme EM7180_GZ 0x26 // intl6_t from registers 0x26-27

#define EM7180_GTIME 0x28 // uintl6_t from registers 0x28-29

#defme EM7180_QRateDivisor 0x32 // uint8_t

#defme EM7180_EnableEvents 0x33

#defme EM7180_HostControl 0x34

#defme EM7180_EventStatus 0x35

#define EM7180_SensorStatus 0x36

#defme EM7180 Sentral Status 0x37 #define EM7180_AlgorithmStatus 0x38

#define EM7180_FeatureFlags 0x39

#define EM7180_ParamAcknowledge 0x3 A

#define EM7180_SavedParamByte0 0x3B

#define EM7180_SavedParamBytel 0x3C

#define EM7180_SavedParamByte2 0x3D

#define EM7180_SavedParamByte3 0x3E

#define EM7180_ActualMagRate 0x45

#define EM7180_Actual AccelRate 0x46

#define EM7180_ActualGyroRate 0x47

#define EM7180_ErrorRegister 0x50

#define EM7180_AlgorithmControl 0x54

#define EM7180_MagRate 0x55

#define EM7180_AccelRate 0x56

#define EM7180_GyroRate 0x57

#define EM7180_LoadParamByte0 0x60

#define EM7180_LoadParamByte 1 0x61

#define EM7180_LoadParamByte2 0x62

#define EM7180_LoadParamByte3 0x63

#define EM7180_ParamRequest 0x64

#define EM7180_ROMVersionl 0x70

#define EM7180_ROMVersion2 0x71

#define EM7180_RAMVersionl 0x72

#define EM7180_RAMVersion2 0x73

#define EM7180_ProductID 0x90

#define EM7180_RevisionID 0x91

#define EM7180_RunStatus 0x92

#define EM7180_UploadAddress 0x94 // uintl6_t registers 0x94 (MSB)-5(LSB) #defme EM7180_UploadData 0x96

#defme EM7180_CRCHost 0x97 // uint32_t from registers 0x97-9 A

#define EM7180_ResetRequest 0x9B

#define EM7180_PassThruStatus 0x9E

#define EM7180 PassThruControl OxAO // Using the Teensy Mini Add-On board, BMX055 SDOl = SD02 = CSB3 = G D as designed

// Seven-bit BMX055 device addresses are ACC = 0x18, GYRO = 0x68, MAG = 0x10 #define BMX055 ACC ADDRESS 0x18 // Address of BMX055 accelerometer #define BMX055_GYRO_ADDRES S 0x68 // Address of BMX055 gyroscope

#define BMX055_MAG_ADDRESS 0x10 // Address of BMX055 magnetometer #define MS5637_ADDRESS 0x76 // Address of MS5637 altimeter

#define EM7180_ ADDRESS 0x28 // Address of the EM7180 SENtral sensor hub #define M24512DFM D AT A ADDRES S 0x50 // Address of the 500 page

M24512DFM EEPROM data buffer, 1024 bits (128 8-bit bytes) per page

#define M24512DFM IDP AGE ADDRES S 0x58 // Address of the single M24512DFM lockable EEPROM ID page #define SerialDebug true // set to true to get Serial output for debugging

// Set initial input parameters

// define X055 ACC full scale options

#define AFS_2G 0x03

#define AFS_4G 0x05

#define AFS_8G 0x08

#define AFS 16G 0x0C enum ACCBW { // define BMX055 accelerometer bandwidths

ABW_8Hz, // 7.81 Hz, 64 ms update time

ABW_16Hz, // 15.63 Hz, 32 ms update time

ABW 3 lHz, // 31.25 Hz, 16 ms update time

ABW_63Hz, // 62.5 Hz, 8 ms update time

ABW_125Hz, // 125 Hz, 4 ms update time

ABW_250Hz, // 250 Hz, 2 ms update time

ABW_500Hz, // 500 Hz, 1 ms update time

ABW lOOOHz // 1000 Hz, 0.5 ms update time

};

enum Gscale {

GFS_2000DPS = 0,

GFS 1000DPS,

GFS 500DPS,

GFS 250DPS,

GFS 125DPS

};

enum GODRBW {

G_2000Hz523Hz = 0, // 2000 Hz ODR and unfiltered (bandwidth 523Hz)

G_2000Hz230Hz,

G_1000Hzl l6Hz,

G_400Hz47Hz,

G_200Hz23Hz,

G_100Hzl2Hz,

G_200Hz64Hz,

G_100Hz32Hz // 100 Hz ODR and 32 Hz bandwidth

};

enum MODR {

MODR l 0Hz = 0, // 10 Hz ODR

MODR_2Hz , // 2 Hz ODR

MODR_6Hz , // 6 Hz ODR

MODR_8Hz , // 8 Hz ODR

MODR_15Hz , // 15 Hz ODR

MODR_20Hz , // 20 Hz ODR

MODR 25Hz , // 25 Hz ODR MODR 30Hz // 30 Hz ODR

};

enum Mmode {

// rms noise -1.0 microTesla, 0.17 raA power

rms noise -0.6 microTesla, 0.5 raA power

// MS5637 pressure sensor sample rates

#define ADC_256 0x00 // define pressure and temperature conversion rates #define ADC_512 0x02

#define ADC_1024 0x04

#define ADC_2048 0x06

#define ADC_4096 0x08

#define ADC_8192 0x0 A

#define ADC_D1 0x40

#define ADC D2 0x50

// Specify sensor full scale

uint8_t Ascale = AFS_4G; // set accel full scale

uint8_t ACCBW = 0x08 & ABW lOOOHz; // Choose bandwidth for accelerometer // Pin definitions

int myLed = 13; // LED on the Teensy 3.1

// BMX055 variables

intl6_t accelCount[3]; // Stores the 16-bit signed accelerometer sensor output float accelBias[3] = {0, 0, 0}; // Bias corrections for gyro, accelerometer, mag float ax, ay, az, gx, gy, gz, mx, my, mz; // variables to hold latest sensor data values float aRes; //resolution of accelerometer

int count;

int delt t; long init time; bool passThru = true;

#define HW SERIAL Serial 1 int datai = 0;

long last wakeup;

long this wakeup;

long dt; // set 48kHz sampling rate

#define CLOCK TYPE (I2S CLOCK 48K INTERNAL) // allocate data buffer

#define bufferSize 8000*3

const uintl6_t target sample = 8000;

const uintl6_t inter = 48000/target_sample;

uint32_t sub sampl e counter = 0;

uint32_t accel counter = 0;

unsigned char audio_buffer[bufferSize];

uint32_t nTX = 0;

uint32_t nRX = 0; boolean silent = true;

unsigned char bytes[4];

// extract the 24bit INMP441 audio data from 32bit sample

void extractdata_inplace(int32_t *pBuf) {

// set highest bit to zero, then bitshift right 7 times

// do not omit the first part (!)

pBuf[0] = (pBuf[0] & 0x7fffffff) »7;

}

/* Direct I2S Receive, we get callback to read 2 words from the FIFO—

-- */ void i2s_rx_callback( int32_t *pBuf )

{

// Downsampling routine; only take every 6th sample,

if (subsample counter != inter-2){

subsample_counter ++;

return;

} else{

subsample counter = 0;

accel_counter++;

}

// perform the data extraction for both channel sides

extractdata_inplace(&pBuf[0]);

//Ignore second channel

//extractdata_inplace(&pBuf[l]); Serial. write((pBuf[0] » 16) & OxFF);

Serial. write((pBuf[0] » 8) & OxFF);

Serial. write(pBuf[0] & OxFF); if (accel counter == 8){

readAccelData(accelCount);

Serial. write((accelCount[0] » 8) & OxFF);

Serial. write(accelCount[0] & OxFF);

Serial .write((accelCount[l] » 8) & OxFF);

Serial.write(accelCount[l] & OxFF);

Serial. write((accelCount[2] » 8) & OxFF);

Serial. write(accelCount[2] & OxFF);

Serial. flushO;

accel counter = 0;

}

}

/* Direct I2S Transmit, we get callback to put 2 words into the FIFO—

- */ void i2s_tx_callback( int32_t *pBuf )

{

// send the data

pBuf[0] = audio_buffer[nTX++];

pBuf[l] = audio_buffer[nTX++];

if(nTX >= bufferSize) nTX=0;

}

/* begin */ void setup()

{

// Wire.begin();

// TWBR = 12; // 400 kbit/sec I2C speed for Pro Mini

// Setup for Master mode, pins 18/19, external pullups, 400kHz for Teensy 3.1 Wire.begin(I2C_MASTER, 0x00, 12C_PINS_16_17, I2C PULLUP EXT,

I2C RATE 400);

delay(1000);

Serial. begin( 115200);

//Serial. println("in da loop"); delay(1000);

I2Cscan(); // should detect SENtral at 0x28

// Set up the SENtral as sensor bus in normal operating mode // Id pass thru

// Put EM7180 SENtral into pass-through mode

SENtralPassThroughMode(); I2Cscan(); // should see all the devices on the I2C bus including two from the EEPROM (ID page and data pages) // Set up the interrupt pin, its set as active high, push-pull

pinMode(myLed, OUTPUT);

// NOTE: I have no idea what this does, but turning this on basically kills BLE. disabled for now.

//digitalWrite(myLed, HIGH);

// Read the BMX-055 WHO AM I registers, this is a good test of communication //Serial. println("BMX055 accelerometer...");

byte c = readByte(BMX055_ACC_ADDRESS, BMX055 ACC WHOAMI); // Read ACC WHO AM I register for BMX055

//Serial.print("BMX055 ACC"); Serial. print(" I AM Ox"); Serial.print(c, HEX);

Serial. print(" I should be Ox"); Serial.println(OxFA, HEX); if (c == OxF A) // WHO_AM_I should always be ACC = OxFA, GYRO = OxOF, MAG = 0x32

{

//Serial. println("BMX055 is online..."); initBMX055();

//Serial. println("BMX055 initialized for active data mode...."); // Initialize device for active mode read of acclerometer, gyroscope, and temperature

// // Reset the MS5637 pressure sensor

// MS5637Reset();

// delay(100);

// Serial. println("MS5637 pressure sensor reset...");

// // Read PROM data from MS5637 pressure sensor

// MS5637PromRead(Pcal);

// Serial.println("PROM data read:");

// Serial.print("C0 = "); Serial. println(Pcal[0]);

// unsigned char refCRC = Pcal[0] » 12;

// Serial.printC'Cl = "); Serial. println(Pcal[l]);

// Serial.print("C2 = "); Serial. println(Pcal [2]);

// Serial.print("C3 = "); Serial. println(Pcal [3]);

// Serial.print("C4 = "); Serial. println(Pcal [4]);

// Serial.print("C5 = "); Serial.println(Pcal[5]);

// Serial.print("C6 = "); Serial. println(Pcal [6]);

// nCRC = MS5637checkCRC(Pcal); //calculate checksum to ensure integrity of MS5637 calibration data

// Serial. print("Checksum = "); Serial. print(nCRC); Serial. print(" , should be ");

Serial. println(refCRC); // delay(lOOO);

// get sensor resolutions, only need to do this once

getAres(); fastcompaccelBMX055(accelBias);

//Serial. println("accel biases (mg)"); Serial. println(1000.*accelBias[0]); Serial.println(1000.*accelBias[l]); Serial.println(1000.*accelBias[2]); }

else

{

//Serial. print("Could not connect to BMX055: Ox");

//Serial. println(c, HEX);

while (1) ; // Loop forever if communication doesn't happen

}

last wakeup = micros(); init time = millis();

//Serial. print(init_time);

// « nothing before the first delay will be printed to the serial

delay(1500); if(! silent){

Serial. print("Pin configuration setting: ");

Serial. println( 12 S PIN P ATTERN , HEX );

Serial. println( "Initializing." );

}

if(! silent) Serial. println( "Initialized I2C Codec" );

// prepare 12 S RX with interrupts

I2SRx0.begin( CLOCK TYPE, i2s_rx_callback );

if(! silent) Serial. println( "Initialized I2S RX without DMA" );

// I2STx0.begin( CLOCK TYPE, i2s_tx_callback );

// Serial.println( "Initialized I2S TX without DMA" ); // fill the buffer with something to see if the RX callback is activated at all audio_buffer[0] = 0x42424242; delay(5000);

// start the 12 S RX

I2SRx0.start();

//I2STx0.start();

if(! silent) Serial.println( "Started I2S RX" ); }

void loopO

{

/*

*

* Sampling should be done in I2S callback for more accurate timing

this wakeup = micros();

dt = 1000 - (this_wakeup - last_wakeup);

if (dt > 0) {

delayMicroseconds(dt);

}

this wakeup = micros();

dt = this wakeup - last wakeup;

last wakeup = this wakeup;

// If intPin goes high, all data registers have new data

// if (digitalRead(intACC2)) { // On interrupt, read data

readAccelData(accelCount); // Read the x/y/z adc values

// Now we'll calculate the accleration value into actual g's

// ax = (float)accelCount[0] * aRes; // + accelBias[0]; // get actual g value, this depends on scale being set

// ay = (float)accelCount[l] * aRes; // + accelBias[l];

// az = (float)accelCount[2] * aRes; // + accelBias[2];

//accel_buffer[datai++] = accelCount[0];

//accel_buffer[datai++] = accelCount[l];

//accel_buffer[datai++] = accelCount[2];

Serial.printC';;;");

Serial. write((accelCount[0] » 8) & OxFF);

Serial. write(accelCount[0] & OxFF);

Serial .write((accelCount[l] » 8) & OxFF);

Serial. write(accelCount[l] & OxFF);

Serial. write((accelCount[2] » 8) & OxFF);

Serial. write(accelCount[2] & OxFF);

Serial. flush();

*/

}

11====== Set of useful function to access acceleration, gyroscope, magnetometer, and temperature data

//========================================================== === void getAres() {

switch (Ascale)

{

// Possible accelerometer scales (and their register bit settings) are:

// 2 Gs (0011), 4 Gs (0101), 8 Gs (1000), and 16 Gs (1100).

// BMX055 ACC data is signed 12 bit

case AFS 2G:

aRes = 2.0 / 2048.0;

break;

case AFS_4G:

aRes = 4.0 / 2048.0;

break;

case AFS 8G:

aRes = 8.0 / 2048.0;

break;

case AFS 16G:

aRes = 16.0 / 2048.0;

break;

}

}

void readAccelData(intl6_t * destination)

{

uint8_t rawData[6]; // x/y/z accel register data stored here

readBytes(BMX055_ACC_ADDRESS, BMX055_ACC_D_X_LSB, 6, &rawData[0]); // Read the six raw data registers into data array

if ((rawData[0] & 0x01) && (rawData[2] & 0x01) && (rawData[4] & 0x01)) { // Check that all 3 axes have new data

destination^] = (intl6_t) (((intl6_t)rawData[l] « 8) | rawData[0]) » 4; // Turn the MSB and LSB into a signed 12-bit value

destination[ 1] = (intl6_t) (((intl6_t)rawData[3] « 8) | rawData[2]) » 4;

destination^] = (intl6_t) (((intl6_t)rawData[5] « 8) | rawData[4]) » 4;

}

}

void SENtralPassThroughMode()

{

// First put SENtral in standby mode

uint8_t c = readByte(EM7180 ADDRES S, EM7180_AlgorithmControl);

writeByte(EM7180 ADDRES S, EM7180_AlgorithmControl, c | 0x01);

// c = readByte(EM7180_ADDRESS, EM7180_AlgorithmStatus);

// Serial. print("c = "); Serial. println(c);

// Verify standby status

// if(readByte(EM7180_ADDRESS, EM7180_AlgorithmStatus) & 0x01) {

Serial. println(" SENtral in standby mode");

// Place SENtral in pass-through mode

writeByte(EM7180 ADDRES S, EM7180_PassThruControl, 0x01); if (readByte(EM7180 ADDRESS, EM7180_PassThruStatus) & 0x01) { Serial. println("SENtral in pass-through mode");

}

else {

Serial. println("ERROR! SENtral not in pass-through mode! ");

}

} void initBMX055()

{

// start with all sensors in default mode with all registers reset

writeByte(BMX055_ACC_ADDRESS, BMX055_ACC_BGW_SOFTRESET, 0xB6); // reset accelerometer

delay(1000); // Wait for all registers to reset

// Configure accelerometer

writeByte(BMX055_ACC_ADDRESS, BMX055 ACC PMU RANGE, Ascale & OxOF); // Set accelerometer full range

writeByte(BMX055_ACC_ADDRESS, BMX055 ACC PMU BW, ACCBW & OxOF); // Set accelerometer bandwidth

writeBy te(BMX055_ACC_ADDRE S S , BMX055 ACC D HBW, 0x00); // Use filtered data

// // writeByte(BMX055 ACC ADDRES S, BMX055_ACC_INT_EN_1 , Ox 10); // Enable ACC data ready interrupt

// // writeByte(BMX055_ACC_ADDRESS, BMX055_ACC_INT_OUT_CTRL, 0x04); // Set interrupts push-pull, active high for INT1 and INT2

// // writeByte(BMX055 ACC ADDRES S, BMX055_ACC_INT_MAP_1 , 0x02); // Define INT1 (intACCl) as ACC data ready interrupt

// // writeByte(BMX055_ACC_ADDRESS, BMX055_ACC_INT_MAP_1, 0x80); // Define INT2 (intACC2) as ACC data ready interrupt // // writeByte(BMX055_ACC_ADDRESS, BMX055_ACC_BGW_SPI3_WDT, 0x06); // Set watchdog timer for 50 ms

// // Configure Gyro

// // start by resetting gyro, better not since it ends up in sleep mode?!

// // writeByte(BMX055_GYRO_ADDRES S, BMX055 GYRO BGW SOFTRESET, 0xB6); // reset gyro

// // delay (100);

// // Three power modes, 0x00 Normal,

// // set bit 7 to 1 for suspend mode, set bit 5 to 1 for deep suspend mode

// // sleep duration in fast-power up from suspend mode is set by bits 1 - 3

// // 000 for 2 ms, 111 for 20 ms, etc. // // writeByte(BMX055_GYRO_ADDRESS, BMX055 GYRO LPM1, 0x00); // set GYRO normal mode

// // set GYRO sleep duration for fast power-up mode to 20 ms, for duty cycle of 50% // // writeBy te(BMX055 ACC ADDRE S S , BMX055 GYRO LPM1, OxOE);

// // set bit 7 to 1 for fast-power-up mode, gyro goes quickly to normal mode upon wake up

// // can set external wake-up interrupts on bits 5 and 4

// // auto-sleep wake duration set in bits 2-0, 001 4 ms, 111 40 ms

// // writeByte(BMX055_GYRO_ADDRESS, BMX055 GYRO LPM2, 0x00); // set GYRO normal mode

// // set gyro to fast wake up mode, will sleep for 20 ms then run normally for 20 ms // // and collect data for an effective ODR of 50 Hz, other duty cycles are possible but there

// // is a minimum wake duration determined by the bandwidth duration, e.g., > 10 ms for 23Hz gyro bandwidth

// // writeByte(BMX055 ACC ADDRES S, BMX055 GYRO LPM2, 0x87);

// writeByte(BMX055_GYRO_ADDRESS, BMX055 GYRO RANGE, Gscale); // set GYRO FS range

// writeByte(BMX055 GYRO ADDRES S, BMX055 GYRO B W, GODRBW); // set GYRO ODR and Bandwidth

// // writeByte(BMX055_GYRO_ADDRESS, BMX055_GYRO_INT_EN_0, 0x80); // enable data ready interrupt

// // writeByte(BMX055 GYRO ADDRES S, BMX055_GYRO_INT_EN_l , 0x04); // select push-pull, active high interrupts

// // writeByte(BMX055_GYRO_ADDRESS, BMX055_GYRO_INT_MAP_1, 0x80); // select INT3 (intGYROl) as GYRO data ready interrupt // // writeByte(BMX055 GYRO ADDRES S, BMX055_GYRO_BGW_SPI3_WDT, 0x06); // Enable watchdog timer for I2C with 50 ms window

// // Configure magnetometer

// writeByte(BMX055 MAG ADDRES S, BMX055 MAG PWR CNTL 1 , 0x82); // Softreset magnetometer, ends up in sleep mode

// delay(100);

// writeByte(BMX055_MAG_ADDRESS, BMX055 MAG PWR CNTL1, 0x01); // Wake up magnetometer

// delay(100);

// writeByte(BMX055_MAG_ADDRESS, BMX055 MAG PWR CNTL2, MODR « 3); // Normal mode

// //writeByte(BMX055_MAG_ADDRESS, BMX055_MAG_PWR_CNTL2, MODR « 3 I 0x02); // Forced mode // //writeByte(BMX055_MAG ADDRESS, BMX055_MAG_INT_EN_2, 0x84); // Enable data ready pin interrupt, active high

// // Set up four standard configurations for the magnetometer

// switch (Mmode)

// {

// case lowPower:

// // Low-power

// writeBy te(BMX055_M AG ADDRE S S , BMX055 MAG REP XY, 0x01); // 3 repetitions (oversampling)

// writeBy te(BMX055_M AG ADDRE S S , BMX055 MAG REP Z , 0x02); 11 3 repetitions (oversampling)

// break;

// case Regular:

// // Regular

// writeBy te(BMX055_M AG ADDRE S S , BMX055 MAG REP XY, 0x04); // 9 repetitions (oversampling)

// writeBy te(BMX055_M AG ADDRE S S , BMX055 MAG REP Z , 0x16); // 15 repetitions (oversampling)

// break;

// case enhancedRegular:

// // Enhanced Regular

// writeBy te(BMX055_M AG ADDRE S S , BMX055 MAG REP XY, 0x07); // 15 repetitions (oversampling)

// writeBy te(BMX055_M AG ADDRE S S , BMX055 MAG REP Z , 0x22); II 21 repetitions (oversampling)

// break;

// case high Accuracy:

// // High Accuracy

// writeByte(BMX055_MAG_ADDRESS, BMX055 MAG REP XY, 0x17); // 47 repetitions (oversampling)

// writeBy te(BMX055_M AG ADDRE S S , BMX055 MAG REP Z , 0x51); // 83 repetitions (oversampling)

// break;

// }

}

void fastcompaccelBMX055(float * destl)

{

writeByte(BMX055_ACC_ADDRESS, BMX055 ACC OFC CTRL, 0x80); // set all accel offset compensation registers to zero

writeBy te(BMX055_ACC_ADDRE S S , BMX055 ACC OFC SETTING, 0x20); // set offset targets to 0, 0, and +1 g for x, y, z axes

writeByte(BMX055_ACC_ADDRESS, BMX055_ACC_OFC_CTRL, 0x20); // calculate x-axis offset byte c = readByte(BMX055_ACC_ADDRESS, BMX055_ACC_OFC_CTRL); while (!(c & 0x10)) { // check if fast calibration complete

c = readByte(BMX055_ACC ADDRESS, BMX055 ACC OFC CTRL);

delay (10);

}

writeByte(BMX055_ACC_ADDRESS, BMX055 ACC OFC CTRL, 0x40); // calculate y-axis offset c = readByte(BMX055_ACC_ADDRESS, BMX055 ACC OFC CTRL);

while (!(c & 0x10)) { // check if fast calibration complete

c = readByte(BMX055_ACC_ADDRESS, BMX055 ACC OFC CTRL);

delay (10);

}

writeByte(BMX055_ACC_ADDRESS, BMX055 ACC OFC CTRL, 0x60); // calculate z-axis offset c = readByte(BMX055_ACC_ADDRESS, BMX055 ACC OFC CTRL);

while (!(c & 0x10)) { // check if fast calibration complete

c = readByte(BMX055_ACC_ADDRESS, BMX055 ACC OFC CTRL);

delay (10);

} int8_t compx = readByte(BMX055_ACC_ADDRESS,

BMX055_ACC_OFC_OFFSET_X);

int8_t compy = readByte(BMX055_ACC_ADDRESS,

BMX055_ACC_OFC_OFFSET_Y);

int8_t compz = readByte(BMX055_ACC_ADDRESS,

BMX055_ACC_OFC_OFFSET_Z); destl [0] = (float) compx / 128.; // accleration bias in g

destl [l] = (float) compy / 128.; // accleration bias in g

destl [2] = (float) compz / 128.; // accleration bias in g

}

// I2C communication with the M24512DFM EEPROM is a little different from I2C communication with the usual motion sensor

// since the address is defined by two bytes

// I2C communication with the MS5637 is a little different from that with the MPU9250 and most other sensors

// For the MS5637, we write commands, and the MS5637 sends data in response, rather than directly reading

// MS5637 registers void MS5637Reset()

{ Wire.beginTransmission(MS5637_ADDRESS); // Initialize the Tx buffer

Wire.write(MS5637_RESET); // Put reset command in Tx buffer

Wire.endTransmission(); // Send the Tx buffer

}

void MS5637PromRead(uintl6_t * destination)

{

uint8_t data[2] = {0, 0};

for (uint8_t ii = 0; ii < 7; ii++) {

Wire.beginTransmission(MS5637_ADDRESS); // Initialize the Tx buffer

Wire.write(0xA0 | ii « 1); // Put PROM address in Tx buffer

Wire.endTransmission(I2C_NOSTOP); // Send the Tx buffer, but send a restart to keep connection alive

uint8_t i = 0;

Wire.requestFrom(MS5637_ADDRESS, 2); // Read two bytes from slave PROM address

while (Wire.available()) {

data[i++] = Wire.read();

} // Put read results in the Rx buffer

destination[ii] = (uintl6_t) (((uintl6_t) data[0] « 8) | data[l]); // construct PROM data for return to main program

}

}

uint32_t MS5637Read(uint8_t CMD, uint8_t OSR) // temperature data read

{

uint8_t data[3] = {0, 0, 0};

Wire.beginTransmission(MS5637_ADDRESS); // Initialize the Tx buffer

Wire.write(CMD | OSR); // Put pressure conversion command in Tx buffer Wire.endTransmission(I2C_NOSTOP); // Send the Tx buffer, but send a restart to keep connection alive switch (OSR)

{

case ADC_256: delay(l); break; // delay for conversion to complete

case ADC_512: delay(3); break;

case ADC_1024: delay(4); break;

case ADC_2048: delay(6); break;

case ADC_4096: delay(10); break;

case ADC_8192: delay(20); break;

}

Wire.beginTransmission(MS5637_ADDRESS); // Initialize the Tx buffer

Wire.write(OxOO); // Put ADC read command in Tx buffer

Wire.endTransmission(I2C_NOSTOP); // Send the Tx buffer, but send a restart to keep connection alive

uint8_t i = 0; Wire.requestFrom(MS5637_ADDRESS, 3); // Read three bytes from slave PROM address

while (Wire.available()) {

data[i++] = Wire.read();

} // Put read results in the Rx buffer

return (uint32_t) (((uint32_t) data[0] « 16) | (uint32_t) data[l] « 8 | data[2]); // construct PROM data for return to main program

}

unsigned char MS5637checkCRC(uintl6_t * n_prom) // calculate checksum from PROM register contents

{

int cnt;

unsigned int n rem = 0;

unsigned char n bit; n_prom[0] = ((n_prom[0]) & OxOFFF); // replace CRC byte by 0 for checksum calculation

n_prom[7] = 0;

for (cnt = 0; cnt < 16; cnt++)

{

if (cnt % 2 == 1) n rem Λ = (unsigned short) ((n_prom[cnt » 1]) & OxOOFF);

else n rem A = (unsigned short) (n_prom[cnt » 1] » 8);

for (n bit = 8; n bit > 0; n bit--)

{

if (n_rem & 0x8000) n_rem = (n_rem « 1) Λ 0x3000;

else n rem = (n rem « 1);

}

}

n_rem = ((n_rem » 12) & OxOOOF);

return (n_rem A 0x00);

}

// simple function to scan for I2C devices on the bus

void I2Cscan()

{

// scan for i2c devices

byte error, address;

int nDevices;

Serial .println(" Scanning... "); nDevices = 0;

for (address = 1; address < 129; address++ )

{ // The i2c_scanner uses the return value of

// the Write. endTransmission to see if

// a device did acknowledge to the address.

Wire.beginTransmission(address);

error = Wire. endTransmission(); if (error == 0)

{

Serial. print("I2C device found at address Ox");

if (address < 16)

Serial.print("0");

Serial. print(address, HEX);

Serial. println(" ! "); nDevices++;

}

else if (error == 4)

{

Serial. print("Unknow error at address Ox");

if (address < 16)

Serial.print("0");

Serial. println(address, HEX);

}

}

if (nDevices == 0)

Serial. println("No I2C devices found\n");

else

Serial. println("done\n");

}

// I2C read/write functions for the MPU9250 and AK8963 sensors void writeByte(uint8_t address, uint8_t sub Address, uint8_t data)

{

Wire.beginTransmission(address); // Initialize the Tx buffer

Wire.write(subAddress); // Put slave register address in Tx buffer Wire.write(data); // Put data in Tx buffer

Wire.endTransmission(); // Send the Tx buffer

} uint8_t readByte(uint8_t address, uint8_t sub Address)

{

uint8_t data; // λ data will store the register data

Wire.beginTransmission(address); // Initialize the Tx buffer

Wire.write(subAddress); // Put slave register address in Tx buffer Wire.endTransmission(I2C_NOSTOP); // Send the Tx buffer, but send a restart to keep connection alive

// Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive

// Wire.requestFrom(address, 1); // Read one byte from slave register address

Wire.requestFrom(address, (size t) 1); // Read one byte from slave register address data = Wire.read(); // Fill Rx buffer with result

return data; // Return data read from slave register

}

void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest)

{

Wire.beginTransmission(address); // Initialize the Tx buffer

Wire.write(subAddress); // Put slave register address in Tx buffer

Wire.endTransmission(I2C_NOSTOP); // Send the Tx buffer, but send a restart to keep connection alive

// Wire.endTransmission(false); // Send the Tx buffer, but send a restart to keep connection alive

uint8_t i = 0;

// Wire.requestFrom(address, count); // Read bytes from slave register address Wire.requestFrom(address, (size t) count); // Read bytes from slave register address while (Wire.available()) {

dest[i++] = Wire.read();

} // Put read results in the Rx buffer

}