I am working on a project that reads accelerometer data, does some digital signal processing to create a synthesized signal to output to a voice coil motor to relay haptic feedback for teleoperation. I have a program that can run the motor at different frequencies using the PWM lib that allows different frequencies on different pins. I also have a program that can read the accelerometer data and print out its principal component, but when I put them together I just get "ovf" for my accelerometer value. I have been trying to find the problem, and I believe it is the function InitTimersSafe() because when I comment this part out I get readings that I expect. I am not sure why it is affecting my accelerometer readings though, since I don't think analogRead() uses a timer. Is there something in the PWM library that I am missing, or does the library actually affect analogRead()?
Below is my code along with its header file, thanks in advance for any help!
#include "pca.h"
#include <PWM.h>
// Global Variables
int xPin = A2, yPin = A1, zPin = A0;
float xVal, yVal, zVal;
float xOffset, yOffset, zOffset;
int g = 9.81;
float t0 = 0, t, dt;
float input[3] = {0, 0 , 0}, output[3] = {0, 0, 0};
Eloquent::ML::Port::PCA pca;
void setup()
{
Serial.begin(9600);
zeroAvg(); //finding avg to get rid of DC bias
// Serial.print(xOffset);
// Serial.print(" ");
// Serial.print(yOffset);
// Serial.print(" ");
// Serial.println(zOffset);
t0 = millis();
InitTimersSafe();
// Serial.println(Timer0_GetFrequency());
// Serial.println(Timer1_GetFrequency());
}
void loop()
{
delay(20);
xVal = ((analogRead(xPin)/156.0)*g)- xOffset; //reading accelerometer data and getting rid of bias
yVal = ((analogRead(yPin)/174.0)*g)- yOffset;
zVal = ((analogRead(zPin)/192.0)*g)- zOffset;
dt = millis() - t0;
t = (t0 + dt)/1000;
t0 = t;
// Serial.print("Acc: "); // printing accel values
// Serial.print(xVal, 7);
// Serial.print(",");
// Serial.print(yVal, 7);
// Serial.print(",");
// Serial.print(zVal, 7);
// Serial.print(",");
// Serial.println(t);
input[0] = {xVal};
input[1] = {yVal};
input[2] = {zVal};
// Serial.print("PCA Inputs: "); // printing accel values
// Serial.print(input[0], 7);
// Serial.print(",");
// Serial.print(input[1], 7);
// Serial.print(",");
// Serial.print(input[2], 7);
// Serial.print(",");
// Serial.println(t);
pca.transform(input, output);
// Serial.print("PCA: "); // printing PCA values
Serial.print(output[0], 7);
// Serial.print(",");
// Serial.print(output[1], 7);
// Serial.print(",");
// Serial.print(output[5], 7); //idk why but this one seems to give reasonable readings
Serial.print(",");
Serial.println(t);
delay(200); // so we can actually read the data
}
// function for finding zero mean
void zeroAvg()
{
int k = 0;
float xSum = 0, ySum = 0, zSum = 0;
while (k < 1000) //average over 1000 iterations
{
xVal = (analogRead(xPin)/156.0)*g;
yVal = (analogRead(yPin)/174.0)*g;
zVal = (analogRead(zPin)/192.0)*g;
xSum = xSum + xVal;
ySum = ySum + yVal;
zSum = zSum + zVal;
k++;
}
xOffset = xSum/1000; // calculating offset values
yOffset = ySum/1000;
zOffset = zSum/1000;
}
This is the pca.h file that is included.
#pragma once
#include <stdarg.h> //<cstdarg>
namespace Eloquent {
namespace ML {
namespace Port {
class PCA {
public:
/**
* Apply dimensionality reduction
* @warn Will override the source vector if no dest provided!
*/
void transform(float *x, float *dest = NULL) {
static float u[2] = { 0 };
u[0] = dot(x, 0.361386591785 , -0.084522514065 , 0.85667060595 , 0.358289197152 );
u[1] = dot(x, 0.656588771287 , 0.730161434785 , -0.173372662796 , -0.075481019917 );
memcpy(dest != NULL ? dest : x, u, sizeof(float) * 2);
}
protected:
/**
* Compute dot product with varargs
*/
float dot(float *x, ...) {
va_list w;
va_start(w, 4);
static float mean[] = { 5.843333333333 , 3.057333333333 , 3.758 , 1.199333333333 };
float dot = 0.0;
for (uint16_t i = 0; i < 4; i++) {
dot += (x[i] - mean[i]) * va_arg(w, double); }
return dot;
}
};
}
}
}