Hackster is hosting Hackster Holidays, Ep. 5: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Friday!Stream Hackster Holidays, Ep. 5 on Friday!
Dimiter Kendri
Created October 24, 2017

Android Things Smart Parking

Smart Parking lot occupancy detector, IOT enabled

217
Android Things Smart Parking

Things used in this project

Story

Read more

Schematics

Parking lot node

FXOS8700 magnetometer with Arduino 101 BLE enabled board

Code

Parking Lot sensor node

Arduino
Main program of sensor node.
/* Arduino 101 Smart parking with Android Things
 * Copyright (C) 2017 by Dimiter Kendri
 *
 *
 * This Library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This Library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with the Arduino 101 Curie Lake monitor.  If not, see
 * <http://www.gnu.org/licenses/>.
 */


#include <CurieBLE.h>
#include <Wire.h>
#include "FXOS8700.h"


FXOS8700CQ magnetometer = FXOS8700CQ(0x1F);

/*********************************************************************************/

const char *moduleName = "AndroidParking";

BLEPeripheral blePeripheral;

// Environment sensing service UUID
// https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.environmental_sensing.xml
#define SERVICE_PARKING "181A"           
#define CHAR_UUID_MAGX "2A6E"        	// magx UUID
#define CHAR_UUID_MAGY "2A6F"           // magy UUID
#define CHAR_UUID_MAGZ "2A6F"           // magz UUID

BLEService MagServ(SERVICE_PARKING);

// We want notifications to be supported
BLEShortCharacteristic MagxChar(CHAR_UUID_MAGX,  BLERead | BLENotify);
BLEShortCharacteristic MagyChar(CHAR_UUID_MAGY,  BLERead | BLENotify);
BLEShortCharacteristic MagzChar(CHAR_UUID_MAGZ,  BLERead | BLENotify);

/*********************************************************************************/

const byte MagInterruptPin = 2;
 
void setupMagnetometer(void);
void updateCharacteristic(void);

void setup() {
  Serial.begin(9600);
  while (!Serial);    // wait for the serial port to open

  Wire.begin();
  
  setupMagnetometer();
  
  // Set BLE name for the module
  blePeripheral.setLocalName(moduleName);
  // Add the service UUID
  blePeripheral.setAdvertisedServiceUuid(MagServ.uuid());
  // Add the BLE service
  blePeripheral.addAttribute(MagServ);
  // Add characteristics
  blePeripheral.addAttribute(MagxChar);
  blePeripheral.addAttribute(MagyChar);
  blePeripheral.addAttribute(MagzChar);
  

  
  // Set initial values
  updateCharacteristic();

  /* Activate the BLE device.  It will start continuously transmitting BLE
     advertising packets and will be visible to remote BLE central devices
     until it receives a new connection */
  blePeripheral.begin();
  
  pinMode(MagInterruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(MagInterruptPin), updateCharacteristic, RISING );
  
  Serial.println("Bluetooth device active, waiting for connections...");
}

void loop() {

  // poll peripheral
  blePeripheral.poll();
}


void setupMagnetometer(void)
{
  Serial.println("Initializing FXOS8700 device...");
  // Initialize the FXOS8700CQ
  magnetometer.init();
}

  
// Get data from sensors, process and push to BLE characteristics
void updateCharacteristic(void)
{
  magnetometer.readMagData();
  
  // Magnometer
  Serial.print("Mag ");
  Serial.print("X: ");
  Serial.print((int)magnetometer.magData.x);
  Serial.print(" Y: ");
  Serial.print((int)magnetometer.magData.y);
  Serial.print(" Z: ");
  Serial.println((int)magnetometer.magData.z);
  
  MagxChar.setValue((int)magnetometer.magData.x);
  MagyChar.setValue((int)magnetometer.magData.y);
  MagzChar.setValue((int)magnetometer.magData.z);
		
}

FXOS8700.cpp

Arduino
Magnetometer sensor
#include <Wire.h>
#include <math.h>

#include "FXOS8700.h"
#include "MemoryMapRegs.h"

// Public Methods //////////////////////////////////////////////////////////////

FXOS8700CQ::FXOS8700CQ(byte addr)
{
	address = addr;
	accelFSR = AFS_2g;     // Set the scale below either 2, 4 or 8
	accelODR = AODR_200HZ; // In hybrid mode, accel/mag data sample rates are half of this value
	magOSR = MOSR_5;     // Choose magnetometer oversample rate
}

// Writes a register
void FXOS8700CQ::writeReg(byte reg, byte value)
{
	Wire.beginTransmission(address);
	Wire.write(reg);
	Wire.write(value);
	Wire.endTransmission();
}

// Reads a register
byte FXOS8700CQ::readReg(byte reg)
{
	byte value;

	Wire.beginTransmission(address);
	Wire.write(reg);
	Wire.endTransmission();
	Wire.requestFrom(address, (uint8_t)1);
	value = Wire.read();
	Wire.endTransmission();

	return value;
}

void FXOS8700CQ::readRegs(byte reg, uint8_t count, byte dest[])
{
	uint8_t i = 0;

	Wire.beginTransmission(address);   // Initialize the Tx buffer
	Wire.write(reg);            	   // Put slave register address in Tx buffer
	Wire.endTransmission(false);       // Send the Tx buffer, but send a restart to keep connection alive
	Wire.requestFrom(address, count);  // Read bytes from slave register address 

	while (Wire.available()) {
		dest[i++] = Wire.read();   // Put read results in the Rx buffer
	}
}



// Read the magnometer data
void FXOS8700CQ::readMagData()
{
	uint8_t rawData[6];  // x/y/z accel register data stored here

	readRegs(M_OUT_X_MSB, 6, &rawData[0]);  // Read the six raw data registers into data array
	magData.x = ((int16_t) rawData[0] << 8 | rawData[1]) >> 2;
	magData.y = ((int16_t) rawData[2] << 8 | rawData[3]) >> 2;
	magData.z = ((int16_t) rawData[4] << 8 | rawData[5]) >> 2;
}

// Read the temperature data
void FXOS8700CQ::readTempData()
{
	tempData = readReg(TEMP);
}

// Put the FXOS8700CQ into standby mode.
// It must be in standby for modifying most registers
void FXOS8700CQ::standby()
{
	byte c = readReg(CTRL_REG1);
	writeReg(CTRL_REG1, c & ~(0x01));
}

// Put the FXOS8700CQ into active mode.
// Needs to be in this mode to output data.
void FXOS8700CQ::active()
{
	byte c = readReg(CTRL_REG1);
	writeReg(CTRL_REG1, c | 0x01);
}

void FXOS8700CQ::init()
{
	standby();  // Must be in standby to change registers

    uint16_t magThreshold = 0x200;                               //counts;
    uint8_t magThresholdHi = (magThreshold & 0xFF00) >> 8;
    uint8_t magThresholdLo = magThreshold & 0xFF;
    writeReg(M_THS_Z_MSB, magThresholdHi);        // Debounce countered cleared to zero when threshold is not longer true
    writeReg(M_THS_Z_LSB, magThresholdLo);
    
    magThreshold = 0x200;                               //counts;
    magThresholdHi = (magThreshold & 0xFF00) >> 8;
    magThresholdLo = magThreshold & 0xFF;
    writeReg(M_THS_Y_MSB, magThresholdHi);        // Debounce countered cleared to zero when threshold is not longer true
    writeReg(M_THS_Y_LSB, magThresholdLo);
    
    
    writeReg( M_THS_X_MSB, 0x03); // Threshold value MSB  
    writeReg( M_THS_X_LSB, 0xE8); // Threshold value LSB  
    //FXOS8700CQ_WriteByte( M_THS_CFG, 0xCA); // Event flag latch enabled, logic OR of enabled axes, only X-axis enabled, threshold interrupt enabled and routed to INT2
    
    writeReg(M_THS_CFG, M_THS_ELE | M_THS_OAE | M_THS_ZEFE | M_THS_YEFE | M_THS_XEFE | M_THS_INT_EN );  //M_INT_threshold on INT2 pin (MCU_INT1), OR INT of all axes for threshold, latch disabled.

        
    writeReg( M_THS_COUNT, 0x02); // 100ms at 100Hz ODR and magnetometer mode only 
    writeReg( M_CTRL_REG1, 0x1D); // Max OSR, only magnetometer is active 
    writeReg( CTRL_REG3, 0x00); // Push-pull, active low interrupt 
   
    writeReg(CTRL_REG3, IPOL_MASK);                     // Active HIGH on INT, push-pull mode
    writeReg( CTRL_REG1, 0x19); // ODR = 100Hz, Active mode    


	active();  // Set to active to start reading
}

// Get accelerometer resolution
float FXOS8700CQ::getAres(void)
{
	switch (accelFSR)
	{
		// Possible accelerometer scales (and their register bit settings) are:
		// 2 gs (00), 4 gs (01), 8 gs (10). 
		case AFS_2g:
			return 2.0/8192.0;
		break;
		case AFS_4g:
			return 4.0/8192.0;
		break;
		case AFS_8g:
			return 8.0/8192.0;
		break;
	}

	return 0.0;
}

// Get magnometer resolution
float FXOS8700CQ::getMres(void)
{
	return 10./32768.;
}
// Private Methods //////////////////////////////////////////////////////////////

FXOS8700.h

Arduino
#ifndef FXOS8700_H_
#define FXOS8700_H_

#include <Arduino.h> // for byte data type

// register addresses
#define STATUS 				0x00
#define OUT_X_MSB 			0x01
#define OUT_X_LSB			0x02
#define OUT_Y_MSB			0x03
#define OUT_Y_LSB			0x04
#define OUT_Z_MSB			0x05
#define OUT_Z_LSB			0x05
#define F_SETUP				0x09
#define TRIG_CFG			0x0A
#define SYSMOD				0x0B
#define INT_SOURCE			0x0C
#define WHO_AM_I			0x0D
#define XYZ_DATA_CFG		0x0E
#define HP_FILTER_CUTOFF	0x0F
#define PL_STATUS			0x10
#define PL_CFG				0x11
#define PL_COUNT			0x12
#define PL_BF_ZCOMP			0x13
#define PL_THS_REG			0x14
#define A_FFMT_CFG			0x15
#define A_FFMT_SRC			0x16
#define A_FFMT_THS			0x17
#define A_FFMT_COUNT		0x18
#define TRANSIENT_CFG		0x1D
#define TRANSIENT_SRC		0x1E
#define TRANSIENT_THS		0x1F
#define TRANSIENT_COUNT		0x20
#define PULSE_CFG			0x21
#define PULSE_SRC			0x22
#define PULSE_THSX			0x23
#define PULSE_THSY			0x24
#define PULSE_THSZ			0x25
#define PULSE_TMLT			0x26
#define PULSE_LTCY			0x27
#define PULSE_WIND			0x28
#define ASLP_COUNT			0x29
#define CTRL_REG1			0x2A
#define CTRL_REG2			0x2B
#define CTRL_REG3			0x2C
#define CTRL_REG4			0x2D
#define CTRL_REG5			0x2E
#define OFF_X				0x2F
#define OFF_Y				0x30
#define OFF_Z				0x31
#define M_DR_STATUS			0x32
#define M_OUT_X_MSB			0x33
#define M_OUT_X_LSB			0x34
#define M_OUT_Y_MSB			0x35
#define M_OUT_Y_LSB			0x36
#define M_OUT_Z_MSB			0x37
#define M_OUT_Z_LSB			0x38
#define CMP_X_MSB			0x39
#define CMP_X_LSB			0x3A
#define CMP_Y_MSB			0x3B
#define CMP_Y_LSB			0x3C
#define CMP_Z_MSB			0x3D
#define CMP_Z_LSB			0x3E
#define M_OFF_X_MSB			0x3F
#define M_OFF_X_LSB			0x40
#define M_OFF_Y_MSB			0x41
#define M_OFF_Y_LSB			0x42
#define M_OFF_Z_MSB			0x43
#define M_OFF_Z_LSB			0x44
#define MAX_X_MSB			0x45
#define MAX_X_LSB			0x46
#define MAX_Y_MSB			0x47
#define MAX_Y_LSB			0x48
#define MAX_Z_MSB			0x49
#define MAX_Z_LSB			0x4A
#define MIN_X_MSB			0x4B
#define MIN_X_LSB			0x4C
#define MIN_Y_MSB			0x4D
#define MIN_Y_LSB			0x4E
#define MIN_Z_MSB			0x4F
#define MIN_Z_LSB			0x50
#define TEMP				0x51
#define M_THS_CFG			0x52
#define M_THS_SRC			0x53
#define M_THS_X_MSB			0x54
#define M_THS_X_LSB			0x55
#define M_THS_Y_MSB			0x56
#define M_THS_Y_LSB			0x57
#define M_THS_Z_MSB			0x58
#define M_THS_Z_LSB			0x59
#define M_THS_COUNT			0x5A
#define M_CTRL_REG1			0x5B
#define M_CTRL_REG2			0x5C
#define M_CTRL_REG3			0x5D
#define M_INT_SRC			0x5E
#define A_VECM_CFG			0x5F
#define A_VECM_THS_MSB		0x60
#define A_VECM_THS_LSB		0x61
#define A_VECM_CNT			0x62
#define A_VECM_INITX_MSB	0x63
#define A_VECM_INITX_LSB	0x64
#define A_VECM_INITY_MSB 	0x65
#define A_VECM_INITY_LSB	0x66
#define A_VECM_INITZ_MSB	0x67
#define A_VECM_INITZ_LSB	0x68
#define M_VECM_CFG			0x69
#define M_VECM_THS_MSB		0x6A
#define M_VECM_THS_LSB		0x6B
#define M_VECM_CNT			0x6C
#define M_VECM_INITX_MSB	0x6D
#define M_VECM_INITX_LSB	0x6E
#define M_VECM_INITY_MSB	0x6F
#define M_VECM_INITY_LSB	0x70
#define M_VECM_INITZ_MSB	0x71
#define M_VECM_INITZ_LSB	0x72
#define A_FFMT_THS_X_MSB	0x73
#define A_FFMT_THS_X_LSB	0x74
#define A_FFMT_THS_Y_MSB	0x75
#define A_FFMT_THS_Y_LSB	0x76
#define A_FFMT_THS_Z_MSB	0x77
#define A_FFMT_THS_Z_LSB	0x78

// Set initial input parameters
enum accelFSR {
	AFS_2g = 0,
	AFS_4g,
	AFS_8g
};

enum accelODR {
	AODR_800HZ = 0, // 200 Hz
	AODR_400HZ,
	AODR_200HZ,
	AODR_100HZ,
	AODR_50HZ,
	AODR_12_5HZ, // 12.5 Hz, etc.
	AODR_6_25HZ,
	AODR_1_56HZ
};

enum magOSR {
	MOSR_0 = 0,  // oversample ratio 2 at 50 and 200 Hz ODR
	MOSR_1,
	MOSR_2,
	MOSR_3,
	MOSR_4,
	MOSR_5,  
	MOSR_6,
	MOSR_7      // oversample ratio 8 at 200 Hz ODR, 32 at 50 HZ ODR
};


class FXOS8700CQ
{
	public:
	typedef struct 
	{
	    int16_t	x;
	    int16_t	y;
	    int16_t	z;
	} SRAWDATA;

	// Sensor data
	SRAWDATA accelData; // RAW acceleration sensor data
	SRAWDATA magData; // RAW magnometer sensor data
	int8_t tempData; // RAW temperature data

	// Sensor configuration
	uint8_t accelFSR;
	uint8_t accelODR;
	uint8_t magOSR;

	FXOS8700CQ(byte addr);

	// Register functions
	void writeReg(byte reg, byte value);
	byte readReg(byte reg);
	void readRegs(byte startReg, uint8_t count, byte dest[]);

	// FXOS8700CQ functions
	// Initialization & Termination
	void init(void);
	void standby(void);
	void active(void);

	// Query sensor data
	void readAccelData(void);
	void readMagData(void);
	void readTempData(void);

	// Resolution
	float getAres(void);
	float getMres(void);

	private:
	// Sensor address
	byte address;
};

#endif

MemoryMapRegs.h

Arduino
#ifndef __MEMMAP_FXO_H__
#define __MEMMAP_FXO_H__


#define FXOS8700CQ_ADDRESS    0x1E
#define READ                  0x00
#define WRITE                 0x80
/**************************STATUS Register********************************/
#define ZYXOW_MASK            0x80
#define ZOW_MASK              0x40
#define YOW_MASK              0x20
#define XOW_MASK              0x10
#define ZYXDR_MASK            0x08
#define ZDR_MASK              0x04
#define YDR_MASK              0x02
#define XDR_MASK              0x01

/**************************STATUS Register********************************/
#define F_OVF_MASK            0x80
#define F_WMRK_FLAG_MASK      0x40
#define F_CNT5_MASK           0x20
#define F_CNT4_MASK           0x10
#define F_CNT3_MASK           0x08
#define F_CNT2_MASK           0x04
#define F_CNT1_MASK           0x02
#define F_CNT0_MASK           0x01
#define F_CNT_MASK            0x3F

/**************************STATUS Register********************************/
#define OUT_X_MSB_REG         0x01
#define OUT_X_LSB_REG         0x02
#define OUT_Y_MSB_REG         0x03
#define OUT_Y_LSB_REG         0x04
#define OUT_Z_MSB_REG         0x05
#define OUT_Z_LSB_REG         0x06

/**************************FIFO Register********************************/
#define F_MODE1_MASK          0x80
#define F_MODE0_MASK          0x40
#define F_WMRK5_MASK          0x20
#define F_WMRK4_MASK          0x10
#define F_WMRK3_MASK          0x08
#define F_WMRK2_MASK          0x04
#define F_WMRK1_MASK          0x02
#define F_WMRK0_MASK          0x01
#define F_MODE_MASK           0xC0
#define F_WMRK_MASK           0x3F

#define F_MODE_DISABLED       0x00
#define F_MODE_CIRCULAR       (F_MODE0_MASK)
#define F_MODE_FILL           (F_MODE1_MASK)
#define F_MODE_TRIGGER        (F_MODE1_MASK+F_MODE0_MASK)

/**************************TRIG_CFG Register********************************/
#define TRIG_TRANS_MASK       0x20
#define TRIG_LNDPRT_MASK      0x10
#define TRIG_PULSE_MASK       0x08
#define TRIG_FF_MT_MASK       0x04

/**************************SYSMOD Register********************************/
#define FGERR_MASK            0x80    
#define FGT_4_MASK            0x40    
#define FGT_3_MASK            0x20    
#define FGT_2_MASK            0x10    
#define FGT_1_MASK            0x08    
#define FGT_0_MASK            0x04    
#define FGT_MASK              0x7C    
#define SYSMOD1_MASK          0x02
#define SYSMOD0_MASK          0x01
#define SYSMOD_MASK           0x03

#define SYSMOD_STANDBY        0x00
#define SYSMOD_WAKE           (SYSMOD0_MASK)
#define SYSMOD_SLEEP          (SYSMOD1_MASK)

/**************************INT_SOURCE Register********************************/
#define SRC_ASLP_MASK         0x80
#define SRC_FIFO_MASK         0x40    
#define SRC_TRANS_MASK        0x20
#define SRC_LNDPRT_MASK       0x10
#define SRC_PULSE_MASK        0x08
#define SRC_FF_MT_MASK        0x04
#define SRC_DRDY_MASK         0x01

/***********************WHO_AM_I Device ID Register****************************/
#define FXOS8700CQ_ID            0xC7
#define MXOS8700CQ_ID            0xC4

/****************XYZ_DATA_CFG Sensor Data Configuration Register***************/
#define HPF_OUT_MASK          0x10    // MMA8451 and MMA8452 only
#define FS1_MASK              0x02
#define FS0_MASK              0x01
#define FS_MASK               0x03

#define FULL_SCALE_2G         0x00
#define FULL_SCALE_4G         (FS0_MASK)
#define FULL_SCALE_8G         (FS1_MASK)


/************HP_FILTER_CUTOFF High Pass Filter Register **********************/
#define PULSE_HPF_BYP_MASK    0x20
#define PULSE_LPF_EN_MASK     0x10
#define SEL1_MASK             0x02
#define SEL0_MASK             0x01
#define SEL_MASK              0x03

/*************PL_STATUS Portrait/Landscape Status Register *******************/
#define NEWLP_MASK            0x80
#define LO_MASK               0x40
#define LAPO1_MASK            0x04
#define LAPO0_MASK            0x02
#define BAFRO_MASK            0x01
#define LAPO_MASK             0x06


/************** PL_CFG Portrait/Landscape Configuration Register***************/
#define DBCNTM_MASK           0x80
#define PL_EN_MASK            0x40

/*****PL_BF_ZCOMP Back/Front and Z Compensation Register***********************/

#define BKFR1_MASK            0x80
#define BKFR0_MASK            0x40
#define ZLOCK2_MASK           0x04
#define ZLOCK1_MASK           0x02
#define ZLOCK0_MASK           0x01
#define BKFR_MASK             0xC0
#define ZLOCK_MASK            0x07

/************PL_P_L_THS Portrait to Landscape Threshold Register***************/
#define PL_P_L_THS_REG        0x14

#define P_L_THS4_MASK         0x80
#define P_L_THS3_MASK         0x40
#define P_L_THS2_MASK         0x20
#define P_L_THS1_MASK         0x10
#define P_L_THS0_MASK         0x08
#define HYS2_MASK             0x04
#define HYS1_MASK             0x02
#define HYS0_MASK             0x01
#define P_L_THS_MASK          0xF8
#define HYS_MASK              0x07

/********************FF_MT_CFG Freefall and Motion Configuration Register******/
#define FF_MT_CFG_REG         0x15

#define ELE_MASK              0x80
#define OAE_MASK              0x40
#define ZEFE_MASK             0x20
#define YEFE_MASK             0x10
#define XEFE_MASK             0x08

/**********FF_MT_SRC Freefall and Motion Source Registers**********************/
#define FF_MT_SRC_REG         0x16

#define EA_MASK               0x80
#define ZHE_MASK              0x20
#define ZHP_MASK              0x10
#define YHE_MASK              0x08
#define YHP_MASK              0x04
#define XHE_MASK              0x02
#define XHP_MASK              0x01

/*****FF_MT_THS Freefall and Motion Threshold Registers*********************/
#define FT_MT_THS_REG         0x17
#define TRANSIENT_THS_REG     0x1F

#define DBCNTM_MASK           0x80
#define THS6_MASK             0x40
#define THS5_MASK             0x20
#define THS4_MASK             0x10
#define THS3_MASK             0x08
#define THS2_MASK             0x04
#define TXS1_MASK             0x02
#define THS0_MASK             0x01
#define THS_MASK              0x7F


/********FF_MT_COUNT Freefall Motion Count Registers************************/
#define FF_MT_COUNT_REG       0x18


/****************TRANSIENT_CFG Transient Configuration Register****************/

#define TELE_MASK             0x10
#define ZTEFE_MASK            0x08
#define YTEFE_MASK            0x04
#define XTEFE_MASK            0x02
#define HPF_BYP_MASK          0x01


/***********TRANSIENT_SRC Transient Source Register****************************/

#define TEA_MASK              0x40
#define ZTRANSE_MASK          0x20
#define Z_TRANS_POL_MASK      0x10
#define YTRANSE_MASK          0x08
#define Y_TRANS_POL_MASK      0x04
#define XTRANSE_MASK          0x02
#define X_TRANS_POL_MASK      0x01


/**************************PULSE_CFG Register****************************/

#define DPA_MASK              0x80
#define PELE_MASK             0x40
#define ZDPEFE_MASK           0x20
#define ZSPEFE_MASK           0x10
#define YDPEFE_MASK           0x08
#define YSPEFE_MASK           0x04
#define XDPEFE_MASK           0x02
#define XSPEFE_MASK           0x01


/**************************PULSE_SRC Register********************************/

#define PEA_MASK              0x80
#define AXZ_MASK              0x40
#define AXY_MASK              0x20
#define AXX_MASK              0x10
#define DPE_MASK              0x08
#define POLZ_MASK             0x04
#define POLY_MASK             0x02
#define POLX_MASK             0x01

#define PTHS_MASK             0x7F

/***************CTRL_REG1 System Control 1 Register****************************/
#define ASLP_RATE1_MASK       0x80
#define ASLP_RATE0_MASK       0x40
#define DR2_MASK              0x20
#define DR1_MASK              0x10
#define DR0_MASK              0x08
#define LNOISE_MASK           0x04
#define FREAD_MASK            0x02
#define ACTIVE_MASK           0x01

#define ASLP_RATE_MASK        0xC0
#define DR_MASK               0x38

#define ASLP_RATE_20MS        0x00
#define ASLP_RATE_80MS        (ASLP_RATE0_MASK)
#define ASLP_RATE_160MS       (ASLP_RATE1_MASK)
#define ASLP_RATE_640MS       (ASLP_RATE1_MASK+ASLP_RATE0_MASK)

#define ASLP_RATE_50HZ        (ASLP_RATE_20MS)
#define ASLP_RATE_12_5HZ      (ASLP_RATE_80MS)
#define ASLP_RATE_6_25HZ      (ASLP_RATE_160MS)
#define ASLP_RATE_1_56HZ      (ASLP_RATE_640MS)

#define HYB_ASLP_RATE_25HZ        (ASLP_RATE_20MS)
#define HYB_ASLP_RATE_6_25HZ      (ASLP_RATE_80MS)
#define HYB_ASLP_RATE_1_56HZ      (ASLP_RATE_160MS)
#define HYB_ASLP_RATE_0_8HZ       (ASLP_RATE_640MS)

#define DATA_RATE_1250US      0x00
#define DATA_RATE_2500US      (DR0_MASK)
#define DATA_RATE_5MS         (DR1_MASK)
#define DATA_RATE_10MS        (DR1_MASK+DR0_MASK)
#define DATA_RATE_20MS        (DR2_MASK)
#define DATA_RATE_80MS        (DR2_MASK+DR0_MASK)
#define DATA_RATE_160MS       (DR2_MASK+DR1_MASK)
#define DATA_RATE_640MS       (DR2_MASK+DR1_MASK+DR0_MASK)

#define DATA_RATE_800HZ       (DATA_RATE_1250US)
#define DATA_RATE_400HZ       (DATA_RATE_2500US)
#define DATA_RATE_200HZ       (DATA_RATE_5MS)
#define DATA_RATE_100HZ       (DATA_RATE_10MS)
#define DATA_RATE_50HZ        (DATA_RATE_20MS)
#define DATA_RATE_12_5HZ      (DATA_RATE_80MS)
#define DATA_RATE_6_25HZ      (DATA_RATE_160MS)
#define DATA_RATE_1_56HZ      (DATA_RATE_640MS)

#define HYB_DATA_RATE_400HZ   (DATA_RATE_1250US)
#define HYB_DATA_RATE_200HZ   (DATA_RATE_2500US)
#define HYB_DATA_RATE_100HZ   (DATA_RATE_5MS)
#define HYB_DATA_RATE_50HZ    (DATA_RATE_10MS)
#define HYB_DATA_RATE_25HZ    (DATA_RATE_20MS)
#define HYB_DATA_RATE_6_25HZ  (DATA_RATE_80MS)
#define HYB_DATA_RATE_3_15HZ  (DATA_RATE_160MS)
#define HYB_DATA_RATE_0_8HZ   (DATA_RATE_640MS)

#define ACTIVE                (ACTIVE_MASK)
#define STANDBY               0x00


/***************CTRL_REG2 System Control 2 Register****************************/
#define ST_MASK               0x80
#define RST_MASK              0x40
#define SMODS1_MASK           0x10
#define SMODS0_MASK           0x08
#define SLPE_MASK             0x04
#define MODS1_MASK            0x02
#define MODS0_MASK            0x01
#define SMODS_MASK            0x18
#define MODS_MASK             0x03

#define SMOD_NORMAL           0x00
#define SMOD_LOW_NOISE        (SMODS0_MASK)
#define SMOD_HIGH_RES         (SMODS1_MASK)
#define SMOD_LOW_POWER        (SMODS1_MASK+SMODS0_MASK)

#define MOD_NORMAL            0x00
#define MOD_LOW_NOISE         (MODS0_MASK)
#define MOD_HIGH_RES          (MODS1_MASK)
#define MOD_LOW_POWER         (MODS1_MASK+MODS0_MASK)


/***************CTRL_REG3 System Control 3 Register****************************/
#define FIFO_GATE_MASK        0x80    
#define WAKE_TRANS_MASK       0x40
#define WAKE_LNDPRT_MASK      0x20
#define WAKE_PULSE_MASK       0x10
#define WAKE_FF_MT_MASK       0x08
#define WAKE_EN_A_VECM        0x04
#define IPOL_MASK             0x02
#define PP_OD_MASK            0x01

/***************CTRL_REG4 System Control 4 Register****************************/
#define INT_EN_ASLP_MASK      0x80
#define INT_EN_FIFO_MASK      0x40  
#define INT_EN_TRANS_MASK     0x20
#define INT_EN_LNDPRT_MASK    0x10
#define INT_EN_PULSE_MASK     0x08
#define INT_EN_FF_MT_MASK     0x04
#define INT_EN_DRDY_MASK      0x01

/***************CTRL_REG5 System Control 5 Register****************************/
#define INT_CFG_ASLP_MASK     0x80
#define INT_CFG_FIFO_MASK     0x40
#define INT_CFG_TRANS_MASK    0x20
#define INT_CFG_LNDPRT_MASK   0x10
#define INT_CFG_PULSE_MASK    0x08
#define INT_CFG_FF_MT_MASK    0x04
#define INT_CFG_DRDY_MASK     0x01

/*
**  XYZ Offset Correction Registers
*/
#define OFF_X_REG             0x2F
#define OFF_Y_REG             0x30
#define OFF_Z_REG             0x31

/*
**  MAG CTRL_REG1 System Control 1 Register
*/
#define M_ACAL_MASK           0x80
#define M_RST_MASK            0x40
#define M_OST_MASK            0x20
#define M_OSR2_MASK           0x10
#define M_OSR1_MASK           0x08
#define M_OSR0_MASK           0x04
#define M_HMS1_MASK           0x02
#define M_HMS0_MASK           0x01

#define M_OSR_MASK            0x1C
#define M_HMS_MASK            0x03

//OSR Selections
#define M_OSR_1_56_HZ         0x00
#define M_OSR_6_25_HZ         M_OSR0_MASK
#define M_OSR_12_5_HZ         M_OSR1_MASK
#define M_OSR_50_HZ           M_OSR1_MASK+M_OSR0_MASK
#define M_OSR_100_HZ          M_OSR2_MASK
#define M_OSR_200_HZ          M_OSR2_MASK+M_OSR0_MASK
#define M_OSR_400_HZ          M_OSR2_MASK+M_OSR1_MASK
#define M_OSR_800_HZ          M_OSR2_MASK+M_OSR1_MASK+M_OSR0_MASK

//Hybrid Mode Selection
#define ACCEL_ACTIVE          0x00
#define MAG_ACTIVE            M_HMS0_MASK
#define HYBRID_ACTIVE         (M_HMS1_MASK | M_HMS0_MASK)


/*
**  MAG CTRL_REG2 System Control 2 Register
*/

#define M_HYB_AUTOINC_MASK    0x20
#define M_MAXMIN_DIS_MASK     0x10
#define M_MAXMIN_DIS_THS_MASK 0x08
#define M_MAXMIN_RST_MASK     0x04
#define M_RST_CNT1_MASK       0x02
#define M_RST_CNT0_MASK       0x01

//Mag Auto-Reset De-Gauss Frequency
#define RST_ODR_CYCLE         0x00
#define RST_16_ODR_CYCLE      M_RST_CNT0_MASK
#define RST_512_ODR_CYCLE     M_RST_CNT1_MASK
#define RST_DISABLED          M_RST_CNT1_MASK+M_RST_CNT0_MASK

/*
**  MAG CTRL_REG3 System Control 3 Register
*/

#define M_RAW_MASK            0x80
#define M_ASLP_OS_2_MASK      0x40
#define M_ASLP_OS_1_MASK      0x20
#define M_ASLP_OS_0_MASK      0x10
#define M_THS_XYZ_MASK        0x08
#define M_ST_Z_MASK           0x04
#define M_ST_XY1_MASK         0x02
#define M_ST_XY0_MASK         0x01
#define M_ASLP_OSR_MASK       0x70
#define M_ST_XY_MASK          0x03

//OSR Selections
#define M_ASLP_OSR_1_56_HZ    0x00
#define M_ASLP_OSR_6_25_HZ    M_ASLP_OS_0_MASK
#define M_ASLP_OSR_12_5_HZ    M_ASLP_OS_1_MASK
#define M_ASLP_OSR_50_HZ      M_ASLP_OS_1_MASK+M_ASLP_OS_0_MASK
#define M_ASLP_OSR_100_HZ     M_ASLP_OS_2_MASK
#define M_ASLP_OSR_200_HZ     M_ASLP_OS_2_MASK+M_ASLP_OS_0_MASK
#define M_ASLP_OSR_400_HZ     M_ASLP_OS_2_MASK+M_ASLP_OS_1_MASK
#define M_ASLP_OSR_800_HZ     M_ASLP_OS_2_MASK+M_ASLP_OS_1_MASK+M_ASLP_OS_0_MASK

/*
**  MAG INT SOURCE M_INT_SRC Register
*/
#define SRC_M_DRDY_MASK       0x01
#define SRC_M_VECM_MASK       0x02
#define SRC_M_THS_MASK        0x04

/*
**  ACCEL VECTOR CONFIG Register
*/


#define A_VECM_INIT_CFG_MASK  0x40
#define A_VECM_INIT_EN_MASK   0x20
#define A_VECM_WAKE_EN_MASK   0x10
#define A_VECM_EN_MASK        0x08
#define A_VECM_UPDM_MASK      0x04
#define A_VECM_INITM_MASK     0x02
#define A_VECM_ELE_MASK       0x01

/*
**  ACCEL VECTOR THS MSB AND LSB Register
*/


#define A_VECM_DBCNTM_MASK    0x80


/*
**  MAG VECTOR CONFIG Register
*/


#define M_VECM_INIT_CFG_MASK  0x40
#define M_VECM_INIT_EN_MASK   0x20
#define M_VECM_WAKE_EN_MASK   0x10
#define M_VECM_EN_MASK        0x08
#define M_VECM_UPDM_MASK      0x04
#define M_VECM_INITM_MASK     0x02
#define M_VECM_ELE_MASK       0x01

/*
**  MAG VECTOR THS MSB AND LSB Register
*/

#define M_VECM_DBCNTM_MASK    0x80

/*
**  ACCEL FFMT THS X MSB AND LSB Register
*/

#define A_FFMT_THS_XYZ_EN_MASK 0x80
#define A_FFMT_THS_X_LSB_MASK  0xFC

/*
**  ACCEL FFMT THS Y MSB AND LSB Register
*/

#define A_FFMT_THS_Y_EN_MASK 0x80
#define A_FFMT_THS_Y_LSB_MASK  0xFC

/*
**  ACCEL FFMT THS Z MSB AND LSB Register
*/

#define A_FFMT_THS_Z_EN_MASK        0x80
#define A_FFMT_THS_Z_LSB_MASK       0xFC

#define FXOS8700CQ_WHOAMI_VAL 	0xC7		// FXOS8700CQ WHOAMI production register value
#define FXOS8700CQ_READ_LEN 	12			// 6 channels of two bytes = 12 bytes 
#define UINT14_MAX 				16383		// For processing the accelerometer data to right-justified 2's complement

/*************************MAG_THS_CFG*****************************/

#define M_THS_ELE       0x80
#define M_THS_OAE       0x40
#define M_THS_ZEFE      0x20
#define M_THS_YEFE      0x80
#define M_THS_XEFE      0x08
#define M_THS_WAKE_EN   0x04
#define M_THS_INT_EN    0x02
#define M_THS_INT_CFG   0x01

#define M_THS_EA        0x80

/*****************************************************************/
#define M_VECM_ELE          0x40
#define M_VECM_INITM        0x20
#define M_VECM_UPDM         0x10
#define M_VECM_EN           0x08
#define M_VECM_WAKE_EN      0x04
#define M_VECM_INT_EN       0x02
#define M_VECM_INIT_CFG     0x01


#endif

Android Things BLE client, prints to serial port.

First version.

Credits

Dimiter Kendri

Dimiter Kendri

23 projects • 159 followers
Robotics and AI

Comments