//http://projectlab.engphys.ubc.ca/coursearchive/apsc150-electronics-2013/accelerometer-adxl335-on-gy-61-breakout-board/
//http://bildr.org/2011/04/sensing-orientation-with-the-adxl335-arduino/
//A gyro is great at measuring rotation, but has no understanding of orientation.
//An accelerometer is good at determining orientation, but has no ability to keep track during rotation.
#include "math.h"
//Analog read pins
const int xPin = A0;
const int yPin = A1;
const int zPin = A2;
/////////servo stuff/////////
int monitorlight = D7; //Light for testing
const int pwr_off = 0; //Sets analog signal to 0
int servoPin = D3;
Servo myServo;
int servoPos = 0;
int pos1= 90;
int pos2 = 50;
int quickness = 25;
//////Shake Variables//////////
int shake_type = 1;
int shake_iterations = 5;
int count = 0;
int thres_count = 2;
int last_zaverage = 2000;
int thres_shake = 3;
bool shake = FALSE;
bool event_being_pub = FALSE;
//The minimum and maximum values that came from
//the accelerometer while standing still
//You very well may need to change these
int minVal = 0;
int maxVal = 10000;
//to hold the caculated values
double x;
double y;
double z;
//variables for low pass filter
const int numReadings = 100;
int readIndex = 0;
int xtotal = 0;
int xaverage = 0;
int xreadings[numReadings];
int ytotal = 0;
int yaverage = 0;
int yreadings[numReadings];
int ztotal = 0;
int zaverage = 0;
int zreadings[numReadings];
void setup(){
Serial.begin(9600);
Particle.variable("window", &numReadings, INT);
Particle.variable("count", &count, INT);
Particle.variable("pos1", &pos1, INT);
Particle.variable("pos2", &pos2, INT);
Particle.variable("quickness", &quickness, INT);
Particle.function("window size", window_size);
Particle.subscribe("bz/new_shake",event_driven);
pinMode(D7, OUTPUT);
for (int thisReading = 0; thisReading < numReadings; thisReading++)
{
xreadings[thisReading] = 0;
yreadings[thisReading] = 0;
zreadings[thisReading] = 0;
}
pinMode(monitorlight, OUTPUT); //The light on the photon is set up for testing
myServo.attach( servoPin );
//Register our Particle to control the servo
Particle.function("servo", servoControl);
// Keep a cloud variable for the current position
Particle.variable( "servoPos" , &servoPos , INT );
Particle.function( "pos1", position1);
Particle.function( "pos2", position2);
Particle.function( "quickness", quick);
/*Particle.function("shake_iterations", shake_iterate);
Particle.function("shake_type", shaking_type);*/
// myServo.write(pos1);
}
void loop(){
//initialize the arrays for the rolling average that will serve as allow pass filter
//read the analog values from the accelerometer
int xRead = analogRead(xPin);
int yRead = analogRead(yPin);
int zRead = analogRead(zPin);
// subtract the last reading:
xtotal = xtotal - xreadings[readIndex];
ytotal = ytotal - yreadings[readIndex];
ztotal = ztotal - zreadings[readIndex];
// read from the sensor:
xreadings[readIndex] = analogRead(xPin);
yreadings[readIndex] = analogRead(yPin);
zreadings[readIndex] = analogRead(zPin);
// add the reading to the total:
xtotal = xtotal + xreadings[readIndex];
ytotal = ytotal + yreadings[readIndex];
ztotal = ztotal + zreadings[readIndex];
// advance to the next position in the array:
readIndex = readIndex + 1;
// if we're at the end of the array...
if (readIndex >= numReadings) {
// ...wrap around to the beginning:
readIndex = 0;
}
// calculate the average:
xaverage = xtotal / numReadings;
yaverage = ytotal / numReadings;
zaverage = ztotal / numReadings;
// send it to the computer as ASCII digit
//output reading to serial connection
send_info_to_serial(xRead, xaverage, yRead, yaverage, zRead, zaverage);
delay(1);//just here to slow down the serial output - Easier to read
//save filtered signal to check for delta
count++;
if (count == thres_count)
{ last_zaverage = zaverage;
count = 0;
}
//check for change in accelerometer
if ((abs(zaverage-last_zaverage) > thres_shake) && (millis() > 10000))
shake = TRUE;
//This triggers the hippo_shake
if (shake == TRUE)
{
hippo_shake(shake_type, shake_iterations);
/*if (event_being_pub == FALSE)
{*/
/*Particle.publish("bz/dad_play", "1");
event_being_pub = TRUE;
delay(6000);*/
/*}*/
}
}
////////////////////Functions/////////////////
int window_size( String speed ) //must return type int, and take an argument type string
{
int window_convert = speed.toInt();
int thres_shake = constrain(window_convert,0,600);
return 1;
}
void hippo_shake(int shake_type, int shake_iterations)
{
for (int p=1; p< shake_iterations; p++)
{
myServo.write(pos1);
delay(quickness);
myServo.write(pos2);
delay(quickness);
shake = FALSE;
}
}
void event_driven(const char *event, const char *data)
{
String hello = data;
int cmd_speed = hello.toInt();
}
void send_info_to_serial(int xRead, int xaverage, int yRead, int yaverage, int zRead, int zaverage)
{
Serial.print(" ");
Serial.print("x: ");
Serial.print(xRead);
Serial.print(" ");
Serial.print(xaverage);
Serial.print(" | y: ");
Serial.print(yRead);
Serial.print(" ");
Serial.print(yaverage);
Serial.print(" | z: ");
Serial.print(zRead);
Serial.print(" ");
Serial.println(zaverage);
}
int servoControl(String command)
{
// Convert
int newPos = command.toInt();
// Make sure it is in the right range
// And set the position
servoPos = constrain( newPos, 0 , 180);
// Set the servo
myServo.write( servoPos );
// done
return 1;
}
/////////////////variable changes for tuning/////////////////
int position1(String command)
{ // Convert
int newPos1 = command.toInt();
// Make sure it is in the right range
// And set the position
pos1 = constrain( newPos1, 0 , 180);
return 1;
}
int position2(String command)
{ // Convert
int newPos2 = command.toInt();
// Make sure it is in the right range
// And set the position
pos2 = constrain( newPos2, 0 , 180);
return 1;
}
int quick(String command)
{ // Convert
quickness = command.toInt();
return 1;
}
int shake_iterate(String command)
{ // Convert
shake_iterations = command.toInt();
return 1;
}
int shaking_type(String command)
{ // Convert
shake_type = command.toInt();
return 1;
}
Click to Expand
Content Rating
Is this a good/useful/informative piece of content to include in the project? Have your say!
You must login before you can post a comment. .