Acelerometers and Piezo sensors

Hi all, recently purchased a spark core and need help understanding how to use accelerometers and piezo sensors in my university project.

developing an electronic device that will record the amount of ‘keep ups’ while playing with a soccer ball, without it hitting the ground (i.e. seeing how many keep ups you can get in a row without it hitting the ground, upon which it would reset).

i was intending on using the accelerometer (adxl345) to recognise when the ball is on the ground and when it is not. when it is on the ground the piezo will not count impacts. Can i create a limit switch out of the accelerometer, whereby the piezo will only count impacts within a range set by the accelerometer? if not, any ideas that would be worth considering?

i am a beginner with all things electronics so forgive me for any misunderstandings.

the value from the piezo will then be sent to a smart phone to view the information. each time the ball hits the ground the sequence will reset.

Hi @mcl0013! That sounds like a useful tool! My initial thought is that you don’t really need the piezo element and can use the accelerometer for all readings. What needs to be figured out is how to differentiate a foot-strike vs. the ball hitting the ground. The simple solution would be to count the +g and -g “peaks”, subtract the last peak from the count (indicating the ball had hit the ground) and divide that number by 2 - you don’t want to count the peak where the ball changes direction in the air and accelerates back toward the ground. If you take the magnitude of the 3D accelerometer readings, that would give you a fairly distinct value for your count. You would probably also want to give the Core a 5 second do nothing check where if the accelerometer hasn’t registered any peaks since the last one, the count would be reset.

I hope that’s a decent answer to your question!

1 Like

Thanks for the great help @gaudsend. definitely pointing me in the right direction :smile:
The issue i have considered with deducting the last peak from the count is that there are no guarantees that the ball will simply bounce once then come to a stop, its undeterminable how many times the ball will bounce on the ground.
i am yet to use/test an accelerometer but is it possible to use its reading at ground level as a ‘reset’ value? if not, any other sensors you might know of that could serve this purpose or are worth exploring?

@gaudsend is right - you will just need to experiment and see how the readings differ between hitting the ground and being kicked. Warning - this might be pretty darn hard in practice. Gather lots and lots of raw data first, carefully match that data to observed events and then process it offline to see if you can develop an algorithm that works reliably enough for your purposes.

Sounds like a great project and a fantastic opportunity to put problem solving skills into practice, and as a university project the process and discipline you use will/should be just as important as the final result.

I would first focus on finding ways to reliably record the data you need and export it so you can analyse it. You may get lucky and discover that you can use a threshold function present on many accelerometers to trigger an event that you subsequently classify as either a kick or a bounce; but I have a hunch that because you will likely have no idea about orientation that you will need to be responsible for doing the vector arithmetic to figure out the G forces in totally arbitrary directions, then take the differential. There may be some cute mathematical tricks to allow you to differentiate in each dimension and analyse that data instead - more research opportunities :smile:

Lots of interesting challenges, should make for a fascinating project. Keep us posted.

Wouldn’t the acceleration of a dead bounce, be different (less) normally that any keep up acceleration.
When the ball comes to rest, check the history of the last few seconds, and determine when it hit the ground ?

@Jack has a good point. The acceleration changes would be different — probably in magnitude between adjacent peaks. You could perform a time series analysis over the last few seconds of the dataset to determine how the foot strike/bounce differ. Depending on the accelerometer used and how it’s interfaced with the Core (analog pin vs. I2C), the limiting factor will be the frequency at which the Core can poll data.

@Andyw is right. Get lots of raw data, and analyse to find the differences.

BTW: Are you planning to place the electronics inside the ball, or what?

the electronics will be housed in a small bracket inside a foam ball for testing, assignment is assessed on the electronics, not the refinement of a product.

alright thank you all for the feedback. will post back when i have some results through testing!

We’ll be here if you want to bounce ideas around (see what I did there ? :smile:)

4 Likes

So i have tested everything and am getting some solid feedback, have been using the arduino uno because it has a serial monitor that i can gather the results from and refine the code. i now need to use this arduino code on a spark core, any idea how i can do this?

just an update on where i am at, my code registers the ‘keep up’ impact well but can’t differentiate hitting a foot or ground, and counts the impacts to receive a ‘high score’ after each sequence has ended. Although this is where i must draw the line for submission. All that remains is converting my code from arduino to particle core. then i need to create a spark.variable and url to link to a freeboard internet widget to display the high score. any tips? especially on how to convert the code from ard to particle.

thanks

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>

/* Assign a unique ID to this sensor at the same time */
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);

unsigned long lasthit = 0;
float threshold = 7.0;
unsigned long timeout = 1500;
unsigned long kickdelay = 400;
int ballstate = 0;
int sequencekicks = 0;
int recordkicks = 0;



void setup(void)
{
  Serial.begin(9600);
  Serial.println("Accelerometer Test"); Serial.println("");

  /* Initialise the sensor */
  if (!accel.begin())
  {
    /* There was a problem detecting the ADXL345 ... check your connections */
    Serial.println("Ooops, no ADXL345 detected ... Check your wiring!");
    while (1);
  }

  /* Set the range to whatever is appropriate for your project */
  accel.setRange(ADXL345_RANGE_16_G);
  // displaySetRange(ADXL345_RANGE_8_G);
  // displaySetRange(ADXL345_RANGE_4_G);
  // displaySetRange(ADXL345_RANGE_2_G);
}


void loop() {
  // put your main code here, to run repeatedly:
  /* Get a new sensor event */
  sensors_event_t event;
  accel.getEvent(&event);

  /* Display the results (acceleration is measured in m/s^2) */
  Serial.print("X: "); Serial.print(event.acceleration.x); Serial.print("  ");
  Serial.print("Y: "); Serial.print(event.acceleration.y); Serial.print("  ");
  Serial.print("Z: "); Serial.print(event.acceleration.z); Serial.print("  ");
  float vector = sqrt(pow(event.acceleration.x, 2) + pow(event.acceleration.y, 2) + pow(event.acceleration.z, 2));
  //equation to find the value of V which is the sum of the vectors
  Serial.print("v: "); Serial.print(vector); Serial.println("m/s^2 ");

  if (millis() - lasthit > kickdelay) { //when the ball is in motion
    if (vector > threshold) { //when the vector is greater than 7.0
      if (ballstate == 0) { //sequence of kicking
        lasthit = millis();
        ballstate = 1; //ball has been kicked
        Serial.println("Kicked");
        sequencekicks ++ ; //adding the kicked values together in the sequence
      }

    } else {
      ballstate = 0; //ball is in the air/in motion
    }
  }

  if (ballstate == 1) {
    if (millis() - lasthit > timeout) { //ball hits the ground
      Serial.println("Hit Ground"); //shows that the sequence has ended
      if (sequencekicks > recordkicks) { //IF most recent attempt is greater than the current record...
        recordkicks = sequencekicks; //...sequencekicks becomes the new record kicks
      }
      Serial.println(sequencekicks); //showing the value of the latest total attempts
      Serial.println(recordkicks); //showing the value of the recordkicks
      sequencekicks = 0; //sequencekicks resets back to 0
    }
  }

  delay(200);

}

Hi @mcl0013! That’s great that you’re getting solid feedback! Personally I’d be interested in seeing some of your data to help you differentiate between a foot-strike and ground impact.

In theory porting your code should be easy. I’m working on getting it to compile on my end and will post back once I have it working!

There should be an increase in velocity (acceleration) on at least one axis, possibly all three when the ball is kicked due to the force being applied to the ball. Inversely there should be a decrease in velocity when the ball hits the ground due to the friction of the ball touching the ground. This is in addition to the normal decaying velocity of the ball as time elapses from the previous kick.

If you collect and analyze the accelerometer data on a fixed frequency basis (many devices let you configure the sampling frequency and have a FIFO to collect the samples and an interrupt to let you know to read out the fifo) you should be able to determine these patterns. It would probably be very apparent if you were to graph the velocity data over time.