Tilt sensor (Part 4)

Part 123456789

Let’s for coding now. Firstly we need to set the analog reference to Internal as follows

	analogReference(INTERNAL);

and build a simple acquiring / converting routine

double analogReadMv(uint8_t channel) {
	double analogValue = 0;
	for (uint8_t _sample = 0; _sample < _samples; _sample++) {
		analogValue += analogRead(vAdcPin[channel]); /* Sum measurements */
	}
	analogValue /= _samples; /* Compute average */	
	analogValue *= 1100.0; /* Convert to millivolts */
	analogValue /= 1024.0;
	/* Retuned value */
	return(analogValue);
}

Note:

  • Some signal conditionning is performed by simple box car smoothing using the global _samples variable

And this is the use you can make of this function in order to acquire raw acceleration data (in mV)

	/* Acquire raw data */
	for (uint8_t channel = 0; channel < _channels; channel++) {	
		vRawData[channel] = analogReadMv(channel, samples);
	}

You can now display the acquired data using the following function:

void displayData(double *ptrData) {
	/* Display header */
	/*               1234567890123456        */
	LCD.printString("  X     Y     Z ", 1);
	/* Display data */
	LCD.eraseBuffer();	
	for (uint8_t channel = 0; channel < _channels; channel++) {
		LCD.insertFloat(ptrData[channel], 0, 4 + (channel * 6), LCD_ALI_RIGHT);	
	}	
	LCD.printBuffer(2);
}

Note:

From the raw data, we want to substract the offset for each channel in this way

	/* Offset data */
	for (uint8_t channel = 0; channel < _channels; channel++) {	
		vOffData[channel] = (vRawData[channel] - vOffset[channel]);
	}

Notes:

  • Vectors of data are global and given different names in order to give us a chance to display any type of data during normal operation.
  • Offsets can be calculated from the ADXL335 data sheet or computed after a calibration process which will be discussed later. The default value is 486 mV for VSS = 3.3 V.

Next post on same subject

4 Comments

  1. Bowser says:

    1/* Acquire raw data */

    Line 3 vRawData[channel] = analogReadMv(channel, samples);

    but

    01 double analogReadMv(uint8_t channel)

    only takes one parameter

    am I missing something?

  2. Didier says:

    You are perfectly right.

    You may decide to use the following function in addition with the global _samples variable

    double analogReadMv(uint8_t channel) {
    double analogValue = 0;
    for (uint8_t _sample = 0; _sample < _samples; _sample++) { analogValue += analogRead(vAdcPin[channel]); /* Sum measurements */ } analogValue /= _samples; /* Compute average */ analogValue *= 1100.0; /* Convert to millivolts */ analogValue /= 1024.0; /* Retuned value */ return(analogValue); } or use an overlaoded function such as double analogReadMv(uint8_t channel) { return(analogReadMv(channel, _samples)); } Thanks for your comment

  3. Rudy says:

    I am new to the Arduino and not to electrically minded but want to use Arduino to interface with this tilt sensor and a servo that will move to the exact opposite position of the sensor. Meaning if the sensor reads 30 degrees the servo would move to a 210 degree position. Would you be able to give me some directions as to how I might acheive this?
    Thank you,
    Rudy

    • Didier says:

      Hi Rudy,
      I did not consider this question yet, in spite of great interest (or say curiosity) for these devices which control a ball on a tilted surface. However, I think that, and it depends upon your application, you may have to use the tilt reading as an error value compared to horizontality and apply it to a PID (Proportional Integral Derivative) controller. Look at the balancing robots papers, the principles are similar.
      Good luck

Leave a Reply

You must be logged in to post a comment.