Example #1
0
// --------------------------------------------------------
// MMA7455_init
//
// Initialize the MMA7455.
// Set also the offset, assuming that the accelerometer is
// in flat horizontal position.
//
// Important notes about the offset:
//    The sensor has internal registers to set an offset.
//    But the offset could also be calculated by software.
//    This function uses the internal offset registers
//    of the sensor.
//    That turned out to be bad idea, since setting the
//    offset alters the actual offset of the sensor.
//    A second offset calculation had to be implemented
//    to fine tune the offset.
//    Using software variables for the offset would be
//    much better.
//
//    The offset is influenced by the slightest vibration
//    (like a computer on the table).
//
int MMA7455_init(uint8_t mode, unsigned char do_calibration)
{
	int x, y, z, error;
	xyz_union xyz;
	uint8_t c1, c2;

	// Initialize the sensor
	//
	// Sensitivity:
	//    2g : GLVL0
	//    4g : GLVL1
	//    8g : GLVL1 | GLVL0
	// Mode:
	//    Standby         : 0
	//    Measurement     : MODE0
	//    Level Detection : MODE1
	//    Pulse Detection : MODE1 | MODE0
	// There was no need to add functions to write and read
	// a single byte. So only the two functions to write
	// and read multiple bytes are used.

	c1 = mode;
	error = MMA7455_write(MMA7455_MCTL, &c1, 1);
	if (error != 0)
		return (error);

	// Read it back, to test the sensor and communication.
	error = MMA7455_read(MMA7455_MCTL, &c2, 1);
	if (error != 0)
		return (error);

	if (c1 != c2)
		return (-99);

	// Nothing to do here if calibration skipped
	if (!do_calibration)
		return (0);

	// Clear the offset registers.
	// If the Arduino was reset or with a warm-boot,
	// there still could be offset written in the sensor.
	// Only with power-up the offset values of the sensor
	// are zero.
	xyz.value.x = xyz.value.y = xyz.value.z = 0;
	error = MMA7455_write(MMA7455_XOFFL, (uint8_t *) &xyz, 6);
	if (error != 0)
		return (error);

	// The mode has just been set, and the sensor is activated.
	// To get a valid reading, wait some time.
	_delay_ms(100);

	// Calcuate the offset.
	//
	// The values are 16-bits signed integers, but the sensor
	// uses offsets of 11-bits signed integers.
	// However that is not a problem,
	// as long as the value is within the range.

	// Assuming that the sensor is flat horizontal,
	// the 'z'-axis should be 1 'g'. And 1 'g' is
	// a value of 64 (if the 2g most sensitive setting
	// is used).
	// Note that the actual written value should be doubled
	// for this sensor.

	error = MMA7455_xyz (&x, &y, &z); // get the x,y,z values
	if (error != 0)
		return (error);

	xyz.value.x = 2 * -x;        // The sensor wants double values.
	xyz.value.y = 2 * -y;
	xyz.value.z = 2 * -(z-64);   // 64 is for 1 'g' for z-axis.

	error = MMA7455_write(MMA7455_XOFFL, (uint8_t *) &xyz, 6);
	if (error != 0)
		return (error);

	// The offset has been set, and everything should be okay.
	// But by setting the offset, the offset of the sensor
	// changes.
	// A second offset calculation has to be done after
	// a short delay, to compensate for that.
	_delay_ms(200);

	error = MMA7455_xyz (&x, &y, &z);    // get te x,y,z values again
	if (error != 0)
		return (error);

	xyz.value.x += 2 * -x;       // add to previous value
	xyz.value.y += 2 * -y;
	xyz.value.z += 2 * -(z-64);  // 64 is for 1 'g' for z-axis.

	// Write the offset for a second time.
	// This time the offset is fine tuned.
	error = MMA7455_write(MMA7455_XOFFL, (uint8_t *) &xyz, 6);
	if (error != 0)
		return (error);

	return (0);          // return : no error
}
Example #2
0
int MMA7455::write(int start, const uint8_t *pData, int size)
{
	return MMA7455_write(start, pData, size);
}