예제 #1
0
파일: MMA7455.cpp 프로젝트: ricki-z/MMA7455
void MMA7455::begin() {
#else
void MMA7455::begin(uint8_t pin_sda, uint8_t pin_scl) {
#endif
  int error;
  uint8_t c;

#if defined __AVR__
  Wire.begin();
#else
  _pin_sda = pin_sda;
  _pin_scl = pin_scl;

  // Initialize the 'Wire' class for I2C-bus communication.
  Wire.begin(_pin_sda,_pin_scl);
#endif

  // Initialize the MMA7455, and set the offset.
  error = MMA7455_init();
  if (error == 0)
    Serial.println("The MMA7455 is okay");
  else
    Serial.println("Check your wiring !");


  // Read the Status Register
  MMA7455_read(MMA7455_STATUS, &c, 1);

  // Read the "Who am I" value
  MMA7455_read(MMA7455_WHOAMI, &c, 1);

  // Read the optional temperature output value (I always read zero)
  MMA7455_read(MMA7455_TOUT, &c, 1);
}
예제 #2
0
파일: MMA7455.cpp 프로젝트: ricki-z/MMA7455
// --------------------------------------------------------
// MMA7455_xyz
//
// Get the 'g' forces.
// The values are with integers as 64 per 'g'.
//
int MMA7455_xyz( uint16_t *pX, uint16_t *pY, uint16_t *pZ)
{
  xyz_union xyz;
  int error;
  uint8_t c;

  // Wait for status bit DRDY to indicate that
  // all 3 axis are valid.
  do
  {
    error = MMA7455_read (MMA7455_STATUS, &c, 1);
  } while ( !bitRead(c, MMA7455_DRDY) && error == 0);
  if (error != 0)
    return (error);

  // Read 6 bytes, containing the X,Y,Z information
  // as 10-bit signed integers.
  error = MMA7455_read (MMA7455_XOUTL, (uint8_t *) &xyz, 6);
  if (error != 0)
    return (error);

  // The output is 10-bits and could be negative.
  // To use the output as a 16-bit signed integer,
  // the sign bit (bit 9) is extended for the 16 bits.
  if (xyz.reg.x_msb & 0x02)    // Bit 9 is sign bit.
    xyz.reg.x_msb |= 0xFC;     // Stretch bit 9 over other bits.
  else
    xyz.reg.x_msb &= 0x3;

  if (xyz.reg.y_msb & 0x02)
    xyz.reg.y_msb |= 0xFC;
  else
    xyz.reg.y_msb &= 0x3;

  if (xyz.reg.z_msb & 0x02)
    xyz.reg.z_msb |= 0xFC;
  else
    xyz.reg.z_msb &= 0x3;

  // The result is the g-force in units of 64 per 'g'.
  *pX = xyz.value.x;
  *pY = xyz.value.y;
  *pZ = xyz.value.z;

  return (0);                  // return : no error
}
예제 #3
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
}
예제 #4
0
파일: MMA7455.cpp 프로젝트: ricki-z/MMA7455
int MMA7455::read(int start, uint8_t *buffer, int size)
{
	return MMA7455_read(start, buffer, size);
}