Be patient with me. I'm not a professional programmer (yet) and this is my first stab at C. Here is the start of my library for accessing accelerometer functions.
The returned tilt is in the form of a quadrant. It starts at the top right corner and runs counter clockwise. The neutral setting represents the center space or dead space where there is not quadrant returned. What I'm needing is a little help correcting what is not correct for Arduino. I do know that it is not yet defined for a library, but am I heading in the right direction?
int pwrPin; // not initialized in case not used
int gndPin; // "
int xPin; // variable to set x pin
int yPin; // y pin
int zPin; // z pin
int stPin; // self test pin, build does not use
long x, y, z; // hold raw x,y,z reading from sensor
int xAngle, yAngle, zAngle; // hold angle conversions
const int samples = 10; // number of samples for error
int readingX[samples]; // array of x samples
int readingY[samples]; // y
int readingZ[samples]; // z
int neutral = 3; // variable that will hold the deadspace for quadrants
int sensorMax = 0; // holds specification for max sensor range
int sensorMin = 0; // holds specification for min sensor range
// not sure if this will work because the pwrPin and gndPin were not initialized and since this
// only runs once........
void setup()
{
if (pwrPin != NULL) {
pinMode(pwrPin, OUTPUT);
digitalWrite(pwrPin, HIGH);
}
if (gndPin != NULL){
pinMode(gndPin, OUTPUT);
digitalWrite(gndPin, LOW);
}
x = y = z = 0;
}
void loop(){
// read in (x) samples into the array
for (int i=0; i<samples; i++){
readingX[i] = analogRead(xPin);
readingY[i] = analogRead(yPin);
readingZ[i] = analogRead(zPin);
}
// sum up all the array for averaging
for (int i=0; i<samples; i++){
x = x + readingX[i];
y = y + readingY[i];
z = z + readingZ[i];
}
// spit out the averages
x = x/samples;
y = y/samples;
z = z/samples;
}
// returns the quadrant that the accelerometer is indicating, quadrants start in top right and go counter clockwise
int getTiltQuadrant(){
if(x>=neutral && y>=neutral)return 1;
if(x>-neutral && x<neutral && y>neutral)return 2;
if(x<=neutral && y>=neutral)return 3;
if(x<=-neutral && y>-neutral && y<neutral) return 4;
if(x<-neutral && y<=-neutral) return 5;
if(x>-neutral && x<neutral && y<-neutral) return 6;
if(x>=neutral && y<=neutral) return 7;
if(x>=neutral && y>-neutral && y<neutral) return 8;
}
int getQuadrantTiltAngle(){
if (x>0 && y>0) return atan(x/y);
if (x>0 && y<0) return atan((x/y)+180);
if (x<0 && y<0) return atan((x/y)+180);
if (x<0 && y>0) return atan((x/y)+360);
}
// get the angle of the x in relation to plane
int getXAngle(){
xAngle = map(x, sensorMin, sensorMax, -90, 90);
return xAngle;
}
// y axis
int getYAngle(){
yAngle = map(y, sensorMin, sensorMax, -90, 90);
return yAngle;
}
// z axis
int getZAngle(){
zAngle = map(z, 662, 355, -90, 90);
return zAngle;
}
// setters and getters section
int getX(){
return x;
}
int getY(){
return y;
}
int getZ(){
return z;
}
void setXPin(int pin){
xPin = pin;
}
void setYPin(int pin){
yPin = pin;
}
void setZPin(int pin){
zPin = pin;
}
void setPwrPin(int pin){
pwrPin = pin;
}
void setGndPin(int pin){
gndPin = pin;
}
void setNeutral(int neutral){
neutral = neutral;
}
void setSensorMax(int maxS){
sensorMax = maxS;
}
void setSenorMin(int minS){
sensorMin = minS;
}
Ok, so I have created my first class in the Accelerometer_Tools library but I'm having some issues.
ADXL335.cpp:33: error: expected unqualified-id before 'void'
I can't seem to figure out what the deal is. --- please help.
I would include the library, but it will not allow me to.
Here is the header file:
/*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
/* * * * * * * * * * * * * * * * * * * * * * * * * * * *
Code by Richard Lowe
* * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "WProgram.h"
#ifndef ADXL335_h
#define ADXL335_h
#include <inttypes.h>
class ADXL335{
public:
// initialize object
ADXL335(uint8_t pwrPin, uint8_t gndPin, uint8_t xPin, uint8_t yPin, uint8_t zPin, uint8_t stPin, int max, int min);
// reads the accelerometer
void readAccelerometer();
// returns 1 of 8 quadrants tilt is found
int getTiltQuadrant();
// returns the angle of tilt
int getQuadrantTiltAngle();
// sets the neutral center for quadrants
void setNeutral(int neutral);
// returns x angle in reference to flat plane
int getXAngle();
// returns y angle in reference to flat plane
int getYAngle();
// returns z angle in reference to flat plane
int getZAngle();
// returns x average reading from sensor
int getX();
// returns y average reading from sensor
int getY();
// returns z average reading from sensor
int getZ();
private:
int _xPin;
int _yPin;
int _zPin;
int _pwrPin;
int _gndPin;
int _stPin;
int _x;
int _y;
int _z;
int _xAngle;
int _yAngle;
int _zAngle;
int _neutral;
int _sensorMax;
int _sensorMin;
};
#endif
Part of my issue is not knowing how to declare arrays in the header and how to make those arrays a fixed size of another declared variable.
Looks pretty good and professional. My confusion: how do you tell which quadrant? The accelerometer can't tell orienation, just tilt angle with vertical axis. You need a magnetic sensor to tell orientation or heading. That's what I thought. Was I wrong?
I'm still in testing, but everything seems to work fine. I'm building an example to help out.
You have an x and y coordinate from tilt along the respective axis. You can use simple if statements to define which quadrant it is in. The idea is that if you have spring mounted actuators on a board with an accelerometer mounted in the center. If you place a ball on the table, the quadrant would determine where and how much the actuator pushes up. Therefore balancing the weight in the center or deadzone in the center. If you leave the default neutral to 0 it would continually try to get it in perfect balance. If you leave yourself a small salezone in the center it could come to rest in that area.
I don't know if I'm correct either. I'm new out of college and with VERY little C experience. I'm still struggling with how to pass arrays, pointers, ......
I'm just finishing the first accelerometer for the libray a ADXL335 3 axis model. If there is anywhere on this site I could post it we might just get the library filled with all sorts of models and functions.
That's it, you're not rotating on a vertical axis so surely you can figure out your quadrant. I didn't know your problem was balancing a ball on a stage. If you had the accelerometer on a cellphone then you need a magnetic sensor to figure orientation of the normal direction of the cell phone. Good work on the code. How is hardware for the platform?
Hi there!
Is there a way you could use the serial monitor to display string of angles in degrees with your code. I am a total newbee,so your help will be greatly appreciated.
Hello every1!
its been long.Below is the code.It gives an error of about 10 degrees with real life investigation.NOW I AM TRYING TO STORE AND READ THIS FROM THE BUILT-IN EEPROMOF THE ARDUINO. I AM HAVING TROUBLE WITH 10Bit to 8 bit conversion. I understand that I will have to divide it by '4' according to the example given with arduino0022. But I cant read the values in 10 bit format smiley-sad.Pleae shout out if any1 can help.
/*
The circuit:
analog 0: accelerometer self test
analog 1: z-axis
analog 2: y-axis
analog 3: x-axis
analog 4: ground
analog 5: vcc
.
*/
// these constants describe the pins. They won't change:
const int groundpin = 18; // analog input pin 4 -- ground
const int powerpin = 19; // analog input pin 5 -- voltage
double xpin = A1; // x-axis of the accelerometer
double ypin = A2; // y-axis
double zpin = A3; // z-axis (only on 3-axis models)
const float arduino_power_supply = 5;
const float sensor_power_supply = 5;
const float zero_g_bias = sensor_power_supply / 2;
void setup()
{
// initialize the serial communications:
Serial.begin(9600);
// Provide ground and power by using the analog inputs as normal
// digital pins. This makes it possible to directly connect the
// breakout board to the Arduino. If you use the normal 5V and
// GND pins on the Arduino, you can remove these lines.
pinMode(groundpin, OUTPUT);
pinMode(powerpin, OUTPUT);
digitalWrite(groundpin, LOW);
digitalWrite(powerpin, HIGH);
}
It's a long program. I don't see where you marked in the program that you want looked at.
There are lots of places you use float and double unnecessarily. Anything you read from analog pin is integer with only 10 bit as you pointed out. Why are you using float and double to store them?
Well, a few things here.
A double on an Arduino is pointless, because it has exactly the same implementation as float.
Also, A1 has the value 15.
Not 15.0001, or 15.00145, but 15 spot on, because there isn't a pin 15.0001 or 15.00145.